home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol044 / du-v77.asm < prev    next >
Assembly Source File  |  1984-04-29  |  42KB  |  2,616 lines

  1. ;      DU.ASM  V7.7    Revised 7/07/81
  2. ;    DISK UTILITY - By Ward Christensen
  3. ;
  4. ;See DU.DOC for description and detailed instructions.
  5. ;
  6. ;This version of DU is compatible with CP/M 1.4 and 2.x
  7. ;and does not require alteration for various hardware
  8. ;configurations.  It adjusts itself automatically to
  9. ;the correct number of sectors, tracks, directory size,
  10. ;etc.  It has been tested on 5-1/4" and 8" floppy, and
  11. ;10 megabyte hard disk systems.
  12. ;
  13. ;Because of the automatic adaption feature, no conditional
  14. ;assembly options are included.  The only alteration that
  15. ;needs to be done is to use DDT to set the byte at 103h
  16. ;to zero for systems using a 2 mHz clock or non-zero for
  17. ;4 mHz clock.  This only affects the time delay used in
  18. ;the 'sleep' command.
  19. ;
  20. ;*************************************************
  21. ;*                         *
  22. ;*   This program has been heavily modified     *
  23. ;* to allow it to work without modification     *
  24. ;* on most versions of CP/M 1.4 and, hopefully,  *
  25. ;* all versions of CP/M 2.x.             *
  26. ;*   If you have difficulty getting this program *
  27. ;* to run, AND if you are using CP/M 2.x, AND     *
  28. ;* if you know your BIOS to be bug-free, leave     *
  29. ;* a message on Technical CBBS of Dearborn,     *
  30. ;* Michigan (313)-846-6127 with a description     *
  31. ;* of the problem and a summary of your hard-     *
  32. ;* ware configuration.                 *
  33. ;*   One known possible problem involves the     *
  34. ;* system tracks on some systems, and results     *
  35. ;* from the system sectors being skewed. There     *
  36. ;* is NO way for a program executing under CP/M  *
  37. ;* to know about this.    This program assumes the *
  38. ;* standard convention of no skew being used on  *
  39. ;: the system tracks. This usually isn't a prob- *
  40. ;* lem because the SYSGEN program can be used to *
  41. ;* get the system from the disk so that it can     *
  42. ;* be modified.                  *
  43. ;*   This program should work under standard     *
  44. ;* versions of CP/M 1.4.  The only requirement     *
  45. ;* is that the BIOS "SETSEC" routine not modify  *
  46. ;* the sector number passed to it in the B     *
  47. ;* register.  Again, system tracks with skewed     *
  48. ;* sectors will be a problem.             *
  49. ;*   If you add any features or make any useful  *
  50. ;* changes to this program, please modem a copy  *
  51. ;* to the above CBBS, so the currency of the     *
  52. ;* program can be maintained.             *
  53. ;*                         *
  54. ;*        Ron Fowler             *
  55. ;*                         *
  56. ;*************************************************
  57. ;
  58. ;
  59. ;07/12/81 Merged DJH vers 7.6 and Bill Ernest ver 7.6
  60. ;      to form new vers 7.7     (RGF)
  61. ;
  62. ;07/07/81 Added "Y" command to allow sectors to be written
  63. ;      sequentially into memory starting at 3000H, for
  64. ;      later recovery by DDT, etc.  (DJH)
  65. ;
  66. ;04/02/81 Added * to map showing multiple group assign-
  67. ;      ment errors.    Fixed bug in getgrp record counw
  68. ;      (William Ernest)
  69. ;
  70. ;01/23/81 Changed SETSEC to ignore high-order result of
  71. ;      SECTRN if SPT<256.  This fixes some translation
  72. ;      problems where the BIOS leaves garbage in H. (BRR)
  73. ;
  74. ;01/15/81 Changed labels to be no more than 6 characters
  75. ;      long.  Moved stack.  Cleaned up file.  (KBP)
  76. ;
  77. ;01/13/81 Updated help messages for '#' and 'N' commands.
  78. ;      Modified sign-on message.  (RGF)
  79. ;
  80. ;01/12/81 Fixed problem with sector translation under
  81. ;      CP/M 1.4.  (RGF)
  82. ;
  83. ;01/11/81 Fixed problem with CP/M 1.4.    Added 'N' command.
  84. ;      Hard-code 'FASTCLOCK' as a boolean at 103h.  Add
  85. ;      fix for sector number being 0 in system tracks,
  86. ;      as suggested by Keith Petersen, W8SDZ. Added '#'
  87. ;      command and memory-full check. Changed login to
  88. ;      position to directory track at every log.  This
  89. ;      is necessary to set up the 'FIRST0' flag.  (RGF)
  90. ;
  91. ;01/08/81 Corrected error in MAP routine that caused map
  92. ;      to fail when >255 groups allocated.  Changed
  93. ;      'REPEAT' to allow up to 65535 repeats.  (RGF)
  94. ;
  95. ;01/06/81 Modified to allow use with ALL systems, without
  96. ;      conditional assembly, thru use of disk parameter
  97. ;      block.  By Ron Fowler, Westland, Mich.
  98. ;
  99. ;01/05/81 Modified '+' and '-' commands as follows:
  100. ;        1) + at end of disk now wraps to start
  101. ;        2) - at start wraps back to end
  102. ;        3) argument for + & - now good to 65535
  103. ;                (RGF)
  104. ;
  105. ;01/03/81 Modified logic in console status test to allow
  106. ;      any non-zero value to indicate char waiting.
  107. ;            (RGF)
  108. ;
  109. ;01/02/81 Made compatible with MACRO80 assembler (labels
  110. ;      made unique within 6 chars, and separated multi-
  111. ;      statement lines).  (RGF)
  112. ;
  113. ;11/14/80 Corrected missing conditional in CLCSUB routine
  114. ;      for MICROP or DIGDBL.  Cleaned up file.  (KBP)
  115. ;
  116. ;11/04/80 Forced write type 1 (pre-read and immediate write)
  117. ;      so deblocking BIOS's don't mess up.  Ignore bit 7
  118. ;      in = command unless <nn> form was used.  Display
  119. ;      unprintables as <nn> in V command.  Show user no.
  120. ;      in M command (will always be 00 for 1.4) and only
  121. ;      print parentheses if E5 present.  (BRR)
  122. ;
  123. ;10/30/80 Fixed bug in backspace/control-X.  Corrected more
  124. ;      bit-7 stuff.    Added 'U' command to change user no.
  125. ;      under CP/M 2.x.  Added pauses in help file. (BRR)
  126. ;
  127. ;10/27/80 Added Thinkertoys DBL DENS, Micromation DBL DENS,
  128. ;      Industrial Micro Systems DBL and QUAD DENS.
  129. ;      Fixed several bit-7 problems in MAP and DUMP logic.
  130. ;      Added control-X (CRT erase line) to command input
  131. ;      logic.  (Bruce R. Ratoff, ACGNJ-SIG/M)
  132. ;
  133. ;09/16/80 Fix backspace in line enter routine, add MAXDIR
  134. ;      equate, general cleanup of ASM file. (KBP)
  135. ;
  136. ;06/22/80 Put in 'Q' command.  Fix so 'P' (printer)
  137. ;      mode outputs L/F's.  (WLC)
  138. ;
  139. ;05/21/80 Make sector, track, be decimal, not hex.
  140. ;      Also dis-allow a read until positioned.
  141. ;      (DU otherwise not in sync with CP/M)    (WLC)
  142. ;
  143. ;03/24/80 Mod for Micropolis, Digital Microsystems DD,
  144. ;      and Northstar DD CP/M.  Trap out garbage
  145. ;      during VIEW of file.    By Keith Petersen, W8SDZ
  146. ;
  147. ;02/24/80 Mod login command to not really do log, just
  148. ;      drive select.  (WLC)
  149. ;
  150. ;02/12/80 Mod for heath CP/M.  (WLC)
  151. ;
  152. ;01/08/80 Reposition after 'M' command.  (WLC)
  153. ;
  154. ;01/07/79 Add VIEW command.  (WLC)
  155. ;
  156. ;01/06/80 Rewrite 'F' command.    (WLC)
  157. ;
  158. ;10/10/79 Save regs in BIOS calls, translate input to upper case
  159. ;      add commands: < save sector
  160. ;            > restore sect
  161. ;            / repeat
  162. ;      allow change from-thru.  (WLC)
  163. ;
  164. ;02/25/79 Put sector read into 'S' command.  (WLC)
  165. ;
  166. ;11/26/78 Add disk # to login command.    (WLC)
  167. ;
  168. ;11/12/78 Add login command.  (WLC)
  169. ;
  170. ;08/06/78 Originally written to reconstruct blown
  171. ;      disks on CBBS via remote access.  (WLC)
  172. ;
  173. ;
  174. ;        ----------------
  175. ;Sorry for the lack of comments in the code 
  176. ;portion of this program - it was just hacked
  177. ;together to satisfy my needs, but lots of
  178. ;other people found it useful.    Its external
  179. ;documentation is good, but its sadly lacking
  180. ;comments on the instructions.    (WLC)
  181. ;        ----------------
  182. ;
  183. ;System equates
  184. ;
  185. BASE    EQU    0    ;SET TO 4200H FOR HEATH OR TRS-80 ALTCPM
  186. ;
  187. FCB    EQU    BASE+5CH
  188. BDOS    EQU    BASE+5
  189. PRINT    EQU    9
  190. GVERS    EQU    12
  191. RESETDK EQU    13
  192. SELDK    EQU    14
  193. SRCHF    EQU    17    ;SEARCH FIRST
  194. SUSER    EQU    32
  195. GETDSK    EQU    25
  196. GETDPB    EQU    31
  197. ;
  198. TRNOFF    EQU    15    ;CP/M 1.4 OFFSET FROM BASE
  199.             ;OF BDOS TO SECTRAN ROUTINE
  200. SKWOFF    EQU    1AH    ;CP/M 1.4 OFFSET TO SKEW TABLE
  201. S2OFF    EQU    14    ;OFFSET INTO FCB FOR S2 BYTE
  202. DPBOFF    EQU    3AH    ;CP/M 1.4 OFFSET TO DPB WITHIN BDOS
  203. S2MASK    EQU    0FH    ;MASK FOR EXTENDED RC BITS OF S2
  204. DPBLEN    EQU    15    ;SIZE OF CP/M 2.x DISK PARM BLOCK
  205. ;
  206. ;
  207. ;Define ASCII characters
  208. ;
  209. CR    EQU    0DH    ;CARRIAGE RETURN
  210. LF    EQU    0AH    ;LINE FEED
  211. TAB    EQU    09H    ;TAB
  212. BS    EQU    08H    ;BACKSPACE
  213. ;
  214.     ORG    BASE+100H
  215. ;
  216.     JMP    PASTCK    ;JUMP OVER CLOCK BYTE AND I.D.
  217. ;
  218. CLOCK:    DB    0    ;<---PUT NON-ZERO HERE FOR 4 MHZ CLOCK
  219.     DB    'DU.COM ver 7.7 7/12/81'
  220. ;
  221. PASTCK: LHLD    BDOS+1    ;GET POINTER TO BDOS ENTRY
  222.     MVI    L,0    ;SET HL=BASE OF BDOS
  223.     SPHL        ;PUT STACK THERE
  224.     SHLD    SETSTK+1 ;SAVE FOR LATER LXI SP INSTR.
  225.     MVI    C,GVERS ;GET CP/M VERSION NR
  226.     CALL    BDOS
  227.     MOV    A,H    ;COMBINE THE TWO BYTE...
  228.     ORA    L    ;...VERSION NR FOR A FLAG
  229.     STA    VER2FL    ;SAVE IT
  230.     LXI    H,3000H ;INITIALIZE "Y" COMMAND MEMORY POINTER
  231.     SHLD    YNKADR
  232. ;
  233. ;Set up local jumps to BIOS
  234.     LHLD    BASE+1    ;WARM BOOT POINTER
  235.     LXI    D,3    ;READY FOR ADD
  236.     DAD    D    
  237.     SHLD    VCONST+1
  238.     DAD    D
  239.     SHLD    VCONIN+1
  240.     DAD    D
  241.     SHLD    VCONOT+1
  242.     DAD    D
  243.     SHLD    VLIST+1
  244.     DAD    D    ;PUNCH
  245.     DAD    D    ;RDR
  246.     DAD    D
  247.     SHLD    VHOME+1
  248.     DAD    D
  249.     SHLD    VSELDK+1
  250.     DAD    D
  251.     SHLD    VSETRK+1
  252.     DAD    D
  253.     SHLD    VSTSEC+1
  254.     DAD    D
  255.     SHLD    SETDMA+1
  256.     DAD    D
  257.     SHLD    VREAD+1
  258.     DAD    D
  259.     SHLD    VWRITE+1
  260.     LDA    VER2FL
  261.     ORA    A
  262.     JZ    DOCPM1
  263.     DAD    D    ;LISTST
  264.     DAD    D
  265.     SHLD    VSCTRN+1
  266.     JMP    HELLO
  267. ;
  268. DOCPM1: LHLD    BDOS+1
  269.     MVI    L,0     ;BDOS ON PAGE BOUNDARY
  270.     PUSH    H
  271.     LXI    D,TRNOFF ;CP/M 1.4 SECTRAN ROUTINE OFFSET
  272.     DAD    D
  273.     SHLD    VSCTRN+1
  274.     POP    H
  275.     LXI    D,SKWOFF ;CP/M 1.4 SKEW TABLE OFFSET
  276.     DAD    D
  277.     SHLD    SECTBL     ;SET UP SKEW TABLE POINTER
  278. ;
  279. HELLO:    CALL    ILPRT
  280.     DB    CR,LF,'DISK UTILITY ver 7.7',CR,LF
  281.     DB    'Universal Version',CR,LF
  282.     DB    CR,LF
  283.     DB    'Type ? for help',CR,LF
  284.     DB    'Type X to exit'
  285.     DB    CR,LF,0
  286.     CALL    GETSTP       ;SET UP PARAMETERS
  287.     LXI    H,BASE+80H ;TO INPUT BUFF
  288.     MOV    A,M
  289.     ORA    A
  290.     JZ    PRMPTR    ;NO COMMAND
  291. ;
  292. ;Got initial command, set it up
  293.     MOV    B,A    ;SAVE LENGTH
  294.     DCR    B
  295.     JZ    PRMPTR
  296.     LXI    D,INBUF
  297.     INX    H    ;SKIP LEN
  298.     INX    H    ;SKIP ' '
  299.     CALL    MOVE
  300.     MVI    A,CR
  301.     STAX    D
  302.     LXI    H,INBUF
  303.     JMP    PRMPTI
  304. ;
  305. PRMPTR: XRA    A
  306.     STA    QFLAG
  307.     CALL    RDBUF
  308. ;
  309. PRMPTI: MVI    A,255
  310.     STA    TOGO    ;LOOP COUNT FOR "/"
  311.     STA    TOGO+1
  312. ;
  313. PROMPT    EQU    $
  314. SETSTK: LXI    SP,$-$    ;MODIFIED AT INIT
  315.     XRA    A    ;ZERO 2-UP PRINT
  316.     STA    TWOUP    ;..SWITCH
  317.     MVI    A,1
  318.     STA    FTSW    ;TELL SEARCH NOT TO INCR
  319.     PUSH    H
  320.     LXI    H,BASE+100H
  321.     SHLD    BUFAD    ;FOR RDBYTE
  322.     POP    H
  323.     CALL    CTLCS    ;ABORT?
  324.     JZ    PRMPTR    ;..YES, READ BUFFER
  325. ;
  326. ;Do we have to position in directory after find?
  327.     LDA    FINDFL
  328.     ORA    A
  329.     JNZ    POSDIR    ;POSITION IN DIRECTORY
  330.     MOV    A,M
  331.     CPI    CR
  332.     JZ    PRMPTR
  333.     CPI    ';'    ;LOGICAL CR?
  334.     INX    H
  335.     JZ    PROMPT
  336.     CALL    UPCASE
  337.     STA    DUMTYP    ;TYPE OF DUMP (A,D,H)
  338. ;
  339. ;Command dispatcher
  340. ;
  341.     CPI    '+'    
  342.     JZ     PLUS
  343. ;
  344.     CPI    '-'
  345.     JZ    MINUS
  346. ;
  347.     CPI    '='
  348.     JZ    SEARCH
  349. ;
  350.     CPI    '<'
  351.     JZ    SAVE
  352. ;
  353.     CPI    '>'
  354.     JZ    RESTOR
  355. ;
  356.     CPI    '#'
  357.     JZ    STATS
  358. ;
  359.     CPI    '?'
  360.     JZ    HELP
  361. ;
  362.     CPI    'A'
  363.     JZ    DUMP
  364. ;
  365.     CPI    'C'
  366.     JZ    CHG
  367. ;
  368.     CPI    'D'
  369.     JZ    DUMP
  370. ;
  371.     CPI    'F'
  372.     JZ    POSFIL
  373. ;
  374.     CPI    'G'
  375.     JZ    POS
  376. ;
  377.     CPI    'H'
  378.     JZ    DUMP
  379. ;
  380.     CPI    'L'
  381.     JZ    LOGIN
  382. ;
  383.     CPI    'M'
  384.     JZ    MAP
  385. ;
  386.     CPI    'N'
  387.     JZ    NEWDSK
  388. ;
  389.     CPI    'P'
  390.     JZ    PRNTFF
  391. ;
  392.     CPI    'Q'
  393.     JZ    QUIET
  394. ;
  395.     CPI    'R'
  396.     JZ    DOREAD
  397. ;
  398.     CPI    'S'
  399.     JZ    POS
  400. ;
  401.     CPI    'T'
  402.     JZ    POS
  403. ;
  404.     CPI    'U'    ;******CP/M 2.x ONLY******
  405.     JZ    USER
  406. ;
  407.     CPI    'V'
  408.     JZ    VIEW
  409. ;
  410.     CPI    'W'
  411.     JZ    DORITE
  412. ;
  413.     CPI    'X'
  414.     JZ    BASE
  415. ;
  416.     CPI    'Y'
  417.     JZ    YANK
  418. ;
  419.     CPI    'Z'
  420.     JZ    SLEEP
  421. ;
  422.     CPI    '/'
  423.     JZ    REPEAT
  424. ;
  425. WHAT:    XRA    A
  426.     STA    QFLAG
  427.     CALL    ILPRT
  428.     DB    '?',0
  429.     JMP    PRMPTR
  430. ;
  431. ;Memory full error
  432. ;
  433. MEMFUL: XRA    A
  434.     STA    QFLAG
  435.     CALL    ILPRT
  436.     DB    '+++ Out of memory +++'
  437.     DB    CR,LF,0
  438.     JMP    PRMPTR
  439. ;
  440. ;Print disk statistics
  441. ;
  442. STATS:    PUSH    H
  443.     CALL    ILPRT
  444.     DB    'Disk Information:',CR,LF
  445.     DB    'Tracks:',9,9,0
  446.     LHLD    MAXTRK
  447.     INX    H
  448.     CALL    DEC
  449.     CALL    ILPRT
  450.     DB    CR,LF,'Sec/trk:',9,0
  451.     LHLD    SPT
  452.     CALL    DEC
  453.     CALL    ILPRT
  454.     DB    CR,LF,'Grpsize:',9,0
  455.     LDA    BLM
  456.     INR    A
  457.     MOV    L,A
  458.     MVI    H,0
  459.     CALL    DEC
  460.     CALL    ILPRT
  461.     DB    ' (sectors per group)',CR,LF
  462.     DB    'Tot grps:',9,0
  463.     LHLD    DSM
  464.     CALL    DEC
  465.     CALL    ILPRT
  466.     DB    CR,LF,'Dir entries:',9,0
  467.     LHLD    DRM
  468.     INX    H
  469.     CALL    DEC
  470.     CALL    ILPRT
  471.     DB    CR,LF,'Sys tracks:',9,0
  472.     LHLD    SYSTRK
  473.     CALL    DEC
  474.     CALL    CRLF
  475.     POP    H
  476.     JMP    PROMPT
  477. ;
  478. ;The following command resets the disk
  479. ;system thru CP/M, and may be usable for
  480. ;changing the disk density or format.
  481. ;This can only be done if your BIOS resets
  482. ;the auto-density select parameters at
  483. ;every track-zero access.
  484. ;
  485. NEWDSK: PUSH    H
  486.     MVI    C,RESETDK
  487.     CALL    BDOS
  488.     LDA    DRIVE
  489.     MOV    C,A
  490.     POP    H
  491.     CALL    SELECT
  492.     JMP    PROMPT
  493. ;
  494. ;Quite mode
  495. ;
  496. QUIET:    STA    QFLAG    ;NOW QUIET
  497.     JMP    PROMPT
  498. ;
  499. ;Repeat buffer contents
  500. ;
  501. REPEAT: CALL    DECIN    ;NN SPECIFIED?
  502.     MOV    A,D
  503.     ORA    E
  504.     JZ    NNN    ;NO.
  505.     LHLD    TOGO
  506.     INX    H    ;TEST FOR FIRST TIME
  507.     MOV    A,H
  508.     ORA    L    ;WAS IT 0FFFFH?
  509.     JNZ    NNN    ;NO: COUNTING
  510.     XCHG        ;GET COUNT
  511.     SHLD    TOGO    ;SET COUNT
  512. ;
  513. NNN:    LHLD    TOGO
  514.     XCHG
  515.     LXI    H,INBUF ;READY TO REPEAT
  516.     INX    D    ;TEST FOR 0FFFFH
  517.     MOV    A,D
  518.     ORA    E
  519.     JZ    PROMPT    ;CONTINOUS
  520.     DCX    D    ;COUNT DOWN
  521.     DCX    D    ;MAKE UP FOR PREV INX D
  522.     XCHG
  523.     SHLD    TOGO
  524.     MOV    A,H    ;ALL DONE?
  525.     ORA    L
  526.     XCHG        ;GET BACK INBUF PTR
  527.     JNZ    PROMPT    ;NO, KEEP GOING
  528.     JMP    PRMPTR    ;ALL DONE
  529. ;
  530. ;Set CP/M 2.x user number
  531. ;
  532. USER:    LDA    VER2FL
  533.     ORA    A
  534.     JZ    WHAT
  535.     CALL    DECIN        ;GET REQUESTED USER NO.
  536.     MOV    A,E
  537.     CPI    32        ;VALID?
  538.     JNC    WHAT
  539.     MOV    A,D
  540.     ORA    A
  541.     JNZ    WHAT
  542.     MVI    C,SUSER
  543.     PUSH    H        ;SAVE CHAR POINTER
  544.     CALL    BDOS        ;SET USER NO.
  545.     POP    H
  546.     JMP    PROMPT
  547. ;
  548. ;Toggle print flag
  549. ;
  550. PRNTFF: LDA    PFLAG
  551.     XRI    1
  552.     STA    PFLAG
  553.     JMP    PROMPT
  554. ;
  555. ;Sleep routine, in tenths of a sec
  556. ;
  557. SLEEP:    CALL    HEXIN    ;GET COUNT IF ANY
  558.     MOV    A,E    ;ANY?
  559.     ORA    A
  560.     JNZ    SLEPLP
  561.     MVI    E,10
  562. ;
  563. SLEPLP: LXI    B,8000    ;APPROX .1 SEC @ 2MHz
  564.     LDA    CLOCK
  565.     ORA    A
  566.     JZ    SLEEP2
  567.     LXI    B,16000 ;APPROX .1 SEC @ 4 MHz
  568. ;
  569. SLEEP2: DCX    B
  570.     MOV    A,B
  571.     ORA    C
  572.     JNZ    SLEEP2
  573.     PUSH    D
  574.     CALL    CTLCS
  575.     POP    D
  576.     JZ    PRMPTR
  577.     DCR    E
  578.     JNZ    SLEPLP
  579.     JMP    PROMPT
  580. ;
  581. ;Check for control-C or S
  582. ;
  583. CTLCS:    CALL    CONST
  584.     ORA    A
  585.     JNZ    GETC
  586.     ORI    1    ;NO CHAR, RETN NZ
  587.     RET
  588. ;
  589. GETC:    CALL    CONIN
  590.     ANI    1FH    ;ALLOW ASCII
  591.     CPI    'S'-40H
  592.     CZ    CONIN
  593.     CPI    'C'-40H
  594.     RET        ;0 SET IF CTL-C
  595. ;
  596. ;Find our way at initialization
  597. ;
  598. GETSTP: MVI    C,GETDSK
  599.     CALL    BDOS    ;GET CURNT DSK
  600.     MOV    C,A    ;  WE HAVE TO SELECT
  601.     JMP    SELECT    ;  TO GET THE DPH
  602. ;
  603. LOGIN:    CALL    DOLOG
  604.     JMP    PROMPT
  605. ;
  606. DOLOG:    MOV    A,M    ;DISK REQ?
  607.     LXI    D,0
  608.     CPI    CR
  609.     JZ    LGNODK
  610.     CPI    ';'
  611.     JZ    LGNODK
  612.     CALL    UPCASE
  613.     INX    H
  614.     SUI    'A'
  615.     MOV    C,A
  616. ;
  617. SELECT: PUSH    H
  618.     MOV    A,C
  619.     STA    DRIVE    ;REMEMBER LATER WHERE WE ARE
  620. ;
  621. VSELDK: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  622.     LDA    VER2FL
  623.     ORA    A    ;IF NOT CP/M 2.x ...
  624.     JZ    SELSKP    ;..THEN SKIP THIS JUNK
  625.     MOV    A,H
  626.     ORA    L
  627.     JZ    WHAT    ;SELECT ERROR
  628.     MOV    E,M    ;GET THE SECTOR TABLE PNTR
  629.     INX    H
  630.     MOV    D,M
  631.     INX    H
  632.     XCHG
  633.     SHLD    SECTBL
  634.     LXI    H,8    ;OFFSET TO DPBPTR
  635.     DAD    D
  636.     MOV    A,M    ;PICK UP DPB POINTER
  637.     INX    H    ;  TO USE
  638.     MOV    H,M    ;  AS PARAMETER
  639.     MOV    L,A    ;  TO LOGIT
  640. ;
  641. SELSKP: CALL    LOGIT
  642.     LHLD    SYSTRK    ;RESET TRACK AND SECTOR
  643.     XCHG        ;  TO DIRECTORY
  644.     CALL    SETTRK    ;  ON EVERY
  645.     LXI    D,1    ;  LOGIN
  646.     CALL    SETSEC    ;  CHANGE
  647.     LHLD    PHYSEC    ;THIS LOGIC WILL TELL
  648.     MOV    A,H    ;  IF FIRST SEC
  649.     ORA    L    ;  IS PHYSICAL 0
  650.     STA    FIRST0
  651.     CALL    CLCSUB
  652.     POP    H
  653. ;
  654. LGNODK: CALL    NORITE
  655.     RET
  656. ;
  657. ;Read in the disk directory
  658. ;
  659. REDDIR: PUSH    H
  660.     CALL    NORITE    ;POSITIONING LOST
  661.     LHLD    SYSTRK
  662.     SHLD    CURTRK
  663.     LXI    H,1
  664.     SHLD    CURSEC
  665.     LHLD    DRM    ;GET DIR SIZE FROM DPB
  666.     INX    H    ;MAKE 1-RELATIVE
  667.     CALL    ROTRHL
  668.     CALL    ROTRHL    ;DIVIDE BY 4 (4 NAMES/SECTOR)
  669.     MOV    B,H
  670.     MOV    C,L
  671.     LXI    D,DIRECT ;DMA ADDR
  672. ;
  673. RDIRLP: PUSH    B
  674.     PUSH    D
  675.     MOV    B,D
  676.     MOV    C,E
  677.     LDA    BDOS+2    ;CHECK MEM AVAIL
  678.     DCR    A
  679.     CMP    D
  680.     JC    MEMFUL
  681.     CALL    SETDMA
  682.     LHLD    CURTRK
  683.     XCHG
  684.     CALL    SETTRK
  685.     LHLD    CURSEC
  686.     XCHG
  687.     CALL    SETSEC
  688.     CALL    READ
  689.     CALL    NXTSEC
  690.     POP    D
  691.     POP    B
  692.     LXI    H,80H
  693.     DAD    D
  694.     XCHG
  695.     DCX    B
  696.     MOV    A,B
  697.     ORA    C
  698.     JNZ    RDIRLP
  699.     LXI    B,BASE+80H
  700.     CALL    SETDMA
  701.     POP    H
  702.     RET
  703. ;
  704. ;Map the directory
  705. ;
  706. MAP:    CALL    REDDIR    ;READ IN DIRECTORY
  707.     MVI    C,0    ;INIT START GRP #
  708.     LDA    AL0    ;READ DIR GRP BITS
  709.     CALL    COLECT    ;COLLECT COUNT OF DIR GRPS..
  710.     LDA    AL1    ;..IN REGISTER C
  711.     CALL    COLECT
  712.     MVI    B,0    ;BC NOW HAS A DEFAULT START GRP #
  713.     CALL    HEXIN
  714.     PUSH    H    ;SAVE INBUF PTR
  715.     MOV    A,E    ;GET START
  716.     ORA    D    ;NOTHING?
  717.     JZ    MAPDF    ;..YES, DFLT
  718.     MOV    B,D
  719.     MOV    C,E
  720. ;
  721. MAPDF:    CALL    HEXB
  722.     MVI    A,'-'
  723.     CALL    TYPE
  724.     MVI    A,' '
  725.     STA    DUPFLG
  726.     CALL    GETGRP    ;GET GRP(C) TO HL
  727. ;
  728. MAPCNT: INX    B    ;NEXT GRP #
  729.     PUSH    H
  730.     LHLD    DSM    ;GET HIGHEST GRP #
  731.     INX    H    ;PLUS 1 FOR COMPARISON
  732.     MOV    A,L    ;WHEN BC REACHES DSM+1..
  733.     CMP    C    ;..THEN WE HAVE EXCEEDED..
  734.     JNZ    MAPC1    ;..THE DISK CAPACITY..
  735.     MOV    A,H
  736.     CMP    B
  737. ;
  738. MAPC1:    POP    H
  739.     JZ    MAPEND    ;..AND WE ARE DONE
  740.     PUSH    H
  741.     CALL    GETGRP    ;GET ANOTHER
  742.     POP    D    ;SEE IF SAME
  743.     CALL    CTLCS
  744.     JZ    MAPND2
  745.     MOV    A,D
  746.     CMP    H
  747.     JNZ    MAPDIF
  748.     MOV    A,E
  749.     CMP    L
  750.     JZ    MAPCNT    ;SAME, CONTINUE
  751. ;
  752. ;Different file encountered
  753. MAPDIF: DCX    B
  754.     CALL    HEXB
  755.     INX    B
  756.     XCHG
  757.     CALL    MAPNAM
  758.     JMP    MAPDF
  759. ;
  760. ;End of map
  761. ;
  762. MAPEND: DCX    B    ;GET LAST
  763.     CALL    HEXB
  764.     CALL    MAPNAM
  765.     POP    H
  766.     CALL    CRLF
  767. ;
  768. ;End of map - reposition to previous group
  769. ;
  770. MAPND2: PUSH    H
  771.     LHLD    GROUP
  772.     XCHG
  773.     JMP    POSGP2
  774. ;
  775. ;Print file name pointed to by HL
  776. ;
  777. MAPNAM: CALL    SPACE
  778.     MOV    A,H
  779.     ORA    L    ;NONE?
  780.     JZ    NONAME
  781.     MOV    A,M    ;SEE IF ALLOC
  782.     CPI    0E5H    ;FREE?
  783.     MVI    A,' '
  784.     JNZ    MPNSP1
  785.     MVI    A,'('
  786. ;
  787. MPNSP1: CALL    TYPE
  788.     PUSH    H    ;SAVE POINTER
  789.     MOV    A,M
  790.     CALL    HEX    ;SHOW USER NUMBER
  791.     CALL    SPACE
  792.     INX    H    ;SKIP USER BYTE
  793.     PUSH    B
  794.     MVI    B,8
  795.     CALL    MAPN2
  796.     MVI    A,'.'
  797.     CALL    TYPE
  798.     MVI    B,3
  799.     CALL    MAPN2
  800.     LDA    DUPFLG
  801.     CALL    TYPE    ;SPACE OR STAR
  802.     POP    B
  803.     MOV    A,M    ;GET EXT
  804.     CALL    HEX
  805.     POP    H
  806.     MOV    A,M
  807.     CPI    0E5H
  808.     MVI    A,' '
  809.     JNZ    MPNSP2
  810.     MVI    A,')'
  811. ;
  812. MPNSP2: CALL    TYPE    ;")" IF ERASED FILE
  813.     JMP    FLIP
  814. ;
  815. NONAME: CALL    ILPRT
  816.     DB    '    ++FREE++        ',0
  817. ;
  818. FLIP:    LDA    TWOUP
  819.     XRI    1
  820.     STA    TWOUP
  821.     JZ    CRLF
  822. ;
  823. DELIM:    MVI    A,':'
  824.     CALL    TYPE
  825.     JMP    SPACE
  826. ;
  827. ;Print name, length in B
  828. ;
  829. MAPN2:    MOV    A,M
  830.     ANI    7FH    ;STRIP POSSIBLE 2.x ATTRIBUTE BIT
  831.     INX    H
  832.     CPI    ' '    ;PRINTABLE?
  833.     JC    MAPN2H    ;..NO, IN HEX
  834.     CPI    7EH    ;7E IS LEADIN ON SOME CRTS
  835.     JC    MAPN2A
  836. ;
  837. MAPN2H: CALL    BHEX
  838.     JMP    MAPN2Z
  839. ;
  840. MAPN2A: CALL    TYPE
  841. ;
  842. MAPN2Z: DCR    B
  843.     JNZ    MAPN2
  844.     RET
  845. ;
  846. ;Find which file group (BC) belongs to
  847. ;
  848. GETGRP: LHLD    DRM    ;MAX DIR ENTRY #
  849.     INX    H    ;MAKE 1-RELATIVE
  850.     SHLD    FILECT
  851.     LXI    H,0
  852.     SHLD    MFPTR
  853.     LXI    H,DIRECT
  854. ;
  855. GETGLP: PUSH    H    ;SAVE POINTER TO NAME
  856.     MOV    A,M    ;PICK UP DN BYTE
  857.     CPI    0E5H
  858.     JZ    GETGNF
  859.     LXI    D,14    ;NOW GET RECORD COUNT
  860.     DAD    D    ;  S2 PORTION ..
  861.     MOV    A,M    ;  IS 0 IN CP/M 1.4
  862.     ANI    0FH
  863.     MOV    E,A
  864.     INX    H
  865.     MOV    A,M
  866.     ORA    E
  867.     JZ    GETGNF
  868.     MVI    E,16    ;FIRST SET FOR 8-BIT GRPS
  869.     LDA    DSM+1
  870.     ORA    A
  871.     JZ    SMALGP
  872.     MVI    E,8    ;NOPE, BIG GROUPS
  873. ;
  874. SMALGP: MOV    D,A    ;SAVE GRP SIZE INDICATOR
  875. ;
  876. GETGL2: INX    H    ;POINTING INTO DM FIELD
  877.     CALL    GRPCMP    ;COMPARE BC GP # AGAINST 1 DM FLD
  878.     JNZ    NOTGOT    ;JUMP IF FOUND ONE
  879. ;
  880. ;Found the file
  881. ;
  882.     PUSH    H    ;SAVE GP PTR
  883.     LHLD    MFPTR
  884.     MOV    A,H
  885.     ORA    L
  886.     POP    H
  887.     XTHL        ;GET ENTRY START & SAVE PTR
  888.     JZ    MPFRST
  889.     MVI    A,'*'
  890.     STA    DUPFLG
  891. MPFRST: SHLD    MFPTR
  892.     XTHL        ;AS THEY WERE
  893. NOTGOT: DCR    E    ;ELSE COUNT DOWN
  894.     JNZ    GETGL2    ;GO TEST SOME MORE
  895. ;
  896. GETGNF: POP    H    ;NOT THIS ONE!
  897.     LXI    D,32    ;SO GO TO NEXT
  898.     DAD    D
  899.     XCHG
  900.     LHLD    FILECT    ;THERE IS LIMIT TO EVERYTHING
  901.     DCX    H
  902.     SHLD    FILECT
  903.     MOV    A,H
  904.     ORA    L
  905.     XCHG        ;RE-ALIGN
  906.     JNZ    GETGLP
  907. ;
  908. ;Get the allocation address, if {ny
  909.     LHLD    MFPTR
  910.     RET
  911. ;
  912. ;Yank the current sector into memory at location YNKADR
  913. ;
  914. YANK:    LDA    7    ;GET TOP BYTE OF CCP POINTER
  915.     MOV    B,A
  916.     LDA    YNKADR+1    ;GET TOP BYTE OF MEMORY POINTER
  917.     CMP    B
  918.     JNC    YMFULL    ;IF MEMORY FULL, THEN SAY SO AND ABORT YANK
  919.     LDA    WRFLG    ;CHECK IF A READ HAS BEEN DONE
  920.     ORA    A
  921.     JZ    BADW    ;IF NO READ, THEN CAN'T YANK, SO ABORT YANK
  922.     PUSH    H
  923.     LHLD    YNKADR    ;MOVE SECTOR INTO YANK MEMORY
  924.     XCHG
  925.     LXI    H,BASE+80H
  926.     MVI    B,128
  927.     CALL    MOVE
  928.     CALL    ILPRT    ;TELL WHERE LAST BYTE IS
  929.     DB    'LAST ADDR=',0
  930.     LHLD    YNKADR    ;CALCULATE LAST BYTE
  931.     LXI    B,80H
  932.     DAD    B
  933.     SHLD    YNKADR    ;SAVE LAST BYTE+1 FOR NEXT YANK
  934.     DCX    H
  935.     MOV    A,H
  936.     CALL    HEX
  937.     MOV    A,L
  938.     CALL    HEX
  939.     CALL    ILPRT
  940.     DB    CR,LF,0
  941.     POP    H
  942.     JMP    PROMPT
  943. ;
  944. YMFULL: XRA    A    ;MEMORY FULL, SO SAY SO
  945.     STA    QFLAG    ;SET TO NOT QUIET MODE FIRST
  946.     CALL    ILPRT
  947.     DB    '++YANK MEMORY FULL'
  948.     DB    CR,LF,0
  949.     JMP    PROMPT
  950. ;
  951. ;Save the current sector
  952. ;
  953. SAVE:    LDA    WRFLG
  954.     ORA    A
  955.     JZ    BADW    ;NONE TO SAVE
  956.     PUSH    H
  957.     LXI    H,BASE+80H
  958.     LXI    D,SAVBUF
  959.     MVI    B,128
  960.     CALL    MOVE
  961.     MVI    A,1    ;..SHOW
  962.     STA    SAVEFL    ;..SAVED EXISTS
  963.     POP    H
  964.     JMP    PROMPT
  965. ;
  966. ;Restore the current sector
  967. ;
  968. RESTOR: LDA    SAVEFL
  969.     ORA    A
  970.     JZ    NOSAVE    ;NONE TO SAVE
  971.     PUSH    H
  972.     LXI    H,SAVBUF
  973.     LXI    D,BASE+80H
  974.     MVI    B,128
  975.     CALL    MOVE
  976.     POP    H
  977.     JMP    PROMPT
  978. ;
  979. NOSAVE: XRA    A
  980.     STA    QFLAG
  981.     CALL    ILPRT
  982.     DB    '++NO "<" SAVE COMMAND ISSUED'
  983.     DB    CR,LF,0
  984.     JMP    PRMPTR
  985. ;
  986. ;Move (HL) to (DE) length in B
  987. ;
  988. MOVE:    MOV    A,M
  989.     STAX    D
  990.     INX    H
  991.     INX    D
  992.     DCR    B
  993.     JNZ    MOVE
  994.     RET
  995. ;
  996. NORITE: XRA    A    ;GET 0
  997.     STA    WRFLG    ;CAN'T WRITE NOW
  998.     RET
  999. ;
  1000. ;No match in search, try next char
  1001. ;
  1002. SRNOMT: POP    H
  1003.     CALL    CTLCS    ;ABORT?
  1004.     JNZ    SEARCH    ;..YES
  1005.     LXI    H,INBUF
  1006.     MVI    M,CR
  1007.     JMP    CLCGRP    ;SHOW WHERE STOPPED
  1008. ;
  1009. ;Search for character string
  1010. ;
  1011. SEARCH: PUSH    H    ;SAVE STRING POINTER
  1012. ;
  1013. SRCHL:    CALL    RDBYTE    ;GET A BYTE
  1014.     MOV    B,A    ;SAVE IT
  1015.     MOV    A,M    ;CHECK NEXT MATCH CHAR.
  1016.     CPI    '<'    ;WILL IT BE HEX?
  1017.     MOV    A,B    ;RESTORE DISK CHAR
  1018.     JZ    SRCHL1
  1019.     ANI    7FH    ;NEXT CHAR IS ASCII...STRIP BIT 7
  1020. ;
  1021. SRCHL1: PUSH    PSW
  1022.     CALL    GETVAL    ;GET SEARCH VALUE
  1023.     MOV    B,A
  1024.     POP    PSW
  1025.     CMP    B    ;MATCH?
  1026.     JNZ    SRNOMT    ;NO MATCH
  1027.     INX    H
  1028.     MOV    A,M    ;DONE?
  1029.     CPI    CR
  1030.     JZ    SREQU
  1031.     CPI    ';'
  1032.     JNZ    SRCHL
  1033. ;
  1034. ;Got match
  1035. SREQU:    XRA    A
  1036.     STA    QFLAG
  1037.     CALL    ILPRT
  1038.     DB    '= AT ',0
  1039.     LDA    BUFAD
  1040.     ANI    7FH
  1041.     CALL    HEX
  1042.     CALL    CRLF
  1043.     JMP    CLCGRP
  1044. ;
  1045. ;Get value from input buffer
  1046. ;
  1047. GETVAL: MOV    A,M
  1048.     CPI    '<'    ;HEX ESCAPE?
  1049.     RNZ        ;NO, RETURN
  1050. ;"<<" means one "<"
  1051.     INX    H
  1052.     MOV    A,M
  1053.     CPI    '<'
  1054.     RZ
  1055. ;Got hex
  1056.     PUSH    D
  1057.     CALL    HEXIN    ;GET VALUE
  1058.     CPI    '>'    ;PROPER DELIM?
  1059.     MOV    A,E    ;GET VALUE
  1060.     POP    D
  1061.     JNZ    WHAT    ;ERROR
  1062.     RET
  1063. ;
  1064. ;Read a byte at a time
  1065. ;
  1066. RDBYTE: PUSH    H
  1067.     LDA    FTSW    ;FIRST READ?
  1068.     ORA    A
  1069.     JNZ    READ1
  1070.     LHLD    BUFAD
  1071.     MOV    A,L
  1072.     ORA    A    ;IN BUFFER?
  1073.     JM    NORD    ;YES, SKIP READ
  1074. ;
  1075. ;Have to read
  1076.     CALL    NXTSEC
  1077. ;
  1078. READ1:    XRA    A
  1079.     STA    FTSW    ;NOT FIRST READ
  1080.     LHLD    CURSEC
  1081.     XCHG
  1082.     CALL    SETSEC
  1083.     LHLD    CURTRK
  1084.     XCHG
  1085.     CALL    SETTRK
  1086.     CALL    READ
  1087.     CALL    CLCSUB
  1088.     LXI    H,BASE+80H
  1089. ;
  1090. NORD:    MOV    A,M
  1091.     INX    H
  1092.     SHLD    BUFAD
  1093.     POP    H
  1094.     RET
  1095. ;
  1096. ;View the file in ASCII starting at
  1097. ;current sector, stepping thru the disk
  1098. ;
  1099. VIEW:    LDA    WRFLG
  1100.     ORA    A
  1101.     JZ    BADDMP
  1102.     CALL    HEXIN    ;GET DISPL IF ANY
  1103.     PUSH    H
  1104.     MOV    A,E
  1105.     ORA    A
  1106.     JNZ    VIEWLP
  1107.     INR    E    ;DFLT=1
  1108. ;
  1109. VIEWLP: LXI    H,BASE+80H ;TO DATA
  1110. ;
  1111. VEWCHR: CALL    CTLCS
  1112.     JZ    VEWEND
  1113.     MOV    A,M
  1114.     CPI    1AH
  1115.     JZ    VEWEOF
  1116.     ANI    7FH
  1117.     CPI    7EH
  1118.     JNC    VIEWHX    ;SHOW RUBOUT AND TILDE AS HEX
  1119.     CPI    ' '
  1120.     JNC    VIEWPR
  1121.     CPI    CR
  1122.     JZ    VIEWPR
  1123.     CPI    LF
  1124.     JZ    VIEWPR
  1125.     CPI    TAB
  1126.     JZ    VIEWPR
  1127. ;
  1128. VIEWHX: MOV    A,M    ;NOT ASCII...PRINT AS <NN>
  1129.     CALL    BHEX
  1130.     JMP    VIEWNP
  1131. ;
  1132. VIEWPR: CALL    TYPE
  1133. ;
  1134. VIEWNP: INR    L
  1135.     JNZ    VEWCHR
  1136.     DCR    E
  1137.     JZ    VEWEND
  1138.     PUSH    D    ;SAVE COUNT
  1139.     CALL    NXTSEC
  1140.     LHLD    CURSEC
  1141.     XCHG
  1142.     CALL    SETSEC    
  1143.     LHLD    CURTRK
  1144.     XCHG
  1145.     CALL    SETTRK
  1146.     CALL    READ
  1147.     POP    D    ;RESTORE COUNT
  1148.     JMP    VIEWLP
  1149. ;
  1150. VEWEOF: CALL    ILPRT
  1151.     DB    CR,LF,TAB,'++EOF++',CR,LF,0
  1152. ;
  1153. VEWEND: POP    H
  1154.     CALL    CRLF
  1155.     JMP    CLCGRP
  1156. ;
  1157. ;Dump in hex or ASCII
  1158. ;
  1159. DUMP:    LDA    WRFLG
  1160.     ORA    A
  1161.     JNZ    DUMPOK
  1162. ;
  1163. BADDMP: XRA    A
  1164.     STA    QFLAG
  1165.     CALL    ILPRT
  1166.     DB    '++Can''t dump, no sector read.',CR,LF,0
  1167. ;
  1168. EXPL:    XRA    A
  1169.     STA    QFLAG
  1170.     CALL    ILPRT
  1171.     DB    'Use G command following F,',CR,LF
  1172.     DB    'or R or S following T',CR,LF,0
  1173.     JMP    PRMPTR
  1174. ;
  1175. DUMPOK: MOV    A,M
  1176.     CPI    ';'
  1177.     JZ    DUMPDF    ;DFLT
  1178.     CPI    CR
  1179.     JNZ    DMPNDF
  1180. ;
  1181. ;Use default
  1182. DUMPDF: LXI    B,BASE+80H
  1183.     LXI    D,0FFH
  1184.     JMP    DUMP1
  1185. ;
  1186. DMPNDF: CALL    DISP
  1187.     MOV    B,D
  1188.     MOV    C,E
  1189.     CPI    CR
  1190.     JZ    DUMP1
  1191.     CPI    ';'
  1192.     JZ    DUMP1
  1193.     INX    H    ;SKIP ','
  1194.     CALL    DISP
  1195. ;
  1196. ;BC = start, DE = end
  1197. ;
  1198. DUMP1:    PUSH    H    ;SAVE COMMAND POINTER
  1199.     MOV    H,B
  1200.     MOV    L,C
  1201. ;
  1202. DUMPLP: MOV    A,L
  1203.     ANI    7FH
  1204.     CALL    HEX
  1205.     CALL    SPACE
  1206.     CALL    SPACE
  1207.     LDA    DUMTYP
  1208.     CPI    'A'
  1209.     JZ    DUMPAS
  1210.     PUSH    H    ;SAVE START
  1211. ;
  1212. DHEX:    MOV    A,M
  1213.     CALL    HEX
  1214.     MOV    A,L
  1215.     ANI    3
  1216.     CPI    3
  1217.     CZ    SPACE
  1218.     MOV    A,L
  1219.     ANI    7
  1220.     CPI    7
  1221.     CZ    SPACE
  1222.     MOV    A,E
  1223.     CMP    L
  1224.     JZ    DPOP
  1225.     INX    H
  1226.     MOV    A,L
  1227.     ANI    0FH
  1228.     JNZ    DHEX
  1229. ;
  1230. DPOP:    CALL    CTLCS
  1231.     JZ    PRMPTR
  1232.     LDA    DUMTYP
  1233.     CPI    'H'
  1234.     JZ    DNOAS    ;HEX ONLY
  1235.     POP    H    ;GET START ADDR
  1236. ;
  1237. DUMPAS: CALL    ASTER
  1238. ;
  1239. DCHR:    MOV    A,M
  1240.     ANI    7FH
  1241.     CPI    ' '
  1242.     JC    DPER
  1243.     CPI    7EH
  1244.     JC    DOK
  1245. ;
  1246. DPER:    MVI    A,'.'
  1247. ;
  1248. DOK:    CALL    TYPE
  1249.     MOV    A,E
  1250.     CMP    L
  1251.     JZ    DEND
  1252.     INX    H
  1253.     MOV    A,L
  1254.     ANI    0FH
  1255.     JNZ    DCHR
  1256. ;
  1257. DEND:    CALL    ASTER
  1258.     CALL    CRLF
  1259.     PUSH    D
  1260.     CALL    CTLCS
  1261.     POP    D
  1262.     JZ    PRMPTR
  1263.     MOV    A,E
  1264.     CMP    L
  1265.     JNZ    DUMPLP
  1266.     POP    H
  1267.     JMP    PROMPT
  1268. ;
  1269. DNOAS:    POP    B
  1270.     CALL    CRLF
  1271.     MOV    A,E
  1272.     CMP    L
  1273.     JNZ    DUMPLP
  1274.     POP    H
  1275.     JMP    PROMPT
  1276. ;
  1277. ;Position
  1278. ;
  1279. POS:    PUSH    PSW
  1280.     MOV    A,M
  1281.     CPI    ';'
  1282.     JZ    POSINQ
  1283.     CPI    CR
  1284.     JNZ    POSOK
  1285. ;
  1286. POSINQ: POP    PSW
  1287.     JMP    INQ
  1288. ;
  1289. POSOK:    POP    PSW
  1290.     CPI    'T'
  1291.     JZ    POSTKD
  1292.     CPI    'S'
  1293.     JZ    POSSCD
  1294.     CPI    'G'
  1295.     JZ    POSGPH
  1296.     JMP    WHAT
  1297. ;
  1298. POSTKD: CALL    DECIN
  1299. ;
  1300. POSTRK: PUSH    H
  1301.     LHLD    MAXTRK
  1302.     CALL    SUBDE
  1303.     POP    H
  1304.     JC    OUTLIM
  1305.     CALL    SETTRK
  1306.     CALL    NORITE    ;TRACK DOESN'T READ
  1307.     MVI    A,1
  1308.     STA    NOTPOS    ;SHOW NOT POSITIONED
  1309.     JMP    CLCGRP
  1310. ;
  1311. POSSCD: CALL    DECIN
  1312.     MOV    A,D
  1313.     ORA    E
  1314.     JZ    WHAT    ;DON'T ALLOW SECTOR 0
  1315. ;
  1316. POSSEC: PUSH    H
  1317.     LHLD    SPT
  1318.     CALL    SUBDE
  1319.     POP    H
  1320.     JC    WHAT
  1321.     CALL    SETSEC
  1322.     CALL    READ
  1323.     XRA    A
  1324.     STA    NOTPOS    ;POSITIONED OK
  1325. ;
  1326. CLCGRP: CALL    CLCSUB
  1327.     JMP    INQ
  1328. ;
  1329. ;Calculate group from track and sector
  1330. ;
  1331. CLCSUB: PUSH    H
  1332.     LHLD    SYSTRK
  1333.     XCHG
  1334.     LHLD    CURTRK
  1335.     CALL    SUBDE
  1336.     XCHG
  1337.     LHLD    SPT
  1338.     CALL    MULT
  1339.     XCHG
  1340.     LHLD    CURSEC
  1341.     DCX    H
  1342.     DAD    D
  1343.     LDA    BLM
  1344.     MOV    B,A
  1345.     MOV    A,L
  1346.     ANA    B
  1347.     STA    GRPDIS
  1348.     LDA    BSH
  1349.     MOV    B,A
  1350. ;
  1351. CLCLOP: CALL    ROTRHL
  1352.     DCR    B
  1353.     JNZ    CLCLOP
  1354.     SHLD    GROUP
  1355.     POP    H
  1356.     RET
  1357. ;
  1358. ;Position in the directory after a find
  1359. ;(Does not work in CP/M-2.x)
  1360. ;
  1361. POSDIR: PUSH    H    ;SAVE INBUF
  1362.     LHLD    BSH
  1363.     XRA    A
  1364.     STA    FINDFL    ;CANCEL POS REQ
  1365.     LDA    DIRPOS    ;GET POSITION
  1366.     RAR
  1367.     RAR
  1368.     PUSH    PSW
  1369.     ANA    H
  1370.     STA    GRPDIS
  1371.     POP    PSW
  1372. ;
  1373. POSDLP: RAR
  1374.     DCR    L
  1375.     JNZ    POSDLP
  1376.     ANI    1    ;GET GROUP
  1377.     MOV    L,A    ;SETUP FOR POSGP2
  1378.     MVI    H,0
  1379.     SHLD    GROUP
  1380.     XCHG
  1381.     JMP    POSGP2    ;POSITION TO IT
  1382. ;
  1383. POSGPH: CALL    HEXIN
  1384. ;
  1385. POSGRP: PUSH    H
  1386.     LHLD    DSM
  1387.     CALL    SUBDE
  1388.     POP    H
  1389.     JC    OUTLIM
  1390.     XCHG
  1391.     SHLD    GROUP
  1392.     XCHG
  1393.     XRA    A
  1394.     STA    GRPDIS
  1395.     PUSH    H
  1396. ;
  1397. POSGP2: CALL    GTKSEC
  1398.     CALL    SETTRK
  1399.     XCHG
  1400.     CALL    SETSEC
  1401.     CALL    READ
  1402.     XRA    A
  1403.     STA    NOTPOS    ;NOW POSITIONED
  1404.     POP    H
  1405.     JMP    INQ
  1406. ;
  1407. GTKSEC: MOV    H,D
  1408.     MOV    L,E
  1409.     LDA    BSH
  1410. ;
  1411. GLOOP:    DAD    H
  1412.     DCR    A
  1413.     JNZ    GLOOP
  1414.     LDA    GRPDIS
  1415.     ADD    L    ;CAN'T CARRY
  1416.     MOV    L,A
  1417. ;
  1418. ;Divide by nr of sectors, quotient=track, remainder=sector
  1419. ;
  1420.     XCHG
  1421.     LHLD    SPT
  1422.     CALL    NEG
  1423.     XCHG
  1424.     LXI    B,0
  1425. ;
  1426. DIVLP:    INX    B
  1427.     DAD    D
  1428.     JC    DIVLP
  1429.     DCX    B
  1430.     XCHG
  1431.     LHLD    SPT
  1432.     DAD    D
  1433.     PUSH    H
  1434.     LHLD    SYSTRK
  1435.     DAD    B
  1436.     XCHG
  1437.     POP    H
  1438.     INX    H
  1439.     RET
  1440. ;
  1441. POSFIL: CALL    NORITE
  1442.     MVI    A,1
  1443.     STA    FINDFL    ;SO WE POSITION LATER
  1444.     LXI    D,FCB
  1445.     XRA    A    ;LOGGED IN DISK
  1446.     STAX    D
  1447.     INX    D
  1448.     MVI    B,8
  1449.     CALL    MVNAME
  1450.     MVI    B,3
  1451.     CALL    MVNAME
  1452.     LXI    D,FCB
  1453.     MVI    C,SRCHF
  1454.     PUSH    H
  1455.     CALL    BDOS
  1456.     INR    A
  1457.     JNZ    FLOK
  1458.     STA    DIRPOS    ;GRP 0 IF NOT FOUND
  1459.     CALL    ILPRT
  1460.     DB    '++FILE NOT FOUND',CR,LF,0
  1461.     POP    H
  1462.     JMP    PROMPT
  1463. ;
  1464. FLOK:    DCR    A
  1465.     STA    DIRPOS    ;SAVE POS. IN DIR
  1466.     ANI    3
  1467.     MOV    L,A
  1468.     MVI    H,0
  1469.     DAD    H    ;X32 BYTES/ENTRY
  1470.     DAD    H
  1471.     DAD    H
  1472.     DAD    H
  1473.     DAD    H
  1474.     LXI    D,BASE+80H
  1475.     DAD    D    ;HL POINTS TO ENTRY
  1476.     LXI    D,32
  1477.     XCHG
  1478.     DAD    D
  1479.     XCHG
  1480.     MVI    A,'D'
  1481.     STA    DUMTYP
  1482.     JMP    DUMPLP    ;WHICH POPS H
  1483. ;
  1484. MVNAME: MOV    A,M
  1485.     CPI    '.'
  1486.     JZ    MVIPAD
  1487.     CPI    CR
  1488.     JZ    PAD
  1489.     CPI    ';'
  1490.     JZ    PAD
  1491.     CALL    UPCASE
  1492.     STAX    D
  1493.     INX    H
  1494.     INX    D
  1495.     DCR    B
  1496.     JNZ    MVNAME
  1497.     MOV    A,M
  1498.     CPI    CR
  1499.     RZ
  1500.     CPI    ';'
  1501.     RZ
  1502.     INX    H
  1503.     CPI    '.'
  1504.     RZ
  1505.     JMP    WHAT
  1506. ;
  1507. MVIPAD: INX    H
  1508. ;
  1509. PAD:    MVI    A,' '
  1510.     STAX    D
  1511.     INX    D
  1512.     DCR    B
  1513.     JNZ    PAD
  1514.     RET
  1515. ;
  1516. PLUS:    LXI    D,1    ;DFLT TO 1 SECT
  1517.     MOV    A,M    ;GET NEXT CHAR
  1518.     CPI    CR    ;CR?
  1519.     JZ    PLUSGO    ;..YES, DFLT TO 1
  1520.     CPI    ';'
  1521.     JZ    PLUSGO
  1522.     CALL    HEXIN    ;GET #
  1523.     MOV    A,D
  1524.     ORA    E
  1525.     JZ    WHAT
  1526. ;
  1527. PLUSGO: CALL    NXTSEC
  1528.     DCX    D    ;MORE TO GO?
  1529.     MOV    A,D
  1530.     ORA    E
  1531.     JNZ    PLUSGO    ;..YES
  1532. ;
  1533. ;Ok, incremented to sector.  Setup and read
  1534. ;
  1535. PLUSMI: PUSH    H
  1536.     LHLD    CURSEC
  1537.     XCHG
  1538.     CALL    SETSEC
  1539.     LHLD    CURTRK
  1540.     XCHG
  1541.     CALL    SETTRK
  1542.     POP    H
  1543.     CALL    READ
  1544.     JMP    CLCGRP
  1545. ;
  1546. MINUS:    LXI    D,1    ;SET DFLT
  1547.     MOV    A,M    ;GET CHAR
  1548.     CPI    CR    ;CR?
  1549.     JZ    MINGO    ;..YES, DFLT=1
  1550.     CPI    ';'
  1551.     JZ    MINGO
  1552.     CALL    HEXIN    ;..NO, GET ##
  1553.     MOV    A,D
  1554.     ORA    E
  1555.     JZ    WHAT
  1556. ;
  1557. MINGO:    PUSH    H
  1558.     LHLD    CURSEC
  1559.     DCX    H
  1560.     MOV    A,H
  1561.     ORA    L
  1562.     JNZ    MINOK
  1563.     LHLD    CURTRK
  1564.     MOV    A,H
  1565.     ORA    L
  1566.     JNZ    SEASH
  1567.     LHLD    MAXTRK    ;WRAP TO END OF DISK
  1568.     SHLD    CURTRK
  1569.     LHLD    MAXSEC
  1570.     JMP    MINOK
  1571. ;
  1572. SEASH:    DCX    H
  1573.     SHLD    CURTRK
  1574.     LHLD    SPT
  1575. ;
  1576. MINOK:    SHLD    CURSEC
  1577.     POP    H
  1578.     DCX    D
  1579.     MOV    A,D
  1580.     ORA    E
  1581.     JNZ    MINGO
  1582.     JMP    PLUSMI
  1583. ;
  1584. ;Go to next sector
  1585. ;
  1586. NXTSEC: PUSH    H
  1587.     PUSH    D
  1588.     LHLD    CURSEC
  1589.     INX    H
  1590.     XCHG
  1591.     LHLD    SPT
  1592.     CALL    SUBDE
  1593.     XCHG
  1594.     JNC    NEXTOK
  1595.     LHLD    CURTRK
  1596.     INX    H
  1597.     XCHG
  1598.     LHLD    MAXTRK
  1599.     CALL    SUBDE
  1600.     JNC    TRASK
  1601.     LXI    D,0    ;WRAP TO START OF DISK
  1602. ;
  1603. TRASK:    XCHG
  1604.     SHLD    CURTRK
  1605.     LXI    H,1
  1606. ;
  1607. NEXTOK: SHLD    CURSEC
  1608.     POP    D
  1609.     POP    H
  1610.     RET
  1611. ;
  1612. ;Tell what group, displacement, track, sector, physical sector
  1613. ;
  1614. INQ:    CALL    INQSUB
  1615.     JMP    PROMPT
  1616. ;
  1617. ;Position inquiry subroutine
  1618. ;Executed via: G S or T (with no operands)
  1619. ;
  1620. INQSUB: PUSH    H
  1621.     LHLD    SYSTRK
  1622.     XCHG
  1623.     LHLD    CURTRK
  1624.     CALL    SUBDE
  1625.     JC    NOGRP
  1626.     CALL    ILPRT
  1627.     DB    'G=',0
  1628.     LHLD    GROUP
  1629.     MOV    B,H
  1630.     MOV    C,L
  1631.     CALL    HEXB
  1632.     MVI    A,':'
  1633.     CALL    TYPE
  1634.     LDA    GRPDIS
  1635.     CALL    HEX
  1636.     MVI    A,','
  1637.     CALL    TYPE
  1638. ;
  1639. NOGRP:    CALL    ILPRT
  1640.     DB    ' T=',0
  1641.     LHLD    CURTRK
  1642.     CALL    DEC
  1643.     CALL    ILPRT
  1644.     DB    ', S=',0
  1645.     LHLD    CURSEC
  1646.     CALL    DEC
  1647.     CALL    ILPRT
  1648.     DB    ', PS=',0
  1649.     LHLD    PHYSEC
  1650.     CALL    DEC
  1651.     CALL    CRLF
  1652.     POP    H
  1653.     RET
  1654. ;
  1655. CHG:    MOV    A,M    ;GET TYPE (HEX, ASCII)
  1656.     CALL    UPCASE
  1657.     PUSH    PSW    ;SAVE "H" OR "A"
  1658.     INX    H
  1659.     CALL    DISP    ;GET, VALIDATE DISP TO DE
  1660.     INX    H
  1661.     LXI    B,0    ;SHOW NO 'THRU' ADDR
  1662.     CPI    '-'    ;TEST DELIM FR. DISP
  1663.     JNZ    CHGNTH    ;NO THRU
  1664.     PUSH    D    ;SAVE FROM
  1665.     CALL    DISP    ;GET THRU
  1666.     INX    H    ;SKIP END DELIM
  1667.     MOV    B,D
  1668.     MOV    C,E    ;BC = THRU
  1669.     POP    D    ;GET FROM
  1670.     JMP    CHGAH
  1671. ;
  1672. CHGNTH: CPI    ','
  1673.     JNZ    WHAT
  1674. ;
  1675. CHGAH:    POP    PSW
  1676.     CPI    'H'
  1677.     JZ    CHGHEX
  1678.     CPI    'A'
  1679.     JNZ    WHAT
  1680. ;
  1681. ;Change ASCII
  1682. CHGALP: MOV    A,M
  1683.     CPI    CR
  1684.     JZ    PROMPT
  1685.     CPI    ';'
  1686.     JZ    PROMPT
  1687.     LDAX    D
  1688.     CPI    ' '
  1689.     JC    CHGAHX
  1690.     CPI    7EH
  1691.     JNC    CHGAHX
  1692.     JMP    CHGA2
  1693. ;
  1694. CHGAHX: CALL    BHEX
  1695.     JMP    CHGA3
  1696. ;
  1697. CHGA2:    CALL    TYPE
  1698. ;
  1699. CHGA3:    SHLD    BACK    ;IN CASE "THRU"
  1700.     CALL    GETVAL    ;ASCII OR <HEX>
  1701.     STAX    D    ;UPDATE CHAR
  1702.     INX    H    ;TO NEXT INPUT CHAR
  1703. ;See if 'THRU' requested
  1704.     MOV    A,C
  1705.     ORA    A
  1706.     JZ    CHANTH
  1707.     CMP    E    ;DONE?..
  1708.     JZ    PROMPT    ;..YES
  1709.     LHLD    BACK
  1710. ;
  1711. CHANTH: INR    E
  1712.     JNZ    CHGALP
  1713.     MOV    A,M
  1714.     CPI    CR
  1715.     JZ    PROMPT
  1716.     CPI    ';'
  1717.     JZ    PROMPT
  1718.     JMP    WHAT
  1719. ;
  1720. ;Change hex
  1721. ;
  1722. CHGHCM: INX    H
  1723. ;
  1724. CHGHEX: MOV    A,M
  1725.     CPI    CR
  1726.     JZ    PROMPT
  1727.     CPI    ';'
  1728.     JZ    PROMPT
  1729.     CPI    ','    ;DELIM?
  1730.     JZ    CHGHCM
  1731.     PUSH    D
  1732.     SHLD    HEXAD    ;IN CASE 'THRU'
  1733.     CALL    HEXIN    ;POSITIONS TO DELIM
  1734.     MOV    A,E    ;GET VALUE
  1735.     POP    D    ;..ADDR
  1736.     PUSH    PSW    ;SAVE VALUE
  1737.     LDAX    D    ;GET OLD
  1738.     CALL    HEX    ;ECHO IN HEX
  1739.     POP    PSW    ;GET NEW
  1740.     STAX    D    ;SAVE NEW
  1741.     MOV    A,C    ;SEE IF 'THRU'
  1742.     ORA    A
  1743.     JZ    CHHNTH    ;..NO.
  1744.     CMP    E    ;..YES, DONE?
  1745.     JZ    PROMPT
  1746.     LHLD    HEXAD    ;..NO: MORE
  1747. ;
  1748. CHHNTH: INR    E
  1749.     JNZ    CHGHEX
  1750.     MOV    A,M
  1751.     CPI    CR
  1752.     JZ    PROMPT
  1753.     CPI    ';'
  1754.     JZ    PROMPT
  1755.     JMP    WHAT
  1756. ;
  1757. DOREAD: LDA    NOTPOS
  1758.     ORA    A
  1759.     JNZ    CANTRD
  1760.     CALL    READ
  1761.     JMP    PROMPT
  1762. ;
  1763. CANTRD: XRA    A
  1764.     STA    QFLAG    ;NOT QUIET
  1765.     CALL    ILPRT
  1766.     DB    '++Can''t read - not positioned',CR,LF
  1767.     DB    'Position by:',CR,LF
  1768.     DB    9,'Track then Sector, or',CR,LF
  1769.     DB    9,'Group',CR,LF,0
  1770.     JMP    PROMPT
  1771. ;
  1772. DORITE: CALL    WRITE
  1773.     JMP    PROMPT
  1774. ;
  1775. BHEX:    PUSH    PSW
  1776.     MVI    A,'<'
  1777.     CALL    TYPE
  1778.     POP    PSW
  1779.     CALL    HEX
  1780.     MVI    A,'>'
  1781.     CALL    TYPE
  1782.     RET
  1783. ;
  1784. HEXB:    LDA    DSM+1
  1785.     ORA    A
  1786.     JZ    HEXX
  1787.     MOV    A,B
  1788.     CALL    HEX
  1789. ;
  1790. HEXX:    MOV    A,C
  1791. ;
  1792. HEX:    PUSH    PSW
  1793.     RAR
  1794.     RAR
  1795.     RAR
  1796.     RAR
  1797.     CALL    NIBBL
  1798.     POP    PSW
  1799. ;
  1800. NIBBL:    ANI    0FH
  1801.     CPI    10
  1802.     JC    HEXNU
  1803.     ADI    7
  1804. ;
  1805. HEXNU:    ADI    '0'
  1806.     JMP    TYPE
  1807. ;
  1808. ;Decimal output routine
  1809. ;
  1810. DEC:    PUSH    B
  1811.     PUSH    D
  1812.     PUSH    H
  1813.     LXI    B,-10
  1814.     LXI    D,-1
  1815. ;
  1816. DECOU2: DAD    B
  1817.     INX    D
  1818.     JC    DECOU2
  1819.     LXI    B,10
  1820.     DAD    B
  1821.     XCHG
  1822.     MOV    A,H
  1823.     ORA    L
  1824.     CNZ    DEC
  1825.     MOV    A,E
  1826.     ADI    '0'
  1827.     CALL    TYPE
  1828.     POP    H
  1829.     POP    D
  1830.     POP    B
  1831.     RET
  1832. ;
  1833. SPACE:    MVI    A,' '
  1834.     JMP    TYPE
  1835. ;
  1836. ASTER:    MVI    A,'*'
  1837.     JMP    TYPE
  1838. ;
  1839. ;Inline print routine
  1840. ;
  1841. ILPRT:    XTHL
  1842. ;
  1843. ILPLP:    CALL    CTLCS    ;ABORT?
  1844.     JZ    PRMPTR
  1845.     MOV    A,M
  1846.     CPI    1    ;PAUSE?
  1847.     JNZ    ILPOK
  1848.     CALL    CONIN
  1849.     CPI    3    ;ABORT?
  1850.     JZ    PRMPTR
  1851.     JMP    ILPNX
  1852. ;
  1853. ILPOK:    CALL    TYPE
  1854. ;
  1855. ILPNX:    INX    H
  1856.     MOV    A,M
  1857.     ORA    A
  1858.     JNZ    ILPLP
  1859.     INX    H
  1860.     XTHL
  1861.     RET
  1862. ;
  1863. ;DISP calls HEXIN, and validates a sector
  1864. ;displacement, then converts it to an address
  1865. ;
  1866. DISP:    CALL    HEXIN
  1867.     PUSH    PSW    ;SAVE DELIMITER
  1868.     MOV    A,D
  1869.     ORA    A
  1870.     JNZ    BADISP
  1871.     MOV    A,E
  1872.     ORA    A
  1873.     JM    BADISP
  1874.     ADI    80H    ;TO POINT TO BUFFER AT BASE+80H
  1875.     MOV    E,A
  1876.     MVI    D,BASE/256
  1877.     POP    PSW    ;GET DELIM
  1878.     RET
  1879. ;
  1880. BADISP: XRA    A
  1881.     STA    QFLAG
  1882.     CALL    ILPRT
  1883.     DB    '++BAD DISPLACEMENT (NOT 0-7F)'
  1884.     DB    CR,LF,0
  1885.     JMP    PRMPTR
  1886. ;
  1887. HEXIN:    LXI    D,0
  1888.     MOV    A,M
  1889.     CPI    '#'    ;DECIMAL?
  1890.     JZ    HDIN    ;MAKE DECIMAL
  1891. ;
  1892. HINLP:    MOV    A,M
  1893.     CALL    UPCASE
  1894.     CPI    CR
  1895.     RZ
  1896.     CPI    ';'
  1897.     RZ
  1898.     CPI    ','
  1899.     RZ
  1900.     CPI    '-'    ;'THRU'?
  1901.     RZ
  1902.     CPI    '>'
  1903.     RZ
  1904.     INX    H
  1905.     CPI    '0'
  1906.     JC    WHAT
  1907.     CPI    '9'+1
  1908.     JC    HINNUM
  1909.     CPI    'A'
  1910.     JC    WHAT
  1911.     CPI    'F'+1
  1912.     JNC    WHAT
  1913.     SUI    7
  1914. ;
  1915. HINNUM: SUI    '0'
  1916.     XCHG
  1917.     DAD    H
  1918.     DAD    H
  1919.     DAD    H
  1920.     DAD    H
  1921.     ADD    L
  1922.     MOV    L,A
  1923.     XCHG
  1924.     JMP    HINLP
  1925. ;
  1926. HDIN:    INX    H    ;SKIP '.'
  1927. ;
  1928. DECIN:    LXI    D,0
  1929. ;
  1930. DINLP:    MOV    A,M
  1931.     CALL    UPCASE
  1932.     CPI    CR
  1933.     RZ
  1934.     CPI    ';'
  1935.     RZ
  1936.     CPI    ','
  1937.     RZ
  1938.     CPI    '-'    ;'THRU'?
  1939.     RZ
  1940.     INX    H
  1941.     CPI    '0'
  1942.     JC    WHAT
  1943.     CPI    '9'+1
  1944.     JNC    WHAT
  1945.     SUI    '0'
  1946.     PUSH    H
  1947.     MOV    H,D
  1948.     MOV    L,E
  1949.     DAD    H    ;X2
  1950.     DAD    H    ;X4
  1951.     DAD    D    ;X5
  1952.     DAD    H    ;X10
  1953.     ADD    L
  1954.     MOV    L,A
  1955.     MOV    A,H
  1956.     ACI    0
  1957.     MOV    H,A
  1958.     XCHG
  1959.     POP    H
  1960.     JMP    DINLP
  1961. ;
  1962. ;Read in a console buffer full
  1963. ;
  1964. RDBUF:    CALL    ILPRT
  1965.     DB    CR,LF,':',0
  1966. ;
  1967. RDBF1:    LXI    H,INBUF
  1968.     MVI    B,0
  1969. ;
  1970. RDBLP:    CALL    CONIN
  1971.     MOV    C,A    ;SAVE FOR BS TEST
  1972. ;
  1973. ;Evaluate control characters
  1974. ;
  1975.     CPI    'U'-40H
  1976.     JZ    RDCTLU
  1977. ;
  1978.     CPI    CR
  1979.     JZ    RDCR
  1980. ;
  1981.     CPI    'H'-40H
  1982.     JZ    RDBS
  1983. ;
  1984.     CPI    7FH
  1985.     JZ    RDBS
  1986. ;
  1987.     CPI    'R'-40H
  1988.     JZ    RDCTLR
  1989. ;
  1990.     CPI    'X'-40H
  1991.     JZ    RDCTLX
  1992. ;
  1993.     CPI    ' '
  1994.     JC    RDBLP
  1995. ;
  1996.     MOV    M,A
  1997.     INX    H
  1998.     INR    B
  1999.     JM    FULL
  2000.     CALL    TYPE
  2001.     JMP    RDBLP
  2002. ;
  2003. FULL:    DCR    B
  2004.     DCX    H
  2005.     MVI    A,'*'    ;SIGNAL WE'RE FULL
  2006.     CALL    TYPE
  2007.     JMP    RDBLP
  2008. ;
  2009. ;Got CR
  2010. ;
  2011. RDCR:    MOV    M,A    ;SAVE IT
  2012.     CALL    TYPE    ;ECHO IT
  2013.     MVI    A,LF    ;ECHO..
  2014.     CALL    TYPE    ;..LF
  2015.     LXI    H,INBUF
  2016.     RET
  2017. ;
  2018. ;Got DELETE or BS, echo if BS
  2019. ;
  2020. RDBS:    XRA    A    ;AT FRONT..
  2021.     ORA    B    ;..OF LINE?
  2022.     JZ    RDCTLU    ;..YES, ECHO ^U
  2023.     DCX    H
  2024.     DCR    B
  2025.     MOV    A,C
  2026.     CPI    'H'-40H ;BS?
  2027.     JZ    BACKUP    ;ECHO THE BS
  2028.     MOV    A,M    ;ECHO..
  2029.     CALL    TYPE    ;..DELETED CHAR
  2030.     JMP    RDBLP
  2031. ;
  2032. BACKUP: CALL    WIPER
  2033.     JMP    RDBLP
  2034. ;
  2035. RDCTLX: INR    B
  2036. ;
  2037. RDCX1:    DCR    B
  2038.     JZ    RDBF1
  2039.     CALL    WIPER
  2040.     JMP    RDCX1
  2041. ;
  2042. WIPER:    PUSH    B
  2043.     PUSH    D
  2044.     PUSH    H
  2045.     LXI    D,BSMSG ;BACKSPACE, SPACE, BACKSPACE
  2046.     MVI    C,PRINT
  2047.     CALL    BDOS
  2048.     POP    H
  2049.     POP    D
  2050.     POP    B
  2051.     RET
  2052. ;
  2053. BSMSG:    DB    BS,' ',BS,'$'
  2054. ;
  2055. ;Got CTL-R, retype
  2056. ;
  2057. RDCTLR: MVI    M,CR
  2058.     CALL    CRLF
  2059.     LXI    H,INBUF
  2060.     MVI    B,0
  2061. ;
  2062. RDCRL:    MOV    A,M
  2063.     CPI    CR
  2064.     JZ    RDBLP
  2065.     CALL    TYPE
  2066.     INR    B
  2067.     INX    H
  2068.     JMP    RDCRL
  2069. ;
  2070. ;Got CTL-U or backup to beginning of line.
  2071. ;
  2072. RDCTLU: MVI    A,'^'
  2073.     CALL    TYPE
  2074.     MVI    A,'U'
  2075.     CALL    TYPE
  2076.     JMP    RDBUF
  2077. ;
  2078. CRLF:    MVI    A,CR
  2079.     CALL    TYPE
  2080.     MVI    A,LF
  2081.     JMP    TYPE
  2082. ;
  2083. UPCASE: CPI    60H
  2084.     RC
  2085.     ANI    5FH    ;MAKE UPPER CASE
  2086.     RET
  2087. ;
  2088. CONST:    PUSH    B
  2089.     PUSH    D
  2090.     PUSH    H
  2091. VCONST: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2092.     POP    H
  2093.     POP    D
  2094.     POP    B
  2095.     RET
  2096. ;
  2097. CONIN:    PUSH    B
  2098.     PUSH    D
  2099.     PUSH    H
  2100. VCONIN: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2101.     POP    H
  2102.     POP    D
  2103.     POP    B
  2104.     RET
  2105. ;
  2106. ;Console out with TAB expansion
  2107. ;
  2108. TYPE:    PUSH    B
  2109.     PUSH    D
  2110.     PUSH    H
  2111.     MOV    C,A    ;FOR OUTPUT ROUTINE
  2112.     CPI    TAB
  2113.     JNZ    TYPE2
  2114. ;
  2115. TYPTAB: MVI    A,' '
  2116.     CALL    TYPE
  2117.     LDA    TABCOL
  2118.     ANI    7
  2119.     JNZ    TYPTAB
  2120.     JMP    TYPRET
  2121. ;
  2122. ;Filter out control characters to
  2123. ;prevent garbage during view of file
  2124. ;
  2125. TYPE2:    CPI    ' '
  2126.     JNC    TYPEQ
  2127.     CPI    CR
  2128.     JZ    TYPEQ
  2129.     CPI    LF
  2130.     JNZ    TYPNCR
  2131. ;
  2132. TYPEQ:    LDA    QFLAG
  2133.     ORA    A
  2134.  
  2135. VCONOT: CZ    $-$    ;ADDR FILLED IN BY 'INIT'
  2136. ;
  2137. ;Update column used in tab expansion
  2138.     MOV    A,C    ;GET CHAR
  2139.     CPI    CR
  2140.     JNZ    TYPNCR
  2141.     MVI    A,0
  2142.     STA    TABCOL
  2143.     JMP    TYPLST
  2144. ;
  2145. TYPNCR: CPI    ' '    ;CTL CHAR?
  2146.     JC    TYPLST    ;..NO CHANGE IN COL
  2147.     LDA    TABCOL
  2148.     INR    A
  2149.     STA    TABCOL
  2150. ;
  2151. TYPLST: LDA    PFLAG
  2152.     ANI    1
  2153.     CNZ    LIST    ;FROM C REG.
  2154. ;
  2155. TYPRET: POP    H
  2156.     POP    D
  2157.     POP    B
  2158.     RET
  2159. ;
  2160. LIST:    PUSH    B    ;SAVED REGS
  2161.     PUSH    D
  2162.     PUSH    H
  2163. VLIST:    CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2164.     POP    H
  2165.     POP    D
  2166.     POP    B
  2167.     RET
  2168. ;
  2169. HOME:    PUSH    H
  2170. VHOME:    CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2171.     POP    H
  2172.     RET
  2173. ;
  2174. ;Set track # in DE
  2175. ;
  2176. SETTRK: PUSH    H
  2177.     LHLD    MAXTRK
  2178.     CALL    SUBDE
  2179.     POP    H
  2180.     JC    OUTLIM
  2181.     XCHG
  2182.     SHLD    CURTRK
  2183.     XCHG
  2184.     MOV    B,D
  2185.     MOV    C,E
  2186.     PUSH    H
  2187. VSETRK: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2188.     POP    H
  2189.     RET
  2190. ;
  2191. SETSEC: PUSH    H
  2192.     PUSH    D
  2193.     LHLD    SYSTRK
  2194.     XCHG
  2195.     SHLD    CURSEC
  2196.     LHLD    CURTRK
  2197.     CALL    SUBDE
  2198.     POP    B
  2199.     MOV    H,B
  2200.     MOV    L,C
  2201.     JNC    NOTSYS
  2202.     LDA    FIRST0    ;SEE IF FIRST SEC 0
  2203.     ORA    A
  2204.     JNZ    GSTSEC    ;NO, JUMP AWAY
  2205.     DCX    H    ;YES, SO DECREMENT
  2206.     JMP    GSTSEC    ;  REQUESTED, THEN GO
  2207. ;
  2208. NOTSYS: LHLD    SECTBL
  2209.     XCHG
  2210.     DCX    B
  2211. VSCTRN: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2212.     LDA    SPT+1    ;IF SPT<256 (HI-ORD = 0)
  2213.     ORA    A    ; THEN FORCE 8-BIT TRANSLATION
  2214.     JNZ    VSCTR1    ; ELSE KEEP ALL 16 BITS
  2215.     MOV    H,A
  2216. ;
  2217. VSCTR1: LDA    VER2FL    ;SEE IF VERSION 2.x
  2218.     ORA    A    ;SET FLAGS
  2219.     JNZ    GSTSEC    ;JUMP IF CP/M 2.x
  2220.     MVI    H,0    ;CP/M 1.4 GOOD TO ONLY 8 BITS
  2221.     MOV    L,C    ;MOST BIOS'S RETURN THE
  2222.             ;  PHYSICAL SEC # IN REG C
  2223. GSTSEC: SHLD    PHYSEC    ;THIS MAY BE REDUNTANT IN
  2224.             ; MOST 1.4 VERSIONS, BUT
  2225.             ; SHOULD CAUSE NO PROBLEMS
  2226.     MOV    B,H
  2227.     MOV    C,L
  2228. VSTSEC: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2229.     POP    H
  2230.     RET
  2231. ;
  2232. OUTLIM: XRA    A
  2233.     STA    QFLAG
  2234.     CALL    ILPRT
  2235.     DB    '++not within tracks 0-',0
  2236.     PUSH    H
  2237.     LHLD    MAXTRK
  2238.     CALL    DEC
  2239.     POP    H
  2240.     CALL    ILPRT
  2241.     DB    '++'
  2242.     DB    CR,LF,0
  2243.     CALL    NORITE
  2244.     JMP    PRMPTR
  2245. ;
  2246. SETDMA: JMP    $-$    ;ADDR FILLED IN BY 'INIT'
  2247. ;
  2248. READ:    MVI    A,1
  2249.     STA    WRFLG
  2250.     PUSH    H
  2251. VREAD:    CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2252.     ORA    A
  2253.     JZ    READOK
  2254.     XRA    A
  2255.     STA    QFLAG
  2256.     CALL    ILPRT
  2257.     DB    '++READ failed, sector may be invalid++'
  2258.     DB    CR,LF,0
  2259. ;
  2260. READOK: POP    H
  2261.     RET
  2262. ;
  2263. WRITE:    LDA    WRFLG
  2264.     ORA    A
  2265.     JNZ    PWRITE
  2266. ;
  2267. BADW:    XRA    A
  2268.     STA    QFLAG
  2269.     CALL    ILPRT
  2270.     DB    '++CANNOT WRITE UNLESS READ ISSUED'
  2271.     DB    CR,LF,0
  2272.     JMP    EXPL
  2273. ;
  2274. PWRITE: PUSH    H
  2275.     MVI    C,1    ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED
  2276. VWRITE: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2277.     ORA    A
  2278.     JZ    WRITOK
  2279.     XRA    A
  2280.     STA    QFLAG
  2281.     CALL    ILPRT
  2282.     DB    '++WRITE failed++',CR,LF,0
  2283. ;
  2284. WRITOK: POP    H
  2285.     RET
  2286. ;
  2287. ;Help
  2288. ;
  2289. HELP:    CALL    ILPRT
  2290.     DB    'Operands in brackets [...] are optional'
  2291.     DB    CR,LF
  2292.     DB    'Numeric values: ''n'' are decimal, ''x'' hex'
  2293.     DB    CR,LF,CR,LF
  2294.     DB    '+[n]   step in [n] sectors;'
  2295.     DB    CR,LF
  2296.     DB    '-[n]   step out [n] sectors'
  2297.     DB    CR,LF
  2298.     DB    '#      print disk parameters for curr drive.'
  2299.     DB    CR,LF
  2300.     DB    '=xxx   search for ASCII xxx from curr sector.'
  2301.     DB    CR,LF
  2302.     DB    '       Caution: upper/lower case matters.'
  2303.     DB    CR,LF
  2304.     DB    '       Use <xx> for hex:'
  2305.     DB    CR,LF
  2306.     DB    '       To find "IN 0" use: =<db><0>     or'
  2307.     DB    CR,LF
  2308.     DB    '       "(tab)H,0(CR)(LF)" use: =<9>H,0<D><A>'
  2309.     DB    CR,LF
  2310.     DB    '<      save current sector into mem. buff.'
  2311.     DB    CR,LF
  2312.     DB    '>      restore saved sector'
  2313.     DB    CR,LF
  2314.     DB    '?      give help'
  2315.     DB    CR,LF
  2316.     DB    'A[ff,tt] ASCII dump'
  2317.     DB    CR,LF,CR,LF
  2318.     DB    '(Type any char. to continue)'
  2319.     DB    1,CR,LF,CR,LF
  2320.     DB    'C      Change:'
  2321.     DB    CR,LF
  2322.     DB    '       CHaddr,byte,byte... (hex)'
  2323.     DB    CR,LF
  2324.     DB    '  or   CAaddr,data...  (Ascii)'
  2325.     DB    CR,LF
  2326.     DB    '       <xx> Allowed for imbedded hex.'
  2327.     DB    CR,LF
  2328.     DB    '  or   CHfrom-thru,byte  e.g. ch0-7f,e5'
  2329.     DB    CR,LF
  2330.     DB    '  or   CAfrom-thru,byte'
  2331.     DB    CR,LF
  2332.     DB    'D[ff,tt] Dump (hex+ASCII)'
  2333.     DB    CR,LF
  2334.     DB    'Fn.t   Find file'
  2335.     DB    CR,LF
  2336.     DB    'Gnn    CP/M Allocation Group nn'
  2337.     DB    CR,LF
  2338.     DB    'H[ff,tt]       hex dump'
  2339.     DB    CR,LF
  2340.     DB    'L      Log in drive'
  2341.     DB    CR,LF
  2342.     DB    'Lx     Log in drive x'
  2343.     DB    CR,LF
  2344.     DB    'M[nn]  Map [from group nn]'
  2345.     DB    CR,LF,CR,LF
  2346.     DB    '(Type any char. to continue)'
  2347.     DB    1,CR,LF,CR,LF
  2348.     DB    'N      New disk'
  2349.     DB    CR,LF
  2350.     DB    'P      Toggle printer switch'
  2351.     DB    CR,LF
  2352.     DB    'Q      Quiet mode (no msgs)'
  2353.     DB    CR,LF
  2354.     DB    'R      Read current sector'
  2355.     DB    CR,LF
  2356.     DB    'Snn    Sector nn'
  2357.     DB    CR,LF
  2358.     DB    'Tnn    Track nn'
  2359.     DB    CR,LF
  2360.     DB    'Unn    Set User nn for Find command (CP/M-2 only)'
  2361.     DB    CR,LF
  2362.     DB    'V[nn]  View [nn] ASCII sectors'
  2363.     DB    CR,LF
  2364.     DB    'W      Write current sector'
  2365.     DB    CR,LF
  2366.     DB    'X      Exit program'
  2367.     DB    CR,LF
  2368.     DB    'Y      Yank current sector into sequential memory'
  2369.     DB    CR,LF
  2370.     DB    'Z[nn]  Sleep [nn tenths]'
  2371.     DB    CR,LF
  2372.     DB    '/[nn]  Repeat [nn (decimal) times]'
  2373.     DB    CR,LF,CR,LF
  2374.     DB    '(Type any char. to continue)'
  2375.     DB    1,CR,LF,CR,LF
  2376.     DB    'Cancel a function with C or Ctl-C.'
  2377.     DB    CR,LF
  2378.     DB    'Suspend output with S or Ctl-S.'
  2379.     DB    CR,LF
  2380.     DB    'Separate commands with ";".'
  2381.     DB    CR,LF
  2382.     DB    '       Example: g0'
  2383.     DB    CR,LF
  2384.     DB    '       +;d;z#20;/'
  2385.     DB    CR,LF
  2386.     DB    '       would step in, dump, sleep 2 sec, '
  2387.     DB    CR,LF
  2388.     DB    '       and repeat until control-c typed.'
  2389.     DB    CR,LF
  2390.     DB    'All "nn" usage except "/", "T", and "S" are'
  2391.     DB    CR,LF
  2392.     DB    '        HEX.  Use #nn for decimal.'
  2393.     DB    CR,LF,CR,LF
  2394.     DB    'See DU.DOC for complete examples.'
  2395.     DB    CR,LF,CR,LF,0
  2396.     JMP    PROMPT
  2397. ;
  2398. ;********************************
  2399. ;*                *
  2400. ;*    Utility Subroutines    *
  2401. ;*                *
  2402. ;********************************
  2403. ;
  2404. GRPCMP: MOV    A,C
  2405.     INR    D
  2406.     DCR    D
  2407.     JZ    CMP8
  2408.     CMP    M
  2409.     INX    H
  2410.     RNZ
  2411.     MOV    A,B
  2412. ;
  2413. CMP8:    CMP    M
  2414.     RET
  2415. ;
  2416. ;2's complement HL ==> HL
  2417. ;
  2418. NEG:    MOV    A,L
  2419.     CMA
  2420.     MOV    L,A
  2421.     MOV    A,H
  2422.     CMA
  2423.     MOV    H,A
  2424.     INX    H
  2425.     RET
  2426. ;
  2427. ;HL/2 ==> HL
  2428. ;
  2429. ROTRHL: ORA    A
  2430.     MOV    A,H
  2431.     RAR
  2432.     MOV    H,A
  2433.     MOV    A,L
  2434.     RAR
  2435.     MOV    L,A
  2436.     RET
  2437. ;
  2438. ;Collect the number of '1' bits
  2439. ;in A as a count in C
  2440. ;
  2441. COLECT: MVI    B,8
  2442. ;
  2443. COLOP:    RAL
  2444.     JNC    COSKIP
  2445.     INR    C
  2446. ;
  2447. COSKIP: DCR    B
  2448.     JNZ    COLOP
  2449.     RET
  2450. ;
  2451. ;HL-DE ==> HL
  2452. ;
  2453. SUBDE:    MOV    A,L
  2454.     SUB    E
  2455.     MOV    L,A
  2456.     MOV    A,H
  2457.     SBB    D
  2458.     MOV    H,A
  2459.     RET
  2460. ;
  2461. ;Quick Kludge multiply
  2462. ;HL=DE ==> HL
  2463. ;
  2464. MULT:    PUSH    B
  2465.     PUSH    D
  2466.     XCHG
  2467.     MOV    B,D
  2468.     MOV    C,E
  2469.     MOV    A,B
  2470.     ORA    C
  2471.     JNZ    MULCON
  2472.     LXI    H,0    ;FILTER SPECIAL CASE
  2473.     JMP    MLDONE    ;  OF MULTIPLY BY 0
  2474. ;
  2475. MULCON: DCX    B
  2476.     MOV    D,H
  2477.     MOV    E,L
  2478. ;
  2479. MULTLP: MOV    A,B
  2480.     ORA    C
  2481.     JZ    MLDONE
  2482.     DAD    D
  2483.     DCX    B
  2484.     JMP    MULTLP
  2485. ;
  2486. MLDONE: POP    D
  2487.     POP    B
  2488.     RET
  2489. ;
  2490. ;Routine to fill in disk params
  2491. ;with every drive change
  2492. ;
  2493. LOGIT:    LDA    VER2FL
  2494.     ORA    A    ;IF NOT CP/M 2.x THEN
  2495.     JZ    LOG14    ;    DO IT AS 1.4
  2496.     LXI    D,DPB    ;   THEN MOVE TO LOCAL
  2497.     MVI    B,DPBLEN ;  WORKSPACE
  2498.     CALL    MOVE
  2499.     JMP    LOGCAL
  2500. ;
  2501. LOG14:    LHLD    BDOS+1    ;FIRST FIND 1.4 BDOS
  2502.     MVI    L,0
  2503.     LXI    D,DPBOFF ;THEN OFFSET TO 1.4'S DPB
  2504.     DAD    D
  2505.     MVI    D,0    ;SO 8 BIT PARMS WILL BE 16
  2506.     MOV    E,M    ;NOW MOVE PARMS
  2507.     INX    H
  2508.     XCHG
  2509.     SHLD    SPT
  2510.     XCHG
  2511.     MOV    E,M
  2512.     INX    H
  2513.     XCHG
  2514.     SHLD    DRM
  2515.     XCHG
  2516.     MOV    A,M
  2517.     INX    H
  2518.     STA    BSH
  2519.     MOV    A,M
  2520.     INX    H
  2521.     STA    BLM
  2522.     MOV    E,M
  2523.     INX    H
  2524.     XCHG
  2525.     SHLD    DSM
  2526.     XCHG
  2527.     MOV    E,M
  2528.     INX    H
  2529.     XCHG
  2530.     SHLD    AL0
  2531.     XCHG
  2532.     MOV    E,M
  2533.     XCHG
  2534.     SHLD    SYSTRK
  2535. ;
  2536. LOGCAL: LXI    H,GRPDIS
  2537.     MOV    A,M
  2538.     PUSH    PSW
  2539.     LDA    BLM
  2540.     MOV    M,A
  2541.     PUSH    H
  2542.     LHLD    DSM
  2543.     XCHG
  2544.     CALL    GTKSEC
  2545.     SHLD    MAXSEC
  2546.     XCHG
  2547.     SHLD    MAXTRK
  2548.     POP    H
  2549.     POP    PSW
  2550.     MOV    M,A
  2551.     RET
  2552. ;
  2553. ;Temporary storage area
  2554. ;
  2555. BUFAD:    DW    BASE+100H ;FORCES INITIAL READ
  2556. HEXAD:    DW    0    ;TO RE-FETCH A VALUE
  2557. TOGO:    DW    0FFFFH    ;REPEAT COUNT (FFFF=CONT)
  2558. TWOUP:    DB    0
  2559. PFLAG:    DB    0    ;1=PRINT
  2560. GROUP:    DW    0
  2561. GRPDIS: DB    0
  2562. SAVEFL: DB    0
  2563. CURTRK: DW    0
  2564. CURSEC: DW    1
  2565. PHYSEC: DW    1
  2566. TABCOL: DB    0
  2567. FILECT: DW    0
  2568. DIRPOS: DB    0
  2569. FINDFL: DB    0    ;1=MUST POSITION AFTER FIND
  2570. FTSW:    DB    1    ;SEARCH W/O INCREMENT
  2571. NOTPOS: DB    1    ;INITIALLY NOT POSITIONED
  2572. WRFLG:    DB    0    ;MAY NOT WRITE UNTIL '+', '-',
  2573. ;             OR 'G' COMMAND
  2574. QFLAG:    DB    0    ;QUIET? (0=NO)
  2575. FIRST0: DB    0    ;SETS TO 0 IF FIRST SEC # IS 0
  2576. DRIVE:    DB    0
  2577. MAXTRK: DW    0
  2578. MAXSEC: DW    0
  2579. VER2FL: DB    0
  2580. SECTBL: DW    0    ;POINTER TO SECTOR SKEW TABLE
  2581. MFPTR:    DW    0
  2582. DUPFLG: DB    0
  2583. YNKADR: DW    0    ;POINTER TO CURRENT YANK ADDRESS
  2584. ;
  2585. BACK:    DS    2    ;TO BACK UP IN "CA0-7F,X"
  2586. DUMTYP: DS    1
  2587. ;
  2588. ;--------------------------------------------------
  2589. ;The disk parameter block
  2590. ;is moved here from CP/M
  2591. ;
  2592. DPB    EQU    $    ;DISK PARAMETER BLOCK (COPY)
  2593. SPT:    DS    2
  2594. BSH:    DS    1
  2595. BLM:    DS    1
  2596. EXM:    DS    1
  2597. DSM:    DS    2
  2598. DRM:    DS    2
  2599. AL0:    DS    1
  2600. AL1:    DS    1
  2601. CKS:    DS    2
  2602. SYSTRK: DS    2
  2603. ;
  2604. ;End of disk parameter block
  2605. ;--------------------------------------------------
  2606. ;
  2607. SAVBUF: DS    128
  2608. INBUF:    DS    128
  2609. ;
  2610. ;Directory read in here; also search work area
  2611. ;
  2612. WORK    EQU    $
  2613. DIRECT    EQU    $
  2614. ;
  2615.     END
  2616.