home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / fpc / source / emmexec.seq < prev    next >
Text File  |  1991-03-06  |  10KB  |  208 lines

  1. \\ EMMEXEC.SEQ   Shell to DOS, leave F-PC in Expanded Memory   by Tom Zimmer
  2.  
  3.   This is a support file for EXEC.SEQ. It's job is to reduce F-PC's
  4. allocated memory size, shell out and perform a DOS command, re-adjust
  5. F-PC's memory allocation back up to the normal level, and read F-PC back
  6. into program memory from expanded memory, then deallocate the expanded
  7. memory that was being used.
  8.  
  9.   The results obtained with this file along with EXEC.SEQ, is a
  10. SHELL command for F-PC that consumes only 8k of program memory while
  11. performing a DOS command as long as sufficient expanded memory is
  12. available.
  13.  
  14.   This file is placed as low as possible in the meta-compile load sequence
  15. to minimize the amount of memory kept during a a DOS Shell command.
  16.  
  17. {
  18.  
  19. FILES DEFINITIONS
  20.  
  21. VARIABLE EMMEXEC.SEQ
  22.  
  23. FORTH DEFINITIONS
  24.  
  25. $FE CONSTANT EMMSTK             \ Put stack just below Forth in header area
  26. VARIABLE #FPCPAGES              \ number of 16k pages needed by F-PC
  27. VARIABLE EMMPAGE#               \ page counter during F-PC program restore.
  28. VARIABLE EMMHNDL                \ holds the number used to talk to EMM driver
  29. VARIABLE EMMPARS                \ size in PARS to keep when shelling to DOS
  30. VARIABLE EMMPARST               \ start in CS: of where we are saving from
  31. VARIABLE USE-DISK               \ should we flush F-PC to disk?
  32.        0 USE-DISK !-T           \ init to don't use disk
  33. VARIABLE DSK-STATUS             \ saved F-PC to disk was ok?=FALSE
  34.    $FFFF DSK-STATUS !-T         \ init to error condition
  35.  
  36. : DISKON        ( -- )          \ flush F-PC to disk enabled
  37.                 USE-DISK ON ;
  38.  
  39. : DISKOFF       ( -- )          \ flush F-PC to disk is disabled
  40.                 USE-DISK OFF
  41.                 DSK-STATUS ON ;
  42.  
  43. CREATE EXEC$      $100 ALLOT    \ the execute command line parameters
  44. CREATE EXEC.PARAM $10  ALLOT    \ the EXEC parameter array
  45.  
  46. CREATE CMDPATH ,"-T \COMMAND.COM" 0 ,-T $40 ALLOT
  47. CREATE EXTHNDL ,"-T FPCIMAGE.$$$" 0 ,-T $40 ALLOT
  48.  
  49. VARIABLE SS_SAVE                \ a place to save the stack segment
  50. VARIABLE SP_SAVE                \ a place to save the stack pointer
  51.  
  52. \ WARNING !! These functions need a lot of setup before they can be used.
  53. \ Study the functions in EXEC.SEQ before trying to directly use this word.
  54. \ Normally this function is ONLY invoked by "$SYS".
  55.  
  56. \ SETBLOCK ****************************************************************
  57. \
  58. \ F-PC has already been moved out to expanded memory before <EMMEXEC>
  59. \ ever gets called, so just shrink F-PC's memory block to the size we
  60. \ have decided we need. About 8k.
  61. \
  62. LABEL SMALFPC   ( -- )          \ reduce memory used by F-PC
  63.                 mov ax, cs
  64.                 mov es, ax              \ ES = CS
  65.                 mov bx, emmpars         \ get new size in paragraphs
  66.                 mov ax, # $4A00
  67.                 int $21                 \ adjust memory smaller
  68.                 ret             end-code
  69.  
  70. \ SETBLOCK ****************************************************************
  71. \
  72. \ Re-adjust F-PC's memory block back up where it was before we flushed
  73. \ ourselves to expanded memory.
  74. \
  75. LABEL EMM>FPC    ( -- )         \ get F-PC back from Expanded Memory
  76.                 mov ax, cs
  77.                 mov es, ax              \ ES = CS
  78.                 mov bx, cs: #pars       \ reset memory to original size
  79.                 mov ax, # $4A00
  80.                 int $21
  81. \ RECOVER FPC FROM EMM ****************************************************
  82. \
  83. \ The hardest work is done here. Pull F-PC back into memory from expanded
  84. \ memory.
  85. \
  86.                 mov cs: emmpage# # 0 word       \ reset the current page
  87.                 begin   mov dx, cs: emmhndl     \ emm handle
  88.                         mov bx, cs: emmpage#    \ logical page
  89.                         mov ax, # $4400         \ map pages func & phy page
  90.                         int $67                 \ expanded memory interrupt
  91.                         xor si, si              \ source starts at offset 0
  92.                         xor di, di              \ destination starts at 0
  93.                         mov es, cs: emmparst    \ set destination into ES
  94.                         mov ds, cs: page-frame  \ DS = physical page frame
  95.                         mov cx, # $4000         \ move count in bytes = 16k
  96.                         repnz  movsb            \ move 16k bytes
  97.                         add cs: emmparst # $400 word \ adjust to next page
  98.                         inc cs: emmpage# word   \ next expanded memory page
  99.                         mov bx, cs: emmpage#    \ get a copy of #pages moved
  100.                         cmp bx, cs: #fpcpages   \ have we moved the pages yet?
  101.              >= until
  102.                 mov ax, cs
  103.                 mov ds, ax                      \ restore data segment
  104. \ DEALLOCATE PAGES ********************************************************
  105. \
  106. \ GIve back the expanded memory we were using to the DOS EMM driver.  If we
  107. \ need to shell out again, we will just re-allocate what we need.
  108. \
  109.                 mov dx, emmhndl         \ get the emm handle
  110.                 mov ah, # $45           \ deallocate pages function
  111.                 int $67
  112.                 mov al, ah              \ ah = status
  113.                 sub ah, ah
  114.                 mov emm-status ax
  115.                 ret             end-code
  116.  
  117. \ RECOVER FPC FROM DISK ***************************************************
  118. \
  119. LABEL DSK>FPC    ( -- )         \ get F-PC back from Disk
  120.                 mov ax, cs
  121.                 mov es, ax              \ ES = CS
  122.                 mov ds, ax              \ DS = CS
  123.                 mov bx, cs: #pars       \ reset memory to original size
  124.                 mov ax, # $4A00
  125.                 int $21                 \ set BLOCK size
  126.                 mov bx, # exthndl 68 +          \ get the file handle
  127.                                                 \ + 68 = HNDLOFFSET addr
  128.                 mov bx, 0 [bx]                  \ get real DOS handle
  129.                 xor cx, cx                      \ reset to start of file
  130.                 xor dx, dx
  131.                 mov ax, # $4200                 \ from start of file
  132.                 int $21                         \ file position
  133.                 mov cs: emmpage# # 0 word       \ reset the current page
  134.                 begin   mov ds, cs: emmparst    \ set destination into ES
  135.                         xor dx, dx              \ offset is zero
  136. \ already in BX         mov bx, # exthndl 68 +  \ the file handle variable
  137. \ already in BX         mov bx, 0 [bx]          \ get real DOS handle
  138.                         mov cx, # $4000         \ move count in bytes = 16k
  139.                         mov ax, # $3F00         \ disk read
  140.                         int $21                 \ read from disk file
  141.                         add cs: emmparst # $400 word \ adjust to next page
  142.                         inc cs: emmpage# word   \ next expanded memory page
  143.                         mov cx, cs: emmpage#    \ get a copy of #pages moved
  144.                         cmp cx, cs: #fpcpages   \ have we moved the pages yet?
  145.              >= until
  146.                 mov ax, cs
  147.                 mov ds, ax                      \ restore data segment
  148. \ already in BX         mov bx, # exthndl 68 +  \ the file handle variable
  149. \ already in BX         mov bx, 0 [bx]          \ get real DOS handle
  150.                 mov ax, # $3E00                 \ close function
  151.                 int $21
  152.                 mov dx, # exthndl 1+            \ filename after count byte
  153.                 mov ax, # $4100                 \ file delete
  154.                 int $21
  155.                 ret             end-code
  156.  
  157. CODE <EXTEXEC>  ( --- return-code )     \ shell to DOS & save to EMM or DISK
  158.                 mov dx, # cmdpath 1+            \ DX contains command path
  159.                 mov sp_save sp          mov ss_save ss  \ Save SP and SS
  160.                 mov ax, # emmstk        mov sp, ax      \ SP becomes EMMSTK
  161.                 push es                                 \ save these regs
  162.                 push si
  163.                 push bp
  164.                 cmp emm-status # 0 word         \ was there Expanded memory?
  165.      0= if      call smalfpc                    \ make segment small
  166.         else    cmp dsk-status # 0 word         \ or use disk?
  167.              0= if      call smalfpc            \ make segment small
  168.                 then
  169.         then
  170. \ EXEC ********************************************************************
  171. \
  172. \ The real Shell to DOS is performed here. We have shrunk ourselves to a
  173. \ very small size, and given all possible memory back to DOS. Now we will
  174. \ perform the DOS command the user requested.
  175. \
  176.                 mov ax, cs
  177.                 mov es, ax              \ ES = CS
  178.                 mov bx, # exec.param
  179.                 mov ax, # $4B00
  180.                 int $21
  181.              u< if      and ax, # $FF   \ ONLY when carry is non zero
  182.                 else    mov ax, # 0
  183.                 then
  184.                 push ax                 \ save AX, the error code
  185.                 cmp emm-status # 0 word         \ was there Expanded memory?
  186.      0= if      call emm>fpc                    \ recover from Expanded Mem
  187.         else    cmp dsk-status # 0 word         \ or use disk?
  188.              0= if      call dsk>fpc            \ recover from Disk
  189.                 then
  190.         then
  191. \ RESTORE REGISTERS *******************************************************
  192. \
  193. \ Restore the registers we saved at the front end of this before returning
  194. \ to F-PC.
  195. \
  196.                 mov ax, cs
  197.                 mov ds, ax
  198.                 pop ax                  \ recover error code from small stack
  199.                 pop bp                  \ restore these registers
  200.                 pop si
  201.                 pop es
  202.                 mov ss, ss_save         \ Restore SP and SS
  203.                 mov sp, sp_save
  204.                 1push   end-code        \ ax contains error code
  205.  
  206. VARIABLE EMMSYSEND              \ end of expanded memory resident portion
  207.  
  208.