; MACRO LIBRARY FOR A ZERO ADDRESS MACHINE ; ***************************************** ; * BEGIN TRACE/DUMP UTILITIES * ; ***************************************** BDOS EQU 0005H ;SYSTEM ENTRY RCHAR EQU 1 ;READ A CHARACTER WCHAR EQU 2 ;WRITE CHARACTER WBUFF EQU 9 ;WRITE BUFFER TRAN EQU 100H ;TRANSIENT PROGRAM AREA DATA EQU 1100H ;DATA AREA CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED ; DEBUGT SET 0 ;;TRACE DEBUG SET FALSE DEBUGP SET 0 ;;PRINT DEBUG SET FALSE ; PRN MACRO PR ;; PRINT MESSAGE 'PR' AT CONSOLE IF DEBUGP ;;PRINT DEBUG ON? LOCAL PMSG,MSG ;;LOCAL MESSAGE JMP PMSG ;;AROUND MESSAGE MSG: DB CR,LF ;;RETURN CARRIAGE DB '&PR$' ;;LITERAL MESSAGE PMSG: PUSH H ;;SAVE TOP ELEMENT OF STACK LXI D,MSG ;;LOCAL MESSAGE ADDRESS MVI C,WBUFF ;;WRITE BUFFER 'TIL $ CALL BDOS ;;PRINT IT POP H ;;RESTORE TOP OF STACK ENDIF ;;END TEST DEBUGP ENDM ; UGEN MACRO ;; GENERATE UTILITIES FOR TRACE OR DUMP LOCAL PSUB JMP PSUB ;;JUMP PAST SUBROUTINES @CH: ;;WRITE CHARACTER IN REG-A MOV E,A MVI C,WCHAR JMP BDOS ;;RETURN THRU BDOS ;; @NB: ;;WRITE NIBBLE IN REG-A ADI 90H DAA ACI 40H DAA JMP @CH ;;RETURN THRU @CH ;; @HX: ;;WRITE HEX VALUE IN REG-A PUSH PSW ;;SAVE LOW BYTE RRC RRC RRC RRC ANI 0FH ;;MASK HIGH NIBBLE CALL @NB ;;PRINT HIGH NIBBLE POP PSW ANI 0FH JMP @NB ;;PRINT LOW NIBBLE ;; @AD ;;WRITE ADDRESS VALUE IN HL PUSH H ;;SAVE VALUE MVI A,' ' ;;LEADING BLANK CALL @CH ;;AHEAD OF ADDRESS POP H ;;HIGH BYTE TO A MOV A,H PUSH H ;;COPY BACK TO STACK CALL @HX ;;WRITE HIGH BYTE POP H MOV A,L ;;LOW BYTE JMP @HX ;;WRITE LOW BYTE ; @IN: ;;READ HEX VALUE TO HL FROM CONSOLE MVI A,' ' ;;LEADING SPACE CALL @CH ;;TO CONSOLE LXI H,0 ;;STARTING VALUE @IN0: PUSH H ;;SAVE IT FOR CHAR READ MVI C,RCHAR ;;READ CHARACTER FUNCTION CALL BDOS ;;READ TO ACCUMULATOR POP H ;;VALUE BEING BUILT IN HL SUI '0' ;;NORMALIZE TO BINARY CPI 10 ;;DECIMAL? JC @IN1 ;;CARRY IF 0,1,...,9 ;; MAY BE HEXADECIMAL A,...,F SUI 'A'-'0'-10 CPI 16 ;;A THROUGH F? RNC ;;RETURN WITH ASSUMED CR @IN1: ;;IN RANGE, MULTIPLY BY 4 AND ADD REPT 4 DAD H ;;SHIFT 4 ENDM ORA L ;;ADD DIGIT MOV L,A ;;AND REPLACE VALUE JMP @IN0 ;;FOR ANOTHER DIGIT ;; PSUB: UGEN MACRO ;; REDEF TO INCLUDE ONCE ENDM UGEN ;;GENERATE FIRST TIME ENDM ; ***************************************** ; * END OF TRACE/DUMP UTILITIES * ; * BEGIN TRACE(ONLY) UTILITIES * ; ***************************************** TRACE MACRO CODE,MNAME ;; TRACE MACRO GIVEN BY MNAME, ;; AT LOCATION GIVEN BY CODE LOCAL PSUB UGEN ;;GENERATE UTILITIES JMP PSUB @T1: DS 2 ;;TEMP FOR REG-1 @T2: DS 2 ;;TEMP FOR REG-2 ;; @TR: ;;TRACE MACRO CALL ;; BC=CODE ADDRESS, DE=MESSAGE SHLD @T1 ;;STORE TOP REG POP H ;;RETURN ADDRESS XTHL ;;REG-2 TO TOP SHLD @T2 ;;STORE TO TEMP PUSH PSW ;;SAVE FLAGS PUSH B ;;SAVE RET ADDRESS MVI C,WBUFF ;;PRINT BUFFER FUNC CALL BDOS ;;PRINT MACRO NAME POP H ;;CODE ADDRESS CALL @AD ;;PRINTED LHLD @T1 ;;TOP OF STACK CALL @AD ;;PRINTED LHLD @T2 ;;TOP-1 CALL @AD ;;PRINTED POP PSW ;;FLAGS RESTORED POP D ;;RETURN ADDRESS LHLD @T2 ;;TOP-1 PUSH H ;;RESTORED PUSH D ;;RETURN ADDRESS LHLD @T1 ;;TOP OF STACK RET ;; PSUB: ;;PAST SUBROUTINES ;; TRACE MACRO C,M ;; REDEFINED TRACE, USES @TR LOCAL PMSG,MSG JMP PMSG MSG: DB CR,LF ;;CR,LF DB '&M$' ;;MAC NAME PMSG: LXI B,C ;;CODE ADDRESS LXI D,MSG ;;MACRO NAME CALL @TR ;;TO TRACE IT ENDM ;; BACK TO ORIGINAL MACRO LEVEL TRACE CODE,MNAME ENDM ; TRT MACRO F ;; TURN ON FLAG "F" DEBUG&F SET 1 ;;PRINT/TRACE ON ENDM ; TRF MACRO F ;; TURN OFF FLAG "F" DEBUG&F SET 0 ;;TRACE/PRINT OFF ENDM ; ?TR MACRO M ;; CHECK DEBUGT TOGGLE BEFORE TRACE IF DEBUGT TRACE %$,M ENDM ; ***************************************** ; * END TRACE (ONLY) UTILITIES * ; * BEGIN DUMP(ONLY) UTILITIES * ; ***************************************** DMP MACRO VNAME,N ;; DUMP VARIABLE VNAME FOR ;; N ELEMENTS (DOUBLE BYTES) LOCAL PSUB ;;PAST SUBROUTINES UGEN ;;GEN INLINE ROUTINES JMP PSUB ;;PAST LOCAL SUBROUTINES @DM: ;;DUMP UTILITY PROGRAM ;; DE=MSG ADDRESS, C=ELEMENT COUNT ;; HL=BASE ADDRESS TO PRINT PUSH H ;;BASE ADDRESS PUSH B ;;ELEMENT COUNT MVI C,WBUFF ;;WRITE BUFFER FUNC CALL BDOS ;;MESSAGE WRITTEN @DM0: POP B ;;RECALL COUNT POP H ;;RECALL BASE ADDRESS MOV A,C ;;END OF LIST? ORA A RZ ;;RETURN IF SO DCR C ;;DECREMENT COUNT MOV E,M ;;NEXT ITEM (LOW) INX H MOV D,M ;;NEXT ITEM (HIGH) INX H ;;READY FOR NEXT ROUND PUSH H ;;SAVE PRINT ADDRESS PUSH B ;;SAVE COUNT XCHG ;;DATA READY CALL @AD ;;PRINT ITEM VALUE JMP @DM0 ;;FOR ANOTHER VALUE ;; @DT: ;;DUMP TOP OF STACK ONLY PRN <(TOP)=> ;;"(TOP)=" PUSH H CALL @AD ;;VALUE OF HL POP H ;;TOP RESTORED RET ;; PSUB: ;; DMP MACRO ?V,?N ;; REDEFINE DUMP TO USE @DM UTILITY LOCAL PMSG,MSG ;; SPECIAL CASE IF NULL PARAMETERS IF NUL VNAME ;; DUMP THE TOP OF THE STACK ONLY CALL @DT EXITM ENDIF ;; OTHERWISE DUMP VARIABLE NAME JMP PMSG MSG: DB CR,LF ;;CRLF DB '&?V=$' ;;MESSAGE PMSG: ADR ?V ;;HL=ADDRESS ACTIVE: SET 0 ;;CLEAR ACTIVE FLAG LXI D,MSG IF NUL ?N ;;USE LENGTH 1 MVI C,1 ELSE MVI C,?N ENDIF CALL @DM ENDM DMP VNAME,N ENDM ; ; ; ***************************************** * END DUMP (ONLY) UTILITIES, * ; * BEGIN STACK MACHINE OPCODES * ; *****************************************