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

  1. ;
  2. ; Program: SH
  3. ; Author: Richard Conn
  4. ; Version: 1.0
  5. ; Date: 5 Mar 84
  6. ;
  7.  
  8. ;
  9. ;    This program illustrates the design of a simple shell under ZCPR3
  10. ; using Z3LIB.  This program is transportable from one ZCPR3 system to another
  11. ; provided it is reassembled with the correct address for the ZCPR3
  12. ; Environment Descriptor (Z3ENV) or DDT is used to patch this address
  13. ; (which is the first two bytes after the opening JMP).  If an external
  14. ; ZCPR3 Environment Descriptor is not available, one will have to be
  15. ; provided by setting the Z3ENV equate to 0 and providing SYSENV.LIB in
  16. ; the current directory at assembly time.
  17. ;
  18.  
  19. ;
  20. ; Equates for Key Values
  21. ;
  22. z3env    SET    0f400h    ;address of ZCPR3 environment
  23. lecnt    equ    20    ;number of pointers on String Ptr Stack
  24. ctrlz    equ    'Z'-'@'    ;^Z for EOF
  25. cmdch    equ    '!'    ;in comment mode, invoke following text as command
  26. cmtch    equ    ';'    ;comment character
  27. subch    equ    '%'    ;substitution flag
  28. fcb    equ    5ch
  29. tbuff    equ    80h
  30. cr    equ    0dh
  31. lf    equ    0ah
  32.  
  33. ;
  34. ; External Z3LIB and SYSLIB Routines
  35. ;
  36.     ext    getshm,putshm
  37.     ext    getud,putud,logud,initfcb,f$open,f$read,f$close
  38.     ext    parser,codend,caps,fillb,hmovb,root,getfn1,pfn1
  39.     ext    retud,print,pafdc,bbline,moveb,crlf,cout,sksp,dutdir
  40.     ext    z3init,getsh2,shpush,shpop,qshell,getefcb,putcl,putcst,putzex
  41.  
  42. ;
  43. ; Environment Definition
  44. ;
  45.     if    z3env ne 0
  46. ;
  47. ; External ZCPR3 Environment Descriptor
  48. ;
  49.     jmp    start
  50.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  51.     db    1    ;External Environment Descriptor
  52. z3eadr:
  53.     dw    z3env
  54. start:
  55.     lhld    z3eadr    ;pt to ZCPR3 environment
  56. ;
  57.     else
  58. ;
  59. ; Internal ZCPR3 Environment Descriptor
  60. ;
  61.     MACLIB    Z3BASE.LIB
  62.     MACLIB    SYSENV.LIB
  63. z3eadr:
  64.     jmp    start
  65.     SYSENV
  66. start:
  67.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  68.     endif
  69.  
  70. ;
  71. ; Start of Program -- Initialize ZCPR3 Environment
  72. ;
  73.     call    z3init    ;initialize the ZCPR3 Environment
  74. ;
  75. ; Set Pointers
  76. ;
  77.     call    codend    ;find scratch area
  78.     shld    intline    ;set ptr to internal line buffer
  79.     lxi    d,200H    ;reserve 200H bytes
  80.     dad    d
  81.     shld    varlist    ;set ptr to variable list
  82.     xra    a
  83.     sta    loadfl    ;say variables not loaded
  84. ;
  85. ; Check for Shell Stack
  86. ;
  87.     call    getsh2    ;get shell status
  88.     jnz    start0    ;skip over shell init
  89.     call    print
  90.     db    'No Shell Stack',0
  91.     ret
  92. ;
  93. ; See if this program was invoked as a shell
  94. ;
  95. start0:
  96.     call    qshell    ;find out from ZCPR3 environment
  97.     jz    shell    ;do not push onto stack if invoked as a shell
  98. start1:
  99. ;
  100. ; Clear Shell Message for Comment Flag
  101. ;
  102.     mvi    b,0    ;message 0
  103.     xra    a    ;A=0 to clear
  104.     call    putshm    ;set message
  105. ;
  106. ; Set Name of Shell Variable File if One is Given
  107. ;
  108.     call    getfn1    ;pt to buffer in env
  109.     lxi    d,fcb+1    ;pt to name
  110.     xchg        ;copy from name
  111.     mvi    b,11    ;11 bytes
  112.     mov    a,m    ;check for name
  113.     cpi    ' '    ;no name if space
  114.     jz    defname
  115.     call    moveb    ;copy if name present
  116.     call    setshdef    ;set default file type
  117.     jmp    setshn
  118. ;
  119. ; Set Name of SH.VAR File
  120. ;
  121. defname:
  122.     call    getfn1    ;get name
  123.     lxi    d,shvfcb+1    ;pt to FCB
  124.     xchg
  125.     mvi    b,11    ;11 chars
  126.     call    moveb
  127. ;
  128. ; Set Name of Shell from External FCB if Possible or From Default if Not
  129. ;
  130. setshn:
  131.     call    root    ;get root address
  132.     lxi    h,shdisk    ;pt to shell disk
  133.     mov    a,b    ;get disk
  134.     adi    'A'    ;convert to letter
  135.     mov    m,a    ;set disk letter
  136.     inx    h    ;pt to user 10's
  137.     mov    a,c    ;get user number
  138.     mvi    b,10    ;subtract 10's
  139.     mvi    d,'0'    ;set char
  140. setshn1:
  141.     sub    b    ;subtract
  142.     jc    setshn2
  143.     inr    d    ;increment digit
  144.     jmp    setshn1
  145. setshn2:
  146.     add    b    ;get 1's
  147.     mov    m,d    ;set 10's digit for user
  148.     inx    h    ;pt to 1's digit
  149.     adi    '0'    ;compute 1's digit
  150.     mov    m,a    ;set 1's digit
  151.     call    getefcb    ;get ptr to external fcb
  152.     jz    start2    ;no external FCB, so use default name
  153.     inx    h    ;pt to program name
  154.     lxi    d,shname    ;pt to string
  155.     mvi    b,8    ;8 chars
  156.     call    moveb    ;copy into buffer
  157. ;
  158. ; Push Name of Shell onto Stack
  159. ;
  160. start2:
  161.     lxi    h,shdisk    ;pt to name of shell
  162.     call    shpush    ;push shell onto stack
  163.     jnz    start3
  164. ;
  165. ; Shell Successfully Installed
  166. ;
  167.     call    print
  168.     db    'Shell Installed',0
  169.     ret
  170. ;
  171. ; Shell Stack Push Error
  172. ;
  173. start3:
  174.     cpi    2    ;shell stack full?
  175.     jnz    start4
  176. ;
  177. ; Shell Stack is Full
  178. ;
  179.     call    print
  180.     db    'Shell Stack Full',0
  181.     ret
  182. ;
  183. ; Shell Stack Entry Size is too small for command line
  184. ;
  185. start4:
  186.     call    print
  187.     db    'Shell Stack Entry Size',0
  188.     ret
  189. ;
  190. ; Restart on Empty Line
  191. ;
  192. shellr:
  193.     call    crlf    ;new line
  194. ;
  195. ; Print Shell Prompt
  196. ;
  197. shell:
  198.     call    retud    ;get current user and disk
  199.     mov    a,b    ;save disk
  200.     adi    'A'
  201.     call    cout    ;print disk letter
  202.     mov    a,c    ;get user
  203.     call    pafdc    ;print A as floating decimal
  204.     call    dutdir    ;convert into DIR reference if possible
  205.     jz    shell1    ;no match
  206.     mvi    a,':'    ;print colon
  207.     call    cout
  208.     mvi    b,8    ;8 chars max
  209. shell0:
  210.     mov    a,m    ;get char
  211.     inx    h    ;pt to next
  212.     cpi    ' '    ;space?
  213.     cnz    cout
  214.     jnz    shell0
  215. shell1:
  216.     mvi    b,0    ;get shell message 0
  217.     call    getshm
  218.     ani    1    ;test for prompt
  219.     jz    shell2    ;print normal prompt
  220.     call    print    ;comment format
  221.     db    '; ',0    ;comment
  222.     jmp    shell3
  223. shell2:    
  224.     call    print    ;normal format
  225.     db    '>> ',0    ;double prompt
  226. ;
  227. ; Accept User Input
  228. ;
  229. shell3:
  230.     mvi    a,1    ;tell ZEX that prompt is up
  231.     call    putzex
  232.     xra    a    ;don't capitalize
  233.     call    bbline
  234.     mvi    a,0    ;say that normal processing is running now
  235.     call    putcst
  236.     call    putzex
  237.     call    sksp    ;skip over leading spaces
  238.     mvi    b,0    ;get shell message 0
  239.     call    getshm
  240.     ani    1    ;test for comment
  241.     jz    shell4    ;process normally
  242. ;
  243. ; Process Shell Input as Comment
  244. ;
  245.     mov    a,m    ;get char
  246.     cpi    cmdch    ;command override?
  247.     jnz    shellr    ;continue with next line if not
  248.     inx    h    ;pt to command and fall thru to process
  249. ;
  250. ; Process Shell Command
  251. ;
  252. shell4:
  253.     mov    a,m    ;get first char
  254.     ora    a    ;no line?
  255.     jz    shellr
  256.     cpi    cmtch    ;comment line?
  257.     jz    shellr
  258. ;
  259. ; Check for and Process Shell-Resident Command
  260. ;
  261.     push    h    ;save HL
  262.     call    shcommand    ;check for shell command
  263.     pop    h    ;restore HL
  264. ;
  265. ; Expand Shell Command Line
  266. ;
  267.     call    expand    ;expand line pted to by HL
  268.     jz    clovfl    ;abort if overflow
  269. ;
  270. ; Load Multiple Command Line
  271. ;
  272.     call    putcl    ;place command line pted to by HL into CL Buffer
  273.     rnz        ;resume ZCPR3 processing
  274. ;
  275. ; Input Line is Longer than Command Line Buffer
  276. ;
  277. clovfl:
  278.     call    print    ;command line buffer has overflowed
  279.     db    cr,lf,'CL Ovfl ',0
  280.     jmp    shellr
  281. ;
  282. ; Expand Shell Command Line (pted to by HL), performing variable
  283. ;    Substitutions
  284. ;
  285. ;    On exit, Z=command line overflow and Line Pted to by HL
  286. ;
  287. expand:
  288.     push    b        ;save counter
  289.     mvi    b,0        ;get shell register 0
  290.     call    getshm
  291.     ani    2        ;test for echo
  292.     cnz    crlf        ;new line if SHECHO is ON
  293.     pop    b        ;get counter
  294.     xchg            ;DE pts to line
  295. ;
  296. ; Init String Pointer Stack
  297. ;
  298.     mvi    a,lecnt        ;set local element count
  299.     sta    locelt
  300.     lxi    h,locstk    ;set local stack
  301.     shld    locadr
  302.     lxi    h,0        ;set done code on stack
  303.     call    locpush        ;push HL
  304. ;
  305. ; Set Ptrs
  306. ;
  307.     lhld    intline        ;pt to internal line
  308.     xchg            ;DE pts to internal line, HL pt next char
  309.     mvi    b,0        ;256 chars max
  310. ;
  311. ; Analyze Next Char
  312. ;
  313. exp1:
  314.     mov    a,m        ;get next char
  315.     cpi    subch        ;substitution char?
  316.     jnz    exp2        ;handle normally
  317. ;
  318. ; Process Shell Variable
  319. ;
  320.     call    expvar        ;resolve variable
  321.     dcr    c        ;error?
  322.     jz    exp1        ;resume if none
  323. ;
  324. ; Store Next Char
  325. ;
  326. exp2:
  327.     stax    d        ;store char
  328. ;
  329. ; Print Char if SHECHO is ON
  330. ;
  331.     push    b        ;save counter
  332.     mov    c,a        ;save char
  333.     mvi    b,0        ;get shell message 0
  334.     call    getshm        ;determines if display is on
  335.     ani    2        ;test for echo
  336.     jz    exp3
  337.     mov    a,c        ;get char
  338.     ani    7FH        ;mask and don't output null
  339.     cnz    cout        ;echo char
  340. ;
  341. ; Advance to Next Char
  342. ;
  343. exp3:
  344.     mov    a,c        ;get char
  345.     pop    b        ;get counter
  346.     inx    h        ;pt to next
  347.     inx    d
  348.     dcr    b        ;count down
  349.     jz    experr        ;error if at 0
  350.     ora    a        ;done?
  351.     jnz    exp1
  352.     inr    b        ;increment count (not counting last 0)
  353.     dcx    d        ;pt to 0 in case of abort
  354. ;
  355. ; Pop String Ptr Stack and Check for Analysis Complete
  356. ;
  357.     call    locpop        ;get ptr to previous string
  358.     mov    a,h        ;done?
  359.     ora    l
  360.     jnz    exp1        ;resume
  361.     dcr    a        ;set NZ
  362. ;
  363. ; Expansion Complete
  364. ;    On entry, Z Flag is Set Accordingly (Z=Error)
  365. ;
  366. experr:
  367.     lhld    intline        ;pt to internal line
  368.     ret
  369.  
  370. ;
  371. ; Expand Variable
  372. ;    Return with HL pting to next char, A=char, C=1 if OK, C=2 if error
  373. ;
  374. expvar:
  375.     shld    varptr        ;save ptr to variable
  376.     inx    h        ;get next char
  377.     mvi    c,2        ;prep for error return
  378.     mov    a,m        ;get it
  379.     ora    a        ;EOL?
  380.     rz
  381.     cpi    subch        ;double sub char?
  382.     rz            ;place one sub char in line if so
  383. ;
  384. ; Place Variable Into SHVAR
  385. ;
  386.     push    b        ;save counter
  387.     push    d        ;save ptr to next char
  388.     push    h        ;save ptr to shell variable
  389.     lxi    h,shvar        ;pt to shell variable buffer
  390.     mvi    b,8        ;8 chars max
  391.     mvi    a,' '        ;space fill
  392.     call    fillb
  393.     xchg            ;DE pts to shell variable buffer
  394.     pop    h        ;pt to shell variable
  395.     mvi    b,8        ;8 chars max
  396. ;
  397. ; Place Shell Variable into Buffer
  398. ;
  399. expv1:
  400.     mov    a,m        ;get char
  401.     call    delck        ;check for delimiter
  402.     jz    expv3        ;done if delimiter
  403.     stax    d        ;save char
  404.     inx    h        ;pt to next
  405.     inx    d
  406.     dcr    b        ;count down
  407.     jnz    expv1
  408. ;
  409. ; Flush Overflow of Shell Variable
  410. ;
  411. expv2:
  412.     mov    a,m        ;get char
  413.     inx    h        ;pt to next
  414.     call    delck        ;check for delimiter
  415.     jnz    expv2
  416.     dcx    h        ;pt to delimiter
  417. ;
  418. ; Shell Variable in buffer SHVAR
  419. ;    HL pts to delimiter after variable in user line
  420. ;
  421. expv3:
  422.     call    locpush        ;stack ptr to next char in current string
  423.     jz    expv4        ;error in stack
  424.     call    varload        ;load shell variable list
  425.     jz    expv4        ;failure
  426.     call    namer        ;resolve named variable reference
  427.     mvi    c,1        ;OK
  428.     jz    expv5        ;name found - resolve
  429. ;
  430. ; Shell Variable Not Resolved - Restore Ptr to It
  431. ;
  432. expv4:
  433.     call    locpop        ;restore ptr
  434.     mvi    c,2        ;error
  435.     lhld    varptr        ;pt to variable
  436. ;
  437. ; Entry Point for OK Return
  438. ;
  439. expv5:
  440.     mov    a,m        ;get char
  441.     pop    d        ;pt to target
  442.     pop    b        ;get counter
  443.     ret
  444.  
  445. ;
  446. ; Push HL onto String Ptr Stack
  447. ;    Return with Z if Stack Overflow
  448. ;
  449. locpush:
  450.     lda    locelt        ;get count
  451.     dcr    a        ;full?
  452.     rz
  453.     sta    locelt        ;set count
  454.     push    d        ;save DE
  455.     xchg            ;DE pts to old string
  456.     lhld    locadr        ;get ptr to top of stack
  457.     mov    m,e        ;store low
  458.     inx    h
  459.     mov    m,d        ;store high
  460.     inx    h        ;pt to next
  461.     shld    locadr
  462.     xchg            ;restore HL
  463.     pop    d        ;restore DE
  464.     xra    a        ;return NZ
  465.     dcr    a
  466.     ret
  467. ;
  468. ; Pop HL from String Ptr Stack
  469. ;
  470. locpop:
  471.     push    d
  472.     lda    locelt        ;increment element count
  473.     inr    a
  474.     sta    locelt
  475.     lhld    locadr        ;get address
  476.     dcx    h        ;pt to high
  477.     mov    d,m        ;get high
  478.     dcx    h        ;pt to low
  479.     mov    e,m        ;get low
  480.     shld    locadr        ;set address
  481.     xchg            ;restore ptr
  482.     pop    d
  483.     ret
  484.  
  485.  
  486. ;
  487. ; Load Shell Variable List
  488. ;
  489. varload:
  490.     push    h        ;save regs
  491.     push    d
  492.     push    b
  493.     lda    loadfl        ;already loaded?
  494.     ora    a        ;NZ=yes
  495.     jnz    varl3
  496.     lhld    varlist        ;clear varlist in case of error
  497.     mvi    m,ctrlz
  498. ;
  499. ; Look for Variable File
  500. ;
  501.     call    getfn1        ;pt to file name of SH.VAR
  502.     lxi    d,shvfcb+1
  503.     mvi    b,11        ;11 bytes
  504.     call    moveb
  505.     call    putud        ;save current location
  506.     call    root        ;determine DU of root
  507.     call    logud        ;goto root
  508.     lhld    varlist        ;pt to named variable list
  509.     lxi    d,shvfcb    ;try to open file
  510.     call    initfcb        ;init FCB
  511.     call    f$open
  512.     jz    varl1
  513. ;
  514. ; Variable File Not Found
  515. ;
  516.     call    getud        ;return home
  517.     xra    a        ;set not found code
  518.     pop    b        ;restore regs
  519.     pop    d
  520.     pop    h
  521.     ret
  522. ;
  523. ; Read in Variable File
  524. ;
  525. varl1:
  526.     lxi    d,shvfcb    ;read in file
  527.     call    f$read
  528.     jnz    varl2
  529.     lxi    d,tbuff        ;pt to data
  530.     xchg            ;copy into memory
  531.     mvi    b,128        ;128 bytes
  532.     call    hmovb
  533.     xchg
  534.     jmp    varl1
  535. varl2:
  536.     lxi    d,shvfcb    ;close file
  537.     call    f$close
  538.     call    getud        ;return home
  539. ;
  540. ; Say List is Already Loaded
  541. ;
  542. varl3:
  543.     xra    a        ;return NZ for OK
  544.     dcr    a
  545.     sta    loadfl        ;set loaded flag
  546.     pop    b        ;restore regs
  547.     pop    d
  548.     pop    h
  549.     ret
  550.  
  551. ;
  552. ; Resolve Named Variable Reference
  553. ;    On input, SHVAR contains the shell variable name and
  554. ;    CODEND pts to the list of shell variables, terminated by ^Z;
  555. ;    if found, return with HL pting to name and Z
  556. ;
  557. namer:
  558.     lhld    varlist        ;pt to variable list
  559. namer1:
  560.     mov    a,m        ;get char
  561.     cpi    ctrlz        ;end of list?
  562.     jz    namex
  563.     lxi    d,shvar        ;pt to shell variable name
  564.     mvi    b,8        ;8 chars
  565. namer2:
  566.     ldax    d        ;get name
  567.     cmp    m        ;match?
  568.     jnz    nomatch
  569.     inx    h        ;pt to next
  570.     inx    d
  571.     dcr    b        ;count down
  572.     jnz    namer2
  573.     ret            ;found!
  574. nomatch:
  575.     mov    a,m        ;flush to end of string
  576.     inx    h        ;pt to next
  577.     ora    a
  578.     jnz    nomatch
  579.     jmp    namer1        ;resume search
  580. ;
  581. ; Search Failed
  582. ;
  583. namex:
  584.     ora    a        ;return NZ (^Z in A)
  585.     ret
  586. ;
  587. ; Check to see if char in A is a delimiter
  588. ;    Return with Z if so
  589. ;
  590. delck:
  591.     push    h        ;pt to table
  592.     push    b        ;save BC
  593.     call    caps        ;capitalize char
  594.     mov    b,a        ;char in B
  595.     lxi    h,dtable    ;pt to delimiter table
  596. delck1:
  597.     mov    a,m        ;get delimiter
  598.     ora    a        ;done?
  599.     jz    notdel
  600.     cmp    b        ;compare
  601.     jz    yesdel
  602.     inx    h        ;pt to next
  603.     jmp    delck1
  604. notdel:
  605.     mov    a,b        ;get char
  606.     ora    a        ;set Z if null, else NZ
  607. yesdel:
  608.     mov    a,b        ;restore char
  609.     pop    b        ;restore regs
  610.     pop    h
  611.     ret
  612.  
  613. ;
  614. ; Delimiter Table
  615. ;
  616. dtable:
  617.     db    '<>;:,.=-_ ',0
  618.  
  619. ;
  620. ; Check for Shell Command and Process if Found
  621. ;    HL pts to command line
  622. ;
  623. shcommand:
  624.     xra    a        ;DIR before DU
  625.     call    parser        ;parse command line pted to by HL
  626.     inx    d        ;pt to name
  627.     lxi    h,ctable    ;pt to command table
  628. shcmd:
  629.     mov    a,m        ;get first char of next entry
  630.     ora    a        ;done?
  631.     rz
  632.     mvi    b,8        ;commands are 8 chars long
  633.     push    h        ;save ptr to FCB
  634.     push    d        ;save ptr to table entry
  635. shcmd1:
  636.     ldax    d        ;compare
  637.     cmp    m
  638.     jnz    shcmd2
  639.     inx    h        ;pt to next
  640.     inx    d
  641.     dcr    b        ;count down
  642.     jnz    shcmd1
  643. ;
  644. ; Command Found - Get Address
  645. ;
  646.     mov    a,m
  647.     inx    h
  648.     mov    h,m
  649.     mov    l,a        ;HL is address
  650. ;
  651. ; Clear Stack and Run
  652. ;
  653.     pop    psw        ;clear stack
  654.     pop    psw
  655.     pop    psw        ;clear return address
  656.     pop    psw        ;clear pushed HL
  657.     pchl            ;"run" command
  658. ;
  659. ; Command Not Found Yet
  660. ;
  661. shcmd2:
  662.     pop    d        ;restore ptrs
  663.     pop    h
  664.     lxi    b,10        ;advance to next command
  665.     dad    b
  666.     jmp    shcmd        ;resume search
  667.  
  668. ;
  669. ; If File Type not Specified, Set Default
  670. ;
  671. setshdef:
  672.     call    getfn1        ;check for file type
  673.     lxi    d,8        ;pt to file byte
  674.     dad    d
  675.     xchg
  676.     lxi    h,shvtype    ;default file type
  677.     mvi    b,3        ;3 chars
  678.     ldax    d        ;get char
  679.     cpi    ' '        ;set if space
  680.     cz    moveb        ;copy
  681.     ret
  682. ;
  683. ; Pop Current Shell
  684. ;
  685. shexit:
  686.     call    print
  687.     db    cr,lf,'Exiting Shell',0
  688.     jmp    shpop    ;clear shell stack entry
  689.  
  690. ;
  691. ; Toggle Shell Comment Mode
  692. ;
  693. shcomment:
  694.     mvi    b,0    ;access shell register 0
  695.     call    getshm
  696.     mov    c,a    ;save in C
  697.     ani    0FEH    ;all bits but comment bit
  698.     mov    d,a
  699.     mov    a,c    ;get comment bit
  700.     cma        ;flip comment bit (other bits are 1)
  701.     ani    1    ;select just comment bit
  702.     ora    d    ;OR in other bits
  703.     call    putshm    ;set new value
  704.     jmp    shellr    ;resume
  705. ;
  706. ; Toggle Shell Echo Mode
  707. ;
  708. shecho:
  709.     call    print
  710.     db    cr,lf,' Echo of Shell Commands is O',0
  711.     mvi    b,0    ;access shell register 0
  712.     call    getshm
  713.     mov    c,a    ;save in C
  714.     ani    0FDH    ;all bits but echo bit
  715.     mov    d,a
  716.     mov    a,c    ;get comment bit
  717.     cma        ;flip comment bit (other bits are 1)
  718.     ani    2    ;select just echo bit
  719.     ora    d    ;OR in other bits
  720.     call    putshm    ;set new value
  721.     ani    2    ;test echo bit
  722.     jz    shecho1
  723.     call    print
  724.     db    'N',0
  725.     jmp    shellr
  726. shecho1:
  727.     call    print
  728.     db    'FF',0
  729.     jmp    shellr    ;resume
  730.  
  731. ;
  732. ; Print Names of SH Commands
  733. ;
  734. shhelp:
  735.     call    print
  736.     db    cr,lf,'SH Commands --',cr,lf,0
  737.     lxi    h,ctable    ;pt to table
  738.     mvi    c,0        ;set count
  739. shh1:
  740.     mov    a,m        ;done?
  741.     ora    a
  742.     jz    shellr
  743.     call    print
  744.     db    '  ',0
  745.     mvi    b,8        ;8 chars
  746. shh2:
  747.     mov    a,m        ;get char
  748.     call    cout
  749.     inx    h        ;pt to next
  750.     dcr    b        ;count down
  751.     jnz    shh2
  752.     inr    c        ;increment count
  753.     mov    a,c
  754.     ani    3        ;new line?
  755.     cz    crlf
  756.     inx    h        ;skip address
  757.     inx    h
  758.     jmp    shh1        ;next
  759.  
  760. ;
  761. ; Command Table
  762. ;
  763. ctable:
  764.     db    '?       '    ;help
  765.     dw    shhelp
  766.     db    'SHCMT   '    ;comment mode
  767.     dw    shcomment
  768.     db    'SHECHO  '    ;echo input
  769.     dw    shecho
  770.     db    'SHEXIT  '    ;exit shell
  771.     dw    shexit
  772.     db    0        ;end of table
  773.  
  774. ;
  775. ; Buffers
  776. ;
  777. shvfcb:
  778.     db    0
  779.     db    'SH      '    ;name of shell variable file
  780. shvtype:
  781.     db    'VAR'
  782.     ds    24        ;36 bytes total
  783. shdisk:
  784.     db    'A'        ;disk letter
  785.     db    '00'        ;user number
  786.     db    ':'        ;separator
  787. shname:
  788.     db    'SH      ',0    ;name of shell to go onto stack
  789. shvar:
  790.     db    '        '    ;shell variable
  791. locelt:
  792.     ds    1        ;string stack element count
  793. locadr:
  794.     ds    2        ;ptr to next entry on stack
  795. locstk:
  796.     ds    lecnt*2        ;string ptr stack
  797. varptr:
  798.     ds    2        ;ptr to current variable in line
  799. varlist:
  800.     ds    2        ;ptr to named variable list
  801. intline:
  802.     ds    2        ;ptr internal expansion line
  803. loadfl:
  804.     ds    1        ;variables loaded flag
  805.  
  806.     end
  807.