home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / z3util / resolv14.lbr / RESOLVE.ZZ0 / RESOLVE.Z80
Encoding:
Text File  |  1989-08-03  |  15.9 KB  |  703 lines

  1. ; RESOLVE.MAC       RESOLVE ZCPR3 COMMAND LINE
  2. ;
  3. ;
  4. ; This utility will resolve a multiple-command line passed to it and place
  5. ; that command line in the Multiple-Command Line Buffer in memory.
  6. ; It will resolve references to shell variables, registers, and System
  7. ; File names.  Each of these is signalled by a flag as follows.
  8. ;
  9. ;    Flag                Meaning
  10. ;    ----                -------
  11. ;     %<text>        Shell variable name.
  12. ;     $R<n>        Register number.  (n = 0-31)
  13. ;     $D        Current disk letter.
  14. ;     $U        Current user number.
  15. ;     $F<n>        System File name.  (n = 1-4)
  16. ;     $N<n>        System File name, chars 1-8 only.  (n = 1-4)
  17. ;     $T<n>        System File name, extension only.  (n = 1-4)
  18. ;     $|        Substitute multiple-command separator.
  19. ;
  20. ; The QUIET flag is adhered to; the program will not print its sign-on
  21. ; message or error messages if the QUIET flag is set.
  22. ;
  23. ; If there is no room for the command-line generated, the ERROR flag will
  24. ; be set, and an error message may be printed, depending upon the state
  25. ; of the QUIET flag.  Uninterpretable '$' parameters will also cause the
  26. ; error flag to be set.
  27. ;
  28. ; Author: Dreas Nielsen
  29. ;
  30. ; Shell variable file manipulation routines are adapted from Richard Conn's
  31. ; 'SH.MAC'
  32. ;
  33. ; History --
  34. ;    Version    Date        Comment
  35. ;    -------    ----        -------
  36. ;    1.0    3/2/86        Up and running -- RDN
  37. ;    1.1    1/13/87        Fixed error in which a shell variable reference
  38. ;                in the first character of another shell
  39. ;                variable wasn't being expanded.  Also changed
  40. ;                so that a single '$', when followed by an
  41. ;                unrecognized flag, is not dropped.
  42. ;    1.2    2/6/89        Fixed register expansion so it doesn't clobber
  43. ;                nesting depth stored in B.
  44. ;    1.2    2/11/89        Changed program banner to read "1.2"
  45. ;    1.3    3/5/89        Changed to allow register references up to
  46. ;                register 32 (0-31).
  47. ;    1.4    8/03/89        Removed all checking of quiet flag.  
  48. ;                Program banner now only displayed when
  49. ;                help requested.  Error handler is now
  50. ;                invoked on command line overflow.
  51. ;                Error flag now set on unresolved shell
  52. ;                variables and the leading '%' is no
  53. ;                longer returned in that case.  Editing 
  54. ;                on register numbers for the $r flag has
  55. ;                been tightened up.  Code cleaned up
  56. ;                somewhat; now requires version 4 SYSLIB
  57. ;                and Z3LIB.  This is now a type 3 program
  58. ;                but I do not recommend linking it for
  59. ;                high-memory execution since the Z3VARLIB
  60. ;                routines don't check for top of TPA.
  61. ;                Howard Goldstein
  62. ;
  63. ;
  64. VERS    EQU    14
  65. ;
  66. ;
  67. PARMFL    EQU    '/'    ; flag indicating parameter follows
  68. SUBCH    EQU    '%'    ; shell-variable reference flag
  69. SYSFLG    EQU    '$'    ; System File reference flag
  70. SUBSEP    EQU    '|'
  71. CMDSEP    EQU    ';'
  72. LECNT    EQU    20        ;number of pointers on String Ptr Stack
  73. CTRLZ    EQU    1AH        ;^Z for EOF
  74. FCB    EQU    5CH
  75. TBUFF    EQU    80H
  76. BDOS    EQU    5
  77. CR    EQU    0DH
  78. LF    EQU    0AH
  79. ;
  80. CMDLIN    EQU    80H    ; CP/M's command line buffer
  81. ;
  82. ;
  83. ; SYSLIB and Z3LIB routines
  84. ;
  85.     EXT    Z3INIT,PUTER2,GETREG,PUTCL,GETFNX,INVERROR
  86.     EXT    SKSP,MAFDC,FILLB,ISALNUM
  87.     EXT    CAPS,PRINT,CODEND
  88. ;
  89. ; Z3VARS routines
  90. ;
  91.     EXT    VARLOAD, VARDEF
  92. ;
  93. ;
  94. ; Program beginning
  95. ;
  96. ; TYPE 3 HEADER
  97.  
  98. ; Code modified as suggested by Charles Irvine to function correctly with
  99. ; interrupts enabled.  Program will abort with an error message when not
  100. ; loaded to the correct address (attempt to run it under CP/M or Z30).
  101.  
  102. entry:
  103.     jr    start0        ; Must use relative jump
  104.     DB    VERS        ;embed version number
  105.     db    'Z3ENV',3    ; Type-3 environment
  106. z3eadr:
  107.     dw    0        ; Filled in by Z33
  108.     dw    entry        ; Intended load address
  109.  
  110. start0:
  111.     ld    hl,0        ; Point to warmboot entry
  112.     ld    a,(hl)        ; Save the byte there
  113.     di            ; Protect against interrupts
  114.     ld    (hl),0c9h    ; Replace warmboot with a return opcode
  115.     rst    0        ; Call address 0, pushing RETADDR
  116.                 ; Onto stack
  117. retaddr:
  118.     ld    (hl),a        ; Restore byte at 0
  119.     dec    sp        ; Get stack pointer to point
  120.     dec    sp        ; To the value of RETADDR
  121.     pop    hl        ; Get it into HL and restore stack
  122.     ei            ; We can allow interrupts again
  123.     ld    de,retaddr    ; This is where we should be
  124.     xor    a        ; Clear carry flag
  125.     push    hl        ; Save address again
  126.     sbc    hl,de        ; Subtract -- we should have 0 now
  127.     pop    hl        ; Restore value of RETADDR
  128.     jr    z,start        ; If addresses matched, begin real code
  129.  
  130.     ld    de,notz33msg-retaddr; Offset to message
  131.     add    hl,de
  132.     ex    de,hl        ; Switch pointer to message into DE
  133.     ld    c,9
  134.     jp    0005h        ; Return via BDOS print string function
  135. notz33msg:
  136.     db    'Not Z33+$'    ; Abort message if not Z33-compatible
  137.  
  138. ;
  139. ; Initialize environment for Z3 routines
  140. START:    LD    HL,(Z3EADR)
  141.     CALL    Z3INIT
  142. ;
  143. ; Reset error flag
  144.     XOR    A
  145.     CALL    PUTER2
  146. ;
  147. ; Save stack and set new one
  148.     LD    (SAVESP),SP
  149.     LD    SP,STACK
  150. ;
  151. ; Set Pointers
  152.     CALL    CODEND        ;find scratch area
  153.     LD    (INTLINE),HL    ;set ptr to internal line buffer
  154.     LD    DE,200H        ;reserve 200H bytes
  155.     ADD    HL,DE
  156.     LD    (VARLIST),HL    ;set ptr to variable list
  157. ;
  158. ; Fill buffer of line to be built with zeroes to ensure that it remains
  159. ; null-terminated.
  160.     LD    HL,(INTLINE)
  161.     LD    D,H
  162.     LD    E,L
  163.     INC    DE
  164.     LD    BC,1FFH
  165.     LD    (HL),0
  166.     LDIR
  167. ;
  168. ; Point to CP/M's command line
  169.     LD    HL,CMDLIN
  170. ;
  171. ; Quit if no command line passed
  172.     LD    A,(HL)
  173.     OR    A
  174.     JP    Z,HELP
  175. ;
  176. ; Now parse command line.
  177. ; First look for option character.  Only option is help, which is exclusive.
  178.     LD    HL,CMDLIN+1
  179.     CALL    SKSP
  180.     LD    A,PARMFL
  181.     CP    (HL)
  182.     JR    NZ,EXPAND
  183.     INC    HL
  184.     CP    (HL)
  185.     JP    Z,HELP
  186.     DEC    HL
  187. ;
  188. ; Expand Command Line pointed to by HL, performing variable
  189. ;    substitutions
  190. ;
  191. ;    On exit, Z=command line overflow and Line Pted to by HL
  192. ;
  193. EXPAND:
  194.     EX    DE,HL        ;DE pts to line
  195. ;
  196. ; Init String Pointer Stack
  197. ;
  198.     LD    A,LECNT        ;set local element count
  199.     LD    (LOCELT),A
  200.     LD    HL,LOCSTK    ;set local stack
  201.     LD    (LOCADR),HL
  202.     LD    HL,0        ;set done code on stack
  203.     CALL    LOCPUSH        ;push HL
  204. ;
  205. ; Set Ptrs
  206. ;
  207.     LD    HL,(INTLINE)    ;pt to internal line
  208.     EX    DE,HL        ;DE pts to internal line, HL pt next char
  209.     LD    B,0        ;256 chars max
  210. ;
  211. ; Analyze Next Char
  212. ;
  213. EXP1:
  214.     LD    A,(HL)        ;get next char
  215.     CP    SYSFLG        ;system file or directory substitution?
  216.     JR    NZ,TEST2
  217.     CALL    SYSFIL
  218.     DEC    C
  219.     JR    Z,EXP1        ;no error on return
  220.     JR    EXP2        ;error on return - store offending char in CL
  221. ;
  222. TEST2:
  223.     CP    SUBCH        ;substitution char?
  224.     JR    NZ,EXP2
  225. ;
  226. ; Process Shell Variable
  227. ;
  228.     CALL    EXPVAR        ;resolve variable
  229.     DEC    C        ;error?
  230.     JR    Z,EXP1        ;resume if none
  231. ;
  232. ;
  233. ; Store Next Char
  234. ;
  235. EXP2:
  236.     LD    (DE),A        ;store char
  237.     INC    HL        ;point to next
  238.     INC    DE
  239.     DEC    B        ;count down
  240.     JR    Z,EXPERR    ;error if at 0
  241. ;
  242.     OR    A        ;done?  (was last char stored a null?)
  243.     JR    NZ,EXP1
  244.     INC    B        ;increment count (not counting last 0)
  245.     DEC    DE        ;pt to null in case another string to analyze
  246. ;
  247. ; Pop String Ptr Stack and Check for Analysis Complete
  248. ;
  249.     CALL    LOCPOP        ;get ptr to previous string
  250.     LD    A,H        ;done?
  251.     OR    L
  252.     JR    NZ,EXP1        ;resume
  253.     DEC    A        ;set NZ
  254. ;
  255. ; Expansion Complete
  256. ;    On entry, Z Flag is Set Accordingly (Z=Error)
  257. ;
  258. EXPERR:    JR    Z,EXPERR1
  259.     LD    HL,(INTLINE)    ;pt to internal line
  260.     CALL    PUTCL
  261.     JR    NZ,EXIT
  262. ;
  263. ; Print overflow message and set error flag
  264. EXPERR1:
  265.     CALL    PRINT
  266.     DB    CR,LF,'Command Line Overflow',CR,LF,0
  267.     LD    A,0FFH        ; indicate external error
  268.     LD    B,13        ;error code
  269.     CALL    INVERROR    ;set up to invoke error handler
  270. ;
  271. ; Return to ZCPR3
  272. ;
  273. EXIT:
  274.     LD    HL,(SAVESP)
  275.     LD    SP,HL
  276.     RET
  277. ;
  278. ; Expand Variable
  279. ;    Return with HL pting to next char, A=char, C=1 if OK, C=2 if error
  280. ;
  281. EXPVAR:
  282.     LD    (VARPTR),HL    ;save ptr to variable
  283.     INC    HL        ;get next char
  284.     LD    C,2        ;prep for error return
  285.     LD    A,(HL)        ;get it
  286.     OR    A        ;EOL?
  287.     RET    Z
  288.     CP    SUBCH        ;double sub char?
  289.     RET    Z        ;place one sub char in line if so
  290. ;
  291. ; Place Variable Into SHVAR
  292. ;
  293.     PUSH    BC        ;save counter
  294.     PUSH    DE        ;save ptr to next char
  295.     PUSH    HL        ;save ptr to shell variable
  296.     LD    HL,SHVAR    ;pt to shell variable buffer
  297.     LD    B,8        ;8 chars max
  298.     LD    A,' '        ;space fill
  299.     CALL    FILLB
  300.     EX    DE,HL        ;DE pts to shell variable buffer
  301.     POP    HL        ;pt to shell variable
  302.     LD    B,8        ;8 chars max
  303. ;
  304. ; Place Shell Variable into Buffer
  305. ;
  306. EXPV1:
  307.     LD    A,(HL)        ;get char
  308.     CALL    DELCK        ;check for delimiter
  309.     JR    NZ,EXPV3        ;done if delimiter
  310.     LD    (DE),A        ;save char
  311.     INC    HL        ;pt to next
  312.     INC    DE
  313.     DJNZ    EXPV1
  314. ;
  315. ; Flush Overflow of Shell Variable
  316. ;
  317. EXPV2:
  318.     LD    A,(HL)        ;get char
  319.     INC    HL        ;pt to next
  320.     CALL    DELCK        ;check for delimiter
  321.     JR    Z,EXPV2
  322.     DEC    HL        ;pt to delimiter
  323. ;
  324. ; Shell Variable in buffer SHVAR
  325. ;    HL pts to delimiter after variable in user line
  326. ;
  327. EXPV3:
  328.     CALL    LOCPUSH        ;stack ptr to next char in current string
  329.     JR    Z,EXPV4        ;error in stack
  330.     LD    HL,(VARLIST)
  331.     CALL    VARLOAD        ;load shell variable list
  332.     JR    NZ,EXPV4    ;failure
  333.     LD    HL,SHVAR
  334.     CALL    VARDEF        ;resolve named variable reference
  335.     JR    Z,EXPV5        ;name found - resolve
  336. ;
  337. ; Shell Variable Not Resolved - Restore Ptr to It
  338. ;
  339. EXPV4:
  340.     CALL    LOCPOP        ;restore ptr
  341.     POP    DE
  342.     POP    BC
  343.     LD    C,2        ;error
  344.     LD    HL,(VARPTR)    ;pt to variable
  345.     INC    HL        ;point past '%'
  346.     CALL    SETERR
  347.     LD    A,(HL)
  348.     RET
  349. ;
  350. ; Entry Point for OK Return
  351. ;
  352. EXPV5:
  353.     LD    A,(HL)        ;get char
  354.     POP    DE        ;pt to target
  355.     POP    BC        ;get counter
  356.     LD    C,1
  357.     RET    
  358.  
  359. ;
  360. ; Push HL onto String Ptr Stack
  361. ;    Return with Z if Stack Overflow
  362. ;
  363. LOCPUSH:
  364.     LD    A,(LOCELT)    ;get count
  365.     DEC    A        ;full?
  366.     RET    Z
  367.     LD    (LOCELT),A    ;set count
  368.     PUSH    DE        ;save DE
  369.     EX    DE,HL        ;DE pts to old string
  370.     LD    HL,(LOCADR)    ;get ptr to top of stack
  371.     LD    (HL),E        ;store low
  372.     INC    HL
  373.     LD    (HL),D        ;store high
  374.     INC    HL        ;pt to next
  375.     LD    (LOCADR),HL
  376.     EX    DE,HL        ;restore HL
  377.     POP    DE        ;restore DE
  378.     XOR    A        ;return NZ
  379.     DEC    A
  380.     RET    
  381. ;
  382. ; Pop HL from String Ptr Stack
  383. ;
  384. LOCPOP:
  385.     PUSH    DE
  386.     LD    A,(LOCELT)    ;increment element count
  387.     INC    A
  388.     LD    (LOCELT),A
  389.     LD    HL,(LOCADR)    ;get address
  390.     DEC    HL        ;pt to high
  391.     LD    D,(HL)        ;get high
  392.     DEC    HL        ;pt to low
  393.     LD    E,(HL)        ;get low
  394.     LD    (LOCADR),HL    ;set address
  395.     EX    DE,HL        ;restore ptr
  396.     POP    DE
  397.     RET    
  398. ;
  399. ; Check to see if char in A is a delimiter
  400. ;    Return with Z if so
  401. ;
  402. DELCK:
  403.     CALL    CAPS        ;capitalize char
  404.     JP    ISALNUM
  405. ;
  406. ;
  407. ; Print help message and exit.
  408. HELP:    CALL    PRINT
  409. ;    DB    'RESOLVE  v. ',(VERS/10)+'0','.',(VERS MOD 10)+'0',CR,LF
  410.     DB    'RESOLVE  v. ',[VERS/10]+'0','.',[VERS MOD 10]+'0',CR,LF
  411.     DB    'Resolve command line -- the following flags are '
  412.     DB    'interpreted:',CR,LF
  413.     DB    '    Flag          Meaning',CR,LF
  414.     DB    '    ----          -------',CR,LF
  415.     DB    '     %<text>     Shell variable name.',CR,LF
  416.     DB    '     $R<n>       Register number.  (n = 1-31)',CR,LF
  417.     DB    '     $D          Current drive letter.',CR,LF
  418.     DB    '     $U          Current user number.',CR,LF
  419.     DB    '     $F<n>       System File name.  (n = 1-4)',CR,LF
  420.     DB    '     $N<n>       System File, name only.',CR,LF
  421.     DB    '     $T<n>       System File, extension only.',CR,LF
  422.     DB    '     $|          Substitute command separator (;)',CR,LF
  423.     DB    0
  424.     JP    EXIT
  425. ;
  426. ;
  427. ;  EXPANSION ROUTINES
  428. ; The following routines each expand a particular kind of reference.
  429. ; Inputs : HL contains a pointer to the command line being interpreted;
  430. ;       DE points to the string being built.
  431. ; Outputs: C  contains an error flag: 2=error, 1=OK
  432. ;       HL points to the next char in the CL to interpret if no error (C=1)
  433. ;          points to last char interpreted if error (C=2)
  434. ;       DE points to the next location to fill in the CL being built
  435. ; If any of the flags are followed by incorrect parameters, the entire
  436. ; token, INCLUDING the leading dollar sign, is copied to the command line
  437. ; being built.
  438. ;
  439. SYSFIL:
  440.     INC    HL        ;point to next character
  441.     LD    C,1        ;prepare for no-error return
  442.     LD    A,(HL)        ;get character
  443.     OR    A        ;end of line?
  444.     JR    NZ,SYSF2
  445.     INC    C        ;indicate error
  446.     DEC    HL
  447.     CALL    SETERR
  448.     LD    A,(HL)
  449.     RET
  450. ;
  451. SYSF2:    CP    'F'        ;full filename?
  452.     JR    Z,FFNAME
  453.     CP    'N'        ;just the name?
  454.     JR    Z,FFNAME
  455.     CP    'T'        ;just the type?
  456.     JR    Z,FFNAME
  457.     CP    'D'        ;current drive?
  458.     JP    Z,CDRIV
  459.     CP    'U'        ;current useer?
  460.     JP    Z,CUSR
  461.     CP    'R'        ;register number?
  462.     JP    Z,REGR
  463.     CP    SUBSEP
  464.     JP    Z,SUBCHR
  465.     CALL    SETERR        ;otherwise, set Z3 error byte
  466.     DEC    HL        ;point back to sysflg
  467.     LD    A,(HL)
  468.     INC    C        ;and return with error indicator
  469.     RET
  470. ;
  471. ; Character is one of the 3 system file flags.  Get number of filename,
  472. ; then get full file name or appropriate part and insert in command line.
  473. ;
  474. FFNAME:
  475.     LD    (FNFLG),A    ;store flag
  476.     INC    HL        ;get number
  477.     LD    A,(HL)
  478.     OR    A
  479.     JR    Z,FFERR
  480. ;
  481. FFNAM2:    CALL    FNCHEK        ;check that number is in range 1-4
  482.     JR    Z,FFERR        ;quit if not
  483. ;
  484.     SUB    30H        ;convert to binary 1-4
  485.     PUSH    HL
  486.     CALL    GETFNX        ;get address of filename in HL
  487.     LD    A,(HL)        ;check for defined name
  488.     CP    ' '
  489.     JR    NZ,FFNAM4
  490. ;
  491.     POP    HL
  492.     INC    HL
  493.     LD    C,1        ;don't store char on return
  494.     RET
  495. ;
  496. FFNAM4:    PUSH    BC
  497.     LD    A,(FNFLG)    ;what do we want?
  498.     CP    'T'        ;type only?
  499.     JR    NZ,FFNAM5
  500.     PUSH    DE        ;save dest address
  501.     LD    DE,8
  502.     ADD    HL,DE        ;point to type
  503.     POP    DE
  504.     JR    FFNAM6
  505. FFNAM5:    CALL    TRANS8        ;transfer 1st 8 chars of filename
  506. ;
  507.     LD    A,(FNFLG)    ;again, what do we want?
  508.     CP    'N'        ;name only?
  509.     JR    Z,FFNAM7
  510.     LD    A,'.'        ;name transferred, now do period
  511.     LD    (DE),A
  512.     INC    DE
  513. ;
  514. FFNAM6:    CALL    TRANS3        ;transfer filetype
  515. FFNAM7:    POP    BC
  516.     POP    HL
  517.     INC    HL
  518.     LD    C,1        ;indicate all OK
  519.     RET
  520. ;
  521. FFERR:                ;erroneous file number
  522.     dec    hl
  523.     DEC    HL        ;point to SYSFLG
  524.     LD    A,(HL)
  525.     LD    C,2        ;store char on return
  526.     RET
  527. ;
  528. ;
  529. ; ================  FILENAME TRANSFER UTILITIES  ================
  530. ;
  531. ;
  532. ; Check whether char in A is in ASCII range '1'-'4'.  Set the error flag and
  533. ; return with Z set if out of range.
  534. ;
  535. FNCHEK:    CP    '1'        ;less than one?
  536.     JR    C,FNERR
  537.     CP    '5'        ; greater than four?
  538.     JR    NC,FNERR
  539.     OR    A        ;force NZ
  540.     RET
  541. ;
  542. FNERR:    CALL    SETERR
  543.     CP    A        ;set Z without disturbing A
  544.     RET
  545. ;
  546. ; Transfer 8 characters of filename from (HL) to (DE).  If fewer than 8 chars,
  547. ; increment HL to point past eighth anyway.  BC also used, not saved.
  548. ;
  549. TRANS8:    LD    B,8        ;# of chars in name
  550. TR82:    LD    A,(HL)
  551.     CP    ' '
  552.     JR    Z,TR83
  553.     LD    (DE),A
  554.     INC    HL
  555.     INC    DE
  556.     DJNZ    TR82
  557. TR83:    LD    A,B        ;were 8 chars transferred?
  558.     OR    A
  559.     RET    Z
  560. TR84:    INC    HL
  561.     DJNZ    TR84
  562.     RET
  563. ;
  564.  
  565. ; Transfer 3 characters of filename from (HL) to (DE).  BC is also used,
  566. ; not saved.  HL is NOT incremented past filename.
  567. ;
  568. TRANS3:    LD    B,3        ;transfer filetype
  569. TR32:    LD    A,(HL)
  570.     CP    ' '
  571.     RET    Z
  572.     LD    (DE),A
  573.     INC    HL
  574.     INC    DE
  575.     DJNZ    TR32
  576.     RET
  577. ; ================  END OF FILENAME TRANSFER UTILITIES  ================
  578. ;
  579. ;
  580. ; Character is substitute command-line separator.  If next character is the 
  581. ; same, preserve one of them.  Otherwise, replace it with the real command
  582. ; separator.
  583. ;
  584. SUBCHR:    LD    C,2        ;prepare for 'error' return
  585.     INC    HL        ;get next char
  586.     LD    A,(HL)
  587.     OR    A        ;premature end of CL?
  588.     RET    Z
  589. ;
  590. SUBCH2:    CP    SUBSEP        ;also sub. cmd. sep?
  591.     RET    Z        ;if so, return it
  592.     DEC    HL        ;else point before it
  593.     LD    A,CMDSEP    ;and return the real cmd. sep.
  594.     RET            ;('error' status will have it stored)
  595. ;
  596. ; Return current drive.
  597. ;
  598. CDRIV:    PUSH    HL
  599.     PUSH    DE
  600.     LD    C,19H
  601.     CALL    BDOS
  602.     ADD    A,'A'
  603.     POP    DE
  604.     POP    HL
  605.     LD    C,2        ;use char in A
  606.     RET
  607. ;
  608. ; Return current user #.
  609. ;
  610. CUSR:    PUSH    HL
  611.     PUSH    DE
  612.     LD    C,20H
  613.     LD    E,0FFH
  614.     CALL    BDOS        ;user # in A
  615.     POP    DE
  616.     CALL    MAFDC        ;up to 3 dec. digits stored at DE
  617.     POP    HL
  618.     INC    HL
  619.     LD    C,1
  620.     RET
  621. ;
  622. ; Get register #.
  623. ;
  624. REGR:    LD    C,2        ;prepare for error
  625.     INC    HL
  626.     LD    A,(HL)        ;get reg #
  627. ;
  628. REGR2:    SUB    '0'
  629.     CP    10        ;check for 0-9
  630.     JR    NC,REGERR
  631.     PUSH    DE        ;save dest. addr., to use reg for mult.
  632.     LD    D,A
  633.     INC    HL
  634.     LD    A,(HL)
  635.     SUB    '0'
  636.     CP    10
  637.     JR    C,REGR3
  638.     DEC    HL
  639.     LD    A,D
  640.     JR    REGR4
  641. REGR3:    LD    E,A
  642.     LD    A,D        ;multiply 1st digit by 10
  643.     ADD    A,A        ;x2
  644.     ADD    A,A        ;x4
  645.     ADD    A,D        ;x5
  646.     ADD    A,A        ;x10
  647.     ADD    A,E        ;add second digit
  648.     CP    32        ;check range -- 0-31
  649.     JR    C,REGR4
  650.     DEC    HL
  651.     POP    DE
  652. REGERR:    DEC    HL        ;point back to '$'
  653.     DEC    HL
  654.     CALL    SETERR
  655.     LD    A,(HL)
  656.     RET
  657. REGR4:    POP    DE        ;get destination addr back
  658.     PUSH    BC
  659.     LD    B,A        ;register # in B
  660.     PUSH    HL
  661.     CALL    GETREG        ;register value now in A
  662.     CALL    MAFDC        ;up to 3 dec. digits stored at DE
  663.     POP    HL
  664.     INC    HL
  665.     POP    BC
  666.     LD    C,1
  667.     RET
  668. ;
  669. ;
  670. ; Set transient error code byte.
  671. ;
  672. SETERR:    PUSH    AF
  673.     XOR    A
  674.     DEC    A
  675.     CALL    PUTER2
  676.     POP    AF
  677.     RET
  678. ;
  679. ;
  680. ; Buffers
  681. ;
  682.     DSEG
  683. ;
  684. SAVESP:    DS    2
  685.     DS    48
  686. STACK:    DS    2
  687. SHVAR:    DS    8
  688. LOCELT:
  689.     DS    1        ;string stack element count
  690. LOCADR:
  691.     DS    2        ;ptr to next entry on stack
  692. LOCSTK:
  693.     DS    LECNT*2        ;string ptr stack
  694. VARPTR:
  695.     DS    2        ;ptr to current variable in line
  696. FNFLG:    DS    1
  697. INTLINE:
  698.     DS    2        ;ptr internal expansion line
  699. VARLIST:
  700.     DS    2        ;list of shell variables.
  701.  
  702.     END    START
  703.