home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug117.arc / ZCMD-1.LBR / ZCMD.ASM next >
Assembly Source File  |  1979-12-31  |  27KB  |  1,049 lines

  1.  
  2.  
  3. ;SET UP TO CREATE SYSTEM FILE
  4.  
  5.     AORG    0CF80H
  6.     NOP
  7.     DEFB    0E7H
  8.     NOP
  9.     DEFB    0D0H
  10.     DEFB    0EEH
  11.     DEFB    08H
  12.     DEFS    7AH    
  13.  
  14. ENTRY:    JP    CPR
  15.     JP    CPR1
  16.     
  17. BIOS    =    0E700H
  18. DRVPFATT=      1
  19. SYSDRV    =    'A'-'@'
  20. SYSUSR    =    0
  21. ERDFLG    =    'V'
  22. CMDSEP    =    ';'
  23. NLINES    =    24
  24. FENCE    =    ':'
  25. PGDFLG    =    'P'
  26. USRMAX    =    003FH
  27. MAXUSR    =    15
  28. DRVMAX    =    003DH
  29. MAXDISK    =    2
  30. SYSFLG    =    'A'
  31. SOFLG    =    'S'
  32. SPRMPT    =    '$'
  33. CPRMPT    =    '>'
  34. NUMBASE    =    'H'
  35. SECTFLG    =    'S'
  36. CURIND    =    '$'
  37. COMMENT    =    ';'
  38. NCHARS    =    4
  39. CR    =    0DH
  40. LF    =    0AH
  41. TAB    =    09H
  42. WBOOT    =    0000H
  43. UDFLAG    =    0004H
  44. BDOS    =    0005H
  45. TFCB    =    005CH
  46. TBUFF    =    0080H
  47. TPA    =    0100H
  48. BUFLEN    =    80
  49. BUFSIZ:    DEFB    BUFLEN        ; Maximum buffer length
  50. CHRCNT:    DEFB    0        ; Number of valid chars in command line
  51. CMDLIN:    DEFM    '              '; Default (cold boot) command
  52.     DEFB    0        ; Command string terminator
  53.     DEFS    BUFLEN-($-CMDLIN)+1; Total is 'BUFLEN' bytes
  54. NXTCHR:    DEFW    CMDLIN        ; Pointer to command input buffer
  55. COMMSG:    DEFM    'COM'
  56. FCBDN:    DEFS    1        ; Disk name
  57. FCBFN:    DEFS    8        ; File name
  58. FCBFT:    DEFS    3        ; File type
  59.     DEFS    1        ; Extent number
  60.     DEFS    2        ; S1 and S2
  61.     DEFS    1        ; Record count
  62. FCBDM:    DEFS    16        ; Disk group map
  63. FCBCR:    DEFS    1        ; Current record number
  64. PAGCNT:    DEFB    NLINES-2    ; Lines left on page
  65. CMDTBL:    DEFM    'DIR '
  66.     DEFW    DIR
  67.     DEFM    'LIST'
  68.     DEFW    LIST
  69.     DEFM    'TYPE'
  70.     DEFW    TYPE
  71.     DEFM    'GO  '
  72.     DEFW    GO
  73.     DEFM    'ERA '
  74.     DEFW    ERA
  75.     DEFM    'SAVE'
  76.     DEFW    SAVE
  77.     DEFM    'REN '
  78.     DEFW    REN
  79.     DEFM    'GET '
  80.     DEFW    GET
  81.     DEFM    'JUMP'
  82.     DEFW    JUMP
  83. NCMNDS    =    9
  84.  
  85. CPR:    LD    SP,STACK    ; Set the stack
  86.     PUSH    BC
  87.     PUSH    DE
  88.     LD    A,CR
  89.     CALL    CONOUT        ; This is required to make BYE's BDCHEK
  90.     LD    C,32        ; Reset locations 6 and 7 after warmboot
  91.     LD    E,241
  92.     CALL    BDOS        ; Call BYE's BDOS
  93.     POP    DE
  94.     POP    BC
  95.     CP    77        ; BYE up and running?
  96.     JR    Z,CPR1
  97.     LD    A,MAXUSR+1    ; Set USRMAX on cold boot
  98.     LD    (USRMAX),A
  99.     LD    A,MAXDISK-1    ; Set DRVMAX on cold boot
  100.     LD    (DRVMAX),A
  101. CPR1:    LD    A,5
  102.     RST    28H
  103.     LD    A,(HL)
  104.     OR    A
  105.     JP    Z,CPR2
  106.     LD    DE,BUFSIZ
  107.     LD    BC,128
  108.     LDIR
  109. CPR2:    LD    SP,STACK
  110.     PUSH    BC
  111.     LD    A,C        ; C=user/disk number (see loc 4)
  112.     RRA            ; Extract user number
  113.     RRA    
  114.     RRA    
  115.     RRA    
  116.     AND    0FH
  117.     LD    (CURUSR),A    ; Set user
  118.     CALL    SETUSR
  119.     CALL    RESET        ; Reset disk system
  120.     POP    BC
  121.     LD    A,C        ; C=user/disk number (see loc 4)
  122.     AND    0FH        ; Extract current disk drive
  123.     LD    (CURDR),A    ; Set it
  124.     CALL    LOGIN        ; Log in default disk
  125.     CALL    SETUD        ; Set user/disk flag
  126.     CALL    DEFDMA
  127. CONT:    LD    HL,(NXTCHR)    ; Point to next character to process
  128.     LD    A,(HL)        ; Get it
  129.     CP    3        ; Restart if CTL-C
  130.     JR    Z,RESTRT
  131.     OR    A        ; 0 if no command line present
  132.     JR    NZ,RS1
  133. RESTRT:    LD    SP,STACK    ; Reset stack
  134.     CALL    CRLF        ; Print prompt
  135.     LD    A,(CURDR)    ; Current drive is part of prompt
  136.     ADD    A,'A'        ; Convert to ASCII A-P
  137.     CALL    CONOUT
  138.     LD    A,(CURUSR)    ; Get user number
  139.     CP    10        ; User < 10?
  140.     JR    C,RS00
  141.     SUB    10        ; Subtract 10 from it
  142.     PUSH    AF        ; Save it
  143.     LD    A,'1'        ; Output 10's digit
  144.     CALL    CONOUT
  145.     POP    AF
  146. RS00:    ADD    A,'0'        ; Output 1's digit (convert to ASCII)
  147.     CALL    CONOUT
  148. RS000:    LD    HL,CMDLIN    ; Set pointer to first character
  149.     LD    (NXTCHR),HL    ; Pointer to next character to process
  150.     LD    (HL),0        ; Zero out command line
  151.     PUSH    HL        ; Save pointer
  152.     CALL    REDBUF        ; Input command line from user
  153.     POP    HL        ; Get pointer
  154.     LD    A,(HL)        ; Check for comment line
  155.     CP    COMMENT        ; Begins with comment character?
  156.     JR    Z,RESTRT
  157.     OR    A        ; No input?
  158.     JR    Z,RESTRT
  159. RS1:    LD    SP,STACK    ; Reset stack
  160.     LD    A,(HL)
  161.     CP    CMDSEP
  162.     JR    NZ,RS2
  163.     INC    HL
  164.     LD    (NXTCHR),HL
  165. RS2:    LD    (CMDCH1),HL    ; Set pointer to first character
  166. CAPBUF:    LD    A,(HL)        ; Capitalize command character
  167.     CALL    UCASE
  168.     LD    (HL),A
  169.     INC    HL        ; Point to next character
  170.     OR    A        ; Eol?
  171.     JR    NZ,CAPBUF
  172.     CALL    SCANER        ; Parse command name from command line
  173.     JR    NZ,ERROR
  174.     LD    DE,RSTCPR    ; Put return address of command
  175.     PUSH    DE        ; On the stack
  176. COLON    =    $+1
  177.     LD    A,0        ; Command of the form 'DU:command'?
  178.     OR    A        ; 0=no
  179.     JP    NZ,COM        ; Process as com file if not
  180.     CALL    CMDSER        ; Scan for cpr-resident command
  181.     JP    NZ,COM        ; Not cpr-resident
  182.     LD    A,(HL)        ; Found it:  get low-order part
  183.     INC    HL        ; Get high-order part
  184.     LD    H,(HL)        ; Store high
  185.     LD    L,A        ; Store low
  186.     JP    (HL)        ; Execute cpr routine
  187. RSTCPR:    CALL    DLOGIN        ; Log in current user/disk
  188. RCPRNL:    CALL    SCANER        ; Extract next token from command line
  189.     LD    A,(FCBFN)    ; Get first char of token
  190.     CP    ' '        ; Any char?
  191.     JP    Z,CONT        ; Continue with next command if no error
  192. ERROR:    CALL    CRLF        ; New line
  193. CURTOK    =    $+1
  194.     LD    HL,0        ; Pt to beginning of command line
  195. ERR1:    LD    A,(HL)        ; Get character
  196.     CP    ' '+1        ; Simple '?' if <sp> or less
  197.     JR    C,ERR2
  198.     CALL    CONOUT        ; Print command char
  199.     INC    HL        ; Pt to next char
  200.     JR    ERR1        ; Continue
  201. ERR2:    CALL    PRINT        ; Print '?'
  202.     DEFB    '?'+80H
  203. ERR3:    CALL    DLOGIN        ; Panic restore of default user/disk
  204.     JP    RESTRT        ; Restart CPR
  205. PRNNF:    CALL    PRINTC        ; No file message
  206.     DEFM    'NO FIL','E'+80H
  207.     RET    
  208. CRLF:    LD    A,CR
  209.     CALL    CONOUT
  210.     LD    A,LF
  211.     JR    CONOUT
  212. CONIN:    LD    C,1        ; Input character
  213.     CALL    BDOS        ; Get input character with ^S
  214.     JP    UCASE        ; Capitalize
  215. CONOUT:    PUSH    BC
  216.     PUSH    DE
  217.     PUSH    HL
  218.     LD    C,2
  219. OUTPUT:    LD    E,A
  220.     CALL    BDOS
  221.     POP    HL
  222.     POP    DE
  223.     POP    BC
  224.     RET    
  225. LCOUT:    PUSH    AF        ; Output character to CRT
  226. PRFLG    =    $+1
  227.     LD    A,0        ; 2nd byte (immediate argument)
  228.     OR    A        ; 0=type
  229.     JR    Z,LC1
  230.     POP    AF        ; Get character
  231. LSTOUT:    PUSH    BC        ; Save regs
  232.     PUSH    DE
  233.     PUSH    HL
  234.     LD    C,5
  235.     JR    OUTPUT
  236. LC1:    POP    AF        ; Get character
  237.     PUSH    AF
  238.     CALL    CONOUT        ; Output to CRT
  239.     POP    AF
  240.     CP    LF        ; Check for paging
  241.     RET    NZ
  242. PAGER:    PUSH    HL
  243.     LD    HL,PAGCNT    ; Count down
  244.     DEC    (HL)
  245.     JR    NZ,PAGER1
  246.     LD    (HL),NLINES-2    ; Refill counter
  247. PGFLG    =    $+1
  248.     LD    A,0        ; 0 may be changed by pgflg equate
  249.     CP    PGDFLG        ; Page default override option wanted?
  250.     JR    Z,PAGER1
  251.     PUSH    BC        ; Save registers
  252. BIOCAL1:CALL    BIOS+9        ; BIOS console input routine
  253.     POP    BC        ; Get register
  254.     CP    'C'-'@'        ; ^C
  255.     JP    Z,RSTCPR    ; Restart CPR
  256. PAGER1:    POP    HL        ; Restore HL
  257.     RET    
  258. READF:    LD    DE,FCBDN    ; Fall through to read
  259. READ:    LD    C,14H        ; Fall through to BDOSB
  260. BDOSB:    PUSH    BC
  261.     CALL    BDOS
  262.     POP    BC
  263.     OR    A
  264.     RET    
  265. PRINTC:    CALL    CRLF        ; New line
  266. PRINT:    EX    (SP),HL        ; Get ptointer to string
  267.     CALL    PRIN1        ; Print string
  268.     EX    (SP),HL        ; Restore HL and return address
  269.     RET    
  270. PRIN1:    LD    A,(HL)        ; Get next byte
  271.     INC    HL        ; Point to next byte
  272.     OR    A        ; End of string?
  273.     RET    Z        ; String terminated by binary 0
  274.     PUSH    AF        ; Save flags
  275.     AND    7FH        ; Mask out MSG
  276.     CALL    CONOUT        ; Print character
  277.     POP    AF        ; Get flags
  278.     RET    M        ; String terminated by MSB set
  279.     JR    PRIN1
  280. GETDRV:    LD    C,19H
  281.     JR    BDOSJP
  282. DEFDMA:    LD    DE,TBUFF    ; 80H=TBUFF
  283. DMASET:    LD    C,1AH
  284.     JR    BDOSJP
  285. RESET:    LD    C,0DH
  286. BDOSJP:    JP    BDOS
  287. LOGIN:    LD    E,A
  288.     LD    C,0EH
  289.     JR    BDOSJP        ; Save some code space
  290. OPENF:    XOR    A
  291.     LD    (FCBCR),A
  292.     LD    DE,FCBDN    ; Fall thrrough to OPEN
  293. OPEN:    LD    C,0FH        ; Fall through to GRBDOS
  294. GRBDOS:    CALL    BDOS
  295.     INC    A        ; Set zero flag for error return
  296.     RET    
  297. CLOSE:    LD    C,10H
  298.     JR    GRBDOS
  299. SEARF:    LD    DE,FCBDN    ; Specify FCB
  300. SEAR1:    LD    C,11H
  301.     JR    GRBDOS
  302. SEARN:    LD    C,12H
  303.     JR    GRBDOS
  304. DELETE:    LD    C,13H
  305.     JR    BDOSJP        ; Save more space
  306. GETUSR:    LD    A,0FFH        ; Get current user number
  307. SETUSR:    LD    E,A        ; User number in 'E'
  308.     LD    C,20H        ; Set user number to value in 'E'
  309.     JR    BDOSJP        ; More space saving
  310. SETUD:    CALL    GETUSR        ; Get number of current user
  311.     AND    0FH        ; Mask sure 4 bits
  312.     ADD    A,A        ; Place it in high nybble
  313.     ADD    A,A
  314.     ADD    A,A
  315.     ADD    A,A
  316.     LD    HL,CURDR    ; Mask in current drive number
  317.     OR    (HL)        ; Mask in
  318.     LD    (UDFLAG),A    ; Set user/disk number
  319.     RET    
  320. UCASE:    AND    7FH        ; Mask out MSB
  321.     CP    61H        ; Lower-case 'A'
  322.     RET    C
  323.     CP    7BH        ; Greater than lower-case Z?
  324.     RET    NC
  325.     AND    5FH        ; Capitalize
  326.     RET    
  327. REDBUF:    LD    A,CPRMPT
  328. RB2:    CALL    CONOUT
  329.     LD    C,0AH        ; Read command line from user
  330.     LD    DE,BUFSIZ
  331.     CALL    BDOS
  332.     LD    HL,CHRCNT    ; Point to character count
  333.     LD    A,(HL)        ; Get character count
  334.     INC    HL        ; Pt to first character of command line
  335.     CALL    ADDAH        ; Pt to after last char of command line
  336.     LD    (HL),0        ; Store ending zero
  337.     RET    
  338. BREAK:    PUSH    BC        ; Save registers
  339.     PUSH    DE
  340.     PUSH    HL
  341. BIOCAL2:CALL    BIOS+6        ; Console status check
  342.     OR    A        ; Set flags
  343. BIOCAL3:CALL    NZ,BIOS+9    ; Get input char with ^s processing
  344.     CP    'S'-'@'        ; Pause if ^S
  345. BIOCAL4:CALL    Z,BIOS+9    ; Get next character
  346.     POP    HL        ; Restore registers
  347.     POP    DE
  348.     POP    BC
  349.     CP    'C'-'@'        ; Check for abort
  350.     RET    
  351. SDELM:    LD    A,(DE)
  352.     OR    A        ; 0=delimiter
  353.     RET    Z
  354.     CP    ' '+1        ; Delim if <= <SP>
  355.     JR    C,ZERO
  356.     CP    '='        ; '='=delimiter
  357.     RET    Z
  358.     CP    5FH        ; Underscore=delimiter
  359.     RET    Z
  360.     CP    '.'        ; '.'=delimiter
  361.     RET    Z
  362.     CP    ':'        ; ':'=delimiter
  363.     RET    Z
  364.     CP    ','        ; ','=delimiter
  365.     RET    Z
  366.     CP    ';'        ; ';'=delimiter
  367.     RET    Z
  368.     CP    '<'        ; '<'=delimiter
  369.     RET    Z
  370.     CP    '>'        ; '>'=delimiter
  371.     RET    Z
  372.     CP    CMDSEP
  373.     RET
  374. ZERO:    XOR    A        ; Set zero flag
  375.     RET    
  376. ADVAN:    LD    DE,(NXTCHR)    
  377. SBLANK:    LD    A,(DE)        ; Get character
  378.     OR    A        ; Zero?
  379.     RET    Z
  380.     CP    CMDSEP
  381.     RET    Z
  382.     CALL    SDELM        ; Skip over delimiter
  383.     RET    NZ
  384.     INC    DE        ; Advance to next char
  385.     JR    SBLANK
  386. ADDAH:    ADD    A,L
  387.     LD    L,A
  388.     RET    NC
  389.     INC    H
  390.     RET    
  391. NUMBER:    CALL    SCANER        ; Parse number and place in fcbfn
  392.     LD    HL,FCBFN+10    ; Pt to end of token for conversion
  393.     LD    B,11        ; 11 characters maximum
  394. NUMS:    LD    A,(HL)        ; Get character from end
  395.     DEC    HL        ; Back up
  396.     CP    ' '        ; Space?
  397.     JR    NZ,NUMS1
  398.     DJNZ    NUMS        ; Count down
  399.     JR    NUM0        ; By default, process
  400. NUMS1:    CP    NUMBASE        ; Check against base switch flag
  401.     JR    Z,HNUM0
  402. NUM0:    LD    HL,FCBFN    ; Point to beginning of token
  403. NUM0A:    LD    BC,1100H    ; C=accumulated value, b=char count
  404. NUM1:    LD    A,(HL)        ; Get character
  405.     CP    ' '        ; Done if <SP>
  406.     JR    Z,NUM2
  407.     CP    ':'        ; Done if colon
  408.     JR    Z,NUM2
  409.     INC    HL        ; Pt to next char
  410.     SUB    '0'        ; Convert to binary
  411.     CP    10        ; Error if >= 10
  412.     JR    NC,NUMERR
  413.     LD    D,A        ; Digit in d
  414.     LD    A,C        ; New value = old value * 10
  415.     RLCA            ; *2
  416.     JR    C,NUMERR
  417.     RLCA            ; *4
  418.     JR    C,NUMERR
  419.     RLCA            ; *8
  420.     JR    C,NUMERR
  421.     ADD    A,C        ; *9
  422.     JR    C,NUMERR
  423.     ADD    A,C        ; *10
  424.     JR    C,NUMERR
  425.     ADD    A,D        ; New value = old value * 10 + digit
  426.     JR    C,NUMERR
  427.     LD    C,A        ; Set new value
  428.     DJNZ    NUM1        ; Count down
  429. NUM2:    LD    A,C        ; Get accumulated value
  430.     RET    
  431. NUMERR:    JP    ERROR        ; Use error routine
  432. HEXNUM:    CALL    SCANER        ; Parse number and place in FCBFN
  433. HNUM0:    LD    HL,FCBFN    ; Point to token for conversion
  434.     LD    DE,0        ; De=accumulated value
  435.     LD    B,11        ; B=character
  436. HNUM1:    LD    A,(HL)        ; Get character
  437.     CP    ' '        ; Done?
  438.     JR    Z,HNUM3
  439.     CP    NUMBASE        ; Done if numbase suffix
  440.     JR    Z,HNUM3
  441.     SUB    '0'        ; Convert to binary
  442.     JR    C,NUMERR
  443.     CP    10        ; 0-9?
  444.     JR    C,HNUM2
  445.     SUB    7        ; A-F?
  446.     CP    10H        ; Error?
  447.     JR    NC,NUMERR
  448. HNUM2:    INC    HL        ; Point to next characer
  449.     LD    C,A        ; Digit in 'C'
  450.     LD    A,D        ; Get accumulated value
  451.     RLCA            ; Exchange nybbles
  452.     RLCA    
  453.     RLCA    
  454.     RLCA    
  455.     AND    0F0H        ; Mask out low nybble
  456.     LD    D,A
  457.     LD    A,E        ; Switch low-order nybbles
  458.     RLCA    
  459.     RLCA    
  460.     RLCA    
  461.     RLCA    
  462.     LD    E,A        ; High nybble of e=new high of e
  463.     AND    0FH        ; Get new low of d
  464.     OR    D        ; Mask in high of d
  465.     LD    D,A        ; New high byte in d
  466.     LD    A,E
  467.     AND    0F0H        ; Mask out low of e
  468.     OR    C        ; Mask in new low
  469.     LD    E,A        ; New low byte in e
  470.     DJNZ    HNUM1        ; Count down
  471. HNUM3:    EX    DE,HL        ; Returned value in hl
  472.     LD    A,L        ; Low-order byte in a
  473.     RET    
  474. DIRPTR:    LD    HL,TBUFF    ; Point to temporary buffer
  475.     ADD    A,C        ; Point to 1st byte of directory entry
  476.     CALL    ADDAH        ; Point to desired byte in dir entry
  477.     LD    A,(HL)        ; Get desired byte
  478.     RET    
  479. SLOGIN:    XOR    A        ; A=0 for default disk
  480.     LD    (FCBDN),A    ; Select default disk since user/disk
  481. TEMPDR    =    $+1
  482.     LD    A,0        ; 2nd byte (immediate arg) is tempdr
  483.     OR    A        ; 0=current drive
  484.     JR    NZ,SLOG1
  485.     LD    A,(CURDR)    ; Log in current drive
  486.     INC    A        ; Add 1 for next dcr
  487. SLOG1:    DEC    A        ; Adjust for proper disk number (a=0)
  488.     CALL    LOGIN        ; Log in new drive
  489. TEMPUSR =    $+1
  490.     LD    A,0        ; 2nd byte is user to be selected
  491.     JP    SETUSR        ; Log in new user
  492. DLOGIN:    DEFS    0
  493. CURDR    =    $+1
  494.     LD    A,0        ; Prep to log in current drive
  495.     CALL    LOGIN        ; Login current drive
  496. CURUSR    =    $+1
  497.     LD    A,0        ; Prep to log in current user number
  498.     JP    SETUSR        ; Log in new user
  499. SCANLOG:CALL    SCANER        ; Do scan
  500.     PUSH    AF        ; Save flag
  501.     CALL    SLOGIN        ; Log in temporary user/disk
  502.     POP    AF        ; Get flag
  503.     RET    
  504. SCANER:    LD    HL,FCBDN    ; Point to FCBDN
  505. SCANX:    XOR    A        ; A=0
  506.     LD    (TEMPDR),A    ; Set temporary drive number to default
  507.     LD    (HL),A        ; Set first byte of FCBDN
  508.     LD    (COLON),A    ; Set no colon flag
  509.     LD    A,(CURUSR)    ; Get current user
  510.     LD    (TEMPUSR),A    ; Set tempusr
  511.     CALL    ADVAN        ; Skip to non-blank or end of line
  512.     LD    (CURTOK),DE
  513.     LD    B,11        ; Prep for possible space fill
  514.     JR    Z,SCAN4
  515.     PUSH    DE        ; Save pointer to first character
  516.     CALL    SDELM        ; Check for delimiter and get first char
  517.     CP    'A'        ; In letter range?
  518.     JR    C,SCAN1
  519.     CP    'P'+1        ; In letter range?
  520.     JR    C,SCAN1A
  521. SCAN1:    CP    '0'        ; Check for digit range
  522.     JR    C,SCAN2
  523.     CP    '9'+1        ; In digit range?
  524.     JR    NC,SCAN2
  525. SCAN1A:    INC    DE        ; Pt to next char
  526.     CALL    SDELM        ; Check for delimiter, else digit
  527.     JR    SCAN1
  528. SCAN2:    POP    DE        ; Restore ptr to first char
  529.     CP    ':'        ; Was delimiter a colon?
  530.     JR    NZ,SCAN3
  531.     LD    (COLON),A    ; Set colon found
  532.     LD    A,(DE)        ; Get first character
  533.     CP    'A'        ; Convert possible drive spec to number
  534.     JR    C,SUD1
  535.     SUB    'A'-1
  536.     PUSH    BC        ; Save 'BC'
  537.     PUSH    AF        ; Save drive request
  538.     LD    A,(DRVMAX)    ; Get maximum legal drive
  539.     ADD    A,2        ; Bump it two for the compare
  540.     LD    B,A        ; Save maximum drive in 'B'
  541.     POP    AF        ; Restore drive request
  542.     CP    B        ; See if illegal drive
  543.     POP    BC        ; Restore bc
  544.     JP    NC,ERROR    ; Invalid disk number
  545.     LD    (TEMPDR),A    ; Set temporary drive number
  546.     LD    (HL),A        ; Set fcbdn
  547.     INC    DE        ; Pt to next char
  548.     LD    A,(DE)        ; See if it is a colon (:)
  549.     CP    ':'
  550.     JR    Z,SUD2
  551. SUD1:    PUSH    HL        ; Save pointer to FCBDN
  552.     EX    DE,HL        ; Hl pts to first digit
  553.     CALL    NUM0A        ; Get number
  554.     EX    DE,HL        ; De pts to terminating colon
  555.     LD    HL,USRMAX
  556.     CP    (HL)
  557.     POP    HL        ; Get pointer to FCBDN
  558.     JP    NC,ERROR
  559.     LD    (TEMPUSR),A    ; Save user number
  560. SUD2:    INC    DE        ; Point to character after colon
  561. SCAN3:    XOR    A        ; A=0
  562.     LD    (QMCNT),A    ; Init question mark count
  563.     LD    B,8        ; Max of 8 chars in file name
  564.     CALL    SCANF        ; Fill FCB file name
  565.     LD    B,3        ; Prepare to extract type
  566.     LD    A,(DE)        ; Get last char which stopped scan
  567.     CP    '.'        ; Have a type if de) delimiter is a '.'
  568.     JR    NZ,SCAN4    
  569.     INC    DE        ; Pt to char in command line after '.'
  570.     CALL    SCANF        ; Fill fcb file type
  571.     JR    SCAN5        ; Skip to next processing
  572. SCAN4:    CALL    SCANF4        ; Space fill
  573. SCAN5:    LD    B,4        ; 4 bytes
  574.     XOR    A        ; A=0
  575.     CALL    SCANF5        ; Fill with zeroes
  576.     LD    (NXTCHR),DE
  577. QMCNT    =    $+1
  578.     LD    A,0        ; Number of question marks
  579.     OR    A        ; Set zero flag to indicate any '?'
  580.     RET    
  581. SCANF:    CALL    SDELM        ; Done if delimiter encountered
  582.     JR    Z,SCANF4
  583.     INC    HL        ; Point to next byte in FCBDN
  584.     CP    '*'        ; Is (DE) a wild card?
  585.     JR    NZ,SCANF1
  586.     LD    (HL),'?'    ; Place '?' in FCB
  587.     CALL    SCQ        ; Scanner count question marks
  588.     JR    SCANF2
  589. SCANF1:    LD    (HL),A        ; Store filename char in fcb
  590.     INC    DE        ; Pt to next char in command line
  591.     CP    '?'        ; Check for question mark (wild)
  592.     CALL    Z,SCQ        ; Scanner count question marks
  593. SCANF2:    DJNZ    SCANF        ; Decrement char count until 8 elapsed
  594. SCANF3:    CALL    SDELM        ; 8 chars or more - skip until delimiter
  595.     RET    Z        ; Zero flag set if delimiter found
  596.     INC    DE        ; Pt to next char in command line
  597.     JR    SCANF3
  598. SCANF4:    LD    A,' '        ; Fill with spaces
  599. SCANF5:    INC    HL        ; Point to next byte in FCB
  600.     LD    (HL),A        ; Fill with byte in A-reg.
  601.     DJNZ    SCANF5
  602.     RET    
  603. SCQ:    PUSH    HL        ; Save HL
  604.     LD    HL,QMCNT    ; Get count
  605.     INC    (HL)        ; Increment
  606.     POP    HL        ; Get HL
  607.     RET    
  608. CMDSER:    LD    HL,CMDTBL    ; Point to command table
  609.     LD    C,NCMNDS    ; Set command counter
  610.     LD    A,C        ; Check number of commands
  611.     OR    A        ; If none, then abort
  612.     JR    Z,CMS5
  613. CMS1:    LD    DE,FCBFN    ; Point to stored command name
  614.     LD    B,NCHARS    ; Number of chars/command (8 max)
  615. CMS2:    LD    A,(DE)        ; Compare against table entry
  616.     CP    (HL)
  617.     JR    NZ,CMS3
  618.     INC    DE        ; Point to next character
  619.     INC    HL
  620.     DJNZ    CMS2        ; Count down
  621.     LD    A,(DE)        ; Next char must be a space
  622.     CP    ' '
  623.     JR    NZ,CMS4
  624.     RET            ; Command is CPR-resident
  625. CMS3:    INC    HL        ; Skip to next command table entry
  626.     DJNZ    CMS3
  627. CMS4:    INC    HL        ; Skip address
  628.     INC    HL
  629.     DEC    C        ; Decrement table entry number
  630.     JR    NZ,CMS1
  631. CMS5:    INC    C        ; Clear zero flag
  632.     RET            ; Command is disk-resident
  633. DIR:    CALL    SCANLOG        ; Extract possible D:FILENAME.TYP token
  634.     LD    HL,FCBFN    ; Make FCB wild (all '?') if no NAME.TYP
  635.     LD    A,(HL)        ; Get first chararacter of NAME.TYPE
  636.     CP    ' '        ; If space, all wild
  637.     CALL    Z,FILLQ
  638.     CALL    ADVAN        ; Look at next input char
  639.     LD    B,80H        ; Prepare for dir-only selection
  640.     JR    Z,DIRDN
  641.     LD    B,1        ; Set for both dir and sys files
  642.     CP    SYSFLG        ; System and dir flag specifier?
  643.     JR    Z,GOTFLG
  644.     CP    SOFLG        ; Sys only?
  645.     JR    NZ,DIRDN
  646.     DEC    B        ; B=0 for sys files only
  647. GOTFLG:    INC    DE        ; Pt to char after flag
  648. DIRDN:    LD    (NXTCHR),DE
  649. DIRPR:    LD    A,B        ; Get flag
  650.     LD    (SYSTST),A    ; Set system test flag
  651.     LD    E,0        ; Set column counter to zero
  652.     PUSH    DE        ; Save column counter (e)
  653.     CALL    SEARF        ; Search for specified file
  654.     JR    NZ,DIR3
  655.     CALL    PRNNF        ; Print no file msg; reg a not changed
  656.     XOR    A        ; Set zero flag
  657.     POP    DE        ; Restore de
  658.     RET    
  659. DIR3:    CALL    GETSBIT        ; Get and test for type of files
  660.     JR    Z,DIR6
  661.     POP    DE        ; Get entry count (=<CR> counter)
  662.     LD    A,E        ; Add 1 to it
  663.     INC    E
  664.     PUSH    DE        ; Save it
  665.     AND    03H        ; Output <CRLF> if 4 entries printed
  666.     JR    NZ,DIR4
  667.     CALL    CRLF        ; New line
  668.     JR    DIR5
  669. DIR4:    CALL    PRINT
  670.     DEFM    '  '
  671.     DEFB    FENCE        ; Then fence char
  672.     DEFB    ' ',' '+80H    ; Then 2 more spaces
  673. DIR5:    LD    B,01H        ; Pt to 1st byte of file name
  674.     LD    A,B        ; A=offset
  675.     CALL    DIRPTR        ; Hl now pts to 1st byte of file name
  676.     CALL    PRFN        ; Print file name
  677. DIR6:    CALL    BREAK        ; Check for abort
  678.     JR    Z,DIR7
  679.     CALL    SEARN        ; Search for next file
  680.     JR    NZ,DIR3
  681. DIR7:    POP    DE        ; Restore stack
  682.     LD    A,0FFH        ; Set nz flag
  683.     OR    A
  684.     RET    
  685. PRFN:    LD    B,8        ; 8 chars
  686.     CALL    PRFN1
  687.     LD    A,'.'        ; Dot
  688.     CALL    CONOUT
  689.     LD    B,3        ; 3 chars
  690. PRFN1:    LD    A,(HL)        ; Get char
  691.     INC    HL        ; Pt to next
  692.     CALL    CONOUT        ; Print char
  693.     DEC    B        ; Count down
  694.     JR    NZ,PRFN1
  695.     RET    
  696. GETSBIT:DEC    A        ; Adjust to returned value
  697.     RRCA            ; Convert number to offset into tbuff
  698.     RRCA    
  699.     RRCA    
  700.     AND    60H
  701.     LD    C,A        ; Offset into TBUFF in c
  702.     LD    A,10        ; Add 10 to point to SYS file attribute
  703.     CALL    DIRPTR        ; A=system byte
  704.     AND    80H        ; Look at only system bit
  705. SYSTST    =    $+1
  706.     XOR    0        ; If SYSTST=0, sys only; if =80h, DIR
  707.     RET            ; NZ if ok, Z if not ok
  708. FILLQ:    LD    B,11        ; Number of characters in FN & FT
  709. FQLP:    LD    (HL),'?'    ; Store '?'
  710.     INC    HL
  711.     DJNZ    FQLP
  712.     RET    
  713. ERA:    CALL    SCANLOG
  714.     LD    B,1        ; Display all matching files
  715.     CALL    DIRPR        ; Print directory of erased files
  716.     RET    Z        ; Abort if no files
  717.     CALL    PRINTC
  718.     DEFM    'OK TO ERASE','?'+80H
  719.     CALL    CONIN        ; Get reply
  720.     CP    'Y'        ; Yes?
  721.     RET    NZ        ; Abort if not
  722. ERA2:    LD    DE,FCBDN    ; Delete file specified
  723.     CALL    DELETE
  724.     RET            ; Reenter cpr
  725. LIST:    LD    A,0FFH        ; Turn on printer flag
  726.     JR    TYPE0
  727. TYPE:    XOR    A        ; Turn off printer flag
  728. TYPE0:    LD    (PRFLG),A    ; Set flag
  729.     CALL    SCANLOG        ; Extract FILENAME.TYP toden
  730.     JP    NZ,ERROR    ; Error if any question marks
  731.     CALL    ADVAN        ; Get pgdflg if it's there
  732.     LD    (PGFLG),A    ; Save it as a flag
  733.     JR    Z,TYPE1
  734.     INC    DE        ; Put new buf pointer
  735. TYPE1:    LD    (NXTCHR),DE
  736.     CALL    OPENF        ; Open selected file
  737.     JP    Z,ERROR        ; Abort if error
  738.     CALL    CRLF        ; New line
  739.     LD    A,NLINES-1    ; Set line count
  740.     LD    (PAGCNT),A
  741.     LD    BC,080H        ; Set character position and tab count
  742. TYPE2:    LD    A,C        ; Get character count
  743.     CP    80H
  744.     JR    C,TYPE3
  745.     PUSH    HL        ; Read next block
  746.     PUSH    BC
  747.     CALL    READF
  748.     POP    BC
  749.     POP    HL
  750.     JR    NZ,TYPE7
  751.     LD    C,0        ; Set character count
  752.     LD    HL,TBUFF    ; Poin to first character
  753. TYPE3:    LD    A,(HL)        ; Get next char
  754.     AND    7FH        ; Mask out msb
  755.     CP    1AH        ; End of file (^z)?
  756.     RET    Z        ; Restart cpr if so
  757.     CP    CR
  758.     JR    Z,TYPE4
  759.     CP    LF        ; Reset tab count?
  760.     JR    Z,TYPE4
  761.     CP    TAB        ; Tab?
  762.     JR    Z,TYPE5
  763.     CALL    LCOUT        ; Output char
  764.     INC    B        ; Increment tab count
  765.     JR    TYPE6
  766. TYPE4:    CALL    LCOUT        ; Output <CR> or <LF>
  767.     LD    B,0        ; Reset tab counter
  768.     JR    TYPE6
  769. TYPE5:    LD    A,' '        ; Space
  770.     CALL    LCOUT
  771.     INC    B        ; Increment position count
  772.     LD    A,B
  773.     AND    7
  774.     JR    NZ,TYPE5
  775. TYPE6:    INC    C        ; Increment char count
  776.     INC    HL        ; Pt to next char
  777.     CALL    BREAK        ; Check for abort
  778.     RET    Z        ; Restart if so
  779.     JR    TYPE2
  780. TYPE7:    DEC    A        ; No error?
  781.     RET    Z        ; Restart cpr
  782.     JP    ERROR
  783. SAVE:    CALL    NUMBER        ; Extract number from command line
  784.     LD    L,A        ; HL=page count
  785.     LD    H,0
  786.     PUSH    HL        ; Save page count
  787.     CALL    EXTEST        ; Test for existence of file
  788.     LD    C,16H        ; Bdos make file
  789.     CALL    GRBDOS
  790.     POP    HL        ; Get page count
  791.     JR    Z,SAVE3
  792.     XOR    A        ; Set record count field
  793.     LD    (FCBCR),A
  794.     CALL    ADVAN        ; Look for 's' for sector option
  795.     INC    DE        ; Pt to after 's' token
  796.     CP    SECTFLG
  797.     JR    Z,SAVE0
  798.     DEC    DE        ; No 's' token, so back up
  799.     ADD    HL,HL        ; Double it for HL=record (128 bytes)
  800. SAVE0:    LD    (NXTCHR),DE
  801.     LD    DE,TPA        ; Point to start of SAVE area (TPA)
  802. SAVE1:    LD    A,H        ; Done with save?
  803.     OR    L        ; HL=0 if so
  804.     JR    Z,SAVE2
  805.     DEC    HL        ; Count down on record
  806.     PUSH    HL        ; Save pointer to block to save
  807.     LD    HL,128        ; 128 bytes per record
  808.     ADD    HL,DE        ; Point to next record
  809.     PUSH    HL        ; Save on stack
  810.     CALL    DMASET        ; Set DMA address for write (addr in DE)
  811.     LD    DE,FCBDN    ; Write record
  812.     LD    C,15H        ; Bdos write record
  813.     CALL    BDOSB        ; Save bc
  814.     POP    DE        ; Get ptr to next record in DE
  815.     POP    HL        ; Get record count
  816.     JR    NZ,SAVE3
  817.     JR    SAVE1        ; Continue
  818. SAVE2:    LD    DE,FCBDN    ; Close saved file
  819.     CALL    CLOSE
  820.     INC    A        ; Error?
  821.     JR    NZ,SAVE4
  822. SAVE3:    CALL    PRNLE        ; Print 'no space' error
  823. SAVE4:    JP    DEFDMA        ; Set DMA to 0080 and restart cpr
  824. EXTEST:    CALL    SCANLOG        ; Extract file name and log in user/disk
  825.     JP    NZ,ERROR    ; '?' is not permitted
  826.     CALL    SEARF        ; Look for specified file
  827.     LD    DE,FCBDN    ; Point to file FCB
  828.     RET    Z        ; Ok if not found
  829.     PUSH    DE        ; Save pointer to FCB
  830.     CALL    PRINTC
  831.     DEFM    'ERASE',' '+80H
  832.     LD    HL,FCBFN    ; Point to file name field
  833.     CALL    PRFN        ; Print it
  834.     LD    A,'?'        ; Print question
  835.     CALL    CONOUT
  836.     CALL    CONIN        ; Get response
  837.     POP    DE        ; Get ptr to fcb
  838.     CP    'Y'        ; Key on yes
  839.     JP    NZ,ERR3        ; Restart as error if no
  840.     PUSH    DE        ; Save ptr to fcb
  841.     CALL    DELETE        ; Delete file
  842.     POP    DE        ; Get ptr to fcb
  843.     RET    
  844. REN:    CALL    EXTEST        ; Test for file existence and return
  845.     LD    A,(TEMPDR)    ; Save selected disk
  846.     PUSH    AF        ; Save on stack
  847. REN0:    LD    HL,FCBDN    ; Save new file name
  848.     LD    DE,FCBDM
  849.     LD    BC,16        ; 16 bytes
  850.     LDIR    
  851.     CALL    ADVAN        ; Advance to next character (non-delim)
  852.     JR    Z,REN4
  853. REN1:    LD    (NXTCHR),DE
  854.     CALL    SCANER        ; Extract FILENAME.TYP token
  855.     JR    NZ,REN4
  856.     POP    AF        ; Get old default drive
  857.     LD    B,A        ; Save it
  858.     LD    HL,TEMPDR    ; Compare it against selected drive
  859.     LD    A,(HL)        ; Default?
  860.     OR    A
  861.     JR    Z,REN2
  862.     CP    B        ; Check for drive error
  863.     JR    NZ,REN4
  864. REN2:    LD    (HL),B
  865.     XOR    A
  866.     LD    (FCBDN),A    ; Set default drive
  867.     LD    DE,FCBDN    ; Rename file
  868.     LD    C,17H        ; BDOS rename FCT
  869.     CALL    GRBDOS
  870.     RET    NZ
  871. REN3:    CALL    PRNNF        ; Print NO FILE message
  872. REN4:    JP    ERROR
  873. RSTJMP:    JP    RCPRNL        ; Restart cpr
  874. JUMP:    CALL    HEXNUM        ; Get load address in HL
  875.     JR    CALLPROG    ; Perform call
  876. GO:    LD    HL,TPA        ; Always to TPA
  877.     JR    CALLPROG    ; Perform call
  878. COM:    LD    A,(FCBFN)    ; Any command?
  879.     CP    ' '        ; ' ' means command was 'D:' to switch
  880.     JR    NZ,COM1
  881.     LD    A,(COLON)    ; Look for colon flag
  882.     OR    A        ; If zero, just blank
  883.     RET    Z        ; Return to main routine
  884.     LD    A,(TEMPUSR)    ; Get selected user
  885.     CP    10H        ; Make sure 4 bits
  886.     JP    NC,ERROR    ; Range error?
  887.     LD    (CURUSR),A    ; Set current user
  888.     CALL    SLOGIN        ; Log in user/disk as if temporarily
  889.     LD    A,(TEMPDR)    ; Get selected drive
  890.     OR    A        ; If 0 (default), no change
  891.     JR    Z,COM0
  892.     DEC    A        ; Adjust for log in
  893.     LD    (CURDR),A    ; Set current drive
  894. COM0:    JP    SETUD        ; Set current user/disk
  895. COM1:    LD    DE,FCBFT    ; Point to file type
  896.     LD    A,(DE)        ; Get first character of file type
  897.     CP    ' '        ; Must be blank, or error
  898.     JP    NZ,ERROR
  899.     LD    HL,COMMSG    ; Place default file type (com) into fcb
  900.     LD    BC,3        ; 3 bytes
  901.     LDIR    
  902.     LD    HL,TPA        ; Set execution/load address
  903.     PUSH    HL        ; Save for execution
  904.     CALL    MLOAD        ; Load memory with file specified
  905.     POP    HL        ; Get execution address
  906. CALLPROG: LD    (EXECADR),HL    ; Perform in-line code modification
  907.     CALL    SCANER        ; Search command line for next token
  908.     LD    HL,TEMPDR    ; Save pointer to drive specification
  909.     PUSH    HL
  910.     LD    A,(HL)        ; Set drive specification
  911.     LD    (FCBDN),A
  912.     LD    HL,FCBDN+10H    ; Pt to 2nd file name
  913.     CALL    SCANX        ; Scan for it and load it into fcb+16
  914.     POP    HL        ; Set up drive specs
  915.     LD    A,(HL)
  916.     LD    (FCBDM),A
  917.     XOR    A
  918.     LD    (FCBCR),A
  919.     LD    DE,TFCB        ; Copy to default FCB
  920.     LD    HL,FCBDN    ; From FCBDN
  921.     LD    BC,33        ; Set up default FCB
  922.     LDIR    
  923. CMDCH1    =    $+1
  924.     LD    HL,CMDLIN
  925. CALLP1:    LD    A,(HL)        ; Skip to end of 2nd file name
  926.     OR    A        ; End of line?
  927.     JR    Z,CALLP2
  928.     CP    CMDSEP
  929.     JR    Z,CALLP2
  930.     CP    ' '        ; End of token?
  931.     JR    Z,CALLP2
  932.     INC    HL
  933.     JR    CALLP1
  934. CALLP2:    LD    B,0        ; Set character count
  935.     LD    DE,TBUFF+1    ; Point to character position
  936. CALLP3:    LD    A,(HL)        ; Copy command line to TBUFF
  937.     LD    (DE),A
  938.     OR    A        ; Done if zero
  939.     JR    Z,CALLP5
  940.     CP    CMDSEP
  941.     JR    Z,CALLP4
  942.     INC    B        ; Increment character count
  943.     INC    HL        ; Point to next
  944.     INC    DE
  945.     JR    CALLP3
  946. CALLP4:    XOR    A
  947.     LD    (DE),A
  948. CALLP5:    LD    (NXTCHR),HL
  949.     LD    A,B        ; Save character count
  950.     LD    (TBUFF),A
  951.     CALL    CRLF        ; New line
  952.     CALL    DEFDMA        ; Set DMA to 0080
  953.     PUSH    AF
  954.     PUSH    BC
  955.     PUSH    DE
  956.     PUSH    HL
  957.     LD    A,5
  958.     RST    28H
  959.     LD    DE,BUFSIZ
  960.     LD    BC,128
  961.     EX    DE,HL
  962.     LDIR
  963.     POP    HL
  964.     POP    DE
  965.     POP    BC
  966.     POP    AF
  967. EXECADR    =    $+1
  968.     CALL    TPA        ; Call transient
  969.     CALL    DEFDMA        ; Set DMA to 0080 in case it was changed
  970.     CALL    DLOGIN        ; Login current user/disk
  971.     JP    CONT        ; Restart CPR and continue command
  972. GET:    CALL    HEXNUM        ; Get load address in hl
  973.     PUSH    HL        ; Save address
  974.     CALL    SCANER        ; Get file name
  975.     POP    HL        ; Restore address
  976.     JP    NZ,ERROR    ; Must be unambiguous
  977. MLOAD:    LD    (LOADADR),HL    ; Set load address
  978. MLA:    LD    A,DRVPFATT
  979.     LD    (SYSTST),A    ; Test flag in getsbit
  980.     CALL    SLOGIN        ; Look under temporary user/disk
  981.     CALL    SEARF        ; Look for file
  982. MLARUN:    LD    HL,PATH        ; Point to path for failure possibility
  983.     JR    NZ,MLA4
  984. MLA0:    LD    A,(HL)        ; Get drive
  985.     OR    A        ; 0=done=command not found
  986. NOCRUN:    JP    Z,ERROR
  987.     CP    CURIND        ; Current drive specified?
  988.     JR    NZ,MLA1
  989.     LD    A,(CURDR)    ; Get current drive
  990.     INC    A        ; Set a=1
  991. MLA1:    LD    (TEMPDR),A    ; Select different drive if not current
  992.     LD    A,1        ; Accept both SYS and DIR files
  993.     LD    (SYSTST),A    ; Test flag is 1 for both
  994.     INC    HL        ; Point to user number
  995.     LD    A,(HL)        ; Get user number
  996.     INC    HL        ; Poin to next entry in path
  997.     PUSH    HL        ; Save pointer
  998.     AND    7FH        ; Mask out system bit
  999.     CP    CURIND        ; Current user specified?
  1000.     JR    NZ,MLA2
  1001.     LD    A,(CURUSR)    ; Get current user number
  1002. MLA2:    LD    (TEMPUSR),A    ; Set temporary user number
  1003.     CPL
  1004.     AND    80H
  1005.     JR    NZ,MLA3
  1006.     LD    (SYSTST),A
  1007. MLA3:    CALL    SLOGIN
  1008. MLA3RT:    CALL    SEARF
  1009.     POP    HL
  1010.     JR    Z,MLA0
  1011. MLA4:    PUSH    HL
  1012.     CALL    GETSBIT
  1013.     POP    HL
  1014.     JR    Z,MLA0
  1015.     CALL    OPENF
  1016. LOADADR =    $+1
  1017.     LD    HL,TPA
  1018. MLA5:    LD    A,ENTRY/256-1
  1019.     CP    H        ; Are we going to overwrite the CPR?
  1020.     JR    C,PRNLE
  1021.     PUSH    HL        ; Save address of next sector
  1022.     EX    DE,HL        ; In DE
  1023.     CALL    DMASET        ; Set DMA address for load
  1024.     LD    DE,FCBDN    ; Read next sector
  1025.     CALL    READ
  1026.     POP    HL        ; Get address of next sector
  1027.     JR    NZ,MLA6
  1028.     LD    DE,128        ; Move 128 bytes per sector
  1029.     ADD    HL,DE        ; Point to next sector in HL
  1030.     JR    MLA5
  1031. MLA6:    DEC    A        ; Load complete
  1032.     JP    Z,DLOGIN    ; Ok if zero, else fall thru to prnle
  1033. PRNLE:    CALL    PRINTC
  1034.     DEFM    'FUL','L'+80H
  1035.     CALL    DLOGIN
  1036.     JP    RESTRT        ; Restart zcmd
  1037. PATH:    DEFM    '$$'
  1038.     DEFM    'A'-'@',0
  1039.     DEFB    0
  1040.     DEFS    48        ; STACK AREA
  1041. STACK:    DEFM    '$'
  1042.     END    
  1043. DLOGIN
  1044.     JP    RESTRT        ; Restart zcmd
  1045. PATH:    DEFM    '$$'
  1046.     DEFM    'A'-'@',0
  1047.     DEFB    0
  1048.     DEFS    48        ; STACK AREA
  1049. STACK:    DEFM    '$'