home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol078 / shell.mac < prev    next >
Encoding:
Text File  |  1984-04-29  |  13.8 KB  |  577 lines

  1.         aseg
  2.     org    0100h
  3.     .z80
  4. ;********************************************************
  5. ;*                            *
  6. ;*                                   *
  7. ;*      SHELL V4.4   Barrie Hall 5/3/1982        *
  8. ;*      ---------------------------------         *
  9. ;*     This program simulates CPM submit.         *
  10. ;*                            *
  11. ;*    Bugs, comments, abuse to:            *
  12. ;*        Barrie Hall                *
  13. ;*        3 Maycock St                *
  14. ;*        East Denistone                *
  15. ;*        2112 NSW, Australia            *
  16. ;*        ph: 802200 a.h                *
  17. ;*     OR                         *
  18. ;*         leave a message on Software Tools        *
  19. ;*       RCPM on Sydney (02)997-1836            *
  20. ;*                            *
  21. ;*                            *    
  22. ;* The first form will load the named command file into    *
  23. ;* characters to CP/M one at a time. If a $<1..9> is    *
  24. ;* encoutered, a string will be substituted.        *
  25. ;* This string comes from the command line, it is the    *
  26. ;* nth space bounded string typed.            *
  27. ;*                            *
  28. ;*  0A>sh <filename> par1 par2 ... parN             *
  29. ;*                            *
  30. ;*  0A>sh   ;typed with a blank command line        *
  31. ;*                            *
  32. ;* will invoke the INTERACTIVE mode. Shell will prompt    *
  33. ;* with a single ">" and wait for you to type a command    *
  34. ;* lines.  The  lines are  transfered  to  the command     *
  35. ;* Buffer after each <CR> , to exit, type a "@", the    *
  36. ;* command lines are now passed to CP/M, one char at a    *
  37. ;* time.                        *
  38. ;*                            *
  39. ;* 0A>sh                        *
  40. ;* >type hmm.txt                    *
  41. ;* >type hello.asm                    *
  42. ;* >stat :dsk                        *
  43. ;* >@                            *
  44. ;*------------------------------------------------------*
  45. ;* Now the system executes those commands        *
  46. ;*------------------------------------------------------*
  47. ;*                            *
  48. ;*     Advantages over CP/M submit/xsub        *
  49. ;*     --------------------------------        *
  50. ;* SHELL will work with ANY program using CONSOLE input.*
  51. ;*                            *
  52. ;* SHELL is memory based, not disk based, so it runs    *
  53. ;* much more quickly, with no disk accesss to fetch    *
  54. ;* commands.                        *
  55. ;*                            *
  56. ;* SHELL has an interactive mode for sequences you dont    *
  57. ;* want to write a submit file for, but still want to    *
  58. ;* execute in a "BATCH MODE", like  lots of printing    *
  59. ;* or compilation.                    *
  60. ;*                            *
  61. ;* Errors,panic exit                    *
  62. ;* -----------------                    *
  63. ;* If SHELL cant find your SUBMIT file, it will tell    *
  64. ;* you, and exit.                    *
  65. ;*                            *
  66. ;* If your submit file trys to use parameters that you    *
  67. ;* didn't type, it will exit with a warm boot, With NO    *
  68. ;* message...                        *
  69. ;*                            *
  70. ;* If you hit a key while SHELL has control of the    *
  71. ;* keyboard calls, it will exit with a warm boot.    *
  72. ;*                            *
  73. ;*      Converting SUBMIT files to SHELL files    *
  74. ;*      --------------------------------------    *
  75. ;*  Simple, just delete the XSUB command if its there...*
  76. ;*                            *
  77. ;*                            *
  78. ;*         Installation-operation            *
  79. ;*         ----------------------            *
  80. ;* This prog runs hidden from CP/M, SO you have    to find    *
  81. ;* about 220 bytes + Buffer size of memory above your    *
  82. ;* BIOS, or between your BIOS and CP/M, if you have    *
  83. ;* some    there.                        *
  84. ;*                            *
  85. ;* Be SURE you know what you are doing here, but if your*
  86. ;* BIOS finishes before the end of memory (including     *
  87. ;* sector buffers ,etc) the memory above it is probably    *
  88. ;* ok to use.                        *
  89. ;*                            *
  90. ;* A lot of systems use a memory mapped video board,    *
  91. ;* there is usually some unused memory above this.    *
  92. ;*                            *
  93. ;* Equate the first location of this memory to DEST.    *
  94. ;*                            *
  95. ;* SECTORS defines how big a command buffer you want,    *
  96. ;* 1/2k is more than enough for 99% of submit files,    *
  97. ;* 1/4k is probably ok.                    *
  98. ;*                             *
  99. ;* Shell intercepts BIOS keyboard calls, CP/M thinks its*
  100. ;* coming from the keyboard, so SHELL will work with ANY*
  101. ;* program that uses keyboard input normally.        *
  102. ;*                            *
  103. ;* Any calls to BIOS keyboard status will return 00,    *
  104. ;* (no chars), so if a program hangs under SHELL, thats    *
  105. ;* why. (I havent found any yet)            *
  106. ;*                            *
  107. ;* Use M80 to assemble this program, I don't know about    *
  108. ;* ZASM. SHELL uses M80's ".phase" op, which allows you    *
  109. ;* to assemble code to run at a location different from *
  110. ;* the load address. Once SHELL has loaded a command    *
  111. ;* file from disk or interactively. It will block move    *
  112. ;* 220 bytes of runtime stuff to your high mem and then *
  113. ;* hook into the BIOS jump table. When it runs out of    *
  114. ;* chars, it does a normal RETURN, (NOT WARM BOOT), so    *
  115. ;* you can stay in the last program loaded.        *
  116. ;*                            *
  117. ;* If you hit ANY KEY while SHELL is in control, SHELL    *
  118. ;* will remove its hooks and warm boot the system.    *
  119. ;*                            *
  120. ;*          Improvements                *
  121. ;*          ------------                *
  122. ;* It is very easy to add some SIMPLE control structures*
  123. ;* like a LOOP--ENDLOOP with a constant number iter-    *
  124. ;* ations and a variable parameter number so we could     *
  125. ;* do this:                        *
  126. ;*                             *
  127. ;*    #loop 5                        *
  128. ;*    cc1 $n                        *
  129. ;*    #end                        *
  130. ;*           :this would compile five programs named on    *
  131. ;* the command line after sh <file>. I plan to do this     *
  132. ;* when I get some time, BUT MAYBE you could do it for    *
  133. ;* yourself????                        *
  134. ;*                            *
  135. ;*        Barrie Hall , August 1982        *
  136. ;*                            *
  137. ;********************************************************
  138. ;
  139. ; History - most recent first.
  140. ; ---------------------------
  141. ; Doco added to front: 4/8/1982 bjh
  142. ;
  143. ;
  144. ;update: 22/7/82  expands 1-9 parameters in the command lin
  145. ;bjh 
  146. ;
  147. ;update: 21/7/82 ,only Warm Boots when a key has
  148. ;     been hit, otherwise, returns to sender
  149. ;
  150. ; update: 18/7/82 to ret to ccp instead of warm boot
  151. ; bjh.
  152. ;
  153. ;-------------------------------------------------------
  154. dest    equ    0f800h        ;my spare memory
  155. sectors    equ    2        ;1/2k of commands???
  156. fdos    equ    0005h
  157. fcb    equ    005ch
  158. fcbcr    equ    fcb+32
  159. cmdbuf    equ    80h       ;cpm command line tail
  160. true    equ    0
  161. false    equ    not true    ;a lie???
  162.  
  163. ;main program
  164. ;fcb is default fcb at 5c
  165. ; work out how big our tpa is
  166. ; get fdos addr from 6 and 7
  167. ;
  168. ; This program runs hidden from cpm
  169. ; at f800h so we must do a block move
  170. ; before execution
  171. bmove::    ld    hl,start
  172.     ld    de,dest
  173.     ld    bc,len-dest
  174.     ldir
  175. ;moved the runtime stuff up high
  176. ;***************************************************
  177. ;* We must check for a filename on the command line
  178. ;* If there is one, skip it and get the parameters
  179. ;* from the command line and put them in the 
  180. ;* parameter buffers 1-9.
  181. ;*  If there is NO file name, enter interactive mode.
  182. ;****************************************************
  183.  
  184. parse::    ld    hl,cmdbuf
  185.     ld    a,(hl)
  186.     cp    0
  187.     jp    z,inter        ;interactive mode
  188.  
  189. ;move the command tail to a safe place
  190.     ld    hl,cmdbuf
  191.     ld    de,param
  192.     ld    c,a
  193.     inc    c
  194.     ld    b,0
  195.     ldir        ;move it
  196.  
  197. stfil::    xor    a
  198.     ld    (fcbcr),a     ;clear current rec field
  199. getfil::
  200.     ld    de,fcb
  201.     call    open
  202.     ld    de,opmess
  203.     cp    0ffh
  204.     jp    z,error
  205. ; file is open, now read it in
  206.     ld    hl,buff        ;hl is buff pointer
  207.     ld    b,sectors    ;read B sectors maximum
  208. rloop::    ld    d,h
  209.     ld    e,l
  210.     call    setdma    ;update dma for read
  211.     ld    de,fcb
  212.     call    read
  213.     cp    0
  214.     jr    nz,endfil
  215.     ld    de,128    ;sector size
  216.     add    hl,de
  217.     djnz    rloop    ;next sector
  218.  
  219. ;file read in
  220.  
  221. ;
  222. ; the rest of prog
  223. ;NOW we have the command file in memory
  224. ;lets hook into the bios, first we have 
  225. ;to compute the address of the jump table
  226. ;at the front of the bios.
  227. ;
  228. endfil::
  229. ghook::    ld    hl,(01h)  ;address of warm boot
  230.     ld    bc,0004h  ;offset to consts:
  231.     add    hl,bc
  232.     ld    a,(hl)
  233.     ld    (kbst),a
  234.     inc    hl
  235.     ld    a,(hl)
  236.     ld    (kbst+1),a
  237.     inc    hl
  238.     inc    hl
  239.     ld    (hokad),hl  ;save for later
  240.     ld    a,(hl)    ;save real conin add
  241.     ld    (kb),a
  242.     inc    hl
  243.     ld    a,(hl)
  244.     ld    (kb+1),a
  245.     dec    hl
  246.     ld    (hl),low hook
  247.     inc    hl
  248.     ld    (hl),high hook
  249.     ld    de,logon
  250.     ld    a,false
  251.     ld    (pflag),a
  252.     ld    hl,buff
  253.     ld    (point),hl
  254. ;the hooks are in so return to cpm and stand back???
  255. error::    call    pmess
  256.     ret
  257.  
  258. inter::                ;interactive mode
  259.  
  260. ;this mode is invoked when there is no file name
  261. ;on the command line..
  262. ;we must print a prompt and read a LINE of input
  263. ;from CPM and then transfer it to the SHELL buffer
  264. ;when we get a blank line,execute the line by
  265. ;installing the shell hooks...
  266.  
  267.     ld    hl,buff
  268.     ld    (point),hl    ;set up pointer into cmd
  269. prmt::    ld    e,'>'
  270.     call    cout
  271.     ld    de,interbuf
  272.     ld    a,40h        ;longest line
  273.     ld    (de),a
  274.     call    lchin
  275.     call    crlf
  276.     ld    de,(point)
  277.     ld    hl,interbuf+1    ;chars in the interbuff
  278.     ld    a,(hl)
  279.     cp    00        ;blank line???
  280.     jr    z,blank        ;do it
  281.     ld    c,a
  282.     inc    hl
  283.     ld    a,(hl)        ;first char of line
  284.     cp    '@'        ;exit condition 
  285.     jr    z,exec        ;go and do it...
  286.     ld    b,0
  287.     ldir            ;move a line into final buff
  288. blank::    ld    a,0dh        ;carraige ret
  289.     ld    (de),a
  290.     inc    de
  291.     ld    (point),de    ;for next line
  292.     jr    prmt        ;next line...
  293. exec::    ld    hl,(point)
  294.     ld    (hl),1ah    ;EOF
  295.     inc    hl
  296.     ld    (hl),1ah    ;EOF - just in case...
  297.     jr    endfil
  298.  
  299. ;cpm routines
  300.  
  301. crlf:    ld    e,0ah
  302.     call    cout
  303.     ld    e,0dh
  304.     call    cout
  305.     ret
  306. ;    
  307. cout:    push    bc
  308.     push    de
  309.     push    hl
  310.     ld    c,2
  311.     jr    cpm
  312. ;
  313. chin:    push    bc
  314.     push    de
  315.     push    hl    
  316.     ld    c,1    
  317.     jr    cpm
  318. ;
  319. lchin::    push    bc
  320.     push    de
  321.     push    hl
  322.     ld    c,10
  323.     jr    cpm
  324.  
  325.  
  326. pmess::    push    bc
  327.     push    de
  328.     push    hl
  329.     ld    c,9
  330.     jr    cpm
  331.  
  332. open::    push    bc
  333.     push    de
  334.     push    hl
  335.     ld    c,15        ;open cp/m file code
  336.     jr    cpm
  337.  
  338. read::    push    bc
  339.     push    de
  340.     push    hl
  341.     ld    c,20        ;read cp/m file code.
  342.     jr    cpm
  343.  
  344.  
  345. setdma::
  346.     push    bc
  347.     push    de
  348.     push    hl
  349.     ld    c,26        ;set dma address code.
  350.     jr    cpm
  351.  
  352. cpm::    call    fdos        ;go to cp/m
  353.     pop    hl        ;restore all registers pushed
  354.     pop    de
  355.     pop    bc
  356.     ret            ;back to the main program
  357. logon::
  358.     db    '(Shell v4.4 installed)',0ah,0dh,'$'
  359. opmess::
  360.     db    'Shell: Cant find command file',0dh,0ah,'$'
  361. interbuf::
  362.     ds    40h
  363. ;----------------------------------------------------------
  364.  
  365. ;this part lives in high memory somewhere
  366.  
  367. start    equ    $
  368.     .phase    dest        ;your spare memory
  369. ;********************************************************
  370. ;*                                  *
  371. ;* This part of the program mimics CP/M CONIN routine    *
  372. ;*                            *
  373. ;********************************************************
  374.  
  375. ;We handle the parameters by checking for a '$' sign
  376. ;and then jumping to a routine which 1. Finds if that
  377. ;parameter was given on the command line. 2. Sets up
  378. ;a flag which tells this prog to get a char from the
  379. ;parameter exp rather than the the main text submit..
  380. ; If this flag is set, the next call to the kb routine
  381. ;will vector to EXPAR, which returns a char from the
  382. ;the parameter being expanded...
  383.  
  384.  
  385. hook::    push    hl
  386.     push    bc
  387.     push    de
  388.     ld    a,(pflag)    ;are we doing a parameter
  389.     cp    true
  390.     jr    z,expar        ;get a char from it instaed
  391.     ld    hl,(point)  ;get pointer to command text
  392. hooka::    ld    a,(hl)
  393.     inc    hl
  394.     cp    1ah    ;eof
  395.     call    z,rhook    ;remove hooks and leave
  396.     cp    0ah    ;piss off line feeds
  397.     jr    z,hooka
  398. ;check for $n paramter
  399.     cp    '$'
  400.     call    z,subs
  401.     ld    (point),hl  ;save pointer to text
  402. pret::                ;back here if we did a par char
  403.     push    af
  404. ;
  405. ;now check kb status routine and get out
  406. ;if a key has been pushed
  407. ;
  408.     ld    hl,rtlab
  409.     push    hl    ;return address
  410.     ld    hl,(kbst)
  411.     jp    (hl)    ;computed gosub
  412. rtlab::    cp    0
  413.     jr    nz,panic  ;key pushed,get out
  414.     pop    af
  415.     pop    de
  416.     pop    bc
  417.     pop    hl
  418.     ret
  419.  
  420. ;get out ,remove hook
  421.  
  422. panic::    call    rhook
  423.     jp    0    ;warm boot
  424.  
  425. rhook::    ld    hl,(hokad)
  426.     ld    a,(kb)
  427.     ld    (hl),a
  428.     inc    hl
  429.     ld    a,(kb+1)
  430.     ld    (hl),a
  431.     ld    a,0dh    ;we return with a return to prog
  432. ;hooks removed, return to what ever called us
  433.     ret
  434. ;return to prog by ret..Hooks in CBIOS removed...
  435.  
  436. ;-----------------------------------------------------------
  437. ; Expand the parameter, this code returns the next
  438. ; char from the parameter we are expanding..
  439.  
  440. expar::    ld    a,(cnt)
  441.     dec    a
  442.     jr    z,finpar    ;no more chars
  443.     ld    (cnt),a
  444.     ld    hl,(ppp)    ;get parameter pointer
  445.     ld    a,(hl)
  446.     inc    hl
  447.     cp    ' '        ;exit if space 
  448.  
  449. ;if it is a space, we have come to the end of the
  450. ;current parameter expansion, clear the flag
  451. ;and return a space in A.
  452. ;This code will not be used again until there is 
  453. ;another $n in the main submit text..
  454.  
  455.     jr    z,finpar    ;clear flag etc..
  456.     ld    (ppp),hl
  457.     jr    pret        ;go back to main
  458.  
  459. finpar::    
  460.     ld    a,false
  461.     ld    (pflag),a
  462.     ld    a,' '
  463.     jr    pret
  464.  
  465.  
  466. ;The following code is called when a $ is encountered in
  467. ;the main submit file, it points (ppp) at the beginning
  468. ;of the relevant string from the command line which
  469. ;we moved to PARAM buffer.
  470. ; This code MUST return the first character of the new
  471. ;expansion..
  472.  
  473. subs::
  474.     push    hl
  475.     ld    a,(hl)        ;get paramter number..
  476.     sub    '0'
  477.     ld    l,a
  478.     push    hl        ;save parameter num
  479.  
  480. ;and point at the correct one
  481. ;parameter ranges from $1 to $9
  482. ;GETS returns DE pointing to the next string in the
  483. ;the command line copy at PARAM, B equal to the 
  484. ;number of chars in the string, or 00 if no string
  485. ;available...
  486.  
  487.     ld    hl,param
  488.     ld    a,(hl)
  489.     ld    (cnt),a
  490.     inc    hl
  491.     ld    (cmdpt),hl    ;start GETS at front of buff
  492.     pop    hl        ;get back parameter number
  493.     call    gets        ;skip filename
  494. fnd::    call    gets
  495.     xor    a
  496.     cp    b
  497.     jr    z,perror    ;parameter error
  498.     dec    l
  499.     jr    nz,fnd
  500.     ld    a,b
  501.     ld    (cnt),a        ;length of parameter
  502.     cp    1        ;only one char in this par??
  503.     jr    z,nexp        ;return it and be done!!
  504.     inc    de        ;points at first char in par
  505.     ld    (ppp),de    ;save pointer to param
  506.     ld    a,true        ;set par flag
  507.     ld    (pflag),a
  508.     dec    de
  509. nexp::    ld    a,(de)        ;first char of parameter
  510.     pop    hl
  511.     inc    hl
  512.     ret
  513. perror::    
  514.     jr    panic    ;warm boot, parameter error
  515.  
  516. ;------------------------------------------------------
  517. ;routine returns pointer to a
  518. ;space bounded string in DE
  519. ;and its length in B or if out of chars B=0.
  520. ;stuffs up BC,DE,AF saves HL
  521.  
  522. gets::    push    hl
  523.     ld    b,0
  524.     ld    hl,(cmdpt)
  525.     ld    a,(cnt)
  526.     ld    c,a        ;get chars left
  527. sllp::    ld    a,(hl)
  528.     inc    hl
  529.     cp    ' '        ;but if that wasnt a space
  530.     jr    nz,thro
  531.     dec    c
  532.     jr    z,exlop
  533.     jr    sllp
  534. thro::
  535.     ld    d,h
  536.     ld    e,l
  537.     dec    de    ;correction
  538.     inc    b    ;1 char already
  539.     dec    c
  540.     jr    z,exlop
  541. lenlop::
  542.     ld    a,(hl)
  543.     inc    hl
  544.     inc    b        ;another char
  545.     dec    c
  546.     jr    z,exlop
  547.     cp    ' '
  548.     jr    nz,lenlop    ;measure the string
  549.     dec    b        ;correction
  550.     ld    (cmdpt),hl    ;save our place on line
  551.     ld    a,c
  552.     ld    (cnt),a        ;save count
  553.     pop    hl
  554.     ret
  555. exlop::
  556.     ld    a,1
  557.     ld    (cnt),a    ;zero out count
  558.     pop    hl
  559.     ret
  560.  
  561. ;--------------------------------------------------------
  562. len::                ;label for bmove
  563. ppp::    ds    2
  564. pflag::    ds    1
  565. cmdpt::    ds    2
  566. cnt::    ds    1
  567. kbst::    ds    2
  568. point:  ds    2
  569. hokad::    ds    2
  570. kb::    ds    2
  571. buff::    ds    sectors*128    ;command buffer
  572. param::    ds    40h        ;space for cpm command line
  573.  
  574. ; and end to it all......
  575.     end
  576.