home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol018
/
3812dump.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
21KB
|
833 lines
;
;
;
; 3812DUMP.ASM Ver.1.0
;
; as of
;
; August 25, 1980
;
; This program is a disk dump and edit utility, originally
; written by S. J. Singer for CP/M 1.4 single density (IBM
; 3741 compatible) diskettes (ref. CP/M User's Group, Volume
; 24.1), and modified for usage with the iCOM FD3812 Double
; Density Disk Controller (IBM System 34 compatible). Note
; also, that this utility is unique to Lifeboat Associates
; implementation of CP/M Version 1.4, and as such may not
; display Group Allocations or Sector Interlace properly for
; other implementations of CP/M 1.4 on double density
; diskette.
;
;
; Operation
;
; The program may be executed either by type 3812DUMP<cr>,
; or 3812DUMP followed by a or track number and sector
; number, or group allocation vector number, or group
; allocation "map", followed by carriage return.
;
; If 3812DUMP alone is typed, the program will display the
; sign-on message, and then prompt for keyboard input with a
; "*" character. Operation in this mode is similar to the
; Digital Research utilities PIP, DDT, or SID except that you
; will be operating directly on disk data rather than memory
; data. After the "*" prompt, you may select one of the
; following operations:
;
;
;
; 1.0 To dump selected tracks and sectors;
;
; *TRACK 3 SECTOR 7<cr>
; *TRACK 5 SECTOR 3-9<cr>
; *TRACK 6<cr> (Dump all 52 sectors of track 6)
; *TRACK 0<cr> (Dump all 26 sectors of track 0)
;
; 2.0 To dump the group allocations by track and sector;
;
; *GROUP 0<cr> (Dump the group allocation for the directory)
;
; 3.0 To dump the group alloaction "bit" map
;
; *MAP<cr>
;
; 4.0 To verify (read all tracks, all sectors for errors)
;
; *VERIFY<cr>
;
;
; Note, that the words VERIFY, MAP, GROUP, TRACK, and SECTOR
; may be abreviated as shown in the following examples:
;
; *G 4<cr>
;
; or,
;
; *T 7 S 3-4<cr>
;
; or,
;
; *S 2-9 T 14<cr>
;
; or,
;
; *M<cr>
;
; or,
;
; *V<cr>
;
;
; Also, the format is quite free. Spaces are usually ignored,
; and ae only required after the words TRACK and SECTOR (or T
; and S). In addition, all the commands may be specified at
; the CP/M command level after the disk "A>" or "B>" etc.,
; prompt as shown in the following example:
;
; A>3812DUMP T 0 S 26<cr>
;
;
; A limited disk editing feature is also included to allow
; "hot patching" of the selected diskette. Any single sector
; on a diskette may be modified (edited), by requesting a dump
; of the track and sector followed by the word EDIT. For
; example:
;
; A>3812DUMP T 1 S 3 EDIT<cr>
;
; The requested sector on the specified track will be
; displayed, followed by the edit prompt "Edit -". Enter the
; "address" of the byte within that sector to be modified, and
; the program will respond by typing back the "address"
; entered and the present content of that address. To change
; the contents of that address, enter a two digit hexadecimal
; value followed by a carriage return. The program will then
; display the next sequential address and its content. To stop
; enetering data, type a "." followed by carriage return, and
; the program will redisplay the the sector showing the
; modifications. Note also, that typeing only a carriage
; return omits any modification of the currently displayed
; address, and merely advances to the next address. At this
; point, you have not actually modified the sector on the
; diskette, only the "memory image"...when editing is
; completed, you may write the "memory image" back to the
; sector by typeing WRITE<cr>. Additionally, you can stop the
; editing of the sector by typeing STOP<cr>, and terminate
; without writing the diskette.
;
; All edit entries must be made in hexadecimal (entering non-
; hexadecimal characters will result in an error message),
; with the permissable range of 0000 to 007F (larger address's
; will give an error message). Note, that for the Lifeboat
; Associates implementation of CP/M Version 1.4, that track 00
; is 26 sectors of 128 bytes each, and all other tracks will
; be 52 sectors of 128 bytes (in reality 26 sectors of 256
; bytes).
;
; An additional feature of the program, is the ability to
; VERIFY (read all tracks and sectors for errors) a diskette
; as shown in the following example:
;
; A>3812DUMP B:VERIFY<cr>
;
; or,
;
; A>3812DUMP V<cr>
;
; or,
;
; *V<cr>
;
;
; Finally, as with other CP/M utiliies, the display may be
; started and stopped while scrolling with Control-S (as a
; "toggle"), and Control-C will return you to the "*" prompt
; (if already at the "*" prompt, you will return to CP/M).
;
;
; Notes
;
; The program must be assembled with Digital Research's
; macro-assembler MAC, and a macro library file DDMACRO.LIB.
;
; This program is PUBLIC DOMAIN, and as such is for
; distribution to all users whether public or private.
;
;
; Best regards,
;
; Kelly Smith, CP/M-NET (tm)
; 805-527-9321 (Modem, 300 Baud)
; 805-527-0518 (Verbal)
;
;
;
;
$+PRINT
MACLIB DDMACRO ;INCLUDE DOUBLE DENSITY MACRO LIBRARY
ORG 100H ;SET PROG START
LXI H,0
DAD SP ;GET STACK POINTER
SHLD OLDSTK
LXI SP,NEWSTK ;SET UP NEW STACK
DISKIO ?DRIVE ;GET CURRENTLY LOGGED DRIVE NO
STA NEWDRV ;ALSO SAVE IN NEW DRIVE NO
LDA 81H ;CONSOLE INPUT ALREADY HERE ?
ORA A
JZ SIGNON ;BUFFER EMPTY, INPUT FROM CONSOLE
LDA 80H ;GET NO OF CHAR INPUT
ORI 80H ;ADD 128
MOV L,A ;TO L
XRA A ;ZERO
MOV H,A ;HL CONTAINS ADDR OF END OF BUFFER
ZBFF: INR L
JZ START ;REMAINDER OF BUFFER ZEROED
MOV M,A
JMP ZBFF ;LOOP
SIGNON: PRINT <CR,LF,'Disk Dump Utility for iCom FD3812, Ver.1.0',CR,LF>
NEWIN: PRINT <CR,LF,'*'>
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
INPUT 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
JZ ADISK
MATCH 82H,'B:' ;DRIVE B
JZ 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,40H ;SHIFT BUFFER DOWN TWO BYTES
;
; SEARCH FOR DIRECT READ OF TRACK AND SECTOR OR VALIDATE
;
GETNAM: INSTR 82H,40H,'VERIFY'
JC VERIFY ;VERIFY DISK
INSTR 82H,40H,'V'
JC VERIFY ;VERIFY DISK
INSTR 82H,40H,'GROUP'
JC GROUP ;DISPLAY CPM 8 SECTOR GROUP
INSTR 82H,40H,'G ' ;SEARCH FOR 'G'
JC GROUP ;DISPLAY GROUP
INSTR 82H,40H,'MAP' ;ALLOCATION MAP
JC MAP ;DISPLAY GROUP ALLOCATION MAP
INSTR 82H,40H,'M' ;ALLOCATION MAP
JC MAP ;DISPLAY GROUP ALLOCATION MAP
INSTR 82H,40H,'TRACK' ;SEARCH FOR TRACK
JC TRK1
INSTR 82H,40H,'T ' ;SEARCH FOR 'T'
JNC FILNAM ;NO TRACK GO TO READ FILE
TRK1: SCAN ;FIND AND CONVERT NUMBER
DECIN
JC INERR ;INPUT ERROR ON CARRY
STA TRACK ;SAVE TRACK NO
INSTR 82H,40H,'SECTOR' ;SEARCH FOR SECTOR
JC SEC1
INSTR 82H,40H,'S ' ;TRY 'S'
JNC WHLTRK ;DUMP ENTIRE TRACK
SEC1: SCAN
DECIN
JC INERR ;INPUT ERROR ON CARRY
STA BSEC ;BEGINNING SECTOR
STA ESEC ;SAVE IN END SECTOR ALSO
XCHG ;SET BUFFER POINTER FOR SCAN
SHLD IPOINT ;SAVE BUFFER POINTER FOR EDIT
INSTR ,40H,'-' ;SEARCH FOR '-'
JNC EDIT ;CHECK FOR EDITION OF SECTOR
SCAN
DECIN ;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
EDIT: LHLD IPOINT ;RESET BUFFER POINTER
INSTR ,40H,'EDIT' ;CHECK EDIT FUNCTION
JNC DOREAD ;GO TO DISPLAY SECTOR
CALL RDISK0 ;DISPLAY SECTOR
EDIT1: PRINT <CR,LF,'Edit - '>
FILL INBUF,INBUF+9
INPUT INBUF,6 ;INPUT MAXIMUM 6 CHAR
INSTR INBUF,8,'WRITE' ;WRITE EDITED SECTOR ON DISK?
JC WRTDSK ;WRITE BUFFER BACK ON DISK
INSTR INBUF,8,'STOP' ;STOP EDITING WITHOUT WRITING?
JC ENDFIL ;EXIT
HEXIN INBUF+2 ;CONV ASCII TO HEX
JNC CKLIM ;IF NO ERROR, CHECK ADDR
LDAX D ;GET ASCII CHAR
CPI '.' ;CHECK FOR EXIT CHAR
JZ EDIT3 ;BACK FOR MORE EDITING
JMP ADERR ;ADDRESS ERROR
CKLIM: LXI D,0080H ;CHECK ADDR LIMIT
CPHL
JP ADERR ;ADDRESS ERROR
SHLD IPOINT ;SAVE ADDRESS
PRINT CRLF,$
PTX: HEXOUT IPOINT+1
HEXOUT IPOINT ;ECHO THE ADDRESS
PRINT SPACE,$
LHLD IPOINT ;ECHO PRESENT CONTENTS
LXI D,0080H
DAD D ;COMPUTE MEMORY ADDR
MOV A,M ;GET BYTE FROM MEMORY
HEXOUT
PRINT SPACE,$
FILL INBUF,INBUF+5 ;ZERO INPUT BUFFER
INPUT INBUF,4 ;INPUT 4 CHAR MAX
HEXIN INBUF+2 ;CONVERT
JNC EDIT2 ;HEX CHAR
LDAX D ;GET ASCII CHAR
CPI '.' ;PERIOD ENDS INPUT
JZ EDIT3 ;BACK FOR MORE EDITING
JMP HEXERR ;ERROR NOT HEX CHAR
EDIT2: LDA INBUF+1 ;LOAD NO OF CHAR TYPED
ORA A
JZ EDITX ;NO REPLACEMENT IF JUST CR
MOV A,L ;CONVERTED CHAR BACK TO A
LHLD IPOINT ;LOAD MEMORY BUFFER POINTER
LXI D,0080H ;OFFSET
DAD D ;CALC MEMORY ADDR
MOV M,A ;STORE NEW INPUT TO MEMORY
EDITX: PRINT CRLF,$
LDA IPOINT ;LEAST SIGNIFICANT HALF OF ADDR
INR A ;INCR BY ONE
ANI 7FH ;COUNT MOD 128
STA IPOINT
JMP PTX ;INPUT MORE DATA
EDIT3: LXI H,0
SHLD LINE ;RESET LINE NO TO ZERO
CALL PRTSEC ;PRINT BUFFER WITH HEADING
JMP EDIT1 ;BACK FOR ADDITIONAL EDITING
WRTDSK: CALLBIOS DWRITE ;WRITE BUFFER BACK ON DISK
JMP ENDFIL ;EXIT
;
; 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
LDA NEWDRV
MOV E,A
DISKIO LOGIN ;SELECT NEW DEIVE IF SPECIFIED
CALLBIOS DREAD ;READ TRACK AND SECTOR
;
; PRINT DRIVE, TRACK AND SECTOR HEADING
;
PRTSEC: LDA NEWDRV ;NEW DRIVE NO
ORA A
JNZ PRNB ;PRINT DRIVE B
PRINT <CR,LF,' Drive A -'>
PRNTRK: PRINT ' Track '
LXI H,0
LDA TRACK
MOV L,A
DECOUT
PRINT ' 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
PRNB: PRINT <CR,LF,' Drive B -'>
JMP PRNTRK ;PRINT TRACK AND SECTOR
;
; DUMP ENTIRE TRACK IF NO SECTOR INPUT
;
WHLTRK: MVI A,1 ;BEGIN SECTOR
STA BSEC
LDA TRACK ;GET TRACK NUMBER
ORA A
JNZ ESEC52 ;IF NOT TRACK 00, DO 52 SECTORS
MVI A,26 ;IT'S TRACK 00, DO 26 SECTORS
JMP ESECEND
ESEC52: MVI A,52 ;NOT TRACK 00, DO 52 SECTORS
ESECEND:STA ESEC
CALL RDISK0 ;TO READ DISK
JMP ENDFIL ;BACK FOR MORE INPUT
;
; FILL IN FCB FOR NAMED FILE
;
FILNAM: FILFCB FCB,82H ;FILL IN FCB NAME FROM INPUT BUFFER
JC NAMERR ;ERROR IN FILE NAME
MATCH FCB+9,'COM' ;TEST FOR COM FILE
JNZ SELDR
LXI H,100H
SHLD LINE ;SET LINE NO. TO 100
SELDR: LDA NEWDRV ;SELECT NEW DRIVE
MOV E,A
DISKIO LOGIN
DISKIO OPEN,FCB ;0PEN FILE
CPI 255 ;CHECK FILE PRESENT
JZ OPNERR ;EXIT IF ERROR
RDFILE: DISKIO READ,FCB ;READ A BLOCK
ORA A ;ZERO INDICATES SUCESSFUL READ
JNZ ENDFIL ;1 INDICATES EOF
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
SAVE B,H
HEXOUT
LDA LINE ;SECOND TWO DIGITS
HEXOUT
PRINT ' '
RESTORE H,B
PLOOP: MOV A,M ;GET A BYTE
SAVE B,H
HEXOUT
PRINT SPACE,$
RESTORE H,B
INX H ;INCR MEMORY POINTER
MOV A,C
CPI 9 ;CHECK 8 CHAR
JNZ DECC ;SKIP IF NOT
SAVE B,H
PRINT SPACE,$
RESTORE H,B
DECC: DCR C ;DECR CHAR COUNT
JNZ PLOOP ;PRINT SOME MORE
SAVE B
PRINT SPACE,$
RESTORE B
LHLD IPOINT ;RESET POINTER FOR ASCII
MVI C,10H ;RESET CHAR COUNT
PLOOP1: MOV A,M ;GET A BYTE
ANI 7FH ;MASK OFF HIGH BIT
CPI 7FH ;DELETE CODE
JZ PERIOD ;PRINT PERIOD FOR DELETE
CPI 20H ;TEST FOR CONTROL CHAR
JP SKIPX ;SKIP SUBSTITUTION
PERIOD: MVI A,2EH ;ASCII PERIOD
SKIPX: SAVE B,H
CHAROUT ;PRINT IT SAVE REGS
RESTORE H,B
INX H ;INCR MEMORY POINTER
MOV A,C
CPI 9 ;CHECK 8 CHAR
JNZ DECC2
SAVE B,H
PRINT SPACE,$
RESTORE H,B
DECC2: DCR C ;DECR CHAR COUNT
JNZ PLOOP1 ;PRINT SOME MORE
SAVE B
PRINT CRLF,$ ;CARRIAGE RETURN
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 SECTIONS VERIFIES A DISK FOR BAD SECTORS
;
VERIFY: MVI A,1 ;START WITH SECTOR 1
STA SNUM
XRA A ;START WITH TRACK 0
STA TNUM
LDA NEWDRV ;SELECT NEW DRIVE
MOV E,A
DISKIO LOGIN
RS0: SETTRK TNUM
JC BADTRK
RS1: SETSEC SNUM
JC BADSEC
CALLBIOS 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
PUSH PSW ;SAVE BIASED SECTOR NUMBER
LDA TRACK ;GET TRACK NUMBER
ORA A
JNZ RS2 ;IF NOT TRACK 00, MAKE MOD 52
POP PSW
SBI 27 ;IT'S TRACK 00, MAKE MOD 26
JMP RS3
RS2: POP PSW ;GET BIASED SECTOR NUMBER
SBI 53 ;CALC SECTOR MOD 52
RS3: JM RS1 ;SECTOR OK IF MINUS
INR A ;SECTOR MOD 26 OR 52
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 <CR,LF,'Succesfully Verified'>
LDA NEWDRV
ORA A
JNZ VAL2
PRINT ' Drive A'
JMP ENDFIL
VAL2: PRINT ' Drive B'
JMP ENDFIL
VALERR: PRINT <CR,LF,'Error, Track '>
LDA TNUM
LXI H,0
MOV L,A
DECOUT
PRINT ' 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
CHARIN ;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: SCAN ;GET THE GROUP NO
DECIN ;CONVERT TO BINARY
JC INERR ;INPUT ERROR IF CARRY SET
STA G ;SAVE GROUP NO
ADI 13 ;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 S ;CHECK SECTOR COUNT
INR A
STA S ;INCR S BY 1
CPI 16 ;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
DAD H ;SHIFT LEFT 4
LDA S ;GET SECTOR NO
MOV E,A ;TO DE
DAD D ;HL HAS G*16+S
LDA TRACK ;GET TRACK NUMBER, DO SECTOR NUMBER AS REQUIRED
ORA A
LXI D,-26 ;26 SECTORS, DIVISOR
JZ SDGRP ;IF TRACK 00, DO SINGLE DENSITY GROUP
LXI D,-52 ;52 SECTORS, DIVISOR
SDGRP: MVI A,1 ;CONTAINS DIVIDEND
DIV: DAD D ;SUB 52
INR A
JC DIV ;LOOP TILL MINUS
PUSH PSW ;SAVE TRACK NUMBER
LDA TRACK ;GET TRACK NUMBER, INDEX AS REQUIRED
ORA A
LXI D,SDTABLE+26 ;INDEX INTO SINGLE DENSITY TABLE
JZ SDDIV
LXI D,DDTABLE+52 ;INDEX INTO DOUBLE DENSITY TABLE
SDDIV: POP PSW ;RECOVER TRACK NUMBER
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
$+PRINT
;
; THIS ROUTINE DISPLAYS THE DISK SECTOR ALLOCATION MAP
;
MAP: LDA NEWDRV
MOV E,A
DISKIO LOGIN ;LOG IN SELECTED DRIVE
DISKIO ?ALLOC ;GET POINTER TO ALLOCATION MAP
MOV H,B
MOV L,A ;TO HL
SHLD IPOINT ;SAVE MAP POINTER
LXI H,0 ;ZERO HL
SHLD G ;ZERO COUNT OF UNUSED GROUPS
PRINT <CR,LF,LF,' Group Allocation Map, Drive -'>
LDA NEWDRV ;LOGGED DRIVE
ORA A
JNZ DRB ;DRIVE B
PRINT <' A',CR,LF,LF>
JMP MAP1
DRB: PRINT <' B',CR,LF,LF>
MAP1: LHLD IPOINT ;POINTER TO DISK ALLOCATION MAP
MVI D,8 ;NO OF LINES
MAP2: MVI C,4 ;WORDS PER LINE
MAPX: SAVE
PRINT ' '
RESTORE
MAP3: MVI B,8 ;BITS PER WORD
MOV A,M ;GET A BYTE FROM ALLOC MAP
MAP4: RAL ;SHIFT LEFT THRU CARRY
SAVE B,D,H,PSW
JC MAP5 ;PRINT A ONE
PRINT '0' ;PRINT A ZERO
LDA G ;UNUSED GROUPS
INR A ;ADD 1
STA G ;STORE IT BACK
JMP MAP6
MAP5: PRINT '1' ;PRINT A ONE
MAP6: RESTORE PSW,H,D,B
SAVE PSW ;SAVE BIT MAP BYTE
MOV A,B ;BIT COUNT
CPI 7
JNZ MAPY
MOV A,C ;WORD COUNT
CPI 2
JNZ MAPY
MOV A,D ;LINE COUNT
CPI 1
JNZ MAPY
RESTORE PSW
JMP MAP7 ;TO PRINT UNUSED GROUPS
MAPY: RESTORE PSW
DCR B ;DCR BIT COUNT
JNZ MAP4 ;PRINT MORE BITS
DCR C ;DECR WORD COUNT
INX H ;INCR ALLOC MAP POINTER
JNZ MAP3
SAVE
PRINT CRLF,$
RESTORE
DCR D ;DECR LINE COUNT
JMP MAP2
MAP7: PRINT <CR,LF,LF,' '>
DECOUT G ;PRINT NO OF UNUSED SECTORS
PRINT <' Groups remaining on disk, out of 486',CR,LF>
JMP ENDFIL ;EXIT
;
;
; THIS ROUTINE RESTORES DRIVE B
;
FIXB: LDA NEWDRV ;CHECK DRIVE NO
ORA A
RZ ;RETURN IF DRIVE A
LDA NEWDRV ;SELECT DRIVE B
MOV E,A
DISKIO LOGIN
XRA A
STA TNUM ;SELECT TRACK ZERO
INR A ;SELECT SECTOR 1
STA SNUM
SETSEC SNUM
SETTRK TNUM
CALLBIOS DHOME ;HOME DRIVES
CALLBIOS DREAD ;READ TRACK ZERO DIRECT
RET
;
; ERROR AND EXIT ROUTINES
;
;
INERR: PRINT <CR,LF,'Input Error'>
JMP ENDFIL
;
BADSEC: PRINT <CR,LF,'Incorrect Sector Number'>
JMP ENDFIL
;
BADTRK: PRINT <CR,LF,'Incorrect Track Number'>
JMP ENDFIL
;
BADGRP: PRINT <CR,LF,'Incorrect Group Number, greater than 485'>
JMP ENDFIL
;
OPNERR: LDA NEWDRV ;CURRENT DRIVE NO
ORA A
JNZ OPNER1
PRINT <CR,LF,'No file by that name on Drive A'>
JMP ENDFIL
OPNER1: PRINT <CR,LF,'No file by that name on Drive B'>
JMP ENDFIL
;
RDERR: PRINT <CR,LF,'Disk Read Error'>
JMP MONITOR
NAMERR: PRINT <CR,LF,'Error in File Name'>
JMP ENDFIL
;
ADERR: PRINT <CR,LF,LF,'Address Error'>
JMP EDIT1 ;ADDRESS ERROR ON EDIT
;
HEXERR: PRINT <CR,LF,' Error, enter Hexadecimal Values Only',CR,LF>
JMP PTX
;
MONITOR: PRINT CRLF,$
LDA DRVNO ;RESTORE LOGGED DRIVE NO
MOV E,A
DISKIO LOGIN
LHLD OLDSTK
SPHL ;RESET OLD STACK POINTER
RET
;
;
; DATA ALLOCATIONS
;
FCB EQU 5CH ;FILE CONTROL BLOCK
SPACE: DB ' $' ;ASCII SPACE
CRLF: DB 0DH,0AH,24H ;ASCII CR LF
I: DW 0 ;PSEUDO INDEX REGISTER
LINE: DW 0 ;LINE NUMBER FOR LISTING
IPOINT: DW 00 ;VARIABLE BUFFER POINTER
INBUF: DS 10 ;USED AS CONSOLE INPUT BUFFER
LASTIN: DB 0 ;LAST CONSOLE INPUT CHAR
INFLAG: DB 0 ;FLAG, RET FOR MORE CONSOLE INPUT
DRVNO: DB 0 ;STORAGE FOR ORIGINALLY LOGGED DRIVE
NEWDRV: DB 0 ;STORAGE FOR NEW DRIVE NO
TRACK: DB 0 ;SELECTED TRACK
BSEC: DB 0 ;SELECTED BEGINNING SECTOR
ESEC: DB 0 ;SELECTED ENDING SECTOR
TNUM: DB 0 ;TRACK NO FOR VALIDATE
SNUM: DB 0 ;SECTOR NO FOR VALIDATE
VALFLG: DB 0 ;VALIDATION ERROR FLAG
G: DB 0 ;CPM GROUP NO
S: DB 0 ;SECTOR NO WITHIN GROUP G
COUNT: DB 0 ;COUNT OF DIRECTORY ENTRIES
OLDSTK: DW 0 ;STORAGE FOR OLD STACK POINTER
ENDSTK: DS 24 ;STORAGE FOR NEW STACK
NEWSTK: DW 0 ;NEW STACK
INB: DW 0 ;STORES POINTER TO INPUT BUFFER AREA
OUTB: DW 0 ;STORES POINTER TO DIRECTORY BUFFER AREA
SDTABLE:DB 01 ;DOUBLE DENSITY SECTOR LOOK UP TABLE
DB 07
DB 13
DB 19
DB 25
DB 05
DB 11
DB 17
DB 23
DB 03
DB 09
DB 15
DB 21
DB 02
DB 08
DB 14
DB 20
DB 26
DB 06
DB 12
DB 18
DB 24
DB 04
DB 10
DB 16
DB 22
DDTABLE:DB 01 ;DOUBLE DENSITY SECTOR LOOK UP TABLE
DB 02
DB 19
DB 20
DB 37
DB 38
DB 03
DB 04
DB 21
DB 22
DB 39
DB 40
DB 05
DB 06
DB 23
DB 24
DB 41
DB 42
DB 07
DB 08
DB 25
DB 26
DB 43
DB 44
DB 09
DB 10
DB 27
DB 28
DB 45
DB 46
DB 11
DB 12
DB 29
DB 30
DB 47
DB 48
DB 13
DB 14
DB 31
DB 32
DB 49
DB 50
DB 15
DB 16
DB 33
DB 34
DB 51
DB 52
DB 17
DB 18
DB 35
DB 36
PDIR DW 0 ;POINTER TABLE TO DIRECTORY (64 ENTRIES MAX)
DIRBUF: EQU PDIR+130 ;START OF AREA USED TO STORE AND SORT DIRECTORY
END