home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpmug / cpmug024.ark / DUMP.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  18.3 KB  |  704 lines

  1. ;            --- DUMP ---
  2. ;
  3. ;                    BY: S. J. SINGER
  4. ;
  5. ;    THIS PROGRAM IS AN IMPROVED DUMP UTILITY FOR CP/M. ANY CPM FILE
  6. ;MAY BE DUMPED TO THE CONSOLE IN A FORMAT SIMILAR TO THAT USED BY THE
  7. ;DDT DUMP COMMAND. IN ADDITION, ANY SECTOR OR GROUP OF SECTORS MAY
  8. ;BE DUMPED IN THE SAME FORMAT.
  9. ;
  10. ;            -- OPERATION --
  11. ;
  12. ;    THE PROGRAM MAY BE RUN EITHER BY TYPING DUMP, OR DUMP FOLLOWED
  13. ;BY THE FILE NAME OR TRACK AND SECTOR. IF DUMP  IS TYPED THE PROGRAM
  14. ;RESPONDS WITH A HEADING FOLLOWED BY A '*' AND WAITS FOR MORE INPUT. 
  15. ;OPERATION IN THIS MODE IS SIMILAR TO OTHER UTILITIES LIKE PIP OR DDT.
  16. ;    THE OPERATION DESIRED MAY THEN BE TYPED IN AS FOLLOWS:
  17. ;
  18. ;        DUMP FILE.NAM
  19. ;        DUMP A:FILE.NAM
  20. ;        DUMP B:FILE.NAM
  21. ;
  22. ;    OR DUMP MAY BE TYPED SEPARATELY AS:
  23. ;
  24. ;        DUMP
  25. ;
  26. ;        *FILE.NAM
  27. ;        *B:FILE.NAM    (THE * IS A PROGRAM PROMPT)
  28. ;
  29. ;    THE PROGRAM MAY ALSO BE USED TO DUMP DISK SECTORS DIRECTLY,
  30. ;DUMP ANY CP/M EIGHT SECTOR GROUP, A MAP OF THE GROUP ALLOCATIONS FOR THE
  31. ;ENTIRE DISK OR THE DIRECTORY SORTED ALPHABETICALLY.
  32. ;
  33. ;        DUMP TRACK 3 SECTOR 7
  34. ;        DUMP TRACK 5   SECTOR  3 - 9
  35. ;        DUMP TRACK   6   (DUMPS ALL 26 SECTORS)
  36. ;        DUMP GROUP  19
  37. ;        DUMP MAP
  38. ;        DUMP DIR    (DUMPS DIRECTORY)
  39. ;
  40. ;    THE WORDS TRACK, SECTOR AND GROUP MAY BE ABREVIATED AS FOLLOWS
  41. ;
  42. ;        DUMP G 4
  43. ;        DUMP T 7 S 3-4
  44. ;        *TRACK 5 S 6
  45. ;        *SECTOR 2- 9  T 14
  46. ;
  47. ;
  48. ;        DUMP B:  TRACK 3
  49. ;        DUMP A: T 9   S 4-6
  50. ;        DUMP B:   G  5
  51. ;        DUMP B:MAP
  52. ;
  53. ;    NOTE THAT THE FORMAT IS QUITE FREE. SPACES ARE USUALLY IGNORED
  54. ;THEY ARE ONLY REQUIRED AFTER THE WORDS TRACK AND SECTOR OR T AND S,
  55. ;AND AFTER THE WORD DUMP.
  56. ;    A LIMITED EDITING FEATURE IS INCLUDED IN THE DUMP UTILITY TO
  57. ;ALLOW CHANGING DATA ON THE DISK. THE EDIT FEATURE WORKS AS FOLLOWS.
  58. ;ANY SINGLE SECTOR ON EITHER DRIVE MAY BE EDITED BY REQUESTING DISPLAY
  59. ;OF THE SECTOR FOLLOWED BY THE WORD EDIT.
  60. ;
  61. ;        DUMP B:TRACK 4 SECTOR 2  EDIT
  62. ;
  63. ;    THE REQUESTED SECTOR WILL BE DISPLAYED FOLLOWED BY AN EDIT PROMPT
  64. ;
  65. ;    EDIT -
  66. ;
  67. ;    ENTER THE ADDRESS OF THE FIRST BYTE TO BE CHANGED. THE PROGRAM WILL
  68. ;RESPOND BY TYPING BACK THE ADDR ENTERED AND THE PRESENT CONTENTS OF THAT
  69. ;ADDRESS. TO CHANGE THE CONTENTS OF THE ADDRESS ENTER THE NEW BYTE FOLLOWED
  70. ;BY A CARRIAGE RETURN. THE PROGRAM WILL DISPLAY THE NEXT ADDRESS AND ITS
  71. ;CONTENTS. TO STOP ENTERING DATA TYPE A PERIOD. THE PROGRAM WILL REDISPLAY
  72. ;THE SECTOR SHOWING THE CHANGES MADE. THE EDIT FEATURE WORKS ALMOST EXACTLY
  73. ;LIKE THE S ENTRY FEATURE IN DDT. TYPING ONLY A CARRIAGE RETURN OMITS ENTRY.
  74. ;    TYPING A PERIOD MERELY REDISPLAYS THE SECTOR FROM MEMORY, IT DOES
  75. ;NOT CAUSE IT TO BE WRITTEN BACK ON THE DISK. WHEN EDITING IS COMPLETE,
  76. ;REDISPLAY THE SECTOR BY TYPING A PERIOD AND TYPE EITHER
  77. ;
  78. ;        WRITE        (WRITE SECTOR BACK ON DISK)
  79. ;        STOP        (STOP EDITING WITHOUT WRITING ON DISK)
  80. ;
  81. ;    ALL EDIT ENTRIES MUST BE MADE IN HEX. ENTERING NON HEX CHARACTERS
  82. ;RESULTS IN AN ERROR MESSAGE. THE PERMISSABLE ADDRESS RANGE IS 0000 TO 007F.
  83. ;LARGER ADDRESSES GIVE AN ERROR MESSAGE. WHEN ENTERING A GROUP OF BYTES THE
  84. ;ADDRESSES ARE COMPUTED MODULO 128, THE NEXT ADDRESS AFTER 007F IS 0000.
  85. ;    THE EDIT FEATURE SHOULD BE USED WITH CAUTION SINCE IT IS POSSIBLE
  86. ;TO EDIT CP/M TO "DEATH" BY CHANGING A SINGLE BYTE. ONE OCCASIONAL VALUABLE
  87. ;USE IS TO RESTORE FILES THAT HAVE BEEN ACCIDENTALLY ERASED. ERASING A FILE
  88. ;USING THE ERA COMMAND DOES NOT ERASE THE DATA FROM THE DISK, BUT ONLY ENTERS
  89. ;AN E5 INTO THE FIRST BYTE OF THE DIRECTORY. TO RESTORE A FILE, DISPLAY
  90. ;THE DIRECTORY BY DISPLAYING GROUPS 0 AND 1. FIND THE SECTOR CONTAINING THE
  91. ;NAME OF THE FILE TO BE RESTORED AND DISPLAY IT USING THE EDIT FEATURE
  92. ;CHANGE THE BYTE PRECEEDING THE FILE NAME FROM E5 TO 00 AND WRITE THE SECTOR
  93. ;BACK ON THE DISK. THIS WILL RESTORE THE FILE PROVIDED NONE OF THE SECTORS
  94. ;IN THE FILE WERE CHANGED AFTER THE FILE WAS "ERASED".
  95. ;
  96. ;    AN ADDITIONAL FEATURE OF DUMP IS THE ABILITY TO VALIDATE A DISK.
  97. ;
  98. ;        DUMP VALIDATE
  99. ;        DUMP A:VALIDATE
  100. ;        DUMP B:VALIDATE
  101. ;
  102. ;    THIS CAUSES THE ENTIRE DISK SELECTED TO BE READ ONE SECTOR AT A
  103. ;TIME. THE SECTOR NUMBER OF ANY SECTOR CAUSING A READ ERROR WILL BE DISPLAYED.
  104. ;WHEN VALIDATING THE PROGRAM READS EVERY FIFTH SECTOR FOR SPEED.
  105. ;
  106. ;    AS WITH OTHER CP/M UTILITIES ^S "FREEZES" THE DISPLAY, AND ^C
  107. ;RETURNS TO THE MONITOR. DUMP CONTAINS MANY ERROR AND CONSISTANCY
  108. ;CHECKS. THE RESULTING MESSAGES SHOULD BE SELF EXPLANATORY.
  109. ;
  110. ;    DUMP WAS ASSEMBLED USING THE CP/M MACRO ASSEMBLER, AND USES A LARGE
  111. ;NUMBER OF MACROS INCLUDED IN A LIBRARY CALLED MACRO.LIB
  112. ;
  113. $-PRINT
  114.     MACLIB    MACRO        ;INCLUDE MACRO LIBRARY
  115.     ORG    100H        ;SET PROG START
  116.     LXI    H,0
  117.     DAD    SP        ;GET STACK POINTER
  118.     SHLD    OLDSTK
  119.     LXI    SP,NEWSTK    ;SET UP NEW STACK
  120.     DISKIO    ?DRIVE        ;GET CURRENTLY LOGGED DRIVE NO
  121.     STA    NEWDRV        ;ALSO SAVE IN NEW DRIVE NO
  122.     LDA    81H        ;CONSOLE INPUT ALREADY HERE ?
  123.     ORA    A
  124.     JZ    SIGNON        ;BUFFER EMPTY, INPUT FROM CONSOLE
  125.     LDA    80H        ;GET NO OF CHAR INPUT
  126.     ORI    80H        ;ADD 128
  127.     MOV    L,A        ;TO L
  128.     XRA    A        ;ZERO
  129.     MOV    H,A        ;HL CONTAINS ADDR OF END OF BUFFER
  130. ZBFF:    INR    L
  131.     JZ    START        ;REMAINDER OF BUFFER ZEROED
  132.     MOV    M,A
  133.     JMP    ZBFF        ;LOOP
  134. SIGNON:    PRINT    <CR,LF,'CP/M DUMP UTILITY VERS 1.3',CR,LF>
  135.     PRINT    <'COPYRIGHT 1978 BY S. J. SINGER',CR,LF>
  136. NEWIN:    PRINT    <CR,LF,'*'>
  137.     MVI    A,0FFH        ;SET SWITCH TO RETURN HERE AGAIN
  138.     STA    INFLAG
  139.     LXI    SP,NEWSTK    ;RESET STACK POINTER
  140.     XRA    A
  141.     STA    VALFLG        ;RESET VALIDATION ERROR FLAG
  142.     LXI    H,0
  143.     SHLD    LINE        ;SET LINE COUNT TO ZERO
  144.     FILL    80H,0FFH    ;ZERO INPUT BUFFER
  145.     INPUT    80H        ;READ FILE NAME
  146. ;
  147. ;  SELECT DISK DRIVE AND SET UP FILE CONTROL BLOCK
  148. ;
  149. START:    FILL    FCB,FCB+32    ;ZERO FILE CONTROL BLOCK
  150.     MATCH    82H,'A:'    ;DRIVE A
  151.     JZ    ADISK
  152.     MATCH    82H,'B:'    ;DRIVE B
  153.     JZ    BDISK
  154.     JMP    GETNAM        ;NO DRIVE SPECIFIED
  155. ADISK:    XRA    A
  156.     STA    NEWDRV        ;SELECT DRIVE A
  157.     JMP    DOWN
  158. BDISK:    MVI    A,1
  159.     STA    NEWDRV        ;SELECT DRIVE B
  160. DOWN:    MOVE    82H,80H,40H    ;SHIFT BUFFER DOWN TWO BYTES
  161. ;
  162. ;  SEARCH FOR DIRECT READ OF TRACK AND SECTOR OR VALIDATE
  163. ;
  164. GETNAM:    INSTR    82H,40H,'VALIDATE'
  165.     JC    VALID        ;VALIDATE DISK
  166.     INSTR    82H,40H,'GROUP'
  167.     JC    GROUP        ;DISPLAY CPM 8 SECTOR GROUP
  168.     INSTR    82H,40H,'G '    ;SEARCH FOR 'G'
  169.     JC    GROUP        ;DISPLAY GROUP
  170.     INSTR    82H,40H,'MAP'    ;ALLOCATION MAP
  171.     JC    MAP        ;DISPLAY GROUP ALLOCATION MAP
  172.     INSTR    82H,40H,'DIR'    ;DIRECTORY REQUEST
  173.     JC    DIR        ;DISPLAY DIRECTORY
  174.     INSTR    82H,40H,'TRACK'    ;SEARCH FOR TRACK
  175.     JC    TRK1
  176.     INSTR    82H,40H,'T '    ;SEARCH FOR 'T'
  177.     JNC    FILNAM        ;NO TRACK GO TO READ FILE
  178. TRK1:    SCAN            ;FIND AND CONVERT NUMBER
  179.     DECIN
  180.     JC    INERR        ;INPUT ERROR ON CARRY
  181.     STA    TRACK        ;SAVE TRACK NO
  182.     INSTR    82H,40H,'SECTOR'    ;SEARCH FOR SECTOR
  183.     JC    SEC1
  184.     INSTR    82H,40H,'S '    ;TRY 'S'
  185.     JNC    WHLTRK        ;DUMP ENTIRE TRACK
  186. SEC1:    SCAN    
  187.     DECIN
  188.     JC    INERR        ;INPUT ERROR ON CARRY
  189.     STA    BSEC        ;BEGINNING SECTOR
  190.     STA    ESEC        ;SAVE IN END SECTOR ALSO
  191.     XCHG            ;SET BUFFER POINTER FOR SCAN
  192.     SHLD    IPOINT        ;SAVE BUFFER POINTER FOR EDIT
  193.     INSTR    ,40H,'-'    ;SEARCH FOR '-'
  194.     JNC    EDIT        ;CHECK FOR EDITION OF SECTOR
  195.     SCAN
  196.     DECIN            ;SCAN AND CONVERT ANOTHER NO
  197.     JC    INERR        ;ERROR IF CARRY SET
  198.     STA    ESEC        ;SAVE IN END SECTOR
  199.     LXI    H,BSEC        ;POINTS TO BSEC
  200.     CMP    M        ;COMPARE BEGIN AND END
  201.     JP    DOREAD        ;OK IF END>=BEGIN
  202.     MOV    B,A        ;OTHERWISE
  203.     MOV    A,M        ;SWITCH THEM
  204.     STA    ESEC
  205.     MOV    M,B
  206. DOREAD:    CALL    RDISK0        ;READ DIRECT
  207.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  208. EDIT:    LHLD    IPOINT        ;RESET BUFFER POINTER
  209.     INSTR    ,40H,'EDIT'    ;CHECK EDIT FUNCTION
  210.     JNC    DOREAD        ;GO TO DISPLAY SECTOR
  211.     CALL    RDISK0        ;DISPLAY SECTOR
  212. EDIT1:    PRINT    <CR,LF,'EDIT - '>
  213.     FILL    INBUF,INBUF+9
  214.     INPUT    INBUF,6        ;INPUT MAXIMUM 6 CHAR
  215.     INSTR    INBUF,8,'WRITE'    ;WRITE EDITED SECTOR ON DISK?
  216.     JC    WRTDSK        ;WRITE BUFFER BACK ON DISK
  217.     INSTR    INBUF,8,'STOP'    ;STOP EDITING WITHOUT WRITING?
  218.     JC    ENDFIL        ;EXIT
  219.     HEXIN    INBUF+2        ;CONV ASCII TO HEX
  220.     JNC    CKLIM        ;IF NO ERROR, CHECK ADDR
  221.     LDAX    D        ;GET ASCII CHAR
  222.     CPI    '.'        ;CHECK FOR EXIT CHAR
  223.     JZ    EDIT3        ;BACK FOR MORE EDITING
  224.     JMP    ADERR        ;ADDRESS ERROR
  225. CKLIM:    LXI    D,0080H        ;CHECK ADDR LIMIT
  226.     CPHL
  227.     JP    ADERR        ;ADDRESS ERROR
  228.     SHLD    IPOINT        ;SAVE ADDRESS
  229.     PRINT    CRLF,$
  230. PTX:    HEXOUT    IPOINT+1
  231.     HEXOUT    IPOINT        ;ECHO THE ADDRESS
  232.     PRINT    SPACE,$
  233.     LHLD    IPOINT        ;ECHO PRESENT CONTENTS
  234.     LXI    D,0080H
  235.     DAD    D        ;COMPUTE MEMORY ADDR
  236.     MOV    A,M        ;GET BYTE FROM MEMORY
  237.     HEXOUT
  238.     PRINT    SPACE,$
  239.     FILL    INBUF,INBUF+5    ;ZERO INPUT BUFFER
  240.     INPUT    INBUF,4        ;INPUT 4 CHAR MAX
  241.     HEXIN    INBUF+2        ;CONVERT
  242.     JNC    EDIT2        ;HEX CHAR
  243.     LDAX    D        ;GET ASCII CHAR
  244.     CPI    '.'        ;PERIOD ENDS INPUT
  245.     JZ    EDIT3        ;BACK FOR MORE EDITING
  246.     JMP    HEXERR        ;ERROR NOT HEX CHAR
  247. EDIT2:    LDA    INBUF+1        ;LOAD NO OF CHAR TYPED
  248.     ORA    A
  249.     JZ    EDITX        ;NO REPLACEMENT IF JUST CR
  250.     MOV    A,L        ;CONVERTED CHAR BACK TO A
  251.     LHLD    IPOINT        ;LOAD MEMORY BUFFER POINTER
  252.     LXI    D,0080H        ;OFFSET
  253.     DAD    D        ;CALC MEMORY ADDR
  254.     MOV    M,A        ;STORE NEW INPUT TO MEMORY
  255. EDITX:    PRINT    CRLF,$
  256.     LDA    IPOINT        ;LEAST SIGNIFICANT HALF OF ADDR
  257.     INR    A        ;INCR BY ONE
  258.     ANI    7FH        ;COUNT MOD 128
  259.     STA    IPOINT
  260.     JMP    PTX        ;INPUT MORE DATA
  261. EDIT3:    LXI    H,0
  262.     SHLD    LINE        ;RESET LINE NO TO ZERO
  263.     CALL    PRTSEC        ;PRINT BUFFER WITH HEADING
  264.     JMP    EDIT1        ;BACK FOR ADDITIONAL EDITING
  265. WRTDSK:    CALLBIOS DWRITE        ;WRITE BUFFER BACK ON DISK
  266.     JMP ENDFIL        ;EXIT
  267. ;
  268. ;  READ TRACK AND SECTOR DIRECT
  269. ;
  270. RDISK0:    CALL    FIXB
  271. RDISK:    SETSEC    BSEC        ;SET SECTOR
  272.     JC    BADSEC        ;WRONG SECTOR NO
  273. TRK2:    SETTRK    TRACK        ;SET TRACK
  274.     JC    BADTRK        ;WRONG TRACK NO
  275.     LDA    NEWDRV
  276.     MOV    E,A
  277.     DISKIO    LOGIN            ;SELECT NEW DEIVE IF SPECIFIED
  278.     CALLBIOS DREAD        ;READ TRACK AND SECTOR
  279. ;
  280. ;  PRINT DRIVE, TRACK AND SECTOR HEADING
  281. ;
  282. PRTSEC:    LDA    NEWDRV        ;NEW DRIVE NO
  283.     ORA    A
  284.     JNZ    PRNB        ;PRINT DRIVE B
  285.     PRINT    <CR,LF,'               DRIVE A -'>
  286. PRNTRK:    PRINT    ' TRACK '
  287.     LXI    H,0
  288.     LDA    TRACK
  289.     MOV    L,A
  290.     DECOUT
  291.     PRINT    '  SECTOR '
  292.     LXI    H,0
  293.     LDA    BSEC
  294.     MOV    L,A
  295.     DECOUT
  296.     PRINT    CRLF,$
  297.     CALL    PRTBUF        ;PRINT IT
  298.     LXI    H,BSEC        ;ADDR OF SECTOR NUMBER
  299.     LDA    ESEC        ;END SECTOR NUMBER
  300.     CMP    M        ;COMPARE THEM
  301.     RZ            ;EXIT IF THEY ARE EQUAL
  302.     INR    M        ;INCR BSEC
  303.     JMP    RDISK
  304. PRNB:    PRINT    <CR,LF,'               DRIVE B -'>
  305.     JMP    PRNTRK        ;PRINT TRACK AND SECTOR
  306. ;
  307. ;  DUMP ENTIRE TRACK IF NO SECTOR INPUT
  308. ;
  309. WHLTRK:    MVI    A,1        ;BEGIN SECTOR
  310.     STA    BSEC
  311.     MVI    A,26        ;END SECTOR
  312.     STA    ESEC
  313.     CALL    RDISK0        ;TO READ DISK
  314.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  315. ;
  316. ;  FILL IN FCB FOR NAMED FILE
  317. ;
  318. FILNAM:    FILFCB    FCB,82H    ;FILL IN FCB NAME FROM INPUT BUFFER
  319.     JC    NAMERR        ;ERROR IN FILE NAME
  320.     MATCH    FCB+9,'COM'    ;TEST FOR COM FILE
  321.     JNZ    SELDR
  322.     LXI    H,100H    
  323.     SHLD    LINE        ;SET LINE NO. TO 100
  324. SELDR:    LDA    NEWDRV        ;SELECT NEW DRIVE
  325.     MOV    E,A
  326.     DISKIO    LOGIN
  327.     DISKIO    OPEN,FCB    ;0PEN FILE
  328.     CPI    255        ;CHECK FILE PRESENT
  329.     JZ    OPNERR        ;EXIT IF ERROR
  330. RDFILE:    DISKIO    READ,FCB    ;READ A BLOCK
  331.     ORA    A        ;ZERO INDICATES SUCESSFUL READ
  332.     JNZ    ENDFIL        ;1 INDICATES EOF
  333.     CALL    PRTBUF        ;DO PRINT SUBROUTINE
  334.     JMP    RDFILE        ;BACK FOR NEXT BLOCK
  335. ENDFIL:    LDA    INFLAG        ;SEE WHERE TO GO
  336.     ORA    A
  337.     JZ    MONITOR
  338.     JMP    NEWIN
  339. ;
  340. ;
  341. ;  PRTBUF - PRINT BUFFER IN HEX AND ASCII
  342. ;
  343. PRTBUF:    MVI    B,8        ;8 LINES
  344.     LXI    H,80H        ;INITIAL BUFFER POINTER
  345.     SHLD    IPOINT        ;STORAGE FOR POINTER
  346. BPRN:    LHLD    IPOINT        ;LOAD POINTER
  347.     MVI    C,16        ;CHAR PER LINE
  348.     LDA    LINE+1        ;LINE NUMBER
  349.     SAVE    B,H
  350.     HEXOUT
  351.     LDA    LINE        ;SECOND TWO DIGITS
  352.     HEXOUT
  353.     PRINT    '  '
  354.     RESTORE    H,B
  355. PLOOP:    MOV    A,M        ;GET A BYTE
  356.     SAVE    B,H
  357.     HEXOUT
  358.     PRINT    SPACE,$
  359.     RESTORE    H,B
  360.     INX    H        ;INCR MEMORY POINTER
  361.     MOV    A,C
  362.     CPI    9        ;CHECK 8 CHAR
  363.     JNZ    DECC        ;SKIP IF NOT
  364.     SAVE    B,H
  365.     PRINT    SPACE,$
  366.     RESTORE    H,B
  367. DECC:    DCR    C        ;DECR CHAR COUNT
  368.     JNZ    PLOOP        ;PRINT SOME MORE
  369.     SAVE    B
  370.     PRINT    SPACE,$
  371.     RESTORE    B
  372.     LHLD    IPOINT        ;RESET POINTER FOR ASCII
  373.     MVI    C,10H        ;RESET CHAR COUNT
  374. PLOOP1:    MOV    A,M        ;GET A BYTE
  375.     ANI    7FH        ;MASK OFF HIGH BIT
  376.     CPI    7FH        ;DELETE CODE
  377.     JZ    PERIOD        ;PRINT PERIOD FOR DELETE
  378.     CPI    20H        ;TEST FOR CONTROL CHAR
  379.     JP    SKIPX        ;SKIP SUBSTITUTION
  380. PERIOD:    MVI    A,2EH        ;ASCII PERIOD
  381. SKIPX:    SAVE    B,H
  382.     CHAROUT            ;PRINT IT SAVE REGS
  383.     RESTORE    H,B
  384.     INX    H        ;INCR MEMORY POINTER
  385.     MOV    A,C
  386.     CPI    9        ;CHECK 8 CHAR
  387.     JNZ    DECC2
  388.     SAVE    B,H
  389.     PRINT    SPACE,$
  390.     RESTORE    H,B
  391. DECC2:    DCR    C        ;DECR CHAR COUNT
  392.     JNZ    PLOOP1        ;PRINT SOME MORE
  393.     SAVE    B
  394.     PRINT    CRLF,$        ;CARRIAGE RETURN
  395.     CALL    PRNCON        ;PRINT CONTROL?
  396.     POP    B
  397.     INDEX    LINE,16        ;INCR LINE NO BY 16
  398.     DCR    B        ;DECR    LINE COUNT
  399.     RZ            ;RETURN IF LINE COUNT ZERO
  400.     INDEX    IPOINT,16    ;INCR POINTER BY 16
  401.     JMP    BPRN        ;LOOP BACK
  402. ;
  403. ;    THIS SECTION VALIDATES A DISK
  404. ;
  405. VALID:    MVI    A,1        ;START WITH SECTOR 1
  406.     STA    SNUM
  407.     XRA    A        ;START WITH TRACK 0
  408.     STA    TNUM
  409.     LDA    NEWDRV        ;SELECT NEW DRIVE
  410.     MOV    E,A
  411.     DISKIO    LOGIN
  412. RS0:    SETTRK    TNUM
  413.     JC    BADTRK
  414. RS1:    SETSEC    SNUM
  415.     JC    BADSEC
  416.     CALLBIOS DREAD
  417.     ORA    A
  418.     CNZ    VALERR        ;ERROR IF NOT ZERO
  419.     CALL    PRNCON        ;ESCAPE ON CONTROL C
  420.     LDA    SNUM        ;SECTOR NO
  421.     ADI    5        ;INCR BY 5
  422.     STA    SNUM        ;STORE IT BACK
  423.     SBI    27        ;CALC SECTOR MOD 26
  424.     JM    RS1        ;SECTOR OK IF MINUS
  425.     INR    A        ;SECTOR MOD 26
  426.     STA    SNUM        ;STORE IT BACK
  427.     CPI    1        ;ARE WE BACK TO ONE YET
  428.     JNZ    RS1        ;READ SOME MORE
  429.     LDA    TNUM        ;TRACK NUMBER
  430.     INR    A        ;INCR BY ONE
  431.     CPI    77        ;CHECK LIMIT
  432.     JZ    VALOUT        ;TO EXIT
  433.     STA    TNUM        ;STORE BACK TRACK NO
  434.     JMP    RS0        ;BACK TO READ ROUTINE
  435. VALOUT:    LDA    VALFLG        ;CHECK ERROR FLAG
  436.     ORA    A
  437.     JNZ    ENDFIL
  438.     PRINT    <CR,LF,'SUCCESSFUL VALIDATION'>
  439.     LDA    NEWDRV
  440.     ORA    A
  441.     JNZ    VAL2
  442.     PRINT    ' DRIVE A'
  443.     JMP    ENDFIL
  444. VAL2:    PRINT    ' DRIVE B'
  445.     JMP    ENDFIL
  446. VALERR:    PRINT    <CR,LF,'ERROR - TRACK '>
  447.     LDA    TNUM
  448.     LXI    H,0
  449.     MOV    L,A
  450.     DECOUT
  451.     PRINT    '  SECTOR '
  452.     LXI    H,0
  453.     LDA    SNUM
  454.     MOV    L,A
  455.     DECOUT
  456.     PRINT    CRLF,$
  457.     MVI    A,-1
  458.     STA    VALFLG        ;SET ERROR FLAG
  459.     RET
  460. ;
  461. ;  PRINT CONTROL AND ESCAPE
  462. ;
  463. PRNCON:    MVI    C,11
  464.     CALL    5
  465.     ANI    1
  466.     RZ            ;RETURN
  467.     CHARIN            ;READ CONSOLE
  468.     CPI    3        ;TEST FOR CONTROL C
  469.     JZ    ENDFIL        ;EXIT IF CONTROL C
  470.     RET
  471. ;
  472. ;    THIS SECTION DISPLAYS A CPM GROUP OF 8 SECTORS
  473. ;
  474. GROUP:    SCAN            ;GET THE GROUP NO
  475.     DECIN            ;CONVERT TO BINARY
  476.     JC    INERR        ;INPUT ERROR IF CARRY SET
  477.     STA    G        ;SAVE GROUP NO
  478.     ADI    13        ;CHECK LEGAL RANGE
  479.     JC    BADGRP
  480.     XRA    A
  481.     STA    S        ;SET SECTOR COUNT TO 0
  482.     CALL    FIXB        ;RESTORE DRIVE B IF SELECTED
  483. GRP1:    CALL    GRPTS        ;CONVERT TO TRACK AND SECTOR
  484.     CALL    RDISK        ;PRINT THE SECTOR
  485.     LDA    S        ;CHECK SECTOR COUNT
  486.     INR    A
  487.     STA    S        ;INCR S BY 1
  488.     CPI    8        ;CHECK LIMIT
  489.     JNZ    GRP1        ;PRINT ANOTHER SECTOR
  490.     JMP    ENDFIL        ;BACK FOR MORE INPUT
  491. ;
  492. ;   GRPTS  CONVERT CPM GROUP AND SECTOR NUMBER TO TRK AND SEC
  493. ;
  494. GRPTS:    MVI    H,0        ;ZERO H
  495.     LDA    G        ;GROUP NO
  496.     MOV    L,A        ;TO L
  497.     MOV    D,H        ;ZERO    D
  498.     DAD    H
  499.     DAD    H
  500.     DAD    H        ;SHIFT LEFT 3
  501.     LDA    S        ;GET SECTOR NO
  502.     MOV    E,A        ;TO DE
  503.     DAD    D        ;HL HAS G*8+S
  504.     LXI    D,-26        ;DIVISOR
  505.     MVI    A,1        ;CONTAINS DIVIDEND
  506. DIV:    DAD    D        ;SUB 26
  507.     INR    A
  508.     JC    DIV        ;LOOP TILL MINUS
  509.     LXI    D,TABLE+26    ;INDEX INTO TABLE
  510.     DAD    D
  511.     STA    TRACK        ;STORE TRACK NO
  512.     MOV    A,M        ;GET SECTOR NO
  513.     STA    BSEC        ;SAVE IN BEGINNING SECTOR
  514.     STA    ESEC        ;SAVE IN END SECTOR TOO
  515.     RET
  516. $+PRINT
  517. ;
  518. ;    THIS ROUTINE DISPLAYS THE DISK SECTOR ALLOCATION MAP
  519. ;
  520. MAP:    LDA    NEWDRV
  521.     MOV    E,A
  522.     DISKIO    LOGIN        ;LOG IN SELECTED DRIVE
  523.     DISKIO    ?ALLOC        ;GET POINTER TO ALLOCATION MAP
  524.     MOV    H,B
  525.     MOV    L,A        ;TO HL
  526.     SHLD    IPOINT        ;SAVE MAP POINTER
  527.     LXI    H,0        ;ZERO HL
  528.     SHLD    G        ;ZERO COUNT OF UNUSED GROUPS
  529.     PRINT    <CR,LF,LF,'             GROUP ALLOCATION MAP DRIVE -'>
  530.     LDA    NEWDRV        ;LOGGED DRIVE
  531.     ORA    A
  532.     JNZ    DRB        ;DRIVE B
  533.     PRINT    <' A',CR,LF,LF>
  534.     JMP    MAP1
  535. DRB:    PRINT    <' B',CR,LF,LF>
  536. MAP1:    LHLD    IPOINT        ;POINTER TO DISK ALLOCATION MAP
  537.     MVI    D,8        ;NO OF LINES
  538. MAP2:    MVI    C,4        ;WORDS PER LINE
  539. MAPX:    SAVE
  540.     PRINT    '            '
  541.     RESTORE
  542. MAP3:    MVI    B,8        ;BITS PER WORD
  543.     MOV    A,M        ;GET A BYTE FROM ALLOC MAP
  544. MAP4:    RAL            ;SHIFT LEFT THRU CARRY
  545.     SAVE    B,D,H,PSW
  546.     JC    MAP5        ;PRINT A ONE
  547.     PRINT    '0'        ;PRINT A ZERO
  548.     LDA    G        ;UNUSED GROUPS
  549.     INR    A        ;ADD 1
  550.     STA    G        ;STORE IT BACK
  551.     JMP    MAP6
  552. MAP5:    PRINT    '1'        ;PRINT A ONE
  553. MAP6:    RESTORE    PSW,H,D,B
  554.     SAVE    PSW        ;SAVE BIT MAP BYTE
  555.     MOV    A,B        ;BIT COUNT
  556.     CPI    7
  557.     JNZ    MAPY
  558.     MOV    A,C        ;WORD COUNT
  559.     CPI    2
  560.     JNZ    MAPY
  561.     MOV    A,D        ;LINE COUNT
  562.     CPI    1
  563.     JNZ    MAPY
  564.     RESTORE    PSW
  565.     JMP    MAP7        ;TO PRINT UNUSED GROUPS
  566. MAPY:    RESTORE    PSW
  567.     DCR    B        ;DCR BIT COUNT
  568.     JNZ    MAP4        ;PRINT MORE BITS
  569.     DCR    C        ;DECR WORD COUNT
  570.     INX    H        ;INCR ALLOC MAP POINTER
  571.     JNZ    MAP3
  572.     SAVE
  573.     PRINT    CRLF,$
  574.     RESTORE
  575.     DCR    D        ;DECR LINE COUNT
  576.     JMP    MAP2
  577. MAP7:    PRINT    <CR,LF,LF,'          '>
  578.     DECOUT    G        ;PRINT NO OF UNUSED SECTORS
  579.     PRINT    <' GROUPS REMAINING ON DISK OUT OF 243',CR,LF>
  580.     JMP    ENDFIL        ;EXIT
  581. ;
  582. ;    THIS ROUTINE SORTS AND DISPLAYS THE DIRECTORY
  583. ;    (NOT IMPLEMENTED IN THIS VERSION)
  584. ;
  585. DIR:    JMP    ENDFIL        ;EXIT
  586. ;
  587. ;    THIS ROUTINE RESTORES DRIVE B
  588. ;
  589. FIXB:    LDA    NEWDRV        ;CHECK DRIVE NO
  590.     ORA    A
  591.     RZ            ;RETURN IF DRIVE A
  592.     LDA    NEWDRV        ;SELECT DRIVE B
  593.     MOV    E,A
  594.     DISKIO    LOGIN
  595.     XRA    A
  596.     STA    TNUM        ;SELECT TRACK ZERO
  597.     INR    A        ;SELECT SECTOR 1
  598.     STA    SNUM
  599.     SETSEC    SNUM
  600.     SETTRK    TNUM
  601.     CALLBIOS DHOME        ;HOME DRIVES
  602.     CALLBIOS DREAD        ;READ TRACK ZERO DIRECT
  603.     RET
  604. ;
  605. ;  ERROR AND EXIT ROUTINES
  606. ;
  607. ;
  608. INERR:    PRINT    <CR,LF,'INPUT ERROR'>
  609.     JMP    ENDFIL
  610. ;
  611. BADSEC:    PRINT    <CR,LF,'INCORRECT SECTOR NUMBER'>
  612.     JMP    ENDFIL
  613. ;
  614. BADTRK:    PRINT    <CR,LF,'INCORRECT TRACK NUMBER'>
  615.     JMP    ENDFIL
  616. ;
  617. BADGRP:    PRINT    <CR,LF,'INCORRECT GROUP NUMBER (GREATER THAN 242)'>
  618.     JMP    ENDFIL
  619. ;
  620. OPNERR:    LDA    NEWDRV        ;CURRENT DRIVE NO
  621.     ORA    A
  622.     JNZ    OPNER1
  623.     PRINT    <CR,LF,'NO FILE BY THAT NAME ON DRIVE A'>
  624.     JMP    ENDFIL
  625. OPNER1:    PRINT    <CR,LF,'NO FILE BY THAT NAME ON DRIVE B'>
  626.     JMP    ENDFIL
  627. ;
  628. RDERR:    PRINT    <CR,LF,'DISK DEAD ERROR'>
  629.     JMP    MONITOR
  630. NAMERR:    PRINT    <CR,LF,'ERROR IN FILE NAME'>
  631.     JMP    ENDFIL
  632. ;
  633. ADERR:    PRINT    <CR,LF,LF,'ADDRESS ERROR'>
  634.     JMP    EDIT1        ;ADDRESS ERROR ON EDIT
  635. ;
  636. HEXERR:    PRINT    <CR,LF,'  ERROR - HEX INPUT ONLY',CR,LF>
  637.     JMP    PTX
  638. ;
  639. MONITOR: PRINT    CRLF,$
  640.     LDA    DRVNO        ;RESTORE LOGGED DRIVE NO
  641.     MOV    E,A
  642.     DISKIO    LOGIN
  643.     LHLD    OLDSTK
  644.     SPHL            ;RESET OLD STACK POINTER
  645.     RET
  646. ;
  647. ;
  648. ;   DATA ALLOCATIONS
  649. ;
  650. FCB    EQU    5CH        ;FILE CONTROL BLOCK
  651. SPACE:    DB    ' $'        ;ASCII SPACE
  652. CRLF:    DB    0DH,0AH,24H    ;ASCII CR LF
  653. I:    DW    0        ;PSEUDO INDEX REGISTER
  654. LINE:    DW    0        ;LINE NUMBER FOR LISTING
  655. IPOINT:    DW    00        ;VARIABLE BUFFER POINTER
  656. INBUF:    DS    10        ;USED AS CONSOLE INPUT BUFFER
  657. LASTIN:    DB    0        ;LAST CONSOLE INPUT CHAR
  658. INFLAG:    DB    0        ;FLAG, RET FOR MORE CONSOLE INPUT
  659. DRVNO:    DB    0        ;STORAGE FOR ORIGINALLY LOGGED DRIVE
  660. NEWDRV:    DB    0        ;STORAGE FOR NEW DRIVE NO
  661. TRACK:    DB    0        ;SELECTED TRACK
  662. BSEC:    DB    0        ;SELECTED BEGINNING SECTOR
  663. ESEC:    DB    0        ;SELECTED ENDING SECTOR
  664. TNUM:    DB    0        ;TRACK NO FOR VALIDATE
  665. SNUM:    DB    0        ;SECTOR NO FOR VALIDATE
  666. VALFLG:    DB    0        ;VALIDATION ERROR FLAG
  667. G:    DB    0        ;CPM GROUP NO
  668. S:    DB    0        ;SECTOR NO WITHIN GROUP G
  669. COUNT:    DB    0        ;COUNT OF DIRECTORY ENTRIES
  670. OLDSTK:    DW    0        ;STORAGE FOR OLD STACK POINTER
  671. ENDSTK:    DS    24        ;STORAGE FOR NEW STACK
  672. NEWSTK:    DW    0        ;NEW STACK
  673. INB:    DW    0        ;STORES POINTER TO INPUT BUFFER AREA
  674. OUTB:    DW    0        ;STORES POINTER TO DIRECTORY BUFFER AREA
  675. TABLE:    DB    01H        ;SECTOR LOOK UP TABLE
  676.     DB    07H
  677.     DB    0DH
  678.     DB    13H
  679.     DB    19H
  680.     DB    05H
  681.     DB    0BH
  682.     DB    11H
  683.     DB    17H
  684.     DB    03H
  685.     DB    09H
  686.     DB    0FH
  687.     DB    15H
  688.     DB    02H
  689.     DB    08H
  690.     DB    0EH
  691.     DB    14H
  692.     DB    1AH
  693.     DB    06H
  694.     DB    0CH
  695.     DB    12H
  696.     DB    18H
  697.     DB    04H
  698.     DB    0AH
  699.     DB    10H
  700.     DB    16H
  701. PDIR    DW    0        ;POINTER TABLE TO DIRECTORY (64 ENTRIES MAX)
  702. DIRBUF:    EQU    PDIR+130    ;START OF AREA USED TO STORE AND SORT DIRECTORY
  703.     END
  704.