$ TITLE ('80/20 MONITOR (MON820), VERSION 1.2, 12 July 77')
;
ASEG
;
; **********************************************************************
; **********************************************************************
;
; 80/20 MONITOR
; (MON820)
; VERSION 1.2
; 12 July 1977
;
; From Intel Document Number 9800484A
;
; **********************************************************************
; **********************************************************************
;
; (C) 1976 INTEL CORPORATION. ALL RIGHTS RESERVED. NO PART OF THIS
; PROGRAM OR PUBLICATION MAY BE REPRODUCED, TRANSMITTED, TRANSCRIBED,
; STORED IN A RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR
; COMPUTER LANGUAGE, IN ANY FORM OR BY ANY MEANS, ELECTRONIC,
; MECHANICAL, MAGNETIC, OPTICAL, CHEMICAL, MANUAL OR OTHERWISE,
; WITHOUT THE PRIOR WRITTEN PERMISSION OF INTEL CORPORATION,
; 3065 BOWERS AVENUE, SANTA CLARA, CALIFORNIA 95051.
;
; **********************************************************************
; **********************************************************************
;
;
; ABSTRACT
; ========
;
; THIS PROGRAM RUNS ON THE SBC 80/30 BOARD AND IS DESIGNED TO PROVIDE
; THE USER WITH A MINIMAL MONITOR. BY USING THIS PROGRAM,
; THE USER CAN EXAMINE AND CHANGE MEMORY OR CPU REGISTERS, LOAD
; A PROGRAM (IN ABSOLUTE HEX) INTO RAM, AND EXECUTE INSTRUCTIONS
; ALREADY IN MEMORY. THE MONITOR ALSO PROVIDES THE USER WITH
; ROUTINES FOR PERFORMING CONSOLE I/O AND PAPER TAPE I/O.
;
;
; PROGRAM ORGANIZATION
; ======= ============
;
; THE LISTING IS ORGANIZED IN THE FOLLOWING WAY. THE FIRST ROUTINE
; IS THE COMMAND RECOGNIZER, WHICH IS THE HIGHEST LEVEL
; ROUTINE IN THE PROGRAM. NEXT, ARE THE ROUTINES TO IMPLEMENT
; THE VARIOUS COMMANDS, FOLLOWED BY THE INTERRUPT HANDLERS,
; AND FINALLY THE UTILITY ROUTINES WHICH ACTUALLY DO THE DIRTY WORK.
;
; WITHIN EACH SECTION, THE ROUTINES ARE ORGANIZED IN ALPHABETICAL
; ORDER, BY ENTRY POINT OF THE ROUTINE.
;
; THE 80/20 MONITOR CAN RESIDE IN TWO 2708 PROM.
; BOTH OF WHICH ARE REQUIRED FOR MONITOR OPERATION.
;
; THE PROGRAM EXPECTS TO RUN IN THE FIRST 2K OF ADDRESS SPACE.
; IF, FOR SOME REASON, THE PROGRAM IS RE-ORG'ED, CARE SHOULD
; BE TAKEN TO MAKE SURE THAT THE TRANSFER INSTRUCTIONS FOR RST 1
; ARE ADJUSTED APPROPRIATELY.
;
; THE PROGRAM ALSO EXPECTSTHAT RAM LOCATIONS 3F00H TO 3FE0H,
; INCLUSIVE, ARE RESERVED FOR THE PROGRAM'S OWN USE. THESE
; LOCATIONS MAY BE ALTERED, HOWEVER, BY CHANGING THE EQU'ED
; SYMBOL "DATA" AS DESIRED.
;
;
ORG 0H
;
; *****************************************************************
;
;
; MONITOR EQUATES
;
;
; *****************************************************************
;
BRCHR EQU 1BH ; CODE FOR BREAK CHARACTER (ESCAPE)
BRTAD EQU 3FAH ; LOCATION OF START OF BRANCH TABLE IN ROM
CMD EQU 027H ; INITIALIZATION
CNCTL EQU 0EDH ; CONSOLE USART CONTROL PORT
CNIN EQU 0ECH ; CONSOLE INPUT PORT
CNOUT EQU 0ECH ; CONSOLE OUTPUT PORT
CONST EQU 0EDH ; CONSOLE STATUS INPUT PORT
CR EQU 00DH ; CODE FOR CARRIAGE RETURN
DATA EQU 16*1024 ; END OF MONITOR 16K RAM USAGE
ESC EQU 01BH ; CODE FOR ESCAPE CHARACTER
HCHAR EQU 00FH ; MASK TO SELECT LOWER HEX CHAR FROM BYTE
INVRT EQU 0FFH ; MASK TO INVERT HALF BYTE FLAG
LF EQU 0AH ; CODE FOR LINE FEED
;LSGNON EQU --- ; LENGTH OF SIGNON MESSAGE - DEFINED LATER
MODE EQU 04FH ; MODE SET FOR USART
;MSTAK EQU --- ; START OG MONITOR STACK - DEFINED LATER
;NCMDS EQU --- ; NUMBER OF VALID COMMANDS
NEWLN EQU 00FH ; MASK FOR CHECKING MEMORY ADDR DISPLAY
PRTY0 EQU 07FH ; MASK TO CLEAR PARITY BIT FROM CONSOLE CHAR
RBR EQU 002H ; RECEIVER BUFFER STATUS READY
REGS EQU DATA-48 ; START OF REGISTER SAVE AREA
;RTABS EQU --- ; SIZE OF ENTRY IN RTAB TABLE
TERM EQU 01BH ; CODE FOR ICMD TERMINATING CHARACTER (ESCAPE)
TRDY EQU 01H ; MASK TO TEST TRANSMITTER STATUS
UPPER EQU 00FFH ; DENOTES UPPER HALF OF BYTE IN ICMD
USAREA EQU DATA-128 ; START OF USER STACK AREA
TXBE EQU 04H ; USART TRANSMITTER BUFFER EMPTY
TTYADV EQU 037H ; TTY READER ADVANCE COMMAND
TTYSTP EQU 035H ; TTY READER STOP COMMAND
ONEMS EQU 139 ; 1 MILLISECOND CONSTANT
IMASK EQU 0H ; INT MASK VALUE
MSKPT EQU 0DBH ; INT. MASK PORT
ICCP EQU 0DAH ; INT CONTROLLER COM PORT
JTBL EQU DATA-32 ; START OF JUMP TABLE IN ROM
ICW1 EQU (JTBL AND 0E0H) + 16H ; INTERRUPT CMD WORD 1
ICW2 EQU JTBL SHR 8 ; INTERRUPT COMMAND WORD 2
OCW3 EQU 0BH ; INTERRUPT OPERATION COMMAND WORD 3
EOIC EQU 020H ; END OF INTERRUPT CMD WORD
TMCP EQU 0DFH ; COMMAND FOR INTERVAL TIMER
CTR0 EQU 0DCH ; COUNTER 0 PORT
CTR1 EQU 0DDH ; COUNTER 1 PORT
CTR2 EQU 0DEH ; COUNTER 2 PORT
MSVC0 EQU 0 ; MOST SIG. VAL. FOR CTR 0
LSVC0 EQU 20H ; LEAST SIG. VAL. FOR CTR 0
C0M0 EQU 030H ; CTR 0 TO MODE 0: SINGLE STEP CMD WORD
B9600 EQU 007DH ; RATE FACTOR FOR 9600 BAUD
B0110 EQU 611DH ; RATE FACTOR FOR 110 BAUD
CHARR EQU 055H ; CODE FOR BAUD RATE RECOGNITION CHAR 'U'
C2M3 EQU 0B6H ; CTT2 TO MODE 3 COMMAND WORD
RSTUST EQU 040H ; UCOMMAND INSTRUCTION TO RESET USART
;
;
;
; *****************************************************************
;
;
;
MVI A,MODE ; USART SET UP MODE.
OUT CNCTL ; OUTPUT MODE
JMP INUST ; BRANCH TO COMPLETE USART INITIALIZATION
NOP
;
;
; *****************************************************************
;
;
; RESTART ENTRY POINT
;
;
; *****************************************************************
;
;
GO: DI ; DISABLE INTERRUPTS ON MONITOR ENTRANCE
CALL REGSV ; SAVE ALL USER REGISTERS
JMP ADROUT
;
;
; *****************************************************************
;
; BRANCH TABLE FOR USER ACCESSIBLE ROUTINES
;
JMP CO ; CONSOLE OUT
JMP CI ; CONSOLE IN
JMP RI ; READER IN
JMP PO ; PUNCH OUT
;
;
; *****************************************************************
;
;
CPYRT: DB '(C) 1980 INTEL CORP'
;
; **********************************************************************
;
; PRINT SIGNON MESSAGE
;
; **********************************************************************
;
SOMSG: LXI H,SGNON ; GET ADDRESS OF SIGNON MESSAGE
MVI B,LSGNON ; LENGTH OF SIGN ON MESSAGE
MSGL:
MOV C,M ; FETCH NEXT CHAR TO C REG
CALL CO ; SEND IT TO THE CONSOLE
INX H ; POINT TO NEXT CHARACTER
DCR B ; END OF MESSAGE?
JNZ MSGL ; RETURN FOR NEXT CHARACTER
;
;
; *****************************************************************
;
;
; COMMAND RECOGNIZING ROUTINE
;
;
; *****************************************************************
;
; FUNCTION* GETCM
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* GETCH,ECHO,ERROR
; DESTROYS* A,B,C,H,L,F/F'S
; DESCRIPTION* GETCM RECEIVES AN INPUT CHARACTER FROM THE USER
; AND ATTEMPTS TO LOCATE THIS CHARACTER IN ITS COMMAND
; CHARACTER TABLE. IF SUCCESSFUL, THE ROUTINE
; CORRESPONDING TO THIS CHARACTER IS SELECTED FROM
; A TABLE OF COMMAND ROUTINE ADDRESSES, AND CONTROL
; IS TRANSFERRED TO THIS ROUTINE. IF THE CHARACTER
; DOES NOT MATCH ANY ENTRIES, CONTROL IS PASSED TO
; THE ERROR HANDLER;
;
GETCM:
LXI SP,MSTAK ; ALWAYS WANT TO RESET STACK PTR TO MONITOR
; /STARTING VALUE SO ROUTINES NEEDN'T CLEAN UP
MVI C,'.' ; PROMPT CHARACTER TO C
CALL ECHO ; SEND PROMPT CHARACTER TO USER TERMINAL
CALL GETCH ; GET COMMAND CHARACTER TO C
CALL ECHO ; ECHO CHARACTER TO USER
MOV A,C ; PUT COMMAND CHARACTER INTO ACCUMULATOR
LXI B,NCMDS ; C CONTAINS LOOP AND INDEX COUNT
LXI H,CTAB ; HL POINTS INTO COMMAND TABLE
GTC05:
CMP M ; COMPARE TABLE ENTY AND CHARACTER
JZ GTC10 ; BRANCH IF EQUAL -COMMAND RECOGNIZED
INX H ; ELSE, INCREMENT TABLE POINTER
DCR C ; DECREMENT LOOP COUNT
JNZ GTC05 ; BRANCH IF NOT AT TABLE END
JMP ERROR ; ELSE, COMMAND CHARACTER IS ILLEGAL
GTC10:
LXI H,CADR ; IF GOOD COMMAND, LOAD ADDRESS OF TABLE
; /OF COMMAND ROUTINE ADDRESSES
DAD B ; ADD WHAT IS LEFT OF LOOP COUNT
DAD B ; ADD AGAIN -EACH ENTRY IN CADR IS 2·BYTES LONG
MOV A,M ; GET LSP OF ADDRESS OF TABLE ENTRY TO A
INX H ; POINT TO NEXT BYTE IN TABLE
MOV H,M ; GET MSP OF ADDRESS OF TABLE ENTRY TO H
MOV L,A ; PUT LSP OF ADDRESS OF TABLE ENTRY INTO L
PCHL ; NEXT INSTRUCTION COMES FROM COMMAND ROUTINE
;
;
; **********************************************************************
;
;
; COMMAND IMPLEMENTING ROUTINES
;
;
; **********************************************************************
;
;
; FUNCTION* DCMD
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* ECHO,NMOUT,HILO,GETCM,CROUT,GETNM
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* DCMD IMPLEMENTS THE DISPLAY MEMORY (D) COMMAND
;
DCMD:
MVI C,2 ; GET TWO NUMBERS FROM INPUT STREAM
CALL GETNM ;
POP D ; ENDING ADDRESS TO DE
POP H ; STARTING ADDRESS TO HL
DCM05:
CALL CROUT ; ECHO CARRIAGE RETURN/LINE FEED
CALL ADRD ; DISPLAY ADDRESS
DCM10:
MVI C,' ' ;
CALL ECHO ; USE BLANK AS SEPARATOR
MOV A,M ; GET CONTENTS OF NEXT MEMORY LOCATION
CALL NMOUT ; DISPLAY CONTENTS
CALL BREAK ; SEE IF USER WANTS OUT
JC EXIT ; IF SO, BRANCH TO EXIT
CALL HILO ; SEE IF ADDRESS OF DISPLAYED LOCATION IS
; /GREATER THAN OR EQUAL TO ENDING ADDRESS
JC EXIT ; EXIT IF NO MORE TO DISPLAY
INX H ; IF MORE TO GO, POINT TO NEXT LOC TO DISPLAY
MOV A,L ; GET LOW ORDER BITS OF NEW ADDRESS
ANI NEWLN ; SEE IF LAST HEX DIGIT OF ADDRESS DENOTES
; /START OF NEW LINE
JNZ DCM10 ; NO - NOT AT END OF LINE
JMP DCM05 ; YES -START NEW LINE WITH ADDRESS
;
;
; *****************************************************************
;
;
; FUNCTION: GCMD
; INPUTS: NONE
; OUTPUTS: NONE
; CALLS: ERROR,GETHX,RSTTF
; DESTROYS: A,B,C,D,E,H,L,F/F'S
; DESCRIPTION: GCMD IMPLEMENTS THE BEGIN EXECUTION (G) COMMAND.
;
;
; ************************************************************
;
;
; GO TO
=SOURCE ADDR
JNC GETCM ; IF NOT, COMMAND IS DONE
JMP MCM05 ; MOVE ANOTHER BYTE
;
; *****************************************************************
;
; .N -IMPLEMENTS SINGLE STEP
;
; FUNCTION* NCMD
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* CROUT
; DESTROYS* A
; DESCRIPTION* NCMD IMPLEMENTS THE SINGLE STEP (N) COMMAND
;
NCMD: CALL CROUT ; ECHO CR/LF
MVI A,0FFH ; SET SINGLE STEP FLAG
JMP RSTTF ; RESTORE REGISTERS AND EXECUTE NEXT INSTRUCTION
;
; *****************************************************************
;
; .R -READ HEXADECIMAL TAPE
;
; FUNCTION* RCMD
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* GETCH,ECHO,CO,RICH,BYTE
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* RCMD IMPLEMENTS THE READ HEXADECIMAL TAPE (R)
; COMMAND.
;
RCMD:
CALL GETCH ; GET CARRIAGE RETURN CHARACTER
CALL ECHO ; ECHO IT
MOV A,C ; MOVE IT TO A REGISTER
CPI CR ; SEE IF CARRIAGE RETURN
JNZ ERROR ; ERROR IF NOT PROPERLY TERMINATED
RCM05:
CALL RICH ; READ CHARACTER FROM TAPE
CPI ':' ; SEE IF RECORD MARK
JNZ RCM05 ; TRY AGAIN IF NOT MARK
XRA A ; ZERO A REGISTER
MOV D,A ; INITIALIZE D FOR HOLDING THE CHECKSUM
CALL BYTE ; READ TWO CHARACTERS FROM TAPE
JZ GETCM ; IF ZERO RECORD LENGTH, ALL DONE
MOV E,A ; OTHERWISE, PUT THE RECORD LENGTH IN E
CALL BYTE ; GET MSB OF LOAD ADDRESS
MOV H,A ; MOVE TO H
CALL BYTE ; GET LSB OF LOAD ADDRESS
MOV L,A ; MOVE TO L
CALL BYTE ; GET RECORD TYPE
MOV C,E ; MOVE RECORD LENGTH TO C
RCM10:
CALL BYTE ; READ DATA FROM TAPE
MOV M,A ; PUT DATA INTO MEMORY
INX H ; INCREMENT HL FOR NEXT LOCATION
DCR E ; DECREMENT RECORD LENGTH
JNZ RCM10 ; LOOP UNTIL DONE
CALL BYTE ; READ CHECKSUM FROM TAPE
JNZ ERROR ; CHECKSUM ERROR IF NOT ZERO
JMP RCM05 ; GET ANOTHER RECORD
;
;
;
; ******************************************************************
;
; .S -SUBSTITUTE INTO MEMORY
;
; FUNCTION* SCMD
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* GETHX,GETCM,NMOUT,ECHO
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* SCMD IMPLEMENTS THE SUBSTITUTE INTO MEMORY (S) COMMAND.
;
SCMD:
CALL GETHX ; GET A NUMBER, IF PRESENT, FROM INPUT
PUSH B ; ADDRESS ENTERED BY USER
POP H ; GET NUMBER TO HL - DENOTES MEMORY LOCATION
SCM05:
MOV A,D ; GET TERMINATOR
CPI ' ' ; SEE IF SPACE
JZ SCM10 ; YES - CONTINUE PROCESSING
CPI ',' ; ELSE, SEE IF COMMA
JNZ GETCH ; NO - TERMINATE COMMAND
SCM10:
MOV A,M ; GET CONTENTS OF SPECIFIED LOCATION TO A
CALL NMOUT ; DISPLAY CONTENTS ON CONSOLE
MVI C,'-'
CALL ECHO ; USE DASH FOR SEPARATOR
CALL GETHX ; GET NEW VALUE FOR MEMORY LOCATION, IF ANY
JNC SCM15 ; IF NO VALUE PRESENT, BRANCH
MOV M,C ; ELSE, STORE LOWER 8 BITS OF NUMBER ENTERED
SCM15:
INX H ; INCREMENT ADDRESS OF MEMORY LOCATION TO VIEW
JMP SCM05
;
;
; *****************************************************************
;
; .W -WRITE HEXADECIMAL TAPE
;
; FUNCTION* WCMD
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* GETNM,LEAD,PO,PBYTE,PADR,PEOL,PEOF
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* WCMD IMPLEMENTS THE WRITE HEXADECIMAL TAPE (W)
; COMMAND.
;
WCMD:
MVI C,2 ;
CALL GETNM ; GET 2 NUMBERS FROM INPUT STREAM
CALL LEAD ; PUNCH 60 NULL CHARACTERS FOR TAPE LEADER
POP D ; ENDING ADDRESS TO DE
POP H ; STARTING ADDRESS TO HL
WCM05:
MOV A,L ; MOVE L TO A
ADI 16 ; INCREMENT THE LSB OF STARTING ADDRESS BY 16
MOV C,A ; MOVE RESULT TO C
MOV A,H ; MOVE H TO A
ACI 0 ; ADD CARRY IN FROM PREVIOUS OPERATION
MOV B,A ; SAVE RESULT IN B
MOV A,E ; NOW MOVE LSB OF ENDING ADDRESS TO A
SUB C ; SUBTRACT LSB OF STARTING ADDRESS
MOV C,A ; SAVE IN C
MOV A,D ; NOW GET MSB OF ENDING ADDRESS IN A
SBB B ; SUBTRACT MSB OF STARTING ADDRESS
JC WCM10 ; BRANCH IF THE RECORD LENGTH IS NOT 16
MVI A,16 ; OTHERWISE SET A TO RECORD LENGTH OF 16
JMP WCM15 ; NOW BRANCH TO PUNCH THE RECORD
WCM10:
MOV A,C ; THIS IS THE LAST RECORD
ADI 17 ; SO SET A TO REMAINING DATA LENGTH
WCM15:
ORA A ; CHECK FOR RECORD LENGTH OF ZERO
JZ WCM25 ; IF IT IS, ALL DONE
PUSH D ; OTHERWISE, SAVE ENDING ADDRESS
MOV E,A ; PUT RECORD LENGTH IN E
MVI D,0 ; INITIALIZE D FOR HOLDING CHECKSUM
MVI C,':' ;
CALL PO ; PUNCH RECORD MARK CHARACTER
MOV A,E ; PUT RECORD LENGTH IN A
CALL PBYTE ; PUNCH RECORD LENGTH
CALL PADR ; PUNCH STARTING ADDRESS
XRA A ; ZERO A
CALL PBYTE ; PUNCH RECORD TYPE
WCM20:
MOV A,M ; GET DATA TO BE PUNCHED FROM MEMORY
CALL PBYTE ; PUNCH IT
INX H ; INCREMENT MEMORY ADDRESS
DCR E ; DECREMENT LENGTH COUNT
JNZ WCM20 ; LOOP UNTIL ALL DATA PUNCHED
XRA A ;
SUB D ; PUNCH CHECKSUM
CALL PBYTE ;
POP D ; RESTORE ENDING ADDRESS
CALL PEOL ; PUNCH CARRIAGE RET~RN AND LINE FEED
JMP WCM05 ;
WCM25:
CALL PEOF ; PUNCH END OF FILE RECORD
JMP EXIT ; ALL DONE
;
;
; *****************************************************************
;
; .X -EXAMINE REGISTERS AND CHANGE
;
; FUNCTION* XCMD
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* GETCH,ECHO,REGDS,GETCM,ERROR,RGADR,NMOUT,CROUT,GETHX
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* XCMD IMPLEMENTS THE REGISTER EXAMINE AND CHANGE (X)
; COMMAND.
;
XCMD:
CALL GETCH ; GET REGISTER IDENTIFIER
CALL ECHO ; ECHO IT
MOV A,C ;
CPI CR ;
JNZ XCM05 ; BRANCH IF NOT CARRIAGE RETURN
CALL REGDS ; ELSE, DISPLAY REGISTER CONTENTS
JMP GETCM ; THEN TERMINATE COMMAND
XCM05:
MOV C,A ; GET REGISTER IDENTIFIER TO C
CALL RGADR ; CONVERT IDENTIFIER INTO RTAB TABLE ADDR
PUSH B ;
POP H ; PUT POINTER TO REGISTER ENTRY INTO HL
MVI C,' ' ;
CALL ECHO ; ECHO SPACE TO USER
MOV A,C ;
STA TEMP ; PUT SPACE INTO TEMP AS DELIMITER
XCM10:
LDA TEMP ; GET TERMINATOR
CPI ' ' ; SEE IF A BLANK
JZ XCM15 ; YES -GO CHECK POINTER INTO TABLE
CPI ',' ; NO -SEE IF COMMA
JNZ GETCM ; NO -MUST BE CARRIAGE RETURN TO END COMMAND
XCM15:
MOV A,M ;
ORA A ; SET F/F'S
JZ EXIT ; BRANCH IF AT END OF TABLE
PUSH H ; PUT POINTER ON STACK
MOV E,M ;
MVI D,REGS SHR 8 ; FETCH ADDRESS OF SAVE LOCATION FROM
INX H ; /TABLE
MOV B,M ; FETCH LENGTH FLAG FROM TABLE
PUSH D ; SAVE ADDRESS OF SAVE LOCATION
PUSH D ;
POP H ; MOVE ADDRESS TO HL
PUSH B ; SAVE LENGTH FLAG
MOV A,M ; GET 8 BITS OF REGISTER FROM SAVE LOCATION
CALL NMOUT ; DISPLAY IT
POP PSW ; GET BACK LENGTH FLAG
PUSH PSW ; SAVE IT AGAIN
ORA A ; SET F/F'S
JZ XCM20 ; IF 8 BIT REGISTER, NOTHING MORE TO DISPLAY
DCX H ; ELSE, FOR 16 BIT REGISTER, GET LOWER 8 BITS
MOV A,M ;
CALL NMOUT ; DISPLAY THEM
XCM20:
MVI C,'-'
CALL ECHO ; USE DASH AS SEPARATOR
CALL GETHX ; SEE IF THERE IS A VALUE TO PUT INTO REGISTER
JNC XCM30 ; NO -GO CHECK FOR NEXT REGISTER
MOV A,D ;
STA TEMP ; ELSE, SAVE THE TERMINATOR FOR NOW
POP PSW ; GET BACK LENGTH FLAG
POP H ; PUT ADDRESS OF SAVE LOCATION INTO HL
ORA A ; SET F/F'S
JZ XCM25 ; IF 8 BIT REGISTER, BRANCH
MOV M,B ; SAVE UPPER 8 BITS
DCX H ; POINT TO SAVE LOCATION FOR LOWER 8 BITS
XCM25:
MOV M,C ; STORE ALL OF 8 BIT OR LOWER 1/2 OF 16 BIT REG
XCM27:
LXI D,RTABS ; SIZE OF ENTRY IN RTAB TABLE
POP H ; POINTER INTO REGISTER TABLE RTAB
DAD D ; ADD ENTRY SIZE TO POINTER
JMP XCM10 ; DO NEXT REGISTER
XCM30:
MOV A,D ; GET TERMINATOR
STA TEMP ; SAVE IN MEMORY
POP D ; CLEAR STACK OF LENGTH FLAG AND ADDRESS
POP D ; /OF SAVE LOCATION
JMP XCM27 ; GO INCREMENT REGISTER TABLE POINTER
;
;
; *****************************************************************
;
;
; INTERRUPT SERVICE ROUTINES
;
;
; *****************************************************************
;
;
; **********************************************************************
;
;
; FUNCTION: INTIN
; INPUTS: NONE
; OUTPUTS: NONE
; CALLS: REGSV,ECHO,NMOUT,REGDS
; DESTROYS: A,B,C
; DESCRIPTION: INTIN HANDLES INTERRUPTS CAUSED BY ACTIVE SIGNALS ON
; TRAP, RST 6.5, AND RST 5.5, IF THEY ARE NOT HANDLED BY
; THE USER. IT PRINTS THE INTERUPT MASK, NEXT INSTRUCTION
; AND REGISTER VALUES.
;
;
INTIN:
CALL REGSV ; SAVE ALL USERS REGISTERS
MVI C,'I' ;
CALL ECHO ; OUTPUT INTERRUPT MESSAGE 'I=#'
MVI C,'=' ;
CALL ECHO ;
MVI A,OCW3 ; READ INTERRUPT 'IN SERVICE' REGISTER
OUT ICCP
IN ICCP
MVI B,8 ; SET UP TO FIND INTERRUPT NUMBER
MVI C,0
FINTH: RAR ; ROTATE TO CHECK INTERRUPT 'IS' BIT
JC FNDI ; EXIT IF # FOUND
INR C
DCR B ; TRY AGAIN
JNZ FINTH
FNDI: MOV A,C ; MOVE FOR OUTPUT CONVERSION
CALL NMOUT ; PRINT INTERRUPT NUMBER
MVI C,' ' ; USE SPACE AS DELIMITER
CALL ECHO ; PRINT IT
CALL NXTIN ; OUTPUT NEXT INSTRUCTION
CALL REGDS ; OUTPUT REGISTERS
MVI A,EOIC ; END OF INTERRUPT
OUT ICCP
JMP GETCH ; GO GET USER COMMAND
;
;
; *****************************************************************
;
;
; FUNCTION STEPIN
; INPUTS: NONE
; OUTPUTS: NONE
; CALLS: REGSV, REGDS, NXTIN
; DESTROYS: A,F/F'S
; DESCRIPTION: STEPIN OUTPUTS DATA AFTER SINGLE STEP TIMER INTERRUPT
;
;
STEPIN:
CALL REGSV ; SAVE ALL USERS REGISTERS
MVI A,EOIC ; END OF INTERRUPT
OUT ICCP
LDA PSAVE+1 ; TEST FOR SINGLE STEP INTO
ANA A
JNZ STPOK ; PC HIGH=0 FOR BREAKPOINT ADDRESS
LDA PSAVE
CPI 0FH ; PC LOW 0
; CALLS* RICH,CNVBN
; DESTROYS* A,B,C,D,F/F'S
; DESCRIPTION* BYTE READS 2 ASCII CHARACTERS FROM THE TELETYPEWRITER
; AND CONVERTS THE CHARACTERS TO ONE HEXADECIMAL CHARACTER.
; THE A REGISTER CONTAINS THE FINAL CHARACTER AND THE
; D REGISTER CONTAINS THE UPDATED VALUE OF
; THE CHECKSUM.
;
BYTE:
PUSH B ; SAVE BC
CALL RICH ; READ ASCII CHARACTER FROM TAPE
MOV C,A ;
CALL CNVBN ; CONVERT CHARACTER TO HEXADECIMAL
RLC ; POSITION VALUE INTO UPPER 4 BITS
RLC ;
RLC ;
RLC ;
MOV B,A ; SAVE RESULTS IN B
CALL RICH ; GET ANOTHER CHARACTER FROM TAPE
MOV C,A ;
CALL CNVBN ; CONVERT IT
ORA B ; OR IN THE UPPER 4 BITS
MOV C,A ; SAVE
ADD D ; INCREMENT CHECKSUM
MOV D,A ;
MOV A,C ; RESTORE HEX DATA TO A REGISTER
POP B ; RESTORE BC
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION* CI
; INPUTS* NONE
; OUTPUTS* A - CHARACTER FROM CONSOLE (8-BITS)
; CALLS* DELAY
; DESTROYS* A,F/F'S
; DESCRIPTION* CI WAITS UNTIL A CHARACTER HAS BEEN ENTERED AT THE
; CONSOLE AND THEN RETURNS THE CHARACTER, VIA THE A
; REGISTER, TO THE CALLING ROUTINE. THIS ROUTINE
; IS CALLED BY THE USER VIA A JUMP TABLE IN RAM.
;
CI:
IN CONST ; GET STATUS OF CONSOLE
ANI RBR ; CHECK FOR RECEIVER BUFFER READY
JZ CI ; NOT YET - WAIT
IN CNIN ; READY SO GET CHARACTER
RET
;
;
; *****************************************************************
;
;
; FUNCTION: CNVBN
; INPUTS: C -ASCII CHARACTER '0'-'9' OR 'A'-'F'
; OUTPUTS: A - 0 TO F HEX
; CALLS: NOTHING
; DESTROYS: A,F/F'S
; DESCRIPTION: CNVBN CONVERTS THE ASCII REPRESENTATION OF A HEX
; CHARACTER INTO ITS CORRESPONDING BINARY VALUE. CNVBN
; DOES NOT CHECK THE VALIDITY OF ITS INPUT.
;
CNVBN:
MOV A,C ;
SUI '0' ; SUBTRACT CODE FOR '0' FROM ARGUMENT
CPI 10 ; WANT TO TEST FOR RESULT OF 0 TO 9
RM ; IF SO, THEN ALL DONE
SUI 7 ; ELSE, RESULT BETWEEN 17 AND 23 DECIMAL
RET ; SO RETURN AFTER SUBTRACTING BIAS OF 7
;
;
; *****************************************************************
;
;
; FUNCTION* CO
; INPUTS* C -CHARACTER TO OUTPUT TO CONSOLE
; OUTPUTS* C -CHARACTER OUTPUT TO CONSOLE
; CALLS* SPDLY,MKDLY,DELAY
; DESTROYS* A,F/F'S
; DESCRIPTION* CO SENDS THE INPUT ARGUMENT TO THE CONSOLE.
; AND THEN SENDS THE INPUT ARGUMENT TO THE CONSOLE.
;
CO:
IN CONST ; GET STATUS OF CONSOLE
ANI TRDY ; SEE IF TRANSMITTER READY
JZ CO ; NO - WAIT
MOV A,C ; ELSE, MOVE CHARACTER TO A REG FOR OUTPUT
OUT CNOUT ; SEND TO CONSOLE
RET
;
;
; *****************************************************************
;
;
; FUNCTION: CROUT
; INPUTS: NONE
; OUTPUTS: NONE
; CALLS: ECHO
; DESTROYS: A,B,C,F/F'S
; DESCRIPTION: CROUT SENDS A CARRIAGE RETURN (AND HENCE A LINE
; FEED) TO THE CONSOLE.
CROUT:
MVI C,CR ;
CALL ECHO ; OUTPUT CARRIAGE RETURN TO USER TERMINAL
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION* DELAY
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* NOTHING
; DESTROYS* NOTHING
; DESCRIPTION* DELAY PROVIDES A PROGRAMMED DELAY OF 1 MILLISECOND
;
DELAY:
PUSH B ; SAVE BC REGISTERS
MVI B,ONEMS ; LOAD 1 MILLISECOND CONSTANT
DEL1:
DCR B ; DECREMENT COUNTER
JNZ DEL1 ; JUMP IF NOT DONE
POP B ; RESTORE BC REGISTERS
RET ; RETURN TO CALLING ROUTINE
;
;
; *****************************************************************
;
;
; FUNCTION: ECHO
; INPUTS: C -CHARACTER TO ECHO TO TERMINAL
; OUTPUTS: C -CHARACTER ECHOED TO TERMINAL
; CALLS: CO
; DESTROYS: A,F/F'S
; DESCRIPTION: ECHO TAKES A SINGLE CHARACTER AS INPUT AND, VIA
; THE MONITOR, SENDS THAT CHARACTER TO THE USER
; TERMINAL; A CARRIAGE RETURN IS ECHOED AS A CARRIAGE
; RETURN LINE FEED, AND AN ESCAPE CHARACTER IS ECHOED AS $
;
ECHO:
MOV B,C ; SAVE ARGUMENTT
MVI A,ESC ;
CMP B ; SEE IF ECHOING AN ESCAPE CHARACTER
JZ ECH05 ;0473-CA 7C 04
MVI C,'$' ; YES - ECHO AS $
ECH05:
CALL CO ; DO OUTPUT THROUGH MONITOR
MVI A,CR ;
CMP B ; SEE IF CHARACTER ECHOED WAS A CARRIAGE RETN
JNZ ECH10 ; NO - NO NEED TO TAKE SPECIAL ACTION
MVI C,LF ; YES -WANT TO ECHO LINE FEED, TOO
CALL CO
ECH10:
MOV C,B ; RESTORE ARGUMENT
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION: ERROR
; INPUTS: NONE
; OUTPUTS: NONE
; CALLS: GCM40,ECHO,CROUT,GETCM
; DESTROYS: A,B,C,F/F'S
; DESCRIPTION: ERROR PRINTS THE ERROR CHARACTER (CURRENTLY A CHECK
; ON THE CONSOLE, FOLLOWED BY A CARRIAGE RETURN-LINE FEED,
; AND THEN RETURNS CONTROL TO THE COMMAND RECOGNIZER.
;
ERROR:
MVI C,'#' ;
CALL ECHO ; SEND # TO CONSOLE
EXIT:
CALL CROUT ; SKIP TO BEGINNING OF NEXT LINE
JMP GETCM ; TRY AGAIN FOR ANOTHER COMMAND
;
;
; *****************************************************************
;
;
; FUNCTION: FRET
; INPUTS: NONE
; OUTPUTS: CARRY - ALWAYS 0
; CALLS: NOTHING
; DESTROYS: CARRY
; DESCRIPTION: FRET IS JUMPED TO BY ANY ROUTINE THAT WISHES TO
; INDICATE FAILURE ON RETURN. FRET SETS THE CARRY
; FALSE, DENOTING FAILURE, AND THEN RETURNS TO THE
; CALLER OF THE ROUTINE INVOKING FRET.
;
FRET:
STC ;FIRST SET CARRY TRUE
CMC ; THEN COMPLEMENT IT TO MAKE IT FALSE
RET ; RETURN APPROPRIATELY
;
;
; *****************************************************************
;
;
; FUNCTION: GETCH
; INPUTS: NONE
; OUTPUTS: C - NEXT CHARACTER IN INPUT STREAM
; CALLS: CI
; DESTROYS: A,C,F/F'S
; DESCRIPTION: GETCH RETURNS THE NEXT CHARACTER IN THE INPUT STREAM
; TO THE CALLING PROGRAM.
;
GETCH:
CALL CI ; GET CHARACTER FROM TERMINAL
ANI PRTY0 ; TURN OFF PARITY BIT IN CASE SET BY CONSOLE
MOV C,A ; PUT VALUE IN C REGISTER FOR RETURN
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION: GETHX
; INPUTS: NONE
; OUTPUTS: BC - 16 BIT INTEGER
; D - CHARACTER WHICH TERMINATED THE INTEGER
; CARRY - 1 IF FIRST CHARACTER NOT DELIMITER
; - 0 IF FIRST CHARACTER IS DELIMITER
; CALLS: GETCH,ECHO,VALDL,VALDG,CNVBN,ERROR
; DESTROYS: A,B,C,D,E,F/F'S
; DESCRIPTION: GETHX ACCEPTS A STRING OF HEX DIGITS FROM THE INPUT
; STREAM AND RETURNS THEIR VALUE AS A 16 BIT BINARY
; INTEGER. IF MORE THAN 4 HEX DIGITS ARE ENTERED,
; ONLY THE LAST 4 ARE USED. THE NUMBER TERMINATES WHEN
; A VALID DELIMITER IS ENCOUNTERED. THE DELIMITER IS
; ALSO RETURNED AS AN OUTPUT OF THE FUNCTION. ILLEGAL
; CHARACTERS (NOT HEX DIGITS OR DELIMITERS) CAUSE AN
; ERROR INDICATION. IF THE FIRST (VALID) CHARACTER
; ENCOUNTERED IN THE INPUT STREAM IS NOT A DELIMITER,
; GETHX WILL RETURN WITH THE CARRY BIT SET TO 1
; OTHERWISE, THE CARRY BIT IS SET TO 0 AND THE CONTENTS
; OF BC ARE UNDEFINED.
;
GETHX:
PUSH H ; SAVE HL
LXI H,0 ; INITIALIZE RESULT
MVI E,0 ; INITIALIZE DIGIT FLAG TO FALSE
GHX05:
CALL GETCH ; GET A CHARACTER
CALL ECHO ; ECHO THE CHARACTER
CALL VALDL ; SEE IF DELIMITER
JNC GHX10 ; NO - BRANCH
MOV D,C ; YES -ALL DONE, BUT WANT TO RETURN DELIMITER
PUSH H ;
POP B ; MOVE RESULT TO BC
POP H ; RESTORE HL
MOV A,E ; GET FLAG
ORA A ; SET F/F'S
JNZ SRET ; IF FLAG NON-0, A NUMBER HAS BEEN FOUND
JZ FRET ; ELSE, DELIMITER WAS FIRST CHARACTER
GHX10:
CALL VALDG ; IF NOT DELIMITER, SEE IF DIGIT
JNC ERROR ; ERROR IF NOT A VALID DIGIT, EITHER
CALL CNVBN ; CONVERT DIGIT TO ITS BINARY VALUE
MVI E,0FFH ; SET DIGIT FLAG NON-0
DAD H ; *2
DAD H ; *4
DAD H ; *8
DAD H ; *16
MVI B,0 ; CLEAR UPPER 8 BITS OF BC PAIR
MOV C,A ; BINARY VALUE OF CHARACTER INTO C
DAD B ; ADD THIS VALUE TO PARTIAL RESULT
JMP GHX05 ; GET NEXT CHARACTER
;
;
; *****************************************************************
;
;
; FUNCTION* GETNM
; INPUTS* C - COUNT OF NUMBERS TO FIND IN INPUT STREAM
; OUTPUTS* TOP OF STACK -NUMBERS FOUND IN REVERSE ORDER (LAST ON TOP
; OF STACK)
; CALLS* GETHX,HILO,ERROR
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* GETNM FINDS A SPECIFIED COUNT OF NUMBERS, BETWEEN 1
; AND 3, INCLUSIVE, IN THE INPUT
; STREAM AND RETURNS THEIR VALUES ON THE STACK. IF 2
; OR MORE NUMBERS ARE REQUESTED, THEN THE FIRST MUST BE
; LESS THAN OR EQUAL TO THE' SECOND, OR THE FIRST AND
; SECOND NUMBERS WILL BE SET EQUAL. THE LAST NUMBER
; REQUESTED MUST BE TERMINATED BY A CARRIAGE RETURN
; OR AN ERROR INDICATION WILL RESULT.
;
GETNM:
MVI L,3 ; PUT MAXIMUM'ARGUMENT COUNT INTO L
MOV A,C ; GET THE ACTUAL ARGUMENT COUNT
ANI 3 ; FORCE TO MAXIMUM OF 3
RZ ; IF 0, DON'T BOTHER TO DO ANYTHIING
MOV H,A ; ELSE, PUT ACTUAL COUNT INTO H
GNM05:
CALL GETHX ; GET A NUMBER FROM INPUT STREAM
JNC ERROR ; ERROR IF NOT THERE -TOO FEW NUMBERS
PUSH B ; ELSE, SAVE NUMBER ON STACK
DCR L ; DECREMENT MAXIMUM ARGUMENT COUNT
DCR H ; DECREMENT ACTUAL ARGUMENT COUNT
JZ GNM10 ; BRANCH IF NO MORE NUMBERS WANTED
MOV A,D ; ELSE, GET NUMBER TERMINATOR TO A
CPI CR ; SEE IF CARRIAGE RETURN
JZ ERROR ; ERROR IF SO - TOO FEW NUMBERS
JMP GNM05 ; ELSE, PROCESS NEXT NUMBER
GNM10:
MOV A,D ; WHEN COUNT 0, CHECK LAST TERMINATOR
CPI CR ;
JNZ ERROR ; ERROR IF NOT CARRIAGE RETURN
LXI B,0FFFFH ; HL GETS LARGEST NUMBER
MOV A,L ; GET WHAT'S LEFT OF MAXIMUM ARG COUNT
ORA A ; CHECK FOR 0
JZ GNM20 ; IF YES, 3 NUMBERS WERE INPUT
GNM15:
PUSH B ; IF NOT, FILL REMAINING ARGUMENTS WITH 0FFFFH
DCR L ;
JNZ GNM15 ;
GNM20:
POP B ; GET THE 3 ARGUMENTS OUT
POP D ;
POP H ;
CALL HILO ; SEE IF FIRST >= SECOND
JNC GNM25 ; NO - BRANCH
MOV D,H ;
MOV E,L ; YES - MAKE SECOND EQUAL TO THE FIRST
GNM25:
XTHL ; PUT FIRST ON STACK -GET RETURN ADDR
PUSH D ; PUT SECOND ON STACK
PUSH B ; PUT THIRD ON STACK
PUSH H ; PUT RETURN ADDRESS ON STACK
GNM30:
DCR A ; DECREMENT RESIDUAL COUNT
RM ; IF NEGATIVE, PROPER RESULTS ON STACK
POP H ; ELSE, GET RETURN ADDR
XTHL ; REPLACE TOP RESULT WITH RETURN ADDR
JMP GNM30 ; TRY AGAIN
;
;
; *****************************************************************
;
;
; FUNCTION* HILO
; INPUTS* DE - 16 BIT INTEGER
; HL -16 BIT INTEGER
; OUTPUTS* CARRY - 0 IF HL=DE·
; CALLS* NOTHING
; DESTROYS* A,F/F'S
; DESCRIPTION* HILO COMPARES THE 2 16 BIT INTEGERS IN HL AND DE. THE
; INTEGERS ARE TREATED AS UNSIGNED NUMBERS. THE CARRY
; BIT IS SET ACCORDING TO THE RESULT OF THE COMPARISON.
;
HILO:
PUSH B ; SAVE BC
MOV B,A ; SAVE A REGISTER
INX H ; INCREMENT HL BY 1
MOV A,H ; WANT TO TEST FOR 0 RESULT AFTER
ORA L ; /INCREMENTING
DCX H ; RESTORE HL
STC ; SET CARRY
JZ HIL05 ; IF SO, CARRY IS SET PROPERLY
MOV A,L ; IF NOT, MOVE L TO A
SUB E ; SUBTRACT E
MOV A,H ; MOVE H TO A
SBB D ; SUBTRACT D WITH BORROW
CMC ; COMPLIMENT CARRY FOR CORRECT CARRY BIT VALUE
HIL05:
MOV A,B ; RESTORE A
POP B ; RESTORE BC
RET ; EXIT
;
;
; *****************************************************************
;
; FUNCTION: INUST
; INPUTS: NONE
; OUTPUTS: NOTHING
; CALLS: NOTHING
; DESTROYS: A,H,L,SP
; DESCRIPTION: INUST OUTPUTS TO THE USART THE COMMAND WORD
; AND INITIALIZES THE STACK POINTER,
; ALSO THE INTERVAL TIMER, AND THE INTERRUPT
; CONTROLLER ARE INITIALIZED.
;
INUST:
MVI A,CMD ;
OUT CNCTL ; OUTPUT COMMAND WORD TO USART
LXI H,MSTAK-64 ; LOAD POINTER TO STACK
SHLD SSAVE ; INITIALIZE USER STACK POINTER
LXI SP,MSTAK ; INITIALIZE MONITOR STACK
MVI A,C0M0 ; INITIALIZE SINGLE STEP TIMER MODE
OUT TMCP
MVI A,C2M3 ; INITIALIZE COUNTER #2 FOR BAUD RATE
OUT TMCP ; OUTPUT COMMAND WORD TO INTERVAL TIMER
BRSEL: MVI B,08D ; LOAD '# OF RATES' COUNTER
LXI H,B9600 ; LOAD BAUD RATE FACTOR
BRS05: MVI A,37H ; RESET USART STATUS ERRORS AND
OUT CNCTL ; SET 'DTR'
BRS06: MOV A,L ; LEAST SIGNIFICANT WORD FOR CTR2
OUT CTR2 ; OUTPUT WORD TO CTR 2
MOV A,H ; MOST SIGNIFICANT WORD FOR CTR2
OUT CTR2 ; OUTPUT WORD TO CTR2
LXI D,1000 ; SETUP 1 SECOND TIMEOUT
BRS07: CALL DELAY ; 1 MS DELAY
DCX D ; DECREMENT TIMER
IN CONST ; INPUT USART STATUS
ANI RBR ; CHECK FOR RECEIVER BUFFER READY
JNZ BRS08 ; NOT YET - WAIT 1 MS AND CHECK AGAIN
MOV A,E ; TEST FOR ZERO -
ORA D ; AFTER DECREMENTING
JNZ BRS07 ; CONTINUE TO CHEK STATUS FOR 1 SECOND
JMP BRSEL ; AFTER 1 SECOND REINITIALIZE BAUD RATE SEARCH
BRS08: IN CNIN ; READY SO GET CHARACTER
ANI 7FH ; MASK OFF PARITY BIT
MOV C,A ; SAVE CHAR
IN CNCTL ; GET USART STATUS
ANI 30H ; MASK ERROR BITS
JNZ BRS10 ; IF ERROR, GET NEXT CHAR
MOV A,C ; CHAR TO ACC
CPI CHARR ; COMPARE FOR CORRECT CHAR
JNZ BRS10 ; IF BAD CHAR, GET NEXT ONE
JMP IICR ; GO TO INTERRUPT INITIALIZATION
BRS10: MVI C,120 ; SETUP 120 MS TIMER
BRS15: CALL DELAY ; 1 MS DELAY
DCR C ; DECREMENT TIMER
JNZ BRS15 ; JUMP IF TIMER NOT EXPIRED
IN CNIN ; CLEAR USART INPUT BUFFER
DCR B ; DECREMENT RATE COUNTER
MOV A,B ; MOVE RATE CTR TO ACC
CPI 01 ; IS RATE CTR=1?
JZ BRS20 ; GO TO 110 BAUD SELECT IF LSB = 1
CPI 00 ; IS RATE CTR=0?
JZ BRSEL ; IF ZERO, START OVER
DAD H ; HALVE THE BAUD RATE
JMP BRS05 ; TRY AGAIN
BRS20: MVI A,RSTUST ; USART RESET VALUE
OUT CNCTL ; RESET USART TO ACCEPT NEW MODE INST.
MVI A,(MODE OR 80H) ; TWO STOP BITS MODE INSTRUCTION
OUT CNCTL ; LOAD NEW MODE INSTRUCTION
MVI A,35H ; RESET USART STATUS ERRORS AND-
OUT CNCTL ; TURN OFF DTR (READER TAPE OFF)
LXI H,B0110 ; LOAD 110 BAUD RATE FACTOR
JMP BRS06 ; TRY AGAIN
;
;
IICR: MVI A,ICW1 ; INITIALIZE INTERRUPT CONTROLLER
OUT ICCP ; OUTPUT COMMAND WORD #1
MVI A,ICW2 ;
OUT ICCP+1 ; OUTPUT COMMAND WORD #2
MVI A,IMASK ; INTERRUPT MASK VALUE
OUT MSKPT ; OUTPUT MASK WORD TO CONTROLLER
LXI D,JPTB ; LOAD START OF PROM JUMP TABLE
LXI H,JTBL ; LOAD START OF RAM JUMP TABLE
MVI B,31D ; LENGTH OF TABLE IN "B"
MTBL: MOV A,M ; MOVE PROM JUMP TABLE TO RAM
STAX D
INX H
INX D
DCR B
JNZ MTBL ; LOOP UNTIL DONE
LXI H,USAREA ; INITIALIZE USER STACK POINTER
SHLD SSAVE
JMP SOMSG ; GO TO PRINT SIGNON MESSAGE
;
;
; *****************************************************************
;
;
; FUNCTION* LEAD
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* PO
; DESTROYS* B,C,F/F'S
; DESCRIPTION* LEAD OUTPUTS 60 NULL CHARACTERS TO PAPER TAPE TO FORM A
; LEADER.
;
LEAD:
MVI B,60 ; LOAD B WITH A COUNT OF 60
LE05:
MVI C,0
CALL PO ; PUNCH NULL CHARACTER
DCR B ; DECREMENT COUNT
JNZ LE05 ; DO IT AGAIN IF NOT DONE
RET
;
;
; *****************************************************************
;
;
; FUNCTION* NMOUT
; INPUTS* A -8 BIT INTEGER
; OUTPUTS* NONE
; CALLS* ECHO,PRVAL
; DESTROYS* A,B,C,F/F'S
; DESCRIPTION* NMOUT CONVERTS THE 8 BIT, UNSIGNED INTEGER IN THE
; A REGISTER INTO 2 ASCII CHARACTERS. THE ASCII CHARACTERS
; ARE THE ONES REPRESENTING THE 8 BITS. THESE TWO
; CHARACTERS ARE SENT TO THE CONSOLE AT THE CURRENT PRINT
; POSITION OF THE CONSOLE.
;
NMOUT:
PUSH PSW ; SAVE ARGUMENT
RRC ;
RRC ;
RRC ;
RRC ; GET UPPER 4 BITS TO LOW 4 BIT POSITIONS
CALL PRVAL ; CONVERT LOWER 4 BITS TO ASCII
CALL ECHO ; SEND TO TERMINAL
POP PSW ; GET BACK ARGUMENT
CALL PRVAL ;
CALL ECHO ;
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION* NXTIN
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* ECHO,NMOUT,CROUT
; DESTROYS* A,F/F'S,C,D,H,L
; DESCRIPTION* NXTIN PRINTS 3 BYTES OF NEXT INSTRUCTION ON THE CONSOLE
;
NXTIN:
MVI C,'N' ; OUTPUT 'NI='
CALL ECHO ;
MVI C,'I' ;
CALL ECHO ;
MVI C,'=' ;
CALL ECHO ;
MVI D,3 ; OUTPUT 3 BYTES
LHLD PSAVE ; GET LAST PC
NXT05:
MOV A,M ;
CALL NMOUT ; OUTPUT BYTE
MVI C,' ' ; USE SPACE FOR DELIMITER
CALL ECHO ;
DCR D ; DECREMENT COUNT
INX H ; INCREMENT PC ADDRESS
JNZ NXT05 ; DO NEXT BYTE
CALL CROUT ;
RET ; RETURN
;
;
; *****************************************************************
;
;
; FUNCTION* PADR
; INPUTS* HL - ADDRESS TO BE PUNCHED
; OUTPUTS* NONE
; CALLS* PBYTE
; DESTROYS* A
; DESCRIPTION* PADR PUNCHES ON THE TELETYPEWRITER THE ADDRESS
; CONTAINED IN THE H,L REGISTERS.
;
PADR:
MOV A,H ; PUNCH FIRST HALF OF ADDRESS
CALL PBYTE ;
MOV A,L ; PUNCH SECOND HALF OF ADDRESS
CALL PBYTE ;
RET ; RETURN TO CALLING ROUTINE
;
;
; *****************************************************************
;
;
; FUNCTION* PBYTE
; INPUTS* A - CHARACTER TO BE PUNCHED
; D - CURRENT VALUE OF CHECKSUM
; OUTPUTS* D - UPDATED VALUE OF CHECKSUM
; CALLS* PRVAL, PO
; DESTROYS* A,F/F'S
; DESCRIPTION* PBYTE CONVERTS THE HEXADECIMAL VALUE IN THE A REGISTER
; INTO TWO ASCII CHARACTERS AND PUNCHES THESE CHARACTERS
; ON PAPER TAPE. THE CHECKSUM CONTAINED IN D IS UPDATED.
;
PBYTE:
PUSH PSW ; SAVE A,F/FIS
RRC ; POSITION UPPER 4 BITS INTO LOWER 4 BITS
RRC ;
RRC ;
RRC ;
CALL PRVAL ; CONVERT UPPER 4 BITS JUST ROTATED TO ASCII
CALL PO ; PUNCH CHARACTER
POP PSW ; RESTORE A,F/F'S
PUSH PSW ; SAVE A AGAIN
CALL PRVAL ; CONVERT LOWER 4 BITS TO ASCII CHARACTER
CALL PO ; PUNCH CHARACTER
POP PSW ; RESTORE A
ADD D ; ADD VALUE TO CHECKSUM
MOV D,A ; UPDATE D REGISTER WITH NEW CHECKSUM
RET ; RETURN TO CALLING ROUTINE
;
;
; *****************************************************************
;
;
; FUNCTION* PEOF
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* PO,PBYTE,PADR,LEAD
; DESTROYS* A,C,D,H,L,F/F'S
; DESCRIPTON* PEOF PUNCHES THE END OF FILE RECORD CONSISTING OF A RECO
; MARK, A LOAD ADDRESS OF 0, THE RECORD TYPE, AND THE
; RECORD CHECKSUM.
;
PEOF:
MVI C,':' ;
CALL PO ; PUNCH RECORD MARK
XRA A ; ZERO CHECKSUM
MOV D,A ; SAVE IN D REGISTER
CALL PBYTE ; PUNCH RECORD LENGTH
LXI H,0 ; LOAD HL WITH ZERO ADDRESS
CALL PADR ; PUNCH IT
MVI A,1 ; LOAD A WITH RECORD TYPE
CALL PBYTE ; PUNCH IT
XRA A ; ZERO A
SUB D ; COMPUTE CHECKSUM
CALL PBYTE ; PUNCH IT
CALL LEAD ; PUNCH TRAILER
RET
;
;
; *****************************************************************
;
;
; FUNCTION* PEOL
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* PO
; DESTROYS* C
; DESCRIPTION* PEOL PUNCHES A CARRIAGE RETURN AND LINE FEED ONTO
; PAPER TAPE.
;
PEOL:
MVI C,CR ;
CALL PO ; PUNCH CARRIAGE RETURN CHARACTER
MVI C,LF ;
CALL PO ; PUNCH LINE FEED CHARACTER
RET ;
;
;
;
; *****************************************************************
;
;
; FUNCTION: PO
; INPUTS* C -CHARACTER TO BE PUNCHED
; OUTPUTS* NONE
; CALLS* CO
; DESTROYS* NOTHING
; DESCRIPTION* PO PUNCHES THE CHARACTER SUPPLIED IN TH C REGISTER TO
; THE USER TELETYPEWRITER.
;
PO:
CALL CO ; CALL CONSOLE OUT TO PERFORM CHARACTER OUTPUT
RET
;
;
; *****************************************************************
;
;
; FUNCTION* PRVAL
; INPUTS* A - INTEGER, RANGE 0 TO F
; OUTPUTS* A - ASCII CHARACTER
; CALLS* NOTHING
; DESTROYS* NOTHING
; DESCRIPTION* PRVAL CONVERTS A NUMBER IN THE RANGE " TO F HEX TO
; THE CORRESPONDING ASCII CHARACTER, 0-9,A-F. PRVAL
; DOES NOT CHECK THE VALIDITY OF ITS INPUT ARGUMENT.
;
PRVAL:
ANI HCHAR ; MASK OUT UPPER 4 BITS -WANT 1 HEX CHAR
ADI 090H ; SET UP A SO THAT A-F CAUSE A CARRY
DAA ; ADJUST CONTENTS OF A REGISTER
ACI 040H ; ADD IN CARRY AND ADJUST UPPER 4 BITS
DAA ; ADJUST CONTENTS OF A REGISTER AGAIN
MOV C,A ; MOVE ASCII CHARACTER ·TO C
RET ; ALL DONE
;
;
; *****************************************************************
;
;
; FUNCTION* REGDS
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* ECHO,NMOUT,ERROR,CROUT
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* REGDS DISPLAYS THE CONTENTS OF THE REGISTER SAVE
; LOCATIONS, IN FORMATTED FORM, ON THE CONSOLE. THE
; DISPLAY IS DRIVEN FROM A TABLE, RTAB, WHICH CONTAINS
; THE REGISTER'S PRINT SYMBOL, SAVE LOCATION ADDRESS,
; AND LENGTH (8 OR 16 BITS).
;
REGDS:
LXI H,RTAB ; LOAD HL WITH ADDRESS OF START OF TABLE
REG05:
MOV C,M ; GET PRINT SYMBOL OF REGISTER
MOV A,C ;
ORA A ; TEST FOR 0 - END OF TABLE
JNZ REG10 ; IF NOT END, BRANCH
CALL CROUT ; ELSE, CARRIAGE RETURN/LINE FEED TO END
RET ; /DISPLAY
REG10:
CALL ECHO ; ECHO CHARACTER
MVI C,'=' ;
CALL ECHO ; OUTPUT EQUALS SIGN, I.E. A=
INX H ; POINT TO START OF SAVE LOCATION ADDRESS
MOV E,M ; GET LSP OF SAVE LOCATION ADDRESS TO E
MVI D,REGS SHR 8 ; PUT MSP OF SAVE LOC ADDRESS INTO D
INX H ; POINT TO LENGTH FLAG
LDAX D ; GET CONTENTS OF SAVE ADDRESS
CALL NMOUT ; DISPLAY ON CONSOLE
MOV A,M ; GET LENGTH FLAG
ORA A ; SET SIGN F/F
JZ REG15 ; IF 0, REGISTER IS 8 BITS
DCX D ; ELSE, 16 BIT REGISTER SO MORE TO DISPLAY
LDAX D ; GET LOWER 8 BITS
CALL NMOUT ; DISPLAY THEM
REG15:
MVI C,' ' ;
CALL ECHO ; OUTPUT BLANK CHARACTER
INX H ; POINT TO START OF NEXT TABLE ENTRY
JMP REG05 ; DO NEXT REGISTER
;
;
; *****************************************************************
;
;
; FUNCTION* REGSV
; INPUTS* NONE
; OUTPUTS* NONE
; CALLS* NONE
; DESTROYS* H,SP
; DESCRIPTION* REGSV SAVES THE USER REGISTERS ON INTERRUPT
;
REGSV:
SHLD LSAVE ; SAVE HL REGISTERS
POP H ; GET CALLING ADDRESS
XTHL ; EXCHANGE CALLER ADDR. WITH INT. PC
SHLD PSAVE ; ASSUME THIS IS THE LAST PROG COUNTER
PUSH PSW ; SAVE A,F/F'S
LXI H,4 ; SET HL TO 4 TO SAVE STACK POINTER CORRECTLY
DAD SP ; GET STACK POINTER VALUE
SHLD SSAVE ; SAVE USERS STACK POINTER
POP PSW ; RESTORE A,F/F'S
POP H ; CALLERS RETURN POINT
LXI SP,ASAVE+1 ; NEW VALUE FOR STACK POINTER
PUSH PSW ; SAVE THE REST OF THE REGISTERS
PUSH B ;
PUSH D ;
PCHL ; RETURN
;
;
; *****************************************************************
;
;
; FUNCTION* RGADR
; INPUTS* C - CHARACTER DENOTING REGISTER
; OUTPUTS* BC - ADDRESS OF ENTRY IN RTAB CORRESPONDING TO REGISTER
; CALLS* ERROR
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* RGADR TAKES A SINGLE CHARACTER AS INPUT. THIS CHARACTER
; DENOTES A REGISTER. RGADR SEARCHES THE TABLE RTAB
; FOR A MATCH ON THE INPUT ARGUMENT. IF ONE OCCURS,
; RGADR RETURNS THE ADDRESS OF THE ADDRESS OF THE
; SAVE LOCATION CORRESPONDING TO THE REGISTER. THIS
; ADDRESS POINTS INTO RTAB. IF NO MATCH OCCURS, THEN
; THE REGISTER IDENTIFIER IS ILLEGAL AND CONTROL IS
; PASSED TO THE ERROR ROUTINE.
;
RGADR:
LXI H,RTAB ; HL GETS ADDRESS OF TABLE START
LXI D,RTABS ; DE GET SIZE OF A TABLE ENTRY
RGA05:
MOV A,M ; GET REGISTER IDENTIFIER
ORA A ; CHECK FOR TABLE END (IDENTIFIER IS (0)
JZ ERROR ; IF AT END OF TABLE, ARGUMENT IS ILLEGAL
CMP C ; ELSE, COMPARE TABLE ENTRY AND ARGUMENT
JZ RGA10 ; IF EQUAL, WE'VE FOUND WHAT WE'RE LOOKING FOR
DAD D ; ELSE, INCREMENT TABLE POINTER TO NEXT ENTRY
JMP RGA05 ; TRY AGAIN
RGA10:
INX H ; IF A MATCH, INCREMENT TABLE POINTER TO
MOV B,H ; /SAVE LOCATION ADDRESS
MOV C,L ; RETURN THIS VALUE
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION* RI
; INPUTS* NONE
; OUTPUTS* A - ZERO, CARRY - 1 IF END OF FILE
; A - CHARACTER, CARRY - 0 IF VALID CHARACTER
; CALLS* DELAY
; DESTROYS* A,F/F'S
; DESCRIPTION* RI READS A CHARACTER FROM THE TTY TAPE READER.
;
RI:
PUSH B ; SAVE BC
RI05:
IN CNCTL ; READ IN USART STATUS
ANI TXBE ; CHECK FOR TRANSMITTER BUFFER EMPTY
JZ RI05 ; TRY AGAIN IF NOT EMPTY
MVI A,TTYADV ; ADVANCE THE TAPE
OUT CNCTL ; OUTPUT THE ADVANCE COMMAND
MVI B,40 ; INITIALIZE TIMER FOR 40 MS.
RI07:
CALL DELAY ; DELAY FOR 1 MILLISECOND
DCR B ; DECREMENT TIMER
JNZ RI07 ; JUMP IF TIMER NOT EXPIRED
MVI A,TTYSTP ; STOP THE READER COMMAND
OUT CNCTL ; OUTPUT STOP COMMAND
MVI B,250 ; INITIALIZE TIMER FOR 250 MS.
RI10:
IN CONST ; INPUT READER STATUS
ANI RBR ; CHECK FOR RECEIVER BUFFER READY
JNZ RI15 ; YES - DATA IS READY
CALL DELAY ; DELAY 1 MS
DCR B ; DECREMENT TIMER
JNZ RI10 ; JUMP IF TIMER NOT EXPIRED
XRA A ; ZERO A
STC ; SET CARRY INDICATING EOF
POP B ; RESTORE BC
RET ; RETURN TO CALLING ROUTINE
RI15:
IN CNIN ; INPUT DATA CHARACTER
ORA A ; CLEAR CARRY
POP B ; RESTORE BC
RET ; RETURN TO CALLING ROUTINE
;
;
; *****************************************************************
;
;
; FUNCTION* RICH
; INPUTS* NONE
; OUTPUTS* A - ZERO, CARRY - 1 IF END OF FILE
; A - CHARACTER, CARRY - 0 IF VALID CHARACTER
; CALLS* RI
; DESTROYS* A,F/F'S
; DESCRIPTION* RICH TESTS FOR AN END OF FILE CONDITION.
;
RICH:
CALL RI ; READ A CHARACTER FROM TAPE
JC ERROR ; JUMP IF READER TIMEOUT ERROR
ANI PRTY0 ; REMOVE PARITY BIT
RET ; RETURN TO CALLING ROUTINE
;
;
; *****************************************************************
;
;
; FUNCTION* RSTTF
; INPUTS* A = 0, NOT SINGLE STEP EXECUTION
; A = 0FFH, SINGLE STEP EXECUTION
; OUTPUTS* NONE
; CALLS* NOTHING
; DESTROYS* A,B,C,D,E,H,L,F/F'S
; DESCRIPTION* RSTTF RESTORES ALL CPU REGISTER, FLIP/FLOPS, STACK
; POINTER AND PROGRAM COUNTER FROM THEIR RESPECTIVE
; SAVE LOCATIONS IN MEMORY. THE ROUTINE THEN TRANSFERS
; CONTROL TO THE LOCATION SPECIFIED BY THE PROGRAM
; COUNTER (I.E. THE RESTORED VALUE). THE ROUTINE
; EXITS WITH THE INTERRUPTS ENABLED.
;
RSTTF:
DI ; DISABLE INTERRUPTS
PUSH PSW ; SAVE A REGISTER
MVI A,C0M0 ; RESET SINGLE STEP TIMER
OUT TMCP
POP PSW ; RESTORE A REGISTER
LXI SP,MSTAK ; SET MONITOR STACK POINTER TO START
; OF STACK
POP D ; START ALSO END OF REGISTER SAVE AREA
POP B
LHLD SSAVE ; RESTORE USER STACK POINTER
SPHL
LHLD FSAVE ; GET A,F/F'S
PUSH H ; SAVE THEM
ANA A ; CHECK FOR SINGLE STEP
JZ RSTDN ; NO, DONE
MVI A,LSVC0 ; YES, LOAD TIMER
OUT CTR0
MVI A,MSVC0
OUT CTR0
RSTDN: POP PSW ; RESTORE A,F/F'S
LHLD PSAVE
PUSH H ; PUT USER RETURN ADDRESS ON USER STACK
LHLD LSAVE ;RESTORE HL REGISTER
EI ; ENABLE ALL (5) INTERRUPTS.
RET ; JUMP TO RESTORED PC LOCATION
;
;
; *****************************************************************
;
;
; FUNCTION* SRET
; INPUTS* NONE
; OUTPUTS* CARRY = 1
; CALLS* NOTHING
; DESTROYS* CARRY
; DESCRIPTION* SRET IS JUMPED TO BY ROUTINES WISHING TO RETURN SUCCESS.
; SRET SETS THE CARRY TRUE AND THEN RETURNS TO THE
; CALLER OF THE ROUTINE INVOKING SRET.
;
SRET:
STC ; SET CARRY TRUE
RET ; RETURN APPROPRIATELY
;
;
; *****************************************************************
;
;
; FUNCTION* STHF0
; INPUTS* DE - 16 BIT ADDRESS OF BYTE TO BE STORED INTO
; OUTPUTS* NONE
; CALLS* NOTHING
; DESTROYS* A,B,C,H,L,F/F'S
; DESCRIPTION* STHF0 CHECKS THE HALF BYTE FLAG IN TEMP TO SEE IF
; IT IS SET TO LOWER. IF SO, STHF0 STORES A 0 TO
; PAD OUT THE LOWER HALF OF THE ADDRESSED BYTE
; OTHERWISE, THE ROUTINE TAKES NO ACTION.
;
STHF0:
LDA TEMP ; GET HALF BYTE FLAG
ORA A ; SET F/F'S
RNZ ; IF SET TO UPPER, DON'T DO ANYTHING
MVI C,0 ; ELSE, WANT TO STORE THE VALUE 0
CALL STHLF ; DO IT
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION* STHLF
; INPUTS* C - 4 BIT VALUE TO BE STORED IN HALF BYTE
; DE - 16 BIT ADDRESS OF BYTE TO BE STORED INTO
; OUTPUTS* NONE
; CALLS* NOTHING
; DESTROYS*A,B,C,H,L,F/F'S
; DESCRIPTION* STHLF TAKES THE 4 BIT VALUE IN C AND STORES IT IN
; HALF OF THE BYTE ADDRESSED BY REGISTERS DE. THE
; HALF BYTE USED (EITHER UPPER OR LOWER) IS DENOTED
; BY THE VALUE OF THE FLAG IN TEMP. STHLF ASSUMES
; THAT THIS FLAG HAS BEEN PREVIOUSLY SET
; (NOMINALLY BY ICMD).
;
STHLF:
PUSH D ;
POP H ; MOVE ADDRESS OF BYTE INTO HL
MOV A,C ; GET VALUE
ANI 0FH ; FORCE TO 4 BIT LENGTH
MOV C,A ; PUT VALUE BACK
LDA TEMP ; GET HALF BYTE FLAG
ORA A ; CHECK FOR LOWER HALF
JNZ STH05 ; BRANCH IF NOT
MOV A,M ; ELSE, GET BYTE
ANI 0F0H ; CLEAR LOWER 4 BITS
ORA C ; OR IN VALUE
MOV M,A ; PUT BYTE BACK
RET ;
STH05:
MOV A,M ; IF UPPER HALF, GET BYTE
ANI 0FH ; CLEAR UPPER 4 BITS
MOV B,A ; SAVE BYTE IN B
MOV A,C ; GET VALUE
RRC ;
RRC ;
RRC ;
RRC ; ALIGN TO UPPER 4 BITS
ORA B ; OR IN ORIGINAL LOWER 4 BITS
MOV M,A ; PUT NEW CONFIGURATION BACK
RET ;
;
;
; *****************************************************************
;
;
; FUNCTION* VALDG
; INPUTS* C - ASCII CHARACTER
; OUTPUTS* CARRY - 1 IF CHARACTER REPRESENTS VALID HEX DIGIT
; - 0 OTHERWISE
; CALLS* NOTHING
; DESTROYS* A,F/F'S
; DESCRIPTION* VALDG RETURNS SUCCESS IF ITS INPUT ARGUMENT IS
; AN ASCII CHARACTER REPRESENTING A VALID HEX DIGIT
; (0-9,A-F), AND FAILURE OTHERWISE.
;
VALDG:
MOV A,C ;
CPI '0' ; TEST CHARACTER AGAINST '0'
JM FRET ; IF ASCII CODE LESS, CANNOT BE VALID DIGIT
CPI '9' ; ELSE, SEE IF IN RANGE '0'-'9'
JM SRET ; CODE BETWEEN '0' AND '9'
JZ SRET ; CODE EQUAL '9'
CPI 'A' ; NOT A DIGIT - TRY FOR A LETTER
JM FRET ; NO - CODE BETWEEN '9' AND 'A'
CPI 'G' ;
JP FRET ; NO - CODE GREATER THAN 'F'
JMP SRET ; OKAY - CODE IS 'A' TO 'F', INCLUSIVE
;
;
; *****************************************************************
;
;
; FUNCTION* VALDL
; INPUTS* C - CHARACTER
; OUTPUTS* CARRY - 1 IF INPUT ARGUMENT VALID DELIM'fER
; - 0 OTHERWISE
; CALLS* NOTHING
; DESTROYS* A,F/F'S
; DESCRIPTION* VALDL RETURNS SUCCESS IF ITS INPUT ARGUMENT IS A VALID
; DELIMITER CHARACTER (SPACE, COMMA, CARRIAGE RETURN,
; AND LINE FEED) FAILURE OTHERWISE.
;
VALDL:
MOV A,C ;
CPI ',' ; CHECK FOR COMMA
JZ SRET ;
CPI CR ; CHECK FOR CARRIAGE RETURN
JZ SRET ;
CPI ' ' ; CHECK FOR SPACE
JZ SRET ;
JMP FRET ; ERROR IF NONE OF THE ABOVE
;
;
; *****************************************************************
;
;
; MONITOR TABLES
;
;
; *****************************************************************
;
;
SGNON:
DB CR, LF, '80/20 MONITOR V 1.2', CR, LF
LSGNON EQU $-SGNON ; LENGTH OF SIGNON MESSAGE
;
;
;
CADR: ; TABLE OF ADDRESSES OF COMMAND ROUTINES
DW 0 ; DUMMY
DW NCMD ;
DW XCMD ;
DW SCMD ;
DW MCMD ;
DW ICMD ;
DW GCMD ;
DW DCMD ;
DW RCMD ;
DW WCMD ;
;
CTAB: ; TABLE OF VALID COMMAND CHARACTERS
DB 'W' ;
DB 'R' ;
DB 'D' ;
DB 'G' ;
DB 'I' ;
DB 'M' ;
DB 'S' ;
DB 'X' ;
DB 'N' ;
NCMDS EQU $-CTAB ; NUMBER OF VALID COMMANDS
;
;
RTAB: ; TABLE OF REGISTER INFORMATION
DB 'A' ; REGISTER IDENTIFIER
DB ASAVE AND 0FFH ; ADDRESS OF REGISTER SAVE LOCATION
DB 0 ; LENGTH FLAG - 0=8 BITS, 1=16 BITS
RTABS EQU $-RTAB ; SIZE OF AN ENTRY IN THIS TABLE
DB 'B' ;
DB BSAVE AND 0FFH ;
DB 0 ;
DB 'C' ;
DB CSAVE AND 0FFH ;
DB 0 ;
DB 'D' ;
DB DSAVE AND 0FFH ;
DB 0 ;
DB 'E' ;
DB ESAVE AND 0FFH ;
DB 0 ;
DB 'F' ;
DB FSAVE AND 0FFH ;
DB 0 ;
DB 'H' ;
DB HSAVE AND 0FFH ;
DB 0 ;
DB 'L' ;
DB LOW (LSAVE) ;
DB 0 ;
DB 'M' ;
DB HSAVE AND 0FFH ;
DB 1 ;
DB 'P' ;
DB PSAVE+1 AND 0FFH ;
DB 1 ;
DB 'S' ;
DB SSAVE+1 AND 0FFH ;
DB 1 ;
DB 0 ; END OF TABLE MARKERS
DB 0
;
;
; *****************************************************************
;
;
;
; THE FOLLOWING JUMP TABLE IS TO BE USED WITH THE
; INTERRUPT CONTROLLER. THE CONTROLLER HAS BEEN INITIALIZED
; TO CALL THIS TABLE WHEN AN INTERRUPT IS ACKNOWLEDGED.
; THIS TABLE IS MOVED TO RAM DURING MONITOR INITIALIZATION.
; THE JUMP SHOULD BE TO AN INTERRUPT SERVICE ROUTINE.
;
;
JPTB:
JMP INTIN ; --- FOR LEVEL 0
NOP ; FILLER
JMP INTIN ; --- FOR LEVEL 1
NOP ; FILLER
JMP STEPIN ; --- FOR LEVEL 2
NOP ; FILLER
JMP INTIN ; --- FOR LEVEL 3
NOP ; FILLER
JMP INTIN ; --- FOR LEVEL 4
NOP ; FILLER
JMP INTIN ; --- FOR LEVEL 5
NOP ; FILLER
JMP INTIN ; --- FOR LEVEL 6
NOP ; FILLER
JMP INTIN ; --- FOR LEVEL 7
;
;
; *****************************************************************
;
;
ORG REGS ; ORG TO REGISTER SAVE - STACK GOES IN HERE
;
MSTAK EQU $ ; START OF MONITOR STACK
ESAVE:
DB 0 ; E REGISTER SAVE LOCATION
DSAVE:
DB 0 ; D REGISTER SAVE LOCATION
CSAVE:
DB 0 ; C REGISTER SAVE LOCATION
BSAVE:
DB 0 ; B REGISTER SAVE LOCATION
FSAVE:
DB 0 ; FLAGS SAVE LOCATION
ASAVE:
DB 0 ; A REGISTER SAVE LOCATION
LSAVE:
DB 0 ; L REGISTER SAVE LOCATION
HSAVE:
DB 0 ; H REGISTER SAVE LOCATION
PSAVE:
DW 0 ; PGM COUNTER SAVE LOCATION
SSAVE:
DW 0 ; USER STACK POINTER SAVE LOCATION
TEMP:
DB 0 ; TEMPORARY MONITOR CELL
;
;
END