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

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