home *** CD-ROM | disk | FTP | other *** search
- ;-------------------------------------------------------
- ;
- ; CP/M DISK DIRECTORY UTILITY
- ;
- ; VERSION 1.3 - 5 NOV 77
- ;
- ; WRITTEN IN TLC
- ;
- ; COPYRIGHT 1977, BY
- ;
- ; JEFFREY W. SHOOK
- ; P. O. BOX 185
- ; ROCKY POINT, NEW YORK
- ; 11778
- ;
- ;---------------------------------------------------
- ORG 100H ; CP/M STARTS EXECUTION HERE
- JMP START ;
- DB 'DSKDIR VERSION 1.1',CR,LF
- DB CR,LF
- DB 'COPYRIGHT 1977',CR,LF
- DB CR,LF
- DB 'JEFFREY W. SHOOK',CR,LF
- DB 'PO BOX 185',CR,LF
- DB 'ROCKY POINT, NEW YORK',CR,LF
- DB '11778',CR,LF,0
- ;
- ; $DECLARE.CONSTANT
- ;
- BDOS: EQU 5 !
- CR: EQU 0DH !
- LF: EQU 0AH !
- !
- ; * FILE CONTROL BLOCK OFFSET VALUES
- ;
- ENTRYP: EQU 0 ; ENTRY.TYPE = 0
- FILNAM: EQU 1 ; FILE.NAME = 1
- FILTYP: EQU 9 ; FILE.TYPE = 9
- EXTNT: EQU 12 ; EXTENT = 12
- RECCNT: EQU 15 ; RECORD.COUNT = 15
- DSKMAP: EQU 16 ; DISK.MAP = 16
- NXTREC: EQU 32 ; NEXT.RECORD = 32
- ;
- SECSIZ: EQU 128 ; SECTOR.SIZE(2) = 128
- DIRSEC: EQU 16 ; DIRECT.SECTORS(1) = 16
- MAXENT: EQU 64 ; MAX.ENTRY(1) = 64
- FALSE: EQU 0 ; FALSE(1) = 0
- TRUE: EQU 0FFH ; TRUE(1) = 0FFH
- TFCB: EQU 05CH ; TFCB(2) = 05CH
- NAMLEN: EQU 11 ; NAME.LENGTH(1) = 11
- ENTLEN: EQU 32 ; ENTRY.LENGTH(1) = 32
- ;
- ; $DECLARE.LOGICAL
- ;
- REDERR: DS 1 ; READ.ERROR(1)
- ENTUSD: DS MAXENT ; ENTRY.USED(MAX.ENTRY)
- NAMEOK: DS 1 ; NAME.OK(1)
- SAMNAM: DS 1 ; SAME.NAME(1)
- BLNKNM: DS 1 ; BLANK.NAME(1)
- ;
- ; $DECLARE.VARIABLE
- ;
- ENTRY: DS 1 ; ENTRY(1)
- ENTNUM: DS 1 ; ENTRY.NUM(1)
- ENTPTR: DS 2 ; ENTRY.POINTER(2)
- TENPTR: DS 2 ; TEMP.ENTRY.PTR(2)
- PRONAM: DS 11 ; PROTO.NAME(11)
- CHRCNT: DS 1 ; CHAR.COUNT(1)
- ; BUFFER(DIRECT.SECTORS * SECTOR.SIZE)
- BUFFER: DS DIRSEC * SECSIZ
- DMADDR: DS 2 ; DMA.ADDRESS(2)
- TRACK: DS 1 ; TRACK(1)
- RECORD: DS 1 ; RECORD(1)
- FILSIZ: DS 2 ; FILE.SIZE(2)
- FILEXT: DS 2 ; FILE.EXTENTS(2)
- TMPENT: DS 1 ; TEMP.ENTRY(1)
- TOTSIZ DS 2 ; TOTAL.SIZE(2)
- TOTEXT: DS 2 ; TOTAL.EXTENTS(2)
- NAMEA: DS 2 ; NAME.A(2)
- NAMEB: DS 2 ; NAME.B(2)
- USDPTR: DS 2 ; USED.POINTER(2)
- LZRO: DS 1 ; LEAD.ZERO.SUPRESS(1)
- STPSAV: DS 2 ; CP/M.STACK.PTR(2)
- DS 248 ; STACK.AREA(248)
- STACK: DS 2 ; STACK.START(2)
- ;
- ; $DECLARE.END
- ;
- ;--------------------------------------
- ;
- START: ; * DISK DIRECTORY UTILITY
- ;
- LXI SP,STACK; INITIALIZE.STACK.POINTER
- CALL GPFNFT ; GET.PROTOTYPE.FILE.NAME.FROM.TFCB
- CALL RDFDIB ; READ.DIRECTORY.FROM.DISK.INTO.BUFFER
- LDA REDERR ; IF READ.ERROR
- CPI FALSE !
- JZ ELSE01 !
- CALL PREM ; PRINT.READ.ERROR.MESSAGE
- JMP FI01 ; ELSE
- ELSE01: !
- LXI H,0 ; TOTAL.SIZE = 0
- SHLD TOTSIZ !
- LXI H,0 ; TOTAL.EXTENTS = 0
- SHLD TOTEXT !
- CALL IEUF ; INITIALIZE.ENTRY.USED.FLAGS
- CALL PDH ; PRINT.DIRECTORY.HEADING
- MVI A,0 ; ENTRY = 0
- STA ENTRY !
- LOOP01: ; LOOP
- LXI D,ENTUSD; . IF (ADDR[ENTRY.USED] + ENTRY) = FALSE
- LXI H,ENTRY !
- MOV L,M !
- MVI H,0 !
- DAD D !
- MOV A,M !
- CPI FALSE !
- JNZ FI02 !
- CALL CETPN ; . . COMPARE.ENTRY.TO.PROTOTYPE.NAME
- LXI H,NAMEOK; . . IF NAME.OK
- MOV A,M !
- CPI TRUE !
- JNZ FI03 !
- CALL PEWSFN ; . . . PROCESS.ENTRYS.WITH.SAME.FILE.NAME
- CALL PFIL ; . . . PRINT.FILE.INFORMATION.LISTING
- FI03: ; . . FI
- FI02: ; . FI
- LXI H,ENTRY ; . ENTRY = ENTRY + 1
- INR M !
- LXI H,ENTRY ; . EXIT.IF ENTRY >= MAX.ENTRY
- MOV A,M !
- CPI MAXENT !
- JP POOL01 !
- JMP LOOP01 ; POOL
- POOL01: !
- CALL PTL ; PRINT.TOTALS.LISTING
- FI01: ; FI
- JMP WBOOT ; RETURN.TO.CP/M
- ;
- ;
- ;--------------------------------------
- ;
- GPFNFT: ; $ GET.PROTOTYPE.FILE.NAME.FROM.TFCB
- ;
- LXI H,CHRCNT; CHAR.COUNT = NAME.LENGTH
- MVI M,NAMLEN!
- LXI H,PRONAM; NAME.A = ADDR[PROTOTYPE.NAME]
- SHLD NAMEA !
- ; NAME.B = TFCB + FILE.NAME
- LXI H,TFCB+FILNAM
- SHLD NAMEB !
- LXI H,BLNKNM; BLANK.NAME = TRUE
- MVI M,TRUE !
- LOOP02: ; LOOP
- LHLD NAMEB ; IF (NAME.B <> " "
- MOV A,M !
- CPI ' ' !
- JZ FI09 !
- LXI H,BLNKNM; BLANK.NAME = FALSE
- MVI M,FALSE !
- FI09: ; FI
- LHLD NAMEB ; (NAME.A) = (NAME.B)
- MOV A,M !
- LHLD NAMEA !
- MOV M,A !
- LHLD NAMEA ; NAME.A = NAME.A + 1
- INX H !
- SHLD NAMEA !
- LHLD NAMEB ; NAME.B = NAME.B + 1
- INX H !
- SHLD NAMEB !
- LXI H,CHRCNT; CHAR.COUNT = CHAR.COUNT - 1
- DCR M !
- LXI H,CHRCNT; EXIT.IF CHAR.COUNT <= 0
- MOV A,M !
- CPI 0 !
- JZ POOL02 !
- JMP LOOP02 ; POOL
- POOL02: !
- IF10: LXI H,BLNKNM; IF BLANK.NAME = TRUE
- MOV A,M
- CPI TRUE !
- JNZ FI10 !
- LXI H,PRONAM; NAME.A = PROTOTYPE.NAME
- SHLD NAMEA !
- LXI H,CHRCNT; CHAR.COUNT = NAME.LENGTH
- MVI M,NAMLEN!
- LOOP07: ; LOOP
- LHLD NAMEA ; (NAME.A) = "?"
- MVI M,'?' !
- LHLD NAMEA ; NAME.A = NAME.A + 1
- INX H !
- SHLD NAMEA !
- LXI H,CHRCNT; CHAR.COUNT = CHAR.COUNT - 1
- DCR M !
- LXI H,CHRCNT; EXIT.IF CHAR.COUNT <= 0
- MOV A,M !
- CPI 0 !
- JZ POOL07 !
- JMP LOOP07 ; LOOP
- POOL07: !
- FI10: ; FI
- RET ; RETURN
- ;
- ;
- ;--------------------------------------
- ;
- RDFDIB: ; $ READ.DIRECTORY.FROM.DISK.INTO.BUFFER
- ;
- LXI H,TFCB ; SELECT.DISK.FROM.TFCB.ENTRY
- MOV A,M !
- ORA A !
- JZ TXXX !
- DCR A !
- MOV C,A !
- MVI B,0 !
- MVI A,24 !
- CALL FBIOS !
- TXXX: LXI H,BUFFER; DMA.ADDRESS = ADDR[BUFFER]
- SHLD DMADDR !
- LXI H,TRACK ; TRACK = 2
- MVI M,2 !
- LXI H,RECORD; RECORD = 1
- MVI M,1 !
- MVI A,27 ; SET.DISK.TRACK
- LXI H,TRACK !
- MOV C,M !
- MVI B,0 !
- CALL FBIOS !
- LOOP03: ; LOOP
- MVI A,33 ; SET.DMA.ADDRESS
- LHLD DMADDR !
- MOV B,H !
- MOV C,L !
- CALL FBIOS !
- LXI H,RECORD; SET.NEXT.SECTOR
- MOV C,M !
- CALL RECSEC !
- MVI A,30 !
- CALL FBIOS !
- MVI A,36 ; READ.ONE.RECORD
- CALL FBIOS !
- CPI FALSE ; SET.READ.ERROR.FLAG
- JZ RDFDI1 !
- MVI A,TRUE !
- RDFDI1: LXI H,REDERR!
- MOV M,A !
- LXI H,REDERR; EXIT.IF READ.ERROR
- MOV A,M !
- CPI TRUE !
- JZ POOL03 !
- LXI D,SECSIZ; DMA.ADDRESS = DMA.ADDRESS + SECTOR.SIZE
- LHLD DMADDR !
- DAD D !
- SHLD DMADDR !
- LXI H,RECORD; RECORD = RECORD + 1
- INR M !
- LXI H,RECORD; EXIT.IF RECORD > DIRECT.SECTORS
- MOV A,M !
- CPI DIRSEC+1!
- JP POOL03 !
- JMP LOOP03 ; POOL
- POOL03: !
- RET ; RETURN
- ;
- ;
- ;--------------------------------------
- ;
- PREM: ; $ PRINT.READ.ERROR.MESSAGE
- ;
- RET ; RETURN
- ;
- ;
- ;--------------------------------------
- ;
- IEUF: ; $ INITIALIZE.ENTRY.USED.FLAGS
- ;
- LXI H,ENTNUM; ENTRY.NUM = 0
- MVI M,0 !
- LXI H,BUFFER; ENTRY.PTR = ADDR[BUFFER]
- SHLD ENTPTR !
- LOOP04: ; LOOP
- LHLD ENTPTR; IF (ENTRY.PTR) = 0
- MOV A,M !
- CPI 0 !
- JNZ ELSE04 !
- LXI H,ENTNUM; (ADDR[ENTRY.USED] + ENTRY.NUM) = FALSE
- MOV E,M !
- MVI D,0 !
- LXI H,ENTUSD!
- DAD D !
- MVI M,FALSE !
- JMP FI04 ; ELSE
- ELSE04: !
- LXI H,ENTNUM; (ADDR[ENTRY.USED] + ENTRY.NUM) = TRUE
- MOV E,M !
- MVI D,0 !
- LXI H,ENTUSD!
- DAD D !
- MVI M,TRUE !
- FI04: ; FI
- LXI H,ENTNUM; ENTRY.NUM = ENTRY.NUM + 1
- INR M !
- LXI D,ENTLEN; ENTRY.PTR = ENTRY.PTR + ENTRY.LENGTH
- LHLD ENTPTR !
- DAD D !
- SHLD ENTPTR !
- LXI H,ENTNUM; EXIT.IF ENTRY.NUM >= MAX.ENTRY
- MOV A,M !
- CPI MAXENT !
- JP POOL04 !
- JMP LOOP04 ; POOL
- POOL04: !
- RET ; RETURN
- ;
- ;
- ;
- ;--------------------------------------
- ;
- PDH: ; PRINT.DIRECTORY.HEADING
- ;
- MVI C,9 ; PRINT "FILE.NAME SIZE SECTORS EXTS"
- LXI D,MSG1 !
- CALL BDOS !
- RET ; RETURN
- MSG1: DB 'FILE.NAME BYTES SCTRS EXTS'
- DB 0DH,0AH,0DH,0AH,'$'
- ;
- ;
- ;--------------------------------------
- ;
- CETPN: ; $ COMPARE.ENTRY.TO.PROTOTYPE.NAME
- ;
- LXI H,PRONAM; NAME.A = ADDR[PROTO.NAME]
- SHLD NAMEA !
- LDA ENTRY ; NAME.B = ADDR[BUFFER] + ENTRY.LENGTH * ENTRY + FILE.NAME
- LXI D,ENTLEN!
- CALL MULT8 !
- LXI D,BUFFER+FILNAM!
- DAD D
- SHLD NAMEB !
- CALL CFN ; COMPARE.FILE.NAMES
- RET ; RETURN
- ;
- ;
- ;--------------------------------------
- ;
- CTNTEN: ; $ COMPARE.TEMP.NAME.TO.ENTRY.NAME
- ;
- LDA TMPENT ; NAME.A = ADDR[BUFFER] + ENTRY.LENGTH * TEMP.ENTRY + FILE.NAME
- LXI D,ENTLEN!
- CALL MULT8 !
- LXI D,BUFFER+FILNAM!
- DAD D
- SHLD NAMEA
- LDA ENTRY ; NAME.B = ADDR[BUFFER] + ENTRY.LENGTH * ENTRY + FILE.NAME
- LXI D,ENTLEN!
- CALL MULT8 !
- LXI D,BUFFER+FILNAM!
- DAD D
- SHLD NAMEB !
- CALL CFN ; COMPARE.FILE.NAMES
- RET ; RETURN
- ;
- ;
- ;--------------------------------------
- ;
- CFN: ; $ COMPARE.FILE.NAMES
- ;
- LXI H,CHRCNT; CHAR.COUNT = NAME.LENGTH
- MVI M,NAMLEN!
- LXI H,NAMEOK; NAME.OK = TRUE
- MVI M,TRUE !
- LOOP05: ; LOOP
- LHLD NAMEA ; IF (NAME.A) <> "?"
- MOV A,M !
- CPI '?' !
- JZ FI05 !
- LHLD NAMEA ; . IF (NAME.A) <> (NAME.B)
- MOV A,M !
- LHLD NAMEB !
- CMP M !
- NOP
- JZ FI06 !
- LXI H,NAMEOK; . . NAME.OK = FALSE
- MVI M,FALSE !
- FI06: ; . FI
- LXI H,NAMEOK; . EXIT.IF NAME.OK = FALSE
- MOV A,M !
- CPI FALSE !
- JZ POOL05 !
- FI05: ; FI
- LXI H,CHRCNT; CHAR.COUNT = CHAR.COUNT - 1
- DCR M !
- LDA CHRCNT ; EXIT.IF CHAR.COUNT = 0
- CPI 0 !
- JZ POOL05 !
- LHLD NAMEA ; NAME.A = NAME.A + 1
- INX H !
- SHLD NAMEA !
- LHLD NAMEB ; NAME.B = NAME.B + 1
- INX H !
- SHLD NAMEB !
- JMP LOOP05 ; POOL
- POOL05: !
- RET ; RETURN
- ;
- ;
- ;--------------------------------------
- ;
- PEWSFN: ; $ PROCESS.ENTRYS.WITH.SAME.FILE.NAME
- ;
- LXI H,0 ; FILE.SIZE = 0
- SHLD FILSIZ !
- LXI H,0 ; FILE.EXTENTS = 0
- SHLD FILEXT !
- LDA ENTRY ; TEMP.ENTRY = ENTRY
- STA TMPENT !
- LDA ENTRY ; ENTRY.POINTER = ADDR[BUFFER] + ENTRY * ENTRY.LENGTH
- LXI D,ENTLEN!
- CALL MULT8 !
- LXI D,BUFFER
- DAD D !
- SHLD ENTPTR !
- LHLD ENTPTR ; TEMP.ENTRY.PTR = ENTRY.POINTER
- SHLD TENPTR !
- LXI H,ENTRY; USED.POINTER = ADDR[ENTRY.USED] + ENTRY
- MOV L,M !
- MVI H,0 !
- LXI D,ENTUSD!
- DAD D !
- SHLD USDPTR !
- LOOP06: ; LOOP
- LHLD USDPTR ; IF (USED.POINTER) = FALSE
- MOV A,M !
- CPI FALSE !
- JNZ FI07 !
- CALL CTNTEN ; . COMPARE.TEMP.NAME.TO.ENTRY.NAME
- LDA NAMEOK ; . IF NAME.OK
- CPI TRUE !
- JNZ FI08 !
- LXI D,RECCNT; . . FILE.SIZE = FILE.SIZE + (TEMP.ENTRY.PTR + RECORD.COUNT)
- LHLD ENTPTR !
- DAD D !
- MOV E,M !
- MVI D,0 !
- LHLD FILSIZ !
- DAD D !
- SHLD FILSIZ !
- LHLD FILEXT ; . . FILE.EXTENTS = FILE.EXTENTS + 1
- INX H !
- SHLD FILEXT !
- LHLD USDPTR; . . (USED.POINTER) = TRUE
- MVI M,TRUE !
- FI08: ; . FI
- FI07: ; FI
- LXI H,TMPENT; TEMP.ENTRY = TEMP.ENTRY + 1
- INR M !
- LXI H,TMPENT; EXIT.IF TEMP.ENTRY >= MAX.ENTRY
- MOV A,M !
- CPI MAXENT !
- JP POOL06 !
- LXI D,ENTLEN; TEMP.ENTRY.PTR = TEMP.ENTRY.PTR + ENTRY.LENGTH
- LHLD TENPTR !
- DAD D !
- SHLD TENPTR !
- LHLD USDPTR ; USED.POINTER = USED.POINTER + 1
- INX H !
- SHLD USDPTR !
- JMP LOOP06 ; POOL
- POOL06: !
- LHLD FILSIZ ; TOTAL.SIZE = TOTAL.SIZE + FILE.SIZE
- XCHG !
- LHLD TOTSIZ !
- DAD D !
- SHLD TOTSIZ !
- LHLD FILEXT ; TOTAL.EXTENTS = TOTAL.EXTENTS + FILE.EXTENTS
- XCHG !
- LHLD TOTEXT !
- DAD D !
- SHLD TOTEXT !
- RET ; RETURN
- ;
- ;
- ;
- ;--------------------------------------
- ;
- PFIL: ; $ PRINT.FILE.INFORMATION.LISTING
- ;
- LHLD ENTPTR ; PRINT FILE.NAME(11)
- INX H !
- MVI B,8 !
- CALL PRNC !
- CALL PRS !
- MVI B,3 !
- CALL PRNC !
- CALL PRS !
- CALL PRS !
- CALL PRS !
- LXI H,DATA ; PRINT FILE.SIZE * SECTOR.SIZE
- CALL CLEAR !
- LHLD FILSIZ !
- SHLD DATA+1 !
- LXI H,DATA !
- CALL SHIFTR !
- CALL BINBCD !
- LXI H,RESULT+2
- CALL PR6HXD !
- CALL PRS !
- CALL PRS !
- CALL PRS !
- LXI H,DATA ; PRINT FILE.SIZE
- CALL CLEAR !
- LHLD FILSIZ !
- SHLD DATA !
- CALL BINBCD !
- LHLD RESULT !
- CALL PRADDR !
- CALL PRS !
- CALL PRS !
- CALL PRS !
- LXI H,DATA ; PRINT FILE.EXTENTS
- CALL CLEAR !
- LHLD FILEXT !
- SHLD DATA !
- CALL BINBCD !
- LHLD RESULT !
- CALL PRADDR !
- CALL PRCRLF !
- RET ; RETURN
- ;
- ;
- ;
- ;--------------------------------------
- ;
- PTL: ; $ PRINT.TOTALS.LISTING
- ;
- CALL PRCRLF !
- MVI C,9 ;PRINT "TOTAL.SIZE "
- LXI D,MSG2 !
- CALL BDOS !
- LXI H,DATA ; PRINT TOTAL.SIZE * SECTOR.SIZE
- CALL CLEAR !
- LHLD TOTSIZ !
- SHLD DATA+1 !
- LXI H,DATA !
- CALL SHIFTR !
- CALL BINBCD !
- LXI H,RESULT+2
- CALL PR6HXD !
- CALL PRS !
- CALL PRS !
- CALL PRS !
- LXI H,DATA ; PRINT TOTAL.SIZE
- CALL CLEAR !
- LHLD TOTSIZ !
- SHLD DATA !
- CALL BINBCD !
- LHLD RESULT !
- CALL PRADDR !
- CALL PRS !
- CALL PRS !
- CALL PRS !
- LXI H,DATA ; PRINT TOTAL.EXTENTS
- LHLD TOTEXT !
- SHLD DATA !
- CALL BINBCD !
- LHLD RESULT !
- CALL PRADDR !
- CALL PRCRLF !
- RET ; RETURN
- MSG2: DB 'TOTAL.SIZE ','$'
- ;
- ;
- ;-----------------------------------------------
- ;
- ; BINARY TO BCD CONVERSION
- ;
- ;-----------------------------------------------
-
- ; ASSUMES THREE REGISTERS IN MEMORY:
- ; 1) DATA - CONTAINS UNSIGNED BINARY NUMBER
- ; 2) PARTIAL - PACKED BCD NUMBER = 2**N
- ; 3) RESULT - PACKED BCD NUMBER = SUM OF PARTIAL VALUES
-
- NBYTES: EQU 3 ; REGISTER LENGTH
- NBITS: EQU NBYTES*8; NUMBER OF BITS CONVERTED
-
-
- BITCNT: DS 1 ; BITS REMAINING TO BE CONVERTED
- RESULT: DS NBYTES ; RESULT REGISTER
- PARTL: DS NBYTES ; PARTIAL REGISTER
- DATA: DS NBYTES ; BINARY DATA REGISTER
-
-
- BINBCD: LXI H,BITCNT; SET BIT COUNT
- MVI M,NBITS
- LXI H,RESULT; CLEAR RESULT REGISTER
- CALL CLEAR
- LXI H,PARTL ; CLEAR PARTIAL SUM REG
- CALL CLEAR
- LXI H,PARTL ; SET PARTIAL = 1
- MVI M,1
- BINBC1: ORA A ; CLEAR CARRY
- LXI H,DATA ; SHIFT DATA RIGHT
- CALL SHIFTR
- JNC BINBC2 ; SKIP ADD IF BIT WAS 0
- LXI H,PARTL ; ADD POWER OF 2 TO RESULT
- LXI D,RESULT
- CALL BCDADD
- BINBC2: LXI H,PARTL ; DOUBLE PARTIAL
- LXI D,PARTL
- CALL BCDADD
- LXI H,BITCNT; CHECK BIT COUNT
- DCR M
- JNZ BINBC1 ; DONE?
- RET
-
-
- ; CLEAR A REGISTER
- ; ADDR IN HL
-
- CLEAR: MVI B,NBYTES; CLEAR A REGISTER
- CLEAR1: MVI M,0
- INX H
- DCR B
- JNZ CLEAR1
- RET
-
-
- ; SHIFT RIGHT WITH CARRY
- ; ADDR IN HL
-
- SHIFTR: RAL ; SAVE CARRY IN A
- MVI B,NBYTES; CALCULATE ADDR OF LAST BYTE
- MOV E,B
- DCR E
- MVI D,0
- DAD D
- SHIFR1: RAR ; RESTORE SAVED CARRY
- MOV A,M
- RAR ; SHIFT DATA
- MOV M,A
- RAL ; SAVE CARRY
- DCX H ; MOVE TO NEXT BYTE
- DCR B ; CHECK BYTE COUNT
- JNZ SHIFR1 ; DONE?
- RAR ; RESTORE CARRY
- RET
-
-
- ; BCD ADDITION
- ; ADDS REGISTER AT ADDR IN HL
- ; TO CONTENTS OF REGISTER AT ADDR DE
-
- BCDADD: MVI B,NBYTES
- XRA A ; CARRY = 0
- BCDAD1: RAR ; RESTORE CARRY
- LDAX D
- ADC M
- DAA
- STAX D
- RAL ; SAVE CARRY
- INX D
- INX H
- DCR B
- JNZ BCDAD1
- RAR ; RESTORE CARRY
- RET
-
- ;***********************************************
- ;
- ; CONVERT CP/M RECORD NUMBER TO DISK SECTOR
- ;
- ; ENTER WITH RECORD IN C, AND
- ; RETURN WITH SECTOR IN C.
- ; DESTROY CONTENTS OF B,HL
- ;
- ;**********************************************
-
- ; COMPUTE TABLE ADDRESS OF SECTOR
-
- RECSEC: LXI H,SECTBL-1
- MVI B,0
- DAD B
- MOV C,M
- RET
-
- ; RECORD TO SECTOR CONVERSION TABLE
-
- SECTBL: DB 1,7,13,19,25,5,11,17
- DB 23,3,9,15,21,2,8,14
- DB 20,26,6,12,18,24,4,10
- DB 16,22
-
- ;******************************************
- ;* HEXIDECIMAL CHARACTER OUTPUT LIBRARY *
- ;******************************************
- ;
- ; VERSION 0.2 19 APR 77
- ;
- PRHL: MOV A,C
- RAR
- RAR
- RAR
- RAR
- JMP PRHR1
- PRHR: MOV A,C
- PRHR1: ANI 0FH
- ADI '0'
- CPI '9'+1
- JM PRA
- ADI '@'-'9'
- PRA: PUSH B
- MOV B,A
- LDA LZRO
- ORA A
- JZ PRA1
- MOV A,B
- CPI '0'
- JNZ PRA1
- MVI B,20H
- JMP PRA2
- PRA1: MVI A,0
- STA LZRO
- PRA2: MOV A,B
- POP B
- PUSH H ! PUSH D ! PUSH B
- MOV E,A
- MVI C,2
- CALL BDOS
- POP B ! POP D ! POP H
- RET
- ;
- ;
- PR2HX: MOV C,M
- INX H
- PR2H: CALL PRHL
- JMP PRHR
- ;
- ;
- PR2HXS: CALL PR2HX
- PRS: MVI A,' '
- JMP PRA
- ;
- ;
- PRADDR: MVI A,TRUE
- STA LZRO
- MOV C,H
- CALL PR2H
- MOV C,L
- JMP PR2H
- ;
- ;
- PR6HXD: MVI A,TRUE
- STA LZRO
- CALL PR2HXD
- CALL PR2HXD
- CALL PR2HXD
- RET
-
- PR2HXD: MOV C,M
- DCX H
- JMP PR2H
-
- PRNC: MOV A,M
- CALL PRA
- INX H
- DCR B
- JNZ PRNC
- RET
-
- PRCRLF: PUSH H ! PUSH D ! PUSH B
- LXI D,CRSTRG
- MVI C,9
- CALL BDOS
- POP B ! POP D ! POP H
- RET
- ;
- ;
- CRSTRG: DB 0DH,0AH,0,0,'$'
- ;
- ;******************************************
- ;----------------------------------------------
- ;
- ; UNSIGNED 8 BIT MULTIPLY
- ;
- ;-----------------------------------------------
-
- ; ENTER WITH:
- ; MULTIPLIER IN A
- ; MULTIPLICAND IN DE
- ; RETURN WITH:
- ; PRODUCT IN HL
- ; DESTROYS:
- ; A, DE
-
- MULT8: LXI H,0 ; CLEAR PARTIAL PRODUCT
- MULT1: ORA A ; CLEAR CARRY
- RAR ; SHIFT MULTPLR RIGHT
- JNC MULT2 ; SKIP IF ZERO
- DAD D ; ADD MPLCND TO PARTIAL
- MULT2: XCHG ;
- DAD H ; SHIFT MLTPCND LEFT
- XCHG ;
- ORA A ; SET FLAGS
- JNZ MULT1 ; LOOP UNTIL DONE
- RET ;
- ;******************************************
- ;* BIOS FUNCTION CALLING PROCEDURE *
- ;******************************************
- ;
- ; THIS PROCEDURE ALLOWS CALLING BIOS
- ; FUNCTIONS WITHOUT PRIOR KNOWLEDGE OF THE
- ; SIZE OF THE CP/M SYSTEM.
- ;
- ; CALL FBIOS WITH THE FUNCTION IN A
- ; AND THE PARAMETER IN BC.
- ;
- FBIOS: MOV E,A ; GET ENTRY OFFSET
- MVI D,0 ; IN DE
- LHLD 1 ; GET BIOS ENTRY + 3
- DAD D ; ADD ENTRY TO OFFSET
- PCHL ; JUMP TO BIOS
- ;
- ; BIOS ENTRY CODE NAMES
- ;
- WBOOT: EQU 0 ; WARM BOOT
- CONST: EQU 3 ; TEST CONSOLE STATUS
- CONIN: EQU 6 ; CONSOLE INPUT
- CONOUT: EQU 9 ; CONSOLE OUTPUT
- LIST: EQU 12 ; LIST OUTPUT
- PUNCH: EQU 15 ; PUNCH OUTPUT
- READER: EQU 18 ; READER INPUT
- HOME: EQU 21 ; HEAD TO TRACK 0
- SELDSK: EQU 24 ; SELECT DRIVE
- SETTRK: EQU 27 ; SET NEXT TRACK
- SETSEC: EQU 30 ; SET NEXT SECTOR
- SETDMA: EQU 33 ; SET DMA ADDRESS
- READS: EQU 36 ; READ SECTOR
- WRITES: EQU 39 ; WRITE SECTOR
- ;
- ;
- END ; END
-