home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / zsys / simtel20 / zcpr3 / sysrcp.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  44.0 KB  |  2,306 lines

  1. *  SYSTEM SEGMENT:  SYS.RCP
  2. *  SYSTEM:  ARIES-1
  3. *  CUSTOMIZED BY:  RICHARD CONN
  4.  
  5. *
  6. *  PROGRAM:  SYSRCP.ASM
  7. *  AUTHOR:  RICHARD CONN
  8. *  VERSION:  1.0
  9. *  DATE:  3 FEB 84
  10. *  PREVIOUS VERSIONS:  NONE
  11. *
  12. VERSION    EQU    10
  13.  
  14. *
  15. *    SYSRCP is a resident command processor for ZCPR3.  As with
  16. * all resident command processors, SYSRCP performs the following functions:
  17. *
  18. *        1.  Assuming that the EXTFCB contains the name of the
  19. *            command, SYSRCP looks to see if the first character
  20. *            of the file name field in the EXTFCB is a question
  21. *            mark; if so, it returns with the Zero Flag Set and
  22. *            HL pointing to the internal routine which prints
  23. *            its list of commands
  24. *        2.  The resident command list in SYSRCP is scanned for
  25. *            the entry contained in the file name field of
  26. *            EXTFCB; if found, SYSRCP returns with the Zero Flag
  27. *            Set and HL pointing to the internal routine which
  28. *            implements the function; if not found, SYSRCP returns
  29. *            with the Zero Flag Reset (NZ)
  30. *
  31.  
  32. *
  33. *  Global Library which Defines Addresses for SYSRCP
  34. *
  35.     MACLIB    Z3BASE    ; USE BASE ADDRESSES
  36.     MACLIB    SYSRCP    ; USE SYSRCP HEADER
  37.  
  38. ;
  39. CTRLC    EQU    'C'-'@'
  40. TAB    EQU    09H
  41. LF    EQU    0AH
  42. FF    EQU    0CH
  43. CR    EQU    0DH
  44. CTRLX    EQU    'X'-'@'
  45. ;
  46. WBOOT    EQU    BASE+0000H        ;CP/M WARM BOOT ADDRESS
  47. UDFLAG    EQU    BASE+0004H        ;USER NUM IN HIGH NYBBLE, DISK IN LOW
  48. BDOS    EQU    BASE+0005H        ;BDOS FUNCTION CALL ENTRY PT
  49. TFCB    EQU    BASE+005CH        ;DEFAULT FCB BUFFER
  50. FCB1    EQU    TFCB            ;1st and 2nd FCBs
  51. FCB2    EQU    TFCB+16
  52. TBUFF    EQU    BASE+0080H        ;DEFAULT DISK I/O BUFFER
  53. TPA    EQU    BASE+0100H        ;BASE OF TPA
  54. DIRBUF    EQU    BASE+4000H        ;DIR BUFFER (MANY ENTRIES PERMITTED)
  55. PAGCNT    EQU    DIRBUF-100H        ;PAGE COUNT BUFFER
  56. OLDFCB    EQU    PAGCNT+1        ;OLD FCB BUFFER
  57. CPBLOCKS    EQU    32        ;USE 4K FOR BUFFERING OF COPY
  58. ;
  59. $-MACRO         ;FIRST TURN OFF THE EXPANSIONS
  60. ;
  61. ; MACROS TO PROVIDE Z80 EXTENSIONS
  62. ;   MACROS INCLUDE:
  63. ;
  64. ;    JR    - JUMP RELATIVE
  65. ;    JRC    - JUMP RELATIVE IF CARRY
  66. ;    JRNC    - JUMP RELATIVE IF NO CARRY
  67. ;    JRZ    - JUMP RELATIVE IF ZERO
  68. ;    JRNZ    - JUMP RELATIVE IF NO ZERO
  69. ;    DJNZ    - DECREMENT B AND JUMP RELATIVE IF NO ZERO
  70. ;
  71. ;    @GENDD MACRO USED FOR CHECKING AND GENERATING
  72. ;    8-BIT JUMP RELATIVE DISPLACEMENTS
  73. ;
  74. @GENDD    MACRO    ?DD    ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS
  75.     IF (?DD GT 7FH) AND (?DD LT 0FF80H)
  76.     DB    100H,?DD    ;Displacement Range Error on Jump Relative
  77.     ELSE
  78.     DB    ?DD
  79.     ENDIF        ;;RANGE ERROR
  80.     ENDM
  81. ;
  82. ;
  83. ; Z80 MACRO EXTENSIONS
  84. ;
  85. JR    MACRO    ?N    ;;JUMP RELATIVE
  86.     IF    I8080    ;;8080/8085
  87.     JMP    ?N
  88.     ELSE        ;;Z80
  89.     DB    18H
  90.     @GENDD    ?N-$-1
  91.     ENDIF        ;;I8080
  92.     ENDM
  93. ;
  94. JRC    MACRO    ?N    ;;JUMP RELATIVE ON CARRY
  95.     IF    I8080    ;;8080/8085
  96.     JC    ?N
  97.     ELSE        ;;Z80
  98.     DB    38H
  99.     @GENDD    ?N-$-1
  100.     ENDIF        ;;I8080
  101.     ENDM
  102. ;
  103. JRNC    MACRO    ?N    ;;JUMP RELATIVE ON NO CARRY
  104.     IF    I8080    ;;8080/8085
  105.     JNC    ?N
  106.     ELSE        ;;Z80
  107.     DB    30H
  108.     @GENDD    ?N-$-1
  109.     ENDIF        ;;I8080
  110.     ENDM
  111. ;
  112. JRZ    MACRO    ?N    ;;JUMP RELATIVE ON ZERO
  113.     IF    I8080    ;;8080/8085
  114.     JZ    ?N
  115.     ELSE        ;;Z80
  116.     DB    28H
  117.     @GENDD    ?N-$-1
  118.     ENDIF        ;;I8080
  119.     ENDM
  120. ;
  121. JRNZ    MACRO    ?N    ;;JUMP RELATIVE ON NO ZERO
  122.     IF    I8080    ;;8080/8085
  123.     JNZ    ?N
  124.     ELSE        ;;Z80
  125.     DB    20H
  126.     @GENDD    ?N-$-1
  127.     ENDIF        ;;I8080
  128.     ENDM
  129. ;
  130. DJNZ    MACRO    ?N    ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
  131.     IF    I8080    ;;8080/8085
  132.     DCR    B
  133.     JNZ    ?N
  134.     ELSE        ;;Z80
  135.     DB    10H
  136.     @GENDD    ?N-$-1
  137.     ENDIF        ;;I8080
  138.     ENDM
  139. *
  140. *  SYSTEM Entry Point
  141. *
  142.     org    rcp        ; passed for Z3BASE
  143.  
  144.     db    'Z3RCP'        ; Flag for Package Loader
  145. *
  146. *  **** Command Table for RCP ****
  147. *    This table is RCP-dependent!
  148. *
  149. *    The command name table is structured as follows:
  150. *
  151. *    ctable:
  152. *        DB    'CMNDNAME'    ; Table Record Structure is
  153. *        DW    cmndaddress    ; 8 Chars for Name and 2 Bytes for Adr
  154. *        ...
  155. *        DB    0    ; End of Table
  156. *
  157. cnsize    equ    4        ; NUMBER OF CHARS IN COMMAND NAME
  158.     db    cnsize    ; size of text entries
  159. ctab:
  160.     db    'H   '    ; Help for RCP
  161.     dw    clist
  162. ctab1:
  163. ;
  164.     IF    CPON
  165.     db    'CP  '    ; Copy
  166.     dw    copy
  167.     ENDIF        ;CPON
  168. ;
  169.     IF    DIRON
  170.     db    'DIR '    ; Directory
  171.     dw    dir
  172.     ENDIF        ;DIRON
  173. ;
  174.     IF    ECHOON
  175.     db    'ECHO'    ; Echo
  176.     dw    echo
  177.     ENDIF
  178. ;
  179.     IF    ERAON
  180.     db    'ERA '    ; Erase
  181.     dw    era
  182.     ENDIF        ;ERAON
  183. ;
  184.     IF    LTON AND LISTON
  185.     db    'LIST'    ; List
  186.     dw    list
  187.     ENDIF        ;LTON AND LISTON
  188. ;
  189.     IF    NOTEON
  190.     db    'NOTE'    ; Note-Comment-NOP Command
  191.     dw    note
  192.     ENDIF
  193. ;
  194.     IF    PEEKON
  195.     db    'P   '    ; Peek into Memory
  196.     dw    peek
  197.     ENDIF        ;PEEKON
  198. ;
  199.     IF    POKEON
  200.     db    'POKE'    ; Poke Values into Memory
  201.     dw    poke
  202.     ENDIF        ;POKEON
  203. ;
  204.     IF    PROTON
  205.     db    'PROT'    ; Protection Codes
  206.     dw    att
  207.     ENDIF        ;PROTON
  208. ;
  209.     IF    REGON
  210.     db    'REG '    ; Register Command
  211.     dw    regcmd
  212.     ENDIF        ;RSETON
  213. ;
  214.     IF    RENON
  215.     db    'REN '    ; Rename
  216.     dw    ren
  217.     ENDIF        ;RENON
  218. ;
  219.     IF    LTON
  220.     db    'TYPE'    ; Type
  221.     dw    type
  222.     ENDIF        ;LTON
  223. ;
  224.     IF    WHLON
  225.     db    'WHL '    ; Wheel
  226.     dw    whl
  227.     db    'WHLQ'    ; Wheel Query
  228.     dw    whlmsg
  229.     ENDIF        ;WHLON
  230. ;
  231.     db    0
  232. *
  233. *  BANNER NAME OF RCP
  234. *
  235. rcp$name:
  236.     db    'SYS '
  237.     db    (version/10)+'0','.',(version mod 10)+'0'
  238.     db    RCPID
  239.     db    0
  240.  
  241. *
  242. *  Command List Routine
  243. *
  244. clist:
  245.     lxi    h,rcp$name    ; print RCP Name
  246.     call    print1
  247.     lxi    h,ctab1        ; print table entries
  248.     mvi    c,1        ; set count for new line
  249. clist1:
  250.     mov    a,m        ; done?
  251.     ora    a
  252.     rz
  253.     dcr    c        ; count down
  254.     jrnz    clist1a
  255.     call    crlf        ; new line
  256.     mvi    c,4        ; set count
  257. clist1a:
  258.     lxi    d,entryname    ; copy command name into message buffer
  259.     mvi    b,cnsize    ; number of chars
  260. clist2:
  261.     mov    a,m        ; copy
  262.     stax    d
  263.     inx    h        ; pt to next
  264.     inx    d
  265.     dcr    b
  266.     jnz    clist2
  267.     inx    h        ; skip to next entry
  268.     inx    h
  269.     push    h        ; save ptr
  270.     lxi    h,entrymsg    ; print message
  271.     call    print1
  272.     pop    h        ; get ptr
  273.     jmp    clist1
  274. *
  275. *  Console Output Routine
  276. *
  277. conout:
  278.     push    h        ; save regs
  279.     push    d
  280.     push    b
  281.     push    psw
  282.     ani    7fh        ; mask MSB
  283.     mov    e,a        ; char in E
  284.     mvi    c,2        ; output
  285.     call    bdos
  286.     pop    psw        ; get regs
  287.     pop    b
  288.     pop    d
  289.     pop    h
  290. ;
  291. ;  This simple return doubles for the NOTE Command (NOP) and CONOUT Exit
  292. ;  NOTE Command: NOTE any text
  293. ;
  294. NOTE:
  295.     ret
  296. *
  297. *  Print String (terminated in 0 or MSB Set) at Return Address
  298. *
  299. print:
  300.     xthl            ; get address
  301.     call    print1
  302.     xthl            ; put address
  303.     ret
  304. *
  305. *  Print String (terminated in 0 or MSB Set) pted to by HL
  306. *
  307. print1:
  308.     mov    a,m        ; done?
  309.     inx    h        ; pt to next
  310.     ora    a        ; 0 terminator
  311.     rz
  312.     call    conout        ; print char
  313.     rm            ; MSB terminator
  314.     jmp    print1
  315. *
  316. *  CLIST Messages
  317. *
  318. entrymsg:
  319.     db    '  '        ; command name prefix
  320. entryname:
  321.     ds    cnsize    ; command name
  322.     db    0    ; terminator
  323.  
  324. *
  325. *  **** RCP Routines ****
  326. *  All code from here on is RCP-dependent!
  327. *
  328.  
  329. ;
  330. ;Section 5A
  331. ;Command: DIR
  332. ;Function:  To display a directory of the files on disk
  333. ;Forms:
  334. ;    DIR <afn>    Displays the DIR files
  335. ;    DIR <afn> S    Displays the SYS files
  336. ;    DIR <afn> A    Display both DIR and SYS files
  337. ;Notes:
  338. ;    The flag SYSFLG defines the letter used to display both DIR and
  339. ;        SYS files (A in the above Forms section)
  340. ;    The flag SOFLG defines the letter used to display only the SYS
  341. ;        files (S in the above Forms section)
  342. ;    The flag WIDE determines if the file names are spaced further
  343. ;        apart (WIDE=TRUE) for 80-col screens
  344. ;    The flag FENCE defines the character used to separate the file
  345. ;        names
  346. ;
  347.     IF    DIRON
  348. DIR:
  349. ;
  350. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  351. ;
  352.     IF    WDIR
  353.     CALL    WHLTST
  354.     ENDIF        ;WHEEL APPROVAL
  355. ;
  356.     CALL    RETSAVE        ;SAVE RET ADDRESS AND SET STACK
  357.     LXI    H,FCB1+1     ;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP
  358.     MOV    A,M        ;GET FIRST CHAR OF FILENAME.TYP
  359.     CPI    ' '        ;IF <SP>, ALL WILD
  360.     CZ    FILLQ
  361.     LDA    FCB2+1        ;GET FIRST CHAR OF 2ND FILE NAME
  362.     MVI    B,80H        ;PREPARE FOR DIR-ONLY SELECTION
  363.     CPI    ' '        ;ANY FLAG?
  364.     JRZ    DIRPR        ;THERE IS NO FLAG, SO DIR ONLY
  365.     MVI    B,1        ;SET FOR BOTH DIR AND SYS FILES
  366.     CPI    SYSFLG        ;SYSTEM AND DIR FLAG SPECIFIER?
  367.     JRZ    DIRPR        ;GOT SYSTEM SPECIFIER
  368.     CPI    SOFLG        ;SYS ONLY?
  369.     JRNZ    DIRPR
  370.     DCR    B        ;B=0 FOR SYS FILES ONLY
  371. ;
  372.     ENDIF        ;DIRON
  373. ;
  374. ; DIRECTORY PRINT ROUTINE; ON ENTRY, B REG IS SET AS FOLLOWS:
  375. ;    0 FOR ONLY SYSTEM FILES, 80H FOR ONLY DIR FILES, 1 FOR BOTH
  376. ;
  377.     IF    DIRON OR ERAON OR LTON OR PROTON OR CPON OR RENON
  378. DIRPR:
  379.     MOV    A,B        ;GET SYSTST FLAG
  380.     CALL    GETDIR        ;LOAD AND SORT DIRECTORY
  381.     JZ    PRFNF        ;PRINT NO FILE MESSAGE
  382.     MVI    E,4        ;COUNT DOWN TO 0
  383. ;
  384. ; ENTRY PRINT LOOP; ON ENTRY, HL PTS TO FILES SELECTED (TERMINATED BY 0)
  385. ;    AND E IS ENTRY COUNTER
  386. ;
  387. DIR3:
  388.     MOV    A,M        ;CHECK FOR DONE
  389.     ORA    A
  390.     JZ    EXIT        ;EXIT IF DONE
  391.     MOV    A,E        ;GET ENTRY COUNTER
  392.     ORA    A        ;OUTPUT <CRLF> IF 4 ENTRIES PRINTED IN LINE
  393.     CZ    DIRCRLF        ;NEW LINE
  394.     MOV    A,E        ;GET ENTRY COUNT
  395.     CPI    4        ;FIRST ENTRY?
  396.     JRZ    DIR4
  397.     CALL    PRINT
  398. ;
  399.     IF    WIDE
  400. ;
  401.     DB    '  '        ;2 SPACES
  402.     DB    FENCE        ;THEN FENCE CHAR
  403.     DB    ' '+80H        ;THEN 1 MORE SPACE
  404. ;
  405.     ELSE
  406. ;
  407.     DB    ' '        ;SPACE
  408.     DB    FENCE+80H    ;THEN FENCE CHAR
  409. ;
  410.     ENDIF            ;WIDE
  411. ;
  412. DIR4:
  413.     CALL    PRFN        ;PRINT FILE NAME
  414.     CALL    BREAK        ;CHECK FOR ABORT
  415.     DCR    E        ;DECREMENT ENTRY COUNTER
  416.     JR    DIR3
  417. ;
  418. ; CRLF FOR DIR ROUTINE
  419. ;
  420. DIRCRLF:
  421.     PUSH    PSW        ;DON'T AFFECT PSW
  422.     CALL    CRLF        ;NEW LINE
  423.     POP    PSW
  424.     MVI    E,4        ;RESET ENTRY COUNTER
  425.     RET
  426. ;
  427. ; AFTER A SEARCH, RETURN NZ SET IF DESIRED TYPE OF FILE FOUND, Z IF NOT
  428. ;   THIS ALGORITHM LOOKS AT THE SYSTEM BIT OF THE LOCATED FILE; THIS
  429. ;   BIT IS SET TO 1 IF THE FILE IS A SYSTEM FILE AND 0 IF NOT A SYSTEM
  430. ;   FILE.  THE FOLLOWING EXCLUSIVE OR MASKS ARE APPLIED TO RETURN Z OR NZ
  431. ;   AS REQUIRED BY THE CALLING PROGRAM:
  432. ;
  433. ;    SYSTEM BYTE: X 0 0 0  0 0 0 0   (AFTER 80H MASK, X=1 IF SYS, 0 IF DIR)
  434. ;
  435. ;    SYS-ONLY   : 0 0 0 0  0 0 0 0   (XOR 0 = 0 if X=0, = 80H if X=1)
  436. ;    DIR-ONLY   : 1 0 0 0  0 0 0 0   (XOR 80H = 80h if X=0, = 0 if X=1)
  437. ;    BOTH       : 0 0 0 0  0 0 0 1   (XOR 1 = 81H or 1H, NZ in both cases)
  438. ;
  439. GETSBIT:
  440.     DCR    A        ;ADJUST TO RETURNED VALUE
  441.     RRC            ;CONVERT NUMBER TO OFFSET INTO TBUFF
  442.     RRC
  443.     RRC
  444.     ANI    60H
  445.     MOV    C,A        ;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY)
  446.     LXI    D,TBUFF        ;PT TO BUFFER
  447.     MOV    A,E        ;BASE ADDRESS IN A
  448.     ADD    C        ;ADD IN ENTRY OFFSET
  449.     MOV    E,A        ;RESULT IN E
  450.     PUSH    D        ;SAVE PTR IN DE
  451.     ADI    10        ;ADD OFFSET OF 10 TO PT TO SYSTEM BYTE
  452.     MOV    E,A        ;SET ADDRESS
  453.     LDAX    D        ;GET BYTE
  454.     POP    D        ;GET PTR IN DE
  455.     ANI    80H        ;LOOK AT ONLY SYSTEM BIT
  456. SYSTST    EQU    $+1        ;IN-THE-CODE VARIABLE
  457.     XRI    0        ; IF SYSTST=0, SYS ONLY; IF SYSTST=80H, DIR
  458.                 ; ONLY; IF SYSTST=1, BOTH SYS AND DIR
  459.     RET            ;NZ IF OK, Z IF NOT OK
  460. ;
  461. ; FILL FCB @HL WITH '?'
  462. ;
  463. FILLQ:
  464.     MVI    B,11        ;NUMBER OF CHARS IN FN & FT
  465.     MVI    A,'?'        ;STORE '?'
  466. FILLP:
  467.     MOV    M,A        ;STORE BYTE
  468.     INX    H        ;PT TO NEXT
  469.     DJNZ    FILLP        ;COUNT DOWN
  470.     RET
  471. ;
  472. ; LOAD DIRECTORY AND SORT IT
  473. ;   ON INPUT, A=SYSTST FLAG (0=SYS, 1=DIR, 80H=BOTH)
  474. ;   DIRECTORY IS LOADED INTO DIRBUF
  475. ;   RETURN WITH ZERO SET IF NO MATCH AND HL PTS TO 1ST ENTRY IF MATCH
  476. ;
  477. GETDIR:
  478.     STA    SYSTST    ; SET SYSTEM TEST FLAG
  479.     CALL    LOGUSR    ; LOG INTO USER AREA OF FCB1
  480.     LXI    H,DIRBUF    ; PT TO DIR BUFFER
  481.     MVI    M,0    ; SET EMPTY
  482.     LXI    B,0    ; SET COUNTER
  483.     CALL    SEARF    ; LOOK FOR MATCH
  484.     RZ        ; RETURN IF NOT FOUND
  485. ;
  486. ;  STEP 1:  LOAD DIRECTORY
  487. ;
  488. GD1:
  489.     PUSH    B    ; SAVE COUNTER
  490.     CALL    GETSBIT    ; CHECK FOR SYSTEM OK
  491.     POP    B
  492.     JRZ    GD2    ; NOT OK, SO SKIP
  493.     PUSH    B    ; SAVE COUNTER
  494.     INX    D    ; PT TO FILE NAME
  495.     XCHG        ; HL PTS TO FILE NAME, DE PTS TO BUFFER
  496.     MVI    B,11    ; COPY 11 BYTES
  497.     CALL    LDIR    ; DO COPY
  498.     XCHG        ; HL PTS TO NEXT BUFFER LOCATION
  499.     POP    B    ; GET COUNTER
  500.     INX    B    ; INCREMENT COUNTER
  501. GD2:
  502.     CALL    SEARN    ; LOOK FOR NEXT
  503.     JRNZ    GD1
  504.     MVI    M,0    ; STORE ENDING 0
  505.     LXI    H,DIRBUF    ; PT TO DIR BUFFER
  506.     MOV    A,M    ; CHECK FOR EMPTY
  507.     ORA    A
  508.     RZ
  509. ;
  510. ;  STEP 2:  SORT DIRECTORY
  511. ;
  512.     PUSH    H    ; SAVE PTR TO DIRBUF FOR RETURN
  513.     CALL    DIRALPHA    ; SORT
  514.     POP    H
  515.     XRA    A    ; SET NZ FLAG FOR OK
  516.     DCR    A
  517.     RET
  518.  
  519. ;*
  520. ;*  DIRALPHA -- ALPHABETIZES DIRECTORY IN DIRBUF; BC CONTAINS
  521. ;*    THE NUMBER OF FILES IN THE DIRECTORY
  522. ;*
  523. DIRALPHA:
  524.     MOV    A,B    ; ANY FILES?
  525.     ORA    C
  526.     RZ
  527.     MOV    H,B    ; HL=BC=FILE COUNT
  528.     MOV    L,C
  529.     SHLD    N    ; SET "N"
  530. ;*
  531. ;*  SHELL SORT --
  532. ;*    THIS SORT ROUTINE IS ADAPTED FROM "SOFTWARE TOOLS"
  533. ;*    BY KERNIGAN AND PLAUGHER, PAGE 106.  COPYRIGHT, 1976, ADDISON-WESLEY.
  534. ;*  ON ENTRY, BC=NUMBER OF ENTRIES
  535. ;*
  536. N    EQU    $+1    ; POINTER FOR IN-THE-CODE MODIFICATION
  537.     LXI    H,0    ; NUMBER OF ITEMS TO SORT
  538.     SHLD    GAP    ; SET INITIAL GAP TO N FOR FIRST DIVISION BY 2
  539.  
  540. ;*  FOR (GAP = N/2; GAP > 0; GAP = GAP/2)
  541. SRTL0:
  542.     ORA    A    ; CLEAR CARRY
  543. GAP    EQU    $+1    ; POINTER FOR IN-THE-CODE MODIFICATION
  544.     LXI    H,0    ; GET PREVIOUS GAP
  545.     MOV    A,H    ; ROTATE RIGHT TO DIVIDE BY 2
  546.     RAR
  547.     MOV    H,A
  548.     MOV    A,L
  549.     RAR
  550.     MOV    L,A
  551.  
  552. ;*  TEST FOR ZERO
  553.     ORA    H
  554.     RZ        ; DONE WITH SORT IF GAP = 0
  555.  
  556.     SHLD    GAP    ; SET VALUE OF GAP
  557.     SHLD    I    ; SET I=GAP FOR FOLLOWING LOOP
  558.  
  559. ;*  FOR (I = GAP + 1; I <= N; I = I + 1)
  560. SRTL1:
  561. I    EQU    $+1    ; POINTER FOR IN-THE-CODE MODIFICATION
  562.     LXI    H,0    ; ADD 1 TO I
  563.     INX    H
  564.     SHLD    I
  565.  
  566. ;*  TEST FOR I <= N
  567.     XCHG        ; I IS IN DE
  568.     LHLD    N    ; GET N
  569.     MOV    A,L    ; COMPARE BY SUBTRACTION
  570.     SUB    E
  571.     MOV    A,H
  572.     SBB    D    ; CARRY SET MEANS I > N
  573.     JRC    SRTL0    ; DON'T DO FOR LOOP IF I > N
  574.  
  575.     LHLD    I    ; SET J = I INITIALLY FOR FIRST SUBTRACTION OF GAP
  576.     SHLD    J
  577.  
  578. ;*  FOR (J = I - GAP; J > 0; J = J - GAP)
  579. SRTL2:
  580.     LHLD    GAP    ; GET GAP
  581.     XCHG        ; ... IN DE
  582. J    EQU    $+1    ; POINTER FOR IN-THE-CODE MODIFICATION
  583.     LXI    H,0    ; GET J
  584.     MOV    A,L    ; COMPUTE J - GAP
  585.     SUB    E
  586.     MOV    L,A
  587.     MOV    A,H
  588.     SBB    D
  589.     MOV    H,A
  590.     SHLD    J    ; J = J - GAP
  591.     JRC    SRTL1    ; IF CARRY FROM SUBTRACTIONS, J < 0 AND ABORT
  592.     MOV    A,H    ; J=0?
  593.     ORA    L
  594.     JRZ    SRTL1    ; IF ZERO, J=0 AND ABORT
  595.  
  596. ;*  SET JG = J + GAP
  597.     XCHG        ; J IN DE
  598.     LHLD    GAP    ; GET GAP
  599.     DAD    D    ; J + GAP
  600.     SHLD    JG    ; JG = J + GAP
  601.  
  602. ;*  IF (V(J) <= V(JG))
  603.     CALL    ICOMPARE    ; J IN DE, JG IN HL
  604.  
  605. ;*  ... THEN BREAK
  606.     JRC    SRTL1
  607.  
  608. ;*  ... ELSE EXCHANGE
  609.     LHLD    J    ; SWAP J, JG
  610.     XCHG
  611. JG    EQU    $+1    ; POINTER FOR IN-THE-CODE MODIFICATION
  612.     LXI    H,0
  613.     CALL    ISWAP    ; J IN DE, JG IN HL
  614.  
  615. ;*  END OF INNER-MOST FOR LOOP
  616.     JR    SRTL2
  617.  
  618. ;*
  619. ;*  SWAP (Exchange) the elements whose indexes are in HL and DE
  620. ;*
  621. ISWAP:
  622.     CALL    IPOS        ; COMPUTE POSITION FROM INDEX
  623.     XCHG
  624.     CALL    IPOS        ; COMPUTE 2ND ELEMENT POSITION FROM INDEX
  625.     MVI    B,11        ; 11 BYTES TO FLIP
  626. ISWAP1:
  627.     LDAX    D        ; GET BYTES
  628.     MOV    C,M
  629.     MOV    M,A        ; PUT BYTES
  630.     MOV    A,C
  631.     STAX    D
  632.     INX    H        ; PT TO NEXT
  633.     INX    D
  634.     DJNZ    ISWAP1
  635.     RET
  636. ;*
  637. ;*  ICOMPARE compares the entry pointed to by the pointer pointed to by HL
  638. ;*    with that pointed to by DE (1st level indirect addressing); on entry,
  639. ;*    HL and DE contain the numbers of the elements to compare (1, 2, ...);
  640. ;*    on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)),
  641. ;*    and Non-Zero and No-Carry means ((DE)) > ((HL))
  642. ;*
  643. ICOMPARE:
  644.     CALL    IPOS        ; GET POSITION OF FIRST ELEMENT
  645.     XCHG
  646.     CALL    IPOS        ; GET POSITION OF 2ND ELEMENT
  647.     XCHG
  648. ;*
  649. ;*  COMPARE DIR ENTRY PTED TO BY HL WITH THAT PTED TO BY DE;
  650. ;*    NO NET EFFECT ON HL, DE; RET W/CARRY SET MEANS DE<HL
  651. ;*    RET W/ZERO SET MEANS DE=HL
  652. ;*
  653.     IF    NOT SORTNT    ; TYPE AND NAME?
  654. ;*
  655. ;*  COMPARE BY FILE TYPE AND FILE NAME
  656. ;*
  657.     PUSH    H
  658.     PUSH    D
  659.     LXI    B,8    ; PT TO FT (8 BYTES)
  660.     DAD    B
  661.     XCHG
  662.     DAD    B
  663.     XCHG        ; DE, HL NOW PT TO THEIR FT'S
  664.     MVI    B,3    ; 3 BYTES
  665.     CALL    COMP    ; COMPARE FT'S
  666.     POP    D
  667.     POP    H
  668.     RNZ        ; CONTINUE IF COMPLETE MATCH
  669.     MVI    B,8    ; 8 BYTES
  670.     JR    COMP    ; COMPARE FN'S
  671. ;
  672.     ELSE        ; NAME AND TYPE
  673. ;*
  674. ;*  COMPARE BY FILE NAME AND FILE TYPE
  675. ;*
  676.     MVI    B,11    ; COMPARE FN, FT AND FALL THRU TO COMP
  677. ;*
  678. ;*  COMP COMPARES DE W/HL FOR B BYTES; RET W/CARRY IF DE<HL
  679. ;*    MSB IS DISREGARDED
  680. ;*
  681. COMP:
  682.     MOV    A,M    ; GET (HL)
  683.     ANI    7FH    ; MASK MSB
  684.     MOV    C,A    ; ... IN C
  685.     LDAX    D    ; COMPARE
  686.     ANI    7FH    ; MASK MSB
  687.     CMP    C
  688.     RNZ
  689.     INX    H    ; PT TO NEXT
  690.     INX    D
  691.     DJNZ    COMP    ; COUNT DOWN
  692.     RET
  693. ;
  694.     ENDIF        ; NOT SORTNT
  695. ;*
  696. ;*  Compute physical position of element whose index is in HL; on exit, HL
  697. ;* is the physical address of this element; Indexes are 1..N
  698. ;*
  699. IPOS:
  700.     DCX    H        ; HL=(HL-1)*11+DIRBUF
  701.     MOV    B,H        ; BC=HL
  702.     MOV    C,L
  703.     DAD    H        ; HL=HL*2
  704.     DAD    H        ; HL=HL*4
  705.     DAD    B        ; HL=HL*5
  706.     DAD    H        ; HL=HL*10
  707.     DAD    B        ; HL=HL*11
  708.     LXI    B,DIRBUF    ; ADD IN DIRBUF
  709.     DAD    B
  710.     RET
  711. ;
  712.     ENDIF        ;DIRON OR ERAON OR LTON OR PROTON OR CPON OR RENON
  713. ;
  714. ;Section 5B
  715. ;Command: ERA
  716. ;Function:  Erase files
  717. ;Forms:
  718. ;    ERA <afn>    Erase Specified files and print their names
  719. ;    ERA <afn> I    Erase Specified files and print their names, but ask
  720. ;                for verification before Erase is done
  721. ;
  722.     IF    ERAON
  723. ERA:
  724. ;
  725. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  726. ;
  727.     IF    WERA
  728.     CALL    WHLTST
  729.     ENDIF        ;WHEEL APPROVAL
  730. ;
  731.     CALL    RETSAVE
  732.     LDA    FCB2+1        ;GET ERAFLG IF IT'S THERE
  733.     STA    ERAFLG        ;SAVE IT AS A FLAG
  734.     MVI    A,1        ;DIR FILES ONLY
  735.     CALL    GETDIR        ;LOAD DIRECTORY OF FILES
  736.     JZ    PRFNF        ;ABORT IF NO FILES
  737. ;
  738. ; MAIN ERASE LOOP
  739. ;
  740. ERA1:
  741.     PUSH    H        ;SAVE PTR TO FILE
  742.     CALL    PRFN        ;PRINT ITS NAME
  743.     SHLD    NXTFILE        ;SAVE PTR TO NEXT FILE
  744.     POP    H        ;GET PTR TO THIS FILE
  745.     CALL    ROTEST        ;TEST FILE PTED TO BY HL FOR R/O
  746.     JRNZ    ERA3
  747. ERAFLG    EQU    $+1        ;ADDRESS OF FLAG
  748.     MVI    A,0        ;2ND BYTE IS FLAG
  749.     CPI    'I'        ;IS IT AN INSPECT OPTION?
  750.     JRNZ    ERA2        ;SKIP PROMPT IF IT IS NOT
  751.     CALL    ERAQ        ;ERASE?
  752.     JRNZ    ERA3        ;SKIP IF NOT
  753. ERA2:
  754.     LXI    D,FCB1+1    ;COPY INTO FCB1
  755.     MVI    B,11        ;11 BYTES
  756.     CALL    LDIR
  757.     CALL    INITFCB1    ;INIT FCB
  758.     MVI    C,19        ;DELETE FILE
  759.     CALL    BDOS
  760. ERA3:
  761.     LHLD    NXTFILE        ;HL PTS TO NEXT FILE
  762.     MOV    A,M        ;GET CHAR
  763.     ORA    A        ;DONE?
  764.     JZ    EXIT
  765.     CALL    CRLF        ;NEW LINE
  766.     JR    ERA1
  767. ;
  768.     ENDIF        ;ERAON
  769. ;
  770. ;Section 5C
  771. ;Command: LIST
  772. ;Function:  Print out specified file on the LST: Device
  773. ;Forms:
  774. ;    LIST <afn>    Print file (NO Paging)
  775. ;Notes:
  776. ;    The flags which apply to TYPE do not take effect with LIST
  777. ;
  778.     IF    LTON
  779. LIST:
  780. ;
  781. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  782. ;
  783.     IF    WLIST
  784.     CALL    WHLTST
  785.     ENDIF        ;WHEEL APPROVAL
  786. ;
  787.     CALL    RETSAVE
  788.     MVI    A,0FFH        ;TURN ON PRINTER FLAG
  789.     JR    TYPE0
  790. ;
  791. ;Section 5D
  792. ;Command: TYPE
  793. ;Function:  Print out specified file on the CON: Device
  794. ;Forms:
  795. ;    TYPE <afn>    Print file
  796. ;    TYPE <afn> P    Print file with paging flag    
  797. ;Notes:
  798. ;    The flag PGDFLG defines the letter which toggles the paging
  799. ;        facility (P in the forms section above)
  800. ;    The flag PGDFLT determines if TYPE is to page by default
  801. ;        (PGDFLT=TRUE if TYPE pages by default); combined with
  802. ;        PGDFLG, the following events occur --
  803. ;            If PGDFLT = TRUE, PGDFLG turns OFF paging
  804. ;            If PGDFLT = FALSE, PGDFLG turns ON paging
  805. ;
  806. TYPE:
  807. ;
  808. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  809. ;
  810.     IF    WTYPE
  811.     CALL    WHLTST
  812.     ENDIF        ;WHEEL APPROVAL
  813. ;
  814.     CALL    RETSAVE
  815.     XRA    A        ;TURN OFF PRINTER FLAG
  816. ;
  817. ; ENTRY POINT FOR CPR LIST FUNCTION (LIST)
  818. ;
  819. TYPE0:
  820.     STA    PRFLG        ;SET FLAG
  821.     LDA    FCB2+1        ;GET PAGE FLAG
  822.     STA    PGFLG        ;SAVE IT AS A FLAG
  823.     MVI    A,1        ;SELECT DIR FILES
  824.     CALL    GETDIR        ;ALLOW AMBIGUOUS FILES
  825.     JZ    PRFNF        ;NO FILES
  826.     SHLD    NXTFILE        ;SET PTR TO NEXT FILE
  827.     JR    TYPEX2
  828. TYPEX:
  829.     LHLD    NXTFILE        ;GET PTR TO NEXT FILE
  830.     MOV    A,M        ;ANY FILES?
  831.     ORA    A
  832.     JZ    EXIT
  833.     LDA    PRFLG        ;CHECK FOR LIST OUTPUT
  834.     ORA    A        ;0=TYPE
  835.     JRZ    TYPEX1
  836.     MVI    A,CR        ;BOL ON PRINTER
  837.     CALL    LCOUT
  838.     MVI    A,FF        ;FORM FEED THE PRINTER
  839.     CALL    LCOUT
  840.     JR    TYPEX2
  841. TYPEX1:
  842.     CALL    PAGEBREAK    ;PAGE BREAK MESSAGE
  843. TYPEX2:
  844.     LXI    D,FCB1+1    ;COPY INTO FCB1
  845.     MVI    B,11        ;11 BYTES
  846.     CALL    LDIR
  847.     SHLD    NXTFILE        ;SET PTR TO NEXT FILE
  848.     CALL    INITFCB1    ;INIT FCB1
  849.     MVI    C,15        ;OPEN FILE
  850.     CALL    BDOS
  851.     INR    A        ;SET ERROR FLAG
  852.     JZ    PRFNF        ;ABORT IF ERROR
  853.     MVI    A,NLINES-2    ;SET LINE COUNT
  854.     STA    PAGCNT
  855.     MVI    A,CR        ;NEW LINE
  856.     CALL    LCOUT
  857.     MVI    A,LF
  858.     CALL    LCOUT
  859.     LXI    B,080H        ;SET CHAR POSITION AND TAB COUNT
  860.                 ;  (B=0=TAB, C=080H=CHAR POSITION)
  861. ;
  862. ;  MAIN LOOP FOR LOADING NEXT BLOCK
  863. ;
  864. TYPE2:
  865.     MOV    A,C        ;GET CHAR COUNT
  866.     CPI    80H
  867.     JRC    TYPE3
  868.     PUSH    H        ;READ NEXT BLOCK
  869.     PUSH    B
  870.     LXI    D,FCB1        ;PT TO FCB
  871.     MVI    C,20        ;READ RECORD
  872.     CALL    BDOS
  873.     ORA    A        ;SET FLAGS
  874.     POP    B
  875.     POP    H
  876.     JRNZ    TYPE7        ;END OF FILE?
  877.     MVI    C,0        ;SET CHAR COUNT
  878.     LXI    H,TBUFF        ;PT TO FIRST CHAR
  879. ;
  880. ;  MAIN LOOP FOR PRINTING CHARS IN TBUFF
  881. ;
  882. TYPE3:
  883.     MOV    A,M        ;GET NEXT CHAR
  884.     ANI    7FH        ;MASK OUT MSB
  885.     CPI    1AH        ;END OF FILE (^Z)?
  886.     JRZ    TYPE7        ;NEXT FILE IF SO
  887. ;
  888. ; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION
  889. ;
  890.     CPI    CR        ;RESET TAB COUNT?
  891.     JRZ    TYPE4
  892.     CPI    LF        ;RESET TAB COUNT?
  893.     JRZ    TYPE4
  894.     CPI    TAB        ;TAB?
  895.     JRZ    TYPE5
  896. ;
  897. ;  OUTPUT CHAR AND INCREMENT CHAR COUNT
  898. ;
  899.     CALL    LCOUT        ;OUTPUT CHAR
  900.     JZ    TYPEX        ;SKIP
  901.     INR    B        ;INCREMENT TAB COUNT
  902.     JR    TYPE6
  903. ;
  904. ;  OUTPUT <CR> OR <LF> AND RESET TAB COUNT
  905. ;
  906. TYPE4:
  907.     CALL    LCOUT        ;OUTPUT <CR> OR <LF>
  908.     JZ    TYPEX        ;SKIP
  909.     MVI    B,0        ;RESET TAB COUNTER
  910.     JR    TYPE6
  911. ;
  912. ;  TABULATE
  913. ;
  914. TYPE5:
  915.     MVI    A,' '        ;<SP>
  916.     CALL    LCOUT
  917.     JZ    TYPEX        ;SKIP
  918.     INR    B        ;INCR POS COUNT
  919.     MOV    A,B
  920.     ANI    7
  921.     JRNZ    TYPE5
  922. ;
  923. ; CONTINUE PROCESSING
  924. ;
  925. TYPE6:
  926.     INR    C        ;INCREMENT CHAR COUNT
  927.     INX    H        ;PT TO NEXT CHAR
  928.     CALL    BREAK        ;CHECK FOR ABORT
  929.     JZ    TYPEX        ;SKIP
  930.     JR    TYPE2
  931. TYPE7:
  932.     LXI    D,FCB1        ;CLOSE FILE
  933.     MVI    C,16        ;BDOS FUNCTION
  934.     CALL    BDOS
  935.     JMP    TYPEX
  936. ;
  937. ; SEND OUTPUT TO LST: OR CON:, AS PER THE FLAG
  938. ;   RETURN WITH Z IF ABORT
  939. ;
  940. LCOUT:
  941.     PUSH    H        ;SAVE REGS
  942.     PUSH    D
  943.     PUSH    B
  944.     MOV    E,A        ;CHAR IN E
  945.     MVI    C,2        ;OUTPUT TO CON:
  946. PRFLG    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  947.     MVI    A,0        ;2ND BYTE IS THE PRINT FLAG
  948.     ORA    A        ;0=TYPE
  949.     JRZ    LC1
  950.     MVI    C,5        ;OUTPUT TO LST:
  951. LC1:
  952.     PUSH    D        ;SAVE CHAR
  953.     CALL    BDOS        ;OUTPUT CHAR IN E
  954.     POP    D        ;GET CHAR
  955.     MOV    A,E
  956.     CPI    LF
  957.     JRNZ    LC2
  958.     LDA    PRFLG        ;OUTPUT TO LST:?
  959.     ORA    A        ;NZ = YES
  960.     JRNZ    LC2
  961. ;
  962. ; CHECK FOR PAGING
  963. ;
  964.     LXI    H,PAGCNT    ;COUNT DOWN
  965.     DCR    M
  966.     JRNZ    LC2        ;JUMP IF NOT END OF PAUSE
  967.     MVI    M,NLINES-2    ;REFILL COUNTER
  968. PGFLG    EQU    $+1        ;POINTER TO IN-THE-CODE BUFFER
  969.     MVI    A,0        ;2ND BYTE IS THE PAGING FLAG
  970.     CPI    PGDFLG        ;PAGE DEFAULT OVERRIDE OPTION WANTED?
  971. ;
  972.     IF    PGDFLT        ;IF PAGING IS DEFAULT
  973. ;
  974.     JRZ    LC2        ;PGDFLG MEANS NO PAGING
  975. ;
  976.     ELSE
  977. ;
  978.     JRNZ    LC2        ;PGDFLG MEANS PAGE
  979. ;
  980.     ENDIF        ;PGDFLT
  981. ;
  982.     CALL    PAGEBREAK    ;PRINT PAGE BREAK MESSAGE
  983.     JR    LC3        ;Z TO SKIP
  984. LC2:
  985.     XRA    A        ;SET OK
  986.     DCR    A        ;NZ=OK
  987. LC3:
  988.     POP    B        ;RESTORE REGS
  989.     POP    D
  990.     POP    H
  991.     RET
  992. ;
  993. ; PRINT PAGE BREAK MESSAGE AND GET USER INPUT
  994. ;   ABORT IF ^C, RZ IF ^X
  995. ;
  996. PAGEBREAK:
  997.     PUSH    H        ;SAVE HL
  998.     CALL    PRINT
  999.     DB    cr,lf,' Typing',' '+80H
  1000.     LXI    H,FCB1+1    ;PRINT FILE NAME
  1001.     CALL    PRFN
  1002.     CALL    DASH        ;PRINT DASH
  1003.     CALL    CONIN        ;GET INPUT
  1004.     POP    H        ;RESTORE HL
  1005.     PUSH    PSW
  1006.     CALL    CRLF        ;NEW LINE
  1007.     POP    PSW
  1008.     CPI    CTRLC        ;^C
  1009.     JZ    EXIT
  1010.     CPI    CTRLX        ;SKIP?
  1011.     RET
  1012. ;
  1013.     ENDIF        ;LTON
  1014. ;
  1015. ;Section 5E
  1016. ;Command: REN
  1017. ;Function:  To change the name of an existing file
  1018. ;Forms:
  1019. ;    REN <New ufn>=<Old ufn>    Perform function
  1020. ;
  1021.     IF    RENON
  1022. REN:
  1023. ;
  1024. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  1025. ;
  1026.     IF    WREN
  1027.     CALL    WHLTST
  1028.     ENDIF        ;WHEEL APPROVAL
  1029. ;
  1030.     CALL    RETSAVE
  1031. ;
  1032. ;
  1033. ; STEP 1:  CHECK FOR FILE 2 BEING AMBIGUOUS
  1034. ;
  1035.     LXI    H,FCB2+1    ;CAN'T BE AMBIGUOUS
  1036.     CALL    AMBCHK1
  1037. ;
  1038. ; STEP 2:  LOG INTO USER AREA
  1039. ;
  1040.     CALL    LOGUSR        ;LOG INTO USER AREA OF FCB1
  1041. ;
  1042. ; STEP 3:  SEE IF NEW FILE ALREADY EXISTS
  1043. ;   EXTEST PERFORMS A NUMBER OF CHECKS:
  1044. ;     1) AMBIGUITY
  1045. ;     2) R/O
  1046. ;     3) IF FILE EXISTS AND NOT R/O, PERMISSION TO DELETE
  1047. ;
  1048.     CALL    EXTEST
  1049.     JZ    EXIT        ;R/O OR NO PERMISSION
  1050. ;
  1051. ; STEP 4:  EXCHANGE FILE NAME FIELDS FOR RENAME
  1052. ;
  1053.     LXI    H,FCB1        ;EXCHANGE NAMES ONLY
  1054.     PUSH    H        ;SAVE PTR
  1055.     INX    H
  1056.     LXI    D,FCB2+1
  1057.     MVI    B,11        ;11 BYTES
  1058. REN1:
  1059.     LDAX    D        ;GET OLD
  1060.     MOV    C,A
  1061.     MOV    A,M
  1062.     STAX    D        ;PUT NEW
  1063.     MOV    M,C
  1064.     INX    H        ;PT TO NEXT
  1065.     INX    D
  1066.     DJNZ    REN1
  1067. ;
  1068. ; STEP 5:  SEE IF OLD FILE IS R/O
  1069. ;
  1070.     CALL    SEARF        ;LOOK FOR FILE
  1071.     JZ    PRFNF
  1072.     CALL    GETSBIT        ;GET PTR TO ENTRY IN TBUFF
  1073.     XCHG            ;HL PTS TO ENTRY
  1074.     INX    H        ;PT TO FN
  1075.     CALL    ROTEST        ;SEE IF FILE IS R/O
  1076.     JNZ    EXIT
  1077. ;
  1078. ; STEP 6:  RENAME THE FILE
  1079. ;
  1080.     POP    D        ;GET PTR TO FCB
  1081.     MVI    C,23        ;RENAME
  1082.     CALL    BDOS
  1083.     INR    A        ;SET ZERO FLAG IF ERROR
  1084.     JZ    PRFNF        ;PRINT NO SOURCE FILE MESSAGE
  1085.     JMP    EXIT
  1086. ;
  1087.     ENDIF        ;RENON
  1088. ;
  1089. ;Section 5F
  1090. ;Command: PROT
  1091. ;Function:  To set the attributes of a file (R/O and SYS)
  1092. ;
  1093. ;Form:
  1094. ;    PROT afn RSI
  1095. ;If either R or S are omitted, the file is made R/W or DIR, resp;
  1096. ;R and S may be in any order.  If I is present, Inspection is enabled.
  1097. ;
  1098.     IF    PROTON
  1099. ATT:
  1100. ;
  1101. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  1102. ;
  1103.     IF    WPROT
  1104.     CALL    WHLTST
  1105.     ENDIF        ;WHEEL APPROVAL
  1106. ;
  1107.     CALL    RETSAVE
  1108.     XRA    A        ;SET NO INSPECT
  1109.     STA    INSPECT
  1110.     LXI    H,0        ;SET R/O AND SYS ATTRIBUTES OFF
  1111.     LXI    D,FCB2+1    ;PT TO ATTRIBUTES
  1112.     MVI    B,3        ;3 CHARS MAX
  1113. ATT1:
  1114.     LDAX    D        ;GET CHAR
  1115.     INX    D        ;PT TO NEXT
  1116.     CPI    'I'        ;INSPECT?
  1117.     JRZ    ATTI
  1118.     CPI    'R'        ;SET R/O?
  1119.     JRZ    ATTR
  1120.     CPI    'S'        ;SET SYS?
  1121.     JRZ    ATTS
  1122. ATT2:
  1123.     DJNZ    ATT1
  1124.     JR    ATT3
  1125. ATTI:
  1126.     STA    INSPECT        ;SET FLAG
  1127.     JR    ATT2
  1128. ATTR:
  1129.     MVI    H,80H        ;SET R/O BIT
  1130.     JR    ATT2
  1131. ATTS:
  1132.     MVI    L,80H        ;SET SYS BIT
  1133.     JR    ATT2
  1134. ATT3:
  1135.     SHLD    FATT        ;SAVE FILE ATTRIBUTES
  1136.     MVI    A,1        ;SELECT DIR AND SYS FILES
  1137.     CALL    GETDIR        ;LOAD DIRECTORY
  1138.     JZ    PRFNF        ;NO FILE ERROR
  1139.     SHLD    NXTFILE        ;PT TO NEXT FILE
  1140.     JR    ATT5
  1141. ATT4:
  1142.     LHLD    NXTFILE        ;PT TO NEXT FILE
  1143.     MOV    A,M        ;END OF LIST?
  1144.     ORA    A
  1145.     JZ    EXIT
  1146.     CALL    CRLF        ;NEW LINE
  1147. ATT5:
  1148.     PUSH    H        ;SAVE PTR TO CURRENT FILE
  1149.     CALL    PRFN        ;PRINT ITS NAME
  1150.     SHLD    NXTFILE        ;SAVE PTR TO NEXT FILE
  1151.     CALL    PRINT
  1152.     DB    ' Set to R','/'+80H
  1153.     LHLD    FATT        ;GET ATTRIBUTES
  1154.     MVI    C,'W'        ;ASSUME R/W
  1155.     MOV    A,H        ;GET R/O BIT
  1156.     ORA    A
  1157.     JRZ    ATT6
  1158.     MVI    C,'O'        ;SET R/O
  1159. ATT6:
  1160.     MOV    A,C        ;GET CHAR
  1161.     CALL    CONOUT
  1162.     MOV    A,L        ;GET SYS FLAG
  1163.     ORA    A        ;SET FLAG
  1164.     JRZ    ATT7
  1165.     CALL    PRINT
  1166.     DB    ' and SY','S'+80H
  1167. ATT7:
  1168. INSPECT    EQU    $+1        ;PTR FOR IN-THE-CODE MODIFICATION
  1169.     MVI    A,0        ;GET INSPECT FLAG
  1170.     ORA    A        ;Z=NO
  1171.     POP    H        ;GET PTR TO CURRENT FILE
  1172.     JRZ    ATT8
  1173.     CALL    ERAQ1        ;ASK FOR Y/N
  1174.     JRNZ    ATT4        ;ADVANCE TO NEXT FILE IF NOT Y
  1175. ATT8:
  1176.     LXI    D,FCB1+1    ;COPY INTO FCB1
  1177.     MVI    B,11        ;11 BYTES
  1178.     CALL    LDIR
  1179. FATT    EQU    $+1        ;PTR FOR IN-THE-CODE MODIFICATION
  1180.     LXI    H,0        ;GET ATTRIBUTES
  1181.     DCX    D        ;PT TO SYS BYTE
  1182.     DCX    D
  1183.     MOV    A,L        ;GET SYS FLAG
  1184.     CALL    ATTSET        ;SET ATTRIBUTE CORRECTLY
  1185.     DCX    D        ;PT TO R/O BYTE
  1186.     MOV    A,H        ;GET R/O FLAG
  1187.     CALL    ATTSET
  1188.     LXI    D,FCB1        ;PT TO FCB
  1189.     MVI    C,30        ;SET ATTRIBUTES
  1190.     CALL    BDOS
  1191.     JR    ATT4
  1192. ATTSET:
  1193.     ORA    A        ;0=CLEAR ATTRIBUTE
  1194.     JRZ    ATTST1
  1195.     LDAX    D        ;GET BYTE
  1196.     ORI    80H        ;SET ATTRIBUTE
  1197.     STAX    D
  1198.     RET
  1199. ATTST1:
  1200.     LDAX    D        ;GET BYTE
  1201.     ANI    7FH        ;CLEAR ATTRIBUTE
  1202.     STAX    D
  1203.     RET
  1204. ;
  1205.     ENDIF        ;PROTON
  1206. ;
  1207. ;Section 5G
  1208. ;Command: CP
  1209. ;Function:  To copy a file from one place to another
  1210. ;
  1211. ;Form:
  1212. ;    CP new=old
  1213. ;
  1214.     IF    CPON
  1215. COPY:
  1216. ;
  1217. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  1218. ;
  1219.     IF    WCP
  1220.     CALL    WHLTST
  1221.     ENDIF        ;WHEEL APPROVAL
  1222. ;
  1223.     CALL    RETSAVE
  1224. ;
  1225. ; STEP 0:  IF NEW IS BLANK, MAKE IT THE SAME NAME AND TYPE AS OLD
  1226. ;
  1227.     LXI    D,FCB1+1    ;PT TO NEW FILE NAME
  1228.     LDAX    D        ;GET FIRST CHAR
  1229.     CPI    ' '        ;NO NAME?
  1230.     JRNZ    COPY0
  1231.     LXI    H,FCB2+1    ;MAKE SAME AS OLD
  1232.     MVI    B,11        ;11 BYTES
  1233.     CALL    LDIR
  1234. ;
  1235. ; STEP 1:  SEE IF NEW=OLD AND ABORT IF SO
  1236. ;
  1237. COPY0:
  1238.     LXI    H,FCB1        ;PT TO NEXT
  1239.     LXI    D,FCB2        ;PT TO OLD
  1240.     PUSH    H        ;SAVE PTRS
  1241.     PUSH    D
  1242.     INX    H        ;PT TO FILE NAME
  1243.     INX    D
  1244.     MVI    B,13        ;COMPARE 13 BYTES
  1245. COPY1:
  1246.     LDAX    D        ;GET OLD
  1247.     CMP    M        ;COMPARE TO NEW
  1248.     JRNZ    COPY2
  1249.     INX    H        ;PT TO NEXT
  1250.     INX    D
  1251.     DJNZ    COPY1
  1252.     MVI    C,25        ;GET CURRENT DISK
  1253.     CALL    BDOS
  1254.     INR    A        ;MAKE 1..P
  1255.     MOV    B,A        ;CURRENT DISK IN B
  1256.     POP    D        ;GET PTR TO DN
  1257.     POP    H
  1258.     LDAX    D        ;GET DISK
  1259.     MOV    C,A        ;... IN C
  1260.     ORA    A        ;CURRENT?
  1261.     JRNZ    COPY1A
  1262.     MOV    C,B        ;MAKE C CURRENT
  1263. COPY1A:
  1264.     MOV    A,M        ;GET DISK
  1265.     ORA    A        ;CURRENT?
  1266.     JRNZ    COPY1B
  1267.     MOV    A,B        ;MAKE A CURRENT
  1268. COPY1B:
  1269.     CMP    C        ;SAME DISK ALSO?
  1270.     JRNZ    COPY3        ;CONTINUE WITH OPERATION
  1271.     JR    CPERR
  1272. COPY2:
  1273.     POP    D        ;GET PTRS
  1274.     POP    H
  1275. ;
  1276. ; STEP 2:  SET USER NUMBERS
  1277. ;
  1278. COPY3:
  1279.     LDA    FCB1+13        ;GET NEW USER
  1280.     STA    USRNEW
  1281.     LDA    FCB2+13        ;GET OLD USER
  1282.     STA    USROLD
  1283. ;
  1284. ; STEP 3:  SEE IF OLD FILE EXISTS
  1285. ;
  1286.     LXI    H,OLDFCB    ;COPY OLD INTO 2ND FCB
  1287.     PUSH    H        ;SAVE PTR TO 2ND FCB
  1288.     XCHG
  1289.     MVI    B,14        ;14 BYTES
  1290.     CALL    LDIR
  1291.     CALL    LOGOLD        ;LOG IN USER NUMBER OF OLD FCB
  1292.     POP    H        ;GET PTR TO 2ND FCB
  1293.     CALL    INITFCB2    ;INIT FCB
  1294.     MVI    C,17        ;LOOK FOR FILE
  1295.     CALL    BDOS
  1296.     INR    A        ;CHECK FOR ERROR
  1297.     JZ    PRFNF        ;FILE NOT FOUND
  1298. ;
  1299. ; STEP 4:  SEE IF NEW EXISTS
  1300. ;
  1301.     CALL    LOGNEW        ;LOG INTO NEW'S USER AREA
  1302.     CALL    EXTEST        ;TEST
  1303.     JZ    EXIT        ;ERROR EXIT
  1304. ;
  1305. ; STEP 5:  CREATE NEW
  1306. ;
  1307.     LXI    D,FCB1        ;PT TO FCB
  1308.     MVI    C,22        ;MAKE FILE
  1309.     CALL    BDOS
  1310.     INR    A        ;ERROR?
  1311.     JRNZ    COPY4
  1312. ;
  1313. ; COPY ERROR
  1314. ;
  1315. CPERR:
  1316.     CALL    PRINT
  1317.     DB    ' Copy','?'+80H
  1318.     JMP    EXIT
  1319. ;
  1320. ; STEP 6:  OPEN OLD
  1321. ;
  1322. COPY4:
  1323.     CALL    LOGOLD        ;GET USER
  1324.     LXI    H,OLDFCB    ;PT TO FCB
  1325.     CALL    INITFCB2    ;INIT FCB
  1326.     MVI    C,15        ;OPEN FILE
  1327.     CALL    BDOS
  1328. ;
  1329. ; STEP 7:  COPY OLD TO NEW WITH BUFFERING
  1330. ;
  1331. COPY5:
  1332.     CALL    LOGOLD        ;GET USER
  1333.     MVI    B,0        ;SET COUNTER
  1334.     LXI    H,TPA        ;SET NEXT ADDRESS TO COPY INTO
  1335. COPY5A:
  1336.     PUSH    H        ;SAVE ADDRESS AND COUNTER
  1337.     PUSH    B
  1338.     LXI    D,OLDFCB    ;READ BLOCK FROM FILE
  1339.     MVI    C,20
  1340.     CALL    BDOS
  1341.     POP    B        ;GET COUNTER AND ADDRESS
  1342.     POP    D
  1343.     ORA    A        ;OK?
  1344.     JRNZ    COPY5B
  1345.     PUSH    B        ;SAVE COUNTER
  1346.     LXI    H,TBUFF        ;COPY FROM BUFFER
  1347.     MVI    B,128        ;128 BYTES
  1348.     CALL    LDIR
  1349.     XCHG            ;HL PTS TO NEXT
  1350.     POP    B        ;GET COUNTER
  1351.     INR    B        ;INCREMENT IT
  1352.     MOV    A,B        ;DONE?
  1353.     CPI    CPBLOCKS    ;DONE IF CPBLOCKS LOADED
  1354.     JRNZ    COPY5A
  1355. COPY5B:
  1356.     MOV    A,B        ;GET COUNT
  1357.     ORA    A
  1358.     JRZ    COPY6        ;DONE IF NOTHING LOADED
  1359.     PUSH    B        ;SAVE COUNT
  1360.     CALL    LOGNEW        ;GET USER
  1361.     LXI    H,TPA        ;PT TO TPA
  1362. COPY5C:
  1363.     LXI    D,TBUFF        ;COPY INTO TBUFF
  1364.     MVI    B,128        ;128 BYTES
  1365.     CALL    LDIR
  1366.     PUSH    H        ;SAVE PTR TO NEXT
  1367.     LXI    D,FCB1        ;PT TO FCB
  1368.     MVI    C,21        ;WRITE BLOCK
  1369.     CALL    BDOS
  1370.     ORA    A
  1371.     JRNZ    CPERR        ;COPY ERROR
  1372.     POP    H        ;GET PTR TO NEXT BLOCK
  1373.     POP    B        ;GET COUNT
  1374.     DCR    B        ;COUNT DOWN
  1375.     JRZ    COPY5        ;GET NEXT
  1376.     PUSH    B        ;SAVE COUNT
  1377.     JR    COPY5C
  1378. ;
  1379. ; STEP 8:  CLOSE FILES
  1380. ;
  1381. COPY6:
  1382.     CALL    LOGOLD        ;GET USER
  1383.     LXI    D,OLDFCB    ;PT TO FCB
  1384.     MVI    C,16        ;CLOSE FILE
  1385.     CALL    BDOS
  1386.     CALL    LOGNEW        ;GET USER
  1387.     LXI    D,FCB1        ;PT TO FCB
  1388.     MVI    C,16        ;CLOSE FILE
  1389.     CALL    BDOS
  1390.     CALL    PRINT
  1391.     DB    ' Don','e'+80H
  1392.     JMP    EXIT
  1393. ;
  1394. ; LOG INTO USER NUMBER OF OLD FILE
  1395. ;
  1396. LOGOLD:
  1397. USROLD    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1398.     MVI    A,0        ;GET NUMBER
  1399.     JMP    SETUSR
  1400. ;
  1401. ; LOG INTO USER NUMBER OF NEW FILE
  1402. ;
  1403. LOGNEW:
  1404. USRNEW    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1405.     MVI    A,0        ;GET NUMBER
  1406.     JMP    SETUSR
  1407. ;
  1408.     ENDIF        ;CPON
  1409. ;
  1410. ;Section 5H
  1411. ;Command: PEEK
  1412. ;Function:  Display memory
  1413. ;
  1414. ;Form:
  1415. ;    PEEK startadr        - 256 bytes displayed
  1416. ;    PEEK startadr endadr    - range of bytes displayed
  1417. ;
  1418.     IF    PEEKON
  1419. PEEK:
  1420. ;
  1421. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  1422. ;
  1423.     IF    WPEEK
  1424.     CALL    WHLTST
  1425.     ENDIF        ;WHEEL APPROVAL
  1426. ;
  1427.     CALL    RETSAVE
  1428.     LXI    H,TBUFF+1    ;FIND FIRST NUMBER
  1429. NXTPEEK    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1430.     LXI    D,0        ;DEFAULT PEEK ADDRESS IF NONE
  1431.     CALL    SKSP        ;SKIP TO NON-BLANK
  1432.     CNZ    HEXNUM        ;GET START ADDRESS IF ANY (ELSE DEFAULT)
  1433.     CALL    PRINT
  1434.     DB    ' Pee','k'+80H
  1435.     CALL    ADRAT        ;PRINT ADDRESS MESSAGE
  1436.     PUSH    D        ;SAVE IT
  1437.     LXI    B,256        ;COMPUTE END ADDRESS
  1438.     XCHG
  1439.     DAD    B
  1440.     XCHG            ;END ADDRESS IN DE
  1441.     CALL    SKSP        ;SKIP TO NON-BLANK
  1442.     JRZ    PEEK1        ;PROCESS
  1443.     CALL    HEXNUM        ;GET 2ND NUMBER IN DE
  1444. PEEK1:
  1445.     POP    H        ;HL IS START ADDRESS, DE IS END ADDRESS
  1446.     CALL    PEEK2        ;DO PEEK
  1447.     SHLD    NXTPEEK        ;SET CONTINUED PEEK ADDRESS
  1448.     JMP    EXIT
  1449. ;
  1450. ; DISPLAY LOOP
  1451. ;
  1452. PEEK2:
  1453.     MOV    A,D        ;SEE IF DE<=HL
  1454.     CMP    H
  1455.     RC            ;OUT OF BOUNDS
  1456.     JRNZ    PEEK2A        ;HL > DE
  1457.     MOV    A,E
  1458.     CMP    L
  1459.     RZ
  1460.     RC
  1461. PEEK2A:
  1462.     CALL    CRLF        ;NEW LINE
  1463.     MOV    A,H        ;PRINT ADDRESS
  1464.     CALL    PASHC
  1465.     MOV    A,L
  1466.     CALL    PAHC
  1467.     CALL    DASH        ;PRINT LEADER
  1468.     MVI    B,16        ;16 BYTES TO DISPLAY
  1469.     PUSH    H        ;SAVE START ADDRESS
  1470. PEEK3:
  1471.     MOV    A,M        ;GET NEXT BYTE
  1472.     CALL    PASHC        ;PRINT WITH LEADING SPACE
  1473.     INX    H        ;PT TO NEXT
  1474.     DJNZ    PEEK3
  1475.     POP    H        ;PT TO FIRST
  1476.     MVI    B,16        ;16 BYTES
  1477.     MVI    A,' '        ;SPACE AND FENCE
  1478.     CALL    CONOUT
  1479.     CALL    PRINT
  1480.     DB    FENCE+80H
  1481. PEEK4:
  1482.     MOV    A,M        ;GET NEXT BYTE
  1483.     MVI    C,'.'        ;ASSUME DOT
  1484.     ANI    7FH        ;MASK IT
  1485.     CPI    ' '        ;DOT IF LESS THAN SPACE
  1486.     JRC    PEEK5
  1487.     CPI    7FH        ;DON'T PRINT DEL
  1488.     JRZ    PEEK5
  1489.     MOV    C,A        ;CHAR IN C
  1490. PEEK5:
  1491.     MOV    A,C        ;GET CHAR
  1492.     CALL    CONOUT        ;SEND IT
  1493.     INX    H        ;PT TO NEXT
  1494.     DJNZ    PEEK4
  1495.     CALL    PRINT        ;CLOSING FENCE
  1496.     DB    FENCE+80H
  1497.     CALL    BREAK        ;ALLOW ABORT
  1498.     JR    PEEK2
  1499. ;
  1500.     ENDIF        ;PEEKON
  1501. ;
  1502. ; PRINT A AS 2 HEX CHARS
  1503. ;   PASHC - LEADING SPACE
  1504. ;
  1505.     IF    PEEKON OR POKEON
  1506. PASHC:
  1507.     PUSH    PSW        ;SAVE A
  1508.     CALL    PRINT
  1509.     DB    ' '+80H
  1510.     POP    PSW
  1511. PAHC:
  1512.     PUSH    B        ;SAVE BC
  1513.     MOV    C,A        ;BYTE IN C
  1514.     RRC            ;EXCHANGE NYBBLES
  1515.     RRC
  1516.     RRC
  1517.     RRC
  1518.     CALL    PAH        ;PRINT HEX CHAR
  1519.     MOV    A,C        ;GET LOW
  1520.     POP    B        ;RESTORE BC AND FALL THRU TO PAH
  1521. PAH:
  1522.     ANI    0FH        ;MASK
  1523.     ADI    '0'        ;CONVERT TO ASCII
  1524.     CPI    '9'+1        ;LETTER?
  1525.     JRC    PAH1
  1526.     ADI    7        ;ADJUST TO LETTER
  1527. PAH1:
  1528.     JMP    CONOUT
  1529. ;
  1530.     ENDIF        ;PEEKON OR POKEON
  1531. ;
  1532. ;Section 5I
  1533. ;Command: POKE
  1534. ;Function:  Place Values into Memory
  1535. ;
  1536. ;Form:
  1537. ;    POKE startadr val1 val2 ...
  1538. ;
  1539.     IF    POKEON
  1540. POKE:
  1541. ;
  1542. ; CHECK FOR WHEEL APPROVAL IF OPTION ENABLED
  1543. ;
  1544.     IF    WPOKE
  1545.     CALL    WHLTST
  1546.     ENDIF        ;WHEEL APPROVAL
  1547. ;
  1548.     CALL    RETSAVE
  1549.     LXI    H,TBUFF+1    ;PT TO FIRST CHAR
  1550.     CALL    SKSP        ;SKIP TO NON-BLANK
  1551.     JRZ    NOARGS        ;ARG ERROR
  1552.     CALL    HEXNUM        ;CONVERT TO NUMBER
  1553.     CALL    PRINT
  1554.     DB    ' Pok','e'+80H
  1555.     CALL    ADRAT        ;PRINT AT MESSAGE
  1556. ;
  1557. ; LOOP FOR STORING HEX VALUES SEQUENTIALLY VIA POKE
  1558. ;
  1559. POKE1:
  1560.     PUSH    D        ;SAVE ADDRESS
  1561.     CALL    SKSP        ;SKIP TO NON-BLANK
  1562.     JZ    EXIT        ;DONE
  1563.     CPI    '"'        ;QUOTED TEXT?
  1564.     JRZ    POKE2
  1565.     CALL    HEXNUM        ;GET NUMBER
  1566.     MOV    A,E        ;GET LOW
  1567.     POP    D        ;GET ADDRESS
  1568.     STAX    D        ;STORE NUMBER
  1569.     INX    D        ;PT TO NEXT
  1570.     JR    POKE1
  1571. ;
  1572. ; STORE ASCII CHARS
  1573. ;
  1574. POKE2:
  1575.     POP    D        ;GET NEXT ADDRESS
  1576.     INX    H        ;PT TO NEXT CHAR
  1577. POKE3:
  1578.     MOV    A,M        ;GET NEXT CHAR
  1579.     ORA    A        ;DONE?
  1580.     JZ    EXIT
  1581.     STAX    D        ;PUT CHAR
  1582.     INX    H        ;PT TO NEXT
  1583.     INX    D
  1584.     JR    POKE3
  1585. ;
  1586. ; No Argument Error
  1587. ;
  1588. NOARGS:
  1589.     CALL    PRINT
  1590.     DB    ' Arg','?'+80H
  1591.     JMP    EXIT
  1592. ;
  1593.     ENDIF        ;POKEON
  1594. ;
  1595. ;Section 5J
  1596. ;Command: REG
  1597. ;Function:  Manipulate Memory Registers
  1598. ;
  1599. ;Forms:
  1600. ;    REG D or REG        <-- Display Register Value
  1601. ;    REG Mreg        <-- Decrement Register Value
  1602. ;    REG Preg        <-- Increment Register Value
  1603. ;    REG Sreg value        <-- Set Register Value
  1604. ;
  1605.     IF    REGON
  1606. REGCMD:
  1607.     LXI    H,FCB1+1    ;PT TO FIRST ARG
  1608.     MOV    A,M        ;GET FIRST CHAR
  1609.     PUSH    PSW        ;SAVE CHAR
  1610.     CPI    'A'        ;ASSUME DIGIT IF LESS THAN 'A'
  1611.     JRC    REGC1
  1612.     INX    H        ;PT TO DIGIT
  1613. REGC1:
  1614.     MOV    A,M        ;GET DIGIT
  1615.     CALL    REGPTR        ;PT TO REGISTER
  1616.     POP    PSW        ;GET CHAR
  1617.     CPI    'S'        ;SET?
  1618.     JRZ    RSET
  1619.     CPI    'P'        ;PLUS?
  1620.     JRZ    RINC
  1621.     CPI    'M'        ;MINUS?
  1622.     JRZ    RDEC
  1623. ;
  1624. ; SHOW REGISTER VALUES
  1625. ;
  1626. RSHOW:
  1627.     XRA    A        ;SELECT REGISTER 0
  1628.     MOV    B,A        ;COUNTER SET TO 0 IN B
  1629.     CALL    REGP2        ;HL PTS TO REGISTER 0
  1630. RSHOW1:
  1631.     MOV    A,B        ;GET COUNTER VALUE
  1632.     CPI    10
  1633.     JZ    CRLF        ;NEW LINE AND EXIT IF DONE
  1634.     CALL    PRINT
  1635.     DB    '  Reg',' '+80H
  1636.     MOV    A,B        ;PRINT REGISTER NUMBER
  1637.     ADI    '0'
  1638.     CALL    CONOUT
  1639.     CALL    PRINT
  1640.     DB    ' ','='+80H
  1641.     PUSH    B        ;SAVE COUNTER
  1642.     CALL    REGOUT        ;PRINT REGISTER VALUE
  1643.     POP    B        ;GET COUNTER
  1644.     INR    B        ;INCREMENT COUNTER
  1645.     MOV    A,B        ;CHECK FOR NEW LINE
  1646.     ANI    3
  1647.     CZ    CRLF
  1648.     INX    H        ;PT TO NEXT REGISTER
  1649.     JR    RSHOW1
  1650. ;
  1651. ; INCREMENT REGISTER VALUE
  1652. ;    HL PTS TO MEMORY REGISTER ON INPUT
  1653. ;
  1654. RINC:
  1655.     INR    M    ;INCREMENT IT
  1656.     JR    REGOUT    ;PRINT RESULT
  1657. ;
  1658. ; DECREMENT REGISTER VALUE
  1659. ;    HL PTS TO MEMORY REGISTER ON INPUT
  1660. ;
  1661. RDEC:
  1662.     DCR    M    ;DECREMENT VALUE
  1663.     JR    REGOUT    ;PRINT RESULT
  1664. ;
  1665. ; SET REGISTER VALUE
  1666. ;    HL PTS TO REGISTER ON INPUT
  1667. ;
  1668. RSET:
  1669.     LXI    D,FCB2+1    ;PT TO VALUE
  1670.     MVI    B,0    ;INIT VALUE TO ZERO
  1671. RSET1:
  1672.     LDAX    D    ;GET NEXT DIGIT
  1673.     INX    D    ;PT TO NEXT
  1674.     SUI    '0'    ;CONVERT TO BINARY
  1675.     JRC    RSET2
  1676.     CPI    10    ;RANGE?
  1677.     JRNC    RSET2
  1678.     MOV    C,A    ;DIGIT IN C
  1679.     MOV    A,B    ;MULTIPLY OLD BY 10
  1680.     ADD    A    ;*2
  1681.     ADD    A    ;*4
  1682.     ADD    B    ;*5
  1683.     ADD    A    ;*10
  1684.     ADD    C    ;ADD IN NEW DIGIT
  1685.     MOV    B,A    ;RESULT IN B
  1686.     JR    RSET1
  1687. RSET2:
  1688.     MOV    M,B    ;SET VALUE
  1689. REGOUT:
  1690.     CALL    PRINT    ;PRINT LEADING SPACE
  1691.     DB    ' '+80H
  1692.     MOV    A,M    ;GET REGISTER VALUE
  1693.     MVI    B,100    ;PRINT 100'S
  1694.     MVI    C,0    ;SET LEADING SPACE FLAG
  1695.     CALL    DECB    ;PRINT 100'S
  1696.     MVI    B,10    ;PRINT 10'S
  1697.     CALL    DECB    ;PRINT 10'S
  1698.     ADI    '0'    ;PRINT 1'S
  1699.     JMP    CONOUT
  1700. ;
  1701. ; SUBTRACT B FROM A UNTIL CARRY, THEN PRINT DIGIT COUNT
  1702. ;
  1703. DECB:
  1704.     MVI    D,'0'    ;SET DIGIT
  1705. DECB1:
  1706.     SUB    B    ;SUBTRACT
  1707.     JRC    DECB2
  1708.     INR    D    ;ADD 1 TO DIGIT CHAR
  1709.     JR    DECB1
  1710. DECB2:
  1711.     ADD    B    ;ADD BACK IN
  1712.     MOV    E,A    ;SAVE A IN E
  1713.     MOV    A,D    ;GET DIGIT CHAR
  1714.     CPI    '0'    ;LEADING ZERO CHECK
  1715.     JRNZ    DECB3
  1716.     MOV    A,C    ;ANY LEADING DIGIT YET?
  1717.     ORA    A
  1718.     JRZ    DECB4
  1719. DECB3:
  1720.     MOV    A,D    ;GET DIGIT CHAR
  1721.     CALL    CONOUT    ;PRINT IT
  1722.     INR    C    ;SET C<>0 FOR LEADING DIGIT CHECK
  1723. DECB4:
  1724.     MOV    A,E    ;RESTORE A FOR NEXT ROUND
  1725.     RET
  1726.  
  1727. ;
  1728. ; SET HL TO POINT TO MEMORY REGISTER WHOSE INDEX IS PTED TO BY HL
  1729. ;    ON INPUT, A CONTAINS REGISTER CHAR
  1730. ;    ON OUTPUT, HL = ADDRESS OF MEMORY REGISTER (REG 0 ASSUMED IF ERROR)
  1731. ;
  1732. REGPTR:
  1733.     MVI    B,0    ;INIT TO ZERO
  1734.     SUI    '0'    ;CONVERT
  1735.     JRC    REGP1
  1736.     CPI    10    ;RANGE
  1737.     JRNC    REGP1
  1738.     MOV    B,A    ;VALUE IN B
  1739. REGP1:
  1740.     MOV    A,B    ;VALUE IN A
  1741. REGP2:
  1742.     LXI    H,Z3MSG+30H    ;PT TO MEMORY REGISTERS
  1743.     ADD    L    ;PT TO PROPER REGISTER
  1744.     MOV    L,A
  1745.     MOV    A,H
  1746.     ACI    0
  1747.     MOV    H,A    ;HL PTS TO REGISTER
  1748.     RET
  1749. ;
  1750.     ENDIF        ;REGON
  1751.  
  1752. ;
  1753. ;Section 5K
  1754. ;Command: WHL/WHLQ
  1755. ;Function:  Set the Wheel Byte on or off
  1756. ;
  1757. ;Form:
  1758. ;    WHL        -- turn Wheel Byte OFF
  1759. ;    WHL password    -- turn Wheel Byte ON if password is correct
  1760. ;    WHLQ        -- find out status of Wheel Byte
  1761. ;
  1762.     IF    WHLON
  1763. WHL:
  1764.     LXI    H,FCB1+1    ;PT TO FIRST CHAR
  1765.     MOV    A,M    ;GET IT
  1766.     CPI    ' '    ;TURN BYTE OFF IF NO PASSWORD
  1767.     JRZ    WHLOFF
  1768.     LXI    D,WHLPASS
  1769.     MVI    B,8    ;CHECK 8 CHARS
  1770. WHL1:
  1771.     LDAX    D    ;GET CHAR
  1772.     CMP    M    ;COMPARE
  1773.     JRNZ    WHLMSG
  1774.     INX    H    ;PT TO NEXT
  1775.     INX    D
  1776.     DJNZ    WHL1
  1777. ;
  1778. ; TURN ON WHEEL BYTE
  1779. ;
  1780.     MVI    A,0FFH    ;TURN ON WHEEL BYTE
  1781.     JR    WHLSET
  1782. ;
  1783. ; TURN OFF WHEEL BYTE
  1784. ;
  1785. WHLOFF:
  1786.     XRA    A    ;TURN OFF WHEEL BYTE
  1787. WHLSET:
  1788.     STA    Z3WHL    ;SET WHEEL BYTE AND PRINT MESSAGE
  1789. ;
  1790. ; PRINT WHEEL BYTE MESSAGE
  1791. ;
  1792. WHLMSG:
  1793.     CALL    PRINT
  1794.     DB    ' Wheel Byte',' '+80H
  1795.     LDA    Z3WHL    ;GET WHEEL BYTE
  1796.     ORA    A    ;ZERO IS OFF
  1797.     JRZ    OFFM
  1798.     CALL    PRINT
  1799.     DB    'O','N'+80H
  1800.     RET
  1801. OFFM:
  1802.     CALL    PRINT
  1803.     DB    'OF','F'+80H
  1804.     RET
  1805. ;
  1806. ; WHEEL PASSWORD DEFINED FROM SYSRCP.LIB FILE
  1807. ;
  1808.     DB    'Z'-'@'    ;LEADING ^Z IN CASE OF TYPE
  1809. WHLPASS:
  1810.     WPASS        ;USE MACRO
  1811. ;
  1812.     ENDIF        ;WHLON
  1813.  
  1814. ;
  1815. ;Section 5L
  1816. ;Command: ECHO
  1817. ;Function:  Echo Text without Interpretation to Console or Printer
  1818. ;
  1819. ;Form:
  1820. ;    ECHO text        <-- echo text to console
  1821. ;    ECHO $text        <-- echo text to printer
  1822. ;
  1823. ;    Additionally, if a form feed character is encountered in the
  1824. ; output string, no further output will be done, a new line will be
  1825. ; issued, and this will be followed by a form feed character.  That is:
  1826. ;
  1827. ;        ECHO $text^L
  1828. ;
  1829. ; will cause "text" to be printed on the printer followed by CR, LF, FF.
  1830. ;
  1831. ECHO:
  1832.     LXI    H,TBUFF+1    ;PT TO FIRST CHAR
  1833. ECHO1:
  1834.     MOV    A,M        ;SKIP LEADING SPACES
  1835.     INX    H        ;PT TO NEXT
  1836.     CPI    ' '
  1837.     JRZ    ECHO1
  1838. ;
  1839.     IF    ECHOLST
  1840.     MOV    B,A        ;CHAR IN B
  1841.     CPI    '$'        ;PRINT FLAG?
  1842.     JRZ    ECHO2
  1843.     ENDIF        ;ECHOLST
  1844. ;
  1845.     DCX    H        ;PT TO CHAR
  1846. ;
  1847. ; LOOP TO ECHO CHARS
  1848. ;
  1849. ECHO2:
  1850.     MOV    A,M        ;GET CHAR
  1851.     ORA    A        ;EOL?
  1852.     JRZ    ECHO4
  1853. ;
  1854.     IF    ECHOLST
  1855.     CPI    FF        ;FORM FEED?
  1856.     JRZ    ECHO3
  1857.     ENDIF        ;ECHOLST
  1858. ;
  1859. ECHO2C:
  1860.     CALL    ECHOUT        ;SEND CHAR
  1861.     INX    H        ;PT TO NEXT
  1862.     JR    ECHO2
  1863. ;
  1864. ; FORM FEED - SEND NEW LINE FOLLOWED BY FORM FEED IF PRINTER OUTPUT
  1865. ;
  1866.     IF    ECHOLST
  1867. ECHO3:
  1868.     MOV    A,B        ;CHECK FOR PRINTER OUTPUT
  1869.     CPI    '$'
  1870.     JRNZ    ECHOFF        ;SEND FORM FEED NORMALLY IF NOT PRINTER
  1871.     CALL    ECHONL        ;SEND NEW LINE
  1872.     MVI    A,FF        ;SEND FORM FEED
  1873.     JR    ECHOUT
  1874. ;
  1875. ; SEND FORM FEED CHAR TO CONSOLE
  1876. ;
  1877. ECHOFF:
  1878.     MVI    A,FF        ;GET CHAR
  1879.     JR    ECHO2C
  1880.     ENDIF        ;ECHOLST
  1881. ;
  1882. ; END OF PRINT LOOP - CHECK FOR PRINTER TERMINATION
  1883. ;
  1884. ECHO4:
  1885.     IF    NOT ECHOLST
  1886. ;
  1887.     RET
  1888. ;
  1889.     ELSE
  1890. ;
  1891.     MOV    A,B        ;CHECK FOR PRINTER OUTPUT
  1892.     CPI    '$'
  1893.     RNZ            ;DONE IF NO PRINTER OUTPUT
  1894. ;
  1895. ; OUTPUT A NEW LINE
  1896. ;
  1897. ECHONL:
  1898.     MVI    A,CR        ;OUTPUT NEW LINE ON PRINTER
  1899.     CALL    ECHOUT
  1900.     MVI    A,LF        ;FALL THRU TO ECHOUT
  1901. ;
  1902.     ENDIF        ;NOT ECHOLST
  1903. ;
  1904. ; OUTPUT CHAR TO PRINTER OR CONSOLE
  1905. ;
  1906. ECHOUT:
  1907.     MOV    C,A        ;CHAR IN C
  1908.     PUSH    H        ;SAVE HL
  1909.     PUSH    B        ;SAVE BC
  1910.     LXI    D,0CH-3        ;OFFSET FOR CONSOLE OUTPUT
  1911. ;
  1912.     IF    ECHOLST
  1913.     MOV    A,B        ;CHECK FOR PRINTER
  1914.     CPI    '$'
  1915.     JRNZ    ECHOUT1
  1916.     INX    D        ;ADD 3 FOR PRINTER OFFSET
  1917.     INX    D
  1918.     INX    D
  1919. ;
  1920.     ENDIF        ;ECHOLST
  1921. ;
  1922. ; OUTPUT CHAR IN C WITH BIOS OFFSET IN DE
  1923. ;
  1924. ECHOUT1:
  1925.     CALL    BIOUT        ;BIOS OUTPUT
  1926.     POP    B        ;RESTORE BC,HL
  1927.     POP    H
  1928.     RET
  1929.  
  1930. ;
  1931. ; OUTPUT CHAR IN C TO BIOS WITH OFFSET IN DE
  1932. ;
  1933. BIOUT:
  1934.     LHLD    WBOOT+1        ;GET ADDRESS OF WARM BOOT
  1935.     DAD    D        ;PT TO ROUTINE
  1936.     PCHL            ;JUMP TO IT
  1937.  
  1938. ;
  1939. ;  ** SUPPORT UTILITIES **
  1940. ;
  1941.  
  1942. ;
  1943. ;  CHECK FOR USER INPUT; IF ^C, RETURN WITH Z
  1944. ;
  1945. BREAK:
  1946.     PUSH    H        ;SAVE REGS
  1947.     PUSH    D
  1948.     PUSH    B
  1949.     MVI    E,0FFH        ;GET CHAR IF ANY
  1950.     MVI    C,6        ;CONSOLE STATUS CHECK
  1951.     CALL    BDOS
  1952.     POP    B        ;RESTORE REGS
  1953.     POP    D
  1954.     POP    H
  1955.     CPI    CTRLC        ;CHECK FOR ABORT
  1956.     JZ    EXIT        ;EXIT
  1957.     CPI    CTRLX        ;SKIP?
  1958.     RET
  1959.  
  1960. ;
  1961. ; COPY HL TO DE FOR B BYTES
  1962. ;
  1963. LDIR:
  1964.     MOV    A,M    ;GET
  1965.     STAX    D    ;PUT
  1966.     INX    H    ;PT TO NEXT
  1967.     INX    D
  1968.     DJNZ    LDIR    ;LOOP
  1969.     RET
  1970.  
  1971. ;
  1972. ;  PRINT FILE NOT FOUND MESSAGE
  1973. ;
  1974. PRFNF:
  1975.     CALL    PRINT
  1976.     DB    ' No File','s'+80H
  1977.     JMP    EXIT
  1978.  
  1979. ;
  1980. ;  OUTPUT NEW LINE TO CON:
  1981. ;
  1982. CRLF:
  1983.     MVI    A,CR
  1984.     CALL    CONOUT
  1985.     MVI    A,LF
  1986.     JMP    CONOUT
  1987.  
  1988. ;
  1989. ; SEARCH FOR FIRST AND NEXT
  1990. ;
  1991. SEARF:
  1992.     PUSH    B    ; SAVE COUNTER
  1993.     PUSH    H    ; SAVE HL
  1994.     MVI    C,17    ; SEARCH FOR FIRST FUNCTION
  1995. SEARF1:
  1996.     LXI    D,FCB1    ; PT TO FCB
  1997.     CALL    BDOS
  1998.     INR    A    ; SET ZERO FLAG FOR ERROR RETURN
  1999.     POP    H    ; GET HL
  2000.     POP    B    ; GET COUNTER
  2001.     RET
  2002. SEARN:
  2003.     PUSH    B    ; SAVE COUNTER
  2004.     PUSH    H    ; SAVE HL
  2005.     MVI    C,18    ; SEARCH FOR NEXT FUNCTION
  2006.     JR    SEARF1
  2007.  
  2008. ;
  2009. ; CONSOLE INPUT
  2010. ;
  2011. CONIN:
  2012.     PUSH    H    ; SAVE REGS
  2013.     PUSH    D
  2014.     PUSH    B
  2015.     MVI    C,1    ; INPUT
  2016.     CALL    BDOS
  2017.     POP    B    ; GET REGS
  2018.     POP    D
  2019.     POP    H
  2020.     ANI    7FH    ; MASK MSB
  2021.     CPI    61H
  2022.     RC
  2023.     ANI    5FH    ; TO UPPER CASE
  2024.     RET
  2025.  
  2026. ;
  2027. ; LOG INTO USER AREA CONTAINED IN FCB1
  2028. ;
  2029. LOGUSR:
  2030.     LDA    FCB1+13        ;GET USER NUMBER
  2031. SETUSR:
  2032.     MOV    E,A
  2033.     MVI    C,32        ;USE BDOS FCT
  2034.     JMP    BDOS
  2035.  
  2036. ;
  2037. ;  PRINT FILE NAME PTED TO BY HL
  2038. ;
  2039. PRFN:
  2040.     CALL    PRINT    ;LEADING SPACE
  2041.     DB    ' '+80H
  2042.     MVI    B,8    ;8 CHARS
  2043.     CALL    PRFN1
  2044.     MVI    A,'.'    ;DOT
  2045.     CALL    CONOUT
  2046.     MVI    B,3    ;3 CHARS
  2047. PRFN1:
  2048.     MOV    A,M    ; GET CHAR
  2049.     INX    H    ; PT TO NEXT
  2050.     CALL    CONOUT    ; PRINT CHAR
  2051.     DJNZ    PRFN1    ; COUNT DOWN
  2052.     RET
  2053.  
  2054. ;
  2055. ; SAVE RETURN ADDRESS
  2056. ;
  2057. RETSAVE:
  2058.     POP    D    ; GET RETURN ADDRESS
  2059.     POP    H    ; GET RETURN ADDRESS TO ZCPR3
  2060.     SHLD    Z3RET    ; SAVE IT
  2061.     PUSH    H    ; PUT RETURN ADDRESS TO ZCPR3 BACK
  2062.     PUSH    D    ; PUT RETURN ADDRESS BACK
  2063.     RET
  2064.  
  2065. ;
  2066. ; EXIT TO ZCPR3
  2067. ;
  2068. EXIT:
  2069. Z3RET    EQU    $+1    ; POINTER TO IN-THE-CODE MODIFICATION
  2070.     LXI    H,0    ; RETURN ADDRESS
  2071.     PCHL        ; GOTO ZCPR3
  2072.  
  2073. ;
  2074. ; TEST WHEEL BYTE FOR APPROVAL
  2075. ;   IF WHEEL BYTE IS 0 (OFF), ABORT WITH A MESSAGE (FLUSH RET ADR AND EXIT)
  2076. ;
  2077.     IF    WHEEL    ;IF ANY WHEEL OPTION IS RUNNING
  2078. WHLTST:
  2079.     LDA    Z3WHL    ;GET WHEEL BYTE
  2080.     ORA    A    ;ZERO?
  2081.     RNZ
  2082.     POP    PSW    ;CLEAR STACK
  2083.     CALL    PRINT
  2084.     DB    ' No Whee','l'+80H
  2085.     RET
  2086.     ENDIF        ;WHEEL
  2087.  
  2088. ;
  2089. ; PRINT A DASH
  2090. ;
  2091.     IF    LTON OR PEEKON
  2092. DASH:
  2093.     CALL    PRINT
  2094.     DB    ' -',' '+80H
  2095.     RET
  2096. ;
  2097.     ENDIF        ;LTON OR PEEKON
  2098. ;
  2099. ; PRINT ADDRESS MESSAGE
  2100. ;   PRINT ADDRESS IN DE
  2101. ;
  2102.     IF    PEEKON OR POKEON
  2103. ADRAT:
  2104.     CALL    PRINT
  2105.     DB    ' at',' '+80H
  2106.     MOV    A,D    ;PRINT HIGH
  2107.     CALL    PAHC
  2108.     MOV    A,E    ;PRINT LOW
  2109.     JMP    PAHC
  2110. ;
  2111. ; EXTRACT HEXADECIMAL NUMBER FROM LINE PTED TO BY HL
  2112. ;   RETURN WITH VALUE IN DE AND HL PTING TO OFFENDING CHAR
  2113. ;
  2114. HEXNUM:
  2115.     LXI    D,0        ;DE=ACCUMULATED VALUE
  2116.     MVI    B,5        ;B=CHAR COUNT
  2117. HNUM1:
  2118.     MOV    A,M        ;GET CHAR
  2119.     CPI    ' '+1        ;DONE?
  2120.     RC            ;RETURN IF SPACE OR LESS
  2121.     INX    H        ;PT TO NEXT
  2122.     SUI    '0'        ;CONVERT TO BINARY
  2123.     JRC    NUMERR        ;RETURN AND DONE IF ERROR
  2124.     CPI    10        ;0-9?
  2125.     JRC    HNUM2
  2126.     SUI    7        ;A-F?
  2127.     CPI    10H        ;ERROR?
  2128.     JRNC    NUMERR
  2129. HNUM2:
  2130.     MOV    C,A        ;DIGIT IN C
  2131.     MOV    A,D        ;GET ACCUMULATED VALUE
  2132.     RLC            ;EXCHANGE NYBBLES
  2133.     RLC
  2134.     RLC
  2135.     RLC
  2136.     ANI    0F0H        ;MASK OUT LOW NYBBLE
  2137.     MOV    D,A
  2138.     MOV    A,E        ;SWITCH LOW-ORDER NYBBLES
  2139.     RLC
  2140.     RLC
  2141.     RLC
  2142.     RLC
  2143.     MOV    E,A        ;HIGH NYBBLE OF E=NEW HIGH OF E,
  2144.                 ;  LOW NYBBLE OF E=NEW LOW OF D
  2145.     ANI    0FH        ;GET NEW LOW OF D
  2146.     ORA    D        ;MASK IN HIGH OF D
  2147.     MOV    D,A        ;NEW HIGH BYTE IN D
  2148.     MOV    A,E
  2149.     ANI    0F0H        ;MASK OUT LOW OF E
  2150.     ORA    C        ;MASK IN NEW LOW
  2151.     MOV    E,A        ;NEW LOW BYTE IN E
  2152.     DJNZ    HNUM1        ;COUNT DOWN
  2153.     RET
  2154. ;
  2155. ; NUMBER ERROR
  2156. ;
  2157. NUMERR:
  2158.     CALL    PRINT
  2159.     DB    ' Num','?'+80H
  2160.     JMP    EXIT
  2161. ;
  2162. ; SKIP TO NEXT NON-BLANK
  2163. ;
  2164. SKSP:
  2165.     MOV    A,M    ;GET CHAR
  2166.     INX    H    ;PT TO NEXT
  2167.     CPI    ' '    ;SKIP SPACES
  2168.     JRZ    SKSP
  2169.     DCX    H    ;PT TO GOOD CHAR
  2170.     ORA    A    ;SET EOL FLAG
  2171.     RET
  2172. ;
  2173.     ENDIF        ;PEEKON OR POKEON
  2174. ;
  2175. ; Test File in FCB for unambiguity and existence, ask user to delete if so
  2176. ;   Return with Z flag set if R/O or no permission to delete
  2177. ;
  2178.     IF    RENON OR CPON
  2179. EXTEST:
  2180.     CALL    AMBCHK        ;AMBIGUOUS FILE NAMES NOT ALLOWED
  2181.     CALL    SEARF        ;LOOK FOR SPECIFIED FILE
  2182.     JRZ    EXOK        ;OK IF NOT FOUND
  2183.     CALL    GETSBIT        ;POSITION INTO DIR
  2184.     INX    D        ;PT TO FILE NAME
  2185.     XCHG            ;HL PTS TO FILE NAME
  2186.     PUSH    H        ;SAVE PTR TO FILE NAME
  2187.     CALL    PRFN        ;PRINT FILE NAME
  2188.     POP    H
  2189.     CALL    ROTEST        ;CHECK FOR R/O
  2190.     JRNZ    EXER
  2191.     CALL    ERAQ        ;ERASE?
  2192.     JRNZ    EXER        ;RESTART AS ERROR IF NO
  2193.     LXI    D,FCB1        ;PT TO FCB1
  2194.     MVI    C,19        ;DELETE FILE
  2195.     CALL    BDOS
  2196. EXOK:
  2197.     XRA    A
  2198.     DCR    A        ;NZ = OK
  2199.     RET
  2200. EXER:
  2201.     XRA    A        ;ERROR FLAG - FILE IS R/O OR NO PERMISSION
  2202.     RET
  2203.  
  2204. ;
  2205. ; CHECK FOR AMBIGUOUS FILE NAME IN FCB1
  2206. ;   RETURN Z IF SO
  2207. ;
  2208. AMBCHK:
  2209.     LXI    H,FCB1+1    ;PT TO FCB
  2210. ;
  2211. ; CHECK FOR AMBIGUOUS FILE NAME PTED TO BY HL
  2212. ;
  2213. AMBCHK1:
  2214.     PUSH    H
  2215.     MVI    B,11        ;11 BYTES
  2216. AMB1:
  2217.     MOV    A,M        ;GET CHAR
  2218.     ANI    7FH        ;MASK
  2219.     CPI    '?'
  2220.     JRZ    AMB2
  2221.     INX    H        ;PT TO NEXT
  2222.     DJNZ    AMB1
  2223.     DCR    B        ;SET NZ FLAG
  2224.     POP    D
  2225.     RET
  2226. AMB2:
  2227.     POP    H        ;PT TO FILE NAME
  2228.     CALL    PRFN
  2229.     CALL    PRINT
  2230.     DB    ' is AF','N'+80H
  2231.     JMP    EXIT
  2232. ;
  2233.     ENDIF        ;RENON OR CPON
  2234. ;
  2235. ;  CHECK USER TO SEE IF HE APPROVES ERASE OF FILE
  2236. ;    RETURN WITH Z IF YES
  2237. ;
  2238.     IF    RENON OR CPON OR ERAON OR PROTON
  2239. ERAQ:
  2240.     CALL    PRINT
  2241.     DB    ' - Eras','e'+80H
  2242. ERAQ1:
  2243.     CALL    PRINT
  2244.     DB    ' (Y/N)?',' '+80H
  2245.     CALL    CONIN        ;GET RESPONSE
  2246.     CPI    'Y'        ;KEY ON YES
  2247.     RET
  2248. ;
  2249.     ENDIF        ;RENON OR CPON OR ERAON OR PROTON
  2250. ;
  2251. ; TEST FILE PTED TO BY HL FOR R/O
  2252. ;    NZ IF R/O
  2253. ;
  2254.     IF    RENON OR ERAON OR CPON
  2255. ROTEST:
  2256.     PUSH    H    ;ADVANCE TO R/O BYTE
  2257.     LXI    B,8    ;PT TO 9TH BYTE
  2258.     DAD    B
  2259.     MOV    A,M    ;GET IT
  2260.     ANI    80H    ;MASK BIT
  2261.     PUSH    PSW
  2262.     LXI    H,ROMSG
  2263.     CNZ    PRINT1    ;PRINT IF NZ
  2264.     POP    PSW    ;GET FLAG
  2265.     POP    H    ;GET PTR
  2266.     RET
  2267. ROMSG:
  2268.     DB    ' is R/','O'+80H
  2269. ;
  2270.     ENDIF        ;RENON OR ERAON OR CPON
  2271. ;
  2272. ; INIT FCB1, RETURN WITH DE PTING TO FCB1
  2273. ;
  2274.     IF    ERAON OR LTON OR CPON
  2275. INITFCB1:
  2276.     LXI    H,FCB1        ;PT TO FCB
  2277. INITFCB2:
  2278.     PUSH    H        ;SAVE PTR
  2279.     LXI    B,12        ;PT TO FIRST BYTE
  2280.     DAD    B
  2281.     MVI    B,24        ;ZERO 24 BYTES
  2282.     XRA    A        ;ZERO FILL
  2283.     CALL    FILLP        ;FILL MEMORY
  2284.     POP    D        ;PT TO FCB
  2285.     RET
  2286. ;
  2287.     ENDIF        ;ERAON OR LTON OR CPON
  2288. ;
  2289. ; BUFFERS
  2290. ;
  2291. NXTFILE:
  2292.     DS    2    ;PTR TO NEXT FILE IN LIST
  2293.  
  2294. ;
  2295. ; SIZE ERROR TEST
  2296. ;
  2297.     IF    ($ GT (RCP + RCPS*128))
  2298. SIZERR    EQU    NOVALUE    ;RCP IS TOO LARGE FOR BUFFER
  2299.     ENDIF
  2300.  
  2301. ;
  2302. ; END OF SYS.RCP
  2303. ;
  2304.  
  2305.     END
  2306.