home *** CD-ROM | disk | FTP | other *** search
- ; TITLE 'UPG80 MONITOR SPECIAL SYSTEM VERSION 3-1 31/8/79'
- ;
- ;**** FOR S100 SYSTEMS WITH JADE I/O BOARDS.
- ;
- ;
- ;*************************************************************
- ;
- ; UPG80 MONITOR :-
- ; MODIFIED VERSION OF AMSAT'S AMS80 V2:0 MONITOR
- ; BY H.J.HARVEY
- ;
- ; THIS MONITOR IS A MINIMUM 8080 SYSTEM MONITOR TO PROVIDE
- ; THE BASIC STRUCTURE NECESSARY FOR 8080 DEBUG AND CONTROL.
- ;
- ; THE ROUTINES ALLOW FOR MEMORY EXAMINE AND MODIFY,
- ; TARGET PROGRAM BREAKPOINTING UNDER MONITOR CONTROL,
- ; USER INTERRUPTS OR RST VECTORS (RST3-RST7),
- ; SIMPLE ASSEMBLY AND DISASSEMBLY, INPUT AND OUTPUT,
- ; AND PROVIDE VARIOUS TELETYPE SUPPORT ROUTINES TO LOAD
- ; AND DUMP MEMORY IN STANDARD 8080 HEX-BINARY.
- ;
- ; THE MONITOR INCLUDES AN EXTENSIVE VECTOR TABLE STARTING
- ; AT (ROM-ORIGIN + 40H) TO ALLOW USER ACCESS TO A NUMBER
- ; OF USEFUL SPECIFIC ROUTINES.
- ;
- ;*************************************************************
- ;
- ; DEFINE CONSOLE CONTROL CHRS
- ;
- CR EQU 0DH ;ASCII CARRIAGE-RETURN
- LF EQU 0AH ;ASCII LINE-FEED
- ;
- ; THE FOLLOWING EQUATES ARE USED TO DEFINE THE COLUMN WIDTH
- ; OF THE DISPLAY CONSOLE.
- ; 'R' COMMAND NEEDS 58 COLUMNS FOR A 1-LINE DISPLAY
- ; 'D' COMMAND NEEDS 53 COLUMNS FOR 16-BYTE DISPLAY
- ; 'P' COMMAND NEEDS 43 COLUMNS FOR 16-BYTE GROUP
- ; COLSW=1 IF MONITOR <58 COLUMNS/LINE
- ; COLSW=0 IF MONITOR >57 COLUMNS/LINE
- ;
- COLSW EQU 0
- ;
- IF NOT COLSW
- ;
- ; 58+ COLUMN CONSTANTS
- ;
- OSET EQU 16 ;16 BYTES PER LINE
- ENDIF
- IF COLSW
- ;
- ; <58 COLUMN CONSTANTS
- ;
- OSET EQU 8 ;8 BYTES PER LINE
- ENDIF
- ;
- ;
- ;
- ; THE FOLLOWING EQUATES ARE DESIGNED FOR CONSOLE CONTROL
- ; OF THE S100 CARD-SET WITH JADE SPI/O BOARDS.
- ; ER SYSTEMS WILL REQUIRE DIFFERENT EQUATES, DEPENDING
- ; UPON THE SELECTION OF I/O PORTS AND CONTROL SETUPS.
- ;
- CNCTL EQU 081H ;SYSTEM I/O CONSTANTS
- CONST EQU 081H
- CNIN EQU 001H
- CNOUT EQU 001H
- CSCTL EQU 080H ;CASSETTE CONTROL
- CSST EQU 080H ;CASSETTE STATUS CHANNEL
- CSIN EQU 000H ;CASSETTE INPUT PORT
- CSOUT EQU 000H ;CASSETTE OUTPUT PORT
- MODE EQU 0FFH ;MM5303 UART MODE SELECT
- TRDY EQU 080H ;TRANSMIT READY BIT
- RBR EQU 010H ;READER READY BIT
- TMOUT EQU 10000 ;10000 MILLISECOND (10 SECS) TIMEOUT
- ONEMS EQU 130 ;CONSTANT FOR 1 MILLISECOND LOOP (F/N DELAY)
- RAM EQU 03F00H ;START OF 256 BYTE RAM.
- ;
- ; ROM AND RAM AREAS CAN NOW BE DEFINED.
- ;
- ROMSW EQU 1 ;ROMSW=1 IF ROM > 0 , OTHERWISE ROMSW=0
- ROM EQU 08000H ;ROM STARTS HERE
- REGS EQU RAM+256-48 ;REGISTER STORE (IN RAM) STARTS HERE
- STACK EQU REGS ;TOP OF STACK INITIALIZE
- ;
- ; START OF SYSTEM
- ;
- ORG ROM
- ;
- ; SET UP SERIAL DATA MODE.
- ;
- PART1:
- DI ;DISABLE ALL INTERRUPTS.
- MVI A,MODE ;SERIAL I/O MODE.
- JMP PART2
- DW RAM
- ;
- ; EXECUTIVE ENTRY ON RST1
- ; THIS ENTRY POINT IS USED WHENEVER AN RST1 (CODE CF)
- ; IS EXECUTED.
- ;
- EXEC:
- SHLD SVHL ;SAVE HL
- POP H ;POP THE CALL ADDRESS INTO HL
- RAR ;PUT CARRY INTO B7 OF ACC
- JMP BEGIN ;GO ON NOW.
- ;
- ; BREAKPOINT SERVICING INPUT AS RESULT OF 'RST 2'
- ; ROUTINE BPAT IS CALLED TO LET THE USER KNOW.
- ;
- BPIN:
- SHLD SVHL ;SAVE HL
- POP H ;GRAB BREAKPOINT ADDRESS
- RAR ;ROTATE RIGHT PUTS CARRY INTO ACC B7
- JMP BPAT ;GO SERVICE IT.
- ;
- ; DEFINE USER INT/SR VECTORS
- ; RST3 THROUGH RST7 MAY BE USED EITHER AS HARDWARE
- ; OR SOFTWARE INTERRUPT VECTORS.
- ; THE ORRESPONDING ADDRESS FOR SERVICE MUST BE
- ; SET UP IN THE APPROPRIATE LOCATIONS IN RAM.
- ; THESE ADDRESSES CAN BE FOUND BY REFERENCE TO THE LABELS
- ; RST3 - RST7 AT THE END OF THIS MONITOR.
- ;
- ;**** NOTE THAT THESE CODE GROUPS ARE TO BE LINKED FROM RAM
- ; IN PAGE ZERO IF THE MONITOR IS NOT ZERO ORGED.
- ;
- RS3:
- PUSH H ;SAVE HL
- LHLD RST3 ;FETCH USER VECTOR
- XTHL ;PUT ON STACK RESTORING HL
- RET ;GO TO USER
- DW ROM ;PAD - ROM START ADDRESS
- RS4:
- PUSH H ;SAVE HL
- LHLD RST4 ;FETCH USER VECTOR
- XTHL ;PUT ON STACK RESTORING HL
- RET ;GO TO USER
- DW RAM ;PAD - RAM START ADDRESS
- RS5:
- PUSH H ;SAVE HL
- LHLD RST5 ;FETCH USER VECTOR
- XTHL ;PUT ON STACK RESTORING HL
- RET ;GO TO USER
- DW REGS ;PAD - END OF REG STORE (ALSO T.O.S.)
- RS6:
- PUSH H ;SAVE HL
- LHLD RST6 ;FETCH USER VECTOR
- XTHL ;PUT ON STACK RESTORING HL
- RET ;GO TO USER
- DW SVA ;PAD - START OF REG STORE.
- RS7:
- PUSH H ;SAVE HL
- LHLD RST7 ;FETCH USER VECTOR
- XTHL ;PUT ON STACK RESTORING HL
- RET ;GO TO USER
- DW ENDROM ;PAD - END OF ROM DATA
- ;
- ; MONITOR SUPPORT SR VECTORS
- ; USER UTILITY SR'S
- ;
- ; THE FOLLOWING SET OF JUMPS ARE PROVIDED SOTHAT USER
- ; PROGRAMS CAN REFERENCE COMMON ENTRY POINTS TO THE VARIOUS
- ; ROUTINES. THESE LOCATIONS WILL REMAIN CONSTANT WHILE THE
- ; ACTUAL LOCATION OF EACH ROUTINE MAY CHANGE AS DIFFERENT
- ; MONITOR REVISIONS OCCUR.
- ;
- ; THE CALLING SEQUENCE FOR EACH SUBROUTIN EMAINS THE
- ; SAME AS DEFINED IN THE LISTING, WITH ONLY A SLIGHT EXECUTION
- ; TIME OVERHEAD DUE TO THE EXTRA JUMP.
- ;
- ZTYPE: JMP TYPE ;TYPE CHR IN 'A'
- ZGETCH: JMP GETCH ;GET CHR IN 'A' (PARITY, NO ECHO)
- ZCHIN: JMP CHIN ; " " " " (ECHO, NO PARITY)
- ZCHINX: JMP CHINX ; " " " " (ECHO/NO ECHO, NO PARITY)
- ZMSG: JMP MSG ;TYPE MESSAGE, PTR IN HL. TERM 0FFH
- ZCRLF: JMP CRLF ;TYPE CR/LF
- ZSPACE: JMP BLANK ;TYPE " "
- ZTHXN: JMP THXN ;TYPE HEX 'A' B3-B0
- ZTHXB: JMP THXB ; " " " " B7-B0
- ZTHXW: JMP THXW ; " " " 'HL'
- ZGHXN: JMP GHXN ;GET HEX 'A' B3-B0
- ZGHXB: JMP GHXB ; " " " B7-B0
- ZGHXW: JMP GHXW ; " " 'HL'
- ZSTORE: JMP STORE ;STORE A IN (HL) AND CHECK
- ZNEGDE: JMP NEGDE ;NEGATE DE REG
- ZPWAIT: JMP PWAIT ;TYPE 'PAUSE' THEN AWAIT ANY CHR
- ZOKQ: JMP OKQ ;TYPE 'OK?', AWAIT CHR, CONTINUE IF ' '
- ZECHO: JMP ECHCN ;ECHO CONTROL (A=0 MEANS OFF)
- ZCNVBN: JMP CNVBN ;CONVERT CHARACTER TO BINARY NYBBLE.
- ZCSTS: JMP CSTS ;LOOK FOR CONSOLE K/B STRIKE.
- ;
- ; UART INITIALIZATION CODE: PART 2.
- ; SEND OUT THE COMMAND WORD.
- ;
- PART2:
- OUT CSCTL ;SET UP CASSETTE I/O
- OUT CNCTL ;AND CONSOLE I/O.
- ;
- ; ZERO OUT THE CURRENT ADDRESS FOR BREAKPOINT.
- ; (NECESSARY TO ALLOW UPDATING)
- ;
- LXI H,0 ;LOAD 16 BIT ZERO
- SHLD BPADD ;PUT ALL ZEROS IN BPADD
- ;
- ; BEGIN MONITOR.
- ; ENTER HERE FOLLOWING A HARDWARE/SOFTWARE RST1
- ;
- BEGIN:
- SHLD SVPC ;STORE CALLING PC
- STA TMPA ;AND CARRY (IN B7)
- RAL ;THEN ROTATE BACK THE ACC.
- LXI H,0 ;NOW TRANSFER THE SP TO HL BY DOING A DUMMY
- DAD SP ;ADD TO HL. (N.B. CLEARS CARRY)
- SHLD SVSP ;SAVE THE CALLER SP.
- LXI SP,SVA+1 ;PICK UP REG STORE POINTER
- PUSH PSW ;TO SAVE PSW
- PUSH B ;AND BC
- PUSH D ;AND DE. (HL ALREADY SAVED)
- LXI H,SVF ;GET THE PSB BYTE
- LDA TMPA ;PICK UP THE CARRY HOLDER,
- RAL ;ROTATE IT BACK TO CARRY.
- JNC BGN1 ;SKIP IF CARRY NOT SET,
- INR M ;OTHERWISE RESET CARRY.
- BGN1:
- LXI H,M0 ;TYPE MONITOR ENTRY MESSAGE
- JMP NEXT1
- ;
- ; NEXT MONITOR COMMAND PLEASE.
- ; ENTER HERE WHENEVER A NEW COMMAND IS EXPECTED.
- ;
- NEXT:
- LXI H,M1 ;TYPE PROMPT MESSAGE
- NEXT1:
- LXI SP,STACK ;SET STACK POINTER FIRST.
- CALL MSG
- CALL CHIN ;GET COMMAND CHARACTER INTO 'A'
- MOV B,A ;AND SAVE IT IN 'B'
- ;
- ; SEARCH OP TABLE
- ; (IF CALLING COMMAND BYTE IS REQUIRED, IT IS IN 'B')
- ;
- LXI H,OPTAB ;HEAD-OF-TABLE VECTOR
- SUI 'A' ;REDUCE CODE TO OFFSET
- CPI 1AH ;SEE IF IT EXCEEDS 'Z' COMMAND.
- JNC TEND ;IF SO, MAY HAVE BEEN SPECIAL.
- ADD A ;ALL O.K. MULTIPLY BY 2 (2 BYTES PER ADDR)
- MOV E,A ;PUT VALUE*2 INTO E
- MVI D,0 ;AND GET ZERO TO CLEAR 'D'
- DAD D ;ADD OFFSET TO HL (ADDRESS REQUIRED AT <HL>)
- MOV E,M ;GET LOWER BYTE OF REQUIRED ADDR
- INX H ;AND THEN GET THE UPPER
- MOV D,M ;BYTE BEFORE TRANSFERRING
- XCHG ;IT TO HL.
- PCHL ;FINALLY JUMP TO ROUTINE CALLED.
- ;
- ; OPERATION ADDRESS TABLE.
- ; CONTAINS AN ADDRESS DESTINATION FOR EACH CHARACTER OF THE
- ; ALPHABET (A-Z IN ASCENDING ORDER.)
- ;
- OPTAB:
- DW GETAD ;A - GET ADDRESS
- DW BPT ;B - BREAKPOINT SETTER/CLEARER
- DW CONT ;C - CONTINUE AFTER B/P
- DW DISP ;D - DISPLAY MEMORY DATA
- DW PEND ;E - END OF FILE PUNCH
- DW FILL ;F - FILL MEMORY WITH DATA
- DW GOTO ;G - PROGRAM GO: NO REGISTER RESTORE.
- DW ASM80 ;H - LINE ASSEMBLER
- DW INPT ;I - INPUT PORT DATA
- DW JUMP ;J - PROGRAM JUMP: REGISTER RESTORE.
- DW KOMP ;K - K(C)OMPARE MEMORY AREAS
- DW LOAD ;L - LOAD HEX-BINARY TAPE
- DW MOVE ;M - MOVE MEMORY BLOCK
- DW NULL ;N - PUNCH NULL BLOCK
- DW OUTPT ;O - OUTPUT PORT DATA.
- DW PUNCH ;P - PUNCH HEX-BINARY DATA
- DW ILLEG
- DW REGEX ;R - REGISTER EXAMINE/MODIFY
- DW SEARCH ;S - SEARCH MEMORY FOR BYTE
- DW ILLEG
- DW USER ;U - USER DEFINE/USE
- DW ILLEG
- DW ILLEG
- DW GETXA ;X - SET UP XEQ ADDRESS
- DW DIS80 ;Y - 8080 DISASSEMBLY.
- DW ZERO ;Z - ZERO OUT MEMORY
- ;
- ; N.B. COMMANDS <CR> <LF> . AND - ARE CHECKED
- ; BY ROUTINE 'TEND'
- ;
- ;
- ; INPUT ONE CHR AND STRIP PARITY
- ; ALTERNATIVE ENTRY POINTS ARE:-
- ;
- ; CALL CHIN
- ; .... ;RESULT IN 'A'
- ; THE INPUT IS ECHO'D IF DATA IS PRINTABLE.
- ;
- ; MVI A,XX ;XX=0 NO ECHO.
- ; CALL CHINX
- ; .... ;RESULT IN 'A'
- ; ECHO CONTROLLED EACH CALL.
- ;
- ; CALL CHINN
- ; .... ;RESULT IN 'A'
- ; ECHO CONTROLLED BY PREVIOUS 'CALL ECHCN'
- ;
- CHIN:
- MVI A,0FFH ;SET ECHO FLAG ON
- CHINX:
- CALL ECHCN ;CALL THE CONTROLLER.
- CHINN:
- CALL GETCH ;GET CHARACTER FROM CONSOLE,
- ANI 7FH ;STRIP ANY PARITY
- PUSH PSW ;SAVE DATA
- LDA ECHO ;SEE IF ECHO REQU'D
- ANA A ;THIS INSTRUCTION SIMPLY SETS FLAGS
- JNZ CHN1 ;TEST FOR ZERO/NON-ZERO CONTROL
- POP PSW ;NO ECHO. SIMPLY RETURN
- RET
- CHN1:
- POP PSW ;GET DATA AND ECHO
- CPI ' ' ;IF NOT CONTROL CHR
- CNC TYPE
- RET ;BEFORE RETURNING
- ;
- ; MESSAGE PRINT
- ; ALLOWS USER TO PRINT A MESSAGE ON THE CONSOLE OUTPUT
- ; BY HAVING A STRING OF CHARACTERS FOLLOWED
- ; BY DELIMITING 0FFH (-1)
- ;
- ; CALLING SEQUENCE:-
- ; LXI H,ADDRESS
- ; CALL MSG
- ; ....
- ;
- MSG:
- PUSH PSW ;SAVE PSW
- PUSH H ;AND HL
- MNXT:
- MOV A,M ;GET NEXT BYTE
- INX H ;BUMP BYTE POINTER.
- CPI 0FFH ;CHECK FOR 0FFH (-1) TERMINATOR
- CNZ TYPE ;NO. TYPE IT
- JNZ MNXT ;NOW READY FOR ANOTHER TRY
- POP H ;MESSAGE FINISHED. RESTORE HL
- POP PSW ;AND PSW
- RET ;BEFORE GOING HOME
- ;
- ; TYPE CR/LF
- ; (THE EASY WAY TO START A NEW LINE)
- ;
- ; CALLING SEQUENCE:-
- ; CALL CRLF
- ; ....
- ;
- CRLF:
- PUSH H ;SAVE HL
- LXI H,M2 ;GET CR/LF MESSAGE
- CALL MSG ;TYPE MESSAGE
- POP H ;RESTORE HL
- RET ;RETURN
- ;
- ;
- ; TYPE ONE SPACE
- ;
- ; CALLING SEQUENCE:-
- ; CALL BLANK
- ; ....
- ;
- BLANK:
- PUSH PSW ;SAVE PSW
- MVI A,' ' ;GET SPACE
- CALL TYPE ;TYPE IT
- POP PSW ;RESTORE PSW
- RET ;THEN RETURN
- ;
- ; TYPE 'A' IN HEX
- ; OUTPUTS THE 2-BIT HEX VALUE OF ACCUMULATOR
- ; TO CONSOLE
- ;
- ; CALLING SEQUENCE:-
- ; LDA DATA
- ; CALL THXB
- ; ....
- ;
- THXB:
- PUSH PSW ;SAVE PSW
- RRC ;SHIFT THE LEFT NYBBLE
- RRC ;INTO THE RIGHT NYBBLE
- RRC ;BY DOING 4 ROTATE RIGHTS.
- RRC
- CALL THXN ;TYPE HEX NYBBLE
- POP PSW ;RESTORE DATA
- ;
- ; TYPE 'A' B3-B0 IN ASCII
- ; TYPES THE 1-BIT HEX VALUE OF THE BOTTOM 4 BITS
- ; OF ACCUMULATOR.
- ;
- ; CALLING SEQUENCE:-
- ; LDA DATA
- ; CALL THXN
- ; ....
- ;
- THXN:
- PUSH PSW ;SAVE PSW
- ANI 0FH ;ISOLATE B3-B0 (THROW AWAY B7-B4)
- ADI 090H ;ADJUST
- DAA ;NOW
- ACI 040H ;TO
- DAA ;ASCII
- CALL TYPE ;BEFORE TYPING
- POP PSW ;RESTORE PSW
- RET ;THEN RETURN
- ;
- ;
- ; TYPE A WORD IN HEX
- ; TYPES THE 4-BIT HEX VALUE OF THE 16-BIT VALUE
- ; HELD IN THE HL REGISTER PAIR.
- ;
- ; CALLING SEQUENCE:-
- ; LHLD WORD
- ; CALL THXW
- ; ....
- ;
- THXW:
- PUSH PSW ;SAVE PSW
- MOV A,H ;GET HIGH BYTE FROM 'H'
- CALL THXB ;AND TYPE IT
- MOV A,L ;GET LOW BYTE FROM 'L' AND
- CALL THXB ;TYPE IT TOO.
- POP PSW ;RESTORE PSW
- RET ;I'M GOIN HOME
- ;
- ; GET HEX CHR FROM CONSOLE
- ; ROUTINE TO GET A SINGLE HEX NYBBLE FROM THE CONSOLE
- ; IF THE DIGIT IS VALID (I.E. 0-9,A-F) THEN THE BINARY
- ; VALUE IS RETURNED IN 'A' AND THE CARRY IS RESET.
- ;
- ; HOWEVER, IF THE RESULT IS NON-HEX, THE BAD CHARACTER
- ; WILL BE IN 'A' AND CARRY WILL BE SET.
- ;
- ; CALLING SEQUENCE:-
- ; CALL GHXN
- ; JC NONHX ;ERROR IF CARRY SET
- ;
- GHXN:
- MVI A,0FH ;MASK TO KEEP ONLY THE RIGHT NYBBLE
- JMP GHB1
- ;
- ; GET HEX BYTE FROM CONSOLE
- ; SIMILAR TO GHXN, BUT RETURNS BYTE VALUE IF O.K.
- ;
- ; CALLING SEQUENCE:-
- ; CALL GHXB
- ; JC NONHX ;CHECK NO HEX I/P
- ;
- GHXB:
- MVI A,0FFH ;MASK TO KEEP WHOLE BYTE.
- GHB1:
- PUSH H ;SAVE HL
- CALL GHXW ;GET HEX DATA VIA GHXW
- JC GHB2 ;PROVIDED THERE HAS BEEN NO ERROR,
- ANA L ;WE CAN MASK THE NYBBLE/BYTE.
- GHB2:
- POP H ;RESTORE HL
- RET ;RETURN TO CALLER
- ;
- ; GET HEX WORD FROM CONSOLE
- ; SIMILAR TO GHXN, BUT RETURNS BINARY WORD (16-BIT)
- ; IN HL REG PAIR IF O.K.
- ;
- ; CALLING SEQUENCE:-
- ; CALL GHXW
- ; JC NONHX ;TEST NON HEX I/P
- ; .... ;RESULT IN HL
- ;
- GHXW:
- PUSH PSW ;SAVE PSW
- LXI H,0 ;ZERO OUT THE HL STORE
- CALL CHINN ;GET FIRST CHARACTER, CONTROLLED ECHO
- CALL CNVBN ;CONVERT IT TO BINARY NYBBLE
- JC GHW3 ;ANY NON-HEX IS ERROR FIRST TIME.
- MOV L,A ;SAVE FIRST DIGIT
- GHW1:
- CALL CHINN ;GET ANOTHER CHARACTER
- CALL CNVBN ;AND CONVERT TO BINARY NYBBLE
- JC GHW2 ;AFTER FIRST DIGIT, CHECK FOR DELIMITER.
- DAD H ;HL*2 ;WE WANT 1-NYBBLE LEFT SHIFT
- DAD H ;HL*4 ;SO WE DOUBLE ADD HL
- DAD H ;HL*8 ;TO ITSELF FOUR TIMES.
- DAD H ;HL*16 ;N.B. TOP DIGIT IS LOST.
- ADD L ;ALL DONE. ADD DIGIT TO LOWER BYTE
- MOV L,A ;UPDATE THE LOWER BYTE.
- JMP GHW1 ;NEXT DIGIT PLEASE.
- GHW2:
- CPI CR ;COMPARE WITH CR
- JZ GHW4
- CPI ' ' ;AND SPACE
- JZ GHW4 ;EITHER IS VALID DELIMITER.
- GHW3:
- INX SP ;NON-HEX BAD BYTE IS RETURNED
- INX SP ;IN A, WITH CARRY SET.
- STC
- RET
- GHW4:
- POP PSW ;NORMAL EXIT, RESTORE PSW
- ORA A ;WITH CARRY CLEARED.
- RET
- ;
- ; CNVBN: CONVERT ASCII TO BINARY NYBBLE,
- ; IS COMMON TO GHXN,GHXB,GHXW
- ;
- CNVBN:
- CPI '0' ;FIRST SEE IF <'0'
- RC
- CPI '9'+1 ;NOW SEE IF NUMERIC
- JC CNVB1 ;IT IS IF CARRY ON.
- CPI 'A' ;NOW TRY A-F
- RC ;ERROR RETURN IF CARRY SET
- CPI 'F'+1 ;CHECK FOR >F
- CMC ;INVERT CARRY
- RC ;RETURN IF NOT OK.
- SUI 7 ;A-F CHR FOUND. SUBTRACT 7
- CNVB1:
- SUI '0' ;NOW MAKE INTO BINARY
- RET ;THEN RETURN
- ;
- ; STORE BYTE IN MEMORY, WITH READ CHECK.
- ; IF READ-BACK DOES NOT AGREE WITH STORE REQUEST AN
- ; APPROPRIATE ERROR MESSAGE IS ISSUED.
- ;
- ; CALLING SEQUENCE:-
- ; ;DATA IN 'A', ADR IN 'HL'
- ; CALL STORE
- ; .... ;RETURNS HERE IF O.K.
- ; ;OTHERWISE RETURNS TO MONITOR.
- ;
- STORE:
- MOV M,A ;STORE BYTE INTO MEMORY
- CMP M ;COMPARE MEMORY WITH A
- RZ ;RETURN IF O.K.
- PUSH H ;SUMTHIN IS WRONG.
- LXI H,M4 ;ISSUE ERROR MESSAGE
- CALL MSG ;TO ADVISE USER
- POP H ;RESTORE HL
- JMP RXAR ;INDICATE ERROR LOC'N
- ;
- ;
- ; MEMORY EXAMINE/MODIFY.
- ;
- ; ENTER FROM MONITOR BY USING:-
- ; A 1234
- ; SETS 'ADR' TO '1234H', TYPES CURRENT CONTENTS THEN AWAITS :-
- ;
- ; (1) VALID BYTE TO STORE, THEN BUMPS 'ADR'
- ; (2) LF TO SIMPLY BUMP 'ADR'
- ; (3) - TO SIMPLY DECREMENT 'ADR'
- ; (4) CR TO RETURN TO MONITOR
- ; (5) . TO RETYPE CURRENT ADR
- ;
- ; IN ADDITION, AT ANY TIME THE USER MAY DIRECTLY
- ; ENTER THIS ROUTINE WITH:-
- ; (1) . TO TYPE CONTENTS OF CURRENT 'ADR'
- ; (2) - TO TYPE CONTENTS OF PREVIOUS 'ADR'
- ; (3) LF TO TYPE CONTENTS OF NEXT 'ADR'
- ; ROUTINE THEN CONTINUES AS ABOVE.
- ;
- GETAD:
- CALL PUWA ;GET ADR REQUIRED
- XCHG
- ;
- GTA1:
- SHLD ADR ;SAVE ADR
- LOCAT:
- CALL CRLF ;CR/LF
- LHLD ADR ;FETCH CURRENT ADR
- CALL THXW ;TYPE CURRENT ADR
- CALL BLANK ;FOLLOWED BY SPACE
- MOV A,M ;FOLLOWED BY BYTE CONTENT
- CALL THXB
- CALL BLANK ;YET ANOTHER SPACE
- CALL GHXB ;LOOK FOR NEW BYTE
- JC NONHX ;CHECK NON-HEX I/P
- CALL STORE ;TRY TO STORE DATA BYTE
- NXLOC:
- LHLD ADR ;PICK UP CURRENT ADR
- INX H ;BUMP 1
- JMP GTA1 ;RESTART PROCESS OF ADR ACCESS.
- ;
- ; ROUTINE 'TEND' IS CALLED FROM MONITOR OP-TAB
- ; TABLE END ROUTINE
- ;
- TEND:
- MOV A,B ;SET 'A' TO COMMAND
- NONHX:
- CPI LF ;SEE IF CHARACTER WAS LF
- JZ NXLOC ;IF SO, GET NEXT LOC'N
- CPI '.' ;MAYBE IT WAS '.'
- JZ LOCAT ;IF SO, GET SAME LOC'N
- CPI '-' ;OR EVEN '-'
- JZ LSTLC ;IN WHICH CASE, BACK UP 1 LOC'N
- NONH1:
- CPI CR ;FINAL CHANCE IS CR
- JZ NEXT ;WHICH MEANS EXIT THE COMMAND
- ;
- ; IN THE EVENT THAT THE COMMAND IS NO GOOD,
- ; ENTER HERE.
- ;
- ILLEG:
- LXI H,M3 ;ILLEGAL CALL, SEND QUERY MESSAGE.
- ILLG1:
- CALL MSG ;TYPE IT, THEN
- JMP NEXT ;'AVE ANOTHER GO.
- ;
- ; PREVIOUS LOCATION REQUEST.
- ;
- LSTLC:
- LHLD ADR ;BACKUP 1 BYTE
- DCX H
- JMP GTA1 ;AND TRY AGAIN.
- ;
- ; NEGATE (2'S COMPLEMENT) 'DE' REG PAIR
- ;
- ; CALLING SEQUENCE:-
- ; .... ;SET UP DE
- ; CALL NEGDE
- ; .... ;NOW DE=-DE
- ;
- NEGDE:
- PUSH PSW ;SAVE PSW
- MOV A,D ;FETCH D
- CMA ;COMPLEMENT IT
- MOV D,A ;RESTORE
- MOV A,E ;FETCH E
- CMA ;COMPLEMENT IT TOO
- MOV E,A ;THE RESTORE
- INX D ;NOW ADD 1 TO GET 2'S COMPL
- POP PSW ;RESTORE PSW
- RET ;TAKE RESULTS HOME
- ;
- ; DISPLAY BLOCK OF MEMORY ON CONSOLE.
- ; CALLED FROM MONITOR AS:-
- ; D XXXX YYYY
- ; AFTER THE FIRST LINE, PRINTS XXXX TO YYYY IN
- ; 8/16 BYTE GROUPS STARTING WITH ADR,MOD 8/16
- ; IF XXXX > YYYY ONLY PRINTS CONTENTS OF XXXX
- ;
- DISP:
- CALL PICKUP ;GET ADDRESS RANGE.
- DMRET:
- CALL CRLF ;NEW LINE
- CALL THXW ;VECTOR ADR TO CONSOLE
- DMNXT:
- CALL BLANK ;1 SPACE
- MOV A,M ;GET DATA
- CALL THXB ;TYPE IT
- CALL LAST ;ALL DONE?
- CALL HOLD ;NO. SEE IF HOLD REQUEST.
- MOV A,L ;ADR MOD8/16?
- ANI OSET-1
- JNZ DMNXT ;NO.
- JMP DMRET ;YES. NEW LINE.
- ;
- ; LOCAL ROUTINE TO TEST FOR HOLD REQUEST.
- ; RETURNS IF NO CHARACTER IN INPUT BUFFER.
- ; PUTS HOLD ON OUTPUT IF <SP> IS TYPED.
- ; OTHERWISE RETURNS TO MONITOR.
- ;
- HOLD:
- CALL CSTS ;GET CONSOLE STATUS.
- RZ ;ZERO. RETURN.
- XRA A ;NON-ZERO.
- CALL CHINX ;GET CHARACTER, NO ECHO.
- CPI ' ' ;TEST FOR SPACE
- JNZ NEXT ;NO SPACE. PANIC.
- JMP GETCH ;SPACE. AWAIT CONTINUE.
- ;
- ; LOCAL ROUTINE TO PICK UP TWO ADDRESSES,
- ; PUTTING THE FIRST ADDRESS INTO HL
- ; AND THE NEGATED SECOND ADDRESS INTO DE
- ;
- PICKUP:
- CALL PUWA ;FROM ADDRESS INTO DE
- CALL PUWA ;FROM ADDRESS INTO HL,
- JMP NEGDE ;NEGATED TO ADDRESS IN DE
- ;
- ; JUMP TO ADDRESS WITH REG'S SET
- ;
- ; CALLED FROM MONITOR BY:-
- ; J 1234 JUMP TO SPECIFIED HEX ADR
- ; J <CR> JUMP TO ADR FROM LAST RST1
- ; (USED AS BREAKPOINT IN PROGRAMS)
- ; J <LF> JUMP TO ADR SET UP BY 'X' COMMAND
- ; J . JUMP TO ADR SET BY LAST USE OF 'A' COMMAND
- ;
- ; RESTORES REGISTERS TO STATE AS SAVED IN RAM ON ENTRY
- ; TO THE MONITOR.
- ; RESPONSES J <CR> , J <LF> AND J . WILL TYPE
- ; THE STORED ADDRESS BEFORE ASKING FOR OK TO PROCEED.
- ;
- ; REMEMBER IF RST1 WAS USED, THAT THE RETURN ADDRESS MAY
- ; NEED TO BE RESET WITH THE 'RP=' COMMAND TO GET YOU
- ; BACK TO THE CALLING POINT.
- ;
- ;
- ; GO DIRECT TO ADR FROM MONITOR.
- ; IDENTICAL TO 'J' COMMAND, BUT DOES
- ; NOT RESTORE REGISTERS.
- ;
- JUMP:
- GOTO:
- PUSH B ;SAVE INPUT COMMAND
- CALL PUWB ;GET ADR
- JNC JMP4 ;HEX ADR GIVEN
- JMP2:
- LHLD SVPC ;ASSUME SAVED PC REQUIRED.
- CPI CR ;SEE IF CR
- JZ JMP3
- LHLD XEQAD ;NO. ASSUME 'X' ADDRESS REQUEST.
- CPI LF ;TRY LF
- JZ JMP3 ;IF NOT,
- LHLD ADR ;ONLY ALTERNATIVE IS 'ADR'
- CPI '.' ;MUST BE '.'
- JNZ ILLEG ;NO. PANIC.
- JMP3:
- CALL THXW ;TYPE HEX ADR
- JMP4:
- CALL OKQ ;IS THIS WHERE WE REALLY WANT TO GO?
- SHLD GOGO+1 ;YES. SET UP JUMP ADR
- MVI A,0C3H ;THIS IS 'JMP' COMMAND
- STA GOGO ;WHICH WE SET UP IN RAM
- POP PSW ;RECOVER COMMAND CHARACTER.
- CPI 'G' ;WAS IT 'G' ?
- JZ GOGO ;YES. IMMEDIATE JUMP TO PROGRAM.
- LXI SP,SVE ;NO. RESTORE SP
- POP D ;AND REGS
- POP B
- POP PSW
- LHLD SVSP ;SAVED SP
- SPHL ;SET NEW SP
- LHLD SVHL ;AND HL
- JMP GOGO ;CUNNINGLY EXECUTE BUILT-UP JUMP
- ;
- ; SET UP EXECUTION ADR FROM MONITOR BY:-
- ; X 1234
- ;
- GETXA:
- CALL PUWA ;GET ADR
- XCHG ;INTO HL
- SHLD XEQAD ;PUT INTO XEQAD
- JMP NEXT ;BACK TO MONITOR
- ;
- ; LOCAL ROUTINE TO CHECK FOR LAST OPERATION.
- ;
- LAST:
- PUSH H ;SAVE MEM VECTOR
- DAD D ;ADD NEGATIVE ADDRESS
- JC NEXT ;FINITO IF CARRY SET
- POP H ;NO. RESTORE
- INX H ;BUMP ADR
- RET ;RETURN
- ;
- ; COMPARE TWO MEMORY BLOCKS, PRINT ANY DIFFERENCES.
- ; USES 'MOVE' TO ALLOCATE THE BLOCK ADDRESSES.
- ;
- ; MOVE MEMORY BLOCK FROM MONITOR BY:-
- ; M XXXX YYYY ZZZZ
- ;
- ; MOVES BLOCK XXXX TO YYYY INTO ZZZZ ONWARDS
- ; TAKE CARE. WILL RESULT IN OVERWRITES IF ZZZZ IS
- ; IN THE RANGE XXXX+1 TO YYYY
- ; CAN BE USED AS A 'FILL' OPERATION BY PUTTING
- ; ZZZZ=XXXX+1. LAST FILL OCCURS AT YYYY+1.
- ;
- KOMP:
- MOVE:
- CALL PUWA ;GET XXXX
- PUSH D ;SAVE ON STACK
- CALL PUWA ;GET YYYY IN DE
- CALL PUWA ;GET ZZZZ IN DE, YYYY GOES TO HL
- XCHG ;DE=Y HL=Z STACK=X
- XTHL ;DE=Y STACK=Z HL=X
- CALL NEGDE ;NEGATE DE
- MOV A,B ;GET COMMAND AND SEE
- CPI 'M' ;IF IT WAS 'M'
- JNZ KOMP1 ;JUMP IF IT WAS NOT.
- CALL OKQ ;MOVE. ARE YOU SURE, USER?
- MOV1:
- MOV A,M ;GET THRU X
- XTHL ;HL=Z STACK=X
- CALL STORE ;STORE AND CHECK
- INX H ;BUMP Z
- XTHL ;RESTORE
- CALL LAST ;END YET?
- JMP MOV1 ;NO.
- ;
- ; REGISTER MODIFY/EXAMINE. FROM MONITOR BY:-
- ;
- ; R <CR> TYPE ALL REG CONTENTS
- ; RA ACCUMULATOR
- ; RF FLAGS,PSB
- ; RB REG B
- ; RC REG C
- ; RD REG D
- ; RE REG E
- ; RH REG H
- ; RL REG L
- ; RS STACK POINTER ***
- ; RP PC IF MONITOR 'CALLED' ***
- ;
- ; *** NOTE: RS, RP GIVE AND EXPECT 4-HEX DIGITS
- ;
- RXLST: DB 'AFBCDEHL',0 ;REGISTER LIST
- ;
- REGEX:
- CALL CHIN ;GET REGISTER IDENTIFIER
- CPI CR ;IS IT CR?
- JZ REXAL ;YEP.
- PUSH PSW ;NO. SAVE PSW
- MVI A,'='
- CALL TYPE ;TYPE A '='
- POP PSW ;RESTORE IDENT
- LXI D,SVPC ;ADR OF P.C.
- CPI 'P' ;SEE IF PC REQUEST
- JZ RX2 ;YES.
- INX D ;POINT TO SP
- INX D
- CPI 'S' ;IS IT 'S'
- JZ RX2 ;YES.
- MOV B,A ;NO. SAVE ID IN B
- LXI H,RXLST ;LIST VECTOR ADR
- LXI D,SVA ;ADR OF 'A' STORE
- RX0:
- MOV A,M ;GET TABLE ID
- ANA A ;CHECK FOR END (0)
- JZ ILLEG ;YES. ILLEGAL REQUEST
- CMP B ;COMPARE WITH REQUEST
- JZ RX1 ;FOUND?
- INX H ;NO. NEXT ENTRY
- DCX D ;NEXT REG
- JMP RX0 ;NEXT TRY.
- ;
- RX1:
- LDAX D ;GET REG
- CALL THXB ;TYPE IT OUT
- CALL BLANK ;FOLLOWED BY SPACE
- CALL GHXB ;GET RESPONSE
- JC NONH1 ;NON-HEX. TRY CR LATER
- STAX D ;STORE INPUT IN REG
- JMP NEXT ;BACK HOME, JAMES.
- ;
- RX2:
- XCHG ;REG ADR TO HL
- MOV E,M ;LOW S OR P
- INX H ;BUMP VECTOR
- MOV D,M ;HI S OR P
- XCHG ;REG VAL IN HL
- CALL THXW ;TYPE HEX WORD
- CALL PUWB ;GET CHANGE.
- JC NONH1 ;NON-HEX JUMP
- XCHG ;RESTORE RAM VECTOR
- MOV M,D ;STORE HI S OR P
- DCX H ;DROP VECTOR
- MOV M,E ;STORE LO S OR P
- JMP NEXT ;RETURN
- RXTSE:
- CALL BLANK ;SPACE
- CALL TYPE ;TYPE THE ID.
- MVI A,'='
- JMP TYPE ;EQUALS
- ;
- REXAL:
- LXI D,SVA ;ADR OF 'A'
- LXI H,RXLST ;ID LIST
- RXA1:
- MOV A,M ;GET ID
- ANA A ;LAST YET? (0)
- JZ RXA2 ;YES
- ;
- ; THIS LITTLE BIT OF CODE GOES IN ONLY IF WE ARE MAKING
- ; A 32 COLUMN CONFIGURED DISPLAY MONITOR.
- ;
- IF COLSW
- CPI 'E' ;SEE IF NEXT REGISTER IS 'E'
- CZ CRLF ;IF SO, NEXT LINE PLEASE,
- ENDIF
- ;
- ; THE ALTERNATIVE IS A 5-BYTE DUMMY PATCH.
- ;
- IF NOT COLSW
- NOP
- NOP
- NOP
- NOP
- NOP
- ENDIF
- ;
- CALL RXTSE ;TYPE ' ',ID,'='
- LDAX D ;GET REG
- DCX D ;DROP REG PTR
- INX H ;BUMP LIST PTR
- CALL THXB ;TYPE CONTENTS
- JMP RXA1 ;NEXT PLEASE.
- RXA2:
- MVI A,'P' ;DO PC
- CALL RXTSE
- LHLD SVPC ;GET PC
- CALL THXW ;TYPE PC
- MVI A,'S' ;NOW DO SP
- CALL RXTSE
- LHLD SVSP ;GET SP
- RXAR:
- CALL THXW ;TYPE VALUE
- JMP NEXT ;RETURN TO MOM.
- ;
- ; HEX WORD PICKUPS.
- ; PUWA GETS WORD, AND RETURNS TO MONITOR IF ERROR.
- ; IF NOT PUTS RESULT IN 'DE'.
- ;
- PUWA:
- CALL PUWB ;GET A HEX WORD
- JC ILLEG ;BADDY OUT HERE
- XCHG ;SAVE INTO DE
- RET ;RETURN
- ;
- ; PUWB GETS WORD INTO 'HL' WITHOUT CHECK.
- ;
- PUWB:
- CALL BLANK ;TYPE A BLANK FIRST.
- JMP GHXW ;NOW GET THE WORD.
- ;
- ; PAUSE GENERATOR.
- ; TYPES THE MESSAGE 'PAUSE' THEN AWAITS ANY KEYSTRIKE
- ; (NO ECHO) BEFORE CONTINUING.
- ;
- PWAIT:
- PUSH H ;SAVE HL
- LXI H,M5 ;MESSAGE 'PAUSE'
- CALL MSG
- POP H ;RECOVER
- JMP GETCH ;ANY RESPONSE WILL DO.
- ;
- ; MONITOR OR USER VERIFY ROUTINE OK?
- ; CALLING SEQUENCE:-
- ; CALL OKQ
- ; .... ;GOES HERE IF RESPONSE IS SP
- ; ;OTHERWISE ABORTS.
- ;
- OKQ:
- PUSH PSW ;SAVE PSW
- PUSH H ;AND HL
- LXI H,M7 ;ADR OF 'OK?' MESSAGE
- CALL MSG ;PRINT IT
- LXI H,M8 ;PREPARE TO ABORT
- CALL GETCH ;USER'S REPLY
- ANI 7FH ;MASK OUT PARITY.
- CPI ' ' ;TRY ' '
- JNZ ILLG1 ;NO. ABORT
- POP H ;YES. RESTORE HL
- POP PSW ;AND PSW
- RET ;AND GO ON.
- ;
- ; ECHO ON/OFF CONTROLLER.
- ;
- ; CALLING SEQUENCE:-
- ; MVI A,XX ;XX=0 FOR OFF
- ; ;XX<>0 FOR ON
- ; CALL ECHCN
- ; .... ;NOW SET/RESET.
- ;
- ECHCN:
- STA ECHO ;STORE REQUIRED VALUE
- RET
- ;
- ; SYSTEM I/O ROUTINES
- ;
- ;******* THIS VERSION SUITS JADE PSI/O SYSTEM HARDWARE *******
- ;
- ; USER MUST PUT HIS OWN CONSOLE DRIVER IN HERE
- ; IF DIFFERENT TO THE VERSION SHOWN
- ;
- ;
- ; TYPE A CHARACTER.
- ; CALLING SEQUENCE:-
- ; LDA CHR
- ; CALL TYPE ;TYPE IT
- ; ....
- ;
- ;
- ; ROUTINE CO IS A PATCH FOR SBC80/SDK80 SYSTEMS
- ; WHICH PASS ARGUMENT IN 'C'
- ;
- CO:
- MOV A,C ;PUT ARGUMENT INTO A
- TYPE:
- PUSH PSW ;SAVE CONTENTS OF 'A'
- TYP1:
- IN CONST ;GET CONSOLE STATUS
- ANI TRDY ;ZERO INDICATES BUSY.
- JZ TYP1 ;IF SO, TRY AGAIN.
- POP PSW ;CLEAR. RESTORE 'A'
- OUT CNOUT ;OUTPUT TO 'CNOUT'
- RET
- ;
- ; RETRIEVE CHARACTER FROM CONSOLE
- ; PARITY IS KEPT, BUT NO ECHO GIVEN.
- ; CALLING SEQUENCE:-
- ; CALL GETCH ;GET CHARACTER
- ; .... ;CHARACTER IN 'A'
- ;
- ;
- ; NOTE: THIS IS ALSO THE ENTRY POINT FOR SDK80/SBC80
- ; ROUTINE CI.
- ;
- CI:
- GETCH:
- CALL CSTS ;GET CONSOLE STATUS
- JZ GETCH ;IF SO, TRY AGAIN.
- IN CNIN ;READY. GET A CHARACTER.
- RET ;RETURN WITH CHAR IN 'A'
- ;
- ; CONSOLE STATUS ROUTINE. CALLED BY DISP AND PUNCH
- ; TO ALLOW STOPPING OF OUTPUT BY TYPING ANY CHAR.
- ; THE BREAK CHARACTER IS THE FIRST CHARACTER INPUT
- ; TO THE MONITOR AFTER RETURN.
- ; (IDEAL BREAK CHARACTER IS <SP>. RESULTS IN MONITOR QUERY)
- ;
- CSTS:
- IN CONST ;GET CONSOLE STATUS
- ANI RBR ;INPUT BUFFER READY?
- RET ;RETURN
- ;
- ;
- ; SYSTEM MESSAGES.
- ;
- M0: DB CR,LF,'UPG80 V3:1'
- M1: DB CR,LF,'* ',0FFH
- M2: DB CR,LF,0FFH
- M3: DB ' ??',0FFH
- M4: DB CR,LF,'MEMORY ERR @ ',0FFH
- M5: DB ' PAUSE ',0FFH
- M7: DB ' OK? ',0FFH
- M8: DB 'ABORT',0FFH
- ORG ROM+0400H
- ;
- M6: DB ' CKS ERR @ ',0FFH
- M10: DB CR,LF,'B/P @ ',0FFH
- ;
- ; SEARCH MEMORY FOR A GIVEN BYTE.
- ; CALLED FROM MONITOR BY:-
- ; S XXXX YYYY VV
- ;
- ; WHERE XXXX= STARTING ADDRESS FOR SEARCH
- ; YYYY= FINISHING ADDRESS FOR SEARCH
- ; VV= BYTE TO BE FOUND
- ;
- ;
- SEARCH:
- CALL PICKUP ;GET BLOCK ADDRESSES.
- CALL GBYTE ;NOW SPACE AND BYTE REF.
- MOV B,A ;SAVE IT IN 'B'
- CALL SRC4 ;START A NEW LINE
- SRC1:
- CALL HOLD ;SEE IF HOLD CALLED.
- MOV A,M ;GET COMPARE.
- CMP B ;COMPARE BYTE WITH MEMORY
- CZ SRC3 ;PRINT ADDRESS IF EQUAL.
- SRC2:
- CALL LAST ;NOW SEE IF ALL DONE.
- JMP SRC1 ;IF NOT, CONTINUE SEARCH
- ;
- ; SRC3 PRINTS ADDRESS
- ; SRC4 SETS UP FOR NEW LINE.
- ;
- SCNT EQU OSET/2
- ;
- SRC3:
- CALL BLANK ;ONE SPACE PLEASE,
- CALL THXW ;FOLLOWED BY THE ADDRESS.
- DCR C ;DECREMENT THE LINE COUNT
- RNZ ;RETURN PRONTO IF NOT FULL.
- SRC4:
- CALL CRLF ;START ON NEW LINE,
- MVI C,SCNT ;LOAD SEARCH COUNTER.
- RET ;THEN CONTINUE ON OUR MERRY WAY.
- ;
- ; COMPARE MEMORY. STARTED OUT IN 'MOVE' FUNCTION WHERE
- ; IT GOT THE ADDRESSES.
- ; CALLED FROM THE MONITOR BY:-
- ; K XXXX YYYY ZZZZ
- ; WHERE XXXX=START ADDR OF FIRST BLOCK
- ; YYYY=STOP ADDR OF FIRST BLOCK
- ; ZZZZ=START ADDR OF SECOND BLOCK
- ; PRINTS OUT ALL OCCURRENCES OF INEQUALITY.
- ;
- KOMP1:
- CALL HOLD ;SEE IF HOLD REQUESTED.
- MOV A,M ;GET FIRST BLOCK BYTE.
- XTHL ;SWAP HL AND T.O.S.
- CMP M ;NOW COMPARE WITH SECOND BYTE
- JZ KOMP2 ;SKIP IF ALL THE SAME.
- CALL SRC4 ;NEW LINE FIRST
- XTHL ;SWAP POINTERS
- CALL KOMP3 ;FIRST ADDR/BYTE
- XTHL ;SWAP THEM BACK
- MOV A,M ;SECOND BYTE IN.
- CALL KOMP3 ;PRINT THEM TOO.
- KOMP2:
- INX H ;BUMP THE SECOND ADDRESS
- XTHL ;BACK WHERE WE STARTED.
- CALL LAST ;SEE IF ALL DONE.
- JMP KOMP1
- KOMP3:
- CALL SRC3 ;PRINT SPACE AND ADDRESS.
- CALL BLANK ;A SPACE
- JMP THXB ;THEN BYTE VALUE
- ;
- ;
- ; ZERO OUT A BLOCK OF MEMORY.
- ; CALLED FROM MONITOR BY:-
- ; Z XXXX YYYY
- ; (THE VALUE VV=0 FOR THIS FUNCTION)
- ;
- ;
- ; FILL BLOCK WITH A VALUE. MONITOR CALL BY:-
- ;
- ; F XXXX YYYY VV
- ;
- ; CAUSES MEMORY LOCATIONS XXXX THRU YYYY TO BE
- ; SET TO THE VALUE VV.
- ;
- ZERO:
- FILL:
- CALL PICKUP ;GET BLOCK ADDRESSES.
- MOV A,B ;GRAB THE COMMAND BYTE (F OR Z)
- CPI 'Z' ;COMPARE WITH 'Z'
- MVI A,0 ;ASSUME ZERO REQUESTED, THEN
- JZ FILL0 ;JUMP IF TRUE.
- CALL GBYTE ;ELSE GET THE FILLING BYTE.
- FILL0:
- CALL OKQ ;VERIFY FILL/ZERO REQUEST
- FILL1:
- CALL STORE ;STORE AND CHECK
- CALL LAST ;END IN SIGHT?
- JMP FILL1 ;NOT YET.
- ;
- ;**** GET BYTE WITH TEST.
- ;
- GBYTE:
- CALL BLANK ;LEADING BLANK
- CALL GHXB ;THEN THE BYTE.
- JC ILLEG ;TEST LEGALITY.
- RET
- ;
- ; USER DEFINABLE ROUTINES.
- ; CALLED FROM MONITOR BY:-
- ; U XXXX ;DEFINE USER CALL ADDRESS.
- ; U <SP> ;GO TO USER ADDRESS.
- ; (IF XXXX=0 THEN USER CALL IS CLEARED)
- ;
- USER:
- CALL BLANK ;PUT IN A SPACE,
- CALL GHXW ;THEN GO FOR THE ADDRESS, IF ANY.
- JC USER2 ;SEE IF CARRY SET (BAD DATA?)
- SHLD USERA ;NO. ADDRESS SET.
- JMP NEXT
- USER2:
- CPI ' ' ;CARRY SET. SEE IF USER CALL REQUEST.
- JNZ ILLEG ;IF NOT, PANIC
- LHLD USERA ;YES. GET THE ADDRESS.
- MOV A,L ;NOW SEE IF LEGAL ADDRESS BY
- ORA H ;LOOKING FOR NON-ZERO ADDRESS.
- JZ ILLEG
- PCHL ;ALL O.K. GO THERE.
- ;
- ;
- ;
- ; ROUTINES TO PUNCH AND LOAD MEMORY.
- ; INTEL STANDARD HEX OBJECT TAPE FORMAT IS USED.
- ;
- ; RECORD START :
- ; BYTE COUNT 2-CHARS
- ; LOAD ADR 4-CHARS
- ; RECORD TYPE 2-CHARS 0=DATA 1=EOF
- ; DATA BYTES (2-CHARS/BYTE)
- ; CHECKSUM FROM BYTE-COUNT TO END OF DATA
- ; (ALL CHARACTERS MUST BE HEX LEGITIMATE 0-9,A-F)
- ;
- ; EOF RECORD MAY CONTAIN EXECUTION ADR.
- ; LOADER GOES TO ADR IF NON-ZERO
- ;
- PUNCH:
- CALL PUWA ;FROM ADR
- CALL PUWA ;TO ADR
- CALL PWAIT ;AWAIT READINESS
- ;
- ; HL=FIRST ADR DE=LAST ADR
- ;
- PN0:
- MOV A,L ;GET LOW PART OF START ADR
- ADI OSET ;INCREMENT BY 8/16
- MOV C,A ;HOLD IN 'C'
- MOV A,H ;GET HIGH PART OF START ADR
- ACI 0 ;TAKE CARE OF ANY O'FLOW
- MOV B,A ;HOLD IN 'B'
- MOV A,E ;NOW LOW PART OF FINAL ADR
- SUB C ;SUBTRACT LOW START
- MOV C,A ;PUT IN 'C'
- MOV A,D ;HIGH PART END ADR.
- SBB B ;SUBTRACT FROM START.
- JC PN1 ;JUMP IF <OSET LEFT.
- MVI A,OSET
- JMP PN2
- PN1:
- MOV A,C ;SET UP FINAL COUNT.
- ADI OSET+1 ;WENT NEGATIVE, ADD 9/17
- PN2:
- ORA A ;SET FLAGS.
- JZ PDONE
- PUSH D ;SAVE HI
- MOV E,A ;LENGTH IN E
- CALL PN3 ;PUNCH HEADER RECORD PARTS.
- JMP PN4
- PN3:
- CALL CCRLF
- MVI D,0 ;CLEAR CKSUM COUNTER.
- MVI A,':' ;PUNCH HEADER
- CALL CTYPE
- MOV A,E
- CALL PBYTE ;PUNCH LENGTH
- MOV A,H
- CALL PBYTE ;PUNCH ADR HI
- MOV A,L
- JMP PBYTE ;PUNCH ADR LO
- PN4:
- XRA A ;CLEAR A
- CALL PBYTE ;RECORD TYPE=0
- PN5:
- MOV A,M ;GET DATA
- INX H
- CALL PBYTE ;FOR PUNCHING
- DCR E ;DROP COUNT BY 1
- JNZ PN5 ;NOT DONE YET
- XRA A ;NOW FIND CKSUM
- SUB D ;AS 2'S COMPL OF 8-BIT SUM
- CALL PBYTE ;PUNCH IT
- POP D ;RESTORE HI ADR
- JMP PN0 ;GO AGAIN
- ;
- ; BYTE PUNCHER.
- ;
- PBYTE:
- PUSH PSW ;HOLD ONTO A,PSB
- CALL CSTS ;SEE IF USER PANICED.
- JNZ NEXT
- POP PSW ;IF NOT, GO ON.
- CALL CTHXB
- ADD D ;UPDATE CKSUM
- MOV D,A
- RET ;GO AGAIN
- ;
- ; ALL DONE NOW.
- ;
- PDONE:
- CALL CCRLF
- PDON1:
- JMP NEXT ;RETURN TO MOMMA
- ;
- ; PUNCH AN END OF FILE.
- ;
- PEND:
- CALL PUWB ;ADR OR CR
- JNC PEND1 ;GO IF ADR
- LXI H,0 ;ASSUME CR, PUT ADR=0
- CPI CR ;WAS IT CR?
- JNZ ILLEG ;IF NOT, ITS ILLEGAL
- PEND1:
- CALL PWAIT ;AWAIT PROMPT
- MVI E,0 ;ZERO LENGTH
- CALL PN3
- MVI A,1 ;RECORD TYPE=1
- CALL PBYTE
- XRA A
- SUB D ;CALCULATE THE CKSUM
- CALL PBYTE ;PUNCH IT.
- ;
- ; PUNCH 100 NULLS
- ;
- NULLS:
- MVI C,100 ;WE WILL PUNCH 100 NULLS (10 INCHES)
- XRA A
- NLS1:
- CALL CTYPE
- DCR C
- JNZ NLS1 ;MORE TO GO?
- JMP PDON1 ;NO. RETURN
- ;
- NULL:
- CALL PWAIT ;THIS ENTRY VIA COMMAND 'N'
- JMP NULLS ;FOLLOWED RAPIDLY BY NULLS.
- ;
- ; LOAD HEX OBJECT TAPE.
- ;
- ; MONITOR COMMAND 'L'
- ; LOAD A HEX-BINARY TAPE AS PRODUCED BY THE 'P'
- ; COMMAND.
- ; MAY CONTAIN AN OFFSET VALUE, ALLOWING THE DATA TO
- ; BE LOADED INTO A DIFFERENT LOCATION TO THAT SPECIFIED
- ; BY THE LOAD ADDRESS.
- ; E.G. L 1000 WILL CAUSE THE LOADED DATA TO BE
- ; 1000H LOCATIONS HIGHER THAN THAT SPECIFIED BY
- ; THE BLOCK LOAD ADDRESS.
- ;
- ;
- LOAD:
- CALL PUWB ;GET THE OFFSET, IF ANY.
- JNC LD4
- CPI CR ;ERROR MAY ONLY BE <CR>
- JNZ ILLEG
- LD4:
- XRA A ;PREPARE TO
- CALL ECHCN ;RESET ECHO.
- CALL CRLF ;NEW LINE PLEASE.
- PUSH H ;SAVE BIAS ADR
- LD5:
- POP H ;GET BIAS
- PUSH H ;AND RESTORE
- CALL RIX ;GET INPUT
- MVI B,':' ;WAIT FOR ':'
- SUB B
- JNZ LD5 ;TRY AGAIN
- MOV D,A ;CLEAR CKSUM
- CALL BYTE ;GET LENGTH
- JZ LD7 ;ZERO MEANS ALL DONE
- MOV E,A ;SAVE LENGTH
- CALL BYTE
- PUSH PSW ;SAVE HI ADR
- CALL BYTE
- POP B ;FETCH MSBYTE
- MOV C,A ;BC NOW HAS ADR
- PUSH B ;SAVE IT
- XTHL ;INTO HL
- SHLD BLKAD ;SAVE BLOCK ADR
- XTHL ;IN CASE OF ERROR
- POP B
- DAD B ;RESTORE AND ADD BIAS
- CALL BYTE ;RECORD TYPE INPUT
- LD6:
- CALL BYTE ;GET DATA BYTES
- CALL STORE ;STORE
- INX H
- DCR E
- JNZ LD6 ;GO ON.
- CALL BYTE ;GET CKSUM
- JZ LD5
- LDERR:
- LXI H,M6 ;CKSUM ERROR
- CALL MSG
- LHLD BLKAD ;ADR OF THIS BLOCK IS
- JMP RXAR ;NOW GIVEN
- LD7:
- CALL BYTE ;MSB OF XEQAD
- MOV H,A
- CALL BYTE
- MOV L,A
- ORA H
- JZ NEXT ;MONITOR IF ADR=0
- PCHL ;OTHERWISE EXECUTE
- ;
- RIX:
- CALL RI
- JC ILLEG ;ON ERROR, PRINT '??'
- ANI 7FH ;REMOVE PARITY
- RET
- ;
- ; ROUTINE RI
- ; GETS A CHARACTER FROM THE CASSETTE READER INPUT
- ;
- ;
- RI:
- PUSH B ;SAVE BC
- LXI B,TMOUT ;GET TIMEOUT (MILLISECONDS)
- RI10:
- CALL CASTS ;GET READER STATUS
- JNZ RI15 ;READY ON NON-ZERO
- CALL DELAY ;IF NOT, DELAY 1 MS
- DCX B ;DECREMENT DELAY COUNT
- MOV A,B ;SEE IF IT
- ORA C ;IS ZERO YET.
- JNZ RI10 ;TRY AGAIN IF NOT DONE
- STC ;SET ERROR CARRY
- POP B ;RESTORE BC
- RET ;TROUBLED RETURN
- RI15:
- CALL CGETCH ;GET DATA.
- ORA A ;CLEAR CARRY ONLY.
- POP B ;RESTORE BC
- RET ;SIMPLY RETURN
- ;
- BYTE:
- PUSH B ;SAVE BC
- CALL RIX ;READ ASCII
- CALL CNVBN ;CONVERT TO HEX
- JC LDERR ;ERROR DETECTOR.
- RLC ;SHIFT LEFT 4 BITS
- RLC
- RLC
- RLC
- MOV B,A ;SAVE THEM A WHILE
- CALL RIX ;GET SECOND BYTE
- CALL CNVBN ;CONVERT TO HEX
- JC LDERR ;ERROR DETECTOR
- ORA B ;OR IN THE SAVED NYBBLE
- MOV C,A ;HOLD BYTE A WHILE.
- ADD D ;ADD TO CKSUM
- MOV D,A ;UPDATE CKSUM
- MOV A,C ;RESTORE BYTE
- POP B ;RESTORE BC
- RET
- ;
- ; FUNCTION DELAY.
- ; CAUSES THE SYSTEM TO DELAY FOR 1 MS.
- ;
- DELAY:
- PUSH B ;SAVE BC
- MVI B,ONEMS ;GET ONE MS LOOP COUNT
- DEL2:
- DCR B ;DECREMENT LOOP COUNT
- JNZ DEL2 ;NOT YET DONE.
- POP B ;ALL DONE. GET BC
- RET ;RETURN TO PATIENT WAITER.
- ; ENTER HERE FOLLOWING A SOFTWARE RST2
- ; I.E. BREAKPOINT SETTING.
- ;
- BPAT:
- SHLD SVPC ;STORE CALLING PC
- STA TMPA ;AND CARRY (IN B7)
- RAL ;THEN ROTATE BACK THE ACC.
- LXI H,0 ;NOW TRANSFER THE SP TO HL BY DOING A DUMMY
- DAD SP ;ADD TO HL. (N.B. CLEARS CARRY)
- SHLD SVSP ;SAVE THE CALLER SP.
- LXI SP,SVA+1 ;PICK UP REG STORE POINTER
- PUSH PSW ;TO SAVE PSW
- PUSH B ;AND BC
- PUSH D ;AND DE. (HL ALREADY SAVED)
- LXI H,SVF ;GET THE PSB BYTE
- LDA TMPA ;PICK UP THE CARRY HOLDER,
- RAL ;ROTATE IT BACK TO CARRY.
- JNC BP1 ;SKIP IF CARRY NOT SET,
- INR M ;OTHERWISE RESET CARRY.
- BP1:
- LXI SP,STACK ;SET SP TO MONITOR STACK
- LXI H,M10 ;TYPE BREAKPOINT MESSAGE
- CALL MSG
- LHLD SVPC ;PICK-UP THE BREAK ADDRESS + 1
- DCX H ;MAKE IT THE REAL ADDRESS.
- SHLD SVPC ;RESET THE SAVED PC STORE
- CALL THXW ;TELL THE USER WHERE HE BROKE.
- CALL CRLF ;NEXT LINE PLEASE.
- JMP REXAL ;NOW PRINT THE REGISTER DATA.
- ;
- ;
- ;
- ; CONTINUE AFTER A BREAKPOINT HALT
- ;
- ; ASSUMES THAT THE LOCATION OF THE B/P HAS BEEN ALTERED
- ; BY A PRIOR
- ; B XXXX COMMAND.
- ; CONTINUE CAN ONLY BE USED TO RETURN THE MONITOR TO
- ; A PROGRAM WHICH HAS BEEN HALTED BY EXECUTION
- ; OF A 'RST 2' INSTRUCTION (0D7H) AT A LOCATION WHOSE CONTENTS
- ; ARE SAVED IN 'BPDAT'.
- ;
- CONT:
- LHLD SVPC ;GET PSEUDO-RESTART.
- MOV A,L ;PUT LOW PART IN ACC.
- ORA H ;RESULT WILL BE ZERO IF ALL
- JZ ILLEG ;BITS ARE ZERO. I.E. NO B/P.
- CALL BLANK ;PRINT A SPACE
- CALL THXW ;FOLLOWED BY THE ADDRESS.
- XCHG ;PUT OLD ADDRESS IN DE
- LHLD BPADD ;NOW GET CURRENT ADDRESS.
- CALL NEGDE ;NEGATE THE PC ADDRESS.
- DAD D ;D.P. ADD TO B/P ADDRESS.
- MOV A,L ;LO RESULT TO ACC,
- ORA H ;OR IT WITH HI RESULT,
- LHLD SVPC ;RECOVER PC (MAY NEED IT)
- JNZ CON3 ;SEE IF DE=HL (I.E. ZERO RESULT)
- LXI H,BPDAT ;GET START ADDRESS OF SAVED INSTRUCTION.
- CON3:
- MVI A,CR ;<CR> FORCES 'J' CONTINUE.
- PUSH PSW ;SAVE SIMULATED 'J' COMMAND
- JMP JMP4 ;NOW ENTER 'JUMP'.
- ;
- ;
- ; BREAK-POINT THE PROGRAM AT LOCATION XXXX
- ; B XXXX
- ;
- ; MAY ALSO BE USED TO CLEAR A PREVIOUS B/P BY
- ; B (CRTN)
- ;
- ; BPT SAVES THE ADDRESS XXXX AND ITS CONTENTS
- ; IT THEN REPLACES THE CONTENTS OF XXXX WITH D7 ( RST 2 ).
- ; THIS FORCES THE PROGRAM TO SAVE ALL DATA AND RETURN
- ; TO THE MONITOR. THE PROGRAM MAY BE RESTARTED FROM
- ; XXXX BY A CONTINUE ( C ) COMMAND AFTER IT HAS HALTED.
- ;
- BPT:
- ;
- ;**** THIS CONDITIONAL CODE INSERTS THE RST2 JUMP IN RAM IF
- ; THE MONITOR IS NOT IN PAGE ZERO.
- ;
- ; ORG 0010H
- ; JMP BPIN
- ;
- IF ROMSW
- MVI A,JMP ;GET A 'JMP'
- STA 0010H ;PUT IT AT 0010H
- LXI H,BPIN ;GET ADDRESS OF 'BPIN'
- SHLD 0011H ;STORE IT AT 0011H
- ENDIF
- CALL PUWB ;GET ADDRESS
- JNC BPT1 ;GOT AN ADDRESS - SO PROCEED
- CPI CR ;NOT AN ADDRESS - WAS IT A CRTN
- JNZ ILLEG ;NO SO BOMB OUT
- LXI H,0 ;YES SO SIMULATE AN ADDRESS OF ZERO
- ;
- ; BPT WILL REMOVE THE OLD B/P (IF ANY )
- ;
- BPT1:
- PUSH H ;COME HERE WITH ADDRESS IN HL. SAVE IT ON THE STACK
- LHLD BPADD ;IS THE PREVIOUS B/P ADDRESS = 0
- MOV A,L ;PUT LO PART OF ADDRESS IN ACC
- ORA H ;THEN 'OR' WITH HI PART
- JZ BPT2 ;IT WAS ZERO SO SAVE XXXX AND (XXX)
- LXI H,BPDAT ;POINT TO THE SAVED DATA FROM THE LAST B/P
- MOV A,M ;GET IT IN A
- LHLD BPADD ;GET THE LAST B/P ADDRESS IN HL
- CALL STORE ;AND RESTORE THE DATA THERE
- ;
- ; BREAKPOINT MAKER.
- ; CREATES A GAP IN THE TARGET PROGRAM BY INSERTING AN 'RST 2'
- ; IN PLACE OF THE FIRST BYTE OF THE INSTRUCTION.
- ; THE INSTRUCTION (ALL BYTES, COUNT COMPUTED) IS PLACED
- ; IN A TEMPORARY STORE, ALONG WITH A JUMP TO THE NEXT
- ; INSTRUCTION IN THE TARGET PROGRAM.
- ;
- BPT2:
- POP H ;RETRIEVE B/P ADDRESS FROM STACK.
- SHLD BPADD ;SAVE IT FOR FUTURE RETURN.
- MOV A,H ;SEE IF THIS IS
- ORA L ;ONLY CLEARING
- JZ NEXT ;THE BREAKPOINT.
- MOV A,M ;LOAD ITS FIRST BYTE.
- LXI H,TAB1 ;GET START ADDRESS OF TABLE 1
- CPI 40H ;SEE IF THE BYTE IS IN TABLE 1
- JC BPT3 ; I.E. LESS THAN 40H
- LXI H,TAB2 ;GET START OF TABLE 2.
- SUI 0C0H ;SEE IF IT IS IN TABLE 2
- JNC BPT3 ; I.E. >0BFH
- MVI A,1 ;THE GROUP 40H TO 0BFH IS 1-BYTE
- JMP BPT5 ;IN LENGTH.
- BPT3:
- MOV D,A ;RANGE OF BYTE IS NOW 0 TO 64
- RRC ;WE MUST PACK THIS RANGE DOWN
- RRC ;TO 0 TO 15 BYTES OFFSET.
- MVI B,0 ;AND THEN MAKE UP THE
- ANI 0FH ;TRUE ADDRESS BY
- MOV C,A ;ADDING THE OFFSET TO THE
- DAD B ;START ADDRESS IN THE TABLE.
- MVI A,3 ;WE MUST ALSO KNOW WHERE IN
- ANA D ;THE BYTE THE INSTRUCTION SIZE
- MOV D,A ;IS TO BE FOUND. (SEE NOTE ABOVE TABLE)
- MOV A,M ;GET THE KEY BYTE.
- BPT4:
- DCR D ;FIND THE KEY POSSY.
- JM BPT5 ;BY DECREMENTING THE 'D' REGISTER UNTIL IT
- RRC ;GOES NEGATIVE. IF NOT FOUND, ROTATE THE KEY
- RRC ;BYTE 2 POSITIONS RIGHT
- JMP BPT4 ;AND TRY AGAIN
- BPT5:
- ANI 3 ;WE CAN NOW COMPUTE THE BYTE COUNT.
- JZ ILLEG ;(OF COURSE 0 IS ILLEGAL)
- MOV C,A ;SAVE THE COUNT IN C
- LXI H,BPDAT ;DATA STORE ADDRESS
- XCHG ;PUT IT INTO DE
- LHLD BPADD ;GET THE SOURCE ADDRESS.
- BPT6:
- MOV A,M ;PICK UP THE DATA BYTE AND
- INX H ;THEN BUMP ADDRESS.
- XCHG ;AFTER SWAPPING HL ADDRESSES,
- MOV M,A ;PUT IT IN THE BUFFER.
- INX H ;NOW BUMP STORE ADDRESS,
- XCHG ;BEFORE RESTORING THE ADDRESSES.
- DCR C ;DECREMENT BYTE COUNTER.
- JNZ BPT6 ;TRY AGAIN IF STILL DATA.
- XCHG ;RETRIEVE THE STORE ADDRESS.
- MVI M,JMP ;PUT 'JMP' (0C3H) IN STORE.
- INX H ;BUMP STORE ADDRESS.
- MOV M,E ;LOW ORDER RETURN ADDRESS.
- INX H ;BUMP YET AGAIN.
- MOV M,D ;HIGH ORDER RETURN ADDRESS.
- LHLD BPADD ;FINALLY REPLACE THE
- MVI M,0D7H ;B/P WITH AN 'RST 2'
- JMP NEXT
- ;
- ; BREAKPOINT DATA TABLE.
- ; CONSISTS OF A SERIES OF DATA BYTES WHICH DEFINE THE
- ; NUMBER OF BYTES IN AN INSTRUCTION, BASED ON THE
- ; VALUE OF ITS FIRST BYTE.
- ;
- ; THE TABLE HAS 2 SECTIONS.
- ; TAB1 CONTAINS DATA FOR BYTES 000H TO 03FH
- ; TAB2 CONTAINS DATA FOR BYTES 0C0H TO 0FFH
- ; EACH BYTE CONTAINS 4 KEYS REPRESENTING THE SIZE OF
- ; 4 INSTRUCTIONS (RANGE 0-3, 0 IS ILLEGAL)
- ; SUCH THAT THE BOTTOM 2 BITS OF THE INSTRUCTION BYTE KEY TO
- ; THE TABLE BYTE AS FOLLOWS:-
- ; 00 BITS B1,B0
- ; 01 BITS B3,B2
- ; 10 BITS B5,B4
- ; 11 BITS B7,B6
- ;
- B00 EQU 0 ;KEY 0 DATA BITS
- B01 EQU 1
- B02 EQU 2
- B03 EQU 3
- B10 EQU 0 ;KEY 1 DATA BITS
- B11 EQU B01*4
- B12 EQU B02*4
- B13 EQU B03*4
- B20 EQU 0 ;KEY 2 DATA BITS
- B21 EQU B11*4
- B22 EQU B12*4
- B23 EQU B13*4
- B30 EQU 0 ;KEY 3 DATA BITS
- B31 EQU B21*4
- B32 EQU B22*4
- B33 EQU B23*4
- ;
- TAB1:
- DB B01+B13+B21+B31
- DB B01+B11+B22+B31
- DB B00+B11+B21+B31
- DB B01+B11+B22+B31
- DB B00+B13+B21+B31
- DB B01+B11+B22+B31
- DB B00+B11+B21+B31
- DB B01+B11+B22+B31
- DB B01+B13+B23+B31
- DB B01+B11+B22+B31
- DB B00+B11+B23+B31
- DB B01+B11+B22+B31
- DB B01+B13+B23+B31
- DB B01+B11+B22+B31
- DB B00+B11+B23+B31
- DB B01+B11+B22+B31
- TAB2:
- DB B01+B11+B23+B33
- DB B03+B11+B22+B31
- DB B01+B11+B23+B30
- DB B03+B13+B22+B31
- DB B01+B11+B23+B32
- DB B03+B11+B22+B31
- DB B01+B10+B23+B32
- DB B03+B10+B22+B31
- DB B01+B11+B23+B31
- DB B03+B11+B22+B31
- DB B01+B11+B23+B31
- DB B03+B10+B22+B31
- DB B01+B11+B23+B31
- DB B03+B11+B22+B31
- DB B01+B11+B23+B31
- DB B03+B10+B22+B31
- ;
- ;**** CASSETTE I/O HANDLING ROUTINES.
- ;
- ;
- ;**** CASSETTE OUTPUT CHARACTER.
- ;
- CTYPE:
- PUSH PSW ;SAVE PSW
- CTYP1:
- IN CSST ;STATUS
- ANI TRDY ;READY?
- JZ CTYP1
- POP PSW ;YES. PRINT
- OUT CSOUT ;AT CASSETTE.
- RET
- ;
- ;**** GET CHARACTER
- ;
- CSI:
- CGETCH:
- CALL CASTS ;GET STATUS
- JZ CSI
- IN CSIN ;GET CHR
- RET
- ;
- ;**** CASSETTE INPUT STATUS
- ;
- CASTS:
- IN CSST ;STATUS BYTE
- ANI RBR ;MASKED
- RET
- ;
- ;**** CASSETTE BYTE PUT.
- ;
- CTHXB:
- PUSH PSW ;SAVE DATA
- RRC ;ROTATE
- RRC ;THE
- RRC ;BYTE
- RRC ;4 BITS.
- CALL CTHXN ;PRINT 1ST NYBBLE
- POP PSW ;RECOVER
- ;
- ;**** CASSETTE NYBBLE PUT.
- ;
- CTHXN:
- PUSH PSW ;SAVED
- ANI 0FH ;BOTTOM 4 BITS
- ADI 90H ;MAKE THE
- DAA ;NYBBLE
- ACI 40H ;INTO AN
- DAA ;ASCII CHR 0-F
- CALL CTYPE ;PUT IT.
- POP PSW
- RET
- ;
- ;**** CASSETTE WORD OUTPUT.
- ;
- CTHXW:
- PUSH PSW ;SAVE PSW
- MOV A,H ;DO TOP
- CALL CTHXB ;BYTE
- MOV A,L ;THEN BOTTOM
- CALL CTHXB ;BYTE
- POP PSW
- RET
- ;
- ;**** CASSETTE CRLF OUTPUT.
- ;
- CCRLF:
- PUSH H ;SAVE HL
- LXI H,M2 ;GET MESSAGE
- CALL CMSG ;PRINT IT.
- POP H
- RET
- ;
- ;**** CASSETTE MESSAGE.
- ;
- CMSG:
- PUSH PSW
- PUSH H ;SAVE PSW AND HL
- CMNXT:
- MOV A,M ;GET BYTE
- INX H ;BUMP PTR.
- CPI 0FFH ;END FLAG?
- CNZ CTYPE
- JNZ CMNXT ;MORE.
- POP H ;RECOVER HL
- POP PSW ;AND PSW
- RET
- ;
- ;**** CASSETTE BLANK.
- ;
- CBLANK:
- PUSH PSW
- MVI A,' ' ;A SPACE
- CALL CTYPE ;IS SENT.
- POP PSW
- RET
- ;
- ;**** GET HEX NYBBLE.
- ;
- CGHXN:
- MVI A,0FH ;ONLY BOTTOM NYBBLE
- JMP CGHB1
- ;
- ;**** GET HEX BYTE.
- ;
- CGHXB:
- MVI A,0FFH ;ALL BYTE NEEDED.
- CGHB1:
- PUSH H ;SAVE HL
- CALL CGHXW ;GET A WORD.
- JC CGHB2 ;ERROR?
- ANA L ;NYBBLE/BYTE ONLY.
- CGHB2:
- POP H
- RET
- ;
- ;**** GET HEX WORD FROM CASSETTE.
- ;
- CGHXW:
- PUSH PSW ;SAVE PSW
- LXI H,0 ;START WITH NOTHING.
- CALL CGETCH ;GET CHARACTER
- ANI 7FH ;AND MASK IT.
- CALL CNVBN ;CONVERT TO BINARY.
- JC GHW3
- MOV L,A ;SAVE IT IF O.K.
- CGHW1:
- CALL CGETCH ;AND ANOTHER
- ANI 7FH ;MASKED.
- CALL CNVBN ;THEN CONVERTED.
- JC GHW2
- DAD H ;*2
- DAD H ;*4
- DAD H ;*8
- DAD H ;*16
- ADD L ;ADD LO BYTE.
- MOV L,A ;UPDATE
- JMP CGHW1
- ;
- ;
- ;
- ;
- ;
- ORG ROM + 07DCH
- ;
- ;**** JUMP TABLE FOR CASSETTE ROUTINES.
- ;
- ZCTYPE: JMP CTYPE
- ZCGETC: JMP CGETCH
- ZCMSG: JMP CMSG
- ZCCRLF: JMP CCRLF
- ZCSPAC: JMP CBLANK
- ZCTHXN: JMP CTHXN
- ZCTHXB: JMP CTHXB
- ZCTHXW: JMP CTHXW
- ZCGHXN: JMP CGHXN
- ZCGHXB: JMP CGHXB
- ZCGHXW: JMP CGHXW
- ZCASTS: JMP CASTS
- ;
- ORG ROM+0800H
- ;
- QIN: EQU 0DBH
- QOUT: EQU 0D3H
- QRET: EQU 0C9H
- ;
- ;**** INPUT AND OUTPUT PORT DATA ROUTINES.
- ;
- INPT:
- OUTPT:
- MVI A,QIN ;ASSUME 'IN' COMMAND
- STA BUFF
- CALL GBYTE ;GET PORT NUMBER.
- STA BUFF+1 ;SAVE IT IN 'BUFF+1'
- MVI A,QRET ;GET 'RET'
- STA BUFF+2
- MVI A,'I' ;SEE IF THIS IS 'IN' COMMAND.
- CMP B
- JNZ OUTER ;MUST BE 'OUT'
- CALL BUFF ;GET INPUT DATA.
- CALL BLANK ;ONE SPACE,
- CALL THXB ;FOLLOWED BY THE BYTE.
- CALL CRLF
- JMP NEXT
- OUTER:
- MVI A,QOUT ;REPLACE 'IN' WITH 'OUT'
- STA BUFF
- CALL GBYTE ;OUTPUT BYTE REQUIRED.
- CALL CRLF
- CALL BUFF ;OUTPUT IT.
- JMP NEXT
- ;
- ;
- ;***********************************************************
- ;
- ; DISASSEMBLER PROGRAM FOR 8080 ROUTINES.
- ;
- ;***********************************************************
- ;
- ;
- ;**** FIND START ADDRESS.
- ;
- DIS80:
- CALL PUWB ;GET START ADDRESS.
- JC ILLEG ;ERROR EXIT
- CALL CRLF
- MOV B,H
- MOV C,L ;BC NOW HAS MEMORY ADDR.
- ;
- ;**** GET BYTE.
- ;
- DIS1:
- MOV H,B ;PUT MEMORY ADDRESS
- MOV L,C ;INTO HL
- CALL THXW ;PRINT IT
- CALL BLANK ;AND A SPACE.
- LDAX B ;GET FIRST BYTE.
- ;
- ;**** FIND THE TABLE POSITION.
- ;
- MOV E,A ;PUT OFFSET INTO C
- MVI D,0 ;AND CLEAR HI BYTE
- ;
- ; ADD OFFSET THREE TIMES.
- ;
- LXI H,ATAB1 ;TABLE START ADDRESS.
- DAD D ;ADD OFFSET
- DAD D ;THREE
- DAD D ;TIMES.
- ;
- ;**** READY TO PROCESS.
- ;
- MOV D,M ;LOAD BYTE COUNT.
- MOV A,D
- INX H ;BUMP PAST BYTE COUNTER.
- CALL BPRNT ;PRINT THE BYTES.
- MOV E,M ;GET OPCODE OFFSET
- MVI D,0 ;INTO DE
- INX H ;BUMP TABLE POINTER.
- PUSH H ;AND SAVE IT
- LXI H,ATAB2 ;ADD OFFSET
- DAD D ;TO THE
- DAD D ;TABLE HEADER
- DAD D ;FOUR
- DAD D ;TIMES.
- MVI D,4
- CALL PRNT ;PRINT OPCODE.
- LXI H,MSGBK ;NOW PRINT
- CALL MSG ;4 SPACES
- POP H ;RETRIEVE PTR.
- MOV E,M ;DITTO FOR OPERAND(S).
- MVI D,0
- LXI H,ATAB3
- DAD D
- DAD D
- DAD D
- MVI D,3
- CALL PRNT ;PRINT OPERAND(S)
- PUSH B ;SAVE MEM PTR.
- MVI H,0 ;ZERO OUT H
- MOV L,A ;PUT BYTE COUNT INTO L
- DAD B ;BUMP MEMORY ADDRESS.
- MOV B,H ;PUT BACK INTO
- MOV C,L ;BC
- POP H ;RETRIEVE MEMORY ADDRESS.
- DCR A ;TEST BYTE COUNT
- JZ DISB1 ;FOR ONE
- DCR A
- JZ DISB2 ;OR TWO
- DISB3:
- INX H ;GET AND
- MOV E,M ;PRINT
- INX H ;16 BIT
- MOV D,M ;DATA
- XCHG ;WORD
- CALL THXW ;VALUE
- JMP DISB1
- DISB2:
- INX H ;GET AND
- MOV A,M ;PRINT 8 BIT
- CALL THXB ;DATA BYTE VALUE
- DISB1:
- CALL CRLF ;NEW LINE PLEASE.
- CALL HOLD ;SEE IF HOLD REQUESTED.
- JMP DIS1 ;NO.
- ;
- ;**** PRINT CURRENT BYTE IF VALID.
- ;
- BPRNT:
- PUSH PSW ;SAVE PSW.
- PUSH B ;SAVE CURRENT MEM PTR.
- MVI E,3 ;PRINT 3 BYTES.
- BPRT1:
- LDAX B ;GET CURRENT MEMORY BYTE.
- DCR D ;DECREMENT COUNTER.
- CP THXB ;PRINT IT,
- CM BLANK ;OR ELSE 2 SPACES.
- CM BLANK
- CALL BLANK ;FOLLOWED BY SPACER.
- INX B ;FINALLY BUMP POINTER.
- DCR E
- JNZ BPRT1
- POP B ;RETRIEVE MEM PTR.
- POP PSW ;AND PSW.
- RET
- ;
- ;**** PRINT A STRING FOLLOWED BY A SPACE.
- ;
- PRNT:
- PUSH PSW
- PRNT1:
- MOV A,M ;GET DATA BYTE
- CALL TYPE ;PRINT IT.
- INX H ;READY FOR NEXT BYTE
- DCR D ;DECREMENT AND TEST
- JNZ PRNT1 ;LOOP COUNT.
- CALL BLANK
- POP PSW
- RET
- ;
- ;
- ;********************************************************
- ;
- ; LINE ASSEMBLER PROGRAM.
- ; USES COMMON TABLES WITH DISASSEMBLER.
- ;
- ;********************************************************
- ;
- ;
- ASM80:
- CALL PUWB ;GET START ADDRESS.
- JC ILLEG
- CALL CRLF
- ASM1:
- CALL THXW ;TYPE CURRENT ADDRESS.
- SHLD MEMADR ;SAVE CURRENT ADDRESS.
- CALL STRING ;GET THE OPCODE STRING.
- LXI H,ATAB2 ;OPCODE TABLE
- MVI B,4 ;HAS 4 BYTES/ENTRY
- CALL STCOMP ;SCAN FOR THE GIVEN STRING.
- JC ILLEG ;CARRY SET ON ERROR.
- STA OPCODE ;SAVE OPCODE OFFSET.
- LXI H,ATAB1+1 ;FIND A CODE
- ASM2:
- CMP M ;WHICH MATCHES
- INX H ;SO THAT
- JZ ASM3 ;WE CAN SEE
- INX H ;IF THE
- INX H ;THIRD BYTE IN
- JMP ASM2 ;THE TABLE
- ASM3:
- MOV A,M ;HAPPENS TO BE
- CPI 0 ;NON-ZERO.
- JZ ASM4 ;I.E. NON-BLANK
- CALL STRING ;OPERAND STRING REQUIRED.
- LXI H,ATAB3 ;LOOK FOR OPERAND STRING
- MVI B,3 ;IN 3 BYTE/ENTRY OPERAND
- CALL STCOMP ;TABLE.
- JC ILLEG
- CALL BLANK ;SPACE UP
- ASM4:
- MOV E,A ;SAVE OPERAND CODE NUMBER
- LDA OPCODE ;AND ALSO
- MOV D,A ;OPCODE CODE NUMBER
- LXI H,ATAB1+1 ;FIND DOUBLE MATCH
- MVI C,0 ;IN THE OPCODE TABLE
- ASM5:
- MOV A,M ;GET TEST BYTE.
- CPI 0FFH ;SEE IF E.O.T.
- JZ ILLEG ;I.E. -1 BYTE.
- CMP D ;OPCODE MATCH?
- JNZ ASM6
- INX H
- MOV A,M
- CMP E ;OPERAND MATCH?
- JZ ASM7
- DCX H
- ASM6:
- INX H ;NO. BUMP
- INX H ;PAST THIS
- INX H ;ENTRY AND
- INR C ;INCREMENT TABLE COUNTER.
- JMP ASM5
- ASM7:
- DCX H ;GOT IT. GO BACK
- DCX H ;TWO BYTES AND
- MOV D,M ;GET BYTE COUNT.
- LHLD MEMADR ;RETRIEVE CURRENT MEM ADDR.
- MOV A,C ;STORE THE FIRST
- CALL STORE ;BYTE VALUE
- MOV A,D ;THEN LOOK AT
- SUI 2 ;SIZE OF INSTRUCTION.
- JM ASB1 ;ONE BYTE
- LXI H,MSGBK ;OR MULTIBYTE.
- CALL MSG
- CALL GHXW ;GET A NUMBER.
- JC ILLEG
- ORA A ;RESET BYTE FLAG.
- JZ ASB2 ;TWO BYTE.
- ASB3:
- XCHG ;NUMBER NOW IN DE.
- LHLD MEMADR ;GET MEMOR ADDR.
- INX H ;PUT LO BYTE
- MOV A,E ;INTO NEXT
- CALL STORE ;ADDRESS.
- INX H ;AND HI BYTE
- MOV A,D ;INTO 3RD BYTE
- CALL STORE ;ADDRESS.
- JMP ASB1 ;FINISH OFF.
- ASB2:
- MOV A,L ;PUT LO BYTE
- LHLD MEMADR ;ONLY INTO
- INX H ;INTO 2ND. BYTE
- CALL STORE ;ADDRESS.
- ASB1:
- INX H ;BUMP TO NEXT ADDR.
- CALL CRLF ;NEW LINE,
- JMP ASM1 ;START ALL OVER AGAIN.
- ;
- ;**** STRING INPUT ROUTINE.
- ; ON RETURN, FIRST 4 BYTES IN 'BUFF' WITH
- ; TRAILING BLANKS IF NECESSARY.
- ;
- STRING:
- LXI H,MSGBK
- CALL MSG
- LXI H,2020H ;PUT SPACES
- SHLD BUFF ;INTO 4 BYTE
- SHLD BUFF+2 ;BUFFER.
- LXI H,BUFF
- MVI E,4
- STR1:
- CALL CHIN ;LOOK FOR
- CPI CR ;<CR> TERMINATOR
- JZ NEXT
- JMP STR3
- STR2:
- CALL CHIN ;GET A CHARACTER.
- STR3:
- CPI CR ;LOOK FOR
- RZ ;<CR> OR
- CPI ' ' ;SPACE AS
- RZ ;DELIMITER.
- DCR E ;ONLY THE FIRST
- JM STR2 ;4 BYTES
- MOV M,A ;ARE STORED.
- INX H
- JMP STR2
- ;
- ;**** STRING COMPARE ROUTINE.
- ; ON INPUT, HL=START OF TEST TABLE
- ; B=BYTE COUNT PER ENTRY.
- ; GOOD OUTPUT, CARRY CLI, ACC=OFFSET VALUE.
- ; BAD OUTPUT, CARRY SET, ACC=0FFH.
- ;
- STCOMP:
- MVI C,0 ;CLEAR COUNTER.
- STC0:
- PUSH B ;SAVE COUNTER AND STRING SIZE.
- LXI D,BUFF ;GET BUFFER START.
- STC1:
- LDAX D ;GET TEST BYTE.
- CMP M ;SEE IF DIFFERENT.
- JNZ STC2
- DCR B ;OR IF ALL BYTES CHECK.
- JZ STC5
- INX D ;BUMP POINTERS
- INX H ;AND THEN
- JMP STC1 ;TRY AGAIN.
- STC2:
- MOV A,M ;DIFFERENT. SAVE CURRENT BYTE.
- STC3:
- DCR B ;BUMP
- INX H ;PAST
- JZ STC4 ;THIS
- JMP STC3 ;BYTE.
- STC4:
- POP B ;RETRIEVE COUNTERS,
- INR C ;BUMP COUNTER,
- CPI 0FFH ;SEE IF E.O.T.
- JZ STC6
- JMP STC0 ;TRY AGAIN.
- STC5:
- POP B ;FOUND A MATCH.
- MOV A,C ;RETURN ENTRY
- ORA A ;IN ACC WITH
- RET ;CARRY RESET.
- STC6:
- STC ;ERROR RETURN
- RET ;SETS CARRY ONLY.
- ;
- MSGBK: DB ' ',0FFH
- ;
- ;**** OPERATION CODE TABLE.
- ; ARRANGED AS FOLLOWS, ACCORDING TO INSTRUCTION
- ; FIRST BYTE VALUE (0-255):-
- ;
- ; FIRST BYTE IS INSTRUCTION SIZE (BYTES)
- ; NEXT 4 BYTES ARE OPCODE.
- ; NEXT BYTE IS ATAB3 ENTRY NUMBER.
- ;
- ATAB1:
- DB 1,0,0
- DB 3,1,1
- DB 1,2,1
- DB 1,6,1
- DB 1,8,1
- DB 1,9,1
- DB 2,30,1
- DB 1,10,0
- DB 1,88,0
- DB 1,14,1
- DB 1,3,1
- DB 1,7,1
- DB 1,8,2
- DB 1,9,2
- DB 2,30,2
- DB 1,11,0
- DB 1,88,0
- DB 3,1,3
- DB 1,2,3
- DB 1,6,3
- DB 1,8,3
- DB 1,9,3
- DB 2,30,3
- DB 1,12,0
- DB 1,88,0
- DB 1,14,3
- DB 1,3,3
- DB 1,7,3
- DB 1,8,4
- DB 1,9,4
- DB 2,30,4
- DB 1,13,0
- DB 1,85,0
- DB 3,1,5
- DB 3,4,0
- DB 1,6,5
- DB 1,8,5
- DB 1,9,5
- DB 2,30,5
- DB 1,15,0
- DB 1,88,0
- DB 1,14,5
- DB 3,5,0
- DB 1,7,5
- DB 1,8,6
- DB 1,9,6
- DB 2,30,6
- DB 1,16,0
- DB 1,86,0
- DB 3,1,9
- DB 3,17,0
- DB 1,6,9
- DB 1,8,7
- DB 1,9,7
- DB 2,30,7
- DB 1,19,0
- DB 1,88,0
- DB 1,14,9
- DB 3,18,0
- DB 1,7,9
- DB 1,8,8
- DB 1,9,8
- DB 2,30,8
- DB 1,20,0
- DB 1,21,11
- DB 1,21,12
- DB 1,21,13
- DB 1,21,14
- DB 1,21,15
- DB 1,21,16
- DB 1,21,17
- DB 1,21,18
- DB 1,21,19
- DB 1,21,20
- DB 1,21,21
- DB 1,21,22
- DB 1,21,23
- DB 1,21,24
- DB 1,21,25
- DB 1,21,26
- DB 1,21,27
- DB 1,21,28
- DB 1,21,29
- DB 1,21,30
- DB 1,21,31
- DB 1,21,32
- DB 1,21,33
- DB 1,21,34
- DB 1,21,35
- DB 1,21,36
- DB 1,21,37
- DB 1,21,38
- DB 1,21,39
- DB 1,21,40
- DB 1,21,41
- DB 1,21,42
- DB 1,21,43
- DB 1,21,44
- DB 1,21,45
- DB 1,21,46
- DB 1,21,47
- DB 1,21,48
- DB 1,21,49
- DB 1,21,50
- DB 1,21,51
- DB 1,21,52
- DB 1,21,53
- DB 1,21,54
- DB 1,21,55
- DB 1,21,56
- DB 1,21,57
- DB 1,21,58
- DB 1,21,59
- DB 1,21,60
- DB 1,21,61
- DB 1,21,62
- DB 1,21,63
- DB 1,21,64
- DB 1,76,0
- DB 1,21,66
- DB 1,21,67
- DB 1,21,68
- DB 1,21,69
- DB 1,21,70
- DB 1,21,71
- DB 1,21,72
- DB 1,21,73
- DB 1,21,74
- DB 1,22,1
- DB 1,22,2
- DB 1,22,3
- DB 1,22,4
- DB 1,22,5
- DB 1,22,6
- DB 1,22,7
- DB 1,22,8
- DB 1,23,1
- DB 1,23,2
- DB 1,23,3
- DB 1,23,4
- DB 1,23,5
- DB 1,23,6
- DB 1,23,7
- DB 1,23,8
- DB 1,24,1
- DB 1,24,2
- DB 1,24,3
- DB 1,24,4
- DB 1,24,5
- DB 1,24,6
- DB 1,24,7
- DB 1,24,8
- DB 1,25,1
- DB 1,25,2
- DB 1,25,3
- DB 1,25,4
- DB 1,25,5
- DB 1,25,6
- DB 1,25,7
- DB 1,25,8
- DB 1,26,1
- DB 1,26,2
- DB 1,26,3
- DB 1,26,4
- DB 1,26,5
- DB 1,26,6
- DB 1,26,7
- DB 1,26,8
- DB 1,27,1
- DB 1,27,2
- DB 1,27,3
- DB 1,27,4
- DB 1,27,5
- DB 1,27,6
- DB 1,27,7
- DB 1,27,8
- DB 1,28,1
- DB 1,28,2
- DB 1,28,3
- DB 1,28,4
- DB 1,28,5
- DB 1,28,6
- DB 1,28,7
- DB 1,28,8
- DB 1,29,1
- DB 1,29,2
- DB 1,29,3
- DB 1,29,4
- DB 1,29,5
- DB 1,29,6
- DB 1,29,7
- DB 1,29,8
- DB 1,42,0
- DB 1,66,1
- DB 3,43,0
- DB 3,40,0
- DB 3,44,0
- DB 1,67,1
- DB 2,31,0
- DB 1,77,0
- DB 1,45,0
- DB 1,39,0
- DB 3,46,0
- DB 1,88,0
- DB 3,47,0
- DB 3,41,0
- DB 2,32,0
- DB 1,78,0
- DB 1,48,0
- DB 1,66,3
- DB 3,49,0
- DB 2,72,0
- DB 3,50,0
- DB 1,67,3
- DB 2,33,0
- DB 1,79,0
- DB 1,51,0
- DB 1,88,0
- DB 3,52,0
- DB 2,73,0
- DB 3,53,0
- DB 1,88,0
- DB 2,34,0
- DB 1,80,0
- DB 1,54,0
- DB 1,66,5
- DB 3,55,0
- DB 1,68,0
- DB 3,56,0
- DB 1,67,5
- DB 2,35,0
- DB 1,81,0
- DB 1,57,0
- DB 1,69,0
- DB 3,58,0
- DB 1,70,0
- DB 3,59,0
- DB 1,88,0
- DB 2,36,0
- DB 1,82,0
- DB 1,60,0
- DB 1,66,10
- DB 3,61,0
- DB 1,74,0
- DB 3,62,0
- DB 1,67,10
- DB 2,37,0
- DB 1,83,0
- DB 1,63,0
- DB 1,71,0
- DB 3,64,0
- DB 1,75,0
- DB 3,65,0
- DB 1,88,0
- DB 2,38,0
- DB 1,84,0
- ;
- ;**** ATAB2 CONTAINS ALL OPCODES.
- ;
- ATAB2:
- DB 'NOP '
- DB 'LXI '
- DB 'STAX'
- DB 'LDAX'
- DB 'SHLD'
- DB 'LHLD'
- DB 'INX '
- DB 'DCX '
- DB 'INR '
- DB 'DCR '
- DB 'RLC '
- DB 'RRC '
- DB 'RAL '
- DB 'RAR '
- DB 'DAD '
- DB 'DAA '
- DB 'CMA '
- DB 'STA '
- DB 'LDA '
- DB 'STC '
- DB 'CMC '
- DB 'MOV '
- DB 'ADD '
- DB 'ADC '
- DB 'SUB '
- DB 'SBB '
- DB 'ANA '
- DB 'XRA '
- DB 'ORA '
- DB 'CMP '
- DB 'MVI '
- DB 'ADI '
- DB 'ACI '
- DB 'SUI '
- DB 'SBI '
- DB 'ANI '
- DB 'XRI '
- DB 'ORI '
- DB 'CPI '
- DB 'RET '
- DB 'JMP '
- DB 'CALL'
- DB 'RNZ '
- DB 'JNZ '
- DB 'CNZ '
- DB 'RZ '
- DB 'JZ '
- DB 'CZ '
- DB 'RNC '
- DB 'JNC '
- DB 'CNC '
- DB 'RC '
- DB 'JC '
- DB 'CC '
- DB 'RPO '
- DB 'JPO '
- DB 'CPO '
- DB 'RPE '
- DB 'JPE '
- DB 'CPE '
- DB 'RP '
- DB 'JP '
- DB 'CP '
- DB 'RM '
- DB 'JM '
- DB 'CM '
- DB 'POP '
- DB 'PUSH'
- DB 'XTHL'
- DB 'PCHL'
- DB 'XCHG'
- DB 'SPHL'
- DB 'OUT '
- DB 'IN '
- DB 'DI '
- DB 'EI '
- DB 'HLT '
- DB 'RST0'
- DB 'RST1'
- DB 'RST2'
- DB 'RST3'
- DB 'RST4'
- DB 'RST5'
- DB 'RST6'
- DB 'RST7'
- DB 'RIM '
- DB 'SIM '
- AT2E: DB 0FFH,0FFH,0FFH,0FFH
- DB '--- '
- ;
- ;**** ATAB3 CONTAINS ALL POSSIBLE OPERANDS.
- ;
- ATAB3:
- DB ' '
- DB 'B '
- DB 'C '
- DB 'D '
- DB 'E '
- DB 'H '
- DB 'L '
- DB 'M '
- DB 'A '
- DB 'SP '
- DB 'PSW'
- DB 'B,B'
- DB 'B,C'
- DB 'B,D'
- DB 'B,E'
- DB 'B,H'
- DB 'B,L'
- DB 'B,M'
- DB 'B,A'
- DB 'C,B'
- DB 'C,C'
- DB 'C,D'
- DB 'C,E'
- DB 'C,H'
- DB 'C,L'
- DB 'C,M'
- DB 'C,A'
- DB 'D,B'
- DB 'D,C'
- DB 'D,D'
- DB 'D,E'
- DB 'D,H'
- DB 'D,L'
- DB 'D,M'
- DB 'D,A'
- DB 'E,B'
- DB 'E,C'
- DB 'E,D'
- DB 'E,E'
- DB 'E,H'
- DB 'E,L'
- DB 'E,M'
- DB 'E,A'
- DB 'H,B'
- DB 'H,C'
- DB 'H,D'
- DB 'H,E'
- DB 'H,H'
- DB 'H,L'
- DB 'H,M'
- DB 'H,A'
- DB 'L,B'
- DB 'L,C'
- DB 'L,D'
- DB 'L,E'
- DB 'L,H'
- DB 'L,L'
- DB 'L,M'
- DB 'L,A'
- DB 'M,B'
- DB 'M,C'
- DB 'M,D'
- DB 'M,E'
- DB 'M,H'
- DB 'M,L'
- DB 'M,M'
- DB 'M,A'
- DB 'A,B'
- DB 'A,C'
- DB 'A,D'
- DB 'A,E'
- DB 'A,H'
- DB 'A,L'
- DB 'A,M'
- DB 'A,A'
- AT3E: DB 0FFH,0FFH,0FFH
- ;
- ; LOAD HEX OBJECT TAPE.
- ;
- ; LOAD A HEX-BINARY TAPE AS PRODUCED BY THE 'P'
- ; COMMAND.
- ; MAY CONTAIN AN OFFSET VALUE, ALLOWING THE DATA TO
- ; BE LOADED INTO A DIFFERENT LOCATION TO THAT SPECIFIED
- ; BY THE LOAD ADDRESS.
- ;
- ;
- SPORT EQU 083H
- DPORT EQU 083H
- SPKT EQU 080H
- ;
- ORG ROM+0F40H
- ;
- LOADF:
- CALL PUWB ;GET THE OFFSET, IF ANY.
- JNC LD4F
- CPI CR ;ERROR MAY ONLY BE <CR>
- JNZ ILLEG
- LD4F:
- CALL CRLF ;NEW LINE PLEASE.
- PUSH H ;SAVE BIAS ADR
- LD5F:
- POP H ;GET BIAS
- PUSH H ;AND RESTORE
- CALL RIXF ;GET INPUT
- MVI B,':' ;WAIT FOR ':'
- SUB B
- JNZ LD5F ;TRY AGAIN
- MOV D,A ;CLEAR CKSUM
- CALL BYTEF ;GET LENGTH
- JZ LD7F ;ZERO MEANS ALL DONE
- MOV E,A ;SAVE LENGTH
- CALL BYTEF
- PUSH PSW ;SAVE HI ADR
- CALL BYTEF
- POP B ;FETCH MSBYTE
- MOV C,A ;BC NOW HAS ADR
- PUSH B ;SAVE IT
- XTHL ;INTO HL
- SHLD BLKAD ;SAVE BLOCK ADR
- XTHL ;IN CASE OF ERROR
- POP B
- DAD B ;RESTORE AND ADD BIAS
- CALL BYTEF ;RECORD TYPE INPUT
- LD6F:
- CALL BYTEF ;GET DATA BYTES
- CALL STORE ;STORE
- INX H
- DCR E
- JNZ LD6F ;GO ON.
- CALL BYTEF ;GET CKSUM
- JZ LD5F
- LDERRF:
- LXI H,M6 ;CKSUM ERROR
- CALL MSG
- LHLD BLKAD ;ADR OF THIS BLOCK IS
- JMP RXAR ;NOW GIVEN
- LD7F:
- CALL BYTEF ;MSB OF XEQAD
- MOV H,A
- CALL BYTEF
- MOV L,A
- ORA H
- JZ NEXT ;MONITOR IF ADR=0
- PCHL ;OTHERWISE EXECUTE
- ;
- RIXF:
- CALL RIF
- JC ILLEG ;ON ERROR, PRINT '??'
- ANI 7FH ;REMOVE PARITY
- RET
- ;
- ; ROUTINE RIF
- ; GETS A CHARACTER FROM THE FAST READER INPUT
- ; I.E. IT STARTS THE READER, AND EXPECTS QUICK REPLY.
- ;
- ;
- RIF:
- PUSH B ;SAVE BC
- PUSH D ;AND DE
- RIF05:
- MVI C,SPKT ;PRESET CURRENT STATUS
- LXI D,0 ;TIMEOUT COUNT.
- RIF10:
- IN SPORT ;GET STATUS.
- ANI SPKT ;LOOK AT SPROCKET ONLY.
- MOV B,A ;SAVE IT.
- MOV A,C ;OLD STATUS
- CMA ;IS INVERTED
- ANA B ;SO THAT + EDGE IS FOUND.
- MOV C,B ;SAVE CURRENT STATUS.
- JNZ RIF15 ;NON-ZERO=GOT IT.
- DCX D ;DROP T/O COUNT
- MOV A,D ;SEE IF
- ORA E ;COUNT IS
- JNZ RIF10 ;ZERO YET.
- STC
- POP D
- POP B
- RET
- RIF15:
- IN DPORT ;AND GET DATA.
- ORA A ;CLEAR CARRY ONLY.
- POP D
- POP B ;RESTORE BC
- RET ;SIMPLY RETURN
- ;
- BYTEF:
- PUSH B ;SAVE BC
- CALL RIXF ;READ ASCII
- CALL CNVBN ;CONVERT TO HEX
- JC LDERR ;ERROR DETECTOR.
- RLC ;SHIFT LEFT 4 BITS
- RLC
- RLC
- RLC
- MOV B,A ;SAVE THEM A WHILE
- CALL RIXF ;GET SECOND BYTE
- CALL CNVBN ;CONVERT TO HEX
- JC LDERR ;ERROR DETECTOR
- ORA B ;OR IN THE SAVED NYBBLE
- MOV C,A ;HOLD BYTE A WHILE.
- ADD D ;ADD TO CKSUM
- MOV D,A ;UPDATE CKSUM
- MOV A,C ;RESTORE BYTE
- POP B ;RESTORE BC
- RET
- ;
- ;
- ; END OF ROM ROUTINES.
- ;
- ;
- ENDROM EQU $
- ;
- ;
- ; SYSTEM RAM AREA DEFINITION.
- ;
- ;
- ORG RAM
- ;
- ; STACK GOES IN HERE, PACKING DOWN FROM
- ; STORAGE AREA.
- ;
- ORG REGS
- ;
- ; MONITOR REG. SAVE AREA.
- ;
- SVPC:
- SVPCL: DS 1 ;SAVED PC LOW
- SVPCH: DS 1 ;SAVED PC HI
- SVSP:
- SVSPL: DS 1 ;SAVED SP LOW
- SVSPH: DS 1 ;SAVED SP HI
- SVHL:
- SVL: DS 1 ;SAVED L
- SVH: DS 1 ;SAVED H
- SVE: DS 1 ;SAVED E
- SVD: DS 1 ;SAVED D
- SVC: DS 1 ;SAVED C
- SVB: DS 1 ;SAVED B
- SVF: DS 1 ;SAVED PSB, FLAGS
- SVA: DS 1 ;SAVED ACC
- ;
- ; SPECIALS USED BY MONITOR
- ;
- BUFF:
- TMPA:
- GOGO: DS 3
- DSA: DS 2 ;START OF ROM DATA
- OPCODE:
- DFA: DS 2 ;END OF ROM DATA
- MEMADR:
- ROMADR: DS 2 ;PROM ADDRESS POINTER.
- ECHO: DS 1 ;CHARACTER ECHO FLAG 0=NO ECHO
- ADR: DS 2 ;EXAMINE/MODIFY ADR
- XEQAD: DS 2 ;'X' EXECUTION ADR
- BLKAD: DS 2 ;'L' BLOCK ADR
- BPADD: DS 2 ;BREAKPOINT SAVE ADDRESS
- BPDAT: DS 6 ;BREAKPOINT SAVE DATA
- USERA: DS 2 ;USER FUNCTION VECTOR ADDRESS
- ;
- ; USER VECTORS RST3-RST7
- ;
- RST3: DS 2
- RST4: DS 2
- RST5: DS 2
- RST6: DS 2
- RST7: DS 2
- ;
- ;
- END
-