home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol018 / 3812dump.asm < prev    next >
Assembly Source File  |  1984-04-29  |  21KB  |  833 lines

  1. ;                     3812DUMP.ASM  Ver.1.0
  2. ;                             as of
  3. ;                        August 25, 1980
  4. ;  This  program is a disk dump and edit  utility,  originally 
  5. ; written  by S.  J.  Singer for CP/M 1.4 single density  (IBM 
  6. ; 3741 compatible) diskettes (ref.  CP/M User's Group,  Volume 
  7. ; 24.1),  and  modified for usage with the iCOM FD3812  Double 
  8. ; Density  Disk Controller (IBM System  34  compatible).  Note 
  9. ; also,  that  this  utility is unique to Lifeboat  Associates 
  10. ; implementation  of  CP/M Version 1.4,  and as such  may  not 
  11. ; display  Group Allocations or Sector Interlace properly  for 
  12. ; other   implementations  of  CP/M  1.4  on  double   density 
  13. ; diskette.
  14. ;                         Operation
  15. ;   The program  may  be executed either by type 3812DUMP<cr>, 
  16. ; or  3812DUMP  followed  by  a  or  track  number  and sector 
  17. ; number,  or  group  allocation  vector  number,   or   group 
  18. ; allocation "map", followed by carriage return.
  19. ;  
  20. ;  If  3812DUMP alone is typed,  the program will display  the 
  21. ; sign-on  message,  and then prompt for keyboard input with a 
  22. ; "*"  character.  Operation  in this mode is similar  to  the 
  23. ; Digital Research utilities PIP,  DDT, or SID except that you 
  24. ; will  be operating directly on disk data rather than  memory 
  25. ; data.  After  the  "*" prompt,  you may select  one  of  the 
  26. ; following operations:
  27. ; 1.0 To dump selected tracks and sectors;
  28. ;      *TRACK 3 SECTOR 7<cr>
  29. ;      *TRACK 5 SECTOR 3-9<cr>
  30. ;      *TRACK 6<cr> (Dump all 52 sectors of track 6)
  31. ;      *TRACK 0<cr> (Dump all 26 sectors of track 0)
  32. ; 2.0 To dump the group allocations by track and sector;
  33. ;      *GROUP 0<cr> (Dump the group allocation for the directory)
  34. ; 3.0 To dump the group alloaction "bit" map
  35. ;      *MAP<cr>
  36. ; 4.0 To verify (read all tracks, all sectors for errors)
  37. ;      *VERIFY<cr>
  38. ;  Note,  that the words VERIFY, MAP, GROUP, TRACK, and SECTOR 
  39. ; may be abreviated as shown in the following examples:
  40. ;      *G 4<cr>
  41. ;      or,
  42. ;      *T 7 S 3-4<cr>
  43. ;      or,
  44. ;      *S 2-9 T 14<cr>
  45. ;      or,
  46. ;      *M<cr>
  47. ;      or,
  48. ;      *V<cr>
  49. ;  Also, the format is quite free. Spaces are usually ignored, 
  50. ; and  ae only required after the words TRACK and SECTOR (or T 
  51. ; and S).  In addition,  all the commands may be specified  at 
  52. ; the  CP/M  command level after the disk "A>" or  "B>"  etc., 
  53. ; prompt as shown in the following example:
  54. ;      A>3812DUMP T 0 S 26<cr>
  55. ;
  56. ;  A  limited  disk editing feature is also included to  allow 
  57. ; "hot patching" of the selected diskette.  Any single  sector 
  58. ; on a diskette may be modified (edited), by requesting a dump 
  59. ; of  the  track  and sector followed by the  word  EDIT.  For 
  60. ; example:
  61. ;      A>3812DUMP T 1 S 3 EDIT<cr>
  62. ;  The  requested  sector  on  the  specified  track  will  be 
  63. ; displayed,  followed by the edit prompt "Edit -".  Enter the 
  64. ; "address" of the byte within that sector to be modified, and 
  65. ; the  program  will  respond by  typing  back  the  "address" 
  66. ; entered  and the present content of that address.  To change 
  67. ; the contents of that address,  enter a two digit hexadecimal 
  68. ; value followed by a carriage return.  The program will  then 
  69. ; display the next sequential address and its content. To stop 
  70. ; enetering data,  type a "." followed by carriage return, and 
  71. ; the  program  will  redisplay  the the  sector  showing  the 
  72. ; modifications.  Note  also,  that  typeing only  a  carriage 
  73. ; return  omits  any modification of the  currently  displayed 
  74. ; address,  and merely advances to the next address.  At  this 
  75. ; point,  you  have  not actually modified the sector  on  the 
  76. ; diskette,   only   the  "memory  image"...when  editing   is 
  77. ; completed,  you  may  write the "memory image" back  to  the 
  78. ; sector by typeing WRITE<cr>.  Additionally, you can stop the 
  79. ; editing  of  the sector by typeing STOP<cr>,  and  terminate 
  80. ; without writing the diskette.
  81. ;  All edit entries must be made in hexadecimal (entering non-
  82. ; hexadecimal  characters  will result in an  error  message), 
  83. ; with the permissable range of 0000 to 007F (larger address's 
  84. ; will  give an error message).  Note,  that for the  Lifeboat 
  85. ; Associates implementation of CP/M Version 1.4, that track 00 
  86. ; is 26 sectors of 128 bytes each,  and all other tracks  will 
  87. ; be  52  sectors of 128 bytes (in reality 26 sectors  of  256 
  88. ; bytes).
  89. ;  An  additional  feature of the program,  is the ability  to 
  90. ; VERIFY  (read all tracks and sectors for errors) a  diskette 
  91. ; as shown in the following example:
  92. ;      A>3812DUMP B:VERIFY<cr>
  93. ;      or,
  94. ;      A>3812DUMP V<cr>
  95. ;      or,
  96. ;      *V<cr>
  97. ;  Finally,  as with other CP/M utiliies,  the display may  be 
  98. ; started  and  stopped while scrolling with Control-S  (as  a 
  99. ; "toggle"),  and  Control-C will return you to the "*" prompt 
  100. ; (if already at the "*" prompt, you will return to CP/M).
  101. ;                          Notes
  102. ;  The  program  must  be assembled  with  Digital  Research's 
  103. ; macro-assembler MAC, and a macro library file DDMACRO.LIB.
  104. ;  This  program  is  PUBLIC DOMAIN,   and  as  such  is  for 
  105. ; distribution to all users whether public or private.
  106. ;                               Best regards,
  107. ;                               
  108. ;                               Kelly Smith, CP/M-NET (tm)
  109. ;                               805-527-9321 (Modem, 300 Baud)
  110. ;                               805-527-0518 (Verbal)
  111. ;
  112. ;
  113. ;
  114. ;
  115. $+PRINT
  116.  
  117.     MACLIB    DDMACRO        ;INCLUDE DOUBLE DENSITY MACRO LIBRARY
  118.  
  119.     ORG    100H        ;SET PROG START
  120.  
  121.     LXI    H,0
  122.     DAD    SP        ;GET STACK POINTER
  123.     SHLD    OLDSTK
  124.     LXI    SP,NEWSTK    ;SET UP NEW STACK
  125.     DISKIO    ?DRIVE        ;GET CURRENTLY LOGGED DRIVE NO
  126.     STA    NEWDRV        ;ALSO SAVE IN NEW DRIVE NO
  127.     LDA    81H        ;CONSOLE INPUT ALREADY HERE ?
  128.     ORA    A
  129.     JZ    SIGNON        ;BUFFER EMPTY, INPUT FROM CONSOLE
  130.     LDA    80H        ;GET NO OF CHAR INPUT
  131.     ORI    80H        ;ADD 128
  132.     MOV    L,A        ;TO L
  133.     XRA    A        ;ZERO
  134.     MOV    H,A        ;HL CONTAINS ADDR OF END OF BUFFER
  135. ZBFF:    INR    L
  136.     JZ    START        ;REMAINDER OF BUFFER ZEROED
  137.     MOV    M,A
  138.     JMP    ZBFF        ;LOOP
  139. SIGNON:    PRINT    <CR,LF,'Disk Dump Utility for iCom FD3812, Ver.1.0',CR,LF>
  140. NEWIN:    PRINT    <CR,LF,'*'>
  141.     MVI    A,0FFH        ;SET SWITCH TO RETURN HERE AGAIN
  142.     STA    INFLAG
  143.     LXI    SP,NEWSTK    ;RESET STACK POINTER
  144.     XRA    A
  145.     STA    VALFLG        ;RESET VALIDATION ERROR FLAG
  146.     LXI    H,0
  147.     SHLD    LINE        ;SET LINE COUNT TO ZERO
  148.     FILL    80H,0FFH    ;ZERO INPUT BUFFER
  149.     INPUT    80H        ;READ FILE NAME
  150. ;
  151. ;  SELECT DISK DRIVE AND SET UP FILE CONTROL BLOCK
  152. ;
  153. START:    FILL    FCB,FCB+32    ;ZERO FILE CONTROL BLOCK
  154.     MATCH    82H,'A:'    ;DRIVE A
  155.     JZ    ADISK
  156.     MATCH    82H,'B:'    ;DRIVE B
  157.     JZ    BDISK
  158.     JMP    GETNAM        ;NO DRIVE SPECIFIED
  159. ADISK:    XRA    A
  160.     STA    NEWDRV        ;SELECT DRIVE A
  161.     JMP    DOWN
  162. BDISK:    MVI    A,1
  163.     STA    NEWDRV        ;SELECT DRIVE B
  164. DOWN:    MOVE    82H,80H,40H    ;SHIFT BUFFER DOWN TWO BYTES
  165. ;
  166. ;  SEARCH FOR DIRECT READ OF TRACK AND SECTOR OR VALIDATE
  167. ;
  168. GETNAM:    INSTR    82H,40H,'VERIFY'
  169.     JC    VERIFY        ;VERIFY DISK
  170.     INSTR    82H,40H,'V'
  171.     JC    VERIFY        ;VERIFY DISK
  172.     INSTR    82H,40H,'GROUP'
  173.     JC    GROUP        ;DISPLAY CPM 8 SECTOR GROUP
  174.     INSTR    82H,40H,'G '    ;SEARCH FOR 'G'
  175.     JC    GROUP        ;DISPLAY GROUP
  176.     INSTR    82H,40H,'MAP'    ;ALLOCATION MAP
  177.     JC    MAP        ;DISPLAY GROUP ALLOCATION MAP
  178.     INSTR    82H,40H,'M'    ;ALLOCATION MAP
  179.     JC    MAP        ;DISPLAY GROUP ALLOCATION MAP
  180.     INSTR    82H,40H,'TRACK'    ;SEARCH FOR TRACK
  181.     JC    TRK1
  182.     INSTR    82H,40H,'T '    ;SEARCH FOR 'T'
  183.     JNC    FILNAM        ;NO TRACK GO TO READ FILE
  184. TRK1:    SCAN            ;FIND AND CONVERT NUMBER
  185.     DECIN
  186.     JC    INERR        ;INPUT ERROR ON CARRY
  187.     STA    TRACK        ;SAVE TRACK NO
  188.     INSTR    82H,40H,'SECTOR'    ;SEARCH FOR SECTOR
  189.     JC    SEC1
  190.     INSTR    82H,40H,'S '    ;TRY 'S'
  191.     JNC    WHLTRK        ;DUMP ENTIRE TRACK
  192. SEC1:    SCAN    
  193.     DECIN
  194.     JC    INERR        ;INPUT ERROR ON CARRY
  195.     STA    BSEC        ;BEGINNING SECTOR
  196.     STA    ESEC        ;SAVE IN END SECTOR ALSO
  197.     XCHG            ;SET BUFFER POINTER FOR SCAN
  198.     SHLD    IPOINT        ;SAVE BUFFER POINTER FOR EDIT
  199.     INSTR    ,40H,'-'    ;SEARCH FOR '-'
  200.     JNC    EDIT        ;CHECK FOR EDITION OF SECTOR
  201.     SCAN
  202.     DECIN            ;SCAN AND CONVERT ANOTHER NO
  203.     JC    INERR        ;ERROR IF CARRY SET
  204.     STA    ESEC        ;SAVE IN END SECTOR
  205.     LXI    H,BSEC        ;POINTS TO BSEC
  206.     CMP    M        ;COMPARE BEGIN AND END
  207.     JP    DOREAD        ;OK IF END>=BEGIN
  208.     MOV    B,A        ;OTHERWISE
  209.     MOV    A,M        ;SWITCH THEM
  210.     STA    ESEC
  211.     MOV    M,B
  212. DOREAD:    CALL    RDISK0        ;READ DIRECT
  213.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  214. EDIT:    LHLD    IPOINT        ;RESET BUFFER POINTER
  215.     INSTR    ,40H,'EDIT'    ;CHECK EDIT FUNCTION
  216.     JNC    DOREAD        ;GO TO DISPLAY SECTOR
  217.     CALL    RDISK0        ;DISPLAY SECTOR
  218. EDIT1:    PRINT    <CR,LF,'Edit - '>
  219.     FILL    INBUF,INBUF+9
  220.     INPUT    INBUF,6        ;INPUT MAXIMUM 6 CHAR
  221.     INSTR    INBUF,8,'WRITE'    ;WRITE EDITED SECTOR ON DISK?
  222.     JC    WRTDSK        ;WRITE BUFFER BACK ON DISK
  223.     INSTR    INBUF,8,'STOP'    ;STOP EDITING WITHOUT WRITING?
  224.     JC    ENDFIL        ;EXIT
  225.     HEXIN    INBUF+2        ;CONV ASCII TO HEX
  226.     JNC    CKLIM        ;IF NO ERROR, CHECK ADDR
  227.     LDAX    D        ;GET ASCII CHAR
  228.     CPI    '.'        ;CHECK FOR EXIT CHAR
  229.     JZ    EDIT3        ;BACK FOR MORE EDITING
  230.     JMP    ADERR        ;ADDRESS ERROR
  231. CKLIM:    LXI    D,0080H        ;CHECK ADDR LIMIT
  232.     CPHL
  233.     JP    ADERR        ;ADDRESS ERROR
  234.     SHLD    IPOINT        ;SAVE ADDRESS
  235.     PRINT    CRLF,$
  236. PTX:    HEXOUT    IPOINT+1
  237.     HEXOUT    IPOINT        ;ECHO THE ADDRESS
  238.     PRINT    SPACE,$
  239.     LHLD    IPOINT        ;ECHO PRESENT CONTENTS
  240.     LXI    D,0080H
  241.     DAD    D        ;COMPUTE MEMORY ADDR
  242.     MOV    A,M        ;GET BYTE FROM MEMORY
  243.     HEXOUT
  244.     PRINT    SPACE,$
  245.     FILL    INBUF,INBUF+5    ;ZERO INPUT BUFFER
  246.     INPUT    INBUF,4        ;INPUT 4 CHAR MAX
  247.     HEXIN    INBUF+2        ;CONVERT
  248.     JNC    EDIT2        ;HEX CHAR
  249.     LDAX    D        ;GET ASCII CHAR
  250.     CPI    '.'        ;PERIOD ENDS INPUT
  251.     JZ    EDIT3        ;BACK FOR MORE EDITING
  252.     JMP    HEXERR        ;ERROR NOT HEX CHAR
  253. EDIT2:    LDA    INBUF+1        ;LOAD NO OF CHAR TYPED
  254.     ORA    A
  255.     JZ    EDITX        ;NO REPLACEMENT IF JUST CR
  256.     MOV    A,L        ;CONVERTED CHAR BACK TO A
  257.     LHLD    IPOINT        ;LOAD MEMORY BUFFER POINTER
  258.     LXI    D,0080H        ;OFFSET
  259.     DAD    D        ;CALC MEMORY ADDR
  260.     MOV    M,A        ;STORE NEW INPUT TO MEMORY
  261. EDITX:    PRINT    CRLF,$
  262.     LDA    IPOINT        ;LEAST SIGNIFICANT HALF OF ADDR
  263.     INR    A        ;INCR BY ONE
  264.     ANI    7FH        ;COUNT MOD 128
  265.     STA    IPOINT
  266.     JMP    PTX        ;INPUT MORE DATA
  267. EDIT3:    LXI    H,0
  268.     SHLD    LINE        ;RESET LINE NO TO ZERO
  269.     CALL    PRTSEC        ;PRINT BUFFER WITH HEADING
  270.     JMP    EDIT1        ;BACK FOR ADDITIONAL EDITING
  271. WRTDSK:    CALLBIOS DWRITE        ;WRITE BUFFER BACK ON DISK
  272.     JMP ENDFIL        ;EXIT
  273. ;
  274. ;  READ TRACK AND SECTOR DIRECT
  275. ;
  276. RDISK0:    CALL    FIXB
  277. RDISK:    SETSEC    BSEC        ;SET SECTOR
  278.     JC    BADSEC        ;WRONG SECTOR NO
  279. TRK2:    SETTRK    TRACK        ;SET TRACK
  280.     JC    BADTRK        ;WRONG TRACK NO
  281.     LDA    NEWDRV
  282.     MOV    E,A
  283.     DISKIO    LOGIN            ;SELECT NEW DEIVE IF SPECIFIED
  284.     CALLBIOS DREAD        ;READ TRACK AND SECTOR
  285. ;
  286. ;  PRINT DRIVE, TRACK AND SECTOR HEADING
  287. ;
  288. PRTSEC:    LDA    NEWDRV        ;NEW DRIVE NO
  289.     ORA    A
  290.     JNZ    PRNB        ;PRINT DRIVE B
  291.     PRINT    <CR,LF,'               Drive A -'>
  292. PRNTRK:    PRINT    ' Track '
  293.     LXI    H,0
  294.     LDA    TRACK
  295.     MOV    L,A
  296.     DECOUT
  297.     PRINT    '  Sector '
  298.     LXI    H,0
  299.     LDA    BSEC
  300.     MOV    L,A
  301.     DECOUT
  302.     PRINT    CRLF,$
  303.     CALL    PRTBUF        ;PRINT IT
  304.     LXI    H,BSEC        ;ADDR OF SECTOR NUMBER
  305.     LDA    ESEC        ;END SECTOR NUMBER
  306.     CMP    M        ;COMPARE THEM
  307.     RZ            ;EXIT IF THEY ARE EQUAL
  308.     INR    M        ;INCR BSEC
  309.     JMP    RDISK
  310. PRNB:    PRINT    <CR,LF,'               Drive B -'>
  311.     JMP    PRNTRK        ;PRINT TRACK AND SECTOR
  312. ;
  313. ;  DUMP ENTIRE TRACK IF NO SECTOR INPUT
  314. ;
  315. WHLTRK:    MVI    A,1        ;BEGIN SECTOR
  316.     STA    BSEC
  317.     LDA    TRACK        ;GET TRACK NUMBER
  318.     ORA    A
  319.     JNZ    ESEC52        ;IF NOT TRACK 00, DO 52 SECTORS
  320.     MVI    A,26        ;IT'S TRACK 00, DO 26 SECTORS
  321.     JMP    ESECEND
  322. ESEC52:    MVI    A,52        ;NOT TRACK 00, DO 52 SECTORS
  323. ESECEND:STA    ESEC
  324.     CALL    RDISK0        ;TO READ DISK
  325.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  326. ;
  327. ;  FILL IN FCB FOR NAMED FILE
  328. ;
  329. FILNAM:    FILFCB    FCB,82H    ;FILL IN FCB NAME FROM INPUT BUFFER
  330.     JC    NAMERR        ;ERROR IN FILE NAME
  331.     MATCH    FCB+9,'COM'    ;TEST FOR COM FILE
  332.     JNZ    SELDR
  333.     LXI    H,100H    
  334.     SHLD    LINE        ;SET LINE NO. TO 100
  335. SELDR:    LDA    NEWDRV        ;SELECT NEW DRIVE
  336.     MOV    E,A
  337.     DISKIO    LOGIN
  338.     DISKIO    OPEN,FCB    ;0PEN FILE
  339.     CPI    255        ;CHECK FILE PRESENT
  340.     JZ    OPNERR        ;EXIT IF ERROR
  341. RDFILE:    DISKIO    READ,FCB    ;READ A BLOCK
  342.     ORA    A        ;ZERO INDICATES SUCESSFUL READ
  343.     JNZ    ENDFIL        ;1 INDICATES EOF
  344.     CALL    PRTBUF        ;DO PRINT SUBROUTINE
  345.     JMP    RDFILE        ;BACK FOR NEXT BLOCK
  346. ENDFIL:    LDA    INFLAG        ;SEE WHERE TO GO
  347.     ORA    A
  348.     JZ    MONITOR
  349.     JMP    NEWIN
  350. ;
  351. ;
  352. ;  PRTBUF - PRINT BUFFER IN HEX AND ASCII
  353. ;
  354. PRTBUF:    MVI    B,8        ;8 LINES
  355.     LXI    H,80H        ;INITIAL BUFFER POINTER
  356.     SHLD    IPOINT        ;STORAGE FOR POINTER
  357. BPRN:    LHLD    IPOINT        ;LOAD POINTER
  358.     MVI    C,16        ;CHAR PER LINE
  359.     LDA    LINE+1        ;LINE NUMBER
  360.     SAVE    B,H
  361.     HEXOUT
  362.     LDA    LINE        ;SECOND TWO DIGITS
  363.     HEXOUT
  364.     PRINT    '  '
  365.     RESTORE    H,B
  366. PLOOP:    MOV    A,M        ;GET A BYTE
  367.     SAVE    B,H
  368.     HEXOUT
  369.     PRINT    SPACE,$
  370.     RESTORE    H,B
  371.     INX    H        ;INCR MEMORY POINTER
  372.     MOV    A,C
  373.     CPI    9        ;CHECK 8 CHAR
  374.     JNZ    DECC        ;SKIP IF NOT
  375.     SAVE    B,H
  376.     PRINT    SPACE,$
  377.     RESTORE    H,B
  378. DECC:    DCR    C        ;DECR CHAR COUNT
  379.     JNZ    PLOOP        ;PRINT SOME MORE
  380.     SAVE    B
  381.     PRINT    SPACE,$
  382.     RESTORE    B
  383.     LHLD    IPOINT        ;RESET POINTER FOR ASCII
  384.     MVI    C,10H        ;RESET CHAR COUNT
  385. PLOOP1:    MOV    A,M        ;GET A BYTE
  386.     ANI    7FH        ;MASK OFF HIGH BIT
  387.     CPI    7FH        ;DELETE CODE
  388.     JZ    PERIOD        ;PRINT PERIOD FOR DELETE
  389.     CPI    20H        ;TEST FOR CONTROL CHAR
  390.     JP    SKIPX        ;SKIP SUBSTITUTION
  391. PERIOD:    MVI    A,2EH        ;ASCII PERIOD
  392. SKIPX:    SAVE    B,H
  393.     CHAROUT            ;PRINT IT SAVE REGS
  394.     RESTORE    H,B
  395.     INX    H        ;INCR MEMORY POINTER
  396.     MOV    A,C
  397.     CPI    9        ;CHECK 8 CHAR
  398.     JNZ    DECC2
  399.     SAVE    B,H
  400.     PRINT    SPACE,$
  401.     RESTORE    H,B
  402. DECC2:    DCR    C        ;DECR CHAR COUNT
  403.     JNZ    PLOOP1        ;PRINT SOME MORE
  404.     SAVE    B
  405.     PRINT    CRLF,$        ;CARRIAGE RETURN
  406.     CALL    PRNCON        ;PRINT CONTROL?
  407.     POP    B
  408.     INDEX    LINE,16        ;INCR LINE NO BY 16
  409.     DCR    B        ;DECR    LINE COUNT
  410.     RZ            ;RETURN IF LINE COUNT ZERO
  411.     INDEX    IPOINT,16    ;INCR POINTER BY 16
  412.     JMP    BPRN        ;LOOP BACK
  413. ;
  414. ;    THIS SECTIONS VERIFIES A DISK FOR BAD SECTORS
  415. ;
  416. VERIFY:    MVI    A,1        ;START WITH SECTOR 1
  417.     STA    SNUM
  418.     XRA    A        ;START WITH TRACK 0
  419.     STA    TNUM
  420.     LDA    NEWDRV        ;SELECT NEW DRIVE
  421.     MOV    E,A
  422.     DISKIO    LOGIN
  423. RS0:    SETTRK    TNUM
  424.     JC    BADTRK
  425. RS1:    SETSEC    SNUM
  426.     JC    BADSEC
  427.     CALLBIOS DREAD
  428.     ORA    A
  429.     CNZ    VALERR        ;ERROR IF NOT ZERO
  430.     CALL    PRNCON        ;ESCAPE ON CONTROL C
  431.     LDA    SNUM        ;SECTOR NO
  432.     ADI    5        ;INCR BY 5
  433.     STA    SNUM        ;STORE IT BACK
  434.     PUSH    PSW        ;SAVE BIASED SECTOR NUMBER
  435.     LDA    TRACK        ;GET TRACK NUMBER
  436.     ORA    A
  437.     JNZ    RS2        ;IF NOT TRACK 00, MAKE MOD 52
  438.     POP    PSW
  439.     SBI    27        ;IT'S TRACK 00, MAKE MOD 26
  440.     JMP    RS3
  441. RS2:    POP    PSW        ;GET BIASED SECTOR NUMBER
  442.     SBI    53        ;CALC SECTOR MOD 52
  443. RS3:    JM    RS1        ;SECTOR OK IF MINUS
  444.     INR    A        ;SECTOR MOD 26 OR 52
  445.     STA    SNUM        ;STORE IT BACK
  446.     CPI    1        ;ARE WE BACK TO ONE YET
  447.     JNZ    RS1        ;READ SOME MORE
  448.     LDA    TNUM        ;TRACK NUMBER
  449.     INR    A        ;INCR BY ONE
  450.     CPI    77        ;CHECK LIMIT
  451.     JZ    VALOUT        ;TO EXIT
  452.     STA    TNUM        ;STORE BACK TRACK NO
  453.     JMP    RS0        ;BACK TO READ ROUTINE
  454. VALOUT:    LDA    VALFLG        ;CHECK ERROR FLAG
  455.     ORA    A
  456.     JNZ    ENDFIL
  457.     PRINT    <CR,LF,'Succesfully Verified'>
  458.     LDA    NEWDRV
  459.     ORA    A
  460.     JNZ    VAL2
  461.     PRINT    ' Drive A'
  462.     JMP    ENDFIL
  463. VAL2:    PRINT    ' Drive B'
  464.     JMP    ENDFIL
  465. VALERR:    PRINT    <CR,LF,'Error, Track '>
  466.     LDA    TNUM
  467.     LXI    H,0
  468.     MOV    L,A
  469.     DECOUT
  470.     PRINT    ' Sector '
  471.     LXI    H,0
  472.     LDA    SNUM
  473.     MOV    L,A
  474.     DECOUT
  475.     PRINT    CRLF,$
  476.     MVI    A,-1
  477.     STA    VALFLG        ;SET ERROR FLAG
  478.     RET
  479. ;
  480. ;  PRINT CONTROL AND ESCAPE
  481. ;
  482. PRNCON:    MVI    C,11
  483.     CALL    5
  484.     ANI    1
  485.     RZ            ;RETURN
  486.     CHARIN            ;READ CONSOLE
  487.     CPI    3        ;TEST FOR CONTROL C
  488.     JZ    ENDFIL        ;EXIT IF CONTROL C
  489.     RET
  490. ;
  491. ;    THIS SECTION DISPLAYS A CPM GROUP OF 8 SECTORS
  492. ;
  493. GROUP:    SCAN            ;GET THE GROUP NO
  494.     DECIN            ;CONVERT TO BINARY
  495.     JC    INERR        ;INPUT ERROR IF CARRY SET
  496.     STA    G        ;SAVE GROUP NO
  497.     ADI    13        ;CHECK LEGAL RANGE
  498.     JC    BADGRP
  499.     XRA    A
  500.     STA    S        ;SET SECTOR COUNT TO 0
  501.     CALL    FIXB        ;RESTORE DRIVE B IF SELECTED
  502. GRP1:    CALL    GRPTS        ;CONVERT TO TRACK AND SECTOR
  503.     CALL    RDISK        ;PRINT THE SECTOR
  504.     LDA    S        ;CHECK SECTOR COUNT
  505.     INR    A
  506.     STA    S        ;INCR S BY 1
  507.     CPI    16        ;CHECK LIMIT
  508.     JNZ    GRP1        ;PRINT ANOTHER SECTOR
  509.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  510. ;
  511. ;   GRPTS  CONVERT CPM GROUP AND SECTOR NUMBER TO TRK AND SEC
  512. ;
  513. GRPTS:    MVI    H,0        ;ZERO H
  514.     LDA    G        ;GROUP NO
  515.     MOV    L,A        ;TO L
  516.     MOV    D,H        ;ZERO    D
  517.     DAD    H
  518.     DAD    H
  519.     DAD    H
  520.     DAD    H        ;SHIFT LEFT 4
  521.     LDA    S        ;GET SECTOR NO
  522.     MOV    E,A        ;TO DE
  523.     DAD    D        ;HL HAS G*16+S
  524.     LDA    TRACK        ;GET TRACK NUMBER, DO SECTOR NUMBER AS REQUIRED
  525.     ORA    A
  526.     LXI    D,-26        ;26 SECTORS, DIVISOR
  527.     JZ    SDGRP        ;IF TRACK 00, DO SINGLE DENSITY GROUP
  528.     LXI    D,-52        ;52 SECTORS, DIVISOR
  529. SDGRP:    MVI    A,1        ;CONTAINS DIVIDEND
  530. DIV:    DAD    D        ;SUB 52
  531.     INR    A
  532.     JC    DIV        ;LOOP TILL MINUS
  533.     PUSH    PSW        ;SAVE TRACK NUMBER
  534.     LDA    TRACK        ;GET TRACK NUMBER, INDEX AS REQUIRED
  535.     ORA    A
  536.     LXI    D,SDTABLE+26    ;INDEX INTO SINGLE DENSITY TABLE
  537.     JZ    SDDIV
  538.     LXI    D,DDTABLE+52    ;INDEX INTO DOUBLE DENSITY TABLE
  539. SDDIV:    POP    PSW        ;RECOVER TRACK NUMBER
  540.     DAD    D
  541.     STA    TRACK        ;STORE TRACK NO
  542.     MOV    A,M        ;GET SECTOR NO
  543.     STA    BSEC        ;SAVE IN BEGINNING SECTOR
  544.     STA    ESEC        ;SAVE IN END SECTOR TOO
  545.     RET
  546. $+PRINT
  547. ;
  548. ;    THIS ROUTINE DISPLAYS THE DISK SECTOR ALLOCATION MAP
  549. ;
  550. MAP:    LDA    NEWDRV
  551.     MOV    E,A
  552.     DISKIO    LOGIN        ;LOG IN SELECTED DRIVE
  553.     DISKIO    ?ALLOC        ;GET POINTER TO ALLOCATION MAP
  554.     MOV    H,B
  555.     MOV    L,A        ;TO HL
  556.     SHLD    IPOINT        ;SAVE MAP POINTER
  557.     LXI    H,0        ;ZERO HL
  558.     SHLD    G        ;ZERO COUNT OF UNUSED GROUPS
  559.     PRINT    <CR,LF,LF,'             Group Allocation Map, Drive -'>
  560.     LDA    NEWDRV        ;LOGGED DRIVE
  561.     ORA    A
  562.     JNZ    DRB        ;DRIVE B
  563.     PRINT    <' A',CR,LF,LF>
  564.     JMP    MAP1
  565. DRB:    PRINT    <' B',CR,LF,LF>
  566. MAP1:    LHLD    IPOINT        ;POINTER TO DISK ALLOCATION MAP
  567.     MVI    D,8        ;NO OF LINES
  568. MAP2:    MVI    C,4        ;WORDS PER LINE
  569. MAPX:    SAVE
  570.     PRINT    '            '
  571.     RESTORE
  572. MAP3:    MVI    B,8        ;BITS PER WORD
  573.     MOV    A,M        ;GET A BYTE FROM ALLOC MAP
  574. MAP4:    RAL            ;SHIFT LEFT THRU CARRY
  575.     SAVE    B,D,H,PSW
  576.     JC    MAP5        ;PRINT A ONE
  577.     PRINT    '0'        ;PRINT A ZERO
  578.     LDA    G        ;UNUSED GROUPS
  579.     INR    A        ;ADD 1
  580.     STA    G        ;STORE IT BACK
  581.     JMP    MAP6
  582. MAP5:    PRINT    '1'        ;PRINT A ONE
  583. MAP6:    RESTORE    PSW,H,D,B
  584.     SAVE    PSW        ;SAVE BIT MAP BYTE
  585.     MOV    A,B        ;BIT COUNT
  586.     CPI    7
  587.     JNZ    MAPY
  588.     MOV    A,C        ;WORD COUNT
  589.     CPI    2
  590.     JNZ    MAPY
  591.     MOV    A,D        ;LINE COUNT
  592.     CPI    1
  593.     JNZ    MAPY
  594.     RESTORE    PSW
  595.     JMP    MAP7        ;TO PRINT UNUSED GROUPS
  596. MAPY:    RESTORE    PSW
  597.     DCR    B        ;DCR BIT COUNT
  598.     JNZ    MAP4        ;PRINT MORE BITS
  599.     DCR    C        ;DECR WORD COUNT
  600.     INX    H        ;INCR ALLOC MAP POINTER
  601.     JNZ    MAP3
  602.     SAVE
  603.     PRINT    CRLF,$
  604.     RESTORE
  605.     DCR    D        ;DECR LINE COUNT
  606.     JMP    MAP2
  607. MAP7:    PRINT    <CR,LF,LF,'          '>
  608.     DECOUT    G        ;PRINT NO OF UNUSED SECTORS
  609.     PRINT    <' Groups remaining on disk, out of 486',CR,LF>
  610.     JMP    ENDFIL        ;EXIT
  611. ;
  612. ;
  613. ;    THIS ROUTINE RESTORES DRIVE B
  614. ;
  615. FIXB:    LDA    NEWDRV        ;CHECK DRIVE NO
  616.     ORA    A
  617.     RZ            ;RETURN IF DRIVE A
  618.     LDA    NEWDRV        ;SELECT DRIVE B
  619.     MOV    E,A
  620.     DISKIO    LOGIN
  621.     XRA    A
  622.     STA    TNUM        ;SELECT TRACK ZERO
  623.     INR    A        ;SELECT SECTOR 1
  624.     STA    SNUM
  625.     SETSEC    SNUM
  626.     SETTRK    TNUM
  627.     CALLBIOS DHOME        ;HOME DRIVES
  628.     CALLBIOS DREAD        ;READ TRACK ZERO DIRECT
  629.     RET
  630. ;
  631. ;  ERROR AND EXIT ROUTINES
  632. ;
  633. ;
  634. INERR:    PRINT    <CR,LF,'Input Error'>
  635.     JMP    ENDFIL
  636. ;
  637. BADSEC:    PRINT    <CR,LF,'Incorrect Sector Number'>
  638.     JMP    ENDFIL
  639. ;
  640. BADTRK:    PRINT    <CR,LF,'Incorrect Track Number'>
  641.     JMP    ENDFIL
  642. ;
  643. BADGRP:    PRINT    <CR,LF,'Incorrect Group Number, greater than 485'>
  644.     JMP    ENDFIL
  645. ;
  646. OPNERR:    LDA    NEWDRV        ;CURRENT DRIVE NO
  647.     ORA    A
  648.     JNZ    OPNER1
  649.     PRINT    <CR,LF,'No file by that name on Drive A'>
  650.     JMP    ENDFIL
  651. OPNER1:    PRINT    <CR,LF,'No file by that name on Drive B'>
  652.     JMP    ENDFIL
  653. ;
  654. RDERR:    PRINT    <CR,LF,'Disk Read Error'>
  655.     JMP    MONITOR
  656. NAMERR:    PRINT    <CR,LF,'Error in File Name'>
  657.     JMP    ENDFIL
  658. ;
  659. ADERR:    PRINT    <CR,LF,LF,'Address Error'>
  660.     JMP    EDIT1        ;ADDRESS ERROR ON EDIT
  661. ;
  662. HEXERR:    PRINT    <CR,LF,'  Error, enter Hexadecimal Values Only',CR,LF>
  663.     JMP    PTX
  664. ;
  665. MONITOR: PRINT    CRLF,$
  666.     LDA    DRVNO        ;RESTORE LOGGED DRIVE NO
  667.     MOV    E,A
  668.     DISKIO    LOGIN
  669.     LHLD    OLDSTK
  670.     SPHL            ;RESET OLD STACK POINTER
  671.     RET
  672. ;
  673. ;
  674. ;   DATA ALLOCATIONS
  675. ;
  676. FCB    EQU    5CH        ;FILE CONTROL BLOCK
  677. SPACE:    DB    ' $'        ;ASCII SPACE
  678. CRLF:    DB    0DH,0AH,24H    ;ASCII CR LF
  679. I:    DW    0        ;PSEUDO INDEX REGISTER
  680. LINE:    DW    0        ;LINE NUMBER FOR LISTING
  681. IPOINT:    DW    00        ;VARIABLE BUFFER POINTER
  682. INBUF:    DS    10        ;USED AS CONSOLE INPUT BUFFER
  683. LASTIN:    DB    0        ;LAST CONSOLE INPUT CHAR
  684. INFLAG:    DB    0        ;FLAG, RET FOR MORE CONSOLE INPUT
  685. DRVNO:    DB    0        ;STORAGE FOR ORIGINALLY LOGGED DRIVE
  686. NEWDRV:    DB    0        ;STORAGE FOR NEW DRIVE NO
  687. TRACK:    DB    0        ;SELECTED TRACK
  688. BSEC:    DB    0        ;SELECTED BEGINNING SECTOR
  689. ESEC:    DB    0        ;SELECTED ENDING SECTOR
  690. TNUM:    DB    0        ;TRACK NO FOR VALIDATE
  691. SNUM:    DB    0        ;SECTOR NO FOR VALIDATE
  692. VALFLG:    DB    0        ;VALIDATION ERROR FLAG
  693. G:    DB    0        ;CPM GROUP NO
  694. S:    DB    0        ;SECTOR NO WITHIN GROUP G
  695. COUNT:    DB    0        ;COUNT OF DIRECTORY ENTRIES
  696. OLDSTK:    DW    0        ;STORAGE FOR OLD STACK POINTER
  697. ENDSTK:    DS    24        ;STORAGE FOR NEW STACK
  698. NEWSTK:    DW    0        ;NEW STACK
  699. INB:    DW    0        ;STORES POINTER TO INPUT BUFFER AREA
  700. OUTB:    DW    0        ;STORES POINTER TO DIRECTORY BUFFER AREA
  701. SDTABLE:DB    01        ;DOUBLE DENSITY SECTOR LOOK UP TABLE
  702.     DB    07
  703.     DB    13
  704.     DB    19
  705.     DB    25
  706.     DB    05
  707.     DB    11
  708.     DB    17
  709.     DB    23
  710.     DB    03
  711.     DB    09
  712.     DB    15
  713.     DB    21
  714.     DB    02
  715.     DB    08
  716.     DB    14
  717.     DB    20
  718.     DB    26
  719.     DB    06
  720.     DB    12
  721.     DB    18
  722.     DB    24
  723.     DB    04
  724.     DB    10
  725.     DB    16
  726.     DB    22
  727. DDTABLE:DB    01        ;DOUBLE DENSITY SECTOR LOOK UP TABLE
  728.     DB    02
  729.     DB    19
  730.     DB    20
  731.     DB    37
  732.     DB    38
  733.     DB    03
  734.     DB    04
  735.     DB    21
  736.     DB    22
  737.     DB    39
  738.     DB    40
  739.     DB    05
  740.     DB    06
  741.     DB    23
  742.     DB    24
  743.     DB    41
  744.     DB    42
  745.     DB    07
  746.     DB    08
  747.     DB    25
  748.     DB    26
  749.     DB    43
  750.     DB    44
  751.     DB    09
  752.     DB    10
  753.     DB    27
  754.     DB    28
  755.     DB    45
  756.     DB    46
  757.     DB    11
  758.     DB    12
  759.     DB    29
  760.     DB    30
  761.     DB    47
  762.     DB    48
  763.     DB    13
  764.     DB    14
  765.     DB    31
  766.     DB    32
  767.     DB    49
  768.     DB    50
  769.     DB    15
  770.     DB    16
  771.     DB    33
  772.     DB    34
  773.     DB    51
  774.     DB    52
  775.     DB    17
  776.     DB    18
  777.     DB    35
  778.     DB    36
  779. PDIR    DW    0        ;POINTER TABLE TO DIRECTORY (64 ENTRIES MAX)
  780. DIRBUF:    EQU    PDIR+130    ;START OF AREA USED TO STORE AND SORT DIRECTORY
  781.     END
  782.