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 / MBUG / MBUG088.ARC / DUTIL.ASM < prev    next >
Assembly Source File  |  1979-12-31  |  65KB  |  3,505 lines

  1. ;PROGRAM:  DUTIL
  2. ;AUTHOR:  RICHARD CONN
  3. ;DERIVATION:  DUTIL is derived from DU Version 7.5
  4. ;VERSION:  1.1
  5. ;DATE:  21 NOV 81
  6. ;PREVIOUS VERSIONS:  1.0 (1 JAN 81)
  7.  
  8. VERS    EQU    11    ; DUTIL Version Number
  9.  
  10. ;
  11. ;  DUTIL is derived from --
  12. ;      DU.ASM  V7.5    Revised 1/23/81
  13. ;    DISK UTILITY - By Ward Christensen
  14. ;
  15. ;  Principal Authors of DU V7.5 are --
  16. ;    WLC   KBP   RGF   BRR
  17. ;
  18. ;  Key comments from DU V7.5 and DUTIL follow --
  19. ;
  20. ;This version of DU is compatible with CP/M 1.4 and 2.x
  21. ;and does not require alteration for various hardware
  22. ;configurations.  It adjusts itself automatically to
  23. ;the correct number of sectors, tracks, directory size,
  24. ;etc.  It has been tested on 5-1/4" and 8" floppy, and
  25. ;10 megabyte hard disk systems.
  26. ;
  27. ;Because of the automatic adaption feature, no conditional
  28. ;assembly options are included.  The only alteration that
  29. ;needs to be done is to use DDT to set the byte at 103h
  30. ;to zero for systems using a 2 mHz clock or non-zero for
  31. ;4 mHz clock.  This only affects the time delay used in
  32. ;the 'sleep' command.
  33. ;
  34. ;For DUTIL, the additional value of PAGSIZ at 104h should
  35. ;be set for the size of the display (in lines) on the user's
  36. ;CON: device.  Under DUTIL, all output is paged, and this
  37. ;determines the page limit.
  38. ;
  39. ;*************************************************
  40. ;*                          *
  41. ;*   This program has been heavily modified     *
  42. ;* to allow it to work without modification     *
  43. ;* on most versions of CP/M 1.4 and, hopefully,     *
  44. ;* all versions of CP/M 2.x.             *
  45. ;*   If you have difficulty getting this program *
  46. ;* to run, AND if you are using CP/M 2.x, AND     *
  47. ;* if you know your BIOS to be bug-free, leave     *
  48. ;* a message on Technical CBBS of Dearborn,     *
  49. ;* Michigan (313)-846-6127 with a description     *
  50. ;* of the problem and a summary of your hard-     *
  51. ;* ware configuration.                 *
  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. ;*   This program should work under standard     *
  63. ;* versions of CP/M 1.4.  The only requirement     *
  64. ;* is that the BIOS "SETSEC" routine not modify     *
  65. ;* the sector number passed to it in the B      *
  66. ;* register.  Again, system tracks with skewed     *
  67. ;* sectors will be a problem.             *
  68. ;*   If you add any features or make any useful     *
  69. ;* changes to this program, please modem a copy     *
  70. ;* to the above CBBS, so the currency of the     *
  71. ;* program can be maintained.             *
  72. ;*                          *
  73. ;*         Ron Fowler             *
  74. ;*                          *
  75. ;*************************************************
  76. ;
  77. ;  The last few revision notes for note are --
  78. ;
  79. ;01/23/81 Changed SETSEC to ignore high-order result of
  80. ;      SECTRN if SPT<256.  This fixes some translation
  81. ;      problems where the BIOS leaves garbage in H. (BRR)
  82. ;
  83. ;01/15/81 Changed labels to be no more than 6 characters
  84. ;      long.  Moved stack.  Cleaned up file.  (KBP)
  85. ;
  86. ;01/13/81 Updated help messages for '#' and 'N' commands.
  87. ;      Modified sign-on message.  (RGF)
  88. ;
  89. ;01/12/81 Fixed problem with sector translation under
  90. ;      CP/M 1.4.  (RGF)
  91. ;
  92.  
  93. ;
  94. ;System equates
  95. ;
  96. BASE    EQU    0    ;SET TO 4200H FOR HEATH OR TRS-80 ALTCPM
  97. ;
  98. ;CP/M Key Areas
  99. ;
  100. FCB    EQU    BASE+5CH    ;CP/M FCB
  101. BDOS    EQU    BASE+5        ;CP/M BDOS ENTRY POINT
  102. TBUFF    EQU    BASE+80H    ;CP/M TEMPORARY DISK I/O BUFFER
  103. TPA    EQU    BASE+100H    ;CP/M TRANSCIENT PROGRAM AREA
  104. ;
  105. ;CP/M BDOS Function Codes
  106. ;
  107. PRINT    EQU    9
  108. GVERS    EQU    12
  109. RESETDK EQU    13
  110. SELDK    EQU    14
  111. SRCHF    EQU    17    ;SEARCH FIRST
  112. SUSER    EQU    32
  113. GETDSK    EQU    25
  114. GETDPB    EQU    31
  115. ;
  116. ;CP/M 1.4 Offsets and Some Key Values
  117. ;
  118. TRNOFF    EQU    15    ;CP/M 1.4 OFFSET FROM BASE
  119.             ;OF BDOS TO SECTRAN ROUTINE
  120. SKWOFF    EQU    1AH    ;CP/M 1.4 OFFSET TO SKEW TABLE
  121. S2OFF    EQU    14    ;OFFSET INTO FCB FOR S2 BYTE
  122. DPBOFF    EQU    3AH    ;CP/M 1.4 OFFSET TO DPB WITHIN BDOS
  123. S2MASK    EQU    0FH    ;MASK FOR EXTENDED RC BITS OF S2
  124. DPBLEN    EQU    15    ;SIZE OF CP/M 2.x DISK PARM BLOCK
  125. ;
  126. ;Define ASCII characters
  127. ;
  128. CR    EQU    0DH    ;CARRIAGE RETURN
  129. LF    EQU    0AH    ;LINE FEED
  130. TAB    EQU    09H    ;TAB
  131. BS    EQU    08H    ;BACKSPACE
  132.  
  133.  
  134.  
  135. ;
  136. ;Beginning of Program
  137. ;
  138.     ORG    TPA
  139.     JMP    START    ;JUMP OVER CLOCK BYTE AND I.D.
  140. ;
  141. CLOCK:
  142.     DB    2    ;<---Put Processor Speed Here (1=1MHZ, 2=2MHZ, etc)
  143. PAGSIZ:
  144.     DB    24    ;<---Put CRT Screen Size Here (24 Lines default)
  145.     DB    'DUTIL.COM from DU.COM ver 7.5 1/23/81 by RLC'
  146. ;
  147. START:
  148.     LXI    H,0    ;GET PTR TO CP/M STACK
  149.     DAD    SP    ;HL=SP
  150.     SHLD    DUTSTK    ;SAVE IT
  151. ;
  152.     LXI    SP,DUTSTK    ; SET STACK
  153. ;
  154.     MVI    C,GVERS    ;GET CP/M VERSION NR
  155.     CALL    BDOS
  156.     MOV    A,H    ;COMBINE THE TWO BYTE...
  157.     ORA    L    ;...VERSION NR FOR A FLAG
  158.     STA    VER2FL    ;SAVE IT
  159. ;
  160. ;Set up local jumps to BIOS
  161. ;
  162.     LHLD    BASE+1    ;WARM BOOT POINTER
  163.     LXI    D,3    ;READY FOR ADD
  164.     DAD    D    
  165.     SHLD    VCONST+1    ;CON: Status
  166.     DAD    D
  167.     SHLD    VCONIN+1    ;CON: Input
  168.     DAD    D
  169.     SHLD    VCONOT+1    ;CON: Output
  170.     DAD    D
  171.     SHLD    VLIST+1        ;LST: Output
  172.     DAD    D    ;Skip PUNCH
  173.     DAD    D    ;Skip RDR
  174.     DAD    D
  175.     SHLD    VHOME+1        ;Home Disk
  176.     DAD    D
  177.     SHLD    VSELDK+1    ;Select Disk
  178.     DAD    D
  179.     SHLD    VSETRK+1    ;Set Track
  180.     DAD    D
  181.     SHLD    VSTSEC+1    ;Set Sector
  182.     DAD    D
  183.     SHLD    SETDMA+1    ;Set DMA Address
  184.     DAD    D
  185.     SHLD    VREAD+1        ;Read Block From Disk
  186.     DAD    D
  187.     SHLD    VWRITE+1    ;Write Block To Disk
  188.     LDA    VER2FL
  189.     ORA    A
  190.     JZ    DOCPM1
  191.     DAD    D    ;Skip LISTST
  192.     DAD    D
  193.     SHLD    VSCTRN+1    ;CP/M 2.x Sector Translation Table
  194.     JMP    HELLO
  195. ;
  196. ;Set up CP/M 1.4 Parameters
  197. ;
  198. DOCPM1:
  199.     LHLD    BDOS+1
  200.     MVI    L,0     ;BDOS ON PAGE BOUNDARY
  201.     PUSH    H
  202.     LXI    D,TRNOFF    ;CP/M 1.4 SECTRAN ROUTINE OFFSET
  203.     DAD    D
  204.     SHLD    VSCTRN+1    ;CP/M 1.4 Sector Translation Table
  205.     POP    H
  206.     LXI    D,SKWOFF ;CP/M 1.4 SKEW TABLE OFFSET
  207.     DAD    D
  208.     SHLD    SECTBL     ;SET UP SKEW TABLE POINTER
  209. ;
  210. ;Initialization Complete -- Print Signon Message and Begin Command Processing
  211. ;
  212. HELLO:
  213.     CALL    GETSTP    ;SET UP CP/M PARAMETERS
  214.     CALL    INITP    ;INITIALIZE BUFFER PARAMETERS
  215.     XRA    A    ;NOT QUIET
  216.     STA    QFLAG
  217.     CALL    ILPRT
  218.     DB    CR,LF,'DUTIL - Disk Utility, Version '
  219.     DB    VERS/10+'0','.',(VERS MOD 10)+'0'
  220.     DB    CR,LF,'    Derived From DISK UTILITY ver 7.5, '
  221.     DB    'Universal Version',CR,LF
  222.     DB    CR,LF
  223.     DB    'Type ? for Help'
  224.     DB    CR,LF,0
  225.     LXI    H,TBUFF    ;TO INPUT BUFF
  226.     MOV    A,M
  227.     ORA    A
  228.     JZ    PRMPTR    ;NO INITIAL COMMAND FROM COMMAND LINE
  229. ;
  230. ;Got initial command, set it up
  231. ;
  232.     MOV    B,A    ;SAVE LENGTH
  233.     DCR    B    ;JUST A SPACE?
  234.     JZ    PRMPTR    ;GOTO COMMAND PROCESSOR IF SO
  235.     LXI    D,INBUF    ;PT TO INLINE BUFFER
  236.     INX    H    ;SKIP LEN
  237.     INX    H    ;SKIP ' '
  238.     MOV    A,M    ;GET FIRST CHAR
  239.     CPI    '/'    ;IF SLASH, PRINT INITIAL HELP (TOOLSET CONVENTION)
  240.     JZ    IHELP    ;PRINT INITIAL HELP INFO
  241.     CALL    MOVE    ;COPY INPUT LINE INTO INLINE BUFFER
  242.     MVI    A,CR    ;STORE ENDING <CR>
  243.     STAX    D
  244.     LXI    H,INBUF    ;PT TO FIRST BYTE OF INLINE BUFFER
  245.     JMP    PRMPTI    ;PROCESS AS THOUGH IT WAS TYPED
  246. ;
  247. ;Input Command Line From User at Console
  248. ;
  249. PRMPTR:
  250.     XRA    A    ;A=0
  251.     STA    QFLAG    ;Set Not Quiet
  252.     CALL    SINBUF    ;Save old INBUF into PINBUF
  253.     CALL    RDBUF    ;Read Input Line
  254.     CALL    EXMAC    ;Expand Macros
  255. ;
  256. ;Begin Processing Command Line in INBUF
  257. ;  At this point, HL points to next character to process
  258. ;
  259. PRMPTI:
  260.     MVI    A,0FFH    ;SET INFINITE LOOP COUNT
  261.     STA    TOGO    ;LOOP COUNT FOR "/"
  262.     STA    TOGO+1
  263. ;
  264. ;Minor Command Loop; This is the entry point for each individual command in
  265. ;  a Command Line; Commands may be separated by semicolons in this manner
  266. ;
  267. PROMPT    EQU    $
  268. SETSTK:
  269.     LXI    SP,DUTSTK    ;RESET STACK
  270.     XRA    A    ;ZERO 2-UP PRINT FOR DUAL-COLUMN PRINT
  271.     STA    TWOUP    ;..SWITCH
  272.     MVI    A,1
  273.     STA    FTSW    ;TELL SEARCH NOT TO INCR
  274.     PUSH    H
  275.     LXI    H,TBUFF    ;SET NO-READ INPUT BUFFER ADDRESS
  276.     SHLD    BUFAD    ;FOR RDBYTE
  277.     POP    H
  278.     CALL    CTLCS    ;ABORT?
  279.     JZ    PRMPTR    ;..YES, READ BUFFER
  280. ;
  281. ;Do we have to position in directory after find?
  282. ;
  283.     LDA    FINDFL
  284.     ORA    A
  285.     JNZ    POSDIR    ;POSITION IN DIRECTORY
  286. ;
  287. ;Begin Command Evaluation -- Check for EOL and Capitalize
  288. ;
  289.     MOV    A,M    ;GET NEXT CHAR IN COMMAND LINE
  290.     INX    H    ;POINT TO FOLLOWING CHAR
  291.     CPI    CR    ;END OF LINE PHYSICALLY?
  292.     JZ    PRMPTR    ;INPUT NEW COMMAND LINE IF SO
  293.     CPI    ';'    ;END OF LINE LOGICALLY?
  294.     JZ    PROMPT    ;PROCESS NEXT ELEMENT IF SO
  295.     CALL    UPCASE    ;CAPITALIZE COMMAND
  296.     STA    DUMTYP    ;TYPE OF DUMP (A,D,H)
  297. ;
  298. ;Command dispatcher
  299. ;  If command not found, abort with error message
  300. ;  If command file, process command with HL pting to next command char and
  301. ;    A containing command letter
  302. ;
  303.     PUSH    H    ;SAVE HL
  304.     MOV    B,A    ;COMMAND IN B
  305.     LXI    H,CMDTBL    ;SCAN COMMAND TABLE FOR USER COMMAND
  306. CMDLP:
  307.     MOV    A,M    ;GET COMMAND
  308.     ORA    A    ;0=END OF TABLE
  309.     JZ    WHAT
  310.     CMP    B    ;COMPARE COMMAND
  311.     JZ    CMDGO
  312.     INX    H    ;PT TO ADR
  313.     INX    H
  314.     INX    H    ;PT TO NEXT CMND
  315.     JMP    CMDLP
  316. CMDGO:
  317.     INX    H    ;PT TO ADDRESS LOW
  318.     MOV    E,M
  319.     INX    H    ;PT TO ADDRESS HIGH
  320.     MOV    D,M
  321.     MOV    A,B    ;COMMAND BACK INTO A
  322.     POP    H    ;RESTORE HL
  323.     PUSH    D    ;PLACE ADDRESS ON STACK
  324.     RET        ;"RUN COMMAND"
  325. ;
  326. ;Macro Expansion Routine -- Expand Macros
  327. ;
  328. EXMAC:
  329.     LXI    H,INBUF    ;PT TO INPUT LINE
  330.     LXI    D,CTEMP    ;BUILD INTO TEMPORARY BUFFER
  331. EXMAC1:
  332.     MOV    A,M    ;GET CHAR
  333.     CPI    '0'    ;SKIP IF LESS THAN '0'
  334.     JC    EXMAC2
  335.     CPI    '9'+1    ;CHECK FOR RANGE
  336.     JNC    EXMAC2
  337.     INX    H    ;PT TO NEXT CHAR
  338.     PUSH    H    ;SAVE PTR TO NEXT CHAR IN LINE
  339.     SUI    '0'    ;CONVERT TO BINARY (0-9)
  340.     MOV    B,A    ;RESULT IN B
  341.     MVI    C,0
  342.     LXI    H,MTABL    ;PT TO BASE OF MACROS
  343.     DAD    B    ;PT TO MACRO
  344.     CALL    COPYM    ;COPY MACRO INTO LINE
  345.     DCX    D    ;BACK UP OVER <CR>
  346.     POP    H    ;GET PTR TO NEXT CHAR IN COMMAND LINE
  347. EXMAC2:
  348.     MOV    A,M    ;GET CHAR
  349.     STAX    D    ;PUT CHAR
  350.     INX    H    ;PT TO NEXT
  351.     INX    D
  352.     CALL    MTEST    ;TEST FOR END OF BUFFER
  353.     CPI    CR    ;DONE?
  354.     JZ    EXMAC3
  355.     CPI    ';'    ;LOGICAL EOL?
  356.     JNZ    EXMAC2
  357.     JMP    EXMAC1    ;PROCESS NEXT COMMAND
  358. EXMAC3:
  359.     LXI    H,CTEMP    ;COPY COMMAND LINE BACK
  360.     LXI    D,INBUF    ;INTO INBUF
  361.     CALL    COPYCR    ;COPY TO <CR>
  362.     LXI    H,INBUF    ;PT TO INBUF
  363.     RET        ;EXPANSION COMPLETE
  364. ;
  365. ;Copy Macro Into Command Line Buffer
  366. ;
  367. COPYM:
  368.     MOV    A,M    ;GET CHAR
  369.     STAX    D    ;PUT CHAR
  370.     INX    H    ;PT TO NEXT
  371.     INX    D
  372.     CALL    MTEST    ;CHECK FOR LIMIT
  373.     CPI    CR    ;END OF MACRO?
  374.     JNZ    COPYM
  375.     RET
  376. ;
  377. ;Test for Buffer Full
  378. ;
  379. MTEST:
  380.     PUSH    H    ;SAVE HL
  381.     PUSH    PSW    ;SAVE A
  382.     LXI    H,CTEMPX    ;CHECK FOR END OF BUFFER
  383.     MOV    A,H    ;GET PAGE
  384.     CMP    D    ;CHECK PAGE
  385.     JZ    MACERR
  386.     POP    PSW    ;GET A
  387.     POP    H    ;GET HL
  388.     RET
  389. ;
  390. ;Macro Command Expansion Error
  391. ;
  392. MACERR:
  393.     XRA    A    ;NOT QUIET
  394.     STA    QFLAG
  395.     CALL    ILPRT
  396.     DB    CR,LF,'Error -- Macro Expanded Command Line too Long',0
  397.     JMP    PRMPTR    ;NEW COMMAND
  398. ;
  399. ;Save INBUF into PINBUF for later processing by '@' command
  400. ;
  401. SINBUF:
  402.     LXI    H,INBUF        ;PT TO INBUF
  403.     LXI    D,PINBUF    ;PT TO PINBUF (PREVIOUS INBUF)
  404. ;
  405. ;Copy (HL) to (DE) until <CR> Encountered
  406. ;
  407. COPYCR:
  408.     MOV    A,M    ;GET CHAR
  409.     STAX    D    ;PUT CHAR
  410.     INX    H    ;PT TO NEXT
  411.     INX    D
  412.     CPI    CR    ;DONE?
  413.     JNZ    COPYCR
  414.     RET
  415.  
  416. ;
  417. ;Command Not Found Error
  418. ;
  419. WHAT:
  420.     XRA    A    ;TURN OFF QUIET FLAG
  421.     STA    QFLAG
  422.     POP    H    ; RESTORE HL
  423.     CALL    ILPRT
  424.     DB    'Invalid Command -- ',0
  425.     MOV    A,B    ;GET COMMAND LETTER
  426.     CALL    TYPE    ;PRINT IT
  427.     JMP    PRMPTR
  428. ;
  429. ;Memory full error
  430. ;
  431. MEMFUL:
  432.     XRA    A    ;TURN OFF QUIET FLAG
  433.     STA    QFLAG
  434.     CALL    ILPRT
  435.     DB    '+++ Out of memory +++'
  436.     DB    CR,LF,0
  437.     JMP    PRMPTR
  438. ;
  439. ;COMMAND:  @
  440. ;Repeat Previous Command Line
  441. ;
  442. PCMD:
  443.     MOV    A,M    ;GET NEXT CHAR
  444.     CPI    CR    ;SHOULD BE <CR>
  445.     JZ    PCMD1
  446.     XRA    A    ;NOT QUIET
  447.     STA    QFLAG
  448.     CALL    ILPRT
  449.     DB    CR,LF,'Warning:  Remainder of Command Line after "@" Deleted',0
  450. PCMD1:
  451.     XRA    A    ;NOT QUIET
  452.     STA    QFLAG
  453.     CALL    ILPRT
  454.     DB    CR,LF,'Command --',CR,LF,0
  455.     LXI    H,PINBUF    ;GET PREVIOUS COMMAND
  456.     LXI    D,INBUF        ;COPY INTO INBUF
  457. PCMD2:
  458.     MOV    A,M    ;GET CHAR
  459.     STAX    D    ;PUT CHAR
  460.     INX    H    ;PT TO NEXT
  461.     INX    D
  462.     CPI    CR    ;END OF LINE?
  463.     PUSH    PSW    ;SAVE FLAG
  464.     CALL    TYPE    ;PRINT CHAR
  465.     POP    PSW    ;GET FLAG
  466.     JNZ    PCMD2
  467.     MVI    A,LF    ;<LF>
  468.     CALL    TYPE
  469.     LXI    H,INBUF    ;RESTART COMMAND PROCESSING
  470.     JMP    PRMPTI    ;INCLUDE LOOP CAPABILITY
  471. ;
  472. ;COMMAND:  :
  473. ;Define or Print Macro
  474. ;:n<text> Defines Macro n, 0<=n<=9; ::n Prints Macro n, 0<=n<=9
  475. ;
  476. MAC:
  477.     MOV    A,M    ;GET NEXT CHAR
  478.     CALL    UPCASE    ;CAPITALIZE
  479.     CPI    'P'    ;PRINT MACRO?
  480.     JNZ    MACROD    ;IF NOT, DEFINE MACRO
  481.     INX    H    ;PT TO MACRO NUMBER
  482.     MOV    A,M    ;GET IT
  483.     CALL    UPCASE    ;CAPITALIZE
  484.     CPI    '@'    ;PRINT PREVIOUS COMMAND?
  485.     JZ    PCPR
  486.     PUSH    PSW    ;SAVE A
  487.     XRA    A    ;A=0
  488.     STA    QFLAG    ;NOT QUIET
  489.     CALL    ILPRT
  490.     DB    'Macro Definitions --',0
  491.     POP    PSW    ;GET A
  492.     CPI    'A'    ;PRINT ALL MACROS?
  493.     JZ    AMACPR
  494.     CALL    MNUM    ;CHECK FOR VALID NUMBER AND RETURN # IN D
  495.     INX    H    ;PT TO CHAR AFTER MACRO NUMBER
  496.     CALL    MACPR    ;PRINT MACRO WHOSE NUMBER IS IN D
  497.     JMP    PROMPT
  498. ;
  499. ;Print Previous Command
  500. ;
  501. PCPR:
  502.     INX    H    ;PT TO CHAR AFTER '@'
  503.     LXI    D,PROMPT    ;SET UP RET ADR
  504.     PUSH    D    ;RETURN ADR ON STACK
  505.     PUSH    H    ;SAVE PTR
  506.     XRA    A    ;NOT QUIET
  507.     STA    QFLAG
  508.     CALL    ILPRT
  509.     DB    'Previous Command Line Definition --'
  510.     DB    CR,LF,'@: ',0
  511.     LXI    H,PINBUF    ;PT TO PREVIOUS COMMAND
  512.     JMP    MPRINT        ;USE MACRO PRINT FACILITY
  513. ;
  514. ;Print All Macros
  515. ;
  516. AMACPR:
  517.     INX    H    ;PT TO CHAR AFTER 'A'
  518.     MVI    D,0    ;SET FOR FIRST MACRO
  519. AMPRL:
  520.     CALL    MACPR    ;PRINT MACRO WHOSE NUMBER IS IN D
  521.     INR    D    ;INCREMENT MACRO NUMBER
  522.     MOV    A,D    ;GET VALUE
  523.     CPI    10    ;DONE?
  524.     JNZ    AMPRL
  525.     JMP    PROMPT    ;CONTINUE PROCESSING
  526. ;
  527. ;Print Macro Whose Number (0-9) is in D
  528. ;
  529. MACPR:
  530.     PUSH    H    ;SAVE PTR
  531.     XRA    A    ;NOT QUIET
  532.     STA    QFLAG
  533.     CALL    ILPRT    ;PRINT HEADER
  534.     DB    CR,LF,0
  535.     MOV    A,D    ;GET NUMBER
  536.     ADI    '0'    ;CONVERT TO ASCII
  537.     CALL    TYPE    ;PRINT
  538.     CALL    ILPRT
  539.     DB    ': ',0
  540.     LXI    H,MTABL    ;PT TO TABLE OF MACROS
  541.     MVI    E,0    ;PAGE OFFSET OF ZERO; MACRO NUMBER ALREADY IN D
  542.     DAD    D    ;PT TO MACRO
  543. MPRINT:
  544.     MOV    A,M    ;GET CHAR
  545.     INX    H    ;PT TO NEXT
  546.     CPI    CR    ;END OF MACRO?
  547.     PUSH    PSW    ;SAVE FLAG
  548.     CALL    TYPE    ;PRINT CHAR
  549.     POP    PSW    ;GET FLAG
  550.     JNZ    MPRINT
  551.     MVI    A,LF    ;<LF>
  552.     CALL    TYPE
  553.     POP    H    ;GET PTR TO NEXT CHAR
  554.     RET
  555. ;
  556. ;Check char in A for valid Macro Number (0-9), print error message if
  557. ; not, return number in D if so
  558. ;
  559. MNUM:
  560.     SUI    '0'    ;CONVERT TO 0-9
  561.     JC    MNERR    ;ERROR IF LESS
  562.     CPI    10    ;RANGE?
  563.     JNC    MNERR
  564.     MOV    D,A    ;RESULT IN D
  565.     RET
  566. MNERR:
  567.     XRA    A    ;NOT QUIET
  568.     STA    QFLAG
  569.     CALL    ILPRT
  570.     DB    CR,LF,'Invalid Macro Number Specified in Command',0
  571.     JMP    PRMPTR    ;NEW COMMAND
  572. ;
  573. ;Define Macro
  574. ;
  575. MACROD:
  576.     CALL    MNUM    ;CHECK NUMBER AND RETURN IN D
  577.     INX    H    ;PT TO CHAR AFTER MACRO NUMBER
  578.     PUSH    H    ;SAVE PTR
  579.     LXI    H,MTABL    ;PT TO MACRO TABLE
  580.     MVI    E,0    ;SET EVEN PAGE
  581.     DAD    D    ;PT TO MACRO ENTRY IN HL
  582.     XCHG        ;... IN DE
  583.     POP    H    ;PT TO MACRO TEXT
  584.     CALL    COPYCR    ;COPY TO <CR>
  585.     JMP    PRMPTR    ;NEW COMMAND
  586. ;
  587. ;COMMAND:  !
  588. ;Delay for user input
  589. ;
  590. UWAIT:
  591.     CALL    WAIT    ; USE WAIT ROUTINE
  592.     JMP    PROMPT
  593. ;
  594. ;COMMAND:  #
  595. ;Print disk statistics
  596. ;
  597. STATS:
  598.     PUSH    H    ;SAVE POINTER TO NEXT COMMAND
  599.     CALL    ILPRT
  600.     DB    '===============================',CR,LF
  601.     DB    '     -- Disk Information --    ',CR,LF
  602.     DB    '-------------------------------',CR,LF
  603.     DB    CR,LF,'Disk Drive:        ',0
  604.     LDA    DRIVE
  605.     ADI    'A'    ;CONVERT TO ASCII
  606.     CALL    TYPE    ;PRINT DRIVE LETTER
  607.     CALL    ILPRT
  608.     DB    CR,LF,'Tracks:            ',0
  609.     LHLD    MAXTRK    ;PRINT NUMBER OF TRACKS
  610.     INX    H
  611.     CALL    DEC
  612.     CALL    ILPRT
  613.     DB    CR,LF,'Sectors/Track:        ',0
  614.     LHLD    SPT    ;PRINT NUMBER OF SECTORS/TRACK
  615.     CALL    DEC
  616.     CALL    ILPRT
  617.     DB    CR,LF,'Group Size:        ',0
  618.     LDA    BLM    ;PRINT SIZE OF A GROUP
  619.     INR    A
  620.     MOV    L,A
  621.     MVI    H,0
  622.     CALL    DEC
  623.     CALL    ILPRT
  624.     DB    ' Blocks/Group'
  625.     DB    CR,LF,'Total Groups:        ',0
  626.     LHLD    DSM    ;PRINT TOTAL NUMBER OF GROUPS ON A DISK
  627.     CALL    DEC
  628.     CALL    ILPRT
  629.     DB    CR,LF,'Directory Entries:    ',0
  630.     LHLD    DRM    ;PRINT NUMBER OF DIRECTORY ENTRIES
  631.     INX    H
  632.     CALL    DEC
  633.     CALL    ILPRT
  634.     DB    CR,LF,'System Tracks:        ',0
  635.     LHLD    SYSTRK    ;PRINT NUMBER OF SYSTEM TRACKS
  636.     CALL    DEC
  637.     CALL    ILPRT
  638.     DB    CR,LF
  639.     DB    '===============================',CR,LF,0
  640.     POP    H    ;RESTORE POINTER TO NEXT COMMAND
  641.     JMP    PROMPT
  642. ;
  643. ;COMMAND:  N
  644. ;The following command resets the disk
  645. ;system thru CP/M, and may be usable for
  646. ;changing the disk density or format.
  647. ;This can only be done if your BIOS resets
  648. ;the auto-density select parameters at
  649. ;every track-zero access.
  650. ;
  651. NEWDSK:
  652.     PUSH    H    ;SAVE POINTER TO NEXT LETTER
  653.     MVI    C,RESETDK    ;BDOS RESET DISK FUNCTION
  654.     CALL    BDOS
  655.     LDA    DRIVE    ;RESELECT CURRENT DRIVE
  656.     MOV    C,A
  657.     POP    H
  658.     CALL    SELECT
  659.     JMP    PROMPT
  660. ;
  661. ;COMMAND:  Q
  662. ;Quite mode
  663. ;
  664. QUIET:
  665.     STA    QFLAG    ;NOW QUIET (FLAG IS NON-ZERO)
  666.     JMP    PROMPT
  667. ;
  668. ;COMMAND:  /
  669. ;Repeat buffer contents
  670. ;
  671. REPEAT:
  672.     CALL    DECIN    ;NN SPECIFIED?
  673.     MOV    A,D
  674.     ORA    E
  675.     JZ    NNN    ;NO -- SET FOR INFINITE LOOP OR SIMPLE REPEAT
  676.     LHLD    TOGO    ;LOAD LOOP FLAG
  677.     INX    H    ;TEST FOR FIRST TIME
  678.     MOV    A,H
  679.     ORA    L    ;WAS IT 0FFFFH?; IF SO, WE HAVE NEW VALUE
  680.     JNZ    NNN    ;NO: COUNTING
  681.     XCHG        ;GET COUNT
  682.     SHLD    TOGO    ;SET COUNT
  683. ;
  684. NNN:
  685.     LHLD    TOGO    ;GET CURRENT COUNT
  686.     XCHG        ;DE=CURRENT COUNT, HL=COUNT LIMIT
  687.     LXI    H,INBUF    ;PT TO FIRST CHAR FOR REPEAT
  688.     INX    D    ;TEST FOR 0FFFFH
  689.     MOV    A,D    ;IF 0FFFFH, INX D MADE DE=0
  690.     ORA    E
  691.     JZ    PROMPT    ;CONTINOUS LOOP IF 0FFFFH
  692.     DCX    D    ;COUNT DOWN
  693.     DCX    D    ;MAKE UP FOR PREV INX D
  694.     XCHG
  695.     SHLD    TOGO    ;SET NEW COUNT (1 LESS THAN BEFORE)
  696.     MOV    A,H    ;ALL DONE?
  697.     ORA    L
  698.     XCHG        ;GET BACK INBUF PTR IN HL
  699.     JNZ    PROMPT    ;KEEP GOING IF NOT YET ZERO
  700.     JMP    PRMPTR    ;ALL DONE
  701. ;
  702. ;COMMAND:  U
  703. ;Set CP/M 2.x user number
  704. ;
  705. USER:
  706.     LDA    VER2FL    ;CP/M 2.X?
  707.     ORA    A
  708.     JZ    WHAT    ;ERROR IF NOT
  709.     CALL    DECIN    ;GET REQUESTED USER NO.
  710.     MOV    A,E
  711.     CPI    32    ;VALID?
  712.     JNC    WHAT
  713.     MOV    A,D    ;HIGH-ORDER BYTE MUST BE ZERO FOR VALID NUMBER
  714.     ORA    A
  715.     JNZ    WHAT
  716.     MOV    A,E    ;SAVE USER NUMBER
  717.     STA    UNUM
  718.     MVI    C,SUSER    ;SET USER NUMBER
  719.     PUSH    H        ;SAVE CHAR POINTER
  720.     CALL    BDOS        ;SET USER NO.
  721.     POP    H
  722.     JMP    PROMPT
  723. ;
  724. ;COMMAND:  P
  725. ;Toggle print flag
  726. ;
  727. PRNTFF:
  728.     LDA    PFLAG    ;TOGGLE PRINT FLAG
  729.     XRI    1
  730.     STA    PFLAG
  731.     JMP    PROMPT
  732. ;
  733. ;COMMAND:  Z
  734. ;Sleep routine, in seconds
  735. ;
  736. SLEEP:
  737.     CALL    DECIN    ;GET COUNT IF ANY
  738.     MOV    A,E    ;ANY?
  739.     ORA    A
  740.     JNZ    SLEPLP
  741.     MVI    E,1    ; 1 SEC DEFAULT
  742. ;
  743. SLEPLP:
  744.     LDA    CLOCK    ; GET CLOCK SPEED
  745.     MOV    D,A
  746. ;
  747. SLEEP1:
  748.     LXI    B,41700    ; APPROX 1 SEC @ 1MHz
  749. ;
  750. SLEEP2:
  751.     DCX    B    ;COUNT DOWN FOR 1 MHz [5 CYCLES]
  752.     MOV    A,B    ;[5 CYCLES] <-- TOTAL TIME: 24 CYCLES
  753.     ORA    C    ;[4 CYCLES] <-- (24 MU-SECS AT 1MHz)
  754.     JNZ    SLEEP2    ;[10 CYCLES]
  755.     PUSH    D
  756.     CALL    CTLCS    ;ABORT?
  757.     POP    D
  758.     JZ    PRMPTR
  759.     DCR    D    ;COUNT DOWN FOR CLOCK SPEED
  760.     JNZ    SLEEP1
  761.     DCR    E    ;COUNT DOWN NUMBER OF REQUESTED SECONDS
  762.     JNZ    SLEPLP
  763.     JMP    PROMPT
  764. ;
  765. ;Check for control-C or S
  766. ;
  767. CTLCS:
  768.     CALL    CONST    ;CHAR AVAILABLE?
  769.     ORA    A
  770.     JNZ    GETC
  771.     ORI    1    ;NO CHAR, RETURN NZ
  772.     RET
  773. ;
  774. GETC:    CALL    CONIN    ;INPUT CHAR
  775.     ANI    1FH    ;ALLOW ASCII
  776.     CPI    'S'-40H    ;WAIT FOR NEXT CHAR IF ^S OR S OR s
  777.     CZ    CONIN
  778.     CPI    'C'-40H    ;CHECK FOR ^C OR C OR c
  779.     RET        ;0 SET IF CTL-C
  780. ;
  781. ;Initialize Memory Buffers
  782. ;
  783. INITP:
  784.     XRA    A    ;A=0
  785.     STA    GLFLAG    ;CLEAR GROUP LOADED FLAG (GROUP NOT LOADED)
  786.     STA    HEXAD    ;CLEAR ADDRESS
  787.     STA    HEXAD+1
  788.     STA    PFLAG    ;SET NO PRINT
  789.     STA    SAVEFL    ;SET NO SAVE DONE
  790.     STA    WRFLG    ;MAY NOT WRITE
  791.     STA    DIRPOS    ;SET NO DIRECTORY POSITION
  792.     STA    FINDFL    ;SET NO POSITION
  793.     INR    A    ;A=1
  794.     STA    FTSW    ;SET SEARCH WITHOUT INCREMENT
  795.     STA    NOTPOS    ;NOT POSITIONED
  796.     LXI    H,0    ;HL=0
  797.     SHLD    MFPTR    ;SET NO MULTI FILE PTR
  798.     SHLD    CURTRK    ;SET TRACK 0
  799.     INX    H    ;HL=1
  800.     SHLD    CURSEC    ;SET LOGICAL SECTOR 1
  801.     SHLD    PHYSEC    ;SET PHYSICAL SECTOR 1
  802.     MVI    A,CR    ;CLEAR PREVIOUS COMMAND
  803.     STA    PINBUF    ;SET PREVIOUS COMMAND TO NIL
  804.     LXI    H,MTABL    ;CLEAR MACRO TABLE
  805.     MVI    B,10    ;10 ENTRIES
  806. INITP1:
  807.     MVI    M,CR    ;STORE <CR>
  808.     INR    H    ;PT TO NEXT PAGE
  809.     DCR    B    ;COUNT DOWN
  810.     JNZ    INITP1
  811.     RET
  812. ;
  813. ;Set up flags, etc, at initialization
  814. ;Find our way at initialization
  815. ;
  816. GETSTP:
  817.     MVI    A,CR    ;INITIALIZE INPUT BUFFER
  818.     STA    INBUF    ;EMPTY BUFFER
  819.     LDA    VER2FL    ;VERSION 2 OR BETTER?
  820.     ORA    A    ;0=1.X
  821.     JZ    GSTP1
  822.     MVI    C,SUSER    ;GET USER NUMBER
  823.     MVI    E,0FFH    ;GET USER
  824.     CALL    BDOS
  825.     STA    UNUM    ;SET USER NUMBER
  826. GSTP1:
  827.     MVI    C,GETDSK
  828.     CALL    BDOS    ;GET CURRENT DISK
  829.     MOV    C,A    ;WE HAVE TO SELECT
  830.     JMP    SELECT    ;TO GET THE DPH
  831. ;
  832. ;COMMAND:  L
  833. ;Log in the selected disk
  834. ;
  835. LOGIN:
  836.     CALL    DOLOG
  837.     JMP    PROMPT
  838. ;
  839. DOLOG:
  840.     MOV    A,M    ;DISK REQUESTED?
  841.     LXI    D,0
  842.     CPI    CR    ;NO REQUEST OF PHYSICAL EOL
  843.     JZ    LGNODK
  844.     CPI    ';'    ;NO REQUEST IF LOGICAL EOL
  845.     JZ    LGNODK
  846.     CALL    UPCASE    ;CAPITALIZE
  847.     INX    H    ;POINT TO NEXT CHAR
  848.     SUI    'A'    ;CONVERT TO 0-15
  849.     MOV    C,A    ;DISK NUMBER IN C
  850. ;
  851. ;Select Disk Whose Number is in C (A=0, B=1, etc)
  852. ;
  853. SELECT:
  854.     PUSH    H    ;SAVE PTR TO NEXT COMMAND LETTER
  855.     MOV    A,C
  856.     STA    DRIVE    ;REMEMBER LATER WHERE WE ARE
  857. ;
  858. VSELDK: CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  859.     LDA    VER2FL
  860.     ORA    A    ;IF NOT CP/M 2.x ...
  861.     JZ    SELSKP    ;..THEN SKIP THIS JUNK
  862.     MOV    A,H
  863.     ORA    L
  864.     JZ    WHAT    ;SELECT ERROR
  865.     MOV    E,M    ;GET THE SECTOR TABLE PNTR
  866.     INX    H
  867.     MOV    D,M
  868.     INX    H
  869.     XCHG
  870.     SHLD    SECTBL    ;SET THE SECTOR TABLE PTR
  871.     LXI    H,8    ;OFFSET TO DPBPTR
  872.     DAD    D
  873.     MOV    A,M    ;PICK UP DPB POINTER
  874.     INX    H    ;  TO USE
  875.     MOV    H,M    ;  AS PARAMETER
  876.     MOV    L,A    ;  TO LOGIT
  877. ;
  878. SELSKP:
  879.     CALL    LOGIT
  880.     LHLD    SYSTRK    ;RESET TRACK AND SECTOR
  881.     XCHG        ;  TO DIRECTORY
  882.     CALL    SETTRK    ;  ON EVERY
  883.     LXI    D,1    ;  LOGIN
  884.     CALL    SETSEC    ;  CHANGE
  885.     LHLD    PHYSEC    ;THIS LOGIC WILL TELL
  886.     MOV    A,H    ;  IF FIRST SEC
  887.     ORA    L    ;  IS PHYSICAL 0
  888.     STA    FIRST0
  889.     CALL    CLCSUB    ;CALCULATE WHAT GROUP/GRPDISP WE ARE IN
  890.     POP    H    ;GET PTR TO NEXT LETTER
  891. ;
  892. LGNODK:
  893.     CALL    NORITE    ;SET NO DISK I/O DONE (NO POSITION)
  894.     RET
  895. ;
  896. ;Read in the disk directory
  897. ;
  898. REDDIR:
  899.     PUSH    H    ;SAVE PTR TO NEXT LETTER
  900.     CALL    NORITE    ;POSITIONING LOST
  901.     LHLD    SYSTRK    ;SAVE CURRENT TRACK
  902.     SHLD    CURTRK
  903.     LXI    H,1    ;SET SECTOR 1
  904.     SHLD    CURSEC
  905.     LHLD    DRM    ;GET DIR SIZE FROM DPB
  906.     INX    H    ;MAKE 1-RELATIVE
  907.     CALL    ROTRHL
  908.     CALL    ROTRHL    ;DIVIDE BY 4 (4 NAMES/SECTOR)
  909.     MOV    B,H    ;BC=NUMBER OF BLOCKS TO READ
  910.     MOV    C,L
  911.     LXI    D,DIRECT    ;DMA ADDR
  912.     XRA    A    ;A=0
  913.     STA    GLFLAG    ;SAY NO GROUP LOADED
  914. ;
  915. ;Read Disk Directory Loop
  916. ;
  917. RDIRLP:
  918.     PUSH    B    ;SAVE REGS
  919.     PUSH    D
  920.     MOV    B,D    ;BC=DMA ADDRESS
  921.     MOV    C,E
  922.     LDA    BDOS+2    ;CHECK MEM AVAIL
  923.     DCR    A    ;ARE WE RNNING INTO BDOS?
  924.     CMP    D
  925.     JC    MEMFUL    ;MEMORY FULL ERROR IF SO
  926.     CALL    SETDMA    ;SET DMA ADDRESS TO THAT IN BC
  927.     LHLD    CURTRK    ;SET TRACK
  928.     XCHG
  929.     CALL    SETTRK
  930.     LHLD    CURSEC    ;SET SECTOR
  931.     XCHG
  932.     CALL    SETSEC
  933.     CALL    READ    ;READ DIRECTORY BLOCK
  934.     CALL    NXTSEC    ;INCREMENT TO NEXT SECTOR
  935.     POP    D
  936.     POP    B
  937.     LXI    H,80H    ;ADVANCE TO NEXT DMA ADDRESS
  938.     DAD    D
  939.     XCHG        ;DE=NEXT DMA ADDRESS
  940.     DCX    B    ;COUNT DOWN DIRECTORY BLOCKS
  941.     MOV    A,B
  942.     ORA    C
  943.     JNZ    RDIRLP
  944.     LXI    B,TBUFF    ;RESET DMA ADDRESS TO TBUFF
  945.     CALL    SETDMA
  946.     POP    H    ;GET PTR TO NEXT CHAR
  947.     RET
  948. ;
  949. ;COMMAND:  M
  950. ;Map the directory
  951. ;
  952. MAP:
  953.     CALL    PAGSET    ;SET PAGING COUNTER
  954.     XRA    A
  955.     STA    ONLY1    ;SET FLAG FOR ALL GROUPS (NOT ONLY 1)
  956.     CALL    REDDIR    ;READ IN DIRECTORY
  957.     MVI    C,0    ;INIT START GRP #
  958.     LDA    AL0    ;READ DIR GRP BITS
  959.     CALL    COLECT    ;COLLECT COUNT OF DIR GRPS..
  960.     LDA    AL1    ;..IN REGISTER C
  961.     CALL    COLECT
  962.     MVI    B,0    ;BC NOW HAS A DEFAULT START GRP #
  963.     CALL    HEXIN    ;GET SPECIFIED GROUP IF ANY
  964.     PUSH    H    ;SAVE INBUF PTR
  965.     MOV    A,E    ;GET START
  966.     ORA    D    ;NOTHING?
  967.     JZ    MAPDF    ;..YES, DFLT
  968.     MVI    A,0FFH    ;SET FLAG FOR ONLY 1 GROUP
  969.     STA    ONLY1
  970.     MOV    B,D    ;GET VALUE IN BC
  971.     MOV    C,E
  972. ;
  973. MAPDF:
  974.     CALL    HEXB    ;PRINT FIRST GROUP NUMBER
  975.     MVI    A,'-'    ;PRINT SEPARATOR
  976.     CALL    TYPE
  977.     MVI    A,' '    ;SET NO DUPLICATES
  978.     STA    DUPFLG
  979.     CALL    GETGRP    ;GET GRP(C) TO HL
  980. ;
  981. MAPCNT:
  982.     INX    B    ;NEXT GRP #
  983.     PUSH    H
  984.     LHLD    DSM    ;GET HIGHEST GRP #
  985.     INX    H    ;PLUS 1 FOR COMPARISON
  986.     MOV    A,L    ;WHEN BC REACHES DSM+1..
  987.     CMP    C    ;..THEN WE HAVE EXCEEDED..
  988.     JNZ    MAPC1    ;..THE DISK CAPACITY..
  989.     MOV    A,H
  990.     CMP    B
  991. ;
  992. MAPC1:
  993.     POP    H
  994.     JZ    MAPEND    ;..AND WE ARE DONE
  995.     PUSH    H
  996.     CALL    GETGRP    ;GET ANOTHER
  997.     POP    D    ;SEE IF SAME
  998.     CALL    CTLCS    ;ABORT?
  999.     JZ    MAPND2
  1000.     MOV    A,D
  1001.     CMP    H
  1002.     JNZ    MAPDIF
  1003.     MOV    A,E
  1004.     CMP    L
  1005.     JZ    MAPCNT    ;SAME, CONTINUE
  1006. ;
  1007. ;Different file encountered
  1008. ;
  1009. MAPDIF:
  1010.     DCX    B
  1011.     CALL    HEXB    ;PRINT ENDING GROUP NUMBER
  1012.     INX    B
  1013.     XCHG
  1014.     CALL    MAPNAM    ;PRINT FILE NAME
  1015.     LDA    ONLY1    ;ONLY 1 NAME TO BE PRINTED?
  1016.     ORA    A    ;0=NO
  1017.     JNZ    MAPND1
  1018.     JMP    MAPDF
  1019. ;
  1020. ;End of map
  1021. ;
  1022. MAPEND:
  1023.     DCX    B    ;GET LAST
  1024.     CALL    HEXB    ;PRINT LAST GROUP NUMBER
  1025.     CALL    MAPNAM    ;PRINT FILE NAME
  1026.     CALL    WAIT    ;DELAY FOR USER
  1027. MAPND1:
  1028.     POP    H
  1029.     CALL    CRLF    ;NEW LINE
  1030. ;
  1031. ;End of map - reposition to previous group
  1032. ;
  1033. MAPND2:
  1034.     PUSH    H
  1035.     LHLD    GROUP    ;POINT TO GROUP IN DE
  1036.     XCHG
  1037.     JMP    POSGP2
  1038. ;
  1039. ;Print file name pointed to by HL
  1040. ;
  1041. MAPNAM:
  1042.     CALL    SPACE    ;LEADING SPACE
  1043.     MOV    A,H
  1044.     ORA    L    ;NONE?
  1045.     JZ    NONAME
  1046.     MOV    A,M    ;SEE IF ALLOC
  1047.     CPI    0E5H    ;FREE?
  1048.     MVI    A,' '    ;MARK ALLOCATED
  1049.     JNZ    MPNSP1
  1050.     MVI    A,'('    ;MARK NOT ALLOCATED (ERASED FILE)
  1051. ;
  1052. MPNSP1:
  1053.     CALL    TYPE    ;PRINT ALLOCATION INDICATOR (SPACE OR '(')
  1054.     PUSH    H    ;SAVE POINTER
  1055.     MOV    A,M
  1056.     CALL    HEX    ;SHOW USER NUMBER
  1057.     CALL    SPACE
  1058.     INX    H    ;SKIP USER BYTE
  1059.     PUSH    B
  1060.     MVI    B,8    ;PRINT FILE NAME
  1061.     CALL    MAPN2
  1062.     MVI    A,'.'    ;PRINT DECIMAL SEPARATOR
  1063.     CALL    TYPE
  1064.     MVI    B,3    ;PRINT FILE TYPE
  1065.     CALL    MAPN2
  1066.     LDA    DUPFLG    ;DUPLICATE?
  1067.     CALL    TYPE    ;SPACE OR STAR
  1068.     POP    B
  1069.     MOV    A,M    ;GET EXT
  1070.     CALL    HEX    ;PRINT EXTENT NUMBER
  1071.     POP    H
  1072.     MOV    A,M
  1073.     CPI    0E5H    ;DELETED ENTRY?
  1074.     MVI    A,' '    ;PRINT ENDING SPACE
  1075.     JNZ    MPNSP2
  1076.     MVI    A,')'    ;PRINT ALLOCATION FLAG
  1077. ;
  1078. MPNSP2:
  1079.     CALL    TYPE    ;")" IF ERASED FILE OR SPACE IF NOT
  1080.     JMP    FLIP
  1081. ;
  1082. NONAME:
  1083.     CALL    ILPRT
  1084.     DB    '    ++ Free ++      ',0
  1085. ;
  1086. FLIP:
  1087.     LDA    TWOUP    ;FLIP FLAG FOR TWO ENTRIES PER LINE
  1088.     XRI    1
  1089.     STA    TWOUP
  1090.     JZ    PAGER    ;NEW LINE WITH PAGING IF REQUIRED
  1091. ;
  1092. DELIM:
  1093.     MVI    A,':'    ;PRINT DELIMITER BETWEEN ADJACENT ENTRIES ON LINE
  1094.     CALL    TYPE
  1095.     JMP    SPACE
  1096. ;
  1097. ;Print name pted to by HL, length in B
  1098. ;
  1099. MAPN2:
  1100.     MOV    A,M
  1101.     ANI    7FH    ;STRIP POSSIBLE 2.x ATTRIBUTE BIT
  1102.     INX    H
  1103.     CPI    ' '    ;PRINTABLE?
  1104.     JC    MAPN2H    ;..NO, IN HEX
  1105.     CPI    7EH    ;7E IS LEADIN ON SOME CRTS
  1106.     JC    MAPN2A
  1107. ;
  1108. MAPN2H:
  1109.     CALL    BHEX    ;PRINT A AS HEX CHARS
  1110.     JMP    MAPN2Z
  1111. ;
  1112. MAPN2A:
  1113.     CALL    TYPE    ;PRINT AS CHAR
  1114. ;
  1115. MAPN2Z:
  1116.     DCR    B    ;COUNT DOWN
  1117.     JNZ    MAPN2
  1118.     RET
  1119. ;
  1120. ;Find which file group (BC) belongs to
  1121. ;
  1122. GETGRP:
  1123.     LHLD    DRM    ;MAX DIR ENTRY #
  1124.     INX    H    ;MAKE 1-RELATIVE
  1125.     SHLD    FILECT
  1126.     LXI    H,0
  1127.     SHLD    MFPTR    ;SET MULTI-FILE (MORE THAN ONE USER) PTR
  1128.     LXI    H,DIRECT    ;PT TO DIRECTORY
  1129.     XRA    A    ;SAY NO GROUP LOADED
  1130.     STA    GLFLAG
  1131. ;
  1132. GETGLP:
  1133.     PUSH    H    ;SAVE POINTER TO NAME
  1134.     MOV    A,M    ;PICK UP DN BYTE
  1135.     CPI    0E5H    ;ERASED?
  1136.     JZ    GETGNF
  1137.     LXI    D,14    ;NOW GET RECORD COUNT
  1138.     DAD    D    ;  S2 PORTION ..
  1139.     MOV    A,M    ;  IS 0 IN CP/M 1.4
  1140.     ANI    0FH
  1141.     MOV    E,A
  1142.     INX    H
  1143.     MOV    A,M
  1144.     ORA    E
  1145.     JZ    GETGNF
  1146.     MVI    E,16    ;FIRST SET FOR 8-BIT GRPS
  1147.     LDA    DSM+1
  1148.     ORA    A
  1149.     JZ    SMALGP
  1150.     MVI    E,8    ;NOPE, BIG GROUPS
  1151. ;
  1152. SMALGP:
  1153.     MOV    D,A    ;SAVE GRP SIZE INDICATOR
  1154. ;
  1155. GETGL2:
  1156.     INX    H    ;POINTING INTO DM FIELD
  1157.     CALL    GRPCMP    ;COMPARE BC GP # AGAINST 1 DM FLD
  1158.     JNZ    NOTGOT    ;JUMP IF NOT FOUND
  1159. ;
  1160. ;Found the file
  1161. ;
  1162.     PUSH    H    ;SAVE GROUP PTR
  1163.     LHLD    MFPTR
  1164.     MOV    A,H    ;ANY ENTRIES?
  1165.     ORA    L
  1166.     POP    H    ;GET PTR
  1167.     XTHL        ;SAVE ENTRY START AND SAVE PTR
  1168.     JZ    MPFRST    ;IF ZERO, THEN FIRST ENTRY
  1169.     MVI    A,'*'    ;SET MULTI FLAG
  1170.     STA    DUPFLG
  1171. MPFRST:
  1172.     SHLD    MFPTR    ;SAVE POINTER
  1173.     XTHL        ;RESTORE ENTRY START AND GET PTR
  1174. NOTGOT:
  1175.     DCR    E    ;COUNT DOWN
  1176.     JNZ    GETGL2    ;GO TEST SOME MORE
  1177. ;
  1178. GETGNF:
  1179.     POP    H    ;NOT THIS ONE
  1180.     LXI    D,32    ;SO GO TO NEXT
  1181.     DAD    D
  1182.     XCHG
  1183.     LHLD    FILECT    ;THERE IS LIMIT TO EVERYTHING
  1184.     DCX    H
  1185.     SHLD    FILECT
  1186.     MOV    A,H
  1187.     ORA    L
  1188.     XCHG        ;RE-ALIGN
  1189.     JNZ    GETGLP
  1190. ;
  1191. ;Set the allocation address, if any
  1192. ;
  1193.     LHLD    MFPTR    ;GET ADDRESS
  1194.     RET
  1195. ;
  1196. ;COMMAND:  <
  1197. ;Save the current sector
  1198. ;
  1199. SAVE:
  1200.     LDA    WRFLG    ;READ DONE?
  1201.     ORA    A
  1202.     JZ    BADW    ;NONE TO SAVE
  1203.     PUSH    H
  1204.     LXI    H,TBUFF    ;COPY FROM TBUFF
  1205.     LXI    D,SAVBUF    ;INTO SAVBUF
  1206.     MVI    B,128    ;128 BYTES
  1207.     CALL    MOVE
  1208.     MVI    A,1    ;..SHOW
  1209.     STA    SAVEFL    ;..SAVED EXISTS
  1210.     POP    H    ;GET PTR TO NEXT CHAR
  1211.     JMP    PROMPT
  1212. ;
  1213. ;This routine is common to Save Group (RG) and Write Group (WG); it is used
  1214. ;  to extract the group number, check it, and position DUTIL to it
  1215. ;  On exit, GROUP = Group Number, GRPDIS = 0, and DUTIL is positioned
  1216. ;
  1217. COMG:
  1218.     INX    H    ;PT TO CHAR AFTER 'G' OF '<G' COMMAND
  1219.     MOV    A,M    ;GET CHAR AFTER 'G'
  1220.     CALL    UPCASE    ;CAPITALIZE
  1221.     CPI    ';'    ;ERROR IF LOGICAL EOL
  1222.     JZ    WHAT
  1223.     CPI    CR    ;ERROR IF PHYSICAL EOL
  1224.     JZ    WHAT
  1225.     CALL    HEXIN    ;GET GROUP NUMBER IN HEX
  1226.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  1227.     LHLD    DSM    ;CHECK FOR BOUNDS ERROR
  1228.     CALL    SUBDE    ;SUBTRACT GROUP NUMBER FROM DSM
  1229.     POP    H    ;RESTORE PTR
  1230.     JC    OUTLIM    ;LIMIT ERROR IF CARRY
  1231.     XCHG        ;SAVE GROUP NUMBER
  1232.     SHLD    GROUP
  1233.     SHLD    TGRP    ;TEMPORARY GROUP NUMBER
  1234.     XCHG        ;GROUP NUMBER IN DE
  1235.     XRA    A    ;A=0
  1236.     STA    GRPDIS    ;SET GROUP DISPLACEMENT
  1237.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  1238.     CALL    GTKSEC    ;CONVERT GROUP NUMBER TO TRACK AND SECTOR
  1239.     CALL    SETTRK    ;SET TRACK
  1240.     XCHG
  1241.     CALL    SETSEC    ;SET SECTOR
  1242.     POP    H    ;GET PTR TO NEXT CHAR
  1243.     RET
  1244. ;
  1245. ;This is the Save Group Routine; it copies the indicated group into the save
  1246. ;  buffer.
  1247. ;
  1248. SAVEG:
  1249.     CALL    COMG    ;EXTRACT COMMON GROUP INFO -- GROUP NUMBER AND POS
  1250.     PUSH    H
  1251.     CALL    ILPRT
  1252.     DB    'Reading from Group ',0
  1253.     LHLD    GROUP    ;GET CURRENT GROUP
  1254.     MOV    B,H    ;VALUE IN BC
  1255.     MOV    C,L
  1256.     CALL    HEXB    ;PRINT AS HEX
  1257.     CALL    ILPRT
  1258.     DB    CR,LF,0
  1259.     POP    H
  1260.     MVI    A,0FFH    ;SET GROUP LOADED FLAG
  1261.     STA    GLFLAG    ;GROUP HAS BEEN LOADED
  1262.     MVI    A,0    ;SET COPY FUNCTION TO SAVE
  1263.     STA    CPYFCT    ;0=READ, 0FFH=WRITE
  1264. ;
  1265. ;Group Copy Routine -- if CPYFCT = 0, Read Group; if CPYFCT = 0FFH, Write Group
  1266. ;
  1267. COPYG:
  1268.     PUSH    H    ;SAVE PTR TO NEXT CHAR IN COMMAND LINE
  1269.     CALL    NORITE    ;POSITIONING LOST
  1270.     LXI    D,GBUFF    ;PT TO BUFFER
  1271.     LDA    BLM    ;GET NUMBER OF BLOCKS/GROUP
  1272.     INR    A    ; ADD 1 TO BLM FOR CORRECT COUNT
  1273.     MOV    B,A    ;COUNT IN B
  1274. ;
  1275. COPYGL:
  1276.     PUSH    B    ;SAVE COUNT
  1277.     PUSH    D    ;SAVE PTR TO NEXT BLOCK TO LOAD
  1278.     LDA    BDOS+2    ;CHECK THAT MEMORY ISN'T FULL
  1279.     CMP    D    ;COMPARE TO LOAD ADDRESS
  1280.     JC    MEMFUL
  1281.     MOV    B,D    ;SET BC=DE FOR SET DMA
  1282.     MOV    C,E
  1283.     CALL    SETDMA    ;SET ADDRESS TO LOAD
  1284.     LDA    CPYFCT    ;READ OR WRITE?
  1285.     ORA    A    ;0=READ
  1286.     PUSH    PSW    ;SAVE FLAGS
  1287.     CZ    READ    ;READ BLOCK
  1288.     POP    PSW    ;GET FLAGS
  1289.     CNZ    PWRITE    ;WRITE BLOCK (NO CHECK)
  1290.     CALL    NXTSEC    ;COMPUTE NEXT SECTOR ADDRESS
  1291.     LHLD    CURTRK    ;GET NEXT TRACK ADDRESS
  1292.     XCHG        ;... IN DE
  1293.     CALL    SETTRK    ;SET IT
  1294.     LHLD    CURSEC    ;GET NEXT SECTOR ADDRESS
  1295.     XCHG        ;... IN DE
  1296.     CALL    SETSEC    ;SET IT
  1297.     POP    D    ;GET PTR TO NEXT BLOCK
  1298.     POP    B    ;GET COUNTER
  1299.     LXI    H,80H    ;OFFSET TO NEXT BLOCK
  1300.     DAD    D
  1301.     XCHG        ;DE PTS TO NEXT BLOCK
  1302.     DCR    B    ;COUNT DOWN
  1303.     JNZ    COPYGL    ;LOOP UNTIL FINISHED
  1304.     LXI    B,TBUFF    ;RESET DMA ADDRESS
  1305.     CALL    SETDMA
  1306.     XRA    A    ;A=0
  1307.     STA    WRFLG    ;SET NO READ DONE
  1308.     LHLD    TGRP    ;GET GROUP NUMBER
  1309.     XCHG        ;... IN DE
  1310.     POP    H    ;GET PTR TO NEXT CHAR
  1311.     JMP    POSGRP    ;POSITION TO GROUP IN DE AND CONTINUE PROCESSING
  1312. ;
  1313. ;COMMAND:  >
  1314. ;Restore the current sector
  1315. ;
  1316. RESTOR:
  1317.     LDA    SAVEFL    ;SAVE DONE PREVIOUSLY?
  1318.     ORA    A
  1319.     JZ    NOSAVE    ;NONE TO SAVE
  1320.     PUSH    H
  1321.     LXI    H,SAVBUF    ;COPY FROM SAVBUF
  1322.     LXI    D,TBUFF    ;INTO TBUFF
  1323.     MVI    B,128    ;128 BYTES
  1324.     CALL    MOVE
  1325.     POP    H    ;GET PTR TO NEXT CHAR
  1326.     JMP    PROMPT
  1327. ;
  1328. ;Write Group Loaded in GBUFF to Disk
  1329. ;
  1330. RESTRG:
  1331.     LDA    GLFLAG    ;GROUP ALREADY LOADED?
  1332.     ORA    A    ;0=NO
  1333.     JZ    RGERR
  1334.     CALL    COMG    ;GET GROUP NUMBER FROM COMMAND LINE AND POS
  1335.     PUSH    H
  1336.     CALL    ILPRT
  1337.     DB    'Writing to Group ',0
  1338.     LHLD    GROUP    ;GET GROUP NUMBER
  1339.     MOV    B,H    ;VALUE IN BC
  1340.     MOV    C,L
  1341.     CALL    HEXB    ;PRINT IN HEX
  1342.     CALL    ILPRT
  1343.     DB    CR,LF,0
  1344.     POP    H
  1345.     MVI    A,0FFH    ;WRITE FUNCTION
  1346.     STA    CPYFCT    ;COPY FUNCTION FOR GROUP COPY ROUTINE
  1347.     JMP    COPYG    ;GROUP COPY ROUTINE
  1348. ;
  1349. RGERR:
  1350.     XRA    A    ;NOT QUIET
  1351.     STA    QFLAG
  1352.     CALL    ILPRT
  1353.     DB    '++ No "RG" Read Group Command Issued or Loaded Group'
  1354.     DB    ' Trashed ++'
  1355.     DB    CR,LF,0
  1356.     JMP    PRMPTR
  1357. ;
  1358. NOSAVE:
  1359.     XRA    A    ;NOT QUIET
  1360.     STA    QFLAG
  1361.     CALL    ILPRT
  1362.     DB    '++ No "<" Save Command Issued ++'
  1363.     DB    CR,LF,0
  1364.     JMP    PRMPTR
  1365. ;
  1366. ;Move (HL) to (DE) length in B
  1367. ;
  1368. MOVE:
  1369.     MOV    A,M
  1370.     STAX    D
  1371.     INX    H
  1372.     INX    D
  1373.     DCR    B
  1374.     JNZ    MOVE
  1375.     RET
  1376. ;
  1377. NORITE:
  1378.     XRA    A    ;GET 0
  1379.     STA    WRFLG    ;CAN'T WRITE NOW
  1380.     RET
  1381. ;
  1382. ;No match in search, try next char
  1383. ;
  1384. SRNOMT:
  1385.     POP    H
  1386.     CALL    CTLCS    ;ABORT?
  1387.     JNZ    SEARCH    ;..YES
  1388.     LXI    H,INBUF
  1389.     MVI    M,CR
  1390.     JMP    CLCGRP    ;SHOW WHERE STOPPED
  1391. ;
  1392. ;COMMAND:  =
  1393. ;Search for character string
  1394. ;
  1395. SEARCH:
  1396.  PUSH    H    ;SAVE STRING POINTER
  1397. ;
  1398. SRCHL:
  1399.     CALL    RDBYTE    ;GET A BYTE
  1400.     MOV    B,A    ;SAVE IT
  1401.     MOV    A,M    ;CHECK NEXT MATCH CHAR.
  1402.     CPI    '<'    ;WILL IT BE HEX?
  1403.     MOV    A,B    ;RESTORE DISK CHAR
  1404.     JZ    SRCHL1
  1405.     ANI    7FH    ;NEXT CHAR IS ASCII...STRIP BIT 7
  1406. ;
  1407. SRCHL1:
  1408.     PUSH    PSW
  1409.     CALL    GETVAL    ;GET SEARCH VALUE
  1410.     MOV    B,A
  1411.     POP    PSW
  1412.     CMP    B    ;MATCH?
  1413.     JNZ    SRNOMT    ;NO MATCH
  1414.     INX    H
  1415.     MOV    A,M    ;DONE?
  1416.     CPI    CR    ;END OF LINE?
  1417.     JZ    SREQU
  1418.     CPI    ';'    ;LOGICAL EOL?
  1419.     JNZ    SRCHL
  1420. ;
  1421. ;Got match
  1422. ;
  1423. SREQU:
  1424.     XRA    A    ;NOT QUIET
  1425.     STA    QFLAG
  1426.     CALL    ILPRT
  1427.     DB    '= at ',0
  1428.     LDA    BUFAD
  1429.     ANI    7FH
  1430.     CALL    HEX
  1431.     CALL    CRLF
  1432.     JMP    CLCGRP
  1433. ;
  1434. ;Get value from input buffer
  1435. ;
  1436. GETVAL:
  1437.     MOV    A,M    ;GET NEXT CHAR
  1438.     CPI    '<'    ;HEX ESCAPE?
  1439.     RNZ        ;NO, RETURN
  1440. ;"<<" means one "<"
  1441.     INX    H
  1442.     MOV    A,M
  1443.     CPI    '<'
  1444.     RZ
  1445. ;Got hex
  1446.     PUSH    D
  1447.     CALL    HEXIN    ;GET VALUE
  1448.     CPI    '>'    ;PROPER DELIM?
  1449.     MOV    A,E    ;GET VALUE
  1450.     POP    D
  1451.     JNZ    WHAT    ;ERROR
  1452.     RET
  1453. ;
  1454. ;Read a byte at a time from disk
  1455. ;
  1456. RDBYTE:
  1457.     PUSH    H
  1458.     LDA    FTSW    ;FIRST READ?
  1459.     ORA    A
  1460.     JNZ    READ1
  1461.     LHLD    BUFAD
  1462.     MOV    A,L
  1463.     ORA    A    ;IN BUFFER?
  1464.     JM    NORD    ;YES, SKIP READ
  1465. ;
  1466. ;Have to read
  1467. ;
  1468.     CALL    NXTSEC    ;ADVANCE TO NEXT BLOCK
  1469. ;
  1470. READ1:
  1471.     XRA    A
  1472.     STA    FTSW    ;NOT FIRST READ
  1473.     LHLD    CURSEC
  1474.     XCHG
  1475.     CALL    SETSEC
  1476.     LHLD    CURTRK
  1477.     XCHG
  1478.     CALL    SETTRK
  1479.     CALL    READ
  1480.     CALL    CLCSUB
  1481.     LXI    H,TBUFF
  1482. ;
  1483. NORD:
  1484.     MOV    A,M
  1485.     INX    H
  1486.     SHLD    BUFAD
  1487.     POP    H
  1488.     RET
  1489. ;
  1490. ;COMMAND:  V
  1491. ;View the file in ASCII starting at
  1492. ;current sector, stepping thru the disk
  1493. ;
  1494. VIEW:
  1495.     LDA    WRFLG
  1496.     ORA    A
  1497.     JZ    BADDMP
  1498.     CALL    DECIN    ;GET DISPL IF ANY
  1499.     PUSH    H
  1500.     MOV    A,E
  1501.     ORA    A
  1502.     JNZ    VIEWLP
  1503.     INR    E    ;DFLT=1
  1504. ;
  1505. VIEWLP:
  1506.     LXI    H,TBUFF    ;TO DATA
  1507. ;
  1508. VEWCHR:
  1509.     CALL    CTLCS    ;ABORT?
  1510.     JZ    VEWEND
  1511.     MOV    A,M    ;GET NEXT CHAR
  1512.     CPI    1AH    ;EOF?
  1513.     JZ    VEWEOF
  1514.     ANI    7FH    ;MASK
  1515.     CPI    7EH    ;ESC CHAR FOR H1500
  1516.     JNC    VIEWHX    ;SHOW RUBOUT AND TILDE AS HEX
  1517.     CPI    ' '
  1518.     JNC    VIEWPR
  1519.     CPI    CR    ;CR PASS
  1520.     JZ    VIEWPR
  1521.     CPI    LF    ;LF PASS
  1522.     JZ    VIEWPR
  1523.     CPI    TAB    ;TAB PASS
  1524.     JZ    VIEWPR
  1525. ;
  1526. VIEWHX:
  1527.     MOV    A,M    ;NOT ASCII...PRINT AS <NN>
  1528.     CALL    BHEX
  1529.     JMP    VIEWNP
  1530. ;
  1531. VIEWPR:
  1532.     CALL    TYPE
  1533. ;
  1534. VIEWNP:
  1535.     INR    L
  1536.     JNZ    VEWCHR
  1537.     DCR    E
  1538.     JZ    VEWEND
  1539.     PUSH    D    ;SAVE COUNT
  1540.     CALL    NXTSEC
  1541.     LHLD    CURSEC
  1542.     XCHG
  1543.     CALL    SETSEC    
  1544.     LHLD    CURTRK
  1545.     XCHG
  1546.     CALL    SETTRK
  1547.     CALL    READ
  1548.     POP    D    ;RESTORE COUNT
  1549.     JMP    VIEWLP
  1550. ;
  1551. VEWEOF:
  1552.     CALL    ILPRT
  1553.     DB    CR,LF,'    ++ EOF ++',CR,LF,0
  1554. ;
  1555. VEWEND:
  1556.     POP    H
  1557.     CALL    CRLF
  1558.     JMP    CLCGRP
  1559. ;
  1560. ;COMMAND:  A or D
  1561. ;Dump in hex or ASCII
  1562. ;
  1563. DUMP:
  1564.     LDA    WRFLG
  1565.     ORA    A
  1566.     JNZ    DUMPOK
  1567. ;
  1568. BADDMP:
  1569.     XRA    A
  1570.     STA    QFLAG    ;NOT QUIET
  1571.     CALL    ILPRT
  1572.     DB    '++ Can''t dump, no sector read ++',CR,LF,0
  1573. ;
  1574. EXPL:
  1575.     XRA    A
  1576.     STA    QFLAG    ;NOT QUIET
  1577.     CALL    ILPRT
  1578.     DB    'Use G command following F,',CR,LF
  1579.     DB    'or R or S following T',CR,LF,0
  1580.     JMP    PRMPTR
  1581. ;
  1582. DUMPOK:
  1583.     MOV    A,M    ;GET NEXT CHAR
  1584.     CPI    ';'    ;LOGICAL EOL?
  1585.     JZ    DUMPDF    ;DFLT
  1586.     CPI    CR    ;PHYSICAL EOL?
  1587.     JNZ    DMPNDF
  1588. ;
  1589. ;Use default
  1590. ;
  1591. DUMPDF:
  1592.     LXI    B,TBUFF
  1593.     LXI    D,0FFH
  1594.     JMP    DUMP1
  1595. ;
  1596. DMPNDF:
  1597.     CALL    DISP
  1598.     MOV    B,D
  1599.     MOV    C,E
  1600.     CPI    CR
  1601.     JZ    DUMP1
  1602.     CPI    ';'
  1603.     JZ    DUMP1
  1604.     INX    H    ;SKIP ','
  1605.     CALL    DISP
  1606. ;
  1607. ;BC = start, DE = end
  1608. ;
  1609. DUMP1:
  1610.     PUSH    H    ;SAVE COMMAND POINTER
  1611.     MOV    H,B
  1612.     MOV    L,C
  1613. ;
  1614. DUMPLP:
  1615.     MOV    A,L
  1616.     ANI    7FH
  1617.     CALL    HEX    ;PRINT HEX VALUE
  1618.     CALL    SPACE
  1619.     CALL    SPACE
  1620.     LDA    DUMTYP
  1621.     CPI    'A'
  1622.     JZ    DUMPAS
  1623.     PUSH    H    ;SAVE START
  1624. ;
  1625. DHEX:
  1626.     MOV    A,M
  1627.     CALL    HEX    ;PRINT HEX VALUE PTED TO BY HL
  1628.     MOV    A,L
  1629.     ANI    3
  1630.     CPI    3    ;EXTRA SPACE EVERY 4
  1631.     CZ    SPACE
  1632.     MOV    A,L
  1633.     ANI    7
  1634.     CPI    7    ;TWO EXTRA SPACES EVERY 8
  1635.     CZ    SPACE
  1636.     MOV    A,E
  1637.     CMP    L
  1638.     JZ    DPOP
  1639.     INX    H
  1640.     MOV    A,L
  1641.     ANI    0FH
  1642.     JNZ    DHEX
  1643. ;
  1644. DPOP:
  1645.     CALL    CTLCS    ;ABORT?
  1646.     JZ    PRMPTR
  1647.     LDA    DUMTYP
  1648.     CPI    'H'
  1649.     JZ    DNOAS    ;HEX ONLY
  1650.     POP    H    ;GET START ADDR
  1651. ;
  1652. DUMPAS:
  1653.     CALL    ASTER    ;PRINT FIRST ASTERISK TO SEPARATE TEXT
  1654. ;
  1655. DCHR:
  1656.     MOV    A,M    ;GET CHAR
  1657.     ANI    7FH
  1658.     CPI    ' '
  1659.     JC    DPER
  1660.     CPI    7EH    ;TRAP ESC FOR H1500
  1661.     JC    DOK
  1662. ;
  1663. DPER:
  1664.     MVI    A,'.'    ;PRINT PRINTING CHAR
  1665. ;
  1666. DOK:
  1667.     CALL    TYPE    ;PRINT CHAR
  1668.     MOV    A,E
  1669.     CMP    L
  1670.     JZ    DEND
  1671.     INX    H
  1672.     MOV    A,L
  1673.     ANI    0FH
  1674.     JNZ    DCHR
  1675. ;
  1676. DEND:
  1677.     CALL    ASTER    ;PRINT ENDING ASTERISK
  1678.     CALL    CRLF    ;NEW LINE
  1679.     PUSH    D
  1680.     CALL    CTLCS    ;ABORT?
  1681.     POP    D
  1682.     JZ    PRMPTR
  1683.     MOV    A,E
  1684.     CMP    L
  1685.     JNZ    DUMPLP
  1686.     POP    H
  1687.     JMP    PROMPT
  1688. ;
  1689. DNOAS:
  1690.     POP    B
  1691.     CALL    CRLF
  1692.     MOV    A,E
  1693.     CMP    L
  1694.     JNZ    DUMPLP
  1695.     POP    H
  1696.     JMP    PROMPT
  1697. ;
  1698. ;COMMAND:  G
  1699. ;Position
  1700. ;
  1701. POS:
  1702.     PUSH    PSW
  1703.     MOV    A,M
  1704.     CPI    ';'    ;LOGICAL EOL?
  1705.     JZ    POSINQ
  1706.     CPI    CR    ;PHYSICAL EOL?
  1707.     JNZ    POSOK
  1708. ;
  1709. POSINQ:
  1710.     POP    PSW
  1711.     JMP    INQ
  1712. ;
  1713. POSOK:
  1714.     POP    PSW
  1715.     CPI    'T'    ;TRACK?
  1716.     JZ    POSTKD
  1717.     CPI    'S'    ;SECTOR?
  1718.     JZ    POSSCD
  1719.     CPI    'G'    ;GROUP?
  1720.     JZ    POSGPH
  1721.     JMP    WHAT    ;ERROR OTHERWISE
  1722. ;
  1723. ;Position to Track
  1724. ;
  1725. POSTKD:
  1726.     CALL    DECIN    ;GET NUMBER IN DECIMAL
  1727. ;
  1728. POSTRK:
  1729.     PUSH    H
  1730.     LHLD    MAXTRK    ;CHECK FOR BEYOND END OF DISK
  1731.     CALL    SUBDE
  1732.     POP    H
  1733.     JC    OUTLIM
  1734.     CALL    SETTRK    ;SET TRACK
  1735.     CALL    NORITE    ;TRACK DOESN'T READ
  1736.     MVI    A,1
  1737.     STA    NOTPOS    ;SHOW NOT POSITIONED
  1738.     JMP    CLCGRP
  1739. ;
  1740. ;Position to Sector
  1741. ;
  1742. POSSCD:
  1743.     CALL    DECIN    ;GET NUMBER IN DECIMAL
  1744.     MOV    A,D
  1745.     ORA    E
  1746.     JZ    WHAT    ;DON'T ALLOW SECTOR 0
  1747. ;
  1748. POSSEC:
  1749.     PUSH    H
  1750.     LHLD    SPT    ;CHECK FOR WITHIN RANGE
  1751.     CALL    SUBDE
  1752.     POP    H
  1753.     JC    WHAT
  1754.     CALL    SETSEC    ;SET SECTOR
  1755.     CALL    READ    ;READ
  1756.     XRA    A
  1757.     STA    NOTPOS    ;POSITIONED OK
  1758. ;
  1759. ;Calculate Group Number/Group Displacement and Print
  1760. ;
  1761. CLCGRP:
  1762.     CALL    CLCSUB
  1763.     JMP    INQ
  1764. ;
  1765. ;Calculate group from track and sector
  1766. ;  On exit, GROUP = Group Number and GRPDIS = Displacement within Group
  1767. ;
  1768. CLCSUB:
  1769.     PUSH    H
  1770.     LHLD    SYSTRK
  1771.     XCHG
  1772.     LHLD    CURTRK
  1773.     CALL    SUBDE    ;COMPUTE RELATIVE TRACK NUMBER (SKIP SYSTEM TRACKS)
  1774.     XCHG
  1775.     LHLD    SPT    ;MULTIPLY BY NUMBER OF SECTORS/TRACK
  1776.     CALL    MULT
  1777.     XCHG        ;DE=TOTAL NUMBER OF SECTORS IN TRACKS
  1778.     LHLD    CURSEC    ;GET SECTOR OFFSET FROM BEGINNING OF TRACK
  1779.     DCX    H
  1780.     DAD    D    ;HL=TOTAL NUMBER OF SECTORS WITH OFFSET
  1781.     LDA    BLM
  1782.     MOV    B,A
  1783.     MOV    A,L
  1784.     ANA    B
  1785.     STA    GRPDIS    ;DISPLACEMENT WITHIN GROUP
  1786.     LDA    BSH
  1787.     MOV    B,A
  1788. ;
  1789. CLCLOP:
  1790.     CALL    ROTRHL
  1791.     DCR    B
  1792.     JNZ    CLCLOP
  1793.     SHLD    GROUP    ;GROUP NUMBER
  1794.     POP    H
  1795.     RET
  1796. ;
  1797. ;Position in the directory after a find
  1798. ;(Does not work in CP/M-2.x)
  1799. ;
  1800. POSDIR:
  1801.     PUSH    H    ;SAVE INBUF
  1802.     LHLD    BSH
  1803.     XRA    A
  1804.     STA    FINDFL    ;CANCEL POS REQ
  1805.     LDA    DIRPOS    ;GET POSITION
  1806.     RAR
  1807.     RAR
  1808.     PUSH    PSW
  1809.     ANA    H
  1810.     STA    GRPDIS
  1811.     POP    PSW
  1812. ;
  1813. POSDLP:
  1814.     RAR
  1815.     DCR    L
  1816.     JNZ    POSDLP
  1817.     ANI    1    ;GET GROUP
  1818.     MOV    L,A    ;SETUP FOR POSGP2
  1819.     MVI    H,0
  1820.     SHLD    GROUP
  1821.     XCHG
  1822.     JMP    POSGP2    ;POSITION TO IT
  1823. ;
  1824. ;Position to Group
  1825. ;
  1826. POSGPH:
  1827.     CALL    HEXIN    ;GET PARAMETER
  1828. ;
  1829. ;Position to Group Numbered in DE and Print Position
  1830. ;
  1831. POSGRP:
  1832.     PUSH    H
  1833.     LHLD    DSM    ;CHECK FOR WITHIN BOUNDS
  1834.     CALL    SUBDE
  1835.     POP    H
  1836.     JC    OUTLIM
  1837.     XCHG
  1838.     SHLD    GROUP    ;SET GROUP NUMBER
  1839.     XCHG
  1840.     XRA    A
  1841.     STA    GRPDIS    ;SET ZERO DISPLACEMENT
  1842.     PUSH    H
  1843. ;
  1844. POSGP2:
  1845.     CALL    GTKSEC    ;CONVERT GROUP TO SECTOR/TRACK
  1846.     CALL    SETTRK    ;SET TRACK
  1847.     XCHG
  1848.     CALL    SETSEC    ;SET SECTOR
  1849.     CALL    READ    ;READ BLOCK
  1850.     XRA    A
  1851.     STA    NOTPOS    ;NOW POSITIONED
  1852.     POP    H
  1853.     JMP    INQ
  1854. ;
  1855. ;Convert Group Number in DE to Sector and Track; also, GRPDIS = Offset in Grp
  1856. ;  On exit, DE = Track Number, HL = Sector Number
  1857. ;
  1858. GTKSEC:
  1859.     MOV    H,D    ;HL=GROUP NUMBER
  1860.     MOV    L,E
  1861.     LDA    BSH    ;GET NUMBER OF SECTORS IN GROUP
  1862. ;
  1863. GLOOP:
  1864.     DAD    H
  1865.     DCR    A
  1866.     JNZ    GLOOP
  1867.     LDA    GRPDIS    ;ADD IN DISPLACEMENT WITHIN GROUP
  1868.     ADD    L    ;CAN'T CARRY
  1869.     MOV    L,A
  1870. ;
  1871. ;Divide by number of sectors, quotient=track, remainder=sector
  1872. ;
  1873.     XCHG        ;DE=TOTAL NUMBER OF SECTORS
  1874.     LHLD    SPT    ;GET NUMBER OF SECTORS/TRACK
  1875.     CALL    NEG    ;HL = -SECTORS/TRACK
  1876.     XCHG
  1877.     LXI    B,0    ;SET TRACK COUNTER TO ZERO
  1878. ;
  1879. DIVLP:
  1880.     INX    B    ;INCREMENT TRACK COUNT
  1881.     DAD    D    ;SUBTRACT SECTORS/TRACK FROM SECTORS TOTAL
  1882.     JC    DIVLP
  1883.     DCX    B    ;ADJUST TRACK COUNT
  1884.     XCHG
  1885.     LHLD    SPT    ;ADD SECTORS/TRACK BACK IN TO ADJUST
  1886.     DAD    D    ;HL=NUMBER OF SECTORS ON LAST TRACK OF GROUP
  1887.     PUSH    H
  1888.     LHLD    SYSTRK    ;ADD IN NUMBER OF SYSTEM TRACKS
  1889.     DAD    B
  1890.     XCHG        ;DE=TRACK NUMBER
  1891.     POP    H
  1892.     INX    H    ;HL=SECTOR NUMBER
  1893.     RET
  1894. ;
  1895. ;COMMAND:  F
  1896. ;Find Directory Entry for specified file
  1897. ;
  1898. POSFIL:
  1899.     CALL    NORITE
  1900.     MVI    A,1
  1901.     STA    FINDFL    ;SO WE POSITION LATER
  1902.     LXI    D,FCB
  1903.     XRA    A    ;LOGGED IN DISK
  1904.     STAX    D
  1905.     INX    D
  1906.     MVI    B,8
  1907.     CALL    MVNAME
  1908.     MVI    B,3
  1909.     CALL    MVNAME
  1910.     LXI    D,FCB
  1911.     MVI    C,SRCHF
  1912.     PUSH    H
  1913.     CALL    BDOS
  1914.     INR    A
  1915.     JNZ    FLOK
  1916.     STA    DIRPOS    ;GRP 0 IF NOT FOUND
  1917.     CALL    ILPRT
  1918.     DB    '++ File Not Found ++',CR,LF,0
  1919.     POP    H
  1920.     JMP    PROMPT
  1921. ;
  1922. FLOK:
  1923.     DCR    A
  1924.     STA    DIRPOS    ;SAVE POS. IN DIR
  1925.     ANI    3
  1926.     MOV    L,A
  1927.     MVI    H,0
  1928.     DAD    H    ;X32 BYTES/ENTRY
  1929.     DAD    H
  1930.     DAD    H
  1931.     DAD    H
  1932.     DAD    H
  1933.     LXI    D,TBUFF
  1934.     DAD    D    ;HL POINTS TO ENTRY
  1935.     LXI    D,32
  1936.     XCHG
  1937.     DAD    D
  1938.     XCHG
  1939.     MVI    A,'D'
  1940.     STA    DUMTYP
  1941.     JMP    DUMPLP    ;WHICH POPS H
  1942. ;
  1943. MVNAME:
  1944.     MOV    A,M    ;GET NEXT CHAR OF FILE NAME/TYPE
  1945.     CPI    '.'    ;END OF FILE NAME?
  1946.     JZ    MVIPAD    ;PAD OUT IF SO
  1947.     CPI    CR    ;END OF ENTRY?
  1948.     JZ    PAD    ;PAD OUT IF SO
  1949.     CPI    ';'    ;END OF ENTRY?
  1950.     JZ    PAD    ;PAD OUT IF SO
  1951.     CALL    UPCASE    ;CAPITALIZE
  1952.     STAX    D    ;STORE
  1953.     INX    H    ;PT TO NEXT
  1954.     INX    D
  1955.     DCR    B    ;COUNT DOWN
  1956.     JNZ    MVNAME
  1957.     MOV    A,M    ;CHECK FOR ERROR
  1958.     CPI    CR    ;OK IF EOL
  1959.     RZ
  1960.     CPI    ';'    ;OK IF LOGICAL EOL
  1961.     RZ
  1962.     INX    H
  1963.     CPI    '.'    ;OK IF DECIMAL
  1964.     RZ
  1965.     JMP    WHAT
  1966. ;
  1967. MVIPAD:
  1968.     INX    H
  1969. ;
  1970. PAD:
  1971.     MVI    A,' '    ;PRINT PADDING SPACES
  1972.     STAX    D
  1973.     INX    D
  1974.     DCR    B
  1975.     JNZ    PAD
  1976.     RET
  1977. ;
  1978. ;COMMAND:  +
  1979. ;Advance to Next Logical Sector
  1980. ;
  1981. PLUS:
  1982.     LXI    D,1    ;DFLT TO 1 SECT
  1983.     MOV    A,M    ;GET NEXT CHAR
  1984.     CPI    CR    ;CR?
  1985.     JZ    PLUSGO    ;..YES, DFLT TO 1
  1986.     CPI    ';'
  1987.     JZ    PLUSGO
  1988.     CALL    DECIN    ;GET #
  1989.     MOV    A,D
  1990.     ORA    E
  1991.     JZ    WHAT
  1992. ;
  1993. PLUSGO:
  1994.     CALL    NXTSEC    ;ADVANCE TO NEXT LOGICAL SECTOR
  1995.     DCX    D    ;MORE TO GO?
  1996.     MOV    A,D
  1997.     ORA    E
  1998.     JNZ    PLUSGO    ;..YES
  1999. ;
  2000. ;Ok, incremented to sector.  Setup and read
  2001. ;
  2002. PLUSMI:
  2003.     PUSH    H
  2004.     LHLD    CURSEC
  2005.     XCHG
  2006.     CALL    SETSEC    ;SET SECTOR
  2007.     LHLD    CURTRK
  2008.     XCHG
  2009.     CALL    SETTRK    ;SET TRACK
  2010.     POP    H
  2011.     CALL    READ    ;READ IT
  2012.     JMP    CLCGRP    ;CALCULATE GROUP AND DISPLAY
  2013. ;
  2014. ;COMMAND:  -
  2015. ;Back up to previous sector
  2016. ;
  2017. MINUS:
  2018.     LXI    D,1    ;SET DFLT
  2019.     MOV    A,M    ;GET CHAR
  2020.     CPI    CR    ;CR?
  2021.     JZ    MINGO    ;..YES, DFLT=1
  2022.     CPI    ';'
  2023.     JZ    MINGO
  2024.     CALL    DECIN    ;..NO, GET ##
  2025.     MOV    A,D
  2026.     ORA    E
  2027.     JZ    WHAT
  2028. ;
  2029. MINGO:
  2030.     PUSH    H
  2031.     LHLD    CURSEC    ;BACK UP SECTOR
  2032.     DCX    H
  2033.     MOV    A,H
  2034.     ORA    L
  2035.     JNZ    MINOK
  2036.     LHLD    CURTRK    ;BEYOND SECTOR ZERO, SO BACK UP TRACK
  2037.     MOV    A,H
  2038.     ORA    L
  2039.     JNZ    SEASH
  2040.     LHLD    MAXTRK    ;WRAP TO END OF DISK
  2041.     SHLD    CURTRK
  2042.     LHLD    MAXSEC
  2043.     JMP    MINOK
  2044. ;
  2045. SEASH:
  2046.     DCX    H
  2047.     SHLD    CURTRK
  2048.     LHLD    SPT    ;GET NUMBER OF SECTORS/TRACK
  2049. ;
  2050. MINOK:
  2051.     SHLD    CURSEC    ;SET NEW CURRENT SECTOR
  2052.     POP    H
  2053.     DCX    D    ;COUNT DOWN ON NUMBER OF TIMES TO BACKUP
  2054.     MOV    A,D
  2055.     ORA    E
  2056.     JNZ    MINGO
  2057.     JMP    PLUSMI    ;READ BLOCK
  2058. ;
  2059. ;Go to next sector
  2060. ;  On exit, CURSEC = Current Sector and CURTRK = Current Track
  2061. ;
  2062. NXTSEC:
  2063.     PUSH    H
  2064.     PUSH    D
  2065.     LHLD    CURSEC    ;INCREMENT CURRENT SECTOR
  2066.     INX    H
  2067.     XCHG
  2068.     LHLD    SPT    ;CHECK TO SEE IF BEYOND END OF TRACK
  2069.     CALL    SUBDE
  2070.     XCHG
  2071.     JNC    NEXTOK
  2072.     LHLD    CURTRK    ;BEYOND END OF TRACK, SO INCR CURRENT TRACK
  2073.     INX    H
  2074.     XCHG
  2075.     LHLD    MAXTRK    ;SEE IF BEYOND END OF DISK
  2076.     CALL    SUBDE
  2077.     JNC    TRASK
  2078.     LXI    D,0    ;WRAP TO START OF DISK
  2079. ;
  2080. TRASK:
  2081.     XCHG
  2082.     SHLD    CURTRK    ;SET NEW CURRENT TRACK
  2083.     LXI    H,1    ;SET SECTOR 1
  2084. ;
  2085. NEXTOK:
  2086.     SHLD    CURSEC    ;SET NEW CURRENT SECTOR
  2087.     POP    D
  2088.     POP    H
  2089.     RET
  2090. ;
  2091. ;Tell what group, displacement, track, sector, physical sector
  2092. ;
  2093. INQ:
  2094.     CALL    INQSUB
  2095.     JMP    PROMPT
  2096. ;
  2097. ;Position inquiry subroutine
  2098. ;Executed via: G S or T (with no operands)
  2099. ;
  2100. INQSUB:
  2101.     PUSH    H
  2102.     LHLD    SYSTRK    ;CHECK IF IN SYSTEM TRACKS
  2103.     XCHG
  2104.     LHLD    CURTRK
  2105.     CALL    SUBDE
  2106.     JC    NOGRP
  2107.     CALL    ILPRT    ;PRINT GROUP NUMBER IF NOT IN SYSTEM TRACKS
  2108.     DB    'Group = ',0
  2109.     LHLD    GROUP
  2110.     MOV    B,H
  2111.     MOV    C,L
  2112.     CALL    HEXB    ;PRINT GROUP NUMBER IN BC
  2113.     MVI    A,':'
  2114.     CALL    TYPE
  2115.     LDA    GRPDIS
  2116.     CALL    HEX    ;PRINT GROUP DISPLACEMENT IN A
  2117.     MVI    A,','
  2118.     CALL    TYPE
  2119. ;
  2120. NOGRP:
  2121.     CALL    ILPRT    ;PRINT TRACK NUMBER
  2122.     DB    ' Track = ',0
  2123.     LHLD    CURTRK
  2124.     CALL    DEC    ;TRACK NUMBER IN DECIMAL
  2125.     CALL    ILPRT    ;PRINT SECTOR NUMBER
  2126.     DB    ', Sector = ',0
  2127.     LHLD    CURSEC
  2128.     CALL    DEC    ;SECTOR NUMBER IN DECIMAL
  2129.     CALL    ILPRT    ;PRINT PHYSCIAL SECTOR NUMBER
  2130.     DB    ', Physical Sector = ',0
  2131.     LHLD    PHYSEC
  2132.     CALL    DEC    ;PHYSICAL SECTOR NUMBER IN DECIMAL
  2133.     CALL    CRLF
  2134.     POP    H
  2135.     RET
  2136. ;
  2137. ;COMMAND:  C
  2138. ;Change Contents of Current Block
  2139. ;
  2140. CHG:
  2141.     MOV    A,M    ;GET TYPE (HEX, ASCII)
  2142.     CALL    UPCASE
  2143.     PUSH    PSW    ;SAVE "H" OR "A"
  2144.     INX    H
  2145.     CALL    HEXIN    ;GET DISP IN HEX
  2146.     CALL    DISP1    ;VALIDATE DISP TO DE
  2147.     INX    H
  2148.     LXI    B,0    ;SHOW NO 'THRU' ADDR
  2149.     CPI    '-'    ;TEST DELIM FR. DISP
  2150.     JNZ    CHGNTH    ;NO THRU
  2151.     PUSH    D    ;SAVE FROM
  2152.     CALL    HEXIN
  2153.     CALL    DISP1    ;GET THRU
  2154.     INX    H    ;SKIP END DELIM
  2155.     MOV    B,D
  2156.     MOV    C,E    ;BC = THRU
  2157.     POP    D    ;GET FROM
  2158.     JMP    CHGAH
  2159. ;
  2160. CHGNTH:
  2161.     CPI    ','
  2162.     JNZ    WHAT
  2163. ;
  2164. CHGAH:
  2165.     POP    PSW
  2166.     CPI    'H'    ;HEX?
  2167.     JZ    CHGHEX
  2168.     CPI    'A'    ;ASCII?
  2169.     JNZ    WHAT
  2170. ;
  2171. ;Change ASCII
  2172. ;
  2173. CHGALP:
  2174.     MOV    A,M    ;GET CHAR
  2175.     CPI    CR
  2176.     JZ    PROMPT
  2177.     CPI    ';'
  2178.     JZ    PROMPT
  2179. ;
  2180. ;The following print of the deleted byte is commented out; if leading
  2181. ;  semicolons are removed, deleted bytes will be printed
  2182. ;
  2183. ;    LDAX    D    ;GET BYTE THAT IS REPLACED
  2184. ;    CPI    ' '
  2185. ;    JC    CHGAHX
  2186. ;    CPI    7EH    ;DON'T PRINT ESC CHAR FOR H1500
  2187. ;    JNC    CHGAHX
  2188. ;    JMP    CHGA2
  2189. ;
  2190. ;CHGAHX:
  2191. ;    CALL    BHEX
  2192. ;    JMP    CHGA3
  2193. ;
  2194. ;CHGA2:
  2195. ;    CALL    TYPE
  2196. ;
  2197. ;End of print of delete bytes
  2198. ;
  2199. CHGA3:
  2200.     SHLD    BACK    ;IN CASE "THRU"
  2201.     CALL    GETVAL    ;GET ASCII OR <HEX> VALUE
  2202.     STAX    D    ;UPDATE BYTE
  2203.     INX    H    ;PT TO NEXT INPUT CHAR
  2204. ;
  2205. ;See if 'THRU' requested
  2206. ;
  2207.     MOV    A,C
  2208.     ORA    A
  2209.     JZ    CHANTH
  2210.     CMP    E    ;DONE?..
  2211.     JZ    PROMPT    ;..YES
  2212.     LHLD    BACK
  2213. ;
  2214. CHANTH:
  2215.     INR    E
  2216.     JNZ    CHGALP
  2217.     MOV    A,M
  2218.     CPI    CR
  2219.     JZ    PROMPT
  2220.     CPI    ';'
  2221.     JZ    PROMPT
  2222.     JMP    WHAT
  2223. ;
  2224. ;Change hex
  2225. ;
  2226. CHGHCM:
  2227.     INX    H
  2228. ;
  2229. CHGHEX:
  2230.     MOV    A,M    ;GET HEX DIGIT
  2231.     CPI    CR
  2232.     JZ    PROMPT
  2233.     CPI    ';'
  2234.     JZ    PROMPT
  2235.     CPI    ','    ;DELIM?
  2236.     JZ    CHGHCM
  2237.     PUSH    D
  2238.     SHLD    HEXAD    ;IN CASE 'THRU'
  2239.     CALL    HEXIN    ;POSITIONS TO DELIM
  2240.     MOV    A,E    ;GET VALUE
  2241.     POP    D    ;..ADDR
  2242. ;
  2243. ;The following comments out the echo of the deleted byte; removing the
  2244. ;  leading semicolons restores the echo
  2245. ;
  2246. ;    PUSH    PSW    ;SAVE VALUE
  2247. ;    LDAX    D    ;GET OLD
  2248. ;    CALL    HEX    ;ECHO IN HEX
  2249. ;    POP    PSW    ;GET NEW
  2250. ;
  2251. ;End of echo of bytes
  2252. ;
  2253.     STAX    D    ;SAVE NEW BYTE
  2254.     MOV    A,C    ;SEE IF 'THRU'
  2255.     ORA    A
  2256.     JZ    CHHNTH    ;..NO.
  2257.     CMP    E    ;..YES, DONE?
  2258.     JZ    PROMPT
  2259.     LHLD    HEXAD    ;..NO: MORE
  2260. ;
  2261. CHHNTH:
  2262.     INR    E
  2263.     JNZ    CHGHEX
  2264.     MOV    A,M
  2265.     CPI    CR
  2266.     JZ    PROMPT
  2267.     CPI    ';'
  2268.     JZ    PROMPT
  2269.     JMP    WHAT
  2270. ;
  2271. ;COMMAND:  R
  2272. ;Read Current Block into TBUFF
  2273. ;COMMAND:  RG
  2274. ;Read Specified Group into GBUFF
  2275. ;
  2276. DOREAD:
  2277.     MOV    A,M    ;GET CHAR AFTER R
  2278.     CALL    UPCASE    ;CAPITALIZE
  2279.     CPI    'G'    ;READ GROUP?
  2280.     JZ    SAVEG    ;SAVE GROUP IF SO
  2281.     LDA    NOTPOS    ;POSITIONED?
  2282.     ORA    A
  2283.     JNZ    CANTRD
  2284.     CALL    READ    ;READ BLOCK
  2285.     JMP    PROMPT
  2286. ;
  2287. CANTRD:
  2288.     XRA    A
  2289.     STA    QFLAG    ;NOT QUIET
  2290.     CALL    ILPRT
  2291.     DB    '++ Can''t read - not positioned ++',CR,LF
  2292.     DB    'Position by:',CR,LF
  2293.     DB    '    Track then Sector, or',CR,LF
  2294.     DB    '    Group',CR,LF,0
  2295.     JMP    PROMPT
  2296. ;
  2297. ;COMMAND:  W
  2298. ;Write Current Block to Disk
  2299. ;COMMAND:  WG
  2300. ;Write Specified Group from GBUFF
  2301. ;
  2302. DORITE:
  2303.     MOV    A,M    ;GET NEXT CHAR
  2304.     CALL    UPCASE    ;CAPITALIZE
  2305.     CPI    'G'    ;GROUP?
  2306.     JZ    RESTRG    ;DO GROUP WRITE
  2307.     CALL    WRITE    ;DO WRITE
  2308.     JMP    PROMPT
  2309. ;
  2310. ;Print Byte in A as Hex Digits
  2311. ;
  2312. BHEX:
  2313.     PUSH    PSW
  2314.     MVI    A,'<'
  2315.     CALL    TYPE
  2316.     POP    PSW
  2317.     CALL    HEX
  2318.     MVI    A,'>'
  2319.     CALL    TYPE
  2320.     RET
  2321. ;
  2322. ;Print Number in BC as Hex Digits
  2323. ;
  2324. HEXB:
  2325.     LDA    DSM+1
  2326.     ORA    A
  2327.     JZ    HEXX
  2328.     MOV    A,B
  2329.     CALL    HEX
  2330. ;
  2331. HEXX:
  2332.     MOV    A,C
  2333. ;
  2334. ;Print Byte in A as 2 Hex Digits
  2335. ;
  2336. HEX:
  2337.     PUSH    PSW
  2338.     RAR        ;GET HIGH NYBBLE
  2339.     RAR
  2340.     RAR
  2341.     RAR
  2342.     CALL    NIBBL    ;PRINT IT
  2343.     POP    PSW    ;GET LOW NYBBLE
  2344. ;
  2345. NIBBL:
  2346.     ANI    0FH    ;MASK LOW NYBBLE
  2347.     CPI    10    ;0-9?
  2348.     JC    HEXNU
  2349.     ADI    7    ;CONVERT TO A-F
  2350. ;
  2351. HEXNU:
  2352.     ADI    '0'    ;CONVERT TO ASCII
  2353.     JMP    TYPE    ;PRINT IT
  2354. ;
  2355. ;Decimal output routine
  2356. ;  Print Number in HL as decimal digits (HL<100)
  2357. ;
  2358. DEC:
  2359.     PUSH    B
  2360.     PUSH    D
  2361.     PUSH    H
  2362.     LXI    B,-10
  2363.     LXI    D,-1
  2364. ;
  2365. DECOU2:
  2366.     DAD    B
  2367.     INX    D
  2368.     JC    DECOU2
  2369.     LXI    B,10
  2370.     DAD    B
  2371.     XCHG
  2372.     MOV    A,H
  2373.     ORA    L
  2374.     CNZ    DEC
  2375.     MOV    A,E
  2376.     ADI    '0'
  2377.     CALL    TYPE
  2378.     POP    H
  2379.     POP    D
  2380.     POP    B
  2381.     RET
  2382. ;
  2383. ;Print <SP>
  2384. ;
  2385. SPACE:    MVI    A,' '
  2386.     JMP    TYPE
  2387. ;
  2388. ;Print '*'
  2389. ;
  2390. ASTER:    MVI    A,'*'
  2391.     JMP    TYPE
  2392. ;
  2393. ;Inline print routine
  2394. ;  Print Chars ending in 0 pted to by Return Address; return to byte after
  2395. ;
  2396. ILPRT:
  2397.     XTHL        ;GET PTR AND SAVE HL
  2398. ;
  2399. ILPLP:
  2400.     CALL    CTLCS    ;ABORT?
  2401.     JZ    PRMPTR
  2402.     MOV    A,M    ;GET CHAR
  2403.     CPI    1    ;PAUSE? -- ^A
  2404.     JNZ    ILPOK
  2405.     CALL    CONIN    ;WAIT FOR ANY CHAR
  2406.     CPI    3    ;ABORT?
  2407.     JZ    PRMPTR
  2408.     JMP    ILPNX
  2409. ;
  2410. ILPOK:
  2411.     CALL    TYPE    ;PRINT CHAR
  2412. ;
  2413. ILPNX:
  2414.     INX    H    ;PT TO NEXT
  2415.     MOV    A,M    ;GET IT
  2416.     ORA    A    ;DONE?
  2417.     JNZ    ILPLP
  2418.     INX    H    ;PT TO BYTE AFTER ENDING 0
  2419.     XTHL        ;RESTORE HL AND RET ADR
  2420.     RET
  2421. ;
  2422. ;DISP calls DECIN, and validates a sector
  2423. ;displacement, then converts it to an address
  2424. ;
  2425. DISP:
  2426.     CALL    DECIN
  2427. DISP1:
  2428.     PUSH    PSW    ;SAVE DELIMITER
  2429.     MOV    A,D
  2430.     ORA    A
  2431.     JNZ    BADISP
  2432.     MOV    A,E
  2433.     ORA    A
  2434.     JM    BADISP
  2435.     ADI    80H    ;TO POINT TO BUFFER AT BASE+80H
  2436.     MOV    E,A
  2437.     MVI    D,BASE/256
  2438.     POP    PSW    ;GET DELIM
  2439.     RET
  2440. ;
  2441. BADISP:
  2442.     XRA    A
  2443.     STA    QFLAG    ;NOT QUIET
  2444.     CALL    ILPRT
  2445.     DB    '++ Bad Displacement (Not 0-7FH) ++'
  2446.     DB    CR,LF,0
  2447.     JMP    PRMPTR
  2448. ;
  2449. ;Input Number from Command Line -- Assume it to be Hex
  2450. ;  Number returned in DE
  2451. ;
  2452. HEXIN:
  2453.     LXI    D,0
  2454.     MOV    A,M
  2455.     CPI    '#'    ;DECIMAL?
  2456.     JZ    HDIN    ;MAKE DECIMAL
  2457. ;
  2458. HINLP:
  2459.     MOV    A,M    ;GET CHAR
  2460.     CALL    UPCASE    ;CAPITALIZE
  2461.     CPI    CR    ;EOL?
  2462.     RZ
  2463.     CPI    ';'    ;EOL?
  2464.     RZ
  2465.     CPI    ','
  2466.     RZ
  2467.     CPI    '-'    ;'THRU'?
  2468.     RZ
  2469.     CPI    '>'
  2470.     RZ
  2471.     INX    H    ;PT TO NEXT CHAR
  2472.     CPI    '0'    ;RANGE?
  2473.     JC    WHAT
  2474.     CPI    '9'+1    ;RANGE?
  2475.     JC    HINNUM
  2476.     CPI    'A'    ;RANGE?
  2477.     JC    WHAT
  2478.     CPI    'F'+1    ;RANGE?
  2479.     JNC    WHAT
  2480.     SUI    7    ;ADJUST FROM A-F TO 10-15
  2481. ;
  2482. HINNUM:
  2483.     SUI    '0'    ;CONVERT FROM ASCII TO BINARY
  2484.     XCHG
  2485.     DAD    H    ;MULT PREVIOUS VALUE BY 16
  2486.     DAD    H
  2487.     DAD    H
  2488.     DAD    H
  2489.     ADD    L    ;ADD IN NEW DIGIT
  2490.     MOV    L,A
  2491.     XCHG
  2492.     JMP    HINLP
  2493. ;
  2494. HDIN:
  2495.     INX    H    ;SKIP '.'
  2496. ;
  2497. ;Input Number in Command Line as Decimal
  2498. ;  Number is returned in DE
  2499. ;
  2500. DECIN:
  2501.     LXI    D,0
  2502.     MOV    A,M    ; GET 1ST CHAR
  2503.     CPI    '#'    ; HEX?
  2504.     JNZ    DINLP
  2505.     INX    H    ; PT TO DIGIT
  2506.     JMP    HINLP    ; DO HEX PROCESSING
  2507. ;
  2508. DINLP:
  2509.     MOV    A,M    ;GET DIGIT
  2510.     CALL    UPCASE    ;CAPITALIZE
  2511.     CPI    CR    ;EOL?
  2512.     RZ
  2513.     CPI    ';'    ;EOL?
  2514.     RZ
  2515.     CPI    ','
  2516.     RZ
  2517.     CPI    '-'    ;'THRU'?
  2518.     RZ
  2519.     INX    H    ;PT TO NEXT
  2520.     CPI    '0'    ;RANGE?
  2521.     JC    WHAT
  2522.     CPI    '9'+1    ;RANGE?
  2523.     JNC    WHAT
  2524.     SUI    '0'    ;CONVERT TO BINARY
  2525.     PUSH    H
  2526.     MOV    H,D
  2527.     MOV    L,E
  2528.     DAD    H    ;X2
  2529.     DAD    H    ;X4
  2530.     DAD    D    ;X5
  2531.     DAD    H    ;X10
  2532.     ADD    L    ;ADD IN DIGIT
  2533.     MOV    L,A
  2534.     MOV    A,H
  2535.     ACI    0
  2536.     MOV    H,A
  2537.     XCHG        ;RESULT IN DE
  2538.     POP    H
  2539.     JMP    DINLP
  2540. ;
  2541. ;Read in a console buffer
  2542. ;
  2543. RDBUF:
  2544.     CALL    ILPRT    ;PRINT PROMPT
  2545.     DB    CR,LF,'DUTIL  ',0
  2546.     LDA    DRIVE    ;GET DRIVE NUMBER
  2547.     ADI    'A'    ;CONVERT TO ASCII
  2548.     CALL    TYPE
  2549.     LDA    VER2FL    ;VERSION 2 OR BETTER?
  2550.     ORA    A    ;0=NO
  2551.     JZ    RDBUF1
  2552.     MVI    A,'/'
  2553.     CALL    TYPE
  2554.     LDA    UNUM    ;DISPLAY USER NUMBER
  2555.     MOV    L,A    ;VALUE IN HL
  2556.     MVI    H,0
  2557.     CALL    DEC    ;PRINT IN DECIMAL
  2558. RDBUF1:
  2559.     CALL    ILPRT    ;PRINT PROMPT
  2560.     DB    '? ',0
  2561.     LXI    D,INBUF-2    ;USE CP/M READLN
  2562.     MVI    C,10
  2563.     CALL    BDOS
  2564.     LDA    INBUF-1    ;GET CHAR COUNT
  2565.     MOV    B,A    ;CHAR COUNT IN B
  2566.     LXI    H,INBUF    ;STORE ENDING <CR>
  2567.     ADD    L    ;ADD CHAR COUNT TO HL
  2568.     MOV    L,A
  2569.     MOV    A,H
  2570.     ACI    0
  2571.     MOV    H,A
  2572.     MVI    A,CR    ;STORE ENDING <CR>
  2573.     MOV    M,A    ;SAVE IT
  2574.     CALL    TYPE    ;ECHO IT
  2575.     MVI    A,LF    ;ECHO..
  2576.     CALL    TYPE    ;..LF
  2577.     LXI    H,INBUF    ;SET PTR TO FIRST CHAR IN LINE
  2578.     RET
  2579. ;
  2580. ;Set paging flag for page routine
  2581. ;
  2582. PAGSET:
  2583.     LDA    PAGSIZ    ;GET SIZE OF PAGE
  2584.     STA    PAGFLG    ;SET FLAG
  2585.     RET
  2586. ;
  2587. ;Page output
  2588. ;
  2589. PAGER:
  2590.     LDA    PAGFLG    ;GET FLAG
  2591.     CPI    2    ;2 LINES LEFT?
  2592.     JZ    WAIT    ;SAME AS USER DELAY
  2593.     DCR    A    ;COUNT DOWN
  2594.     STA    PAGFLG
  2595.     JMP    CRLF
  2596. ;
  2597. ;Delay Routine
  2598. ;
  2599. WAIT:    PUSH    H
  2600.     CALL    ILPRT
  2601.     DB    CR,LF,'Type Any Character to Continue or ^C to Abort - ',0
  2602.     POP    H
  2603.     CALL    CONIN    ;GET RESPONSE
  2604.     CPI    'C'-40H    ;^C?
  2605.     JZ    WAIT1
  2606.     CALL    CRLF    ;NEW LINE
  2607.     CALL    PAGSET    ;RESET PAGE COUNT
  2608.     RET
  2609. WAIT1:
  2610.     LDA    IHFLG    ;INITIAL HELP?
  2611.     ORA    A    ;0=NO
  2612.     JZ    PRMPTR    ;ABORT TO COMMAND PROMPT
  2613.     JMP    EXIT1    ;ABORT TO CP/M
  2614. ;
  2615. ;CRLF Routine
  2616. ;
  2617. CRLF:    MVI    A,CR
  2618.     CALL    TYPE
  2619.     MVI    A,LF
  2620.     JMP    TYPE
  2621. ;
  2622. ;Convert to Upper Case
  2623. ;
  2624. UPCASE:
  2625.     ANI    7FH    ;MASK OUT MSB
  2626.     CPI    60H    ;LESS THAN SMALL A?
  2627.     RC        ;RETURN IF SO
  2628.     ANI    5FH    ;MAKE UPPER CASE
  2629.     RET
  2630. ;
  2631. ;CON: Status Routine
  2632. ;
  2633. CONST:
  2634.     PUSH    B
  2635.     PUSH    D
  2636.     PUSH    H
  2637. VCONST:
  2638.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2639.     POP    H
  2640.     POP    D
  2641.     POP    B
  2642.     RET
  2643. ;
  2644. ;CON: Input Routine
  2645. ;
  2646. CONIN:
  2647.     PUSH    B
  2648.     PUSH    D
  2649.     PUSH    H
  2650. VCONIN:
  2651.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2652.     POP    H
  2653.     POP    D
  2654.     POP    B
  2655.     RET
  2656. ;
  2657. ;Console out with TAB expansion
  2658. ;  Char in A
  2659. ;
  2660. TYPE:
  2661.     PUSH    B    ;SAVE REGS
  2662.     PUSH    D
  2663.     PUSH    H
  2664.     MOV    C,A    ;FOR OUTPUT ROUTINE
  2665.     CPI    TAB
  2666.     JNZ    TYPE2
  2667. ;Tabulate
  2668. TYPTAB:
  2669.     MVI    A,' '    ;PRINT SPACE
  2670.     CALL    TYPE
  2671.     LDA    TABCOL    ;GET COL COUNT
  2672.     ANI    7    ;DONE?
  2673.     JNZ    TYPTAB
  2674.     JMP    TYPRET
  2675. ;
  2676. ;Filter out control characters to
  2677. ;prevent garbage during view of file
  2678. ;
  2679. TYPE2:
  2680.     CPI    ' '
  2681.     JNC    TYPEQ
  2682.     CPI    CR
  2683.     JZ    TYPEQ
  2684.     CPI    LF
  2685.     JNZ    TYPNCR
  2686. ;
  2687. TYPEQ:
  2688.     LDA    QFLAG    ;CHECK QUIET FLAG FOR NO MESSAGES
  2689.     ORA    A
  2690.  
  2691. ;
  2692. ;CON: Output Routine
  2693. ;
  2694. VCONOT:    CZ    $-$    ;ADDR FILLED IN BY 'INIT'
  2695. ;
  2696. ;Update column used in tab expansion
  2697. ;
  2698.     MOV    A,C    ;GET CHAR
  2699.     CPI    CR
  2700.     JNZ    TYPNCR
  2701.     MVI    A,0    ;RESET TAB COLUMN IF <CR>
  2702.     STA    TABCOL
  2703.     JMP    TYPLST
  2704. ;
  2705. TYPNCR:
  2706.     CPI    ' '    ;CTL CHAR?
  2707.     JC    TYPLST    ;..NO CHANGE IN COL
  2708.     LDA    TABCOL    ;INCR TAB COUNT
  2709.     INR    A
  2710.     STA    TABCOL
  2711. ;
  2712. TYPLST:
  2713.     LDA    PFLAG    ;CHECK FOR PRINTER OUTPUT
  2714.     ANI    1
  2715.     CNZ    LIST    ;FROM C REG
  2716. ;
  2717. TYPRET:
  2718.     POP    H    ;RESTORE REGS
  2719.     POP    D
  2720.     POP    B
  2721.     RET
  2722. ;
  2723. ;LST: Output Routine
  2724. ;  Char in C
  2725. ;
  2726. LIST:
  2727.     PUSH    B    ;SAVED REGS
  2728.     PUSH    D
  2729.     PUSH    H
  2730. VLIST:
  2731.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2732.     POP    H
  2733.     POP    D
  2734.     POP    B
  2735.     RET
  2736. ;
  2737. ;Home Disk Routine
  2738. ;
  2739. HOME:
  2740.     PUSH    H
  2741. VHOME:
  2742.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2743.     POP    H
  2744.     RET
  2745. ;
  2746. ;Set track # in DE
  2747. ;
  2748. SETTRK:
  2749.     PUSH    H
  2750.     LHLD    MAXTRK    ;CHECK FOR WITHIN BOUNDS
  2751.     CALL    SUBDE    ;IF TRACK # IN DE > MAX, THEN ERROR
  2752.     POP    H
  2753.     JC    OUTLIM
  2754.     XCHG        ;RESET CURRENT TRACK
  2755.     SHLD    CURTRK
  2756.     XCHG
  2757.     MOV    B,D    ;BC=TRACK NUMBER
  2758.     MOV    C,E
  2759.     PUSH    H
  2760. ;
  2761. VSETRK:
  2762.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2763.     POP    H
  2764.     RET
  2765. ;
  2766. ;Set Sector Number in DE
  2767. ;
  2768. SETSEC:
  2769.     PUSH    H
  2770.     PUSH    D
  2771.     LHLD    SYSTRK    ;GET NUMBER OF SYSTEM TRACKS
  2772.     XCHG
  2773.     SHLD    CURSEC    ;SET CURRENT SECTOR
  2774.     LHLD    CURTRK    ;GET CURRENT TRACK
  2775.     CALL    SUBDE    ;SEE IF WE ARE IN THE SYSTEM TRACKS
  2776.     POP    B    ;BC=SECTOR NUMBER
  2777.     MOV    H,B    ;HL=SECTOR NUMBER
  2778.     MOV    L,C
  2779.     JNC    NOTSYS    ;IF NO CARRY FOR SUBDE, WE ARE NOT IN SYSTEM TRACKS
  2780.     LDA    FIRST0    ;SEE IF FIRST SEC 0
  2781.     ORA    A
  2782.     JNZ    GSTSEC    ;NO, JUMP AWAY
  2783.     DCX    H    ;YES, SO DECREMENT
  2784.     JMP    GSTSEC    ;REQUESTED, THEN GO
  2785. ;
  2786. ;Not in System Tracks, so Skew Factor is effective
  2787. ;
  2788. NOTSYS:
  2789.     LHLD    SECTBL    ;GET PTR TO SECTOR TABLE
  2790.     XCHG        ;... IN DE
  2791.     DCX    B    ;DECREMENT SECTOR NUMBER BY 1
  2792. ;
  2793. VSCTRN:
  2794.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2795.     LDA    SPT+1    ;IF SPT<256 (HI-ORD = 0)
  2796.     ORA    A    ; THEN FORCE 8-BIT TRANSLATION
  2797.     JNZ    VSCTR1    ; ELSE KEEP ALL 16 BITS
  2798.     MOV    H,A
  2799. VSCTR1:
  2800.     LDA    VER2FL    ;SEE IF VERSION 2.x
  2801.     ORA    A    ;SET FLAGS
  2802.     JNZ    GSTSEC    ;JUMP IF CP/M 2.x
  2803.     MVI    H,0    ;CP/M 1.4 GOOD TO ONLY 8 BITS
  2804.     MOV    L,C    ;MOST BIOS'S RETURN THE
  2805.             ;  PHYSICAL SEC # IN REG C
  2806. GSTSEC:
  2807.     SHLD    PHYSEC    ;THIS MAY BE REDUNTANT IN
  2808.             ; MOST 1.4 VERSIONS, BUT
  2809.             ; SHOULD CAUSE NO PROBLEMS
  2810.     MOV    B,H
  2811.     MOV    C,L
  2812. ;
  2813. VSTSEC:
  2814.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2815.     POP    H    ;RESTORE PTR TO NEXT CHAR
  2816.     RET
  2817. ;
  2818. ;Out of Disk Track Limit
  2819. ;
  2820. OUTLIM:
  2821.     XRA    A    ;NOT QUIET
  2822.     STA    QFLAG
  2823.     CALL    ILPRT
  2824.     DB    '++ Not Within Tracks 0-',0
  2825.     PUSH    H
  2826.     LHLD    MAXTRK    ;PRINT MAX TRACK NUMBER
  2827.     CALL    DEC
  2828.     POP    H
  2829.     CALL    ILPRT
  2830.     DB    ' ++',CR,LF,0
  2831.     CALL    NORITE    ;NOT POSITIONED
  2832.     JMP    PRMPTR
  2833. ;
  2834. ;Set DMA Address
  2835. ;
  2836. SETDMA:
  2837.     JMP    $-$    ;ADDR FILLED IN BY 'INIT'
  2838. ;
  2839. ;Read Next Block into DMA Address
  2840. ;
  2841. READ:
  2842.     MVI    A,1    ;SET FLAG
  2843.     STA    WRFLG
  2844.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  2845. ;
  2846. VREAD:
  2847.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2848.     ORA    A    ;ERROR?
  2849.     JZ    READOK
  2850.     XRA    A    ;NOT QUIET
  2851.     STA    QFLAG
  2852.     CALL    ILPRT
  2853.     DB    '++ READ Failed, Sector may be Invalid ++'
  2854.     DB    CR,LF,0
  2855. ;
  2856. READOK:
  2857.     POP    H    ;GET PTR TO NEXT CHAR
  2858.     RET
  2859. ;
  2860. ;Write Block in DMA Address to Disk
  2861. ;
  2862. WRITE:
  2863.     LDA    WRFLG    ;READ ALREADY PERFORMED?
  2864.     ORA    A    ;ERROR IF NOT
  2865.     JNZ    PWRITE
  2866. ;
  2867. BADW:
  2868.     XRA    A    ;NOT QUIET
  2869.     STA    QFLAG
  2870.     CALL    ILPRT
  2871.     DB    '++ Cannot Write Unless Read Issued ++'
  2872.     DB    CR,LF,0
  2873.     JMP    EXPL
  2874. ;
  2875. ;Do Write
  2876. ;
  2877. PWRITE:
  2878.     PUSH    H    ;SAVE PTR TO NEXT CHAR
  2879.     MVI    C,1    ;FORCE WRITE TYPE 1 IN CASE 2.x DEBLOCK USED
  2880. ;
  2881. VWRITE:
  2882.     CALL    $-$    ;ADDR FILLED IN BY 'INIT'
  2883.     ORA    A    ;ERROR?
  2884.     JZ    WRITOK
  2885.     XRA    A    ;NOT QUIET
  2886.     STA    QFLAG
  2887.     CALL    ILPRT
  2888.     DB    '++ WRITE Failed ++',CR,LF,0
  2889. ;
  2890. WRITOK:
  2891.     POP    H
  2892.     RET
  2893. ;
  2894. ;Help; HELP is entry point for HELP (?) command, HELP1 is entry point for
  2895. ; Initial Help Command, and IHELP is entry point for HELP (/) from command
  2896. ; line
  2897. ;
  2898. IHELP:
  2899.     XRA    A
  2900.     STA    QFLAG    ;NOT QUIET
  2901.     CALL    ILPRT
  2902.     DB    'Introductory HELP on DUTIL (Disk Utility)',CR,LF
  2903.     DB    '  The DUTIL program is designed to provide the user with'
  2904.     DB    CR,LF
  2905.     DB    'the ability to manipulate information on the disk as easily'
  2906.     DB    CR,LF
  2907.     DB    'as the DDT and SID utilities allow the user to manipulate'
  2908.     DB    CR,LF
  2909.     DB    'information in memory.',CR,LF
  2910.     DB    '  The following is a summary of the commands available to'
  2911.     DB    CR,LF
  2912.     DB    'the DUTIL user.  This same list is invoked internally by the'
  2913.     DB    CR,LF
  2914.     DB    '? Command of DUTIL.  For additional information on disk'
  2915.     DB    CR,LF
  2916.     DB    'structures and how to use DUTIL in general, refer to the'
  2917.     DB    CR,LF
  2918.     DB    'files DUTIL.DOC and DUTIL.HLP.',CR,LF,0
  2919.     MVI    A,0FFH    ;A=0FFH
  2920.     STA    IHFLG    ;SET INITIAL HELP
  2921.     CALL    WAIT
  2922.     JMP    HELP1    ;PROCESS NORMALLY
  2923. HELP:
  2924.     XRA    A    ;A=0
  2925.     STA    IHFLG    ;SET NO INITIAL HELP
  2926. HELP1:
  2927.     XRA    A
  2928.     STA    QFLAG    ;NOT QUIET
  2929.     CALL    ILPRT
  2930.     DB    '=======================================================',CR,LF
  2931.     DB    '           -- Command Summary --        ',CR,LF
  2932.     DB    '-------------------------------------------------------',CR,LF
  2933.     DB    CR,LF
  2934.     DB    'Operands in brackets [...] are optional'
  2935.     DB    CR,LF,CR,LF
  2936.     DB    '@    Repeat Previous Non-@ Command Line'
  2937.     DB    CR,LF
  2938.     DB    '+[nn]    Step In [nn (decimal)] Sectors;    -[nn]  Step Out '
  2939.     DB    'Sectors'
  2940.     DB    CR,LF
  2941.     DB    '#    Print Disk Parameters for Current Drive'
  2942.     DB    CR,LF
  2943.     DB    '=xxx    Search for ASCII xxx from Current Sector'
  2944.     DB    CR,LF
  2945.     DB    '     Caution: upper/lower case matters.'
  2946.     DB    CR,LF
  2947.     DB    '     Use <xx> for hex:'
  2948.     DB    CR,LF
  2949.     DB    '      To find "IN 0" use: =<db><0>     or'
  2950.     DB    CR,LF
  2951.     DB    '      "(tab)H,0(CR)(LF)" use: =<9>H,0<D><A>'
  2952.     DB    CR,LF
  2953.     DB    '<    Save Current Sector;    >      Restore Saved Sector'
  2954.     DB    CR,LF
  2955.     DB    '/[nn]    Repeat [nn (decimal) times];    !      Pause for User'
  2956.     DB    CR,LF
  2957.     DB    ':ntext    Define ''text'' to be Macro n;    n    Perform Macro'
  2958.     DB    ' n, 0<=n<=9'
  2959.     DB    CR,LF
  2960.     DB    ':Pn    Print Macro n, 0<=n<=9'
  2961.     DB    CR,LF
  2962.     DB    ':Px    Print All Macros if x=A or Print Prev Line if x=@'
  2963.     DB    CR,LF,CR,LF,0
  2964.     CALL    WAIT
  2965.     CALL    ILPRT
  2966.     DB    '-------------------------------------------------------',CR,LF
  2967.     DB    'A[ff,tt]    ASCII Dump'
  2968.     DB    CR,LF
  2969.     DB    'C    Change:'
  2970.     DB    CR,LF
  2971.     DB    '     CHaddr,byte,byte... (hex)'
  2972.     DB    CR,LF
  2973.     DB    '     or CAaddr,data...  (Ascii)'
  2974.     DB    CR,LF
  2975.     DB    '     <xx> Allowed for imbedded hex.'
  2976.     DB    CR,LF
  2977.     DB    '     or CHfrom-thru,byte  e.g. ch0-7f,e5'
  2978.     DB    CR,LF
  2979.     DB    '     or CAfrom-thru,byte'
  2980.     DB    CR,LF
  2981.     DB    'D[ff,tt]    Dump (Hex and ASCII)'
  2982.     DB    CR,LF
  2983.     DB    'Fn.t    Find File'
  2984.     DB    CR,LF
  2985.     DB    'Gnn    CP/M Allocation Group nn (hex)'
  2986.     DB    CR,LF
  2987.     DB    'H[ff,tt]    Hex Dump'
  2988.     DB    CR,LF
  2989.     DB    'L    Log in drive;    Lx    Log in drive x'
  2990.     DB    CR,LF
  2991.     DB    'M[nn]    Map [from group nn (hex)]'
  2992.     DB    CR,LF,CR,LF,0
  2993.     CALL    WAIT
  2994.     CALL    ILPRT
  2995.     DB    '-------------------------------------------------------',CR,LF
  2996.     DB    CR,LF
  2997.     DB    'N    Load New Disk;    P    Toggle Printer Switch'
  2998.     DB    CR,LF
  2999.     DB    'Q    Quiet Mode (no messages)'
  3000.     DB    CR,LF
  3001.     DB    'R    Read Current Sector;    RG    Read Specified Group'
  3002.     DB    CR,LF
  3003.     DB    'Snn    Sector nn (decimal)'
  3004.     DB    CR,LF
  3005.     DB    'Tnn    Track nn (decimal)'
  3006.     DB    CR,LF
  3007.     DB    'Unn    Set User nn (decimal) for Find command (CP/M-2 only)'
  3008.     DB    CR,LF
  3009.     DB    'V[nn]    View [nn (decimal)] ASCII Sectors'
  3010.     DB    CR,LF
  3011.     DB    'W    Write Current Sector;    WG    Write Specified Group'
  3012.     DB    CR,LF
  3013.     DB    'X    Exit Program'
  3014.     DB    CR,LF
  3015.     DB    'Z[nn]    Sleep [nn (decimal) seconds]'
  3016.     DB    CR,LF,CR,LF,0
  3017.     CALL    WAIT
  3018.     CALL    ILPRT
  3019.     DB    '-------------------------------------------------------',CR,LF
  3020.     DB    CR,LF
  3021.     DB    'Command Line is of the form:  DUTIL d/u?',CR,LF
  3022.     DB    '    "d" is Logged-In Disk, "u" is Current User',CR,LF
  3023.     DB    CR,LF
  3024.     DB    'Cancel a function with C or Ctrl-C.'
  3025.     DB    CR,LF
  3026.     DB    'Suspend output with S or Ctrl-S.'
  3027.     DB    CR,LF
  3028.     DB    'Separate commands with ";".'
  3029.     DB    CR,LF
  3030.     DB    '    Example: g0'
  3031.     DB    CR,LF
  3032.     DB    '    +;d;z2;/'
  3033.     DB    CR,LF
  3034.     DB    '     would step in, dump, sleep 2 sec, '
  3035.     DB    CR,LF
  3036.     DB    '     and repeat until control-c typed.'
  3037.     DB    CR,LF
  3038.     DB    '"nn" usage varies with command as follows:',CR,LF
  3039.     DB    '    +, -, /, T, S, U, V, Z    nn in Decimal',CR,LF
  3040.     DB    '                (use #nn for Hex)',CR,LF
  3041.     DB    '    G, M            nn in Hexadecimal',CR,LF
  3042.     DB    '                (use #nn for Decimal)'
  3043.     DB    CR,LF
  3044.     DB    '"ff" and "tt" are in Hexadecimal (use #ff or #tt for Decimal)'
  3045.     DB    CR,LF,CR,LF
  3046.     DB    '=======================================================',CR,LF
  3047.     DB    0
  3048.     CALL    WAIT
  3049.     CALL    ILPRT
  3050.     DB    '=======================================================',CR,LF
  3051.     DB    'DUTIL Status Information',CR,LF
  3052.     DB    '-------------------------------------------------------',CR,LF
  3053.     DB    'Processor Speed:  ',0
  3054.     LDA    CLOCK    ;GET CLOCK SPEED
  3055.     ADI    '0'    ;CONVERT TO ASCII
  3056.     CALL    TYPE    ;PRINT
  3057.     CALL    ILPRT
  3058.     DB    ' MHz',CR,LF
  3059.     DB    'Number of Lines on CON:  ',0
  3060.     LDA    PAGSIZ    ;GET PAGE SIZE
  3061.     MOV    L,A    ;NUMBER IN HL
  3062.     MVI    H,0
  3063.     CALL    DEC    ;PRINT NUMBER IN DECIMAL
  3064.     CALL    ILPRT
  3065.     DB    CR,LF,'Group Save Buffer Address:  ',0
  3066.     LXI    B,GBUFF    ;BC=ADDRESS
  3067.     CALL    HEXB    ;PRINT AS HEX
  3068.     CALL    ILPRT
  3069.     DB    ' Hex',CR,LF
  3070.     DB    '=======================================================',CR,LF
  3071.     DB    0
  3072.     LDA    IHFLG    ;INITIAL HELP?
  3073.     ORA    A    ;0=NO
  3074.     JNZ    EXIT1    ;RETURN TO CP/M IF SO
  3075.     JMP    PRMPTR    ;NEW LINE INPUT IF NOT
  3076. ;
  3077. ;COMMAND:  X
  3078. ;Exit to CP/M
  3079. ;
  3080. EXIT:
  3081.     XRA    A
  3082.     STA    QFLAG    ;NOT QUIET
  3083.     CALL    ILPRT    ;PRINT
  3084.     DB    CR,LF,'Exit to CP/M -- Do you wish to Warm Boot (Y/N/<CR>=N)?'
  3085.     DB    ' ',0
  3086.     CALL    CONIN    ;GET RESPONSE
  3087.     CALL    UPCASE    ;CAPITALIZE
  3088.     CPI    'Y'    ;YES?
  3089.     JZ    BASE    ;WARM BOOT IF SO
  3090. ;
  3091. ;Quick Exit to CP/M
  3092. ;
  3093. EXIT1:
  3094.     LHLD    DUTSTK    ;GET CP/M STACK PTR
  3095.     SPHL        ;SET SP
  3096.     RET
  3097.  
  3098. ;
  3099. ;********************************
  3100. ;*                *
  3101. ;*    Utility Subroutines    *
  3102. ;*                *
  3103. ;********************************
  3104. ;
  3105. GRPCMP:
  3106.     MOV    A,C
  3107.     INR    D
  3108.     DCR    D
  3109.     JZ    CMP8
  3110.     CMP    M
  3111.     INX    H
  3112.     RNZ
  3113.     MOV    A,B
  3114. ;
  3115. CMP8:
  3116.     CMP    M
  3117.     RET
  3118. ;
  3119. ;2's complement HL ==> HL
  3120. ;
  3121. NEG:
  3122.     MOV    A,L
  3123.     CMA
  3124.     MOV    L,A
  3125.     MOV    A,H
  3126.     CMA
  3127.     MOV    H,A
  3128.     INX    H
  3129.     RET
  3130. ;
  3131. ;HL/2 ==> HL
  3132. ;
  3133. ROTRHL:
  3134.     ORA    A
  3135.     MOV    A,H
  3136.     RAR
  3137.     MOV    H,A
  3138.     MOV    A,L
  3139.     RAR
  3140.     MOV    L,A
  3141.     RET
  3142. ;
  3143. ;Collect the number of '1' bits
  3144. ;in A as a count in C
  3145. ;
  3146. COLECT:
  3147.     MVI    B,8    ;NUMBER OF BITS
  3148. ;
  3149. COLOP:
  3150.     RAL
  3151.     JNC    COSKIP
  3152.     INR    C
  3153. ;
  3154. COSKIP:
  3155.     DCR    B
  3156.     JNZ    COLOP
  3157.     RET
  3158. ;
  3159. ;HL-DE ==> HL
  3160. ;  Carry Flag is Significant
  3161. ;
  3162. SUBDE:
  3163.     MOV    A,L
  3164.     SUB    E
  3165.     MOV    L,A
  3166.     MOV    A,H
  3167.     SBB    D
  3168.     MOV    H,A
  3169.     RET
  3170. ;
  3171. ;Quick Kludge multiply
  3172. ;HL*DE ==> HL
  3173. ;
  3174. MULT:
  3175.     PUSH    B
  3176.     PUSH    D
  3177.     XCHG
  3178.     MOV    B,D
  3179.     MOV    C,E
  3180.     MOV    A,B
  3181.     ORA    C
  3182.     JNZ    MULCON
  3183.     LXI    H,0    ;FILTER SPECIAL CASE
  3184.     JMP    MLDONE    ;  OF MULTIPLY BY 0
  3185. ;
  3186. MULCON:
  3187.     DCX    B
  3188.     MOV    D,H
  3189.     MOV    E,L
  3190. ;
  3191. MULTLP:
  3192.     MOV    A,B
  3193.     ORA    C
  3194.     JZ    MLDONE
  3195.     DAD    D
  3196.     DCX    B
  3197.     JMP    MULTLP
  3198. ;
  3199. MLDONE:
  3200.     POP    D
  3201.     POP    B
  3202.     RET
  3203. ;
  3204. ;Routine to fill in disk params
  3205. ;with every drive change
  3206. ;
  3207. LOGIT:
  3208.     LDA    VER2FL
  3209.     ORA    A    ;IF NOT CP/M 2.x THEN
  3210.     JZ    LOG14    ;    DO IT AS 1.4
  3211. ;
  3212. ;CP/M 2.x
  3213. ;
  3214.     LXI    D,DPB    ;   THEN MOVE TO LOCAL
  3215.     MVI    B,DPBLEN ;  WORKSPACE
  3216.     CALL    MOVE
  3217.     JMP    LOGCAL
  3218. ;
  3219. ;CP/M 1.4
  3220. ;
  3221. LOG14:
  3222.     LHLD    BDOS+1    ;FIRST FIND 1.4 BDOS
  3223.     MVI    L,0
  3224.     LXI    D,DPBOFF ;THEN OFFSET TO 1.4'S DPB
  3225.     DAD    D
  3226.     MVI    D,0    ;SO 8 BIT PARMS WILL BE 16
  3227.     MOV    E,M    ;NOW MOVE PARMS
  3228.     INX    H
  3229.     XCHG
  3230.     SHLD    SPT
  3231.     XCHG
  3232.     MOV    E,M
  3233.     INX    H
  3234.     XCHG
  3235.     SHLD    DRM
  3236.     XCHG
  3237.     MOV    A,M
  3238.     INX    H
  3239.     STA    BSH
  3240.     MOV    A,M
  3241.     INX    H
  3242.     STA    BLM
  3243.     MOV    E,M
  3244.     INX    H
  3245.     XCHG
  3246.     SHLD    DSM
  3247.     XCHG
  3248.     MOV    E,M
  3249.     INX    H
  3250.     XCHG
  3251.     SHLD    AL0
  3252.     XCHG
  3253.     MOV    E,M
  3254.     XCHG
  3255.     SHLD    SYSTRK
  3256. ;
  3257. LOGCAL:
  3258.     LXI    H,GRPDIS
  3259.     MOV    A,M
  3260.     PUSH    PSW
  3261.     LDA    BLM
  3262.     MOV    M,A
  3263.     PUSH    H
  3264.     LHLD    DSM
  3265.     XCHG
  3266.     CALL    GTKSEC
  3267.     SHLD    MAXSEC
  3268.     XCHG
  3269.     SHLD    MAXTRK
  3270.     POP    H
  3271.     POP    PSW
  3272.     MOV    M,A
  3273.     RET
  3274.  
  3275. ;***********************************
  3276. ;
  3277. ;  DUTIL Command Table
  3278. ;
  3279. ;***********************************
  3280. CMDTBL:
  3281.     DB    ':'
  3282.     DW    MAC
  3283. ;
  3284.     DB    '@'
  3285.     DW    PCMD
  3286. ;
  3287.     DB    '+'    
  3288.     DW     PLUS
  3289. ;
  3290.     DB    '-'
  3291.     DW    MINUS
  3292. ;
  3293.     DB    '='
  3294.     DW    SEARCH
  3295. ;
  3296.     DB    '<'
  3297.     DW    SAVE
  3298. ;
  3299.     DB    '>'
  3300.     DW    RESTOR
  3301. ;
  3302.     DB    '#'
  3303.     DW    STATS
  3304. ;
  3305.     DB    '?'
  3306.     DW    HELP
  3307. ;
  3308.     DB    '/'
  3309.     DW    REPEAT
  3310. ;
  3311.     DB    '!'
  3312.     DW    UWAIT
  3313. ;
  3314.     DB    'A'
  3315.     DW    DUMP
  3316. ;
  3317.     DB    'C'
  3318.     DW    CHG
  3319. ;
  3320.     DB    'D'
  3321.     DW    DUMP
  3322. ;
  3323.     DB    'F'
  3324.     DW    POSFIL
  3325. ;
  3326.     DB    'G'
  3327.     DW    POS
  3328. ;
  3329.     DB    'H'
  3330.     DW    DUMP
  3331. ;
  3332.     DB    'L'
  3333.     DW    LOGIN
  3334. ;
  3335.     DB    'M'
  3336.     DW    MAP
  3337. ;
  3338.     DB    'N'
  3339.     DW    NEWDSK
  3340. ;
  3341.     DB    'P'
  3342.     DW    PRNTFF
  3343. ;
  3344.     DB    'Q'
  3345.     DW    QUIET
  3346. ;
  3347.     DB    'R'
  3348.     DW    DOREAD
  3349. ;
  3350.     DB    'S'
  3351.     DW    POS
  3352. ;
  3353.     DB    'T'
  3354.     DW    POS
  3355. ;
  3356.     DB    'U'    ;******CP/M 2.x ONLY******
  3357.     DW    USER
  3358. ;
  3359.     DB    'V'
  3360.     DW    VIEW
  3361. ;
  3362.     DB    'W'
  3363.     DW    DORITE
  3364. ;
  3365.     DB    'X'
  3366.     DW    EXIT
  3367. ;
  3368.     DB    'Z'
  3369.     DW    SLEEP
  3370. ;
  3371.     DB    0    ; End of Table
  3372. ;*************************************
  3373.  
  3374. ;
  3375. ;Temporary storage area
  3376. ;
  3377.     DS    100    ;50-ELT STACK
  3378. DUTSTK:
  3379.     DS    2    ;OLD CP/M STACK POINTER; TOP OF DUTIL STACK
  3380. BUFAD:
  3381.     DS    2    ;FORCES INITIAL READ
  3382. HEXAD:
  3383.     DS    2    ;TO RE-FETCH A VALUE
  3384. TOGO:
  3385.     DS    2    ;REPEAT COUNT (FFFF=CONT)
  3386. TWOUP:
  3387.     DS    1
  3388. UNUM:
  3389.     DS    1    ;NUMBER OF CURRENT USER
  3390. ONLY1:
  3391.     DS    1    ;FLAG TO PRINT ONLY 1 MAP ENTRY (0=NO)
  3392. MFPTR:
  3393.     DS    2    ;MULTI FILE PTR FOR GETGRP
  3394. PAGFLG:
  3395.     DS    1    ;LINE COUNTER FOR PAGING
  3396. PFLAG:
  3397.     DS    1    ;1=PRINT
  3398. GROUP:
  3399.     DS    2    ;GROUP NUMBER
  3400. GRPDIS:
  3401.     DS    1    ;DISPLACEMENT INTO GROUP
  3402. SAVEFL:
  3403.     DS    1    ;SAVE FLAG
  3404. CURTRK:
  3405.     DS    2    ;CURRENT TRACK NUMBER
  3406. CURSEC:
  3407.     DS    2    ;CURRENT SECTOR NUMBER
  3408. PHYSEC:
  3409.     DS    2    ;CURRENT PHYSICAL SECTOR NUMBER
  3410. TABCOL:
  3411.     DS    1    ;TAB COLUMN
  3412. GLFLAG:
  3413.     DS    1    ;GROUP LOADED FLAG; 0=NO
  3414. CPYFCT:
  3415.     DS    1    ;GROUP COPY FUNCTION; 0=READ, 0FFH=WRITE
  3416. FILECT:
  3417.     DS    2    ;FILE COUNT
  3418. DIRPOS:
  3419.     DS    1    ;POSITION IN DIRECTORY
  3420. FINDFL:
  3421.     DS    1    ;1=MUST POSITION AFTER FIND
  3422. FTSW:
  3423.     DS    1    ;SEARCH W/O INCREMENT
  3424. NOTPOS:
  3425.     DS    1    ;INITIALLY NOT POSITIONED
  3426. WRFLG:
  3427.     DS    1    ;MAY NOT WRITE UNTIL '+', '-',
  3428. ;             OR 'G' COMMAND
  3429. TGRP:
  3430.     DS    2    ;TEMPORARY GROUP FLAG
  3431. QFLAG:
  3432.     DS    1    ;QUIET? (0=NO)
  3433. FIRST0:
  3434.     DS    1    ;SETS TO 0 IF FIRST SEC # IS 0
  3435. DRIVE:
  3436.     DS    1    ;DRIVE NUMBER
  3437. MAXTRK:
  3438.     DS    2    ;MAX TRACK NUMBER
  3439. MAXSEC:
  3440.     DS    2    ;MAX SECTOR NUMBER
  3441. VER2FL:
  3442.     DS    1    ;CP/M VERSION 2.X FLAG
  3443. SECTBL:
  3444.     DS    2    ;POINTER TO SECTOR SKEW TABLE
  3445. ;
  3446. IHFLG:
  3447.     DS    1    ;0=NOT AT INITIAL HELP, 0FFH=AT INITIAL HELP
  3448. DUPFLG:
  3449.     DS    1    ;SPACE OR STAR TO INDICATE MULTIPLE USERS
  3450. BACK:
  3451.     DS    2    ;TO BACK UP IN "CA0-7F,X"
  3452. DUMTYP:
  3453.     DS    1
  3454. ;
  3455. ;The disk parameter block
  3456. ;is moved here from CP/M
  3457. ;
  3458. DPB    EQU    $    ;DISK PARAMETER BLOCK (COPY)
  3459. SPT:
  3460.     DS    2
  3461. BSH:
  3462.     DS    1
  3463. BLM:
  3464.     DS    1
  3465. EXM:
  3466.     DS    1
  3467. DSM:
  3468.     DS    2
  3469. DRM:
  3470.     DS    2
  3471. AL0:
  3472.     DS    1
  3473. AL1:
  3474.     DS    1
  3475. CKS:
  3476.     DS    2
  3477. SYSTRK:
  3478.     DS    2
  3479. ;
  3480. ;End of disk parameter block
  3481. ;
  3482. SAVBUF:
  3483.     DS    128+2+2
  3484. ;
  3485. ;Set INBUF to a Page Boundary
  3486. ;
  3487.     ORG    $/100H*100H+100H-2
  3488.     DB    126    ; SIZE OF BUFFER FOR CP/M
  3489.     DS    1
  3490. INBUF:
  3491.     DS    400H    ;EXTRA SPACE FOR MACRO EXPANSION
  3492. PINBUF:
  3493.     DS    400H    ;PREVIOUS CONTENTS OF INPUT BUFFER
  3494. CTEMP:
  3495.     DS    400H    ;BUILD NEW COMMAND LINE BUFFER
  3496. CTEMPX    EQU    $    ;END OF CTEMP
  3497. ;
  3498. ;Directory read in here; also loaded group area and Macros
  3499. ;
  3500. MTABL:    DS    100H*10            ;10 PAGES FOR 10 MACROS
  3501. GBUFF    EQU    $
  3502. DIRECT    EQU    $
  3503. ;
  3504.     END
  3505.