$ 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