home *** CD-ROM | disk | FTP | other *** search
Text File | 1984-04-29 | 22.0 KB | 1,027 lines |
- ; --- DUMP ---
- ;
- ; BY: S. J. SINGER
- ;
- ; THIS PROGRAM IS AN IMPROVED DUMP UTILITY FOR CP/M. ANY CPM FILE
- ;MAY BE DUMPED TO THE CONSOLE IN A FORMAT SIMILAR TO THAT USED BY THE
- ;DDT DUMP COMMAND. IN ADDITION, ANY SECTOR OR GROUP OF SECTORS MAY
- ;BE DUMPED IN THE SAME FORMAT.
- ;
- ; -- OPERATION --
- ;
- ; THE PROGRAM MAY BE RUN EITHER BY TYPING DUMP, OR DUMP FOLLOWED
- ;BY THE FILE NAME OR TRACK AND SECTOR. IF DUMP IS TYPED THE PROGRAM
- ;RESPONDS WITH A HEADING FOLLOWED BY A '*' AND WAITS FOR MORE INPUT.
- ;OPERATION IN THIS MODE IS SIMILAR TO OTHER UTILITIES LIKE PIP OR DDT.
- ; THE OPERATION DESIRED MAY THEN BE TYPED IN AS FOLLOWS:
- ;
- ; DUMP FILE.NAM
- ; DUMP A:FILE.NAM
- ; DUMP B:FILE.NAM
- ;
- ; OR DUMP MAY BE TYPED SEPARATELY AS:
- ;
- ; DUMP
- ;
- ; *FILE.NAM
- ; *B:FILE.NAM (THE * IS A PROGRAM PROMPT)
- ;
- ; THE PROGRAM MAY ALSO BE USED TO DUMP DISK SECTORS DIRECTLY, OR
- ;DUMP ANY CP/M EIGHT SECTOR GROUP.
- ;
- ; DUMP TRACK 3 SECTOR 7
- ; DUMP TRACK 5 SECTOR 3 - 9
- ; DUMP TRACK 6 (DUMPS ALL 26 SECTORS)
- ; DUMP GROUP 19
- ;
- ; THE WORDS 'TRACK' AND 'SECTOR' MAY BE ABREVIATED AS FOLLOWS
- ;
- ; DUMP T 7 S 3-4
- ; *TRACK 5 S 6
- ; *SECTOR 2- 9 T 14
- ;
- ;
- ; DUMP B: TRACK 3
- ; DUMP A: T 9 S 4-6
- ;
- ; NOTE THAT THE FORMAT IS QUITE FREE. SPACES ARE USUALLY IGNORED
- ;THEY ARE ONLY REQUIRED AFTER THE WORDS TRACK AND SECTOR OR T AND S,
- ;AND AFTER THE WORD DUMP.
- ; AN ADDITIONAL FEATURE OF DUMP IS THE ABILITY TO VALIDATE A DISK.
- ;
- ; DUMP VALIDATE
- ; DUMP A:VALIDATE
- ; DUMP B:VALIDATE
- ;
- ; THIS CAUSES THE ENTIRE DISK SELECTED TO BE READ ONE SECTOR AT A
- ;TIME. THE SECTOR NUMBER OF ANY SECTOR CAUSING A READ ERROR WILL BE DISPLAYED
- ;
- ; AS WITH OTHER CP/M UTILITIES ^S "FREEZES" THE DISPLAY, AND ^C
- ;RETURNS TO THE MONITOR. DUMP CONTAINS MANY ERROR AND CONSISTANCY
- ;CHECKS. THE RESULTING MESSAGES SHOULD BE SELF EXPLANATORY.
- ;
- ;
- ;
- ;
- ;
- ; 40. SETTRK - SET DISK TRACK DIRECTLY
- ;
- .DEFINE SETTRK [N,%OUT] = [
- LDA N
- CPI 77 ;CHECK SECTOR MAX
- CMC ;COMPLIMENT CARRY
- JC %OUT
- MOV C,A ;SET SECTOR NUMBER
- LDA 2 ;ADDR OF BIOS
- STA .+5
- CALL 001EH
- %OUT:]
- ;
- ;
- ; 42. SETSEC - SET DISK SECTOR DIRECTLY
- ;
- .DEFINE SETSEC [N,%OUT,%L1] = [
- LDA N ;;SECTOR NO
- ORA A ;;IS SECTOR ZERO
- JZ %L1 ;;ERROR IF ZERO, SET CARRY
- CPI 27 ;;CHECK SECTOR > 26
- %L1: CMC
- JC %OUT
- MOV C,A
- LDA 2 ;;BIOS ADDR
- STA .+5
- CALL 0021H ;;CALL BIOS DIRECTLY
- %OUT:]
- ;
- ; 73. HOME - HOME ALL DRIVES
-
- .DEFINE HOME = [
- LDA 2
- STA .+5
- CALL 0018H] ;;CALL BIOS DIRECTLY
- ;
- ; 44. DREAD - READ DISK DIRECT
- ;
- .DEFINE DREAD = [
- LDA 2
- STA .+5
- CALL 0027H ;;CALL BIOS DIRECTLY
- ]
- ;
- ; 72. DECOUT - CONVERT CONTENTS OF HL TO DECIMAL AND OUTPUT TO CONSOLE
- ;
- .DEFINE DECOUT = [
- .IFN $DECSW,[
- CALL DECPRN]
- .IFE $DECSW,[
- CALL DECPRN
- $DECSW = 1
- JMP ENDDEC
- DECPRN: PUSH B
- PUSH D
- PUSH H
- LXI B,-10
- LXI D,-1 ;;THIS BECOMES NO DIVIDED BY RADIX
- DAD B
- INX D
- JC .-2 ;;SUBTRACT TILL NEGATIVE
- LXI B,10
- DAD B ;;ADD RADIX BACK ONCE
- XCHG ;;N/10 IN HL, REMAINDER IN DE
- MOV A,H
- ORA L
- CNZ DECPRN ;;PRINT ANY DIGITS TO LEFT
- MOV A,E
- ADI '0'
- CONOUT 'SR' ;;PRINT THIS DIGIT
- POP H
- POP D
- POP B
- RET
- ENDDEC:]]
- ;
- ; 10. CONIN [$S] - CONSOLE INPUT TO A
- ;
- .DEFINE CONIN [$S] = [
- .IFIDN [$S] [SR], [
- PUSH H
- PUSH D
- PUSH B]
- MVI C,1
- CALL 5
- .IFIDN [$S] [SR],[
- POP B
- POP D
- POP H]
- ] ;END MACRO
- ; 14. $INSTR - IN STRING FUNCTION SEARCHES STRING OF LEN LSRT FOR SUBSTRING
- ; RETURNS WITH CARRY SET IF MATCH AND HL POINTING TO END SUBSTR
- ;
- .DEFINE $INSTR [STRING,LSTR,SUBSTRING,%STR,%OVER] = [
- .IFNB [STRING],[
- LHLD STRING] ;;GET STRING ADDR
- MVI B,LSTR ;;STRING LENGTH
- .IFN $STRSW,[
- LXI D,%STR
- MVI C,%OVER-%STR
- CALL FSTR
- JMP %OVER
- %STR: .ASCII 'SUBSTRING'
- %OVER:]
- .IFE $STRSW,[
- LXI D,%STR
- MVI C,%OVER-%STR
- CALL FSTR
- JMP %END
- %STR: .ASCII 'SUBSTRING'
- %OVER:
- $STRSW = 1
- FSTR: MOV A,B ;;STRING LEN
- SUB C ;;SUBSTR LEN
- CMC
- JM .+21 ;;SUBSTR LONGER THAN STRING
- MOV B,A ;;STRING LENGTH-SUBSTRING LENGTH
- INSTR1: PUSH H
- PUSH D
- PUSH B
- DCR C ;;DECR LENGTH COUNT
- JM .+17 ;;EXIT MATCH FOUND
- LDAX D ;;GET A BYTE FROM FIRST STRING
- CMP M ;;CONPARE WITH SECOND STRING
- JNZ .+8 ;;EXIT NO MATCH
- INX H
- INX D ;;INCR ADDR POINTERS
- JMP .-11 ;;TRY AGAIN
- XRA A ;;CLEAR CARRY
- JMP .+4 ;;EXIT
- STC ;;SET CARRY
- POP B
- POP D
- POP H
- JC SSX ;;MATCH FOUND SET POINTER AND RET
- DCR B ;;DECR STRING LEN
- RM ;;RETURN IF MINUS - NO MATCH
- INX H ;;INCR STRING POINTER
- JMP INSTR1 ;;GO TRY SOME MORE
- RET
- SSX: LXI D,0
- MOV E,C
- DAD D ;;ADD LENGTH TO POINTER
- STC ;;SET CARRY
- RET
- %END:]]
- ;
- ; 60. FNUM - SCAN INPUT BUFFER FROM [BP] FOR NUMBER AND CONVERT LEAST
- ; SIGNIFICANT 4 DIGITS TO BINARY. LEADING BLANKS OR TABS SKIPPED
- ; CONVERSION TERMINATES WITH BLANK - , OR 0. CARRY SET IF ERROR
- ; ON EXIT DE CONTAINS POINTER TO NEXT CHAR AFTER NUMBER.
- ;
- .DEFINE FNUM [BP,%SCAN,%SCAN1,%CON] = [
- .IFNB [BP] , [
- LHLD BP]
- .IFN $NUMSW,[
- CALL NUMSCN]
- .IFE $NUMSW,[
- CALL NUMSCN
- $NUMSW = 1
- JMP ENDNUM
- NUMSCN: XCHG ;;POINTER IN DE
- DCX D
- %SCAN: INX D ;;INCR POINTER
- LDAX D ;;GET A CHAR
- CPI 20H ;;IS IT BLANK
- JZ %SCAN ;;LOOP BACK
- CPI 09H ;;A TAB
- JZ %SCAN ;;LOOP BACK
- LXI H,0 ;;ZERO HL
- %SCAN1: CHRBCD ;;CONVERT TO BCD
- RC ;;NON NUMERIC CHAR ERROR
- DAD H ;;SHIFT LEFT 4
- DAD H
- DAD H
- DAD H
- ADD L
- MOV L,A ;;ADD A DIGIT INTO HL
- INX D ;;INCR POINTER
- LDAX D ;;GET ANOTHER CHAR
- CPI 20H ;;SPACE
- JZ %CON
- CPI 9H ;;TAB
- JZ %CON
- CPI 0 ;;ZERO
- JZ %CON
- CPI '-' ;;MINUS
- JZ %CON
- CPI ',' ;;COMMA
- JZ %CON
- JMP %SCAN1 ;;CONVERT ANOTHER CHAR
- %CON: PUSH D ;;SAVE POINTER TO LAST CHAR
- BCDBIN ;;CONVERT TO BINARY
- POP D ;;GET BACK POINTER
- RET
- ENDNUM:]]
- ;
- ;
- ;
- ; 50. CHRBCD - CONVERT AN ASCII CHAR IN A TO BCD, CARRY SET IF ERROR
- ;
- .DEFINE CHRBCD [%OUT] = [
- CPI 40H ;;
- CMC ;;COMPLIMENT CARRY
- JC %OUT
- CPI 30H
- JC %OUT
- ANI 0FH ;;EXTR LOWER 4 BITS
- %OUT:]
- ;
- ; 56. BCDBIN - CONVERT A BCD POS INTEGER IN HL TO BINARY
- ; RESULT IN HL AND LEAST SIGNIFICANT 8 BITS IN A
- ;
- .DEFINE BCDBIN = [
- XCHG ;;MOVE HL TO DE
- MOV A,E ;;LOW 2 DIGITS TO A
- MVI H,0 ;;ZERO H
- ANI 0FH ;;EXTR AND CLEAR CARRY
- MOV L,A ;;ONE'S DIGIT TO L
- LXI B,10 ;;MULTIPLIER FOR 2ND DIGIT
- MOV A,E ;;LOW DIGITS BACK TO A
- RAR ;;SHIFT R TO CLEAR SIGN
- SUI 8 ;;SUBTRACT 1 FROM 10'S POS
- JM .+7 ;;10'S FINISHED IF MINUS
- DAD B ;;ADD 10 TO HL
- JMP .-6
- LXI B,100 ;;MULTIPLIER FOR 3RD DIGIT
- MOV A,D ;;GET 2 HIGH DIGITS IN A
- ANI 0FH ;;EXTR 100'S DIGIT
- DCR A ;;SUB 1 FROM 100'S
- JM .+7 ;;100'S FINISHED IF MINUS
- DAD B ;;ADD 100 TO HL
- JMP .-5 ;;MULTIPLY BY 100
- LXI B,1000 ;;MULTIPLIER FOR 4TH DIGIT
- MOV A,D ;;TWO HIGH DIGITS BACK TO A
- ANI 0F0H ;;EXTR AND CLEAR CARRY
- RAR ;;SHIFT R TO CLEAR SIGN
- SUI 8 ;;SUBTRACT 1 FROM 1000'S
- JM .+7 ;;1000'S FINISHED IF MINUS
- DAD B ;;ADD 1000 TO HL
- JM .-6 ;;MULTIPLY BY 1000
- XRA A ;;CLEAR CARRY
- MOV A,L ;;LEAST SIGNIFICANT 8 BITS TO A
- ]
- ;
- ; 2. CPHL - COMPARE DE AND HL AND SET FLAGS
- ;
- .DEFINE CPHL = [
- MOV A,H
- CMP D ;;COMPARE HIGH BYTES
- JNZ .+5
- MOV A,L
- CMP E] ;;COMPARE LOW BYTES
- ;
- ; 12. INDEX - INDEX AN ADDRESS POINTER BY A CONSTANT
- ;
- .DEFINE INDEX [POINTER,INDX] = [
- LHLD POINTER
- LXI D,INDX
- DAD D
- SHLD POINTER]
- ;
- ; 3. MOVE - MOVE A BLOCK OF LENGTH LEN FROM SOURCE TO DEST
- ;
- .DEFINE MOVE [SOURCE,DEST,LEN] = [
- LXI D,SOURCE ;SOURCE
- LXI H,DEST ;DEST
- LXI B,LEN ;LENGTH
- LDAX D ;GET A BYTE
- MOV M,A ;STORE IT
- INX H
- INX D ;BUMP POINTERS
- DCX B ;DECR LENGTH COUNT
- MOV A,B
- ORA C
- JNZ .-7] ;TEST DONE?
- ;
- ; 15. $MATCH - COMPARE STRING WITH LITERAL AND SET CARRY IF EQUAL
- ;
- .DEFINE $MATCH [STR1,STR2,%STR,%OVER] = [
- LXI H,STR1
- .IFN $MATSW,[
- LXI D,%STR
- MVI C,%OVER-%STR
- CALL SMATCH
- JMP %OVER
- %STR: .ASCII 'STR2'
- %OVER:]
- .IFE $MATSW,[
- LXI D,%STR
- MVI C,%OVER-%STR
- CALL SMATCH
- JMP MATEND
- %STR: .ASCII 'STR2'
- %OVER:
- $MATSW = 1 ;;CONDITIONAL ASSEMBLY SWITCH
- SMATCH: DCR C ;;DECR LENGTH COUNT
- JM SM3 ;;EXIT MATCH FOUND
- LDAX D ;;GET A BYTE FROM FIRST STRING
- CMP M ;;COMPARE WITH SECOND STRING
- JNZ SM2 ;;EXIT, NO MATCH
- INX H
- INX D ;;INCR ADDR POINTERS
- JMP SMATCH ;;TRY AGAIN
- SM2: XRA A ;;CLEAR CARRY
- JMP .+4 ;;EXIT
- SM3: STC ;;SET CARRY
- RET
- MATEND:]]
- ;
- ;
- ; 5. READTB - READ CHAR STRING INTO INPUT TEXT BUFFER
- ;
- .DEFINE READTB [TEXT,MAX(127)] = [
- MVI C,10
- LXI D,TEXT
- MVI A,MAX
- STAX D ;SET MAXIMUM BUFFER LENGTH
- CALL 5]
- ;
- ; 30. - BINHEX - CONVERT AN 8 BIT NUMBER IN A TO HEX, RESULT IN HL
- ;
- .DEFINE BINHEX [%OVER,%CONV] = [
- PUSH PSW ;;SAVE NO ON STACK
- RAR
- RAR
- RAR
- RAR ;;SHIFT RIGHT 4 BITS
- CALL %CONV ;;CONVERT TO HEX
- MOV L,A ;;SAVE IN L
- POP PSW ;;GET BACK NO
- CALL %CONV ;;CONVERT IT
- MOV H,A ;;PUT IT IN A
- JMP %OVER ;;GET OUT
- %CONV: ANI 0FH ;;EXTR LOW 4 BITS
- ADI 90H ;;ADD OFFSET FOR CONV
- DAA ;;DECIMAL ADJUST
- ACI 40H ;;ADD 40H
- DAA ;;DECIMAL ADJUST AGAIN
- RET
- %OVER:]
- ;
- ; 31. HEXOUT - CONVERT A BINARY NO TO HEX AND OUTPUT TO CONSOLE
- ;
- .DEFINE HEXOUT = [
- .IFN $HEXSW,[
- CALL HEXPRN
- ]
- .IFE $HEXSW,[
- $HEXSW = 1
- CALL HEXPRN
- JMP ENDHEX
- HEXPRN: PUSH H
- PUSH D
- PUSH B
- BINHEX ;;CONVERT TO HEX
- PUSH H ;;SAVE HEX NUMBER ON STACK
- MOV A,L
- CONOUT ;;PRINT FIRST DIGIT
- POP PSW ;;GET SECOND DIGIT
- CONOUT ;;PRINT SECOND DIGIT
- POP B
- POP D
- POP H
- RET
- ENDHEX:]]
- ;
- ; 7. PRINT - PRINT TEXT FROM MEMORY TO CONSOLE
- ;
- .DEFINE PRINT [B$] = [
- PUSH H
- PUSH D
- PUSH B
- MVI C,9
- LXI D,B$
- CALL 5
- POP B
- POP D
- POP H]
- ;
- ; 11. CONOUT - CONSOLE OUTPUT FROM A
- ;
- .DEFINE CONOUT [$S] = [
- .IFNB [$S],[
- PUSH H
- PUSH D
- PUSH B]
- MOV E,A
- MVI C,2
- CALL 5
- .IFNB [$S],[
- POP B
- POP D
- POP H]
- ] ;END MACRO
- ;
- ; 6. PRINTL - PRINT A LITERAL CHARACTER STRING ENCLOSED IN ' '
- ;
- .DEFINE PRINTL [A$,%OUT] = [
- MVI C,9
- LXI D,.+9
- CALL 5
- JMP %OUT
- .ASCII 'A$'
- %OUT:]
- ;
- ; 9. READ - READ NEXT DISK FILE
- ;
- .DEFINE READ [FCB] = [
- MVI C,20
- LXI D,FCB
- CALL 5
- ORA A
- JZ .+4
- STC] ;;SET CARRY ON EOF OR ERROR
- ;
- ; 8. OPEN - OPEN DISK FILE
- ;
- .DEFINE OPEN [NAME] = [
- MVI C,15
- LXI D,NAME
- CALL 5
- CPI 0FFH ;TEST FOR ERROR
- CMC ;COMPLIMENT CARRY
- JNZ .+4
- STC]
- ;
- ; 18. GETDRV - INTERROGATE AND SAVE CURRENTLY LOGGED DISK NO
- ;
- .DEFINE GETDRV [SAVE] = [
- MVI C,25
- CALL 5
- STA SAVE]
- ;
- ; 20. RESDRV - RESTORE SAVED DISK DRIVE NUMBER
- ;
- .DEFINE RESDRV [SAVE] = [
- MVI C,14
- LDA SAVE
- MOV E,A
- CALL 5]
- ;
- ;
- ; 1. FILL - FILL A BLOCK OF MEMORY WITH A CONSTANT MAX 64K
- ;
- .DEFINE FILL [START,END,CONST(0)] = [
- LXI H,START ;;SET START ADDR
- .IFB [END],[
- XRA A
- MOV M,A] ;;STORE ONE BYTE IF NO END
- .IFNB [END],[
- LXI D,END-START+1 ;;SET LENGTH
- MVI A,CONST ;;LOAD CONSTANT IN A
- MOV M,A ;;STORE THE CONST
- INX H ;;INCR H
- DCX D ;;DECR LENGTH
- MOV A,D
- ORA E ;;TEST LENGTH = ZERO
- JNZ .-7]] ;;REPEAT IF DE AND HL NOT EQUAL
- ;
- ; 13. FILFCB - FILL IN ID FIELDS OF FCB (FILE NAME ENDED BY ZERO BYTE)
- ; ON EXIT - CARRY SET IF NAME TOO LONG
- ; - HL POINTS TO NEXT BYTE AFTER NAME
-
- ;
- .DEFINE FILFCB [FCB,IDSTR,%ERROR,%DONE] = [
- LHLD IDSTR ;;POINTER TO NAME STRING
- XCHG
- LXI H,FCB ;;ADDR OF FILE CONTROL BLOCK
- .IFN $FCBSW,[
- CALL FFCB]
- .IFE $FCBSW,[
- CALL FFCB
- $FCBSW = 1 ;;SET CONDITIONAL ASSEMBLY SWITCH
- JMP ENDFCB
- FFCB: MVI M,0 ;CLEAR FIRST BYTE OF FCB
- INX H
- PUSH H ;;SAVE FCB NAME ADDR
- MVI C,11 ;;SIZE OF NAME
- MVI A,' ' ;;SPACE TO A
- MOV M,A ;;SET NAME FIELD TO SPACES
- INX H
- DCR C
- JNZ .-3
- POP H ;;RECOVER NAME ADDR
- MVI C,8 ;;MAXIMUM SIZE OF NAME+1
- LDAX D ;;GET ID BYTE
- CPI ' ' ;;LEADING SPACES ?
- JNZ .+7 ;;CONTINUE IF NOT
- INX D ;;SKIP LEADING SPACES
- JMP .-7
- LDAX D ;;GET ID BYTE
- CPI 0 ;;IS IT A ZERO BYTE
- JZ %DONE ;;YES DONE
- CPI ' ' ;;IMBEDDED SPACE?
- JZ %DONE ;;YES DONE
- CPI '.' ;;NAME.TYP SEPARATOR?
- JZ .+13 ;;YES, PROCESS TYPE
- MOV M,A ;;STORE NAME BYTE
- INX D
- INX H ;BUMP POINTERS
- DCR C ;DECREMENT MAX COUNT
- JP .-20 ;LOOP
- JMP %ERROR ;ERROR, NAME TOO BIG
- INX D ;SKIP OVER '.'
- MOV A,C
- ORA A
- JZ .+8
- INX H ;;SKIP TO TYPE FIELD
- DCR C
- JNZ .-2
- MVI C,3 ;;SIZE OF TYPE FIELD
- LDAX D ;;GET ID BYTE
- CPI 0 ;;ZERO BYTE?
- JZ %DONE ;;YES, DONE
- CPI ' ' ;;SPACE?
- JZ %DONE ;;YES, DONE
- MOV M,A ;;STORE TYPE BYTE
- INX D ;;BUMP POINTERS
- INX H
- DCR C ;;DECREMENT MAX COUNT
- JNZ .-15 ;;LOOP
- JMP %DONE ;;DONE
-
-
- %ERROR: STC ;;SET CARRY
- %DONE: XCHG ;;POINTER TO END OF NAME
- RET
- ENDFCB:]] ;;END MACRO
- ;
- .PABS ;ABSOLUTE ASSEMBLY
- .LIST
- .SALL
- .XSYM
- .LOC 100H ;ORIGIN AT 100H
- $FCBSW = 0 ;CONDITIONAL ASSEMBLY SWITCHES
- $HEXSW = 0
- $MATSW = 0
- $NUMSW = 0
- $STRSW = 0
- $DECSW = 0
- LXI SP,NEWSTK ;SET UP NEW STACK
- GETDRV DRVNO ;GET CURRENTLY LOGGED DRIVE NO
- STA NEWDRV ;ALSO SAVE IN NEW DRIVE NO
- LDA 81H ;CONSOLE INPUT ALREADY HERE ?
- ORA A
- JNZ START
- PRINT CRLF
- PRINTL 'CP/M DUMP UTILITY VERS 1.2$'
- PRINT CRLF
- PRINTL 'COPYRIGHT 1977 BY S. J. SINGER$'
- NEWIN: PRINT CRLF2
- PRINTL '*$'
- MVI A,0FFH ;SET SWITCH TO RETURN HERE AGAIN
- STA INFLAG
- LXI SP,NEWSTK ;RESET STACK POINTER
- XRA A
- STA VALFLG ;RESET VALIDATION ERROR FLAG
- LXI H,0
- SHLD LINE ;SET LINE COUNT TO ZERO
- FILL 80H,0FFH ;ZERO INPUT BUFFER
- READTB 80H ;READ FILE NAME
- ;
- ; SELECT DISK DRIVE AND SET UP FILE CONTROL BLOCK
- ;
- START: FILL FCB,FCB+32 ;ZERO FILE CONTROL BLOCK
- $MATCH 82H,'A:' ;DRIVE A
- JC ADISK
- $MATCH 82H,'B:' ;DRIVE B
- JC BDISK
- JMP GETNAM ;NO DRIVE SPECIFIED
- ADISK: XRA A
- STA NEWDRV ;SELECT DRIVE A
- JMP DOWN
- BDISK: MVI A,1
- STA NEWDRV ;SELECT DRIVE B
- DOWN: MOVE 82H,80H,80 ;SHIFT BUFFER DOWN TWO BYTES
- ;
- ; SEARCH FOR DIRECT READ OF TRACK AND SECTOR OR VALIDATE
- ;
- GETNAM: $INSTR SLOC1,80H,'VALIDATE'
- JC VALID ;VALIDATE DISK
- $INSTR SLOC1,80H,'GROUP'
- JC GROUP ;DISPLAY CPM 8 SECTOR GROUP
- $INSTR SLOC1,80H,'TRACK' ;SEARCH FOR TRACK
- JC TRK1
- $INSTR SLOC1,80H,'T ' ;SEARCH FOR 'T'
- JNC FILNAM ;NO TRACK GO TO READ FILE
- TRK1: FNUM ;FIND AND CONVERT NUMBER
- JC INERR ;INPUT ERROR ON CARRY
- STA TRACK ;SAVE TRACK NO
- $INSTR SLOC1,80H,'SECTOR' ;SEARCH FOR SECTOR
- JC SEC1
- $INSTR SLOC1,80H,'S ' ;TRY 'S'
- JNC WHLTRK ;DUMP ENTIRE TRACK
- SEC1: FNUM
- JC INERR ;INPUT ERROR ON CARRY
- STA BSEC ;BEGINNING SECTOR
- STA ESEC ;SAVE IN END SECTOR ALSO
- XCHG ;SET BUFFER POINTER FOR SCAN
- $INSTR ,80H,'-' ;SEARCH FOR '-'
- JNC DOREAD ;CONTINUE IF NO '-'
- FNUM ;SCAN AND CONVERT ANOTHER NO
- JC INERR ;ERROR IF CARRY SET
- STA ESEC ;SAVE IN END SECTOR
- LXI H,BSEC ;POINTS TO BSEC
- CMP M ;COMPARE BEGIN AND END
- JP DOREAD ;OK IF END>=BEGIN
- MOV B,A ;OTHERWISE
- MOV A,M ;SWITCH THEM
- STA ESEC
- MOV M,B
- DOREAD: CALL RDISK0 ;READ DIRECT
- JMP ENDFIL ;BACK FOR MORE INPUT
- ;
- ; READ TRACK AND SECTOR DIRECT
- ;
- RDISK0: CALL FIXB
- RDISK: SETSEC BSEC ;SET SECTOR
- JC BADSEC ;WRONG SECTOR NO
- TRK2: SETTRK TRACK ;SET TRACK
- JC BADTRK ;WRONG TRACK NO
- RESDRV NEWDRV ;SELECT NEW DRIVE IF SPECIFIED
- DREAD ;READ TRACK AND SECTOR
- ;
- ; PRINT DRIVE, TRACK AND SECTOR HEADING
- ;
- LDA NEWDRV ;NEW DRIVE NO
- ORA A
- JNZ PRNB ;PRINT DRIVE B
- PRINT CRLF
- PRINTL ' DRIVE A -$'
- PRNTRK: PRINTL ' TRACK $'
- LXI H,0
- LDA TRACK
- MOV L,A
- DECOUT
- PRINTL ' SECTOR $'
- LXI H,0
- LDA BSEC
- MOV L,A
- DECOUT
- PRINT CRLF
- CALL PRTBUF ;PRINT IT
- LXI H,BSEC ;ADDR OF SECTOR NUMBER
- LDA ESEC ;END SECTOR NUMBER
- CMP M ;COMPARE THEM
- RZ ;EXIT IF THEY ARE EQUAL
- INR M ;INCR BSEC
- JMP RDISK ;READ ANOTHER SECTOR
- PRNB: PRINT CRLF
- PRINTL ' DRIVE B -$'
- JMP PRNTRK ;PRINT TRACK AND SECTOR
- ;
- ; DUMP ENTIRE TRACK IF NO SECTOR INPUT
- ;
- WHLTRK: MVI A,1 ;BEGIN SECTOR
- STA BSEC
- MVI A,26 ;END SECTOR
- STA ESEC
- CALL RDISK0 ;TO READ DISK
- JMP ENDFIL ;BACK FOR MORE INPUT
- ;
- ; FILL IN FCB FOR NAMED FILE
- ;
- FILNAM: FILFCB FCB,SLOC1 ;FILL IN FCB NAME FROM INPUT BUFFER
- JC NAMERR ;ERROR IN FILE NAME
- $MATCH FCB+9,'COM' ;TEST FOR COM FILE
- JNC SELDR
- LXI H,100H
- SHLD LINE ;SET LINE NO. TO 100
- SELDR: RESDRV NEWDRV ;SELECT NEW DRIVE
- OPEN FCB ;OPEN FILE
- JC OPNERR ;EXIT IF ERROR
- RDFILE: READ FCB ;READ A BLOCK
- JC ENDFIL ;CARRY SET EOF OR ERROR
- CALL PRTBUF ;DO PRINT SUBROUTINE
- JMP RDFILE ;BACK FOR NEXT BLOCK
- ENDFIL: LDA INFLAG ;SEE WHERE TO GO
- ORA A
- JZ MONITOR
- JMP NEWIN
- ;
- ;
- ; PRTBUF - PRINT BUFFER IN HEX AND ASCII
- ;
- PRTBUF: MVI B,8 ;8 LINES
- LXI H,80H ;INITIAL BUFFER POINTER
- SHLD IPOINT ;STORAGE FOR POINTER
- BPRN: LHLD IPOINT ;LOAD POINTER
- MVI C,16 ;CHAR PER LINE
- LDA LINE+1 ;LINE NUMBER
- HEXOUT
- LDA LINE ;SECOND TWO DIGITS
- HEXOUT
- PRINT SPACE2
- PLOOP: MOV A,M ;GET A BYTE
- HEXOUT
- PRINT SPACE
- INX H ;INCR MEMORY POINTER
- MOV A,C
- CPI 9 ;CHECK 8 CHAR
- JNZ DECC ;SKIP IF NOT
- PRINT SPACE
- DECC: DCR C ;DECR CHAR COUNT
- JNZ PLOOP ;PRINT SOME MORE
- PRINT SPACE
- LHLD IPOINT ;RESET POINTER FOR ASCII
- MVI C,10H ;RESET CHAR COUNT
- PLOOP1: MOV A,M ;GET A BYTE
- CPI 7FH ;COMPARE WITH 7FH (DEL)
- JP PERIOD ;SUBSTITUTE PERIOD
- CPI 20H ;TEST FOR CONTROL CHAR
- JP SKIPX ;SKIP SUBSTITUTION
- PERIOD: MVI A,2EH ;ASCII PERIOD
- SKIPX: CONOUT 'SR' ;PRINT IT (SAVE REGS)
- INX H ;INCR MEMORY POINTER
- MOV A,C
- CPI 9 ;CHECK 8 CHAR
- JNZ DECC2
- PRINT SPACE
- DECC2: DCR C ;DECR CHAR COUNT
- JNZ PLOOP1 ;PRINT SOME MORE
- PRINT CRLF
- PUSH B
- CALL PRNCON ;PRINT CONTROL?
- POP B
- INDEX LINE,16 ;INCR LINE NO BY 16
- DCR B ;DECR LINE COUNT
- RZ ;RETURN IF LINE COUNT ZERO
- INDEX IPOINT,16 ;INCR POINTER BY 16
- JMP BPRN ;LOOP BACK
- ;
- ; THIS SECTION VALIDATES A DISK
- ;
- VALID: MVI A,1 ;START WITH SECTOR 1
- STA SNUM
- XRA A ;START WITH TRACK 0
- STA TNUM
- RESDRV NEWDRV ;SELECT NEW DRIVE
- RS0: SETTRK TNUM
- JC BADTRK
- RS1: SETSEC SNUM
- JC BADSEC
- DREAD
- ORA A
- CNZ VALERR ;ERROR IF NOT ZERO
- CALL PRNCON ;ESCAPE ON CONTROL C
- LDA SNUM ;SECTOR NO
- ADI 5 ;INCR BY 5
- STA SNUM ;STORE IT BACK
- SBI 27 ;CALC SECTOR MOD 26
- JM RS1 ;SECTOR OK IF MINUS
- INR A ;SECTOR MOD 26
- STA SNUM ;STORE IT BACK
- CPI 1 ;ARE WE BACK TO ONE YET
- JNZ RS1 ;READ SOME MORE
- LDA TNUM ;TRACK NUMBER
- INR A ;INCR BY ONE
- CPI 77 ;CHECK LIMIT
- JZ VALOUT ;TO EXIT
- STA TNUM ;STORE BACK TRACK NO
- JMP RS0 ;BACK TO READ ROUTINE
- VALOUT: LDA VALFLG ;CHECK ERROR FLAG
- ORA A
- JNZ ENDFIL
- PRINT CRLF
- PRINTL 'SUCCESSFUL VALIDATION$'
- LDA NEWDRV
- ORA A
- JNZ VAL2
- PRINTL ' DRIVE A$'
- JMP ENDFIL
- VAL2: PRINTL ' DRIVE B$'
- JMP ENDFIL
- VALERR: PRINT CRLF
- PRINTL 'ERROR - TRACK $'
- LDA TNUM
- LXI H,0
- MOV L,A
- DECOUT
- PRINTL ' SECTOR $'
- LXI H,0
- LDA SNUM
- MOV L,A
- DECOUT
- PRINT CRLF
- MVI A,-1
- STA VALFLG ;SET ERROR FLAG
- RET
- ;
- ;
- ; PRINT CONTROL AND ESCAPE
- ;
- PRNCON: MVI C,11
- CALL 5
- ANI 1
- RZ ;RETURN
- CONIN ;READ CONSOLE
- CPI 3 ;TEST FOR CONTROL C
- JZ ENDFIL ;EXIT IF CONTROL C
- RET
- ;
- ;
- ;
- ; THIS SECTION DISPLAYS A CPM GROUP OF 8 SECTORS
- ;
- GROUP: FNUM ;GET THE GROUP NO
- JC INERR ;INPUT ERROR IF CARRY SET
- STA G ;SAVE GROUP NO
- ADI 12 ;CHECK LEGAL RANGE
- JC BADGRP
- XRA A
- STA S ;SET SECTOR COUNT TO 0
- CALL FIXB ;RESTORE DRIVE B IF SELECTED
- GRP1: CALL GRPTS ;CONVERT TO TRACK AND SECTOR
- CALL RDISK ;PRINT THE SECTOR
- LDA G ;CHECK LAST GROUP
- ADI 13 ;HAS ONLY 6 SECTORS
- JNC GRP2
- LDA S ;SECTOR COUNT
- CPI 5
- JZ ENDFIL ;EXIT
- GRP2: LDA S ;CHECK SECTOR COUNT
- INR A
- STA S ;INCR S BY 1
- CPI 8 ;CHECK LIMIT
- JNZ GRP1 ;PRINT ANOTHER SECTOR
- JMP ENDFIL ;BACK FOR MORE INPUT
- ; GRPTS CONVERT CPM GROUP AND SECTOR NUMBER TO TRK AND SEC
- ;
- GRPTS: MVI H,0 ;ZERO H
- LDA G ;GROUP NO
- MOV L,A ;TO L
- MOV D,H ;ZERO D
- DAD H
- DAD H
- DAD H ;SHIFT LEFT 3
- LDA S ;GET SECTOR NO
- MOV E,A ;TO DE
- DAD D ;HL HAS G*8+S
- LXI D,-26 ;DIVISOR
- MVI A,1 ;CONTAINS DIVIDEND
- DIV: DAD D ;SUB 26
- INR A
- JC DIV ;LOOP TILL MINUS
- LXI D,TABLE+26 ;INDEX INTO TABLE
- DAD D
- STA TRACK ;STORE TRACK NO
- MOV A,M ;GET SECTOR NO
- STA BSEC ;SAVE IN BEGINNING SECTOR
- STA ESEC ;SAVE IN END SECTOR TOO
- RET
- ;
- ; THIS ROUTINE RESTORES DRIVE B
- ;
- FIXB: LDA NEWDRV ;CHECK DRIVE NO
- ORA A
- RZ ;RETURN IF DRIVE A
- RESDRV NEWDRV ;SELECT DRIVE B
- XRA A
- STA TNUM ;SELECT TRACK ZERO
- INR A ;SELECT SECTOR 1
- STA SNUM
- SETSEC SNUM
- SETTRK TNUM
- HOME ;HOME DRIVES
- DREAD ;READ TRACK ZERO
- RET
- ; ERROR AND EXIT ROUTINES
- ;
- ;
- INERR: PRINT CRLF
- PRINTL 'INPUT ERROR$'
- JMP ENDFIL
- ;
- BADSEC: PRINT CRLF
- PRINTL 'INCORRECT SECTOR NUMBER$'
- JMP ENDFIL
- ;
- BADTRK: PRINT CRLF
- PRINTL 'INCORRECT TRACK NUMBER$'
- JMP ENDFIL
- ;
- BADGRP: PRINT CRLF
- PRINTL 'INCORRECT GROUP NUMBER (GREATER THAN 243)$'
- JMP ENDFIL
- ;
- OPNERR: PRINT CRLF
- LDA NEWDRV ;CURRENT DRIVE NO
- ORA A
- JNZ OPNER1
- PRINTL 'NO FILE BY THAT NAME ON DRIVE A$'
- JMP ENDFIL
- OPNER1: PRINTL 'NO FILE BY THAT NAME ON DRIVE B$'
- JMP ENDFIL
- ;
- RDERR: PRINT CRLF
- PRINTL 'DISK READ ERROR$'
- JMP MONITOR
- NAMERR: PRINT CRLF
- PRINTL 'ERROR IN FILE NAME$'
- JMP ENDFIL
- ;
- MONITOR:PRINT CRLF
- RESDRV DRVNO ;RESTORE LOGGED DRIVE NO
- JMP 0 ;EXIT BACK TO MONITOR
- ;
- ;
- ; DATA ALLOCATIONS
- ;
- FCB = 5CH ;FILE CONTROL BLOCK
- CRLF: .ASCII [0DH][0AH][24H]
- CRLF2: .ASCII [0DH][0AH][0AH][24H]
- SPACE: .ASCII [20H][24H]
- SPACE2: .ASCII [20H][20H][24H]
- LINE: .WORD 0 ;LINE NUMBER FOR LISTING
- IPOINT: .WORD 00 ;VARIABLE BUFFER POINTER
- SLOC1: .WORD 82H ;POINTER TO BEGINNING OF INPUT BUFFER
- LASTIN: .BYTE 0 ;LAST CONSOLE INPUT CHAR
- INFLAG: .BYTE 0 ;FLAG, RET FOR MORE CONSOLE INPUT
- DRVNO: .BYTE 0 ;STORAGE FOR ORIGINALLY LOGGED DRIVE
- NEWDRV: .BYTE 0 ;STORAGE FOR NEW DRIVE NO
- TRACK: .BYTE 0 ;SELECTED TRACK
- BSEC: .BYTE 0 ;SELECTED BEGINNING SECTOR
- ESEC: .BYTE 0 ;SELECTED ENDING SECTOR
- TNUM: .BYTE 0 ;TRACK NO FOR VALIDATE
- SNUM: .BYTE 0 ;SECTOR NO FOR VALIDATE
- VALFLG: .BYTE 0 ;VALIDATION ERROR FLAG
- G: .BYTE 0 ;CPM GROUP NO
- S: .BYTE 0 ;SECTOR NO WITHIN GROUP G
- ENDSTK: .BLKW 16 ;STORAGE FOR NEW STACK
- NEWSTK: .WORD 0 ;NEW STACK
- TABLE: .BYTE 01H ;SECTOR LOOK UP TABLE
- .BYTE 07H
- .BYTE 0DH
- .BYTE 13H
- .BYTE 19H
- .BYTE 05H
- .BYTE 0BH
- .BYTE 11H
- .BYTE 17H
- .BYTE 03H
- .BYTE 09H
- .BYTE 0FH
- .BYTE 15H
- .BYTE 02H
- .BYTE 08H
- .BYTE 0EH
- .BYTE 14H
- .BYTE 1AH
- .BYTE 06H
- .BYTE 0CH
- .BYTE 12H
- .BYTE 18H
- .BYTE 04H
- .BYTE 0AH
- .BYTE 10H
- .BYTE 16H
- .END
-