home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpmug
/
cpmug036.ark
/
MAC6.AZM
< prev
next >
Wrap
Text File
|
1984-04-29
|
11KB
|
580 lines
.TITLE "CP/M DISK I/O DRIVERS FOR TDL'S MACROASSEMBLER VER. 1.6"
;
; VERSION 1.2 11 APR 77
; VERSION 1.3 20 SEP 77
; VERSION 1.4 17 OCT 77
;
; BY JEFFREY W. SHOOK
; PO BOX 185
; ROCKY POINT, NY 11778
;
; VERSION 1.5 28 DEC 78
; VERSION 1.6 11 MAR 79
;
; BY MIKE FAVITTA
; 2 JANET LANE
; ALBANY, NY 12203
;
; THIS PROGRAM ADAPTS THE TDL MACROASSEMBLER
; TO WORK UNDER CP/M.
;
; SEE MAC6.DOC FOR DETAILS
;
;***********************************
; CP/M STANDARD EQUATES
;***********************************
BOOT = 0000H ;WARM START ADDRESS
TFCB = 005CH ;DEFAULT FCB ADDRESS
TBUF = 0080H ;DEFAULT BUFFER ADDRESS
TBASE = 0100H ;TRANSIENT PROGRAM BASE
CBASE = 8500H ;CCP BASE ADDRESS
BDOS = 0005H ;BDOS ENTRY POINT
CONIN = 09A09H ;CONSOLE INPUT SUBROUTINE
CONOUT = 09A0CH ;CONSOLE OUTPUT ROUTINE
TDL = 0B23H ;TDL ASSEM START
TDLR = 0B27H ;TDL RECOVERY ADDR
;***********************************
; CP/M FUNCTION CODES
;***********************************
SRSET = 00 ;SYSTEM RESET
RCON = 01 ;READ CONSOLE
WCON = 02 ;WRITE CONSOLE
RRDR = 03 ;READ READER
WPUN = 04 ;WRITE PUNCH
WLST = 05 ;WRITE LIST
ISTAT = 07 ;GET IOSTATUS
SSTAT = 08 ;SET IOSTATUS
WCONB = 09 ;WRITE CONSOLE BUFFER
RCONB = 10 ;READ CONSOLE BUFFER
CSTAT = 11 ;CHECK CONSOLE STATUS
LHEAD = 12 ;LIFT DISK HEAD
RSDSK = 13 ;RESET DISK SYSTEM
SDISK = 14 ;SELECT DISK
OPEN = 15 ;OPEN FILE
CLOSE = 16 ;CLOSE FILE
SFRST = 17 ;SEARCH FIRST
SNEXT = 18 ;SEARCH NEXT
FDELT = 19 ;DELETE FILE
READ = 20 ;READ RECORD
WRITE = 21 ;WRITE RECORD
CREATE = 22 ;CREATE FILE
RENAM = 23 ;RENAME FILE
LOGIN = 24 ;GET LOGIN
IDISK = 25 ;GET DISK NUMBER
SDMA = 26 ;SET DMA VECTOR
IALLOC = 27 ;GET ALLOCATION VECTOR
;
EOF = 1AH ; CP/M END OF FILE CHAR
CR = 0DH
LF = 0AH
;
;
.LOC 100H ; LET CP/M FIND US
JMP MACAD
;
;
; TRANSIENT PROGRAM STORAGE
; DEFINITIONS
;
CSTSF: .BYTE 0 ; CONSOLE STATUS FLAG
SDSK: .WORD 0 ; SOURCE DRIVE
ODSK: .WORD 1 ; OUTPUT DRIVE
OPT: .WORD 0 ; SAVE OPTIONS HERE
PASSP: .WORD PASST ; PASS TABLE POINTER
SRCPTR: .WORD 0 ; SOURCE BUFFER POINTER
LSTPTR: .WORD LSTBUF ; LISTING BUFFER POINTER
HEXPTR: .WORD HEXBUF ; HEX OBJECT FILE POINTER
SRCFCB: .BLKB 36 ; SOURCE FILE CONTROL BLOCK
SRCBUF: .BLKB 128 ; SOURCE FILE BUFFER
LSTFCB: .BLKB 36 ; LISTING FILE CONTROL BLOCK
LSTBUF: .BLKB 128 ; LISTING FILE BUFFER
HEXFCB: .BLKB 36 ; OBJECT FILE CONTROL BLOCK
HEXBUF: .BLKB 128 ; OBJECT FILE BUFFER
;
;
MACAD: LXI SP,MACRX+16EH ; SET TEMP STACK
LXI H,SRCFCB
LXI B,MACAD-SRCFCB
MVI A,0
CLEAR: MOV M,A ; ZERO FCB AND BUFFER
INX H ; AREAS
DCX B
CMP C
JRNZ CLEAR
CMP B
JRNZ CLEAR
LDA TFCB+17 ; SAVE OPTIONS
STA OPT
LDA TFCB+18
STA OPT+1
MVI A,'L' ; DON'T ALLOW LO
CALL OPTS ; TOGETHER AS OPTIONS
JRNZ ..SKP
MVI A,'O'
CALL OPTS
JZ ILGOP
..SKP: MVI C,IDISK ; GET ACTIVE DRIVE #
CALL BDOS
MOV C,A
MVI A,'S' ; IS THE
CALL OPTS ; S OPTION SET
MOV A,C
JRNZ DUAL ; NO,SET UP FOR 2 DRIVES
STA SDSK ; SET UP FOR 1 DRIVE
STA ODSK
JMPR SKIP
DUAL: BIT 0,A ; IS SOURCE ON A
JRZ SKIP
STA SDSK ; SOURCE ON B
MVI A,0
STA ODSK
SKIP: LXI H,AZM ; INSERT FILETYPE
LXI D,TFCB+9
LXI B,3 ; IN TRANSIENT FCB
LDIR ; MOVE FILETYPE
LXI D,TFCB ; CHECK DIRECTORY
MVI C,SFRST ; TO SEE IF FILE EXISTS
CALL BDOS
MVI C,0 ; ERROR 0
CPI 0FFH
CZ ERROR
LXI H,TFCB ; MOVE FILE NAME TO SRCFCB
LXI D,SRCFCB
LXI B,12
LDIR ; MOVE BLOCK
LDED ODSK ; LOG IN OUTPUT DRIVE
MVI C,SDISK
CALL BDOS
MVI A,'O' ; IF O OPT SET
CALL OPTS ; DON'T WANT LIST FILE
JRZ MHEX
LXI D,LSTFCB; CREATE LISTING FILE
LXI B,PRN
CALL MAKEF
MHEX: MVI A,'L' ; IF L OPT SET
CALL OPTS ; DON'T WANT HEX FILE
JRZ ..SKP
LXI D,HEXFCB; CREATE OBJECT FILE
LXI B,HXR
CALL MAKEF
..SKP: JMP MACRX ; GO ASSEMBLE
;
; TABLE OF FILETYPES
;
AZM: .ASCII 'AZM'
PRN: .ASCII 'PRN'
HXR: .ASCII 'HXR'
;
; END OF ASSEMBLY
;
TRPSIM: MVI C,EOF ; EMPTY LIST BUFFER
MVI A,'O' ; DON'T CLOSE IF
CALL OPTS ; O OPT SET
JRZ CHEX
LOOP: CALL LOSIM
JRNC LOOP
MVI C,CLOSE ; CLOSE FILE
LXI D,LSTFCB
CALL BDOS
CHEX: MVI A,'L' ; DON'T CLOSE IF
CALL OPTS ; L OPT SET
JRZ DONE
MVI C,EOF
TRPS1: CALL POSIM ; EMPTY HEX BUFFER
JRNC TRPS1
MVI C,CLOSE ; CLOSE FILE
LXI D,HEXFCB
CALL BDOS
DONE: JMP BOOT
;
; IF CHAR IN A MATCHES 1 OF THE
; OPTIONS, SET THE ZERO FLAG
;
OPTS: PUSH H
LXI H,OPT ; POINT TO OPTIONS
CMP M ; MATCH ?
JRZ ..SKP ; YES,RETURN
INX H ; NO,TRY NEXT ONE
CMP M
..SKP: POP H
RET
;
; SIMULATE CONSOLE INPUT FOR PASS
; CONTROL OF ASSEMBLER.
; PASS 1 = SYMBOL TABLE
; PASS 2 = LISTING
; PASS 3 = HEX OBJECT FILE
;
CISIM: PUSH H ; SAVE ASSEMBLER REGISTERS
PUSH D
PUSH B
LDED SDSK ; LOG IN SOURCE DRIVE
MVI C,SDISK
CALL BDOS
MVI A,0 ; SET NEXT RECORD POINTER TO ZERO
STA CSTSF ; CLEAR CONSOLE STATUS FLAG
STA SRCFCB+12 ; CLEAR FCB
STA SRCFCB+15
STA SRCFCB+32
LXI D,SRCBUF ;MAKE SURE SRCBUF
MVI C,SDMA ;IS USED
CALL BDOS
LXI D,SRCFCB
MVI C,OPEN ;OPEN SOURCE FILE
CALL BDOS
MVI C,1 ; ERROR 1
CPI 0FFH
CZ ERROR
LXI H,SRCBUF+128
SHLD SRCPTR ; SET SRC PTR TO END OF BUFFER
LHLD PASSP ; LOAD POINTER TO PASS #
MOV C,M ; GET PASS
MVI A,'1' ; IS IT PASS 1
CMP M
JRNZ ..SKP ; NO
MVI A,'O' ; YES,CHECK FOR O OPT
CALL OPTS
JRNZ EXIT ; NOT SET
INX H ; SKIP LIST PASS
JMPR EXIT
..SKP: MVI A,'2' ; IS IT PASS 2
CMP M
JRNZ EXIT ; NO
MVI A,'L' ; YES,CHECK FOR L OPT
CALL OPTS
JRNZ EXIT ; NOT SET
INX H ; SKIP OBJECT PASS
EXIT: MOV A,C ; A=PASS #
INX H
SHLD PASSP
POP B
POP D
POP H
RET
;
;
; TABLE OF PASS NUMBERS
;
PASST: .ASCII '1230'
;
; CHARACTER INPUT SUBROUTINE
;
; CREATE A SOURCE BUFFER AND LOAD
; IT FROM THE DISK. AT EACH CALL
; SUPPLY ONE CHARCTER IN A REG.
; IF BUFFER EMPTY, CALL BDOS TO
; FILL IT. SET CARRY IF EOF IS
; FOUND IN FILE.
;
RISIM: PUSH H ; SAVE ASSM HL,DE
PUSH D
LXI D,SRCFCB; GET FCB ADDRESS
LHLD SRCPTR ; GET BUFFER POINTER
CALL BUFIN ; READ A BYTE
SHLD SRCPTR ; SAVE BUFFER POINTER
POP D ; RESTORE HL,DE
POP H
CPI EOF ; CHECK FOR EOF CHAR
STC ; SET EOF FLAG IN CARRY
RZ
CMC ; NOT EOF, ERASE MARK
RET
;
; LIST CHARACTER OUTPUT
;
; CREATE AN OUTPUT BUFFER AND
; PUT EACH CHAR IN UNTIL FULL.
; THEN WRITE CONTENTS TO DISK
; FILE AND RESET POINTER.
;
LOSIM: PUSH D
PUSH H
LHLD LSTPTR
LXI D,LSTFCB
CALL BUFOUT
SHLD LSTPTR
POP H
POP D
MOV A,C
RET
;
;
; PUNCH CHARACTER OUTPUT
; SIMILAR TO LIST OUTPUT
;
POSIM: PUSH D
PUSH H
LHLD HEXPTR
LXI D,HEXFCB
CALL BUFOUT
SHLD HEXPTR
POP H
POP D
MOV A,C
RET
;
; SOURCE BUFFER CONTROL
; REFILL BUFFER IF EMPTY, PUT NEXT CHARACTER IN A
; ENTER WITH FCB ADDRESS IN DE, BUFFER POINTER IN HL
; SAVES BC, RETURNS WITH CHAR IN A, BUFFER POINTER IN HL
;
BUFIN: MOV A,E ; COMPUTE END OF BUFFER
ADI SRCBUF+128-SRCFCB
CMP L
JRNZ SRCB1
PUSH B
MVI C,READ
CALL REFILL
ANI 0FEH ; CHECK FOR GOOD READ
CPI 0
MVI C,2 ; ERROR 2
CNZ ERROR
POP B
SRCB1: MOV A,M
INX H
RET
;
;
; OUTPUT BUFFER CONTROL
;
; IF BUFFER FULL, WRITE CONTENTS TO DISK,
; PUT CHAR FROM C IN BUFFER.
;
; ENTER WITH FCB ADDR IN DE, BUFFER PTR IN HL,
; AND CHAR IN C.
; RETURN WITH BUFFER PTR IN HL,SAVE BC,SET CARRY AFTER
; BUFFER REFILL.
;
BUFOUT: MOV A,E ; COMPUTE END OF BUFFER
ADI 164
CMP L ; FULL?
STC ; CLEAR CARRY
CMC
JRNZ BUFOU1 ; NOT FULL, STORE CHAR
PUSH B ; FULL, SAVE CHAR
MVI C,WRITE
CALL REFILL
CPI 0 ; GOOD WRITE?
MVI C,3 ; ERROR 3
CNZ ERROR
POP B
STC ; MARK REFILL
BUFOU1: MOV M,C ; STORE CHAR IN BUFFER
INX H ; MOVE PTR TO NEXT CHAR
RET
;
;
; BUFFER I/O ROUTINE
;
; ENTER WITH CP/M READ OR WRITE CODE
; IN BC AND FCB ADDRESS IN DE.
; RETURN WITH INITIALIZED BUFFER
; POINTER IN HL.
;
REFILL: PUSH D
PUSH B
BIT 0,C ; IN OR OUT DRIVE
JRZ SEL
LDED ODSK ; OUTPUT DRIVE
JMPR CONT
SEL: LDED SDSK ; SOURCE DRIVE
CONT: MVI C,SDISK ; LOG IN DRIVE
CALL BDOS
POP B
POP D
LXI H,36 ; CALC START OF BUFFER
DAD D
PUSH H ; SAVE START OF BUFFER
PUSH D ; SAVE FCB ADDRESS
XCHG
PUSH B ; SAVE CP/M CODE
MVI C,SDMA
CALL BDOS ; SET DMA ADDRESS
POP B ; GET CP/M CODE
POP D ; GET FCB ADDRESS
CALL BDOS ; READ OR WRITE BUFFER
POP H ; SET PTR TO START OF BUFFER
RET
;
;
; CREATE AND OPEN A FILE WITH SAME NAME AS DEFAULT FCB
;
; ENTER WITH ADDRESS OF FCB IN DE, AND
; ADDRESS OF FILETYPE STRING IN BC.
;
MAKEF: LXI H,TFCB
PUSH D
PUSH B
LXI B,9
LDIR ; MOVE FILENAME
POP H
LXI B,3
LDIR ; MOVE FILETYPE
MVI C,FDELT
POP D
PUSH D
CALL BDOS ; DELETE FILE
MVI C,CREATE
POP D
PUSH D
CALL BDOS ; CREATE FILE
MVI C,4 ; ERROR 4
CPI 0FFH
CZ ERROR
MVI C,OPEN
POP D
CALL BDOS ; OPEN FILE
MVI C,5 ; ERROR 5
CPI 0FFH
CZ ERROR
RET
;
; MEMORY SIZE TEST
;
MEMSIM: PUSH H
LHLD BDOS+1
DCX H
MOV A,L
MOV B,H
POP H
RET
;
; CONSOLE STATUS CHECK
CSTSIM: LDA CSTSF ; CHECK CONSOLE STATUS
RET
; IOCHECK
;
IOSIM: MVI A,0A8H
RET
;
; ERROR HANDLER
;
ERROR: PUSH B ; SAVE ERROR INDEX
PUSH PSW
LXI D,ERMES1
CALL PRTMES
POP PSW
POP B
POP H ; CALLER'S ADDRESS
PUSH B
ORA A ; CLEAR CARRY
LXI D,3 ; ADJUST ADDRESS
DSBC D
PUSH PSW
CALL OUTHHL ; PRINT IT
LXI D,ERMES2
CALL PRTMES
POP PSW
CALL OUT2H ; PRINT ERR STATUS
LXI D,CRLF
CALL PRTMES
POP D ; GET ERROR INDEX
MVI D,0 ; CLEAR HIGH ORDER BYTE
SLAR E ; MULTIPLY BY 2
LXI H,MESLST ; POINT TO MES ADDR
DAD D
MOV E,M ; LOAD IT IN DE
INX H
MOV D,M
CALL PRTMES ; PRINT IT
LXI D,CRLF
CALL PRTMES
JMP BOOT
;
ILGOP: LXI D,ILOPT ; EXIT FOR ILLEGAL
CALL PRTMES ; OPTIONS
JMP BOOT
;
PRTMES: MVI C,WCONB ; PRINT A LINE
CALL BDOS
RET
;
;
ERMES1: .ASCII [CR][LF]'MACROASSEMBLER DISK ERROR '
.ASCII 'AT ADDRESS $'
ERMES2: .ASCII [CR][LF]'CP/M RETURNED A STATUS OF $'
ILOPT: .ASCII [CR][LF]'ILLEGAL OPTION COMBINATION'
CRLF: .ASCII [CR][LF]'$'
;
MESLST: .WORD EMES1
.WORD EMES2
.WORD EMES3
.WORD EMES4
.WORD EMES5
.WORD EMES6
;
EMES1: .ASCII 'SOURCE FILE NOT FOUND$'
EMES2: .ASCII 'CAN NOT OPEN SOURCE FILE$'
EMES3: .ASCII '** BAD READ **$'
EMES4: .ASCII '** BAD WRITE **$'
EMES5: .ASCII 'CAN NOT CREATE OUTPUT FILE$'
EMES6: .ASCII 'CAN NOT OPEN OUTPUT FILE$'
;
;
; OUT2H PRINT 2 HEX DIGITS FROM A
; OUTHHL PRINT HL
OUTHHL: MOV A,H ; PRINT HL
CALL OUT2H
MOV A,L
OUT2H: PUSH PSW
CALL OUTHL
POP PSW
JMPR OUTHR
OUTHL: RRC
RRC
RRC
RRC
OUTHR: ANI 0FH
ADI '0'
CPI '9'+1
JRC OUTHR1
ADI '@'-'9'
OUTHR1: JMPR OUTCH
CO: MOV A,C ; CHECK FOR PASS REQUEST
CPI '='
JRNZ CO1
MVI A,0FFH ; SET CONSOLE STATUS
STA CSTSF
CO1: MOV A,C ; SIMULATE TDL CO
OUTCH: PUSH PSW ; CONSOLE OUTPUT
PUSH B
PUSH D
PUSH H
MVI C,WCON
MOV E,A
CALL BDOS
POP H
POP D
POP B
POP PSW
RET
; NEW MACROASSEMBLER I/O VECTOR TABLE
; TO OVERWRITE PRESENT ASSEMBLER VECTOR TABLE
.LOC 0800H
MACRX: JMP TDL
JMP TDLR
JMP CISIM
JMP RISIM
JMP CO
JMP POSIM
JMP LOSIM
JMP CSTSIM
JMP IOSIM
JMP MEMSIM
JMP TRPSIM
.END