Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM II/MPM II SOURCE/CONTROL/DSTACK.LIB
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

468 lines
9.5 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; 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 ;;MESSAGE TO PRINT
IF NUL ?N ;;USE LENGTH 1
MVI C,1
ELSE
MVI C,?N
ENDIF
CALL @DM ;;TO PERFORM THE DUMP
ENDM ;;END OF REDEFINITION
DMP VNAME,N
ENDM
;
; *****************************************
; * END DUMP (ONLY) UTILITIES, *
; * BEGIN STACK MACHINE OPCODES *
; *****************************************
ACTIVE SET 0 ;ACTIVE REGISTER FLAG
;
SIZ MACRO SIZE
ORG TRAN ;;SET TO TRANSIENT AREA
;; CREATE A STACK WHEN "XIT" ENCOUNTERED
@STK SET SIZE ;;SAVE FOR DATA AREA
LXI SP,STACK
ENDM
;
SAVE MACRO
;; CHECK TO ENSURE "ENTER" PROPERLY SET UP
IF STACK ;;IS IT PRESENT?
ENDIF
SAVE MACRO ;;REDEFINE AFTER INITIAL REFERENCE
IF ACTIVE ;;ELEMENT IN HL
PUSH H ;;SAVE IT
ENDIF
ACTIVE SET 1 ;;SET ACTIVE
ENDM
SAVE
ENDM
;
REST MACRO
;; RESTORE THE TOP ELEMENT
IF NOT ACTIVE
POP H ;;RECALL TO HL
ENDIF
ACTIVE SET 1 ;;MARK AS ACTIVE
ENDM
;
CLEAR MACRO
;; CLEAR THE TOP ACTIVE ELEMENT
REST ;;ENSURE ACTIVE
ACTIVE SET 0 ;;CLEARED
ENDM
;
DCL MACRO VNAME,SIZE
;; LABEL THE DECLARATION
VNAME:
IF NUL SIZE
DS 2 ;;ONE WORD REQ'D
ELSE
DS SIZE*2 ;;DOUBLE WORDS
ENDM
;
LIT MACRO VAL
;; LOAD LITERAL VALUE TO TOP OF STACK
SAVE ;;SAVE IF ACTIVE
LXI H,VAL ;;LOAD LITERAL
?TR LIT
ENDM
;
ADR MACRO BASE,INX,CON
;; LOAD ADDRESS OF BASE, INDEXED BY INX,
;; WITH CONSTANT OFFSET GIVEN BY CON
SAVE ;;PUSH IF ACTIVE
IF NUL INX&CON
LXI H,BASE ;;ADDRESS OF BASE
EXITM ;;SIMPLE ADDRESS
ENDIF
;; MUST BE INX AND/OR CON
IF NUL INX
LXI H,CON*2 ;;CONSTANT
ELSE
LHLD INX ;;INDEX TO HL
DAD H ;;DOUBLE PRECISION INX
IF NOT NUL CON
LXI D,CON*2 ;;DOUBLE CONST
DAD D ;;ADDED TO INX
ENDIF ;;NOT NUL CON
ENDIF ;;NUL INX
LXI D,BASE ;;READY TO ADD
DAD D ;;BASE+INX*2+CON*2
ENDM
;
VAL MACRO B,I,C
;; GET VALUE OF B+I+C TO HL
;; CHECK SIMPLE CASE OF B ONLY
IF NUL I&C
SAVE ;;PUSH IF ACTIVE
LHLD B ;;LOAD DIRECTLY
ELSE
;; "ADR" PUSHES ACTIVE REGISTERS
ADR B,I,C ;;ADDRESS IN HL
MOV E,M ;;LOW ORDER BYTE
INX H
MOV D,M ;;HIGH ORDER BYTE
XCHG ;;BACK TO HL
ENDIF
?TR VAL ;;TRACE SET?
ENDM
;
STO MACRO B,I,C
;; STORE THE VALUE OF THE TOP OF STACK
;; LEAVING THE TOP ELEMENT ACTIVE
IF NUL I&C
REST ;;ACTIVATE STACK
SHLD B ;;STORED DIRECTLY TO B
ELSE
ADR B,I,C
POP D ;;VALUE IS IN DE
MOV M,E ;;LOW BYTE
INX H
MOV M,D ;;HIGH BYTE
ENDIF
CLEAR ;;MARK EMPTY
?TR STO ;;TRACE?
ENDM
;
SUM MACRO
REST ;;RESTORE IF SAVED
;; ADD THE TOP TWO STACK ELEMENTS
POP D ;;TOP-1 TO DE
DAD D ;;BACK TO HL
?TR SUM
ENDM
;
DIF MACRO
;; COMPUTE DIFFERENCE BETWEEN TOP ELEMENTS
REST ;;RESTORE IF SAVED
POP D ;;TOP-1 TO DE
MOV A,E ;;TOP-1 LOW BYTE TO A
SUB L ;;LOW ORDER DIFFERENCE
MOV L,A ;;BACK TO L
MOV A,D ;;TOP-1 HIGH BYTE
SBB H ;;HIGH ORDER DIFFERENCE
MOV H,A ;;BACK TO H
;; CARRY FLAG MAY BE SET UPON RETURN
?TR DIF
ENDM
;
LSR MACRO LEN
;; LOGICAL SHIFT RIGHT BY LEN
REST ;;ACTIVATE STACK
REPT LEN ;;GENERATE INLINE
XRA A ;;CLEAR CARRY
MOV A,H
RAR ;;ROTATE WITH HIGH 0
MOV H,A
MOV A,L
RAR
MOV L,A ;;BACK WITH HIGH BIT
ENDM
ENDM
;
GEQ MACRO LAB
;; JUMP TO LAB IF (TOP-1) IS GREATER OR
;; EQUAL TO (TOP) ELEMENT.
DIF ;;COMPUTE DIFFERENCE
CLEAR ;;CLEAR ACTIVE
?TR GEQ
JNC LAB ;;NO CARRY IF GREATER
ORA H ;;BOTH BYTES ZERO?
JZ LAB ;;ZERO IF EQUAL
;; DROP THROUGH IF NEITHER
ENDM
;
DUP MACRO
;; DUPLICATE THE TOP ELEMENT IN THE STACK
REST ;;ENSURE ACTIVE
PUSH H
?TR DUP
ENDM
;
BRN MACRO ADDR
;; BRANCH TO ADDRESS
JMP ADDR
ENDM
;
XIT MACRO
?TR XIT ;;TRACE ON?
JMP 0 ;;RESTART AT 0000
ORG DATA ;;START DATA AREA
DS @STK*2 ;;OBTAINED FROM "SIZ"
STACK: ENDM
;
; *****************************************
; * MEMORY MAPPED I/O SECTION *
; *****************************************
; INPUT VALUES WHICH ARE READ AS IF IN MEMORY
ADC0 EQU 1080H ;A-D CONVERTER 0
ADC1 EQU 1082H ;A-D CONVERTER 1
ADC2 EQU 1084H ;A-D CONVERTER 2
ADC3 EQU 1086H ;A-D CONVERTER 3
;
DAC0 EQU 1090H ;D-A CONVERTER 0
DAC1 EQU 1092H ;D-A CONVERTER 1
DAC2 EQU 1094H ;D-A CONVERTER 2
DAC3 EQU 1096H ;D-A CONVERTER 3
;
RWTRACE MACRO MSG,ADR
;; READ OR WRITE TRACE WITH MESSAGE
;; GIVEN BY "MSG" TO/FROM "ADR"
PRN <MSG AT ADR>
ENDM
;
RDM MACRO ?C
;; READ A-D CONVERTER NUMBER "?C"
SAVE ;;CLEAR THE STACK
IF DEBUGP ;;STOP EXECUTION IN DDT
RWTRACE <A-D INPUT >,% ADC&?C
UGEN ;;ENSURE @IN IS PRESENT
CALL @IN ;;VALUE TO HL
SHLD ADC&?C ;;SIMULATE MEMORY INPUT
ELSE
;; READ FROM MEMORY MAPPED INPUT ADDRESS
LHLD ADC&?C
ENDIF
?TR RDM ;;TRACING?
ENDM
;
WRM MACRO ?C
;; WRITE D-A CONVERTER NUMBER "?C"
REST ;;RESTORE STACK
IF DEBUGP ;;TRACE THE OUTPUT
RWTRACE <D-A OUTPUT>,% DAC&?C
UGEN ;;INCLUDE SUBROUTINES
CALL @AD ;;WRITE THE VALUE
ENDIF
SHLD DAC&?C
?TR WRM ;;TRACING OUTPUT?
CLEAR ;;REMOVE THE VALUE
ENDM
; *****************************************
; * END OF MACRO LIBRARY *
; *****************************************