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