home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ZSYS / SIMTEL20 / ZCPR3 / DU3.MAC < prev    next >
Text File  |  2000-06-30  |  84KB  |  4,446 lines

  1. ; 03/01/85    Richard Conn: Replaced fixed in EDPLOT that was somehow lost
  2. ;        (see lines suffixed by <RLC-3/1/85>
  3. ;
  4. ; 01/18/85    Modified by Jay Sage to incorporate a set of permanent
  5. ;        macros.  These macros can be invoked by the command tail
  6. ;        when DU is invoked.  They are copied from a space of 128
  7. ;        bytes near the beginning of the code.  The area is
  8. ;        identified by a string of text to facilitate patching.
  9. ;        The macros are listed one after another, separated by
  10. ;        carriage return characters.  Macros that are not to be
  11. ;        defined must be present as carriage returns alone or the
  12. ;        program will fail.
  13. ;
  14. ; PROGRAM:  DU3
  15. ; AUTHOR:  RICHARD CONN
  16. ; DERIVATION:  DUTIL is derived from DU Version 7.5
  17. ;        DU2 is derived from DUTIL Version 1.1
  18. ;        DU3 is derived from DU2 Version 1.1
  19. ; VERSION:  1.0
  20. ; DATE:  20 June 84
  21. ; PREVIOUS VERSIONS:  None
  22. ; NOTE:  DU3 must be assembled using M80 (or equiv)
  23. ;
  24. VERS    EQU    13
  25. Z3ENV    EQU    0F400H
  26.  
  27. ;
  28. ;  DU3 is derived from --
  29. ;      DU.ASM  V7.5    Revised 1/23/81
  30. ;    DISK UTILITY - By Ward Christensen
  31. ;
  32. ;  Principal Authors of DU V7.5 are --
  33. ;    WLC   KBP   RGF   BRR
  34. ;
  35. ;  Key comments from DU V7.5 and DU3 follow --
  36. ;
  37. ;This version of DU is compatible with CP/M 2.x
  38. ;and does not require alteration for various hardware
  39. ;configurations.  It adjusts itself automatically to
  40. ;the correct number of sectors, tracks, directory size,
  41. ;etc.  It has been tested on 5-1/4" and 8" floppy, and
  42. ;10 megabyte hard disk systems.
  43. ;
  44. ;Because of the automatic adaption feature, no conditional
  45. ;assembly options are included.
  46. ;
  47. ;*************************************************
  48. ;*                          *
  49. ;*   This program has been heavily modified     *
  50. ;* to allow it to work without modification     *
  51. ;* on all versions of CP/M 2.x.             *
  52. ;*   One known possible problem involves the     *
  53. ;* system tracks on some systems, and results     *
  54. ;* from the system sectors being skewed. There     *
  55. ;* is NO way for a program executing under CP/M     *
  56. ;* to know about this.  This program assumes the *
  57. ;* standard convention of no skew being used on     *
  58. ;: the system tracks. This usually isn't a prob- *
  59. ;* lem because the SYSGEN program can be used to *
  60. ;* get the system from the disk so that    it can     *
  61. ;* be modified.                     *
  62. ;*                          *
  63. ;*         Ron Fowler             *
  64. ;*                          *
  65. ;*************************************************
  66. ;
  67.  
  68. ;
  69. ;  SYSLIB and Z3LIB References
  70. ;
  71.     ext    z3vinit,envptr,cls,at,tinit,dinit,stndout,stndend,gotoxy
  72.     ext    getspeed,getcrt,getmdisk,getmuser
  73.     ext    codend
  74.  
  75. ;
  76. ;System equates
  77. ;
  78. BASE    EQU    0    ;SET TO 4200H FOR HEATH OR TRS-80 ALTCPM
  79. ;
  80. ;CP/M Key Areas
  81. ;
  82. FCB    EQU    BASE+5CH    ;CP/M FCB
  83. BDOS    EQU    BASE+5        ;CP/M BDOS ENTRY POINT
  84. TBUFF    EQU    BASE+80H    ;CP/M TEMPORARY DISK I/O BUFFER
  85. TPA    EQU    BASE+100H    ;CP/M TRANSCIENT PROGRAM AREA
  86. ;
  87. ;  Some Key Variables in DU3
  88. ;
  89. EOLCH    equ    ','        ;Marks logical end of line
  90. SEPCH    equ    ' '        ;Argument Separator
  91. MULCH    equ    '*'        ;Multiplication Command
  92. DIM    equ    1        ;Enter DIM Mode for ILPRT
  93. BRIGHT    equ    2        ;Enter BRIGHT Mode for ILPRT
  94.  
  95. ;
  96. ;CP/M BDOS Function Codes
  97. ;
  98. PRINT    EQU    9
  99. GVERS    EQU    12
  100. RESETDK EQU    13    ;RESET SYSTEM
  101. SELDK    EQU    14    ;SELECT DISK
  102. CLOSEF    EQU    16    ;CLOSE FILE
  103. SRCHF    EQU    17    ;SEARCH FIRST
  104. SRCHN    EQU    18    ;SEARCH NEXT
  105. DELF    EQU    19    ;DELETE FILE
  106. WRITEF    EQU    21    ;WRITE BLOCK TO FILE
  107. MAKEF    EQU    22    ;CREATE FILE
  108. SUSER    EQU    32    ;SELECT USER
  109. GETDSK    EQU    25
  110. GETDPB    EQU    31
  111. ;
  112. ;CP/M 1.4 Offsets and Some Key Values
  113. ;
  114. TRNOFF    EQU    15    ;CP/M 1.4 OFFSET FROM BASE
  115.             ;OF BDOS TO SECTRAN ROUTINE
  116. SKWOFF    EQU    1AH    ;CP/M 1.4 OFFSET TO SKEW TABLE
  117. S2OFF    EQU    14    ;OFFSET INTO FCB FOR S2 BYTE
  118. DPBOFF    EQU    3AH    ;CP/M 1.4 OFFSET TO DPB WITHIN BDOS
  119. S2MASK    EQU    0FH    ;MASK FOR EXTENDED RC BITS OF S2
  120. DPBLEN    EQU    15    ;SIZE OF CP/M 2.x DISK PARM BLOCK
  121. ;
  122. ;Define ASCII characters
  123. ;
  124. CR    EQU    0DH    ;CARRIAGE RETURN
  125. LF    EQU    0AH    ;LINE FEED
  126. TAB    EQU    09H    ;TAB
  127. BS    EQU    08H    ;BACKSPACE
  128.  
  129. ;
  130. ;   MACROS INCLUDE:
  131. ;
  132. ;    DJNZ    - DECREMENT B AND JUMP RELATIVE IF NO ZERO
  133. ;
  134. DJNZ    MACRO    ?N    ;;DECREMENT B AND JUMP ON NO ZERO
  135.      DCR    B
  136.      JNZ    ?N
  137.     ENDM
  138. ;
  139. ; END OF MACROS
  140. ;
  141.  
  142.  
  143. ;
  144. ;Beginning of Program
  145. ;
  146. ;
  147. ; Environment Definition
  148. ;
  149.     if    z3env ne 0
  150. ;
  151. ; External ZCPR3 Environment Descriptor
  152. ;
  153.     jmp    start
  154.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  155.     db    1    ;External Environment Descriptor
  156. z3eadr:
  157.     dw    z3env
  158.  
  159. ;
  160. ; Space Added for Initial Macro Definitions -- block added by <JPS>
  161. ;
  162.     ;label to help locate when patching
  163.  
  164.     db    'INITIAL MACROS:'
  165.  
  166. imac0:    db    'G0,D',cr    ;macro 0
  167.     db    '-D',cr        ;macro 1
  168.     db    '+D',cr        ;macro 2
  169.     db    cr        ;macro 3
  170.     db    cr        ;macro 4
  171.     db    cr        ;macro 5
  172.     db    cr        ;macro 6
  173.     db    cr        ;macro 7
  174.     db    cr        ;macro 8
  175.     db    cr        ;macro 9
  176.  
  177.     ;fill rest of 128 bytes with nulls
  178.  
  179.     if    imac0 + 128 - $ gt 0
  180.     rept    imac0 + 128 - $
  181.     db    0
  182.     endm
  183.     endif
  184.  
  185. ; End of Block Added by <JPS>
  186.  
  187. start:
  188.     lhld    z3eadr    ;pt to ZCPR3 environment
  189. ;
  190.     else
  191. ;
  192. ; Internal ZCPR3 Environment Descriptor
  193. ;
  194.     MACLIB    Z3BASE.LIB
  195.     MACLIB    SYSENV.LIB
  196. z3eadr:
  197.     jmp    start
  198.     SYSENV
  199. start:
  200.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  201.     endif
  202.  
  203. ;
  204. ; Start of Program -- Initialize ZCPR3 Environment
  205. ;
  206.     call    z3vinit    ;initialize the ZCPR3 Env and the VLIB Env
  207.     call    tinit    ;init terminal
  208.     LXI    H,0    ;GET PTR TO CP/M STACK
  209.     DAD    SP    ;HL=SP
  210.     SHLD    DUTSTK    ;SAVE IT
  211. ;
  212.     call    codend    ;get free space
  213.     lxi    d,100h    ;open area
  214.     dad    d    ;large stack area
  215.     shld    savbuf
  216.     dad    d    ;100H for SAVBUF
  217.     push    h    ;save ptr
  218.     mvi    m,126    ;allow 126-char input line
  219.     inx    h
  220.     inx    h    ;ptr to INBUF
  221.     shld    inbuf
  222.     pop    h    ;pt to beginning
  223.     lxi    d,400h    ;large area for expansion
  224.     dad    d
  225.     shld    pinbuf    ;ptr to PINBUF
  226.     dad    d
  227.     shld    ctemp    ;ptr to CTEMP
  228.     dad    d
  229.     shld    ctempx    ;ptr to CTEMPX
  230.     shld    mtabl    ;ptr to MACRO TABLE
  231.     lxi    d,100h*10    ;10 macros
  232.     dad    d
  233.     shld    gbuff    ;group save buffer
  234.     shld    direct    ;directory load buffer
  235. ;
  236.     lhld    savbuf    ;top of stack
  237.     sphl        ; SET STACK
  238. ;
  239.     call    getspeed
  240.     sta    clock    ;set clock speed
  241.     call    getcrt    ;get CRT data
  242.     inx    h    ;pt to screen size
  243.     mov    a,m    ;get it
  244.     sta    pagsiz    ;set page size
  245.     call    getmdisk    ;get max disk
  246.     sta    mdisk    ;and set it
  247.     call    getmuser    ;get max user
  248.     sta    muser    ;and set it
  249. ;
  250. ;Set up local jumps to BIOS
  251. ;
  252. START1:
  253.     LHLD    BASE+1    ;WARM BOOT POINTER
  254.     LXI    D,3    ;READY FOR ADD
  255.     DAD    D    
  256.     SHLD    VCONST+1    ;CON: Status
  257.     DAD    D
  258.     SHLD    VCONIN+1    ;CON: Input
  259.     DAD    D
  260.     SHLD    VCONOT+1    ;CON: Output
  261.     DAD    D
  262.     SHLD    VLIST+1        ;LST: Output
  263.     DAD    D    ;Skip PUNCH
  264.     DAD    D    ;Skip RDR
  265.     DAD    D
  266.     SHLD    VHOME+1        ;Home Disk
  267.     DAD    D
  268.     SHLD    VSELDK+1    ;Select Disk
  269.     DAD    D
  270.     SHLD    VSETRK+1    ;Set Track
  271.     DAD    D
  272.     SHLD    VSTSEC+1    ;Set Sector
  273.     DAD    D
  274.     SHLD    SETDMA+1    ;Set DMA Address
  275.     DAD    D
  276.     SHLD    VREAD+1        ;Read Block From Disk
  277.     DAD    D
  278.     SHLD    VWRITE+1    ;Write Block To Disk
  279.     DAD    D    ;Skip LISTST
  280.     DAD    D
  281.     SHLD    VSCTRN+1    ;CP/M 2.x Sector Translation Table
  282. ;    JMP    HELLO
  283. ;
  284. ;Initialization Complete -- Print Signon Message and Begin Command Processing
  285. ;
  286. HELLO:
  287.     CALL    GETSTP    ;SET UP CP/M PARAMETERS
  288.     CALL    INITP    ;INITIALIZE BUFFER PARAMETERS
  289.     CALL    ILPRT
  290.     DB    'DU3 - Disk Utility III, Version '
  291.     DB    VERS/10+'0','.',(VERS MOD 10)+'0'
  292.     DB    CR,LF,CR,LF
  293.     DB    DIM,'Type ? for Help',BRIGHT
  294.     DB    CR,LF,0
  295. ;
  296. ;Clear Editor Reference
  297. ;
  298.     XRA    A
  299.     STA    EDRUN    ;EDITOR NOT RUNNING
  300. ;
  301. ;Save initial command line in INBUF
  302. ;
  303.     LXI    H,TBUFF    ;PT TO COMMAND LINE BUFFER
  304.     MOV    A,M    ;GET CHAR COUNTER
  305.     ora    a    ;check for no tail <JPS>
  306.     jnz    ctail    ;if not, no need to increment <JPS>
  307.     inr    a    ;allow for blank otherwise present <JPS>
  308. ctail:            ; <JPS>
  309.     INX    H    ;PT TO FIRST CHAR
  310.     ADD    L    ;COMPUTE LOCATION OF AFTER LAST CHAR
  311.     MOV    L,A
  312.     MOV    A,H
  313.     ACI    0
  314.     MOV    H,A
  315.     MVI    M,CR    ;SET ENDING CR
  316.     LHLD    INBUF    ;PT TO BUFFER
  317.     XCHG        ;... IN DE
  318.     LXI    H,TBUFF+2    ;PT TO INPUT LINE (1 changed to 2 <JPS>)
  319.     MVI    B,128    ;COPY BUFFER
  320.     CALL    MOVE
  321. ;
  322. ;Establish Initial Position
  323. ;
  324.     LXI    D,0    ;GROUP 0
  325.     CALL    DEGROUP    ;POSITION TO GROUP
  326.     CALL    INQSUB    ;PRINT POSITION
  327. ;
  328. ;Check for initial command
  329. ;
  330.     LHLD    INBUF    ;INPUT BUFFER
  331.     MOV    A,M
  332.     CPI    CR
  333.     JZ    PRMPTR    ;NO INITIAL COMMAND FROM COMMAND LINE
  334.     INX    H    ;PT TO FIRST CHAR
  335. ;
  336. ;Got initial command, set it up
  337. ;
  338.     MOV    A,M    ;GET FIRST CHAR
  339.     CPI    '/'    ;IF SLASH, PRINT INITIAL HELP (TOOLSET CONVENTION)
  340.     JZ    IHELP    ;PRINT INITIAL HELP INFO
  341.     XRA    A
  342.     STA    IHFLG    ;SET NO INITIAL HELP
  343. ; line replaced <JPS>
  344. ;    JMP    PRMPTI    ;PROCESS AS THOUGH COMMAND LINE WAS TYPED <JPS>
  345.     jmp    prmpts    ;allow processing of macros in command line <JPS>
  346. ;
  347. ;Input Command Line From User at Console
  348. ;
  349. PRMPTR:
  350.     XRA    A    ;A=0
  351.     STA    IHFLG    ;Set No Initial Help
  352.     LDA    EDRUN    ;Check for Editor Running
  353.     ORA    A
  354.     JNZ    EDIT0    ;Reenter Editor
  355.     CALL    SINBUF    ;Save old INBUF into PINBUF
  356. PRMPTE:
  357.     CALL    RDBUF    ;Read Input Line
  358. PRMPTS:            ;Entry when Command Line has Input <JPS>
  359.     CALL    EXMAC    ;Expand Macros
  360. ;
  361. ;Begin Processing Command Line in INBUF
  362. ;  At this point, HL points to next character to process
  363. ;
  364. PRMPTI:
  365.     MVI    A,0FFH    ;SET INFINITE LOOP COUNT
  366.     STA    TOGO    ;LOOP COUNT FOR MULTIPLE LOOPS
  367.     STA    TOGO+1
  368. ;
  369. ;Minor Command Loop; This is the entry point for each individual command in
  370. ;  a Command Line; Commands may be separated by semicolons in this manner
  371. ;
  372. PROMPT    EQU    $
  373. SETSTK:
  374.     SHLD    STKSAV    ;SAVE HL FOR STACK LOAD
  375.     LHLD    SAVBUF    ;RESET STACK
  376.     SPHL
  377.     LHLD    STKSAV    ;RESTORE HL
  378.     XRA    A    ;ZERO 2-UP PRINT FOR DUAL-COLUMN PRINT
  379.     STA    TWOUP    ;..SWITCH
  380.     MVI    A,1
  381.     STA    FTSW    ;TELL SEARCH NOT TO INCR
  382.     PUSH    H
  383.     LXI    H,TBUFF    ;SET NO-READ INPUT BUFFER ADDRESS
  384.     SHLD    BUFAD    ;FOR RDBYTE
  385.     POP    H
  386.     CALL    CTLCS    ;ABORT?
  387.     JZ    PRMPTR    ;..YES, READ BUFFER
  388. ;
  389. ;Do we have to position in directory after find?
  390. ;
  391.     LDA    FINDFL
  392.     ORA    A
  393.     JNZ    POSDIR    ;POSITION IN DIRECTORY
  394. ;
  395. ;Begin Command Evaluation -- Check for EOL and Capitalize
  396. ;
  397.     MOV    A,M    ;GET NEXT CHAR IN COMMAND LINE
  398.     INX    H    ;POINT TO FOLLOWING CHAR
  399.     CPI    CR    ;END OF LINE PHYSICALLY?
  400.     JZ    PRMPTR    ;INPUT NEW COMMAND LINE IF SO
  401.     CPI    EOLCH    ;END OF LINE LOGICALLY?
  402.     JZ    PROMPT    ;PROCESS NEXT ELEMENT IF SO
  403.     CALL    UPCASE    ;CAPITALIZE COMMAND
  404.     STA    DUMTYP    ;TYPE OF DUMP (A,D,H)
  405.     LXI    D,CMDTBL    ;PT TO COMMAND TABLE
  406.     CALL    CMD    ;PROCESS
  407.     JMP    WHAT    ;ERROR RETURN
  408. ;
  409. ;Command dispatcher
  410. ;  If command not found, abort with error message
  411. ;  If command file, process command with HL pting to next command char and
  412. ;    A containing command letter
  413. ;
  414. CMD:
  415.     PUSH    H    ;SAVE HL
  416.     MOV    B,A    ;COMMAND IN B
  417.     XCHG        ;HL PTS TO COMMAND TABLE
  418. CMDLP:
  419.     MOV    A,M    ;GET COMMAND
  420.     ORA    A    ;0=END OF TABLE
  421.     JZ    CMDER
  422.     CMP    B    ;COMPARE COMMAND
  423.     JZ    CMDGO
  424.     INX    H    ;PT TO ADR
  425.     INX    H
  426.     INX    H    ;PT TO NEXT CMND
  427.     JMP    CMDLP
  428. CMDGO:
  429.     INX    H    ;PT TO ADDRESS LOW
  430.     MOV    E,M
  431.     INX    H    ;PT TO ADDRESS HIGH
  432.     MOV    D,M
  433.     POP    H    ;RESTORE HL
  434.     POP    PSW    ;CLEAR RETURN ADDRESS
  435.     MOV    A,B    ;COMMAND BACK INTO A
  436.     PUSH    D    ;PLACE ADDRESS ON STACK
  437.     RET        ;"RUN COMMAND"
  438. CMDER:
  439.     POP    H    ;RESTORE HL
  440.     MOV    A,B    ;RESTORE COMMAND CHAR IN CASE CMD RUN
  441.     RET        ;... IMMEDIATELY AGAIN ON A NEW TABLE
  442. ;
  443. ;Macro Expansion Routine -- Expand Macros
  444. ;
  445. EXMAC:
  446.     LHLD    CTEMP    ;BUILD INTO TEMPORARY BUFFER
  447.     XCHG
  448.     LHLD    INBUF    ;PT TO INPUT LINE
  449. EXMAC1:
  450.     MOV    A,M    ;GET CHAR
  451.     CPI    '0'    ;SKIP IF LESS THAN '0'
  452.     JC    EXMAC2
  453.     CPI    '9'+1    ;CHECK FOR RANGE
  454.     JNC    EXMAC2
  455.     INX    H    ;PT TO NEXT CHAR
  456.     PUSH    H    ;SAVE PTR TO NEXT CHAR IN LINE
  457.     SUI    '0'    ;CONVERT TO BINARY (0-9)
  458.     MOV    B,A    ;RESULT IN B
  459.     MVI    C,0
  460.     LHLD    MTABL    ;PT TO BASE OF MACROS
  461.     DAD    B    ;PT TO MACRO
  462.     CALL    COPYM    ;COPY MACRO INTO LINE
  463.     DCX    D    ;BACK UP OVER <CR>
  464.     POP    H    ;GET PTR TO NEXT CHAR IN COMMAND LINE
  465. EXMAC2:
  466.     MOV    A,M    ;GET CHAR
  467.     STAX    D    ;PUT CHAR
  468.     INX    H    ;PT TO NEXT
  469.     INX    D
  470.     CALL    MTEST    ;TEST FOR END OF BUFFER
  471.     CPI    CR    ;DONE?
  472.     JZ    EXMAC3
  473.     CPI    EOLCH    ;LOGICAL EOL?
  474.     JNZ    EXMAC2
  475.     JMP    EXMAC1    ;PROCESS NEXT COMMAND
  476. EXMAC3:
  477.     LHLD    CTEMP    ;COPY COMMAND LINE BACK
  478.     XCHG
  479.     LHLD    INBUF    ;INTO INBUF
  480.     XCHG
  481.     CALL    COPYCR    ;COPY TO <CR>
  482.     LHLD    INBUF    ;PT TO INBUF
  483.     RET        ;EXPANSION COMPLETE
  484. ;
  485. ;Copy Macro Into Command Line Buffer
  486. ;
  487. COPYM:
  488.     MOV    A,M    ;GET CHAR
  489.     STAX    D    ;PUT CHAR
  490.     INX    H    ;PT TO NEXT
  491.     INX    D
  492.     CALL    MTEST    ;CHECK FOR LIMIT
  493.     CPI    CR    ;END OF MACRO?
  494.     JNZ    COPYM
  495.     RET
  496. ;
  497. ;Test for Buffer Full
  498. ;
  499. MTEST:
  500.     PUSH    H    ;SAVE HL
  501.     PUSH    PSW    ;SAVE A
  502.     LHLD    CTEMPX    ;CHECK FOR END OF BUFFER
  503.     MOV    A,H    ;GET PAGE
  504.     CMP    D    ;CHECK PAGE
  505.     JZ    MACERR
  506.     POP    PSW    ;GET A
  507.     POP    H    ;GET HL
  508.     RET
  509. ;
  510. ;Macro Command Expansion Error
  511. ;
  512. MACERR:
  513.     CALL    ILPRT
  514.     DB    CR,LF,'Error -- Macro Expanded Command Line too Long',0
  515.     JMP    PRMPTR    ;NEW COMMAND
  516. ;
  517. ;Save INBUF into PINBUF for later processing by '@' command
  518. ;
  519. SINBUF:
  520.     LHLD    PINBUF        ;PT TO PINBUF (PREVIOUS INBUF)
  521.     XCHG
  522.     LHLD    INBUF        ;PT TO INBUF
  523. ;
  524. ;Copy (HL) to (DE) until <CR> Encountered
  525. ;
  526. COPYCR:
  527.     MOV    A,M    ;GET CHAR
  528.     STAX    D    ;PUT CHAR
  529.     INX    H    ;PT TO NEXT
  530.     INX    D
  531.     CPI    CR    ;DONE?
  532.     JNZ    COPYCR
  533.     RET
  534.  
  535. ;
  536. ;Command Not Found Error
  537. ;
  538. WHAT:
  539.     POP    H    ; RESTORE HL
  540.     CALL    ILPRT
  541.     DB    DIM,'Invalid Command at or after ',BRIGHT,0
  542.     MOV    A,B    ;GET COMMAND LETTER
  543.     CALL    TYPE    ;PRINT IT
  544.     JMP    PRMPTR
  545. ;
  546. ;Memory full error
  547. ;
  548. MEMFUL:
  549.     CALL    ILPRT
  550.     DB    '+++ Out of memory +++'
  551.     DB    CR,LF,0
  552.     JMP    PRMPTR
  553. ;
  554. ;COMMAND:  E
  555. ;Edit Current Block
  556. ;
  557. EROW    EQU    6    ;FIRST ROW OF EDITOR DISPLAY
  558. ECOL    EQU    4    ;FIRST COL OF EDITOR DISPLAY
  559. ECOLC    EQU    ECOL+16*3+2    ;FIRST COL OF EDITOR CHAR DISPLAY
  560. ECURS    EQU    '>'    ;EDITOR CURSOR
  561. ;
  562. EDIT:
  563.     CALL    SINBUF    ;SAVE COMMAND LINE AS PREVIOUS
  564.     MVI    A,0FFH
  565.     STA    EDRUN    ;EDITOR IS RUNNING
  566. ;
  567. ; SET UP ARROW KEYS
  568. ;
  569.     LHLD    ENVPTR    ;PT TO ENVIRONMENT DESCRIPTOR
  570.     LXI    D,80H+10H    ;PT TO ARROW KEY INFO
  571.     DAD    D
  572.     LXI    D,EDCURT    ;PT TO CURSOR TABLE
  573.     MVI    B,4    ;4 ARROW KEYS
  574. EDITA:
  575.     MOV    A,M    ;GET CHAR
  576.     STAX    D    ;STORE CHAR
  577.     INX    H    ;PT TO NEXT
  578.     INX    D    ;PT TO NEXT ENTRY
  579.     INX    D
  580.     INX    D
  581.     DJNZ    EDITA    ;COUNT DOWN
  582. ;
  583. ; REENTER EDIT WITH PTRS RESET
  584. ; REFRESH EDIT SCREEN
  585. ;
  586. EDIT0:
  587.     CALL    CLS    ;NEW SCREEN
  588.     CALL    AT
  589.     DB    2,32    ;ROW 2, COL 32
  590.     CALL    ILPRT    ;BANNER
  591.     DB    'DU3 Block Editor',0
  592.     MVI    H,EROW+9    ;POSITION FOR COMMAND DISPLAY
  593.     MVI    L,1
  594.     CALL    GOTOXY    ;POSITION CURSOR
  595.     CALL    ILPRT    ;PRINT COMMAND SUMMARY
  596.     DB    ' -- Movement --'
  597.     DB    '  -------------- Operation ---------------',CR,LF
  598.     DB    '      ^E          '
  599.     DB    DIM,'Enter: ',BRIGHT,'A',DIM,' ASCII Chars',BRIGHT
  600.     DB    '      +',DIM,' Next Sector',BRIGHT,CR,LF
  601.     DB    '       ^          '
  602.     DB    DIM,'       ',BRIGHT,'H',DIM,' Hex Numbers',BRIGHT
  603.     DB    '      -',DIM,' Last Sector',BRIGHT,CR,LF
  604.     DB    '  ^S <-+-> ^D    '
  605.     DB    '                     '
  606.     DB    '     ^C',DIM,' Exit DU3   ',BRIGHT
  607.     DB    CR,LF
  608.     DB    '       v          '
  609.     DB    'C',DIM,' DU3 Command Line  ',BRIGHT
  610.     DB    '     ^R',DIM,' Rescreen   ',BRIGHT,CR,LF
  611.     DB    '      ^X          '
  612.     DB    'X',DIM,' Exit Editor to DU3',BRIGHT
  613.     DB    '     ^W',DIM,' Write Block',BRIGHT
  614.     DB    0
  615.     CALL    AT
  616.     DB    2,65
  617.     CALL    ILPRT
  618.     DB    DIM,'Position:',BRIGHT,0
  619. ;    JMP    EDITCMD
  620. ;
  621. ; REFRESH SCREEN DISPLAY DATA ONLY
  622. ;
  623. EDITR:
  624.     XRA    A    ;A=0
  625.     STA    EINDEX    ;SET INDEX TO 0 (FIRST ELEMENT)
  626.     STA    EDERR    ;SET NO PREVIOUS ERROR
  627.     CALL    AT    ;POSITION CURSOR
  628.     DB    EROW-2,ECOL
  629.     CALL    INQSUB    ;PRINT POSITION DATA
  630.     CALL    EDPLOT    ;PLOT BUFFER DATA
  631. ;
  632. ; INPUT EDITOR COMMAND
  633. ;
  634. EDITCMD:
  635.     CALL    EDERCL    ;CLEAR EDITOR INVALID COMMAND MESSAGE
  636. EDITCMD1:
  637.     CALL    AT    ;POSITION FOR COMMAND LINE
  638.     DB    22,10
  639.     CALL    ILPRT
  640.     DB    DIM,'Edit Command?  ',BRIGHT,BS,0
  641.     CALL    CONIN    ;GET CHAR
  642.     CALL    UPCASE    ;CAPITALIZE
  643.     MOV    B,A    ;COMMAND IN B
  644.     LXI    D,EDCURT    ;PROCESS CURSOR COMMANDS FIRST
  645.     CALL    CMD    ;PROCESS COMMAND
  646.     LXI    D,ECMDTBL    ;EDITOR COMMAND TABLE
  647.     CALL    CMD    ;PROCESS COMMAND
  648.     MVI    A,0FFH    ;SET ERROR FLAG
  649.     STA    EDERR
  650.     CALL    AT    ;CLEAR ERROR MESSAGE
  651.     DB    23,15
  652.     CALL    ILPRT
  653.     DB    'Invalid Command',0
  654.     JMP    EDITCMD1
  655. ;
  656. ;Clear Editor Invalid Command Message
  657. ;
  658. EDERCL:
  659.     LDA    EDERR    ;PREVIOUS ERROR?
  660.     ORA    A    ;0=NO
  661.     RZ
  662.     XRA    A    ;CLEAR FLAG
  663.     STA    EDERR
  664.     CALL    AT    ;CLEAR ERROR MESSAGE
  665.     DB    23,15
  666.     CALL    ILPRT
  667.     DB    '                         ',0
  668.     RET
  669. ;
  670. ;PLOT BUFFER DATA
  671. ;
  672. EDPLOT:
  673.     MVI    H,EROW    ;SET ROW
  674.     MVI    L,ECOL-1    ;SET COLUMN <RLC-3/1/85>
  675.     CALL    GOTOXY    ;POSITION CURSOR
  676.     XCHG        ;POSITION IN DE
  677.     LXI    H,TBUFF    ;PT TO DATA
  678.     MVI    B,8    ;8 LINES
  679. EDIT00:
  680.     MVI    C,16    ;16 ELEMENTS
  681.     CALL    SPACE    ;PRINT LEADING SPACE <RLC-3/1/85>
  682. EDIT01:
  683.     MOV    A,M    ;GET BYTE
  684.     CALL    HEX    ;PRINT AS HEX
  685.     CALL    SPACE    ;PRINT 1 SPACE
  686.     INX    H    ;PT TO NEXT
  687.     DCR    C    ;COUNT DOWN
  688.     JNZ    EDIT01
  689.     XCHG        ;POSITION AGAIN
  690.     INR    H    ;NEXT ROW
  691.     CALL    GOTOXY
  692.     XCHG
  693.     DCR    B    ;COUNT DOWN
  694.     JNZ    EDIT00
  695.     MVI    H,EROW    ;RESET ROW
  696.     MVI    L,ECOLC    ;RESET COL
  697.     CALL    GOTOXY    ;POSITION CURSOR
  698.     XCHG        ;POSITION IN DE
  699.     LXI    H,TBUFF    ;PT TO DATA
  700.     MVI    B,8    ;8 LINES
  701. EDIT02:
  702.     CALL    ASTER    ;PRINT BAR
  703.     MVI    C,16    ;16 ELEMENTS
  704. EDIT03:
  705.     MOV    A,M    ;GET BYTE
  706.     ANI    7FH    ;MASK MSB
  707.     CPI    7FH    ;7FH IS DOT
  708.     JZ    EDIT7F
  709.     CPI    ' '    ;SPACE OR MORE?
  710.     JNC    EDIT04
  711. EDIT7F:
  712.     MVI    A,'.'    ;PRINT DOT
  713. EDIT04:
  714.     CALL    TYPE    ;PRINT BYTE
  715.     INX    H    ;PT TO NEXT
  716.     DCR    C    ;COUNT DOWN
  717.     JNZ    EDIT03
  718.     CALL    ASTER    ;PRINT ENDING BAR
  719.     XCHG        ;POSITION AGAIN
  720.     INR    H    ;NEXT ROW
  721.     CALL    GOTOXY
  722.     XCHG
  723.     DCR    B    ;COUNT DOWN
  724.     JNZ    EDIT02
  725.     CALL    EDCUR    ;POSITION CURSOR
  726.     RET
  727. ;
  728. ;EDITOR COMMAND TABLE
  729. ;
  730. ECMDTBL:
  731.     DB    CR    ;NOP
  732.     DW    EDITCMD
  733.     DB    'C'-'@'    ;^C = EXIT DU3
  734.     DW    EDCC
  735.     DB    'R'-'@'    ;^R = REFRESH
  736.     DW    EDIT0
  737.     DB    'E'-'@'    ;^E=UP
  738.     DW    EDUP
  739.     DB    'X'-'@'    ;^X=DOWN
  740.     DW    EDDOWN
  741.     DB    'D'-'@'    ;^D=RIGHT
  742.     DW    EDRIGHT
  743.     DB    'S'-'@'    ;^S=LEFT
  744.     DW    EDLEFT
  745.     DB    'W'-'@'    ;WRITE BLOCK
  746.     DW    EDITWR
  747.     DB    ' '    ;NOP
  748.     DW    EDITCMD
  749.     DB    '+'    ;ADVANCE
  750.     DW    EDITPLUS
  751.     DB    '-'    ;BACKUP
  752.     DW    EDITMINUS
  753.     DB    'A'    ;CHANGE ALPHA
  754.     DW    EDITALP
  755.     DB    'C'    ;COMMAND LINE
  756.     DW    EDITCL
  757.     DB    'H'    ;CHANGE HEX
  758.     DW    EDITHEX
  759.     DB    'X'    ;EXIT
  760.     DW    EDITX
  761.     DB    0    ;END OF TABLE
  762. ;
  763. ;  ARROW KEY DEFINITONS FROM TCAP
  764. ;
  765. EDCURT:
  766.     DB    0    ;0 INDICATES NO ARROW KEYS
  767.     DW    EDUP
  768.     DB    0
  769.     DW    EDDOWN
  770.     DB    0
  771.     DW    EDRIGHT
  772.     DB    0
  773.     DW    EDLEFT
  774.     DB    0    ;END OF TABLE
  775. ;
  776. ;EDITOR BUFFERS
  777. ;
  778. EINDEX:
  779.     DS    1    ;INDEX ENTRY
  780. EDERR:
  781.     DS    1    ;ERROR FLAG
  782. EDRUN:
  783.     DS    1    ;FLAG SAYING THAT EDITOR IS RUNNING
  784. ;
  785. ;Write Block to Disk
  786. ;
  787. EDITWR:
  788.     CALL    EDERCL    ;CLEAR ERROR LINE
  789.     CALL    WRITE    ;WRITE BLOCK
  790.     CALL    AT
  791.     DB    23,15    ;MESSAGE
  792.     CALL    ILPRT
  793.     DB    'Block Written',0
  794.     MVI    A,0FFH    ;SET ERROR
  795.     STA    EDERR
  796.     JMP    EDITCMD1
  797. ;
  798. ;Enter ASCII Chars
  799. ;
  800. EDITALP:
  801.     CALL    EDERCL    ;CLEAR ERROR LINE
  802.     CALL    AT
  803.     DB    22,35
  804.     CALL    ILPRT
  805.     DB    DIM,'Enter Text (<hh> for Hex)',BRIGHT
  806.     DB    CR,LF,' --> ',0
  807.     CALL    RDBUF1    ;INPUT TEXT WITHOUT PROMPT
  808.     CALL    EDPRCL    ;CLEAR PROMPT LINE
  809.     LDA    EINDEX    ;PT TO POSITION
  810.     LXI    D,TBUFF    ;COMPUTE OFFSET
  811.     ADD    E
  812.     MOV    E,A
  813.     MOV    A,D
  814.     ACI    0
  815.     MOV    D,A    ;DE PTS TO BYTE, HL PTS TO TEXT
  816. EDITA1:
  817.     MOV    A,M    ;GET CHAR
  818.     CPI    CR    ;EOL?
  819.     JZ    EDITA2    ;REFRESH SCREEN
  820.     CALL    GETVAL    ;GET ASCII OR <HEX> VALUE
  821.     STAX    D    ;UPDATE BYTE
  822.     INX    H    ;PT TO NEXT INPUT CHAR
  823.     INR    E    ;PT TO NEXT BUFFER BYTE
  824.     JNZ    EDITA1
  825. EDITA2:
  826.     CALL    EDPLOT    ;REPLOT
  827.     JMP    EDITCMD1    ;DONE-REFRESH SCREEN
  828. ;
  829. ;Enter Numbers
  830. ;
  831. EDITHEX:
  832.     CALL    EDERCL    ;CLEAR ERROR LINE
  833.     CALL    AT
  834.     DB    22,35
  835.     CALL    ILPRT
  836.     DB    DIM,'Enter Hex Numbers (#nn for Dec)'
  837.     DB    BRIGHT
  838.     DB    CR,LF,' --> ',0
  839.     CALL    RDBUF1    ;INPUT TEXT WITHOUT PROMPT
  840.     CALL    EDPRCL    ;CLEAR PROMPT LINE
  841.     LDA    EINDEX    ;PT TO POSITION
  842.     LXI    D,TBUFF    ;COMPUTE OFFSET
  843.     ADD    E
  844.     MOV    E,A
  845.     MOV    A,D
  846.     ACI    0
  847.     MOV    D,A    ;DE PTS TO BYTE, HL PTS TO TEXT
  848. EDITH1:
  849.     MOV    A,M    ;GET HEX DIGIT
  850.     CPI    CR    ;EOL?
  851.     JZ    EDITA2    ;REFRESH SCREEN
  852.     CPI    ' '    ;SKIP SPACES
  853.     JNZ    EDITH2
  854.     INX    H    ;SKIP SPACE
  855.     JMP    EDITH1
  856. EDITH2:
  857.     PUSH    D    ;SAVE PTR
  858.     CALL    HEXIN    ;GET VALUE AND POSITION HL
  859.     MOV    A,E    ;... IN A
  860.     POP    D    ;GET PTR
  861.     STAX    D    ;PUT BYTE
  862.     INR    E    ;ADVANCE TO NEXT BYTE
  863.     JNZ    EDITH1
  864.     JMP    EDITA2    ;DONE-REFRESH
  865. ;
  866. ;CLEAR PROMPT LINE
  867. ;
  868. EDPRCL:
  869.     CALL    AT    ;PROMPT LINE
  870.     DB    22,35
  871.     MVI    B,40    ;40 POSITIONS
  872.     CALL    EDPCL
  873.     CALL    AT    ;USER INPUT
  874.     DB    23,1
  875.     MVI    B,79    ;79 POSITIONS
  876. EDPCL:
  877.     CALL    SPACE    ;CLEAR PROMPT LINE WITH SPACES
  878.     DCR    B
  879.     JNZ    EDPCL
  880.     RET
  881. ;
  882. ;Enter Command Line from Editor
  883. ;
  884. EDITCL:
  885.     CALL    EDERCL    ;CLEAR ERROR LINE
  886.     CALL    CRLF    ;NEW LINE
  887.     JMP    PRMPTE    ;GET COMMAND LINE FROM USER
  888. ;
  889. ;Advance to Next Block
  890. ;
  891. EDITPLUS:
  892.     CALL    NXTSEC    ;ADVANCE SECTORS
  893. EDITP1:
  894.     PUSH    H
  895.     LHLD    CURSEC
  896.     XCHG
  897.     CALL    SETSEC    ;SET SECTOR
  898.     LHLD    CURTRK
  899.     XCHG
  900.     CALL    SETTRK    ;SET TRACK
  901.     POP    H
  902.     CALL    READ    ;READ IN BLOCK
  903.     CALL    CLCSUB    ;CALCULATE GROUP DATA
  904.     JMP    EDITR    ;REFRESH DATA
  905. ;
  906. ;Backup to Last Block
  907. ;
  908. EDITMINUS:
  909.     CALL    LSTSEC    ;BACKUP BLOCK
  910.     JMP    EDITP1
  911. ;
  912. ;Exit EDIT Mode
  913. ;
  914. EDITX:
  915.     XRA    A
  916.     STA    EDRUN    ;EDITOR IS NOT RUNNING NOW
  917.     CALL    EDERCL    ;CLEAR ERROR LINE
  918.     JMP    PRMPTR
  919. ;
  920. ;Exit DU3
  921. ;
  922. EDCC:
  923.     CALL    EDERCL    ;CLEAR ERROR LINE
  924.     JMP    EXIT
  925. ;
  926. ;EDIT MOVE: UP
  927. ;
  928. EDUP:
  929.     CALL    EDCCUR    ;CLEAR CURSOR
  930.     LDA    EINDEX    ;BACKUP INDEX BY 16
  931.     SUI    16
  932. ;
  933. ;Common EDIT MOVE Routine - on input, A=new index
  934. ;
  935. EDMOVE:
  936.     ANI    7FH    ;MOD 128
  937.     STA    EINDEX
  938.     CALL    EDCUR    ;SET CURSOR
  939.     JMP    EDITCMD
  940. ;
  941. ;EDIT MOVE: DOWN
  942. ;
  943. EDDOWN:
  944.     CALL    EDCCUR    ;CLEAR CURSOR
  945.     LDA    EINDEX    ;INCREMENT INDEX BY 16
  946.     ADI    16
  947.     JMP    EDMOVE    ;COMMON ROUTINE
  948. ;
  949. ;EDIT MOVE: RIGHT
  950. ;
  951. EDRIGHT:
  952.     CALL    EDCCUR    ;CLEAR CURSOR
  953.     LDA    EINDEX    ;INCREMENT INDEX BY 1
  954.     INR    A
  955.     JMP    EDMOVE    ;COMMON ROUTINE
  956. ;
  957. ;EDIT MOVE: LEFT
  958. ;
  959. EDLEFT:
  960.     CALL    EDCCUR    ;CLEAR CURSOR
  961.     LDA    EINDEX    ;DECREMENT INDEX BY 1
  962.     DCR    A
  963.     JMP    EDMOVE    ;COMMON ROUTINE
  964. ;
  965. ;EDIT SUBROUTINE: EDCUR
  966. ; Position Editor Cursor at EINDEX
  967. ;EDIT SUBROUTINE: EDCCUR
  968. ; Clear Editor Cursor at EINDEX
  969. ;
  970. EDCUR:
  971.     PUSH    H    ;SAVE HL
  972.     MVI    C,ECURS    ;CURSOR CHAR
  973.     CALL    EDSETCUR
  974.     CALL    AT    ;UPDATE DATA
  975.     DB    2,75
  976.     LDA    EINDEX    ;PT TO BYTE AT CURSOR
  977.     LXI    H,TBUFF
  978.     ADD    L
  979.     MOV    L,A
  980.     MOV    A,H
  981.     ACI    0
  982.     MOV    H,A    ;HL PTS TO BYTE AT CURSOR
  983.     MOV    A,M    ;GET BYTE
  984.     CALL    HEX    ;PRINT AS HEX
  985.     CALL    SPACE
  986.     MOV    A,M    ;GET BYTE
  987.     POP    H    ;RESTORE HL
  988.     ANI    7FH    ;MASK
  989.     CPI    7FH    ;7FH IS DOT
  990.     JZ    EDC7F
  991.     CPI    ' '    ;OUTPUT CHAR OR DOT
  992.     JNC    TYPE
  993. EDC7F:
  994.     MVI    A,'.'    ;DOT
  995.     JMP    TYPE
  996. EDCCUR:
  997.     MVI    C,' '    ;CLEAR CURSOR
  998. EDSETCUR:
  999.     CALL    EDROW    ;COMPUTE ROW
  1000.     ANI    0FH    ;COMPUTE COL MOD 16
  1001.     MOV    B,A    ;RESULT IN B
  1002.     ADD    A    ;*2
  1003.     ADD    B    ;*3
  1004.     ADI    ECOL    ;ADD IN COL
  1005.     DCR    A    ;SUBTRACT 1
  1006.     MOV    L,A    ;COL POSITION SET
  1007.     CALL    GOTOXY    ;POSITION CURSOR
  1008.     MOV    A,C    ;OUTPUT CHAR
  1009.     JMP    TYPE
  1010. ;
  1011. ;Compute Row from EINDEX
  1012. ;
  1013. EDROW:
  1014.     LDA    EINDEX    ;GET INDEX
  1015.     MOV    B,A    ;SAVE IN B
  1016.     RRC        ;DIVIDE BY 16
  1017.     RRC
  1018.     RRC
  1019.     RRC
  1020.     ANI    0FH    ;MASK FOR LSB ONLY
  1021.     ADI    EROW    ;COMPUTE ROW
  1022.     MOV    H,A    ;ROW SET
  1023.     MOV    A,B    ;GET INDEX
  1024.     RET
  1025. ;
  1026. ;COMMAND:  @
  1027. ;Repeat Previous Command Line
  1028. ;
  1029. PCMD:
  1030.     MOV    A,M    ;GET NEXT CHAR
  1031.     CPI    CR    ;SHOULD BE <CR>
  1032.     JZ    PCMD1
  1033.     CALL    ILPRT
  1034.     DB    CR,LF,'Warning:  Remainder of Command Line after "@" Deleted',0
  1035. PCMD1:
  1036.     CALL    ILPRT
  1037.     DB    CR,LF,DIM,'Command --',BRIGHT,CR,LF,0
  1038.     LHLD    INBUF    ;COPY INTO INBUF
  1039.     XCHG
  1040.     LHLD    PINBUF    ;GET PREVIOUS COMMAND
  1041. PCMD2:
  1042.     MOV    A,M    ;GET CHAR
  1043.     STAX    D    ;PUT CHAR
  1044.     INX    H    ;PT TO NEXT
  1045.     INX    D
  1046.     CPI    CR    ;END OF LINE?
  1047.     PUSH    PSW    ;SAVE FLAG
  1048.     CALL    TYPE    ;PRINT CHAR
  1049.     POP    PSW    ;GET FLAG
  1050.     JNZ    PCMD2
  1051.     MVI    A,LF    ;<LF>
  1052.     CALL    TYPE
  1053.     LHLD    INBUF    ;RESTART COMMAND PROCESSING
  1054.     JMP    PRMPTI    ;INCLUDE LOOP CAPABILITY
  1055. ;
  1056. ;COMMAND:  :
  1057. ;Define or Print Macro
  1058. ;:n<text> Defines Macro n, 0<=n<=9; ::n Prints Macro n, 0<=n<=9
  1059. ;
  1060. MAC:
  1061.     MOV    A,M    ;GET NEXT CHAR
  1062.     CALL    UPCASE    ;CAPITALIZE
  1063.     CPI    'P'    ;PRINT MACRO?
  1064.     JNZ    MACROD    ;IF NOT, DEFINE MACRO
  1065.     INX    H    ;PT TO MACRO NUMBER
  1066.     MOV    A,M    ;GET IT
  1067.     CALL    UPCASE    ;CAPITALIZE
  1068.     CPI    '@'    ;PRINT PREVIOUS COMMAND?
  1069.     JZ    PCPR
  1070.     PUSH    PSW    ;SAVE A
  1071.     call    cls
  1072.     cz    crlf
  1073.     CALL    ILPRT
  1074.     DB    DIM,'Macro Definitions --',BRIGHT,0
  1075.     POP    PSW    ;GET A
  1076.     CPI    'A'    ;PRINT ALL MACROS?
  1077.     JZ    AMACPR
  1078.     CALL    MNUM    ;CHECK FOR VALID NUMBER AND RETURN # IN D
  1079.     INX    H    ;PT TO CHAR AFTER MACRO NUMBER
  1080.     CALL    MACPR    ;PRINT MACRO WHOSE NUMBER IS IN D
  1081.     JMP    PROMPT
  1082. ;
  1083. ;Print Previous Command
  1084. ;
  1085. PCPR:
  1086.     INX    H    ;PT TO CHAR AFTER '@'
  1087.     LXI    D,PROMPT    ;SET UP RET ADR
  1088.     PUSH    D    ;RETURN ADR ON STACK
  1089.     PUSH    H    ;SAVE PTR
  1090.     CALL    ILPRT
  1091.     DB    DIM,'Previous Command Line Definition --',BRIGHT
  1092.     DB    CR,LF,'@: ',0
  1093.     LHLD    PINBUF    ;PT TO PREVIOUS COMMAND
  1094.     JMP    MPRINT        ;USE MACRO PRINT FACILITY
  1095. ;
  1096. ;Print All Macros
  1097. ;
  1098. AMACPR:
  1099.     INX    H    ;PT TO CHAR AFTER 'A'
  1100.     MVI    D,0    ;SET FOR FIRST MACRO
  1101. AMPRL:
  1102.     CALL    MACPR    ;PRINT MACRO WHOSE NUMBER IS IN D
  1103.     INR    D    ;INCREMENT MACRO NUMBER
  1104.     MOV    A,D    ;GET VALUE
  1105.     CPI    10    ;DONE?
  1106.     JNZ    AMPRL
  1107.     JMP    PROMPT    ;CONTINUE PROCESSING
  1108. ;
  1109. ;Print Macro Whose Number (0-9) is in D
  1110. ;
  1111. MACPR:
  1112.     PUSH    H    ;SAVE PTR
  1113.     CALL    ILPRT    ;PRINT HEADER
  1114.     DB    CR,LF,DIM,0
  1115.     MOV    A,D    ;GET NUMBER
  1116.     ADI    '0'    ;CONVERT TO ASCII
  1117.     CALL    TYPE    ;PRINT
  1118.     CALL    ILPRT
  1119.     DB    ': ',BRIGHT,0
  1120.     LHLD    MTABL    ;PT TO TABLE OF MACROS
  1121.     MVI    E,0    ;PAGE OFFSET OF ZERO; MACRO NUMBER ALREADY IN D
  1122.     DAD    D    ;PT TO MACRO
  1123. MPRINT:
  1124.     MOV    A,M    ;GET CHAR
  1125.     INX    H    ;PT TO NEXT
  1126.     CPI    CR    ;END OF MACRO?
  1127.     PUSH    PSW    ;SAVE FLAG
  1128.     CALL    TYPE    ;PRINT CHAR
  1129.     POP    PSW    ;GET FLAG
  1130.     JNZ    MPRINT
  1131.     MVI    A,LF    ;<LF>
  1132.     CALL    TYPE
  1133.     POP    H    ;GET PTR TO NEXT CHAR
  1134.     RET
  1135. ;
  1136. ;Check char in A for valid Macro Number (0-9), print error message if
  1137. ; not, return number in D if so
  1138. ;
  1139. MNUM:
  1140.     SUI    '0'    ;CONVERT TO 0-9
  1141.     JC    MNERR    ;ERROR IF LESS
  1142.     CPI    10    ;RANGE?
  1143.     JNC    MNERR
  1144.     MOV    D,A    ;RESULT IN D
  1145.     RET
  1146. MNERR:
  1147.     CALL    ILPRT
  1148.     DB    CR,LF,'Invalid Macro Number Specified in Command',0
  1149.     JMP    PRMPTR    ;NEW COMMAND
  1150. ;
  1151. ;Define Macro
  1152. ;
  1153. MACROD:
  1154.     CALL    MNUM    ;CHECK NUMBER AND RETURN IN D
  1155.     INX    H    ;PT TO CHAR AFTER MACRO NUMBER
  1156.     PUSH    H    ;SAVE PTR
  1157.     LHLD    MTABL    ;PT TO MACRO TABLE
  1158.     MVI    E,0    ;SET EVEN PAGE
  1159.     DAD    D    ;PT TO MACRO ENTRY IN HL
  1160.     XCHG        ;... IN DE
  1161.     POP    H    ;PT TO MACRO TEXT
  1162.     CALL    COPYCR    ;COPY TO <CR>
  1163.     JMP    PRMPTR    ;NEW COMMAND
  1164. ;
  1165. ;COMMAND:  !
  1166. ;Delay for user input
  1167. ;
  1168. UWAIT:
  1169.     CALL    WAIT    ; USE WAIT ROUTINE
  1170.     JMP    PROMPT
  1171. ;
  1172. ;COMMAND:  #
  1173. ;Print disk statistics
  1174. ;
  1175. STATS:
  1176.     PUSH    H    ;SAVE POINTER TO NEXT COMMAND
  1177.     call    cls
  1178.     cz    crlf
  1179.     CALL    ILPRT
  1180.     DB    DIM
  1181.     DB    '    -- Queue Information --',BRIGHT,CR,LF
  1182.     DB    CR,LF
  1183.     DB    0
  1184.     CALL    QSTATS    ;PRINT STATUS INFO
  1185.     CALL    ILPRT
  1186.     DB    CR,LF
  1187.     DB    DIM
  1188.     DB    '    -- Disk Information --',BRIGHT,CR,LF
  1189.     DB    CR,LF
  1190.     DB    DIM,'Disk Drive:        ',BRIGHT,0
  1191.     LDA    DRIVE
  1192.     ADI    'A'    ;CONVERT TO ASCII
  1193.     CALL    TYPE    ;PRINT DRIVE LETTER
  1194.     CALL    ILPRT
  1195.     DB    CR,LF,DIM,'Tracks:            ',BRIGHT,0
  1196.     LHLD    MAXTRK    ;PRINT NUMBER OF TRACKS
  1197.     INX    H
  1198.     CALL    DEC
  1199.     CALL    ILPRT
  1200.     DB    CR,LF,DIM,'Sectors/Track:        ',BRIGHT,0
  1201.     LHLD    SPT    ;PRINT NUMBER OF SECTORS/TRACK
  1202.     CALL    DEC
  1203.     CALL    ILPRT
  1204.     DB    CR,LF,DIM,'Group Size:        ',BRIGHT,0
  1205.     LDA    BLM    ;PRINT SIZE OF A GROUP
  1206.     INR    A
  1207.     MOV    L,A
  1208.     MVI    H,0
  1209.     CALL    DEC
  1210.     CALL    ILPRT
  1211.     DB    DIM,' Blocks/Group',BRIGHT
  1212.     DB    CR,LF,DIM,'Total Groups:        ',BRIGHT,0
  1213.     LHLD    DSM    ;PRINT TOTAL NUMBER OF GROUPS ON A DISK
  1214.     CALL    DEC
  1215.     CALL    ILPRT
  1216.     DB    CR,LF,DIM,'Directory Entries:    ',BRIGHT,0
  1217.     LHLD    DRM    ;PRINT NUMBER OF DIRECTORY ENTRIES
  1218.     INX    H
  1219.     CALL    DEC
  1220.     CALL    ILPRT
  1221.     DB    CR,LF,DIM,'System Tracks:        ',BRIGHT,0
  1222.     LHLD    SYSTRK    ;PRINT NUMBER OF SYSTEM TRACKS
  1223.     CALL    DEC
  1224.     CALL    SWAIT
  1225.     POP    H    ;RESTORE POINTER TO NEXT COMMAND
  1226.     JMP    PROMPT
  1227. ;
  1228. ;COMMAND:  N
  1229. ;The following command resets the disk
  1230. ;system thru CP/M, and may be usable for
  1231. ;changing the disk density or format.
  1232. ;This can only be done if your BIOS resets
  1233. ;the auto-density select parameters at
  1234. ;every track-zero access.
  1235. ;
  1236. NEWDSK:
  1237.     PUSH    H    ;SAVE POINTER TO NEXT LETTER
  1238.     MVI    C,RESETDK    ;BDOS RESET DISK FUNCTION
  1239.     CALL    BDOS
  1240.     LDA    DRIVE    ;RESELECT CURRENT DRIVE
  1241.     MOV    C,A
  1242.     POP    H
  1243.     CALL    SELECT
  1244.     JMP    PROMPT
  1245. ;
  1246. ;COMMAND:  Q
  1247. ;Queue Control
  1248. ;
  1249. QUEUER:
  1250.     MOV    A,M    ;GET 2ND ARGUMENT
  1251.     CALL    UPCASE    ;CAPITALIZE
  1252.     CPI    EOLCH    ;END OF LINE?
  1253.     JZ    QSTAT    ;STATUS REPORT
  1254.     CPI    CR    ;END OF LINE?
  1255.     JZ    QSTAT
  1256.     INX    H    ;PT TO AFTER KEY CHAR
  1257.     PUSH    H    ;SAVE PTR
  1258.     CPI    'Z'    ;ZERO QUEUE?
  1259.     JZ    QZERO
  1260.     CPI    'S'    ;SAVE QUEUE?
  1261.     JZ    QFSAVE
  1262.     POP    H    ;GET PTR
  1263.     CALL    ILPRT
  1264.     DB    'Invalid Queue Command',CR,LF,0
  1265.     JMP    PRMPTR    ;ABORT LINE ON ERROR
  1266. ;
  1267. ;  Zero the Queue
  1268. ;
  1269. QZERO:
  1270.     LHLD    DIRECT    ;ZERO QUEUE
  1271.     SHLD    QNXT    ;SET NEXT
  1272.     SHLD    QLST    ;SET LAST
  1273.     LXI    H,0    ;ZERO COUNT
  1274.     SHLD    QCNT
  1275.     POP    H    ;GET PTR AND FALL THRU TO QSTAT
  1276. ;
  1277. ;  Print Status of Queue
  1278. ;
  1279. QSTAT:
  1280.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  1281.     call    cls
  1282.     cz    crlf
  1283.     CALL    ILPRT
  1284.     DB    DIM
  1285.     DB    '** Queue Status Summary **'
  1286.     DB    BRIGHT
  1287.     DB    CR,LF,0
  1288.     CALL    QSTATS    ;PRINT STATUS
  1289.     POP    H    ;RESTORE PTR
  1290.     JMP    PROMPT
  1291. QSTATS:
  1292.     LHLD    QCNT    ;GET SIZE OF QUEUE
  1293.     CALL    PRQCNT    ;PRINT DATA
  1294.     CALL    PRQSPAC    ;PRINT SPACE AVAILABLE INFO
  1295.     CALL    ILPRT
  1296.     DB    CR,LF
  1297.     DB    DIM,'Group Save Buffer Address:  ',BRIGHT,0
  1298.     PUSH    H
  1299.     LHLD    GBUFF    ;BC=ADDRESS
  1300.     MOV    B,H
  1301.     MOV    C,L
  1302.     POP    H
  1303.     CALL    HEXB1    ;PRINT AS HEX
  1304.     CALL    ILPRT
  1305.     DB    ' Hex',CR,LF
  1306.     DB    0
  1307.     CALL    ILPRT
  1308.     DB    DIM,'Address of Head of Queue:   ',BRIGHT,0
  1309.     LHLD    QNXT    ;PRINT ADDRESS OF HEAD OF QUEUE
  1310.     MOV    B,H    ;... ADDRESS IN BC
  1311.     MOV    C,L
  1312.     CALL    HEXB1    ;PRINT IN HEX
  1313.     CALL    ILPRT
  1314.     DB    ' Hex',CR,LF
  1315.     DB    DIM,'Address of Tail of Queue:   ',BRIGHT,0
  1316.     LHLD    QLST    ;PRINT ADDRESS OF TAIL OF QUEUE
  1317.     MOV    B,H
  1318.     MOV    C,L
  1319.     CALL    HEXB1
  1320.     CALL    ILPRT
  1321.     DB    ' Hex',CR,LF,0
  1322.     RET
  1323. ;
  1324. ;  Print Amount of Space Left in Queue
  1325. ;
  1326. PRQSPAC:
  1327.     LXI    B,-1    ;SET COUNT
  1328.     LHLD    QLST    ;GET PTR TO QUEUE TAIL
  1329. QSTAT1:
  1330.     INX    B    ;INCREMENT COUNT
  1331.     LXI    D,80H    ;PT TO NEXT QUEUE ELEMENT
  1332.     DAD    D
  1333.     XCHG        ;WRAP AROUND
  1334.     CALL    QWRAP
  1335.     LHLD    QNXT    ;GET PTR TO FIRST ELEMENT
  1336.     XCHG
  1337.     MOV    A,H    ;COMPARE
  1338.     CMP    D
  1339.     JNZ    QSTAT1
  1340.     MOV    A,L
  1341.     CMP    E
  1342.     JNZ    QSTAT1
  1343.     MOV    H,B    ;HL=BLOCK COUNT
  1344.     MOV    L,C
  1345.     CALL    DEC    ;PRINT AS DECIMAL
  1346.     CALL    ILPRT
  1347.     DB    DIM,'    Blocks Left in Queue',BRIGHT,CR,LF,0
  1348.     RET
  1349. ;
  1350. ;  Save Queue as a File
  1351. ;
  1352. QFSAVE:
  1353.     MOV    A,M    ;GET FIRST CHAR OF FILE NAME
  1354.     CPI    EOLCH    ;EOL?
  1355.     JZ    WHAT
  1356.     CPI    CR    ;EOL?
  1357.     JZ    WHAT
  1358.     LXI    D,FCB    ;START TO FILL FCB
  1359.     XRA    A    ;A=0
  1360.     STAX    D    ;SELECT DEFAULT DRIVE
  1361.     INX    D    ;PT TO FILE NAME
  1362.     MVI    B,8    ;SAVE FILE NAME
  1363.     CALL    MVNAME
  1364.     MVI    B,3    ;SAVE FILE TYPE
  1365.     CALL    MVNAME
  1366.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  1367.     LHLD    QCNT    ;ANY ELEMENTS IN QUEUE?
  1368.     MOV    A,H
  1369.     ORA    L
  1370.     JZ    QEMPTY
  1371.     PUSH    H    ;SAVE QUEUE COUNT
  1372.     CALL    NORITE    ;CAN'T WRITE NOW
  1373.     LXI    D,FCB    ;PT TO FCB
  1374.     CALL    FCBINIT    ;INIT FCB
  1375.     MVI    C,DELF    ;DELETE FILE
  1376.     PUSH    D    ;SAVE DE
  1377.     CALL    BDOS
  1378.     POP    D
  1379.     CALL    FCBINIT    ;INIT FCB AGAIN
  1380.     MVI    C,MAKEF    ;CREATE FILE
  1381.     CALL    BDOS
  1382.     POP    B    ;GET QUEUE COUNT IN BC
  1383.     LHLD    QNXT    ;PT TO NEXT BLOCK IN QUEUE
  1384. QFS1:
  1385.     PUSH    B    ;SAVE COUNT
  1386.     LXI    D,TBUFF    ;COPY INTO TBUFF
  1387.     MVI    B,128    ;128 BYTES
  1388.     CALL    MOVE
  1389.     XCHG        ;PT TO NEXT QUEUE BLOCK IN DE
  1390.     CALL    QWRAP    ;WRAP AROUND
  1391.     PUSH    D    ;SAVE PTRS
  1392.     LXI    D,FCB    ;PT TO FCB
  1393.     MVI    C,WRITEF    ;WRITE BLOCK TO FILE
  1394.     CALL    BDOS
  1395.     POP    H    ;GET PTR TO NEXT BLOCK
  1396.     POP    B    ;GET COUNT
  1397.     DCX    B    ;COUNT DOWN
  1398.     MOV    A,B    ;DONE?
  1399.     ORA    C
  1400.     JNZ    QFS1
  1401.     LXI    D,FCB    ;CLOSE FILE
  1402.     MVI    C,CLOSEF
  1403.     CALL    BDOS
  1404.     CALL    ILPRT
  1405.     DB    'Queue Saved in File',CR,LF,0
  1406.     POP    H    ;PT TO NEXT CHAR
  1407.     JMP    PROMPT
  1408. FCBINIT:
  1409.     PUSH    D    ;SAVE PTR
  1410.     LXI    H,12    ;SKIP TO EX FIELD
  1411.     DAD    D
  1412.     MVI    B,24    ;ZERO 36 BYTES
  1413.     XRA    A    ;A=0
  1414. FCBIN1:
  1415.     MOV    M,A    ;STORE ZEROES
  1416.     INX    H
  1417.     DJNZ    FCBIN1
  1418.     POP    D    ;RESTORE PTR
  1419.     RET
  1420. ;
  1421. ;COMMAND:  *
  1422. ;Repeat buffer contents
  1423. ;
  1424. REPEAT:
  1425.     CALL    DECIN    ;NN SPECIFIED?
  1426.     MOV    A,D
  1427.     ORA    E
  1428.     JZ    NNN    ;NO -- SET FOR INFINITE LOOP OR SIMPLE REPEAT
  1429.     LHLD    TOGO    ;LOAD LOOP FLAG
  1430.     INX    H    ;TEST FOR FIRST TIME
  1431.     MOV    A,H
  1432.     ORA    L    ;WAS IT 0FFFFH?; IF SO, WE HAVE NEW VALUE
  1433.     JNZ    NNN    ;NO: COUNTING
  1434.     XCHG        ;GET COUNT
  1435.     SHLD    TOGO    ;SET COUNT
  1436. ;
  1437. NNN:
  1438.     LHLD    TOGO    ;GET CURRENT COUNT
  1439.     XCHG        ;DE=CURRENT COUNT, HL=COUNT LIMIT
  1440.     LHLD    INBUF    ;PT TO FIRST CHAR FOR REPEAT
  1441.     INX    D    ;TEST FOR 0FFFFH
  1442.     MOV    A,D    ;IF 0FFFFH, INX D MADE DE=0
  1443.     ORA    E
  1444.     JZ    PROMPT    ;CONTINOUS LOOP IF 0FFFFH
  1445.     DCX    D    ;COUNT DOWN
  1446.     DCX    D    ;MAKE UP FOR PREV INX D
  1447.     XCHG
  1448.     SHLD    TOGO    ;SET NEW COUNT (1 LESS THAN BEFORE)
  1449.     MOV    A,H    ;ALL DONE?
  1450.     ORA    L
  1451.     XCHG        ;GET BACK INBUF PTR IN HL
  1452.     JNZ    PROMPT    ;KEEP GOING IF NOT YET ZERO
  1453.     JMP    PRMPTR    ;ALL DONE
  1454. ;
  1455. ;COMMAND:  U
  1456. ;Set CP/M 2.x user number
  1457. ;
  1458. USER:
  1459.     CALL    DECIN    ;GET REQUESTED USER NO.
  1460.     LDA    MUSER    ;GET MAX USER
  1461.     MOV    B,A    ;... IN B
  1462.     MOV    A,E
  1463.     CMP    B    ;VALID?
  1464.     JNC    USRERR
  1465.     MOV    A,D    ;HIGH-ORDER BYTE MUST BE ZERO FOR VALID NUMBER
  1466.     ORA    A
  1467.     JNZ    USRERR
  1468.     MOV    A,E    ;SAVE USER NUMBER
  1469.     STA    UNUM
  1470.     MVI    C,SUSER    ;SET USER NUMBER
  1471.     PUSH    H        ;SAVE CHAR POINTER
  1472.     CALL    BDOS        ;SET USER NO.
  1473.     POP    H
  1474.     JMP    PROMPT
  1475. USRERR:
  1476.     CALL    ILPRT
  1477.     DB    'User Number Out of Range',CR,LF,0
  1478.     JMP    PRMPTR
  1479. ;
  1480. ;COMMAND:  P
  1481. ;Toggle print flag
  1482. ;
  1483. PRNTFF:
  1484.     LDA    PFLAG    ;TOGGLE PRINT FLAG
  1485.     XRI    1
  1486.     STA    PFLAG
  1487.     JMP    PROMPT
  1488. ;
  1489. ;COMMAND:  Z
  1490. ;Sleep routine, in seconds
  1491. ;
  1492. SLEEP:
  1493.     CALL    DECIN    ;GET COUNT IF ANY
  1494.     MOV    A,E    ;ANY?
  1495.     ORA    A
  1496.     JNZ    SLEPLP
  1497.     MVI    E,1    ; 1 SEC DEFAULT
  1498. ;
  1499. SLEPLP:
  1500.     LDA    CLOCK    ; GET CLOCK SPEED
  1501.     MOV    D,A
  1502. ;
  1503. SLEEP1:
  1504.     LXI    B,41700    ; APPROX 1 SEC @ 1MHz
  1505. ;
  1506. SLEEP2:
  1507.     DCX    B    ;COUNT DOWN FOR 1 MHz [5 CYCLES]
  1508.     MOV    A,B    ;[5 CYCLES] <-- TOTAL TIME: 24 CYCLES
  1509.     ORA    C    ;[4 CYCLES] <-- (24 MU-SECS AT 1MHz)
  1510.     JNZ    SLEEP2    ;[10 CYCLES]
  1511.     PUSH    D
  1512.     CALL    CTLCS    ;ABORT?
  1513.     POP    D
  1514.     JZ    PRMPTR
  1515.     DCR    D    ;COUNT DOWN FOR CLOCK SPEED
  1516.     JNZ    SLEEP1
  1517.     DCR    E    ;COUNT DOWN NUMBER OF REQUESTED SECONDS
  1518.     JNZ    SLEPLP
  1519.     JMP    PROMPT
  1520. ;
  1521. ;Check for control-C or S
  1522. ;
  1523. CTLCS:
  1524.     CALL    CONST    ;CHAR AVAILABLE?
  1525.     ORA    A
  1526.     JNZ    GETC
  1527.     ORI    1    ;NO CHAR, RETURN NZ
  1528.     RET
  1529. ;
  1530. GETC:    CALL    CONIN    ;INPUT CHAR
  1531.     ANI    1FH    ;ALLOW ASCII
  1532.     CPI    'S'-40H    ;WAIT FOR NEXT CHAR IF ^S OR S OR s
  1533.     CZ    CONIN
  1534.     CPI    'C'-40H    ;CHECK FOR ^C OR C OR c
  1535.     RET        ;0 SET IF CTL-C
  1536. ;
  1537. ;Initialize Memory Buffers
  1538. ;
  1539. INITP:
  1540.     XRA    A    ;A=0
  1541.     STA    HEXAD    ;CLEAR ADDRESS
  1542.     STA    HEXAD+1
  1543.     STA    PFLAG    ;SET NO PRINT
  1544.     STA    SAVEFL    ;SET NO SAVE DONE
  1545.     STA    WRFLG    ;MAY NOT WRITE
  1546.     STA    DIRPOS    ;SET NO DIRECTORY POSITION
  1547.     STA    FINDFL    ;SET NO POSITION
  1548.     INR    A    ;A=1
  1549.     STA    FTSW    ;SET SEARCH WITHOUT INCREMENT
  1550.     STA    NOTPOS    ;NOT POSITIONED
  1551.     LXI    H,0    ;HL=0
  1552.     SHLD    QCNT    ;SET NO ELEMENTS IN QUEUE
  1553.     SHLD    MFPTR    ;SET NO MULTI FILE PTR
  1554.     SHLD    CURTRK    ;SET TRACK 0
  1555.     INX    H    ;HL=1
  1556.     SHLD    CURSEC    ;SET LOGICAL SECTOR 1
  1557.     SHLD    PHYSEC    ;SET PHYSICAL SECTOR 1
  1558.     LHLD    PINBUF    ;SET PREVIOUS COMMAND TO NIL
  1559.     MVI    M,CR    ;CLEAR PREVIOUS COMMAND
  1560.     LHLD    DIRECT    ;SET FIRST AND LAST QUEUE ELEMENT PTRS
  1561.     SHLD    QNXT
  1562.     SHLD    QLST
  1563.  
  1564.     ; Initialize Default Macros -- new block by <JPS>
  1565.  
  1566.     LHLD    MTABL    ;CLEAR MACRO TABLE
  1567.     MVI    B,10    ;10 ENTRIES
  1568.     lxi    d,imac0    ;point to beginning of default macro table
  1569.  
  1570. initp1:    push    h    ;save pointer to start of each macro
  1571.  
  1572. initp2:    ldax    d    ;get next initial macro character
  1573.     mov    m,a    ;store it in macro table
  1574.     inx    d
  1575.     inx    h
  1576.     cpi    cr    ;end of macro?
  1577.     jnz    initp2
  1578.  
  1579.     pop    h    ;retrieve pointer to start of this macro
  1580.     dcr    b    ;see if we've done all macros
  1581.     rz        ;if so, return
  1582.     inr    h    ;point to next macro
  1583.     jmp    initp1    
  1584.  
  1585. ;INITP1:
  1586. ;    MVI    M,CR    ;STORE <CR>
  1587. ;    INR    H    ;PT TO NEXT PAGE
  1588. ;    DJNZ    INITP1
  1589. ;    RET
  1590.  
  1591. ; End of Block Changed by <JPS>
  1592.  
  1593. ;
  1594. ;Set up flags, etc, at initialization
  1595. ;Find our way at initialization
  1596. ;
  1597. GETSTP:
  1598.     PUSH    H
  1599.     LHLD    INBUF    ;PT TO INPUT BUFFER
  1600.     MVI    M,CR    ;INITIALIZE INPUT BUFFER
  1601.     POP    H
  1602.     MVI    C,SUSER    ;GET USER NUMBER
  1603.     MVI    E,0FFH    ;GET USER
  1604.     CALL    BDOS
  1605.     STA    UNUM    ;SET USER NUMBER
  1606.     MVI    C,GETDSK
  1607.     CALL    BDOS    ;GET CURRENT DISK
  1608.     MOV    C,A    ;WE HAVE TO SELECT
  1609.     JMP    SELECT    ;TO GET THE DPH
  1610. ;
  1611. ;COMMAND:  L
  1612. ;Log in the selected disk
  1613. ;
  1614. LOGIN:
  1615.     CALL    DOLOG
  1616.     JMP    PROMPT
  1617. ;
  1618. DOLOG:
  1619.     MOV    A,M    ;DISK REQUESTED?
  1620.     LXI    D,0
  1621.     CPI    CR    ;NO REQUEST OF PHYSICAL EOL
  1622.     JZ    LGNODK
  1623.     CPI    EOLCH    ;NO REQUEST IF LOGICAL EOL
  1624.     JZ    LGNODK
  1625.     CALL    UPCASE    ;CAPITALIZE
  1626.     INX    H    ;POINT TO NEXT CHAR
  1627.     SUI    'A'    ;CONVERT TO 0-15
  1628.     MOV    C,A    ;DISK NUMBER IN C
  1629.     LDA    MDISK    ;GET MAX DISK
  1630.     MOV    B,A    ;... IN B
  1631.     MOV    A,C
  1632.     CMP    B
  1633.     JC    SELECT
  1634.     CALL    ILPRT
  1635.     DB    'Disk Letter Out of Range',CR,LF,0
  1636.     JMP    PRMPTR
  1637. ;
  1638. ;Select Disk Whose Number is in C (A=0, B=1, etc)
  1639. ;
  1640. SELECT:
  1641.     PUSH    H    ;SAVE PTR TO NEXT COMMAND LETTER
  1642.     MOV    A,C
  1643.     STA    DRIVE    ;REMEMBER LATER WHERE WE ARE
  1644. ;
  1645. VSELDK: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  1646.     MOV    A,H
  1647.     ORA    L
  1648.     JZ    WHAT    ;SELECT ERROR
  1649.     MOV    E,M    ;GET THE SECTOR TABLE PNTR
  1650.     INX    H
  1651.     MOV    D,M
  1652.     INX    H
  1653.     XCHG
  1654.     SHLD    SECTBL    ;SET THE SECTOR TABLE PTR
  1655.     LXI    H,8    ;OFFSET TO DPBPTR
  1656.     DAD    D
  1657.     MOV    A,M    ;PICK UP DPB POINTER
  1658.     INX    H    ;  TO USE
  1659.     MOV    H,M    ;  AS PARAMETER
  1660.     MOV    L,A    ;  TO LOGIT
  1661.     CALL    LOGIT
  1662.     LHLD    SYSTRK    ;RESET TRACK AND SECTOR
  1663.     XCHG        ;  TO DIRECTORY
  1664.     CALL    SETTRK    ;  ON EVERY
  1665.     LXI    D,1    ;  LOGIN
  1666.     CALL    SETSEC    ;  CHANGE
  1667.     LHLD    PHYSEC    ;THIS LOGIC WILL TELL
  1668.     MOV    A,H    ;  IF FIRST SEC
  1669.     ORA    L    ;  IS PHYSICAL 0
  1670.     STA    FIRST0
  1671.     CALL    CLCSUB    ;CALCULATE WHAT GROUP/GRPDISP WE ARE IN
  1672.     POP    H    ;GET PTR TO NEXT LETTER
  1673. ;
  1674. LGNODK:
  1675.     CALL    NORITE    ;SET NO DISK I/O DONE (NO POSITION)
  1676.     RET
  1677. ;
  1678. ;Read in the disk directory
  1679. ;
  1680. REDDIR:
  1681.     PUSH    H    ;SAVE PTR TO NEXT LETTER
  1682.     CALL    NORITE    ;POSITIONING LOST
  1683.     LHLD    SYSTRK    ;SAVE CURRENT TRACK
  1684.     SHLD    CURTRK
  1685.     LXI    H,1    ;SET SECTOR 1
  1686.     SHLD    CURSEC
  1687.     LHLD    DRM    ;GET DIR SIZE FROM DPB
  1688.     INX    H    ;MAKE 1-RELATIVE
  1689.     CALL    ROTRHL
  1690.     CALL    ROTRHL    ;DIVIDE BY 4 (4 NAMES/SECTOR)
  1691.     MOV    B,H    ;BC=NUMBER OF BLOCKS TO READ
  1692.     MOV    C,L
  1693.     XCHG
  1694.     LHLD    DIRECT    ;DMA ADDR
  1695.     XCHG        ;... IN DE
  1696. ;
  1697. ;Read Disk Directory Loop
  1698. ;
  1699. RDIRLP:
  1700.     PUSH    B    ;SAVE REGS
  1701.     PUSH    D
  1702.     MOV    B,D    ;BC=DMA ADDRESS
  1703.     MOV    C,E
  1704.     LDA    BDOS+2    ;CHECK MEM AVAIL
  1705.     DCR    A    ;ARE WE RNNING INTO BDOS?
  1706.     CMP    D
  1707.     JC    MEMFUL    ;MEMORY FULL ERROR IF SO
  1708.     CALL    SETDMA    ;SET DMA ADDRESS TO THAT IN BC
  1709.     LHLD    CURTRK    ;SET TRACK
  1710.     XCHG
  1711.     CALL    SETTRK
  1712.     LHLD    CURSEC    ;SET SECTOR
  1713.     XCHG
  1714.     CALL    SETSEC
  1715.     CALL    READ    ;READ DIRECTORY BLOCK
  1716.     CALL    NXTSEC    ;INCREMENT TO NEXT SECTOR
  1717.     POP    D
  1718.     POP    B
  1719.     LXI    H,80H    ;ADVANCE TO NEXT DMA ADDRESS
  1720.     DAD    D
  1721.     XCHG        ;DE=NEXT DMA ADDRESS
  1722.     DCX    B    ;COUNT DOWN DIRECTORY BLOCKS
  1723.     MOV    A,B
  1724.     ORA    C
  1725.     JNZ    RDIRLP
  1726.     LXI    B,TBUFF    ;RESET DMA ADDRESS TO TBUFF
  1727.     CALL    SETDMA
  1728.     POP    H    ;GET PTR TO NEXT CHAR
  1729.     RET
  1730. ;
  1731. ;COMMAND:  M
  1732. ;Map the directory
  1733. ;
  1734. MAP:
  1735.     PUSH    H    ;SAVE PTR
  1736.     LHLD    QCNT    ;GET COUNT
  1737.     MOV    A,H
  1738.     ORA    L
  1739.     POP    H
  1740.     JZ    MAP1    ;PROCEED IF QUEUE EMPTY
  1741.     CALL    ILPRT    ;PRINT ABORT MESSAGE
  1742.     DB    CR,LF,'MAP not permitted -- Block Queue would be overlaid',0
  1743.     JMP    PRMPTR
  1744. MAP1:
  1745.     CALL    PAGSET    ;SET PAGING COUNTER
  1746.     XRA    A
  1747.     STA    ONLY1    ;SET FLAG FOR ALL GROUPS (NOT ONLY 1)
  1748.     CALL    REDDIR    ;READ IN DIRECTORY
  1749.     MVI    C,0    ;INIT START GRP #
  1750.     LDA    AL0    ;READ DIR GRP BITS
  1751.     CALL    COLECT    ;COLLECT COUNT OF DIR GRPS..
  1752.     LDA    AL1    ;..IN REGISTER C
  1753.     CALL    COLECT
  1754.     MVI    B,0    ;BC NOW HAS A DEFAULT START GRP #
  1755.     CALL    HEXIN    ;GET SPECIFIED GROUP IF ANY
  1756.     PUSH    H    ;SAVE INBUF PTR
  1757.     MOV    A,E    ;GET START
  1758.     ORA    D    ;NOTHING?
  1759.     JZ    MAPDF    ;..YES, DFLT
  1760.     MVI    A,0FFH    ;SET FLAG FOR ONLY 1 GROUP
  1761.     STA    ONLY1
  1762.     MOV    B,D    ;GET VALUE IN BC
  1763.     MOV    C,E
  1764. ;
  1765. MAPDF:
  1766.     CALL    HEXB    ;PRINT FIRST GROUP NUMBER
  1767.     MVI    A,'-'    ;PRINT SEPARATOR
  1768.     CALL    TYPE
  1769.     MVI    A,' '    ;SET NO DUPLICATES
  1770.     STA    DUPFLG
  1771.     CALL    GETGRP    ;GET GRP(C) TO HL
  1772. ;
  1773. MAPCNT:
  1774.     INX    B    ;NEXT GRP #
  1775.     PUSH    H
  1776.     LHLD    DSM    ;GET HIGHEST GRP #
  1777.     INX    H    ;PLUS 1 FOR COMPARISON
  1778.     MOV    A,L    ;WHEN BC REACHES DSM+1..
  1779.     CMP    C    ;..THEN WE HAVE EXCEEDED..
  1780.     JNZ    MAPC1    ;..THE DISK CAPACITY..
  1781.     MOV    A,H
  1782.     CMP    B
  1783. ;
  1784. MAPC1:
  1785.     POP    H
  1786.     JZ    MAPEND    ;..AND WE ARE DONE
  1787.     PUSH    H
  1788.     CALL    GETGRP    ;GET ANOTHER
  1789.     POP    D    ;SEE IF SAME
  1790.     CALL    CTLCS    ;ABORT?
  1791.     JZ    MAPND2
  1792.     MOV    A,D
  1793.     CMP    H
  1794.     JNZ    MAPDIF
  1795.     MOV    A,E
  1796.     CMP    L
  1797.     JZ    MAPCNT    ;SAME, CONTINUE
  1798. ;
  1799. ;Different file encountered
  1800. ;
  1801. MAPDIF:
  1802.     DCX    B
  1803.     CALL    HEXB    ;PRINT ENDING GROUP NUMBER
  1804.     INX    B
  1805.     XCHG
  1806.     CALL    MAPNAM    ;PRINT FILE NAME
  1807.     LDA    ONLY1    ;ONLY 1 NAME TO BE PRINTED?
  1808.     ORA    A    ;0=NO
  1809.     JNZ    MAPND1
  1810.     JMP    MAPDF
  1811. ;
  1812. ;End of map
  1813. ;
  1814. MAPEND:
  1815.     DCX    B    ;GET LAST
  1816.     CALL    HEXB    ;PRINT LAST GROUP NUMBER
  1817.     CALL    MAPNAM    ;PRINT FILE NAME
  1818.     CALL    WAIT    ;DELAY FOR USER
  1819. MAPND1:
  1820.     POP    H
  1821.     CALL    CRLF    ;NEW LINE
  1822. ;
  1823. ;End of map - reposition to previous group
  1824. ;
  1825. MAPND2:
  1826.     PUSH    H
  1827.     LHLD    GROUP    ;POINT TO GROUP IN DE
  1828.     XCHG
  1829.     JMP    POSGP2
  1830. ;
  1831. ;Print file name pointed to by HL
  1832. ;
  1833. MAPNAM:
  1834.     CALL    SPACE    ;LEADING SPACE
  1835.     MOV    A,H
  1836.     ORA    L    ;NONE?
  1837.     JZ    NONAME
  1838.     MOV    A,M    ;SEE IF ALLOC
  1839.     CPI    0E5H    ;FREE?
  1840.     MVI    A,' '    ;MARK ALLOCATED
  1841.     JNZ    MPNSP1
  1842.     MVI    A,'('    ;MARK NOT ALLOCATED (ERASED FILE)
  1843. ;
  1844. MPNSP1:
  1845.     CALL    TYPE    ;PRINT ALLOCATION INDICATOR (SPACE OR '(')
  1846.     PUSH    H    ;SAVE POINTER
  1847.     MOV    A,M
  1848.     CALL    HEX    ;SHOW USER NUMBER
  1849.     CALL    SPACE
  1850.     INX    H    ;SKIP USER BYTE
  1851.     PUSH    B
  1852.     MVI    B,8    ;PRINT FILE NAME
  1853.     CALL    MAPN2
  1854.     MVI    A,'.'    ;PRINT DECIMAL SEPARATOR
  1855.     CALL    TYPE
  1856.     MVI    B,3    ;PRINT FILE TYPE
  1857.     CALL    MAPN2
  1858.     LDA    DUPFLG    ;DUPLICATE?
  1859.     CALL    TYPE    ;SPACE OR STAR
  1860.     POP    B
  1861.     MOV    A,M    ;GET EXT
  1862.     CALL    HEX    ;PRINT EXTENT NUMBER
  1863.     POP    H
  1864.     MOV    A,M
  1865.     CPI    0E5H    ;DELETED ENTRY?
  1866.     MVI    A,' '    ;PRINT ENDING SPACE
  1867.     JNZ    MPNSP2
  1868.     MVI    A,')'    ;PRINT ALLOCATION FLAG
  1869. ;
  1870. MPNSP2:
  1871.     CALL    TYPE    ;")" IF ERASED FILE OR SPACE IF NOT
  1872.     JMP    FLIP
  1873. ;
  1874. NONAME:
  1875.     CALL    ILPRT
  1876.     DB    DIM,'    ++ Free ++      ',BRIGHT,0
  1877. ;
  1878. FLIP:
  1879.     LDA    TWOUP    ;FLIP FLAG FOR TWO ENTRIES PER LINE
  1880.     XRI    1
  1881.     STA    TWOUP
  1882.     JZ    PAGER    ;NEW LINE WITH PAGING IF REQUIRED
  1883. ;
  1884. DELIM:
  1885.     MVI    A,':'    ;PRINT DELIMITER BETWEEN ADJACENT ENTRIES ON LINE
  1886.     CALL    TYPE
  1887.     JMP    SPACE
  1888. ;
  1889. ;Print name pted to by HL, length in B
  1890. ;
  1891. MAPN2:
  1892.     MOV    A,M
  1893.     ANI    7FH    ;STRIP POSSIBLE 2.x ATTRIBUTE BIT
  1894.     INX    H
  1895.     CPI    ' '    ;PRINTABLE?
  1896.     JC    MAPN2H    ;..NO, IN HEX
  1897.     CPI    7EH    ;7E IS LEADIN ON SOME CRTS
  1898.     JC    MAPN2A
  1899. ;
  1900. MAPN2H:
  1901.     CALL    BHEX    ;PRINT A AS HEX CHARS
  1902.     JMP    MAPN2Z
  1903. ;
  1904. MAPN2A:
  1905.     CALL    TYPE    ;PRINT AS CHAR
  1906. ;
  1907. MAPN2Z:
  1908.     DJNZ    MAPN2
  1909.     RET
  1910. ;
  1911. ;Find which file group (BC) belongs to
  1912. ;
  1913. GETGRP:
  1914.     LHLD    DRM    ;MAX DIR ENTRY #
  1915.     INX    H    ;MAKE 1-RELATIVE
  1916.     SHLD    FILECT
  1917.     LXI    H,0
  1918.     SHLD    MFPTR    ;SET MULTI-FILE (MORE THAN ONE USER) PTR
  1919.     LHLD    DIRECT    ;PT TO DIRECTORY
  1920. ;
  1921. GETGLP:
  1922.     PUSH    H    ;SAVE POINTER TO NAME
  1923.     MOV    A,M    ;PICK UP DN BYTE
  1924.     CPI    0E5H    ;ERASED?
  1925.     JZ    GETGNF
  1926.     LXI    D,14    ;NOW GET RECORD COUNT
  1927.     DAD    D    ;  S2 PORTION ..
  1928.     MOV    A,M    ;  IS 0 IN CP/M 1.4
  1929.     ANI    0FH
  1930.     MOV    E,A
  1931.     INX    H
  1932.     MOV    A,M
  1933.     ORA    E
  1934.     JZ    GETGNF
  1935.     MVI    E,16    ;FIRST SET FOR 8-BIT GRPS
  1936.     LDA    DSM+1
  1937.     ORA    A
  1938.     JZ    SMALGP
  1939.     MVI    E,8    ;NOPE, BIG GROUPS
  1940. ;
  1941. SMALGP:
  1942.     MOV    D,A    ;SAVE GRP SIZE INDICATOR
  1943. ;
  1944. GETGL2:
  1945.     INX    H    ;POINTING INTO DM FIELD
  1946.     CALL    GRPCMP    ;COMPARE BC GP # AGAINST 1 DM FLD
  1947.     JNZ    NOTGOT    ;JUMP IF NOT FOUND
  1948. ;
  1949. ;Found the file
  1950. ;
  1951.     PUSH    H    ;SAVE GROUP PTR
  1952.     LHLD    MFPTR
  1953.     MOV    A,H    ;ANY ENTRIES?
  1954.     ORA    L
  1955.     POP    H    ;GET PTR
  1956.     XTHL        ;SAVE ENTRY START AND SAVE PTR
  1957.     JZ    MPFRST    ;IF ZERO, THEN FIRST ENTRY
  1958.     MVI    A,'*'    ;SET MULTI FLAG
  1959.     STA    DUPFLG
  1960. MPFRST:
  1961.     SHLD    MFPTR    ;SAVE POINTER
  1962.     XTHL        ;RESTORE ENTRY START AND GET PTR
  1963. NOTGOT:
  1964.     DCR    E    ;COUNT DOWN
  1965.     JNZ    GETGL2    ;GO TEST SOME MORE
  1966. ;
  1967. GETGNF:
  1968.     POP    H    ;NOT THIS ONE
  1969.     LXI    D,32    ;SO GO TO NEXT
  1970.     DAD    D
  1971.     XCHG
  1972.     LHLD    FILECT    ;THERE IS LIMIT TO EVERYTHING
  1973.     DCX    H
  1974.     SHLD    FILECT
  1975.     MOV    A,H
  1976.     ORA    L
  1977.     XCHG        ;RE-ALIGN
  1978.     JNZ    GETGLP
  1979. ;
  1980. ;Set the allocation address, if any
  1981. ;
  1982.     LHLD    MFPTR    ;GET ADDRESS
  1983.     RET
  1984. ;
  1985. ;COMMAND:  <
  1986. ;Save the current sector
  1987. ;    Special Form of <S saves current block onto queue
  1988. ;    Special Form of <G saves indicated group onto queue
  1989. ;
  1990. SAVE:
  1991.     LDA    WRFLG    ;READ DONE?
  1992.     ORA    A
  1993.     JZ    BADW    ;NONE TO SAVE
  1994.     MOV    A,M    ;CHECK FOR 'S'
  1995.     CALL    UPCASE    ;CAPITALIZE
  1996.     CPI    'B'    ;BLOCK SAVE
  1997.     JZ    QSAV    ;SAVE ON STACK
  1998.     CPI    'G'    ;GROUP SAVE
  1999.     JZ    SAVEG
  2000.     PUSH    H
  2001.     LHLD    SAVBUF    ;PT TO SAVBUF
  2002.     XCHG        ;COPY INTO SAVBUF
  2003.     LXI    H,TBUFF    ;FROM TBUFF
  2004.     MVI    B,128    ;128 BYTES
  2005.     CALL    MOVE
  2006.     MVI    A,1    ;..SHOW
  2007.     STA    SAVEFL    ;..SAVED EXISTS
  2008.     POP    H    ;GET PTR TO NEXT CHAR
  2009.     JMP    PROMPT
  2010. ;
  2011. ;  Save Block on Queue
  2012. ;
  2013. QSAV:
  2014.     INX    H    ;SKIP OVER 2ND <
  2015.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  2016.     LHLD    QLST    ;SEE IF ANOTHER SAVE WILL FILL QUEUE
  2017.     LXI    D,128    ;SET HL TO PT TO END OF NEXT SECTOR IN QUEUE
  2018.     DAD    D
  2019.     XCHG        ;DE PTS TO END OF NEXT BLOCK
  2020. QSAV0:
  2021.     LHLD    QNXT    ;SEE IF QUEUE IS FULL NOW
  2022.     MOV    A,H    ;MAY BE SAME
  2023.     CMP    D
  2024.     JNZ    QSAV1
  2025.     MOV    A,L    ;MAY NOT BE SAME
  2026.     CMP    E
  2027.     JZ    QSAV2    ;QUEUE IS FULL, SO ABORT
  2028. QSAV1:
  2029.     LHLD    QLST    ;GET PTR TO LAST QUEUE ELEMENT
  2030.     XCHG        ;... IN DE
  2031.     LXI    H,TBUFF    ;COPY FROM TBUFF
  2032.     MVI    B,128    ;128 BYTES
  2033.     CALL    MOVE
  2034.     CALL    QWRAP    ;CHECK FOR WRAP AROUND
  2035.     XCHG        ;HL PTS TO NEW LAST QUEUE POSITION
  2036.     SHLD    QLST    ;SAVE HL
  2037.     LHLD    QCNT    ;INCREMENT SECTOR COUNT
  2038.     INX    H
  2039.     SHLD    QCNT
  2040.     CALL    PRQCNT    ;PRINT QUEUE COUNT
  2041.     POP    H    ;PT TO NEXT CHAR
  2042.     JMP    PROMPT
  2043. QSAV2:
  2044.     CALL    ILPRT
  2045.     DB    'Block Queue is Full -- Block Not Saved',CR,LF,0
  2046.     LHLD    QCNT    ;GET COUNT
  2047.     CALL    PRQCNT    ;PRINT COUNT
  2048.     POP    H    ;PT TO NEXT CHAR
  2049.     JMP    PRMPTR
  2050. ;
  2051. ;  PRINT NUMBER OF ELEMENTS IN QUEUE
  2052. ;
  2053. PRQCNT:
  2054.     CALL    DEC    ;PRINT AS DECIMAL
  2055.     CALL    ILPRT
  2056.     DB    DIM,'    Blocks in Queue',BRIGHT,CR,LF,0
  2057.     RET
  2058. ;
  2059. ;  CHECK TO SEE IF QUEUE ELEMENT PTED TO BY DE SHOULD BE WRAPPED AROUND
  2060. ;    ON EXIT, DE PTS TO QUEUE ELEMENT WITH WRAP AROUND
  2061. ;
  2062. QWRAP:
  2063.     LHLD    BDOS+1    ;CHECK FOR WRAP AROUND
  2064.     MOV    A,H
  2065.     SUI    10    ;BELOW CCP
  2066.     CMP    D    ;WRAP AROUND IF EQUAL
  2067.     RNZ
  2068.     XCHG
  2069.     LHLD    DIRECT    ;NEXT ELEMENT IS HERE
  2070.     XCHG        ;... IN DE
  2071.     RET
  2072. ;
  2073. ;This routine is common to Save Group (RG) and Write Group (WG); it is used
  2074. ;  to extract the group number, check it, and position DU3 to it
  2075. ;  On exit, GROUP = Group Number, GRPDIS = 0, and DU3 is positioned
  2076. ;
  2077. COMG:
  2078.     INX    H    ;PT TO CHAR AFTER 'G' OF '<G' COMMAND
  2079.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  2080.     MOV    A,M    ;GET CHAR AFTER 'G'
  2081.     LHLD    GROUP    ;GET CURRENT GROUP
  2082.     CALL    UPCASE    ;CAPITALIZE
  2083.     CPI    EOLCH    ;CURRENT IF LOGICAL EOL
  2084.     JZ    COMG1
  2085.     CPI    CR    ;CURRENT IF PHYSICAL EOL
  2086.     JZ    COMG1
  2087.     CALL    HEXIN    ;GET GROUP NUMBER IN HEX
  2088.     LHLD    DSM    ;CHECK FOR BOUNDS ERROR
  2089.     CALL    SUBDE    ;SUBTRACT GROUP NUMBER FROM DSM
  2090.     POP    H    ;RESTORE PTR
  2091.     JC    OUTLIM    ;LIMIT ERROR IF CARRY
  2092.     PUSH    H    ;SAVE PTR AGAIN
  2093.     XCHG        ;SAVE GROUP NUMBER
  2094.     SHLD    GROUP
  2095. COMG1:
  2096.     SHLD    TGRP    ;TEMPORARY GROUP NUMBER
  2097.     XCHG        ;GROUP NUMBER IN DE
  2098.     XRA    A    ;A=0
  2099.     STA    GRPDIS    ;SET GROUP DISPLACEMENT
  2100.     CALL    GTKSEC    ;CONVERT GROUP NUMBER TO TRACK AND SECTOR
  2101.     CALL    SETTRK    ;SET TRACK
  2102.     XCHG
  2103.     CALL    SETSEC    ;SET SECTOR
  2104.     POP    H    ;GET PTR TO NEXT CHAR
  2105.     RET
  2106. ;
  2107. ;This is the Save Group Routine; it copies the indicated group into the save
  2108. ;  buffer.
  2109. ;
  2110. SAVEG:
  2111.     CALL    COMG    ;EXTRACT COMMON GROUP INFO -- GROUP NUMBER AND POS
  2112.     PUSH    H
  2113.     CALL    ILPRT
  2114.     DB    'Reading from Group ',0
  2115.     LHLD    GROUP    ;GET CURRENT GROUP
  2116.     MOV    B,H    ;VALUE IN BC
  2117.     MOV    C,L
  2118.     CALL    HEXB    ;PRINT AS HEX
  2119.     CALL    ILPRT
  2120.     DB    CR,LF,0
  2121.     LHLD    QLST    ;LAST PTR USED FOR READ
  2122.     SHLD    QPTR
  2123.     POP    H
  2124.     MVI    A,0    ;SET COPY FUNCTION TO SAVE
  2125.     STA    CPYFCT    ;0=READ, 0FFH=WRITE
  2126. ;
  2127. ;Group Copy Routine -- if CPYFCT = 0, Read Group; if CPYFCT = 0FFH, Write Group
  2128. ;
  2129. COPYG:
  2130.     PUSH    H    ;SAVE PTR TO NEXT CHAR IN COMMAND LINE
  2131.     CALL    NORITE    ;POSITIONING LOST
  2132.     XCHG        ;SAVE HL
  2133.     LHLD    QPTR    ;PT TO NEXT QUEUE POSITION
  2134.     XCHG        ;... IN DE
  2135.     LDA    BLM    ;GET NUMBER OF BLOCKS/GROUP
  2136.     INR    A    ; ADD 1 TO BLM FOR CORRECT COUNT
  2137.     MOV    B,A    ;COUNT IN B
  2138. ;
  2139. COPYGL:
  2140.     PUSH    B    ;SAVE COUNT
  2141.     PUSH    D    ;SAVE PTR TO NEXT BLOCK TO LOAD
  2142.     MOV    B,D    ;SET BC=DE FOR SET DMA
  2143.     MOV    C,E
  2144.     CALL    SETDMA    ;SET ADDRESS TO LOAD
  2145.     LDA    CPYFCT    ;READ OR WRITE?
  2146.     ORA    A    ;0=READ
  2147.     JNZ    COPYGLW
  2148.     CALL    READ    ;READ BLOCK
  2149.     LHLD    QCNT    ;INCREMENT QUEUE ELEMENT COUNT
  2150.     INX    H
  2151.     SHLD    QCNT
  2152.     JMP    COPYGL0
  2153. COPYGLW:
  2154.     LHLD    QCNT    ;QUEUE EMPTY?
  2155.     MOV    A,H
  2156.     ORA    L
  2157.     JZ    QEMPTY
  2158.     CALL    PWRITE    ;WRITE BLOCK (NO CHECK)
  2159.     LHLD    QCNT    ;DECREMENT QUEUE ELEMENT COUNT
  2160.     DCX    H
  2161.     SHLD    QCNT
  2162. COPYGL0:
  2163.     CALL    NXTSEC    ;COMPUTE NEXT SECTOR ADDRESS
  2164.     LHLD    CURTRK    ;GET NEXT TRACK ADDRESS
  2165.     XCHG        ;... IN DE
  2166.     CALL    SETTRK    ;SET IT
  2167.     LHLD    CURSEC    ;GET NEXT SECTOR ADDRESS
  2168.     XCHG        ;... IN DE
  2169.     CALL    SETSEC    ;SET IT
  2170.     POP    D    ;GET PTR TO NEXT BLOCK
  2171.     POP    B    ;GET COUNTER
  2172.     LXI    H,80H    ;OFFSET TO NEXT BLOCK
  2173.     DAD    D
  2174.     SHLD    QPTR
  2175.     XCHG        ;DE PTS TO NEXT BLOCK
  2176.     CALL    QWRAP    ;ALLOW WRAP AROUND IN QUEUE
  2177.     LDA    CPYFCT    ;0=READ
  2178.     ORA    A    ;NO QUEUE OVERFLOW CHECK IF WRITE
  2179.     JNZ    COPYGL1
  2180.     LHLD    QNXT    ;CHECK FOR QUEUE OVERFLOW
  2181.     MOV    A,H    ;MUST NOT BE EQUAL
  2182.     CMP    D
  2183.     JNZ    COPYGL1
  2184.     MOV    A,L
  2185.     CMP    E
  2186.     JZ    QSAV2
  2187. COPYGL1:
  2188.     DJNZ    COPYGL    ;LOOP UNTIL FINISHED
  2189.     LHLD    QCNT    ;PRINT COUNT
  2190.     CALL    PRQCNT
  2191.     LHLD    QPTR    ;GET QUEUE PTR
  2192.     LDA    CPYFCT    ;RESET PROPER QUEUE PTR
  2193.     ORA    A    ;0=READ
  2194.     JZ    COPYGL2
  2195.     SHLD    QNXT    ;NEXT PTR USED FOR WRITE
  2196.     JMP    COPYGL3
  2197. COPYGL2:
  2198.     SHLD    QLST    ;LAST PTR USED FOR READ
  2199. COPYGL3:
  2200.     LXI    B,TBUFF    ;RESET DMA ADDRESS
  2201.     CALL    SETDMA
  2202.     XRA    A    ;A=0
  2203.     STA    WRFLG    ;SET NO READ DONE
  2204.     LHLD    TGRP    ;GET GROUP NUMBER
  2205.     XCHG        ;... IN DE
  2206.     POP    H    ;GET PTR TO NEXT CHAR
  2207.     JMP    POSGRP    ;POSITION TO GROUP IN DE AND CONTINUE PROCESSING
  2208. ;
  2209. ;COMMAND:  >
  2210. ;Restore the current sector
  2211. ;    Special Form >S gets next block from queue
  2212. ;    Special Form >G gets next group from queue
  2213. ;
  2214. RESTOR:
  2215.     MOV    A,M    ;CHECK FOR SPECIAL FORM
  2216.     CALL    UPCASE    ;CAPITALIZE
  2217.     CPI    'B'    ;BLOCK SAVE?
  2218.     JZ    QRESTOR
  2219.     CPI    'G'    ;GROUP SAVE?
  2220.     JZ    RESTRG
  2221.     LDA    SAVEFL    ;SAVE DONE PREVIOUSLY?
  2222.     ORA    A
  2223.     JZ    NOSAVE    ;NONE TO SAVE
  2224.     PUSH    H
  2225.     LHLD    SAVBUF    ;COPY FROM SAVBUF
  2226.     LXI    D,TBUFF    ;INTO TBUFF
  2227.     MVI    B,128    ;128 BYTES
  2228.     CALL    MOVE
  2229.     POP    H    ;GET PTR TO NEXT CHAR
  2230.     JMP    PROMPT
  2231. ;
  2232. ;  Restore Sector from Queue
  2233. ;
  2234. QRESTOR:
  2235.     INX    H    ;PT TO NEXT CHAR
  2236.     PUSH    H    ;SAVE PTR ON STACK
  2237.     LHLD    QCNT    ;GET ELEMENT COUNT
  2238.     MOV    A,H    ;EMPTY?
  2239.     ORA    L
  2240.     JZ    QEMPTY    ;ABORT IF EMPTY
  2241.     DCX    H    ;COUNT DOWN
  2242.     SHLD    QCNT
  2243.     CALL    PRQCNT    ;PRINT COUNT
  2244.     LHLD    QNXT    ;PT TO NEXT ELEMENT IN QUEUE
  2245.     LXI    D,TBUFF    ;COPY INTO TBUFF
  2246.     MVI    B,128    ;128 BYTES
  2247.     CALL    MOVE
  2248.     XCHG        ;DE=PTR TO NEXT ELEMENT IN QUEUE
  2249.     CALL    QWRAP    ;CHECK FOR WRAP AROUND
  2250.     XCHG        ;HL PTS TO NEXT ELEMENT IN QUEUE
  2251.     SHLD    QNXT    ;SAVE PTR
  2252.     POP    H    ;RESTORE PTR
  2253.     JMP    PROMPT
  2254. QEMPTY:
  2255.     CALL    ILPRT
  2256.     DB    'Error -- Queue Empty',CR,LF,0
  2257.     POP    H    ;RESTORE NEXT CHAR PTR
  2258.     JMP    PRMPTR
  2259. ;
  2260. ;Write Group Loaded in GBUFF to Disk
  2261. ;
  2262. RESTRG:
  2263.     CALL    COMG    ;GET GROUP NUMBER FROM COMMAND LINE AND POS
  2264.     PUSH    H
  2265.     CALL    ILPRT
  2266.     DB    'Writing to Group ',0
  2267.     LHLD    GROUP    ;GET GROUP NUMBER
  2268.     MOV    B,H    ;VALUE IN BC
  2269.     MOV    C,L
  2270.     CALL    HEXB    ;PRINT IN HEX
  2271.     CALL    ILPRT
  2272.     DB    CR,LF,0
  2273.     LHLD    QNXT    ;NEXT PTR USED FOR WRITE
  2274.     SHLD    QPTR
  2275.     POP    H
  2276.     MVI    A,0FFH    ;WRITE FUNCTION
  2277.     STA    CPYFCT    ;COPY FUNCTION FOR GROUP COPY ROUTINE
  2278.     JMP    COPYG    ;GROUP COPY ROUTINE
  2279. ;
  2280. NOSAVE:
  2281.     CALL    ILPRT
  2282.     DB    '++ No "<" Save Command Issued ++'
  2283.     DB    CR,LF,0
  2284.     JMP    PRMPTR
  2285. ;
  2286. ;Move (HL) to (DE) length in B
  2287. ;
  2288. MOVE:
  2289.     MOV    A,M
  2290.     STAX    D
  2291.     INX    H
  2292.     INX    D
  2293.     DJNZ    MOVE
  2294.     RET
  2295. ;
  2296. NORITE:
  2297.     XRA    A    ;GET 0
  2298.     STA    WRFLG    ;CAN'T WRITE NOW
  2299.     RET
  2300. ;
  2301. ;No match in search, try next char
  2302. ;
  2303. SRNOMT:
  2304.     POP    H
  2305.     CALL    CTLCS    ;ABORT?
  2306.     JNZ    SEARCH    ;..YES
  2307.     LHLD    INBUF
  2308.     MVI    M,CR
  2309.     JMP    CLCGRP    ;SHOW WHERE STOPPED
  2310. ;
  2311. ;COMMAND:  =
  2312. ;Search for character string
  2313. ;
  2314. SEARCH:
  2315.     PUSH    H    ;SAVE STRING POINTER
  2316. ;
  2317. SRCHL:
  2318.     CALL    RDBYTE    ;GET A BYTE
  2319.     MOV    B,A    ;SAVE IT
  2320.     MOV    A,M    ;CHECK NEXT MATCH CHAR.
  2321.     CPI    '<'    ;WILL IT BE HEX?
  2322.     MOV    A,B    ;RESTORE DISK CHAR
  2323.     JZ    SRCHL1
  2324.     ANI    7FH    ;NEXT CHAR IS ASCII...STRIP BIT 7
  2325. ;
  2326. SRCHL1:
  2327.     PUSH    PSW
  2328.     CALL    GETVAL    ;GET SEARCH VALUE
  2329.     MOV    B,A
  2330.     POP    PSW
  2331.     CMP    B    ;MATCH?
  2332.     JNZ    SRNOMT    ;NO MATCH
  2333.     INX    H
  2334.     MOV    A,M    ;DONE?
  2335.     CPI    CR    ;END OF LINE?
  2336.     JZ    SREQU
  2337.     CPI    EOLCH    ;LOGICAL EOL?
  2338.     JNZ    SRCHL
  2339. ;
  2340. ;Got match
  2341. ;
  2342. SREQU:
  2343.     CALL    ILPRT
  2344.     DB    '= at ',0
  2345.     LDA    BUFAD
  2346.     ANI    7FH
  2347.     CALL    HEX
  2348.     CALL    CRLF
  2349.     JMP    CLCGRP
  2350. ;
  2351. ;Get value from input buffer
  2352. ;
  2353. GETVAL:
  2354.     MOV    A,M    ;GET NEXT CHAR
  2355.     CPI    '<'    ;HEX ESCAPE?
  2356.     RNZ        ;NO, RETURN
  2357. ;"<<" means one "<"
  2358.     INX    H
  2359.     MOV    A,M
  2360.     CPI    '<'
  2361.     RZ
  2362. ;Got hex
  2363.     PUSH    D
  2364.     CALL    HEXIN    ;GET VALUE
  2365.     CPI    '>'    ;PROPER DELIM?
  2366.     MOV    A,E    ;GET VALUE
  2367.     POP    D
  2368.     JNZ    WHAT    ;ERROR
  2369.     RET
  2370. ;
  2371. ;Read a byte at a time from disk
  2372. ;
  2373. RDBYTE:
  2374.     PUSH    H
  2375.     LDA    FTSW    ;FIRST READ?
  2376.     ORA    A
  2377.     JNZ    READ1
  2378.     LHLD    BUFAD
  2379.     MOV    A,L
  2380.     ORA    A    ;IN BUFFER?
  2381.     JM    NORD    ;YES, SKIP READ
  2382. ;
  2383. ;Have to read
  2384. ;
  2385.     CALL    NXTSEC    ;ADVANCE TO NEXT BLOCK
  2386. ;
  2387. READ1:
  2388.     XRA    A
  2389.     STA    FTSW    ;NOT FIRST READ
  2390.     LHLD    CURSEC
  2391.     XCHG
  2392.     CALL    SETSEC
  2393.     LHLD    CURTRK
  2394.     XCHG
  2395.     CALL    SETTRK
  2396.     CALL    READ
  2397.     CALL    CLCSUB
  2398.     LXI    H,TBUFF
  2399. ;
  2400. NORD:
  2401.     MOV    A,M
  2402.     INX    H
  2403.     SHLD    BUFAD
  2404.     POP    H
  2405.     RET
  2406. ;
  2407. ;COMMAND:  V
  2408. ;View the file in ASCII starting at
  2409. ;current sector, stepping thru the disk
  2410. ;
  2411. VIEW:
  2412.     LDA    WRFLG
  2413.     ORA    A
  2414.     JZ    BADDMP
  2415.     CALL    DECIN    ;GET DISPL IF ANY
  2416.     PUSH    H
  2417.     MOV    A,E
  2418.     ORA    A
  2419.     JNZ    VIEWLP
  2420.     INR    E    ;DFLT=1
  2421. ;
  2422. VIEWLP:
  2423.     LXI    H,TBUFF    ;TO DATA
  2424. ;
  2425. VEWCHR:
  2426.     CALL    CTLCS    ;ABORT?
  2427.     JZ    VEWEND
  2428.     MOV    A,M    ;GET NEXT CHAR
  2429.     CPI    1AH    ;EOF?
  2430.     JZ    VEWEOF
  2431.     ANI    7FH    ;MASK
  2432.     CPI    7EH    ;ESC CHAR FOR H1500
  2433.     JNC    VIEWHX    ;SHOW RUBOUT AND TILDE AS HEX
  2434.     CPI    ' '
  2435.     JNC    VIEWPR
  2436.     CPI    CR    ;CR PASS
  2437.     JZ    VIEWPR
  2438.     CPI    LF    ;LF PASS
  2439.     JZ    VIEWPR
  2440.     CPI    TAB    ;TAB PASS
  2441.     JZ    VIEWPR
  2442. ;
  2443. VIEWHX:
  2444.     MOV    A,M    ;NOT ASCII...PRINT AS <NN>
  2445.     CALL    BHEX
  2446.     JMP    VIEWNP
  2447. ;
  2448. VIEWPR:
  2449.     CALL    TYPE
  2450. ;
  2451. VIEWNP:
  2452.     INR    L
  2453.     JNZ    VEWCHR
  2454.     DCR    E
  2455.     JZ    VEWEND
  2456.     PUSH    D    ;SAVE COUNT
  2457.     CALL    NXTSEC
  2458.     LHLD    CURSEC
  2459.     XCHG
  2460.     CALL    SETSEC    
  2461.     LHLD    CURTRK
  2462.     XCHG
  2463.     CALL    SETTRK
  2464.     CALL    READ
  2465.     POP    D    ;RESTORE COUNT
  2466.     JMP    VIEWLP
  2467. ;
  2468. VEWEOF:
  2469.     CALL    ILPRT
  2470.     DB    CR,LF,DIM,' ++ EOF ++',BRIGHT,CR,LF,0
  2471. ;
  2472. VEWEND:
  2473.     POP    H
  2474.     CALL    CRLF
  2475.     JMP    CLCGRP
  2476. ;
  2477. ;COMMAND:  A or D
  2478. ;Dump in hex or ASCII
  2479. ;
  2480. DUMP:
  2481.     LDA    WRFLG
  2482.     ORA    A
  2483.     JNZ    DUMPOK
  2484. ;
  2485. BADDMP:
  2486.     CALL    ILPRT
  2487.     DB    '++ Can''t dump, no sector read ++',CR,LF,0
  2488. ;
  2489. EXPL:
  2490.     CALL    ILPRT
  2491.     DB    'Use G command following F,',CR,LF
  2492.     DB    'or R or S following T',CR,LF,0
  2493.     JMP    PRMPTR
  2494. ;
  2495. DUMPOK:
  2496.     MOV    A,M    ;GET NEXT CHAR
  2497.     CPI    EOLCH    ;LOGICAL EOL?
  2498.     JZ    DUMPDF    ;DFLT
  2499.     CPI    CR    ;PHYSICAL EOL?
  2500.     JNZ    DMPNDF
  2501. ;
  2502. ;Use default
  2503. ;
  2504. DUMPDF:
  2505.     LXI    B,TBUFF
  2506.     LXI    D,0FFH
  2507.     JMP    DUMP1
  2508. ;
  2509. DMPNDF:
  2510.     CALL    DISP
  2511.     MOV    B,D
  2512.     MOV    C,E
  2513.     CPI    CR
  2514.     JZ    DUMP1
  2515.     CPI    EOLCH
  2516.     JZ    DUMP1
  2517.     INX    H    ;SKIP SEPCH
  2518.     CALL    DISP
  2519. ;
  2520. ;BC = start, DE = end
  2521. ;
  2522. DUMP1:
  2523.     PUSH    H    ;SAVE COMMAND POINTER
  2524.     MOV    H,B
  2525.     MOV    L,C
  2526. ;
  2527. DUMPLP:
  2528.     CALL    DUMPHL    ;PERFORM DUMP OF DIR ENTRY AT HL
  2529.     POP    H    ;RESTORE HL
  2530.     JMP    PROMPT
  2531. ;
  2532. ; PERFORM DUMP AT HL
  2533. ;
  2534. DUMPHL:
  2535.     CALL    STNDOUT    ;DIM
  2536.     MOV    A,L
  2537.     ANI    7FH
  2538.     CALL    HEX    ;PRINT HEX VALUE
  2539.     CALL    STNDEND    ;BRIGHT
  2540.     CALL    SPACE
  2541.     CALL    SPACE
  2542.     LDA    DUMTYP
  2543.     CPI    'A'
  2544.     JZ    DUMPAS
  2545.     PUSH    H    ;SAVE START
  2546. ;
  2547. ; DUMP 16 BYTES STARTING AT HL (CHECK FOR DE TERMINATION)
  2548. ;
  2549. DHEX:
  2550.     MOV    A,M
  2551.     CALL    HEX    ;PRINT HEX VALUE PTED TO BY HL
  2552.     MOV    A,L
  2553.     ANI    3
  2554.     CPI    3    ;EXTRA SPACE EVERY 4
  2555.     CZ    SPACE
  2556.     MOV    A,L
  2557.     ANI    7
  2558.     CPI    7    ;TWO EXTRA SPACES EVERY 8
  2559.     CZ    SPACE
  2560.     MOV    A,E    ;CHECK FOR END OF BYTES TO DUMP
  2561.     CMP    L
  2562.     JZ    DPOP
  2563.     INX    H
  2564.     MOV    A,L    ;CHECK FOR END OF 16 BYTES
  2565.     ANI    0FH
  2566.     JNZ    DHEX
  2567. ;
  2568. DPOP:
  2569.     CALL    CTLCS    ;ABORT?
  2570.     JZ    PRMPTR
  2571.     LDA    DUMTYP    ;CHECK FOR ASCII ALSO
  2572.     CPI    'H'
  2573.     JZ    DNOAS    ;HEX ONLY
  2574.     POP    H    ;GET START ADDR
  2575. ;
  2576. ;  DUMP ASCII CHARS - HL PTS TO FIRST BYTE
  2577. ;
  2578. DUMPAS:
  2579.     CALL    ASTER    ;PRINT FIRST ASTERISK TO SEPARATE TEXT
  2580. ;
  2581. DCHR:
  2582.     MOV    A,M    ;GET CHAR
  2583.     ANI    7FH
  2584.     CPI    ' '
  2585.     JC    DPER
  2586.     CPI    7FH    ;TRAP DEL
  2587.     JC    DOK
  2588. ;
  2589. DPER:
  2590.     MVI    A,'.'    ;PRINT PRINTING CHAR
  2591. ;
  2592. DOK:
  2593.     CALL    TYPE    ;PRINT CHAR
  2594.     MOV    A,E    ;CHECK FOR END OF DUMP
  2595.     CMP    L
  2596.     JZ    DEND
  2597.     INX    H
  2598.     MOV    A,L    ;CHECK FOR END OF 16 BYTES
  2599.     ANI    0FH
  2600.     JNZ    DCHR
  2601. ;
  2602. ; END OF ASCII DUMP
  2603. ;
  2604. DEND:
  2605.     CALL    ASTER    ;PRINT ENDING ASTERISK
  2606.     CALL    CRLF    ;NEW LINE
  2607.     PUSH    D
  2608.     CALL    CTLCS    ;ABORT?
  2609.     POP    D
  2610.     JZ    PRMPTR
  2611.     MOV    A,E    ;DONE WITH DUMP?
  2612.     CMP    L
  2613.     JNZ    DUMPHL
  2614.     RET
  2615. ;
  2616. ; NO ASCII DUMP
  2617. ;
  2618. DNOAS:
  2619.     POP    B    ;CLEAR STACK (START ADDRESS OF DUMP)
  2620.     CALL    CRLF    ;NEW LINE
  2621.     MOV    A,E    ;DONE WITH DUMP?
  2622.     CMP    L
  2623.     JNZ    DUMPHL
  2624.     RET
  2625. ;
  2626. ;COMMAND:  G
  2627. ;Position
  2628. ;
  2629. POS:
  2630.     PUSH    PSW
  2631.     MOV    A,M
  2632.     CPI    EOLCH    ;LOGICAL EOL?
  2633.     JZ    POSINQ
  2634.     CPI    CR    ;PHYSICAL EOL?
  2635.     JNZ    POSOK
  2636. ;
  2637. POSINQ:
  2638.     POP    PSW
  2639.     JMP    INQ
  2640. ;
  2641. POSOK:
  2642.     POP    PSW
  2643.     CPI    'T'    ;TRACK?
  2644.     JZ    POSTKD
  2645.     CPI    'S'    ;SECTOR?
  2646.     JZ    POSSCD
  2647.     CPI    'G'    ;GROUP?
  2648.     JZ    POSGPH
  2649.     JMP    WHAT    ;ERROR OTHERWISE
  2650. ;
  2651. ;Position to Track
  2652. ;
  2653. POSTKD:
  2654.     CALL    DECIN    ;GET NUMBER IN DECIMAL
  2655. ;
  2656. POSTRK:
  2657.     PUSH    H
  2658.     LHLD    MAXTRK    ;CHECK FOR BEYOND END OF DISK
  2659.     CALL    SUBDE
  2660.     POP    H
  2661.     JC    OUTLIM
  2662.     CALL    SETTRK    ;SET TRACK
  2663.     CALL    NORITE    ;TRACK DOESN'T READ
  2664.     MVI    A,1
  2665.     STA    NOTPOS    ;SHOW NOT POSITIONED
  2666.     JMP    CLCGRP
  2667. ;
  2668. ;Position to Sector
  2669. ;
  2670. POSSCD:
  2671.     CALL    DECIN    ;GET NUMBER IN DECIMAL
  2672.     MOV    A,D
  2673.     ORA    E
  2674.     JZ    WHAT    ;DON'T ALLOW SECTOR 0
  2675. ;
  2676. POSSEC:
  2677.     PUSH    H
  2678.     LHLD    SPT    ;CHECK FOR WITHIN RANGE
  2679.     CALL    SUBDE
  2680.     POP    H
  2681.     JC    WHAT
  2682.     CALL    SETSEC    ;SET SECTOR
  2683.     CALL    READ    ;READ
  2684.     XRA    A
  2685.     STA    NOTPOS    ;POSITIONED OK
  2686. ;
  2687. ;Calculate Group Number/Group Displacement and Print
  2688. ;
  2689. CLCGRP:
  2690.     CALL    CLCSUB
  2691.     JMP    INQ
  2692. ;
  2693. ;Calculate group from track and sector
  2694. ;  On exit, GROUP = Group Number and GRPDIS = Displacement within Group
  2695. ;
  2696. CLCSUB:
  2697.     PUSH    H
  2698.     LHLD    SYSTRK
  2699.     XCHG
  2700.     LHLD    CURTRK
  2701.     CALL    SUBDE    ;COMPUTE RELATIVE TRACK NUMBER (SKIP SYSTEM TRACKS)
  2702.     XCHG
  2703.     LHLD    SPT    ;MULTIPLY BY NUMBER OF SECTORS/TRACK
  2704.     CALL    MULT
  2705.     XCHG        ;DE=TOTAL NUMBER OF SECTORS IN TRACKS
  2706.     LHLD    CURSEC    ;GET SECTOR OFFSET FROM BEGINNING OF TRACK
  2707.     DCX    H
  2708.     DAD    D    ;HL=TOTAL NUMBER OF SECTORS WITH OFFSET
  2709.     LDA    BLM
  2710.     MOV    B,A
  2711.     MOV    A,L
  2712.     ANA    B
  2713.     STA    GRPDIS    ;DISPLACEMENT WITHIN GROUP
  2714.     LDA    BSH
  2715.     MOV    B,A
  2716. ;
  2717. CLCLOP:
  2718.     CALL    ROTRHL
  2719.     DJNZ    CLCLOP
  2720.     SHLD    GROUP    ;GROUP NUMBER
  2721.     POP    H
  2722.     RET
  2723. ;
  2724. ;Position in the directory after a find
  2725. ;(Does not work in CP/M-2.x)
  2726. ;
  2727. POSDIR:
  2728.     PUSH    H    ;SAVE INBUF
  2729.     LHLD    BSH
  2730.     XRA    A
  2731.     STA    FINDFL    ;CANCEL POS REQ
  2732.     LDA    DIRPOS    ;GET POSITION
  2733.     RAR
  2734.     RAR
  2735.     PUSH    PSW
  2736.     ANA    H
  2737.     STA    GRPDIS
  2738.     POP    PSW
  2739. ;
  2740. POSDLP:
  2741.     RAR
  2742.     DCR    L
  2743.     JNZ    POSDLP
  2744.     ANI    1    ;GET GROUP
  2745.     MOV    L,A    ;SETUP FOR POSGP2
  2746.     MVI    H,0
  2747.     SHLD    GROUP
  2748.     XCHG
  2749. ;
  2750. POSGP2:
  2751.     CALL    GTKSEC    ;CONVERT GROUP TO SECTOR/TRACK
  2752.     CALL    SETTRK    ;SET TRACK
  2753.     XCHG
  2754.     CALL    SETSEC    ;SET SECTOR
  2755.     CALL    READ    ;READ BLOCK
  2756.     XRA    A
  2757.     STA    NOTPOS    ;NOW POSITIONED
  2758.     POP    H
  2759.     JMP    INQ
  2760. ;
  2761. ;Position to Group
  2762. ;
  2763. POSGPH:
  2764.     CALL    HEXIN    ;GET PARAMETER
  2765. ;
  2766. ;Position to Group Numbered in DE and Print Position
  2767. ;
  2768. POSGRP:
  2769.     CALL    DEGROUP    ;GOTO GROUP
  2770.     JC    OUTLIM
  2771.     JMP    INQ    ;PRINT POSITION
  2772. ;
  2773. ;Position to Group Numbered in DE
  2774. ; Return with Carry Set if Out of Limits
  2775. ;
  2776. DEGROUP:
  2777.     PUSH    H
  2778.     LHLD    DSM    ;CHECK FOR WITHIN BOUNDS
  2779.     CALL    SUBDE
  2780.     POP    H
  2781.     RC
  2782.     PUSH    H    ;SAVE HL
  2783.     XCHG
  2784.     SHLD    GROUP    ;SET GROUP NUMBER
  2785.     XCHG
  2786.     XRA    A
  2787.     STA    GRPDIS    ;SET ZERO DISPLACEMENT
  2788.     CALL    GTKSEC    ;CONVERT GROUP TO SECTOR/TRACK
  2789.     CALL    SETTRK    ;SET TRACK
  2790.     XCHG
  2791.     CALL    SETSEC    ;SET SECTOR
  2792.     CALL    READ    ;READ BLOCK
  2793.     XRA    A    ;SET NC AND FLAG
  2794.     STA    NOTPOS    ;NOW POSITIONED
  2795.     POP    H
  2796.     RET
  2797. ;
  2798. ;Convert Group Number in DE to Sector and Track; also, GRPDIS = Offset in Grp
  2799. ;  On exit, DE = Track Number, HL = Sector Number
  2800. ;
  2801. GTKSEC:
  2802.     MOV    H,D    ;HL=GROUP NUMBER
  2803.     MOV    L,E
  2804.     LDA    BSH    ;GET NUMBER OF SECTORS IN GROUP
  2805. ;
  2806. GLOOP:
  2807.     DAD    H
  2808.     DCR    A
  2809.     JNZ    GLOOP
  2810.     LDA    GRPDIS    ;ADD IN DISPLACEMENT WITHIN GROUP
  2811.     ADD    L    ;CAN'T CARRY
  2812.     MOV    L,A
  2813. ;
  2814. ;Divide by number of sectors, quotient=track, remainder=sector
  2815. ;
  2816.     XCHG        ;DE=TOTAL NUMBER OF SECTORS
  2817.     LHLD    SPT    ;GET NUMBER OF SECTORS/TRACK
  2818.     CALL    NEG    ;HL = -SECTORS/TRACK
  2819.     XCHG
  2820.     LXI    B,0    ;SET TRACK COUNTER TO ZERO
  2821. ;
  2822. DIVLP:
  2823.     INX    B    ;INCREMENT TRACK COUNT
  2824.     DAD    D    ;SUBTRACT SECTORS/TRACK FROM SECTORS TOTAL
  2825.     JC    DIVLP
  2826.     DCX    B    ;ADJUST TRACK COUNT
  2827.     XCHG
  2828.     LHLD    SPT    ;ADD SECTORS/TRACK BACK IN TO ADJUST
  2829.     DAD    D    ;HL=NUMBER OF SECTORS ON LAST TRACK OF GROUP
  2830.     PUSH    H
  2831.     LHLD    SYSTRK    ;ADD IN NUMBER OF SYSTEM TRACKS
  2832.     DAD    B
  2833.     XCHG        ;DE=TRACK NUMBER
  2834.     POP    H
  2835.     INX    H    ;HL=SECTOR NUMBER
  2836.     RET
  2837. ;
  2838. ;COMMAND:  F
  2839. ;Find Directory Entry for specified file
  2840. ;
  2841. POSFIL:
  2842.     CALL    NORITE
  2843.     MVI    A,1
  2844.     STA    FINDFL    ;SO WE POSITION LATER
  2845.     LXI    D,FCB
  2846.     XRA    A    ;LOGGED IN DISK
  2847.     STAX    D
  2848.     INX    D
  2849.     MVI    B,8
  2850.     CALL    MVNAME
  2851.     MVI    B,3
  2852.     CALL    MVNAME
  2853.     MVI    A,'?'
  2854.     STAX    D    ;LOOK IN ALL EXTENTS
  2855.     MVI    A,'D'    ;SET TYPE OF DUMP TO FULL
  2856.     STA    DUMTYP
  2857.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  2858.     LXI    D,FCB
  2859.     MVI    C,SRCHF
  2860.     CALL    BDOS
  2861.     INR    A
  2862.     JNZ    FLOK
  2863.     STA    DIRPOS    ;GRP 0 IF NOT FOUND
  2864.     CALL    ILPRT
  2865.     DB    '++ File Not Found ++',CR,LF,0
  2866.     POP    H    ;RESTORE PTR TO NEXT CHAR
  2867.     JMP    PROMPT
  2868. ;
  2869. FLOK:
  2870.     DCR    A
  2871.     STA    DIRPOS    ;SAVE POS. IN DIR
  2872.     ANI    3
  2873.     MOV    L,A
  2874.     MVI    H,0
  2875.     DAD    H    ;X32 BYTES/ENTRY
  2876.     DAD    H
  2877.     DAD    H
  2878.     DAD    H
  2879.     DAD    H
  2880.     LXI    D,TBUFF
  2881.     DAD    D    ;HL POINTS TO ENTRY
  2882.     LXI    D,32
  2883.     XCHG
  2884.     DAD    D
  2885.     XCHG
  2886.     CALL    DUMPHL    ;PRINT DIR ENTRY
  2887.     LXI    D,FCB    ;LOOK FOR NEXT EXTENT
  2888.     MVI    C,SRCHN
  2889.     CALL    BDOS
  2890.     INR    A
  2891.     JNZ    FLOK
  2892.     POP    H    ;RESTORE PTR TO NEXT CHAR
  2893.     JMP    PROMPT
  2894. ;
  2895. MVNAME:
  2896.     MOV    A,M    ;GET NEXT CHAR OF FILE NAME/TYPE
  2897.     CPI    '.'    ;END OF FILE NAME?
  2898.     JZ    MVIPAD    ;PAD OUT IF SO
  2899.     CPI    CR    ;END OF ENTRY?
  2900.     JZ    PAD    ;PAD OUT IF SO
  2901.     CPI    EOLCH    ;END OF ENTRY?
  2902.     JZ    PAD    ;PAD OUT IF SO
  2903.     CALL    UPCASE    ;CAPITALIZE
  2904.     STAX    D    ;STORE
  2905.     INX    H    ;PT TO NEXT
  2906.     INX    D
  2907.     DJNZ    MVNAME
  2908.     MOV    A,M    ;CHECK FOR ERROR
  2909.     CPI    CR    ;OK IF EOL
  2910.     RZ
  2911.     CPI    EOLCH    ;OK IF LOGICAL EOL
  2912.     RZ
  2913.     INX    H
  2914.     CPI    '.'    ;OK IF DECIMAL
  2915.     RZ
  2916.     JMP    WHAT
  2917. ;
  2918. MVIPAD:
  2919.     INX    H
  2920. ;
  2921. PAD:
  2922.     MVI    A,' '    ;PRINT PADDING SPACES
  2923.     STAX    D
  2924.     INX    D
  2925.     DJNZ    PAD
  2926.     RET
  2927. ;
  2928. ;COMMAND:  +
  2929. ;Advance to Next Logical Sector
  2930. ;
  2931. PLUS:
  2932.     LXI    D,1    ;DFLT TO 1 SECT
  2933.     MOV    A,M    ;GET NEXT CHAR
  2934.     CPI    CR    ;CR?
  2935.     JZ    PLUSGO    ;..YES, DFLT TO 1
  2936.     CPI    EOLCH
  2937.     JZ    PLUSGO
  2938.     CALL    DECIN    ;GET #
  2939.     MOV    A,D
  2940.     ORA    E
  2941.     JNZ    PLUSGO
  2942.     LXI    D,1    ;SET 1 IF VALUE OF ZERO
  2943. ;
  2944. PLUSGO:
  2945.     CALL    NXTSEC    ;ADVANCE TO NEXT LOGICAL SECTOR
  2946.     DCX    D    ;MORE TO GO?
  2947.     MOV    A,D
  2948.     ORA    E
  2949.     JNZ    PLUSGO    ;..YES
  2950. ;
  2951. ;Ok, incremented to sector.  Setup and read
  2952. ;
  2953. PLUSMI:
  2954.     PUSH    H
  2955.     LHLD    CURSEC
  2956.     XCHG
  2957.     CALL    SETSEC    ;SET SECTOR
  2958.     LHLD    CURTRK
  2959.     XCHG
  2960.     CALL    SETTRK    ;SET TRACK
  2961.     POP    H
  2962.     CALL    READ    ;READ IT
  2963.     JMP    CLCGRP    ;CALCULATE GROUP AND DISPLAY
  2964. ;
  2965. ;COMMAND:  -
  2966. ;Back up to previous sector
  2967. ;
  2968. MINUS:
  2969.     LXI    D,1    ;SET DFLT
  2970.     MOV    A,M    ;GET CHAR
  2971.     CPI    CR    ;CR?
  2972.     JZ    MINGO    ;..YES, DFLT=1
  2973.     CPI    EOLCH
  2974.     JZ    MINGO
  2975.     CALL    DECIN    ;..NO, GET ##
  2976.     MOV    A,D
  2977.     ORA    E
  2978.     JNZ    MINGO
  2979.     LXI    D,1    ;ASSUME 1
  2980. ;
  2981. MINGO:
  2982.     CALL    LSTSEC    ;BACK UP ONE SECTOR
  2983.     DCX    D    ;COUNT DOWN ON NUMBER OF TIMES TO BACKUP
  2984.     MOV    A,D
  2985.     ORA    E
  2986.     JNZ    MINGO
  2987.     JMP    PLUSMI    ;READ BLOCK
  2988. ;
  2989. ;Go to last sector
  2990. ; Wrap around to last sector of previous track or last sector of
  2991. ; last track, as necessary
  2992. ;
  2993. LSTSEC:
  2994.     PUSH    H
  2995.     LHLD    CURSEC    ;BACK UP SECTOR
  2996.     DCX    H
  2997.     MOV    A,H
  2998.     ORA    L
  2999.     JNZ    LSEC1
  3000.     LHLD    CURTRK    ;BEYOND SECTOR ZERO, SO BACK UP TRACK
  3001.     MOV    A,H
  3002.     ORA    L
  3003.     JNZ    LSEC0
  3004.     LHLD    MAXTRK    ;WRAP TO END OF DISK
  3005.     SHLD    CURTRK
  3006.     LHLD    MAXSEC
  3007.     JMP    LSEC1
  3008. ;
  3009. LSEC0:
  3010.     DCX    H
  3011.     SHLD    CURTRK
  3012.     LHLD    SPT    ;GET NUMBER OF SECTORS/TRACK
  3013. ;
  3014. LSEC1:
  3015.     SHLD    CURSEC    ;SET NEW CURRENT SECTOR
  3016.     POP    H
  3017.     RET
  3018. ;
  3019. ;Go to next sector
  3020. ;  On exit, CURSEC = Current Sector and CURTRK = Current Track
  3021. ;
  3022. NXTSEC:
  3023.     PUSH    H
  3024.     PUSH    D
  3025.     LHLD    CURSEC    ;INCREMENT CURRENT SECTOR
  3026.     INX    H
  3027.     XCHG
  3028.     LHLD    SPT    ;CHECK TO SEE IF BEYOND END OF TRACK
  3029.     CALL    SUBDE
  3030.     XCHG
  3031.     JNC    NEXTOK
  3032.     LHLD    CURTRK    ;BEYOND END OF TRACK, SO INCR CURRENT TRACK
  3033.     INX    H
  3034.     XCHG
  3035.     LHLD    MAXTRK    ;SEE IF BEYOND END OF DISK
  3036.     CALL    SUBDE
  3037.     JNC    TRASK
  3038.     LXI    D,0    ;WRAP TO START OF DISK
  3039. ;
  3040. TRASK:
  3041.     XCHG
  3042.     SHLD    CURTRK    ;SET NEW CURRENT TRACK
  3043.     LXI    H,1    ;SET SECTOR 1
  3044. ;
  3045. NEXTOK:
  3046.     SHLD    CURSEC    ;SET NEW CURRENT SECTOR
  3047.     POP    D
  3048.     POP    H
  3049.     RET
  3050. ;
  3051. ;Tell what group, displacement, track, sector, physical sector
  3052. ;
  3053. INQ:
  3054.     CALL    INQSUB
  3055.     JMP    PROMPT
  3056. ;
  3057. ;Position inquiry subroutine
  3058. ;Executed via: G S or T (with no operands)
  3059. ;
  3060. INQSUB:
  3061.     PUSH    H
  3062.     LHLD    SYSTRK    ;CHECK IF IN SYSTEM TRACKS
  3063.     XCHG
  3064.     LHLD    CURTRK
  3065.     CALL    SUBDE
  3066.     JC    NOGRP
  3067.     CALL    ILPRT    ;PRINT GROUP NUMBER IF NOT IN SYSTEM TRACKS
  3068.     DB    DIM,'Group = ',BRIGHT,0
  3069.     LHLD    GROUP
  3070.     MOV    B,H
  3071.     MOV    C,L
  3072.     CALL    HEXB    ;PRINT GROUP NUMBER IN BC
  3073.     MVI    A,':'
  3074.     CALL    TYPE
  3075.     LDA    GRPDIS
  3076.     CALL    HEX    ;PRINT GROUP DISPLACEMENT IN A
  3077.     MVI    A,','
  3078.     CALL    TYPE
  3079. ;
  3080. NOGRP:
  3081.     CALL    ILPRT    ;PRINT TRACK NUMBER
  3082.     DB    DIM,' Track = ',BRIGHT,0
  3083.     LHLD    CURTRK
  3084.     CALL    DEC    ;TRACK NUMBER IN DECIMAL
  3085.     CALL    ILPRT    ;PRINT SECTOR NUMBER
  3086.     DB    DIM,', Sector = ',BRIGHT,0
  3087.     LHLD    CURSEC
  3088.     CALL    DEC    ;SECTOR NUMBER IN DECIMAL
  3089.     CALL    ILPRT    ;PRINT PHYSCIAL SECTOR NUMBER
  3090.     DB    DIM,', Physical Sector = ',BRIGHT,0
  3091.     LHLD    PHYSEC
  3092.     CALL    DEC    ;PHYSICAL SECTOR NUMBER IN DECIMAL
  3093.     CALL    CRLF
  3094.     POP    H
  3095.     RET
  3096. ;
  3097. ;COMMAND:  C
  3098. ;Change Contents of Current Block
  3099. ;
  3100. CHG:
  3101.     MOV    A,M    ;GET TYPE (HEX, ASCII)
  3102.     CALL    UPCASE
  3103.     PUSH    PSW    ;SAVE "H" OR "A"
  3104.     INX    H
  3105.     CALL    HEXIN    ;GET DISP IN HEX
  3106.     CALL    DISP1    ;VALIDATE DISP TO DE
  3107.     INX    H
  3108.     LXI    B,0    ;SHOW NO 'THRU' ADDR
  3109.     CPI    '-'    ;TEST DELIM FR. DISP
  3110.     JNZ    CHGNTH    ;NO THRU
  3111.     PUSH    D    ;SAVE FROM
  3112.     CALL    HEXIN
  3113.     CALL    DISP1    ;GET THRU
  3114.     INX    H    ;SKIP END DELIM
  3115.     MOV    B,D
  3116.     MOV    C,E    ;BC = THRU
  3117.     POP    D    ;GET FROM
  3118.     JMP    CHGAH
  3119. ;
  3120. CHGNTH:
  3121.     CPI    SEPCH
  3122.     JNZ    WHAT
  3123. ;
  3124. CHGAH:
  3125.     POP    PSW
  3126.     CPI    'H'    ;HEX?
  3127.     JZ    CHGHEX
  3128.     CPI    'A'    ;ASCII?
  3129.     JNZ    WHAT
  3130. ;
  3131. ;Change ASCII
  3132. ;
  3133. CHGALP:
  3134.     MOV    A,M    ;GET CHAR
  3135.     CPI    CR
  3136.     JZ    PROMPT
  3137.     CPI    EOLCH
  3138.     JZ    PROMPT
  3139. ;
  3140. ;The following print of the deleted byte is commented out; if leading
  3141. ;  semicolons are removed, deleted bytes will be printed
  3142. ;
  3143. ;    LDAX    D    ;GET BYTE THAT IS REPLACED
  3144. ;    CPI    ' '
  3145. ;    JC    CHGAHX
  3146. ;    CPI    7EH    ;DON'T PRINT ESC CHAR FOR H1500
  3147. ;    JNC    CHGAHX
  3148. ;    JMP    CHGA2
  3149. ;
  3150. ;CHGAHX:
  3151. ;    CALL    BHEX
  3152. ;    JMP    CHGA3
  3153. ;
  3154. ;CHGA2:
  3155. ;    CALL    TYPE
  3156. ;
  3157. ;End of print of delete bytes
  3158. ;
  3159. CHGA3:
  3160.     SHLD    BACK    ;IN CASE "THRU"
  3161.     CALL    GETVAL    ;GET ASCII OR <HEX> VALUE
  3162.     STAX    D    ;UPDATE BYTE
  3163.     INX    H    ;PT TO NEXT INPUT CHAR
  3164. ;
  3165. ;See if 'THRU' requested
  3166. ;
  3167.     MOV    A,C
  3168.     ORA    A
  3169.     JZ    CHANTH
  3170.     CMP    E    ;DONE?..
  3171.     JZ    PROMPT    ;..YES
  3172.     LHLD    BACK
  3173. ;
  3174. CHANTH:
  3175.     INR    E
  3176.     JNZ    CHGALP
  3177.     MOV    A,M
  3178.     CPI    CR
  3179.     JZ    PROMPT
  3180.     CPI    EOLCH
  3181.     JZ    PROMPT
  3182.     JMP    WHAT
  3183. ;
  3184. ;Change hex
  3185. ;
  3186. CHGHCM:
  3187.     INX    H
  3188. ;
  3189. CHGHEX:
  3190.     MOV    A,M    ;GET HEX DIGIT
  3191.     CPI    CR
  3192.     JZ    PROMPT
  3193.     CPI    EOLCH
  3194.     JZ    PROMPT
  3195.     CPI    SEPCH    ;DELIM?
  3196.     JZ    CHGHCM
  3197.     PUSH    D
  3198.     SHLD    HEXAD    ;IN CASE 'THRU'
  3199.     CALL    HEXIN    ;POSITIONS TO DELIM
  3200.     MOV    A,E    ;GET VALUE
  3201.     POP    D    ;..ADDR
  3202. ;
  3203. ;The following comments out the echo of the deleted byte; removing the
  3204. ;  leading semicolons restores the echo
  3205. ;
  3206. ;    PUSH    PSW    ;SAVE VALUE
  3207. ;    LDAX    D    ;GET OLD
  3208. ;    CALL    HEX    ;ECHO IN HEX
  3209. ;    POP    PSW    ;GET NEW
  3210. ;
  3211. ;End of echo of bytes
  3212. ;
  3213.     STAX    D    ;SAVE NEW BYTE
  3214.     MOV    A,C    ;SEE IF 'THRU'
  3215.     ORA    A
  3216.     JZ    CHHNTH    ;..NO.
  3217.     CMP    E    ;..YES, DONE?
  3218.     JZ    PROMPT
  3219.     LHLD    HEXAD    ;..NO: MORE
  3220. ;
  3221. CHHNTH:
  3222.     INR    E
  3223.     JNZ    CHGHEX
  3224.     MOV    A,M
  3225.     CPI    CR
  3226.     JZ    PROMPT
  3227.     CPI    EOLCH
  3228.     JZ    PROMPT
  3229.     JMP    WHAT
  3230. ;
  3231. ;COMMAND:  R
  3232. ;Read Current Block into TBUFF
  3233. ;COMMAND:  RG
  3234. ;Read Specified Group into GBUFF
  3235. ;
  3236. DOREAD:
  3237.     LDA    NOTPOS    ;POSITIONED?
  3238.     ORA    A
  3239.     JNZ    CANTRD
  3240.     CALL    READ    ;READ BLOCK
  3241.     JMP    PROMPT
  3242. ;
  3243. CANTRD:
  3244.     CALL    ILPRT
  3245.     DB    '++ Can''t read - not positioned ++',CR,LF
  3246.     DB    'Position by:',CR,LF
  3247.     DB    '    Track then Sector, or',CR,LF
  3248.     DB    '    Group',CR,LF,0
  3249.     JMP    PROMPT
  3250. ;
  3251. ;COMMAND:  W
  3252. ;Write Current Block to Disk
  3253. ;COMMAND:  WG
  3254. ;Write Specified Group from GBUFF
  3255. ;
  3256. DORITE:
  3257.     CALL    WRITE    ;DO WRITE
  3258.     JMP    PROMPT
  3259. ;
  3260. ;Print Byte in A as Hex Digits
  3261. ;
  3262. BHEX:
  3263.     PUSH    PSW
  3264.     MVI    A,'<'
  3265.     CALL    TYPE
  3266.     POP    PSW
  3267.     CALL    HEX
  3268.     MVI    A,'>'
  3269.     CALL    TYPE
  3270.     RET
  3271. ;
  3272. ;Print Number in BC as Hex Digits
  3273. ;  HEXB does not print MS Byte if DSM shows small disk size
  3274. ;  HEXB1 prints BC regardless
  3275. ;
  3276. HEXB:
  3277.     LDA    DSM+1
  3278.     ORA    A
  3279.     JZ    HEXX
  3280. HEXB1:
  3281.     MOV    A,B
  3282.     CALL    HEX
  3283. ;
  3284. HEXX:
  3285.     MOV    A,C
  3286. ;
  3287. ;Print Byte in A as 2 Hex Digits
  3288. ;
  3289. HEX:
  3290.     PUSH    PSW
  3291.     RAR        ;GET HIGH NYBBLE
  3292.     RAR
  3293.     RAR
  3294.     RAR
  3295.     CALL    NIBBL    ;PRINT IT
  3296.     POP    PSW    ;GET LOW NYBBLE
  3297. ;
  3298. NIBBL:
  3299.     ANI    0FH    ;MASK LOW NYBBLE
  3300.     CPI    10    ;0-9?
  3301.     JC    HEXNU
  3302.     ADI    7    ;CONVERT TO A-F
  3303. ;
  3304. HEXNU:
  3305.     ADI    '0'    ;CONVERT TO ASCII
  3306.     JMP    TYPE    ;PRINT IT
  3307. ;
  3308. ;Decimal output routine
  3309. ;  Print Number in HL as decimal digits
  3310. ;
  3311. DEC:
  3312.     PUSH    B
  3313.     PUSH    D
  3314.     PUSH    H
  3315.     XRA    A    ;SET NO LEADING DIGIT
  3316.     STA    DDIG
  3317.     LXI    B,10000
  3318.     CALL    DPRT
  3319.     DAD    B
  3320.     LXI    B,1000
  3321.     CALL    DPRT
  3322.     DAD    B
  3323.     LXI    B,100
  3324.     CALL    DPRT
  3325.     DAD    B
  3326.     LXI    B,10
  3327.     CALL    DPRT
  3328.     DAD    B
  3329.     MOV    A,L    ;ALWAYS PRINT LSD
  3330.     ADI    '0'    ;ASCII
  3331.     CALL    TYPE
  3332.     POP    H
  3333.     POP    D
  3334.     POP    B
  3335.     RET
  3336. DPRT:
  3337.     PUSH    B    ;SAVE BC
  3338.     MVI    D,0FFH    ;SET -1
  3339. DPRTL:
  3340.     INR    D    ;ADD 1 TO OUTPUT DIGIT
  3341.     MOV    A,L    ;L-C
  3342.     SUB    C
  3343.     MOV    L,A
  3344.     MOV    A,H    ;H-B
  3345.     SBB    B
  3346.     MOV    H,A
  3347.     JNC    DPRTL
  3348.     POP    B    ;RESTORE BC
  3349.     LDA    DDIG    ;GET LEADING DIGIT FLAG
  3350.     ORA    D    ;CHECK FOR ZERO STILL
  3351.     STA    DDIG    ;SET FLAG
  3352.     MOV    A,D    ;GET DIGIT TO PRINT
  3353.     RZ        ;ABORT IF BOTH ZERO
  3354.     ADI    '0'    ;ASCII
  3355.     JMP    TYPE
  3356. DDIG:    DS    1    ;TEMP FOR DEC USE ONLY
  3357. ;
  3358. ;Print <SP>
  3359. ;
  3360. SPACE:
  3361.     MVI    A,' '
  3362.     JMP    TYPE
  3363. ;
  3364. ;Print a dim '|'
  3365. ;
  3366. ASTER:
  3367.     CALL    STNDOUT    ;DIM
  3368.     MVI    A,'|'
  3369.     CALL    TYPE
  3370.     JMP    STNDEND    ;BRIGHT
  3371. ;
  3372. ;Inline print routine
  3373. ;  Print Chars ending in 0 pted to by Return Address; return to byte after
  3374. ;
  3375. ILPRT:
  3376.     XTHL        ;PT TO STRING
  3377. ILPLP:
  3378.     CALL    CTLCS    ;ABORT?
  3379.     JZ    PRMPTR
  3380.     MOV    A,M    ;GET CHAR
  3381. ;    CPI    1    ;PAUSE? -- ^A
  3382. ;    JNZ    ILPOK
  3383. ;    CALL    CONIN    ;WAIT FOR ANY CHAR
  3384. ;    CPI    3    ;ABORT?
  3385. ;    JZ    PRMPTR
  3386. ;    JMP    ILPNX
  3387. ;
  3388. ;ILPOK:
  3389.     CPI    DIM    ;GOTO DIM?
  3390.     JZ    ILPDIM
  3391.     CPI    BRIGHT    ;GOTO BRIGHT?
  3392.     JZ    ILPBRI
  3393.     CALL    TYPE    ;PRINT CHAR
  3394.     JMP    ILPNX
  3395. ILPDIM:
  3396.     CALL    STNDOUT    ;ENTER STANDOUT MODE
  3397.     JMP    ILPNX
  3398. ILPBRI:
  3399.     CALL    STNDEND    ;EXIT STANDOUT MODE
  3400. ;
  3401. ILPNX:
  3402.     INX    H    ;PT TO NEXT
  3403.     MOV    A,M    ;GET IT
  3404.     ORA    A    ;DONE?
  3405.     JNZ    ILPLP
  3406.     INX    H    ;PT TO BYTE AFTER ENDING 0
  3407.     XTHL        ;RESTORE HL AND RET ADR
  3408.     RET
  3409. ;
  3410. ;DISP calls DECIN, and validates a sector
  3411. ;displacement, then converts it to an address
  3412. ;
  3413. DISP:
  3414.     CALL    DECIN
  3415. DISP1:
  3416.     PUSH    PSW    ;SAVE DELIMITER
  3417.     MOV    A,D
  3418.     ORA    A
  3419.     JNZ    BADISP
  3420.     MOV    A,E
  3421.     ORA    A
  3422.     JM    BADISP
  3423.     ADI    80H    ;TO POINT TO BUFFER AT BASE+80H
  3424.     MOV    E,A
  3425.     MVI    D,BASE/256
  3426.     POP    PSW    ;GET DELIM
  3427.     RET
  3428. ;
  3429. BADISP:
  3430.     CALL    ILPRT
  3431.     DB    '++ Bad Displacement (Not 0-7FH) ++'
  3432.     DB    CR,LF,0
  3433.     JMP    PRMPTR
  3434. ;
  3435. ;Input Number from Command Line -- Assume it to be Hex
  3436. ;  Number returned in DE
  3437. ;
  3438. HEXIN:
  3439.     LXI    D,0    ;INIT VALUE
  3440.     MOV    A,M
  3441.     CPI    '#'    ;DECIMAL?
  3442.     JZ    HDIN    ;MAKE DECIMAL
  3443. ;
  3444. HINLP:
  3445.     MOV    A,M    ;GET CHAR
  3446.     CALL    UPCASE    ;CAPITALIZE
  3447.     CPI    CR    ;EOL?
  3448.     RZ
  3449.     CPI    EOLCH    ;EOL?
  3450.     RZ
  3451.     CPI    SEPCH
  3452.     RZ
  3453.     CPI    ' '    ;SPACE?
  3454.     RZ
  3455.     CPI    '-'    ;'THRU'?
  3456.     RZ
  3457.     CPI    '>'
  3458.     RZ
  3459.     INX    H    ;PT TO NEXT CHAR
  3460.     CPI    '0'    ;RANGE?
  3461.     JC    WHAT
  3462.     CPI    '9'+1    ;RANGE?
  3463.     JC    HINNUM
  3464.     CPI    'A'    ;RANGE?
  3465.     JC    WHAT
  3466.     CPI    'F'+1    ;RANGE?
  3467.     JNC    WHAT
  3468.     SUI    7    ;ADJUST FROM A-F TO 10-15
  3469. ;
  3470. HINNUM:
  3471.     SUI    '0'    ;CONVERT FROM ASCII TO BINARY
  3472.     XCHG
  3473.     DAD    H    ;MULT PREVIOUS VALUE BY 16
  3474.     DAD    H
  3475.     DAD    H
  3476.     DAD    H
  3477.     ADD    L    ;ADD IN NEW DIGIT
  3478.     MOV    L,A
  3479.     XCHG
  3480.     JMP    HINLP
  3481. ;
  3482. HDIN:
  3483.     INX    H    ;SKIP '#'
  3484. ;
  3485. ;Input Number in Command Line as Decimal
  3486. ;  Number is returned in DE
  3487. ;
  3488. DECIN:
  3489.     LXI    D,0
  3490.     MOV    A,M    ; GET 1ST CHAR
  3491.     CPI    '#'    ; HEX?
  3492.     JNZ    DINLP
  3493.     INX    H    ; PT TO DIGIT
  3494.     JMP    HINLP    ; DO HEX PROCESSING
  3495. ;
  3496. DINLP:
  3497.     MOV    A,M    ;GET DIGIT
  3498.     CALL    UPCASE    ;CAPITALIZE
  3499.     CPI    '0'    ;RANGE?
  3500.     RC
  3501.     CPI    '9'+1    ;RANGE?
  3502.     RNC
  3503.     SUI    '0'    ;CONVERT TO BINARY
  3504.     INX    H    ;PT TO NEXT
  3505.     PUSH    H
  3506.     MOV    H,D
  3507.     MOV    L,E
  3508.     DAD    H    ;X2
  3509.     DAD    H    ;X4
  3510.     DAD    D    ;X5
  3511.     DAD    H    ;X10
  3512.     ADD    L    ;ADD IN DIGIT
  3513.     MOV    L,A
  3514.     MOV    A,H
  3515.     ACI    0
  3516.     MOV    H,A
  3517.     XCHG        ;RESULT IN DE
  3518.     POP    H
  3519.     JMP    DINLP
  3520. ;
  3521. ;Read in a console buffer
  3522. ;
  3523. RDBUF:
  3524.     CALL    ILPRT    ;PRINT PROMPT
  3525.     DB    CR,LF,'DU3  ',0
  3526.     LDA    DRIVE    ;GET DRIVE NUMBER
  3527.     ADI    'A'    ;CONVERT TO ASCII
  3528.     CALL    TYPE
  3529.     LDA    UNUM    ;DISPLAY USER NUMBER
  3530.     MOV    L,A    ;VALUE IN HL
  3531.     MVI    H,0
  3532.     CALL    DEC    ;PRINT IN DECIMAL
  3533.     CALL    ILPRT    ;PRINT PROMPT
  3534.     DB    '? ',0
  3535. ;
  3536. ;ENTRY POINT TO READ BUFFER WITHOUT PROMPT
  3537. ;
  3538. RDBUF1:
  3539.     LHLD    INBUF    ;USE CP/M READLN
  3540.     DCX    H
  3541.     DCX    H
  3542.     XCHG
  3543.     MVI    C,10
  3544.     PUSH    D
  3545.     CALL    BDOS
  3546.     POP    D
  3547.     INX    D    ;PT TO CHAR COUNT
  3548.     LDAX    D    ;GET CHAR COUNT
  3549.     MOV    B,A    ;CHAR COUNT IN B
  3550.     INX    D    ;PT TO INPUT LINE
  3551.     XCHG        ;... IN HL
  3552.     ADD    L    ;ADD CHAR COUNT TO HL
  3553.     MOV    L,A
  3554.     MOV    A,H
  3555.     ACI    0
  3556.     MOV    H,A
  3557.     MVI    A,CR    ;STORE ENDING CR
  3558.     MOV    M,A    ;SET CR
  3559.     CALL    TYPE    ;ECHO IT
  3560.     MVI    A,LF    ;ECHO..
  3561.     CALL    TYPE    ;..LF
  3562.     LHLD    INBUF    ;SET PTR TO FIRST CHAR IN LINE
  3563.     RET
  3564. ;
  3565. ;Set paging flag for page routine
  3566. ;
  3567. PAGSET:
  3568.     LDA    PAGSIZ    ;GET SIZE OF PAGE
  3569.     STA    PAGFLG    ;SET FLAG
  3570.     RET
  3571. ;
  3572. ;Page output
  3573. ;
  3574. PAGER:
  3575.     LDA    PAGFLG    ;GET FLAG
  3576.     CPI    2    ;2 LINES LEFT?
  3577.     JZ    WAIT    ;SAME AS USER DELAY
  3578.     DCR    A    ;COUNT DOWN
  3579.     STA    PAGFLG
  3580.     JMP    CRLF
  3581. ;
  3582. ;Delay Routine
  3583. ;
  3584. SWAIT:
  3585.     CALL    AT
  3586.     DB    23,5    ;POSITION CURSOR
  3587.     JMP    WAIT0
  3588. WAIT:
  3589.     CALL    CRLF    ;NEW LINE
  3590. WAIT0:
  3591.     PUSH    H
  3592.     CALL    ILPRT
  3593.     DB    DIM,'Type Any Character to Continue or ^C to Abort - ',BRIGHT,0
  3594.     POP    H
  3595.     CALL    CONIN    ;GET RESPONSE
  3596.     CPI    'C'-40H    ;^C?
  3597.     JZ    WAIT1
  3598.     CALL    CRLF    ;NEW LINE
  3599.     CALL    PAGSET    ;RESET PAGE COUNT
  3600.     RET
  3601. WAIT1:
  3602.     LDA    IHFLG    ;INITIAL HELP?
  3603.     ORA    A    ;0=NO
  3604.     JZ    PRMPTR    ;ABORT TO COMMAND PROMPT
  3605.     JMP    EXIT1    ;ABORT TO CP/M
  3606. ;
  3607. ;CRLF Routine
  3608. ;
  3609. CRLF:
  3610.     MVI    A,CR
  3611.     CALL    TYPE
  3612.     MVI    A,LF
  3613.     JMP    TYPE
  3614. ;
  3615. ;Convert to Upper Case
  3616. ;
  3617. UPCASE:
  3618.     ANI    7FH    ;MASK OUT MSB
  3619.     CPI    60H    ;LESS THAN SMALL A?
  3620.     RC        ;RETURN IF SO
  3621.     ANI    5FH    ;MAKE UPPER CASE
  3622.     RET
  3623. ;
  3624. ;CON: Status Routine
  3625. ;
  3626. CONST:
  3627.     PUSH    B
  3628.     PUSH    D
  3629.     PUSH    H
  3630. VCONST:
  3631.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3632.     POP    H
  3633.     POP    D
  3634.     POP    B
  3635.     RET
  3636. ;
  3637. ;CON: Input Routine
  3638. ;
  3639. CONIN:
  3640.     PUSH    B
  3641.     PUSH    D
  3642.     PUSH    H
  3643. VCONIN:
  3644.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3645.     POP    H
  3646.     POP    D
  3647.     POP    B
  3648.     RET
  3649. ;
  3650. ;Console out with TAB expansion
  3651. ;  Char in A
  3652. ;
  3653. TYPE:
  3654.     PUSH    B    ;SAVE REGS
  3655.     PUSH    D
  3656.     PUSH    H
  3657.     MOV    C,A    ;FOR OUTPUT ROUTINE
  3658.     CPI    TAB
  3659.     JNZ    TYPE2
  3660. ;Tabulate
  3661. TYPTAB:
  3662.     MVI    A,' '    ;PRINT SPACE
  3663.     CALL    TYPE
  3664.     LDA    TABCOL    ;GET COL COUNT
  3665.     ANI    7    ;DONE?
  3666.     JNZ    TYPTAB
  3667.     JMP    TYPRET
  3668. ;
  3669. ;Filter out control characters to
  3670. ;prevent garbage during view of file
  3671. ;
  3672. TYPE2:
  3673.     CPI    ' '
  3674.     JNC    TYPEQ
  3675.     CPI    CR
  3676.     JZ    TYPEQ
  3677.     CPI    LF
  3678.     JNZ    TYPNCR
  3679. ;
  3680. TYPEQ:
  3681. ;
  3682. ;CON: Output Routine
  3683. ;
  3684. VCONOT:    CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3685. ;
  3686. ;Update column used in tab expansion
  3687. ;
  3688.     MOV    A,C    ;GET CHAR
  3689.     CPI    CR
  3690.     JNZ    TYPNCR
  3691.     MVI    A,0    ;RESET TAB COLUMN IF <CR>
  3692.     STA    TABCOL
  3693.     JMP    TYPLST
  3694. ;
  3695. TYPNCR:
  3696.     CPI    ' '    ;CTL CHAR?
  3697.     JC    TYPLST    ;..NO CHANGE IN COL
  3698.     LDA    TABCOL    ;INCR TAB COUNT
  3699.     INR    A
  3700.     STA    TABCOL
  3701. ;
  3702. TYPLST:
  3703.     LDA    PFLAG    ;CHECK FOR PRINTER OUTPUT
  3704.     ANI    1
  3705.     CNZ    LIST    ;FROM C REG
  3706. ;
  3707. TYPRET:
  3708.     POP    H    ;RESTORE REGS
  3709.     POP    D
  3710.     POP    B
  3711.     RET
  3712. ;
  3713. ;LST: Output Routine
  3714. ;  Char in C
  3715. ;
  3716. LIST:
  3717.     PUSH    B    ;SAVED REGS
  3718.     PUSH    D
  3719.     PUSH    H
  3720. VLIST:
  3721.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3722.     POP    H
  3723.     POP    D
  3724.     POP    B
  3725.     RET
  3726. ;
  3727. ;Home Disk Routine
  3728. ;
  3729. HOME:
  3730.     PUSH    H
  3731. VHOME:
  3732.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3733.     POP    H
  3734.     RET
  3735. ;
  3736. ;Set track # in DE
  3737. ;
  3738. SETTRK:
  3739.     PUSH    H
  3740.     LHLD    MAXTRK    ;CHECK FOR WITHIN BOUNDS
  3741.     CALL    SUBDE    ;IF TRACK # IN DE > MAX, THEN ERROR
  3742.     POP    H
  3743.     JC    OUTLIM
  3744.     XCHG        ;RESET CURRENT TRACK
  3745.     SHLD    CURTRK
  3746.     XCHG
  3747.     MOV    B,D    ;BC=TRACK NUMBER
  3748.     MOV    C,E
  3749.     PUSH    H
  3750. ;
  3751. VSETRK:
  3752.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3753.     POP    H
  3754.     RET
  3755. ;
  3756. ;Set Sector Number in DE
  3757. ;
  3758. SETSEC:
  3759.     PUSH    H
  3760.     PUSH    D
  3761.     LHLD    SYSTRK    ;GET NUMBER OF SYSTEM TRACKS
  3762.     XCHG
  3763.     SHLD    CURSEC    ;SET CURRENT SECTOR
  3764.     LHLD    CURTRK    ;GET CURRENT TRACK
  3765.     CALL    SUBDE    ;SEE IF WE ARE IN THE SYSTEM TRACKS
  3766.     POP    B    ;BC=SECTOR NUMBER
  3767.     MOV    H,B    ;HL=SECTOR NUMBER
  3768.     MOV    L,C
  3769.     JNC    NOTSYS    ;IF NO CARRY FOR SUBDE, WE ARE NOT IN SYSTEM TRACKS
  3770.     LDA    FIRST0    ;SEE IF FIRST SEC 0
  3771.     ORA    A
  3772.     JNZ    GSTSEC    ;NO, JUMP AWAY
  3773.     DCX    H    ;YES, SO DECREMENT
  3774.     JMP    GSTSEC    ;REQUESTED, THEN GO
  3775. ;
  3776. ;Not in System Tracks, so Skew Factor is effective
  3777. ;
  3778. NOTSYS:
  3779.     LHLD    SECTBL    ;GET PTR TO SECTOR TABLE
  3780.     XCHG        ;... IN DE
  3781.     DCX    B    ;DECREMENT SECTOR NUMBER BY 1
  3782. ;
  3783. VSCTRN:
  3784.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3785.     LDA    SPT+1    ;IF SPT<256 (HI-ORD = 0)
  3786.     ORA    A    ; THEN FORCE 8-BIT TRANSLATION
  3787.     JNZ    GSTSEC    ; ELSE KEEP ALL 16 BITS
  3788.     MOV    H,A
  3789. GSTSEC:
  3790.     SHLD    PHYSEC
  3791.     MOV    B,H
  3792.     MOV    C,L
  3793. ;
  3794. VSTSEC:
  3795.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3796.     POP    H    ;RESTORE PTR TO NEXT CHAR
  3797.     RET
  3798. ;
  3799. ;Out of Disk Track Limit
  3800. ;
  3801. OUTLIM:
  3802.     CALL    ILPRT
  3803.     DB    '++ Not Within Tracks 0-',0
  3804.     PUSH    H
  3805.     LHLD    MAXTRK    ;PRINT MAX TRACK NUMBER
  3806.     CALL    DEC
  3807.     POP    H
  3808.     CALL    ILPRT
  3809.     DB    ' ++',CR,LF,0
  3810.     CALL    NORITE    ;NOT POSITIONED
  3811.     JMP    PRMPTR
  3812. ;
  3813. ;Set DMA Address
  3814. ;
  3815. SETDMA:
  3816.     JMP    $-$    ;ADDR FILLED IN BY 'INIT'
  3817. ;
  3818. ;Read Next Block into DMA Address
  3819. ;
  3820. READ:
  3821.     MVI    A,1    ;SET FLAG
  3822.     STA    WRFLG
  3823.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  3824. ;
  3825. VREAD:
  3826.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3827.     ORA    A    ;ERROR?
  3828.     JZ    READOK
  3829.     CALL    ILPRT
  3830.     DB    '++ READ Failed, Sector may be Invalid ++'
  3831.     DB    CR,LF,0
  3832. ;
  3833. READOK:
  3834.     POP    H    ;GET PTR TO NEXT CHAR
  3835.     RET
  3836. ;
  3837. ;Write Block in DMA Address to Disk
  3838. ;
  3839. WRITE:
  3840.     LDA    WRFLG    ;READ ALREADY PERFORMED?
  3841.     ORA    A    ;ERROR IF NOT
  3842.     JNZ    PWRITE
  3843. ;
  3844. BADW:
  3845.     CALL    ILPRT
  3846.     DB    '++ Cannot Write Unless Read Issued ++'
  3847.     DB    CR,LF,0
  3848.     JMP    EXPL
  3849. ;
  3850. ;Do Write
  3851. ;
  3852. PWRITE:
  3853.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  3854.     MVI    C,1    ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED
  3855. ;
  3856. VWRITE:
  3857.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  3858.     ORA    A    ;ERROR?
  3859.     JZ    WRITOK
  3860.     CALL    ILPRT
  3861.     DB    '++ WRITE Failed ++',CR,LF,0
  3862. ;
  3863. WRITOK:
  3864.     POP    H
  3865.     RET
  3866. ;
  3867. ;Help; HELP is entry point for HELP (?) command, HELP1 is entry point for
  3868. ; Initial Help Command, and IHELP is entry point for HELP (/) from command
  3869. ; line
  3870. ;
  3871. IHELP:
  3872.     call    cls
  3873.     cz    crlf
  3874.     call    helpban
  3875.     CALL    ILPRT
  3876.     DB    DIM,'Introductory HELP on DU3 (Disk Utility)',BRIGHT,CR,LF
  3877.     DB    '  The DU3 program is designed to provide the user with'
  3878.     DB    CR,LF
  3879.     DB    'the ability to manipulate information on the disk as easily'
  3880.     DB    CR,LF
  3881.     DB    'as the DDT and SID utilities allow the user to manipulate'
  3882.     DB    CR,LF
  3883.     DB    'information in memory.',CR,LF
  3884.     DB    '  The following is a summary of the commands available to'
  3885.     DB    CR,LF
  3886.     DB    'the DU3 user.  This same list is invoked internally by the'
  3887.     DB    CR,LF
  3888.     DB    '? Command of DU3.  For additional information on disk'
  3889.     DB    CR,LF
  3890.     DB    'structures and how to use DU3 in general, refer to the'
  3891.     DB    CR,LF
  3892.     DB    'file DU3.HLP.',CR,LF,0
  3893.     MVI    A,0FFH    ;A=0FFH
  3894.     STA    IHFLG    ;SET INITIAL HELP
  3895.     CALL    SWAIT
  3896.     JMP    HELP1    ;PROCESS NORMALLY
  3897. HELP:
  3898.     XRA    A    ;A=0
  3899.     STA    IHFLG    ;SET NO INITIAL HELP
  3900. HELP1:
  3901.     call    cls
  3902.     cz    crlf
  3903.     call    helpban    ;print help banner
  3904.     CALL    ILPRT
  3905.     DB    'Operands in brackets [...] are optional'
  3906.     DB    CR,LF,CR,LF
  3907.     DB    '    @    ',DIM,'Repeat Previous Non-@ Command Line'
  3908.     DB    BRIGHT,CR,LF
  3909.     DB    '    +[nn]    ',DIM,'Step In [nn (decimal)] Sectors'
  3910.     DB    BRIGHT,CR,LF
  3911.     DB    '    -[nn]    ',DIM,'Step Out [nn (decimal)] Sectors'
  3912.     DB    BRIGHT,CR,LF
  3913.     DB    DIM
  3914.     DB    '     Note:  + or - need not be followed by a "," to '
  3915.     DB    'delimit commands.'
  3916.     DB    BRIGHT
  3917.     DB    CR,LF
  3918.     DB    '    #    ',DIM,'Print Disk Parameters for Current Drive'
  3919.     DB    BRIGHT
  3920.     DB    CR,LF
  3921.     DB    '    =xxx    ',DIM
  3922.     DB    'Search for ASCII xxx from Current Sector'
  3923.     DB    BRIGHT
  3924.     DB    CR,LF
  3925.     DB    DIM
  3926.     DB    '     Note:  upper/lower case matters.  Use <xx> for hex:'
  3927.     DB    BRIGHT
  3928.     DB    CR,LF
  3929.     DB    DIM
  3930.     DB    '      To find "IN 0" use: =<db><0>     or'
  3931.     DB    BRIGHT
  3932.     DB    CR,LF
  3933.     DB    DIM
  3934.     DB    '      "(tab)H,0(CR)(LF)" use: =<9>H,0<D><A>'
  3935.     DB    BRIGHT
  3936.     DB    CR,LF
  3937.     DB    '    *[nn]    ',DIM,'Repeat [nn (decimal) times]'
  3938.     DB    BRIGHT,CR,LF
  3939.     DB    '    !    ',DIM,'Pause for User',BRIGHT,CR,LF
  3940.     DB    '    :ntext    ',DIM,'Define ''text'' to be Macro n'
  3941.     DB    BRIGHT,CR,LF
  3942.     DB    '    n    ',DIM,'Perform Macro n, 0<=n<=9',BRIGHT,CR,LF
  3943.     DB    '    :Pn    ',DIM,'Print Macro n, 0<=n<=9',BRIGHT
  3944.     DB    CR,LF
  3945.     DB    '    :Px    ',DIM
  3946.     DB    'Print All Macros if x=A or Print Prev Line if x=@'
  3947.     DB    BRIGHT
  3948.     DB    0
  3949.     CALL    SWAIT
  3950.     call    cls
  3951.     cz    crlf
  3952.     call    helpban
  3953.     CALL    ILPRT
  3954.     DB    '    A[ff,tt]    ',DIM,'ASCII Dump',BRIGHT
  3955.     DB    CR,LF
  3956.     DB    '    C        ',DIM,'Change:',BRIGHT
  3957.     DB    CR,LF
  3958.     DB    '              CHaddr byte byte... (hex)'
  3959.     DB    CR,LF
  3960.     DB    '              ',DIM,'or',BRIGHT
  3961.     DB    ' CAaddr data...  (Ascii)'
  3962.     DB    CR,LF
  3963.     DB    DIM
  3964.     DB    '                 <xx> Allowed for imbedded hex.'
  3965.     DB    BRIGHT
  3966.     DB    CR,LF
  3967.     DB    '              ',DIM,'or',BRIGHT
  3968.     DB    ' CHfrom-thru byte  e.g. ch0-7f e5'
  3969.     DB    CR,LF
  3970.     DB    '              ',DIM,'or',BRIGHT,' CAfrom-thru byte'
  3971.     DB    CR,LF
  3972.     DB    '    D[ff,tt]    ',DIM,'Dump (Hex and ASCII)',BRIGHT
  3973.     DB    CR,LF
  3974.     DB    '    E               ',DIM,'DU3 Editor',BRIGHT,CR,LF
  3975.     DB    '                    ',DIM,' Note: Rest of Command Line '
  3976.     DB    'is Flushed',BRIGHT,CR,LF
  3977.     DB    '    Ffn.ft        ',DIM,'Find File',BRIGHT
  3978.     DB    CR,LF
  3979.     DB    '    Gnn        ',DIM,'CP/M Allocation Group nn (hex)'
  3980.     DB    BRIGHT,CR,LF
  3981.     DB    '    H[ff,tt]    ',DIM,'Hex Dump',BRIGHT
  3982.     DB    CR,LF
  3983.     DB    '    L[d]        ',DIM,'Log in Current Drive or Drive d'
  3984.     DB    BRIGHT,CR,LF
  3985.     DB    '    M[nn]        ',DIM,'Map [from group nn (hex)]'
  3986.     DB    BRIGHT
  3987.     DB    0
  3988.     CALL    SWAIT
  3989.     call    cls
  3990.     cz    crlf
  3991.     call    helpban
  3992.     CALL    ILPRT
  3993.     DB    '    N    ',DIM,'Load New Disk',BRIGHT,CR,LF
  3994.     DB    '    P    ',DIM,'Toggle Printer Switch',BRIGHT,CR,LF
  3995.     DB    '    Q    ',DIM,'Queue Status;',BRIGHT,CR,LF
  3996.     DB    '    QZ    ',DIM,'Zero (Empty) Queue',BRIGHT,CR,LF
  3997.     DB    '    QSfn.ft ',DIM,'Save Queue as a File on Disk',BRIGHT
  3998.     DB    CR,LF
  3999.     DB    '    <    ',DIM,'Save Current Block into Temp',BRIGHT
  4000.     DB    CR,LF
  4001.     DB    '    >    ',DIM,'Restore Temp Block',BRIGHT,CR,LF
  4002.     DB    '    <B    ',DIM,'Save Block into Queue',BRIGHT,CR,LF
  4003.     DB    '    >B    ',DIM,'Restore Queue Block',BRIGHT,CR,LF
  4004.     DB    '    <G[n]    ',DIM,'Save Group into Queue',BRIGHT,CR,LF
  4005.     DB    '    >G[n]    ',DIM,'Restore Queue Group',BRIGHT,CR,LF
  4006.     DB    '    Snn    ',DIM,'Sector nn (decimal)',BRIGHT,CR,LF
  4007.     DB    '    Tnn    ',DIM,'Track nn (decimal)',BRIGHT,CR,LF
  4008.     DB    '    Unn    ',DIM,'Set User nn (decimal) for Find command'
  4009.     DB    BRIGHT,CR,LF
  4010.     DB    '    V[nn]    ',DIM,'View [nn (decimal)] ASCII Blocks',BRIGHT
  4011.     DB    CR,LF
  4012.     DB    '    R    ',DIM,'Read Current Block',BRIGHT,CR,LF
  4013.     DB    '    W    ',DIM,'Write Current Block',BRIGHT,CR,LF
  4014.     DB    '    X    ',DIM,'Exit Program',BRIGHT,CR,LF
  4015.     DB    '    Z[nn]    ',DIM,'Sleep [nn (decimal) seconds]',BRIGHT
  4016.     DB    0
  4017.     CALL    SWAIT
  4018.     call    cls
  4019.     cz    crlf
  4020.     call    helpban
  4021.     CALL    ILPRT
  4022.     DB    DIM,'Command Line is of the form:  ',BRIGHT,'DU3 du?',CR,LF
  4023.     DB    '    ',DIM,'"d" is Logged-In Disk, "u" is Current User'
  4024.     DB    BRIGHT,CR,LF
  4025.     DB    CR,LF
  4026.     DB    'Ctrl-C    ',DIM,'Cancel a function',BRIGHT,CR,LF
  4027.     DB    'Ctrl-S    ',DIM,'Suspend output',BRIGHT,CR,LF
  4028.     DB    '","    ',DIM,'Separate commands',BRIGHT,CR,LF
  4029.     DB    CR,LF
  4030.     DB    DIM,'Examples:',BRIGHT,' g0 ',DIM,'and',BRIGHT
  4031.     DB    ' +,d,z2,*'
  4032.     DB    CR,LF
  4033.     DB    DIM,'Causes:',BRIGHT,CR,LF
  4034.     DB    '    1. Position to group 0',CR,LF
  4035.     DB    '    2. Loops on step in, dump, sleep 2 sec',CR,LF
  4036.     DB    '        until control-c is typed',CR,LF,CR,LF
  4037.     DB    '"nn" usage varies with command as follows:',CR,LF
  4038.     DB    '    +, -, *, T, S, U, V, Z    ',DIM,'nn in Decimal'
  4039.     DB    BRIGHT,CR,LF
  4040.     DB    '                ',DIM,'(use #nn for Hex)'
  4041.     DB    BRIGHT,CR,LF
  4042.     DB    '    G, M            ',DIM,'nn in Hexadecimal'
  4043.     DB    BRIGHT,CR,LF
  4044.     DB    '                ',DIM,'(use #nn for Decimal)'
  4045.     DB    BRIGHT,CR,LF
  4046.     DB    CR,LF
  4047.     DB    '"ff" and "tt" are in Hexadecimal (use #ff or #tt for Decimal)'
  4048.     DB    0
  4049.     CALL    SWAIT
  4050.     LDA    IHFLG    ;INITIAL HELP?
  4051.     ORA    A    ;0=NO
  4052.     JNZ    EXIT1    ;RETURN TO CP/M IF SO
  4053.     JMP    PRMPTR    ;NEW LINE INPUT IF NOT
  4054. helpban:
  4055.     call    ilprt
  4056.     DB    '      ',DIM,'-- DU3 Command Summary --',BRIGHT
  4057.     DB    CR,LF,CR,LF,0
  4058.     ret
  4059. ;
  4060. ;COMMAND:  X
  4061. ;Exit to CP/M
  4062. ;
  4063. EXIT:
  4064.     call    dinit    ;deinit terminal
  4065.     JMP    BASE    ;WARM BOOT
  4066. ;
  4067. ;Quick Exit to CP/M
  4068. ;
  4069. EXIT1:
  4070.     LHLD    DUTSTK    ;GET CP/M STACK PTR
  4071.     SPHL        ;SET SP
  4072.     RET
  4073.  
  4074. ;
  4075. ;********************************
  4076. ;*                *
  4077. ;*    Utility Subroutines    *
  4078. ;*                *
  4079. ;********************************
  4080. ;
  4081. GRPCMP:
  4082.     MOV    A,C
  4083.     INR    D
  4084.     DCR    D
  4085.     JZ    CMP8
  4086.     CMP    M
  4087.     INX    H
  4088.     RNZ
  4089.     MOV    A,B
  4090. ;
  4091. CMP8:
  4092.     CMP    M
  4093.     RET
  4094. ;
  4095. ;2's complement HL ==> HL
  4096. ;
  4097. NEG:
  4098.     MOV    A,L
  4099.     CMA
  4100.     MOV    L,A
  4101.     MOV    A,H
  4102.     CMA
  4103.     MOV    H,A
  4104.     INX    H
  4105.     RET
  4106. ;
  4107. ;HL/2 ==> HL
  4108. ;
  4109. ROTRHL:
  4110.     ORA    A
  4111.     MOV    A,H
  4112.     RAR
  4113.     MOV    H,A
  4114.     MOV    A,L
  4115.     RAR
  4116.     MOV    L,A
  4117.     RET
  4118. ;
  4119. ;Collect the number of '1' bits
  4120. ;in A as a count in C
  4121. ;
  4122. COLECT:
  4123.     MVI    B,8    ;NUMBER OF BITS
  4124. ;
  4125. COLOP:
  4126.     RAL
  4127.     JNC    COSKIP
  4128.     INR    C
  4129. ;
  4130. COSKIP:
  4131.     DCR    B
  4132.     JNZ    COLOP
  4133.     RET
  4134. ;
  4135. ;HL-DE ==> HL
  4136. ;  Carry Flag is Significant
  4137. ;
  4138. SUBDE:
  4139.     MOV    A,L
  4140.     SUB    E
  4141.     MOV    L,A
  4142.     MOV    A,H
  4143.     SBB    D
  4144.     MOV    H,A
  4145.     RET
  4146. ;
  4147. ;Quick Kludge multiply
  4148. ;HL*DE ==> HL
  4149. ;
  4150. MULT:
  4151.     PUSH    B
  4152.     PUSH    D
  4153.     XCHG
  4154.     MOV    B,D
  4155.     MOV    C,E
  4156.     MOV    A,B
  4157.     ORA    C
  4158.     JNZ    MULCON
  4159.     LXI    H,0    ;FILTER SPECIAL CASE
  4160.     JMP    MLDONE    ;  OF MULTIPLY BY 0
  4161. ;
  4162. MULCON:
  4163.     DCX    B
  4164.     MOV    D,H
  4165.     MOV    E,L
  4166. ;
  4167. MULTLP:
  4168.     MOV    A,B
  4169.     ORA    C
  4170.     JZ    MLDONE
  4171.     DAD    D
  4172.     DCX    B
  4173.     JMP    MULTLP
  4174. ;
  4175. MLDONE:
  4176.     POP    D
  4177.     POP    B
  4178.     RET
  4179. ;
  4180. ;Routine to fill in disk params
  4181. ;with every drive change
  4182. ;
  4183. LOGIT:
  4184.     LXI    D,DPB    ;   THEN MOVE TO LOCAL
  4185.     MVI    B,DPBLEN ;  WORKSPACE
  4186.     CALL    MOVE
  4187.     LXI    H,GRPDIS
  4188.     MOV    A,M
  4189.     PUSH    PSW
  4190.     LDA    BLM
  4191.     MOV    M,A
  4192.     PUSH    H
  4193.     LHLD    DSM
  4194.     XCHG
  4195.     CALL    GTKSEC
  4196.     SHLD    MAXSEC
  4197.     XCHG
  4198.     SHLD    MAXTRK
  4199.     POP    H
  4200.     POP    PSW
  4201.     MOV    M,A
  4202.     RET
  4203.  
  4204. ;***********************************
  4205. ;
  4206. ;  DU3 Command Table
  4207. ;
  4208. ;***********************************
  4209. CMDTBL:
  4210.     DB    ' '    ;null command
  4211.     DW    PROMPT
  4212. ;
  4213.     DB    ':'
  4214.     DW    MAC
  4215. ;
  4216.     DB    '@'
  4217.     DW    PCMD
  4218. ;
  4219.     DB    '+'    
  4220.     DW     PLUS
  4221. ;
  4222.     DB    '-'
  4223.     DW    MINUS
  4224. ;
  4225.     DB    '='
  4226.     DW    SEARCH
  4227. ;
  4228.     DB    '<'
  4229.     DW    SAVE
  4230. ;
  4231.     DB    '>'
  4232.     DW    RESTOR
  4233. ;
  4234.     DB    '#'
  4235.     DW    STATS
  4236. ;
  4237.     DB    '?'
  4238.     DW    HELP
  4239. ;
  4240.     DB    MULCH
  4241.     DW    REPEAT
  4242. ;
  4243.     DB    '!'
  4244.     DW    UWAIT
  4245. ;
  4246.     DB    'A'
  4247.     DW    DUMP
  4248. ;
  4249.     DB    'C'
  4250.     DW    CHG
  4251. ;
  4252.     DB    'D'
  4253.     DW    DUMP
  4254. ;
  4255.     DB    'E'
  4256.     DW    EDIT
  4257. ;
  4258.     DB    'F'
  4259.     DW    POSFIL
  4260. ;
  4261.     DB    'G'
  4262.     DW    POS
  4263. ;
  4264.     DB    'H'
  4265.     DW    DUMP
  4266. ;
  4267.     DB    'L'
  4268.     DW    LOGIN
  4269. ;
  4270.     DB    'M'
  4271.     DW    MAP
  4272. ;
  4273.     DB    'N'
  4274.     DW    NEWDSK
  4275. ;
  4276.     DB    'P'
  4277.     DW    PRNTFF
  4278. ;
  4279.     DB    'Q'
  4280.     DW    QUEUER
  4281. ;
  4282.     DB    'R'
  4283.     DW    DOREAD
  4284. ;
  4285.     DB    'S'
  4286.     DW    POS
  4287. ;
  4288.     DB    'T'
  4289.     DW    POS
  4290. ;
  4291.     DB    'U'
  4292.     DW    USER
  4293. ;
  4294.     DB    'V'
  4295.     DW    VIEW
  4296. ;
  4297.     DB    'W'
  4298.     DW    DORITE
  4299. ;
  4300.     DB    'X'
  4301.     DW    EXIT
  4302. ;
  4303.     DB    'Z'
  4304.     DW    SLEEP
  4305. ;
  4306.     DB    0    ; End of Table
  4307. ;*************************************
  4308.  
  4309. ;
  4310. ;Temporary storage area
  4311. ;
  4312. clock:
  4313.     ds    1    ;clock speed
  4314. pagsiz:
  4315.     ds    1    ;page size
  4316. muser:
  4317.     ds    1    ;max user
  4318. mdisk:
  4319.     ds    1    ;max disk
  4320. STKSAV:
  4321.     DS    2    ;SAVE HL VALUE
  4322. DUTSTK:
  4323.     DS    2    ;OLD CP/M STACK POINTER; TOP OF DU3 STACK
  4324. BUFAD:
  4325.     DS    2    ;FORCES INITIAL READ
  4326. QCNT:
  4327.     DS    2    ;NUMBER OF SECTORS IN QUEUE
  4328. QNXT:
  4329.     DS    2    ;PTR TO NEXT SECTOR IN QUEUE
  4330. QLST:
  4331.     DS    2    ;PTR TO LAST SECTOR IN QUEUE
  4332. QPTR:
  4333.     DS    2    ;G-P QUEUE PTR
  4334. HEXAD:
  4335.     DS    2    ;TO RE-FETCH A VALUE
  4336. TOGO:
  4337.     DS    2    ;REPEAT COUNT (FFFF=CONT)
  4338. TWOUP:
  4339.     DS    1
  4340. UNUM:
  4341.     DS    1    ;NUMBER OF CURRENT USER
  4342. ONLY1:
  4343.     DS    1    ;FLAG TO PRINT ONLY 1 MAP ENTRY (0=NO)
  4344. MFPTR:
  4345.     DS    2    ;MULTI FILE PTR FOR GETGRP
  4346. PAGFLG:
  4347.     DS    1    ;LINE COUNTER FOR PAGING
  4348. PFLAG:
  4349.     DS    1    ;1=PRINT
  4350. GROUP:
  4351.     DS    2    ;GROUP NUMBER
  4352. GRPDIS:
  4353.     DS    1    ;DISPLACEMENT INTO GROUP
  4354. SAVEFL:
  4355.     DS    1    ;SAVE FLAG
  4356. CURTRK:
  4357.     DS    2    ;CURRENT TRACK NUMBER
  4358. CURSEC:
  4359.     DS    2    ;CURRENT SECTOR NUMBER
  4360. PHYSEC:
  4361.     DS    2    ;CURRENT PHYSICAL SECTOR NUMBER
  4362. TABCOL:
  4363.     DS    1    ;TAB COLUMN
  4364. CPYFCT:
  4365.     DS    1    ;GROUP COPY FUNCTION; 0=READ, 0FFH=WRITE
  4366. FILECT:
  4367.     DS    2    ;FILE COUNT
  4368. DIRPOS:
  4369.     DS    1    ;POSITION IN DIRECTORY
  4370. FINDFL:
  4371.     DS    1    ;1=MUST POSITION AFTER FIND
  4372. FTSW:
  4373.     DS    1    ;SEARCH W/O INCREMENT
  4374. NOTPOS:
  4375.     DS    1    ;INITIALLY NOT POSITIONED
  4376. WRFLG:
  4377.     DS    1    ;MAY NOT WRITE UNTIL '+', '-',
  4378. ;             OR 'G' COMMAND
  4379. TGRP:
  4380.     DS    2    ;TEMPORARY GROUP FLAG
  4381. FIRST0:
  4382.     DS    1    ;SETS TO 0 IF FIRST SEC # IS 0
  4383. DRIVE:
  4384.     DS    1    ;DRIVE NUMBER
  4385. MAXTRK:
  4386.     DS    2    ;MAX TRACK NUMBER
  4387. MAXSEC:
  4388.     DS    2    ;MAX SECTOR NUMBER
  4389. SECTBL:
  4390.     DS    2    ;POINTER TO SECTOR SKEW TABLE
  4391. ;
  4392. IHFLG:
  4393.     DS    1    ;0=NOT AT INITIAL HELP, 0FFH=AT INITIAL HELP
  4394. DUPFLG:
  4395.     DS    1    ;SPACE OR STAR TO INDICATE MULTIPLE USERS
  4396. BACK:
  4397.     DS    2    ;TO BACK UP IN "CA0-7F,X"
  4398. DUMTYP:
  4399.     DS    1
  4400. ;
  4401. ;The disk parameter block
  4402. ;is moved here from CP/M
  4403. ;
  4404. DPB    EQU    $    ;DISK PARAMETER BLOCK (COPY)
  4405. SPT:
  4406.     DS    2
  4407. BSH:
  4408.     DS    1
  4409. BLM:
  4410.     DS    1
  4411. EXM:
  4412.     DS    1
  4413. DSM:
  4414.     DS    2
  4415. DRM:
  4416.     DS    2
  4417. AL0:
  4418.     DS    1
  4419. AL1:
  4420.     DS    1
  4421. CKS:
  4422.     DS    2
  4423. SYSTRK:
  4424.     DS    2
  4425. ;
  4426. ;End of disk parameter block
  4427. ;
  4428. SAVBUF:
  4429.     DS    2
  4430. INBUF:
  4431.     DS    2    ;INPUT LINE BUFFER
  4432. PINBUF:
  4433.     DS    2    ;PREVIOUS CONTENTS OF INPUT BUFFER
  4434. CTEMP:
  4435.     DS    2    ;BUILD NEW COMMAND LINE BUFFER
  4436. CTEMPX:
  4437.     DS    2    ;END OF CTEMP
  4438. MTABL:
  4439.     DS    2    ;10 PAGES FOR 10 MACROS
  4440. GBUFF:
  4441.     DS    2
  4442. DIRECT:
  4443.     DS    2
  4444. ;
  4445.     END
  4446.