mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
727 lines
13 KiB
NASM
727 lines
13 KiB
NASM
TITLE 'ASM IO MODULE'
|
|
; I/O MODULE FOR CP/M ASSEMBLER
|
|
;
|
|
ORG 200H
|
|
BOOT EQU 000H ;REBOOT LOCATION
|
|
; I/O MODULE ENTRY POINTS
|
|
JMP INIT ;INITIALIZE, START ASSEMBLER
|
|
JMP SETUP ;FILE SETUP
|
|
JMP GNC ;GET NEXT CHARACTER
|
|
JMP PNC ;PUT NEXT OUTPUT CHARACTER
|
|
JMP PNB ;PUT NEXT HEX BYTE
|
|
JMP PCHAR ;PRINT CONSOLE CHARACTER
|
|
JMP PCON ;PRINT CONSOLE BUFFER TO CRLF
|
|
JMP WOBUFF ;WRITE OUTBUFFER
|
|
JMP PERR ;PLACE ERROR CHARACTER INTO PBUFF
|
|
JMP DHEX ;PLACE HEX BYTE INTO OUTPUT BUFFER
|
|
JMP EOR ;END OF ASSEMBLY
|
|
; DATA FOR I/O MODULE
|
|
BPC: DS 2 ;BASE PC FOR CURRENT HEX RECORD
|
|
DBL: DS 1 ;HEX BUFFER LENGTH
|
|
DBUFF: DS 16 ;HEX BUFFER
|
|
;
|
|
; DISK NAMES
|
|
CDISK: DS 1 ;CURRENTLY SELECTED DISK
|
|
ADISK: DS 1 ;.ASM DISK
|
|
PDISK: DS 1 ;.PRN DISK
|
|
HDISK: DS 1 ;.HEX DISK
|
|
;
|
|
;
|
|
;
|
|
; COMMON EQUATES
|
|
QBMAX EQU 120 ;MAX PRINT SIZE
|
|
QBUFF EQU 10CH ;PRINT BUFFER
|
|
QBP EQU QBUFF+QBMAX ;PRINT BUFFER POINTER
|
|
;
|
|
TOKEN EQU QBP+1 ;CURRENT TOKEN UDER SCAN
|
|
VALUE EQU TOKEN+1 ;VALUE OF NUMBER IN BINARY
|
|
ACCLEN EQU VALUE+2 ;ACCUMULATOR LENGTH
|
|
ACMAX EQU 64 ;MAX ACCUMULATOR LENGTH
|
|
ACCUM EQU ACCLEN+1
|
|
;
|
|
EVALUE EQU ACCUM+ACMAX ;VALUE FROM EXPRESSION ANALYSIS
|
|
;
|
|
SYTOP EQU EVALUE+2 ;CURRENT SYMBOL TOP
|
|
SYMAX EQU SYTOP+2 ;MAX ADDRESS+1
|
|
;
|
|
PASS EQU SYMAX+2 ;CURRENT PASS NUMBER
|
|
FPC EQU PASS+1 ;FILL ADDRESS FOR DHEX ROUTINE
|
|
ASPC EQU FPC+2 ;ASSEMBLER'S PSEUDO PC
|
|
;
|
|
CR EQU 0DH ;CARRIAGE RETURN
|
|
LF EQU 0AH ;LINE FEED
|
|
EOF EQU 1AH ;END OF FILE MARK
|
|
;
|
|
;
|
|
; DOS ENTRY POINTS
|
|
BDOS EQU 5H ;DOS ENTRY POINT
|
|
READC EQU 1 ;READ CONSOLE DEVICE
|
|
WRITC EQU 2 ;WRITE CONSOLE DEVICE
|
|
REDYC EQU 11 ;CONSOLE CHARACTER READY
|
|
SELECT EQU 14 ;SELECT DISK SPECIFIED BY REGISTER E
|
|
OPENF EQU 15 ;OPEN FILE
|
|
CLOSF EQU 16 ;CLOSE FILE
|
|
DELEF EQU 19 ;DELETE FILE
|
|
READF EQU 20 ;READ FILE
|
|
WRITF EQU 21 ;WRITE FILE
|
|
MAKEF EQU 22 ;MAKE A FILE
|
|
CSEL EQU 25 ;RETURN CURRENTLY SELECTED DISK
|
|
SETDM EQU 26 ;SET DMA ADDRESS
|
|
;
|
|
; FILE AND BUFFERING PARAMETERS
|
|
NSB EQU 8 ;NUMBER OF SOURCE BUFFERS
|
|
NPB EQU 6 ;NUMBER OF PRINT BUFFERS
|
|
NHB EQU 6 ;NUMBER OF HEX BUFFERS
|
|
;
|
|
SSIZE EQU NSB*128
|
|
PSIZE EQU NPB*128
|
|
HSIZE EQU NHB*128
|
|
;
|
|
; FILE CONTROL BLOCKS
|
|
SCB: DS 9 ;FILE NAME
|
|
DB 'ASM' ;FILE TYPE
|
|
SCBR: DS 1 ;REEL NUMBER (ZEROED IN SETUP)
|
|
DS 19 ;MISC AND DISK MAP
|
|
SCBCR: DS 1 ;CURRENT RECORD (ZEROED IN SETUP)
|
|
;
|
|
PCB: DS 9
|
|
DB 'PRN',0
|
|
DS 19
|
|
DB 0 ;RECORD TO WRITE NEXT
|
|
;
|
|
HCB: DS 9
|
|
DB 'HEX',0
|
|
DS 19
|
|
DB 0
|
|
;
|
|
; POINTERS AND BUFFERS
|
|
SBP: DW SSIZE ;NEXT CHARACTER POSITION TO READ
|
|
SBUFF: DS SSIZE
|
|
;
|
|
PBP: DW 0
|
|
PBUFF: DS PSIZE
|
|
;
|
|
HBP: DW 0
|
|
HBUFF: DS HSIZE
|
|
FCB EQU 5CH ;FILE CONTROL BLOCK ADDRESS
|
|
FNM EQU 1 ;POSITION OF FILE NAME
|
|
FLN EQU 9 ;FILE NAME LENGTH
|
|
BUFF EQU 80H ;INPUT DISK BUFFER ADDRESS
|
|
;
|
|
SEL: ;SELECT DISK IN REG-A
|
|
LXI H,CDISK
|
|
CMP M ;SAME?
|
|
RZ
|
|
MOV M,A ;CHANGE CURRENT DISK
|
|
MOV E,A
|
|
MVI C,SELECT
|
|
CALL BDOS
|
|
RET
|
|
;
|
|
SCNP: ;SCAN THE NEXT PARAMETER
|
|
INX H
|
|
MOV A,M
|
|
CPI ' '
|
|
JZ SCNP0
|
|
SBI 'A' ;NORMALIZE
|
|
RET
|
|
SCNP0: LDA CDISK
|
|
RET
|
|
;
|
|
PCON: ;PRINT MESSAGE AT H,L TO CONSOLE DEVICE
|
|
MOV A,M
|
|
CALL PCHAR
|
|
MOV A,M
|
|
INX H
|
|
CPI CR
|
|
JNZ PCON
|
|
MVI A,LF
|
|
CALL PCHAR
|
|
RET
|
|
;
|
|
FNAME: ;FILL NAME FROM DEFAULT FILE CONTROL BLOCK
|
|
LXI D,FCB
|
|
MVI B,FLN
|
|
FNAM0: LDAX D ;GET NEXT FILE CHARACTER
|
|
CPI '?'
|
|
JZ FNERR ;FILE NAME ERROR
|
|
MOV M,A ;STORE TO FILE CNTRL BLOCK
|
|
INX H
|
|
INX D
|
|
DCR B
|
|
JNZ FNAM0 ;FOR NEXT CHARACTER
|
|
RET
|
|
;
|
|
INIT: ;SET UP STACK AND FILES, START ASSEMBLER
|
|
LXI H,TITL
|
|
CALL PCON
|
|
JMP SET0
|
|
;
|
|
OPEN: ;OPEN FILE ADDRESSED BY D,E
|
|
MVI C,OPENF
|
|
CALL BDOS
|
|
CPI 255
|
|
RNZ
|
|
; OPEN ERROR
|
|
LXI H,ERROP
|
|
CALL PCON
|
|
JMP BOOT
|
|
;
|
|
CLOSE: ;CLOSE FILE ADDRESSED BY D,E
|
|
MVI C,CLOSF
|
|
CALL BDOS
|
|
CPI 255
|
|
RNZ ;CLOSE OK
|
|
LXI H,ERRCL
|
|
CALL PCON
|
|
JMP BOOT
|
|
;
|
|
DELETE: ;DELETE FILE ADDRESSED BY D,E
|
|
MVI C,DELEF
|
|
JMP BDOS
|
|
;
|
|
MAKE: ;MAKE FILE ADDRESSED BY D,E
|
|
MVI C,MAKEF
|
|
CALL BDOS
|
|
CPI 255
|
|
RNZ
|
|
; MAKE ERROR
|
|
LXI H,ERRMA
|
|
CALL PCON
|
|
JMP BOOT
|
|
;
|
|
SELA: LDA ADISK
|
|
CALL SEL
|
|
RET
|
|
;
|
|
NPR: ;RETURN ZERO FLAG IF NO PRINT FILE
|
|
LDA PDISK
|
|
CPI 'Z'-'A'
|
|
RZ
|
|
CPI 'X'-'A' ;CONSOLE
|
|
RET
|
|
;
|
|
SELP: LDA PDISK
|
|
CALL SEL
|
|
RET
|
|
;
|
|
SELH: LDA HDISK
|
|
CALL SEL
|
|
RET
|
|
;
|
|
SET0: ;SET UP FILES FOR INPUT AND OUTPUT
|
|
LDA FCB ;GET FIRST CHARACTER
|
|
CPI ' ' ;MAY HAVE FORGOTTEN NAME
|
|
JZ FNERR ;FILE NAME ERROR
|
|
MVI C,CSEL ;CURRENT DISK?
|
|
CALL BDOS ;GET IT TO REG-A
|
|
STA CDISK
|
|
;
|
|
; SCAN PARAMETERS
|
|
LXI H,FCB+FLN-1
|
|
CALL SCNP
|
|
STA ADISK
|
|
CALL SCNP
|
|
STA HDISK
|
|
CALL SCNP
|
|
STA PDISK
|
|
;
|
|
LXI H,SCB ;ADDRESS SOURCE FILE CONTROL BLOCK
|
|
CALL FNAME ;FILE NAME OBTAINED FROM DEFAULT FCB
|
|
;
|
|
CALL NPR ;Z OR X?
|
|
JZ NOPR
|
|
LXI H,PCB ;ADDRESS PRINT FILE CONTROL BLOCK
|
|
PUSH H ;SAVE A COPY FOR OPEN
|
|
PUSH H ;SAVE A COPY FOR DELETE
|
|
CALL FNAME ;FILL PCB
|
|
CALL SELP
|
|
POP D ;FCB ADDRESS
|
|
CALL DELETE
|
|
POP D ;FCB ADDRESS
|
|
CALL MAKE
|
|
;
|
|
NOPR: ;TEST FOR HEX FILE
|
|
LDA HDISK
|
|
CPI 'Z'-'A'
|
|
JZ NOHEX
|
|
LXI H,HCB
|
|
PUSH H
|
|
PUSH H
|
|
CALL FNAME
|
|
CALL SELH
|
|
POP D
|
|
CALL DELETE
|
|
POP D
|
|
CALL MAKE
|
|
;
|
|
; FILES SET UP, CALL ASSEMBLER
|
|
NOHEX: JMP ENDMOD
|
|
;
|
|
SETUP: ;SETUP INPUT FILE FOR SOURCE PROGRAM
|
|
LXI H,SSIZE
|
|
SHLD SBP ;CAUSE IMMEDIATE READ
|
|
XRA A ;ZERO VALUE
|
|
STA SCBR ;CLEAR REEL NUMBER
|
|
STA SCBCR ;CLEAR CURRENT RECORD
|
|
STA DBL ;CLEAR HEX BUFFER LENGTH
|
|
CALL SELA
|
|
LXI D,SCB
|
|
CALL OPEN
|
|
;
|
|
RET
|
|
;
|
|
FNERR: ;FILE NAME ERROR
|
|
LXI H,ERRFN
|
|
CALL PCON
|
|
JMP BOOT
|
|
;
|
|
;
|
|
GCOMP: ;COMPARE D,E AGAINS H,L
|
|
MOV A,D
|
|
CMP H
|
|
RNZ
|
|
MOV A,E
|
|
CMP L
|
|
RET
|
|
;
|
|
GNC: ;GET NEXT CHARACTER FROM SOURCE BUFFER
|
|
PUSH B
|
|
PUSH D
|
|
PUSH H ;ENVIRONMENT SAVED
|
|
LHLD SBP
|
|
LXI D,SSIZE
|
|
CALL GCOMP
|
|
JNZ GNC2
|
|
;
|
|
; READ ANOTHER BUFFER
|
|
CALL SELA
|
|
LXI H,0
|
|
SHLD SBP
|
|
MVI B,NSB ;NUMBER OF SOURCE BUFFERS
|
|
LXI H,SBUFF
|
|
GNC0: ;READ 128 BYTES
|
|
PUSH B ;SAVE COUNT
|
|
PUSH H ;SAVE BUFFER ADDRESS
|
|
MVI C,READF
|
|
LXI D,SCB
|
|
CALL BDOS ;PERFORM THE READ
|
|
POP H ;RESTORE BUFFER ADDRESS
|
|
POP B ;RESTORE BUFFER COUNT
|
|
ORA A ;SET FLAGS
|
|
MVI C,128
|
|
JNZ GNC1
|
|
; NORMAL READ OCCURRED
|
|
LXI D,BUFF ;SOURCE BUFFER ADDRESS
|
|
MVI C,128
|
|
MOV0: LDAX D ;GET CHARACTER
|
|
MOV M,A ;STORE CHARACTER
|
|
INX D
|
|
INX H
|
|
DCR C
|
|
JNZ MOV0
|
|
; BUFFER LOADED, TRY NEXT BUFFER
|
|
;
|
|
DCR B
|
|
JNZ GNC0
|
|
JMP GNC2
|
|
;
|
|
GNC1: ;EOF OR ERROR
|
|
CPI 3 ;ALLOW 0,1,2
|
|
JNC FRERR ;FILE READ ERROR
|
|
GNCE: MVI M,EOF ;STORE AND END OF FILE CHARACTER
|
|
INX H
|
|
DCR C
|
|
JNZ GNCE ;FILL CURRENT BUFFER WITH EOF'S
|
|
;
|
|
GNC2: ;GET CHARACTER TO ACCUMULATOR AND RETURN
|
|
LXI D,SBUFF
|
|
LHLD SBP
|
|
PUSH H ;SAVE CURRENT SBP
|
|
INX H ;READY FOR NEXT READ
|
|
SHLD SBP
|
|
POP H ;RESTORE PREVIOUS SBP
|
|
DAD D ;ABSOLUTE ADDRESS OF CHARACTER
|
|
MOV A,M ;GET IT
|
|
POP H
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
FRERR: LXI H,ERRFR
|
|
CALL PCON ;PRINT READ ERROR MESSAGE
|
|
JMP BOOT
|
|
;
|
|
PNC: ;SAME AT PNCF, BUT ENVIRONMENT IS SAVED FIRST
|
|
PUSH B
|
|
; CHECK FOR CONSOLE OUTPUT / NO OUTPUT
|
|
MOV B,A ;SAVE CHARACTER
|
|
LDA PDISK ;Z OR X?
|
|
CPI 'Z'-'A' ;Z NO OUTPUT
|
|
JZ PNRET
|
|
;
|
|
CPI 'X'-'A'
|
|
MOV A,B ;RECOVER CHAR FOR CON OUT
|
|
JNZ PNGO
|
|
CALL PCHAR
|
|
JMP PNRET
|
|
;
|
|
; NOT X OR Z, SO PRINT IT
|
|
PNGO: PUSH D
|
|
PUSH H
|
|
CALL PNCF
|
|
POP H
|
|
POP D
|
|
PNRET: POP B
|
|
RET
|
|
;
|
|
PNCF: ;PRINT NEXT CHARACTER
|
|
LHLD PBP
|
|
XCHG
|
|
LXI H,PBUFF
|
|
DAD D
|
|
MOV M,A ;CHARACTER STORED AT PBP IN PBUFF
|
|
XCHG ;PBP TO H,L
|
|
INX H ;POINT TO NEXT CHARACTER
|
|
SHLD PBP ;REPLACE IT
|
|
XCHG
|
|
LXI H,PSIZE
|
|
CALL GCOMP ;AT END OF BUFFER?
|
|
RNZ ;RETURN IF NOT
|
|
;
|
|
; OVERFLOW, WRITE BUFFER
|
|
CALL SELP
|
|
LXI H,0
|
|
SHLD PBP
|
|
LXI H,PBUFF
|
|
LXI D,PCB ;D,E ADDRESS FILE CONTROL BLOCK
|
|
MVI B,NPB ;NUMBER OF BUFFERS TO B
|
|
; (DROP THROUGH TO WBUFF)
|
|
;
|
|
WBUFF: ;WRITE BUFFERS STARTING AT H,L FOR B BUFFERS
|
|
; CHECK FOR EOF'S
|
|
MOV A,M
|
|
CPI EOF
|
|
RZ ;DON'T DO THE WRITE
|
|
;
|
|
PUSH B ;SAVE NUMBER OF BUFFERS
|
|
PUSH D ;SAVE FCB ADDRESS
|
|
MVI C,128 ;READY FOR MOVE
|
|
LXI D,BUFF
|
|
WBUF0: ;MOVE TO BUFFER
|
|
MOV A,M ;GET CHARACTER
|
|
STAX D ;PUT CHARACTER
|
|
INX H
|
|
INX D
|
|
DCR C
|
|
JNZ WBUF0
|
|
;
|
|
; WRITE BUFFER
|
|
POP D ;RECOVER FCB ADDRESS
|
|
PUSH D ;SAVE IT AGAIN FOR LATER
|
|
PUSH H ;SAVE BUFFER ADDRESS
|
|
MVI C,WRITF ;DOS WRITE FUNCTION
|
|
CALL BDOS
|
|
POP H ;RECOVER BUFFER ADDRESS
|
|
POP D ;RECOVER FCB ADDRESS
|
|
POP B ;RECOVER BUFFER COUNT
|
|
ORA A ;SET ERROR RETURN FLAGS
|
|
JNZ FWERR
|
|
;
|
|
; WRITE OK
|
|
DCR B
|
|
RZ ;RETURN IF NO MORE BUFFERS TO WRITE
|
|
JMP WBUFF
|
|
;
|
|
FWERR: ;ERROR IN WRITE
|
|
LXI H,ERRFW
|
|
CALL PCON ;ERROR MESSAGE OUT
|
|
JMP EORC ;TO CLOSE AND REBOOT
|
|
;
|
|
;
|
|
PNB: ;PUT NEXT HEX BYTE
|
|
PUSH B
|
|
PUSH D
|
|
PUSH H
|
|
CALL PNBF
|
|
POP H
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
PNBF: ;PUT NEXT BYTE
|
|
; (SIMILAR TO THE PNCF SUBROUTINE)
|
|
LHLD HBP
|
|
XCHG
|
|
LXI H,HBUFF
|
|
DAD D
|
|
MOV M,A ;CHARACTER STORED AT HBP IN HBUFF
|
|
XCHG
|
|
INX H ;HBP INCREMENTED
|
|
SHLD HBP
|
|
XCHG ;BACK TO D,E
|
|
LXI H,HSIZE
|
|
CALL GCOMP ;EQUAL?
|
|
RNZ
|
|
;
|
|
; OVERFLOW, WRITE BUFFERS
|
|
CALL SELH
|
|
LXI H,0
|
|
SHLD HBP
|
|
LXI H,HBUFF
|
|
LXI D,HCB ;FILE CONTROL BLOCK FOR HEX FILE
|
|
MVI B,NHB
|
|
JMP WBUFF ;WRITE BUFFERS
|
|
;
|
|
PCHAR: ;PRINT CHARACTER IN REGISTER A
|
|
PUSH B
|
|
PUSH D
|
|
PUSH H
|
|
MVI C,WRITC
|
|
MOV E,A
|
|
CALL BDOS
|
|
POP H
|
|
POP D
|
|
POP B
|
|
RET
|
|
;
|
|
WOCHAR: ;WRITE CHARACTER IN REG-A WITH REFLECT AT CONSOLE IF ERROR
|
|
MOV C,A ;SAVE THE CHAR
|
|
CALL PNC ;PRINT CHAR
|
|
LDA QBUFF
|
|
CPI ' '
|
|
RZ
|
|
; ERROR IN LINE
|
|
LDA PDISK
|
|
CPI 'X'-'A'
|
|
RZ ;ALREADY PRINTED IF 'X'
|
|
;
|
|
MOV A,C ;RECOVER CHARACTER
|
|
CALL PCHAR ;PRINT IT
|
|
RET
|
|
;
|
|
WOBUFF: ;WRITE THE OUTPUT BUFFER TO THE PRINT FILE
|
|
LDA QBP ;GET CHARACTER COUNT
|
|
LXI H,QBUFF ;BASE OF BUFFER
|
|
WOB0: ORA A ;ZERO COUNT?
|
|
JZ WOBE
|
|
; NOT END, SAVE COUNT AND GET CHARACTER
|
|
MOV B,A ;SAVE COUNT
|
|
MOV A,M
|
|
CALL WOCHAR ;WRITE CHARACTER
|
|
INX H ;ADDRESS NEXT CHARACTER OF BUFFER
|
|
MOV A,B ;GET COUNT
|
|
DCR A
|
|
JMP WOB0
|
|
;
|
|
WOBE: ;END OF PRINT - ZERO QBP
|
|
STA QBP
|
|
; FOLLOW BY CR LF
|
|
MVI A,CR
|
|
CALL WOCHAR
|
|
MVI A,LF
|
|
CALL WOCHAR
|
|
LXI H,QBUFF
|
|
MVI A,QBMAX ;READY TO BLANK OUT
|
|
WOB2: MVI M,' '
|
|
INX H
|
|
DCR A
|
|
JNZ WOB2
|
|
RET
|
|
;
|
|
;
|
|
PERR: ;FILL QBUFF ERROR MESSAGE POSITION
|
|
MOV B,A ;SAVE CHARACTER
|
|
LXI H,QBUFF
|
|
MOV A,M
|
|
CPI ' '
|
|
RNZ ;DON'T CHANGE IT IF ALREADY SET
|
|
MOV M,B ;STORE ERROR CHARACTER
|
|
RET
|
|
;
|
|
EOR: ;END OF ASSEMBLER
|
|
CALL NPR ;Z OR A?
|
|
JZ EOPR
|
|
; FILL OUTPUT FILES WITH EOF'S
|
|
EOR2: LHLD PBP
|
|
MOV A,L
|
|
ORA H ;VALUE ZERO?
|
|
JZ EOPR
|
|
MVI A,EOF ;CTL-Z IS END OF FILE
|
|
CALL PNC ;PUT ENDFILES IN PRINT BUFFER
|
|
JMP EOR2 ;EVENTUALLY BUFFER IS WRITTEN
|
|
;
|
|
EOPR: ;END OF PRINT FILE, CHECK HEX
|
|
LDA HDISK
|
|
CPI 'Z'-'A'
|
|
JZ EORC
|
|
EOR0: ;WRITE TERMINATING RECORD INTO HEX FILE
|
|
LDA DBL ;MAY BE ZERO ALREADY
|
|
ORA A
|
|
CNZ WHEX ;WRITE HEX BUFFER IF NOT ZERO
|
|
LHLD FPC ;GET CURRENT FPC AS LAST ADDRESS
|
|
SHLD BPC ;RECORD LENGTH ZERO, BASE ADDRESS 0000
|
|
CALL WHEX ;WRITE HEX BUFFER
|
|
;
|
|
; NOW CLEAR OUTPUT BUFFER FOR HEX FILE
|
|
EOR1: LHLD HBP
|
|
MOV A,L
|
|
ORA H
|
|
JZ EORC
|
|
MVI A,EOF
|
|
CALL PNB
|
|
JMP EOR1
|
|
;
|
|
; CLOSE FILES AND TERMINATE
|
|
EORC:
|
|
CALL NPR
|
|
JZ EORPC
|
|
CALL SELP
|
|
LXI D,PCB
|
|
CALL CLOSE
|
|
EORPC:
|
|
LDA HDISK
|
|
CPI 'Z'-'A'
|
|
JZ EORHC
|
|
CALL SELH
|
|
LXI D,HCB
|
|
CALL CLOSE
|
|
;
|
|
EORHC:
|
|
LXI H,ENDA
|
|
CALL PCON
|
|
JMP BOOT
|
|
;
|
|
TITL: DB 'CP/M ASSEMBLER - VER 1.4',CR
|
|
ERROP: DB 'NO SOURCE FILE PRESENT',CR
|
|
ERRMA: DB 'NO DIRECTORY SPACE',CR
|
|
ERRFN: DB 'SOURCE FILE NAME ERROR',CR
|
|
ERRFR: DB 'SOURCE FILE READ ERROR',CR
|
|
ERRFW: DB 'OUTPUT FILE WRITE ERROR',CR
|
|
ERRCL: DB 'CANNOT CLOSE FILES',CR
|
|
ENDA: DB 'END OF ASSEMBLY',CR
|
|
;
|
|
DHEX: ;DATA TO HEX BUFFER (BYTE IN REG-A)
|
|
PUSH B
|
|
MOV B,A ;HOLD CHARACTER FOR 'Z' TEST
|
|
LDA HDISK
|
|
CPI 'Z'-'A'
|
|
MOV A,B ;RECOVER CHARACTER
|
|
JZ DHRET
|
|
PUSH D ;ENVIRONMENT SAVED
|
|
PUSH PSW ;SAVE DATA BYTE
|
|
LXI H,DBL ;CURRENT LENGTH
|
|
MOV A,M ;TO ACCUM
|
|
ORA A ;ZERO?
|
|
JZ DHEX3
|
|
;
|
|
; LENGTH NOT ZERO, MAY BE FULL BUFFER
|
|
CPI 16
|
|
JC DHEX1 ;BR IF LESS THAN 16 BYTES
|
|
; BUFFER FULL, DUMP IT
|
|
CALL WHEX ;DBL = 0 UPON RETURN
|
|
JMP DHEX3 ;SET BPC AND DATA BYTE
|
|
;
|
|
DHEX1: ;PARTIAL BUFFER IN PROGRESS, CHECK FOR SEQUENTIAL BYTE LOAD
|
|
LHLD FPC
|
|
XCHG
|
|
LHLD BPC ;BASE PC IN H,L
|
|
MOV C,A ;CURRENT LENGTH OF BUFFER
|
|
MVI B,0 ;IS IN B,C
|
|
DAD B ;BPC+DBL TO H,L
|
|
MOV A,E ;READY FOR COMPARE
|
|
CMP L ;EQUAL?
|
|
JNZ DHEX2 ;BR IF NOT
|
|
MOV A,D ;CHECK HO BYTE
|
|
CMP H
|
|
JZ DHEX4 ;BR IF SAME ADDRESS
|
|
;
|
|
DHEX2: ;NON SEQUENTIAL ADDRESS, DUMP AND CHANGE BASE ADDRESS
|
|
CALL WHEX
|
|
DHEX3: ;SET NEW BASE
|
|
LHLD FPC
|
|
SHLD BPC
|
|
;
|
|
DHEX4: ;STORE DATA BYTE AND INC DBL
|
|
LXI H,DBL
|
|
MOV E,M ;LENGTH TO REG-E
|
|
INR M ;DBL=DBL+1
|
|
MVI D,0 ;HIGH ORDER ZERO FOR DOUBLE ADD
|
|
LXI H,DBUFF
|
|
DAD D ;DBUFF+DBL TO H,L
|
|
POP PSW ;RESTORE DATA BYTE
|
|
MOV M,A ;INTO DATA BUFFER
|
|
POP D
|
|
DHRET: POP B ;ENVIRONMENT RESTORED
|
|
RET
|
|
;
|
|
WRC: ;WRITE CHARACTER WITH CHECK SUM IN D
|
|
PUSH PSW
|
|
RRC
|
|
RRC
|
|
RRC
|
|
RRC
|
|
ANI 0FH
|
|
CALL HEXC ;OUTPUT HEX CHARACTER
|
|
POP PSW ;RESTORE BYTE
|
|
PUSH PSW ;SAVE A VERSION
|
|
ANI 0FH
|
|
CALL HEXC ;WRITE LOW NIBBLE
|
|
POP PSW ;RESTORE BYTE
|
|
ADD D ;COMPUTE CHECKSUM
|
|
MOV D,A ;SAVE CS
|
|
RET
|
|
;
|
|
HEXC: ;WRITE CHARACTER
|
|
ADI 90H
|
|
DAA
|
|
ACI 40H
|
|
DAA
|
|
JMP PNB ;PUT BYTE
|
|
;
|
|
WHEX: ;WRITE CURRENT HEX BUFFER
|
|
MVI A,':' ;RECORD HEADER
|
|
CALL PNB ;PUT BYTE
|
|
LXI H,DBL ;RECORD LENGTH ADDRESS
|
|
MOV E,M ;LENGTH TO REG-E
|
|
XRA A ;ZERO TO REG-A
|
|
MOV D,A ;CLEAR CHECKSUM
|
|
MOV M,A ;LENGTH IS ZEROED FOR NEXT WRITE
|
|
LHLD BPC ;BASE ADDRESS FOR RECORD
|
|
MOV A,E ;LENGTH TO A
|
|
CALL WRC ;WRITE HEX VALUE
|
|
MOV A,H ;HIGH ORDER BASE ADDR
|
|
CALL WRC ;WRITE HO BYTE
|
|
MOV A,L ;LOW ORDER BASE ADDR
|
|
CALL WRC ;WRITE LO BYTE
|
|
XRA A ;ZERO TO A
|
|
CALL WRC ;WRITE RECORD TYPE 00
|
|
MOV A,E ;CHECK FOR LENGTH 0
|
|
ORA A
|
|
JZ WHEX1
|
|
;
|
|
; NON - ZERO, WRITE DATA BYTES
|
|
LXI H,DBUFF
|
|
WHEX0: MOV A,M ;GET BYTE
|
|
INX H
|
|
CALL WRC ;WRITE DATA BYTE
|
|
DCR E ;END OF BUFFER?
|
|
JNZ WHEX0
|
|
;
|
|
; END OF DATA BYTES, WRITE CHECK SUM
|
|
WHEX1: XRA A
|
|
SUB D ;COMPUTE CHECKSUM
|
|
CALL WRC
|
|
;
|
|
; SEND CRLF AT END OF RECORD
|
|
MVI A,CR
|
|
CALL PNB
|
|
MVI A,LF
|
|
CALL PNB
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ENDMOD EQU ($ AND 0FFE0H)+20H
|
|
END
|