home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / fpc / source / window.seq < prev    next >
Text File  |  1989-09-26  |  13KB  |  428 lines

  1. \ WINDOW.SEQ    Window code for F83                     by Graig A. Lindley
  2.  
  3. POSTFIX         \ Use the postfix assembler syntax.
  4.  
  5. comment:
  6.  
  7. IBM window program
  8. by
  9. Craig A. Lindley
  10. Manitou Springs, Colorado
  11. November 1985
  12.  
  13. Dr. Dobbs #117 July 1986
  14.  
  15. : ?comp state @ not abort" Compilation only" ;
  16. : ?pairs   <> abort" Bad Case Statement" ;
  17.  
  18. : case   ?comp csp @ !csp 4 ; immediate
  19.  
  20. : of     4 ?pairs
  21.          compile over compile = compile ?branch
  22.          here 0 , compile drop 5 ; immediate
  23.  
  24. : endof  5 ?pairs compile branch here 0 ,
  25.          swap >resolve 4 ; immediate
  26. : endcase  4 ?pairs ( compile drop )
  27.            begin sp@ csp @ <>
  28.            while >resolve
  29.            repeat csp ! ; immediate
  30.  
  31. comment;
  32.  
  33. \ write count # of chars with attrib at cursor position
  34.  
  35. code chra ( attrib,count--)
  36.   cx pop ax pop ah bl mov
  37.   bh bh xor 9 # ah mov        \ char in al, func. code in ah
  38.   si push 16 int si pop       \ do video interrupt
  39.   next end-code
  40.  
  41. \ write 1 char with attrib at cursor - update cursor position
  42.  
  43. code chra+ ( attrib--)
  44.   ax pop ah bl mov bh bh xor
  45.   1 # cx mov 9 # ah mov       \ char in al, func. code in ah
  46.   si push 16 int              \ count-1 write char/attrib
  47.   3 # ah mov 16 int dl inc 2 # ah mov 16 int
  48.   si pop                      \ inc cursor position
  49.   next end-code
  50.  
  51. \ read char and attrib at cursor position
  52.  
  53. code rdchra  ( --attrib )
  54.   0 # bh mov 8 # ah mov        \ pg = 0  func. code = 8
  55.   si push 16 int si pop        \ do video interrupt
  56.   1push  end-code              \ attrib to stack
  57.  
  58. \ put char with attrib at x,y
  59.  
  60. : putch ( x,y,attrib--) >r at r> 1 chra ;
  61.  
  62. \ get char with attrib at x,y
  63.  
  64. : getch ( x,y--attrib) at rdchra ;
  65.  
  66. \ draw count # of chars starting at x,y
  67.  
  68. : drawrow ( x,y,attrib,count--) >r >r at r> r> chra ;
  69.  
  70. \ scroll specified window up n lines
  71.  
  72. code scrlup ( xul,yul,xlr,ylr,n,attrib--)
  73.   bx pop bl bh mov di pop
  74.   dx pop dl dh mov ax pop al dl mov  \ dx has lr x y
  75.   cx pop cl ch mov ax pop al cl mov  \ cx has ul x y
  76.   di ax mov si push bp push          \ save regs
  77.   6 # ah mov 16 int          \ ax # of lines func code ah
  78.   bp pop si pop              \ restore forth regs
  79.   next end-code
  80.  
  81. \ DOS memory management support
  82. \ tell DOS to allocate memory bytes
  83.  
  84. code calloc ( #bytes--seg,? )
  85.   bx pop 4 # cl mov bx cl shr       \    -- maxp error code F
  86.   bx inc 72 # ah mov 33 int         \ func. code 48h, int 21h
  87.   u< if bx push ax push ax ax xor   \ if C then error
  88.      else ax push -1 # ax mov
  89.      then 1push end-code
  90.  
  91. \ tell DOS to free memory segment
  92.  
  93. code free ( seg--? )
  94.   ax pop es push ax es mov          \ error code F
  95.   73 # ah mov 33 int                \ func code 4Ah, int 21h
  96.         es pop
  97.   u< if ax push ax ax xor           \ if C then error
  98.      else -1 # ax mov
  99.      then 1push end-code
  100.  
  101. \ tell DOS to shrink or expand allocated memory segment
  102.  
  103. code setblock ( #bytes--? )
  104.         bx pop es push
  105.         cs ax mov ax es mov           \ maxp error code F
  106.         4 # cl mov bx cl shr   \ bx has # of paragraphs
  107.         bx inc 74 # ah mov 33 int     \ func code 4Ah, int 21h
  108.         es pop
  109.      u< if bx push ax push ax ax xor   \ if C then error
  110.         else -1 # ax mov
  111.         then 1push end-code
  112.  
  113. \ fetch word from extended memory
  114.  
  115. code e@ ( seg,addr--n)
  116.         bx pop ax pop           \ seg in es, addr in bx
  117.         es push ax es mov
  118.         es: 0 [bx] ax mov       \ get the data on stack
  119.         es pop
  120.         1push end-code
  121.  
  122. \ store word in extended memory
  123.  
  124. code e!  ( n,seg,addr--)
  125.         bx pop dx pop ax pop
  126.         es push dx es mov
  127.         ax es: 0 [bx] mov       \ store the data
  128.         es pop
  129.         next end-code
  130.  
  131. \ read current cursor location
  132.  
  133. code rdcur ( --x,y)
  134.   si push 0 # bh mov
  135.   3 # ah mov 16 int               \ func. code 3, int 10h
  136.   si pop ah ah xor
  137.   dl al mov ax push dh al mov
  138.   1push end-code
  139.  
  140. \ Window Control Block (WCB) record layout            860704clz)
  141.  
  142.  0 constant ulx      2 constant uly       \ upper left corner
  143.  4 constant width    6 constant height
  144.  8 constant curx    10 constant cury      \ current cursor pos
  145. 12 constant oldx    14 constant oldy      \ old cursor pos
  146. 16 constant bufseg  18 constant oldwcbseg \ seg storage
  147. 20 constant attrib                        \ window attrib.
  148.  
  149. 22 constant recordsize
  150. 15 constant border                        \ border attribute
  151. HEX
  152. B000 constant vseg                        \ start video memory
  153.   \ B800 = color graphics adapter, B000 = monochrome monitor
  154. variable wcbseg                           \ current WCB seg
  155. DECIMAL
  156.  
  157. \ WCB extended memory access
  158.  
  159. \ store word n at addr in current WCB
  160.  
  161. : wcbseg! ( n,addr--) wcbseg @ swap e! ;
  162.  
  163. \ fetch word from addr in current WCB
  164.  
  165. : wcbseg@ ( addr--n) wcbseg @ swap e@ ;
  166.  
  167. : top ( --)
  168.   ulx wcbseg@ uly wcbseg@ [ 201 border 256 * + ] literal putch
  169.   ulx wcbseg@ 1+ uly wcbseg@ [ 205 border 256 * + ] literal
  170.   width wcbseg@ drawrow
  171.   ulx wcbseg@ width wcbseg@ + 1+ uly wcbseg@
  172.   [ 187 border 256 * + ] literal putch ;
  173.  
  174. : bottom ( --)
  175.   ulx wcbseg@ uly wcbseg@ height wcbseg@ + 1+
  176.   [ 200 border 256 * + ] literal putch
  177.   ulx wcbseg@ 1+ uly wcbseg@ height wcbseg@ + 1+
  178.   [ 205 border 256 * + ] literal width wcbseg@ drawrow
  179.   ulx wcbseg@ width wcbseg@ + 1+ uly wcbseg@ height wcbseg@ + 1+
  180.   [ 188 border 256 * + ] literal putch ;
  181.  
  182. : sides ( --)
  183.   uly wcbseg@ height wcbseg@ + 1+ uly wcbseg@ 1+
  184.   do ulx wcbseg@ i [ 186 border 256 * + ] literal putch
  185.      ulx wcbseg@ width wcbseg@ + 1+ i
  186.      [ 186 border 256 * + ] literal putch
  187.   loop ;
  188.  
  189. \ used by scn->buf and buf->scn
  190.  
  191. label saveh   nop nop         \ storage for height parameter
  192. label savew   nop nop         \             width parameter
  193. label saveptr nop nop         \             start pointer
  194. label savesi  nop nop         \             forth's IP reg
  195. label saveds  nop nop         \             current ds reg
  196.  
  197. \ move data from screen to memory buffer
  198.  
  199. HEX
  200.  
  201. code scn->buf ( x,y,width,height,seg--)
  202.   cld dx pop 0 # di mov saveh #) pop savew #) pop ax pop
  203.   A0 # bl mov bl mul bx pop bx shl bx ax add ax saveptr #) mov
  204.   si savesi #) mov ds ax mov ax saveds #) mov vseg # ax mov
  205.   es push dx es mov
  206.   ax ds mov cs: saveptr #) si mov cs: saveh #) cx mov
  207.   here cx push cs: savew #) cx mov rep movs
  208.        cs: saveptr #) si mov A0 # si add si cs: saveptr #) mov
  209.        cx pop
  210.   loop
  211.   cs: saveds #) ax mov ax ds mov
  212.   savesi #) si mov
  213.   es pop
  214.   next end-code
  215.  
  216. DECIMAL
  217.  
  218. \ move data from memory buffer to screen
  219.  
  220. HEX
  221. code buf->scn  ( seg,x,y,width,height--)
  222.   cld saveh #) pop savew #) pop ax pop A0 # bl mov
  223.   bl mul bx pop bx shl bx ax add ax saveptr #) mov
  224.   si savesi #) mov ds ax mov ax saveds #) mov ax pop ax ds mov
  225.   es push
  226.   vseg # ax mov ax es mov 0 # si mov cs: saveptr #) di mov
  227.   cs: saveh #) cx mov
  228.   here cx push cs: savew #) cx mov rep movs
  229.        cs: saveptr #) di mov A0 # di add di cs: saveptr #) mov
  230.        cx pop
  231.   loop
  232.   cs: saveds #) ax mov ax ds mov savesi #) si mov
  233.   es pop
  234.   next end-code
  235. DECIMAL
  236.  
  237. \ moves screen data to memory buffer
  238. \ and then draws the actual window frame
  239.  
  240. : wndw ( --)
  241.    ulx wcbseg@ uly wcbseg@
  242.    width wcbseg@ 2+ height wcbseg@ 2+
  243.    bufseg wcbseg@ scn->buf
  244.    top sides bottom ;
  245.  
  246. : clearwindow ( --)
  247.    ulx wcbseg@ 1+                   \ upper left x
  248.    uly wcbseg@ 1+                   \ upper right y
  249.    ulx wcbseg@ width wcbseg@ +      \ lower left x
  250.    uly wcbseg@ height wcbseg@ +     \ lower right y
  251.    0 attrib wcbseg@ scrlup          \ scroll entire window
  252.    0 curx wcbseg! 0 cury wcbseg! ;  \ home window cursor
  253.  
  254. : window ( x,y,width,height,attrib--? )
  255.    recordsize calloc                  \ reserve space for wcb
  256.      if wcbseg @ >r wcbseg ! r>
  257.         oldwcbseg wcbseg! attrib wcbseg!
  258.         2dup 2+ swap 2+ * 2* calloc \ reserve space for scr buf
  259.           if bufseg wcbseg!         \ save buffer seg
  260.              height wcbseg! width wcbseg!    \ save parameters
  261.              uly    wcbseg! ulx   wcbseg!    \ in new wcb
  262.              rdcur oldy wcbseg! oldx wcbseg! \ get old cur pos
  263.              wndw clearwindow true
  264.           else ." Buffer allocation failure." cr
  265.              wcbseg @ free drop drop 0
  266.           then
  267.      else ." WCB allocation failure." abort ( drop drop 0 )
  268.      then ;
  269.  
  270. \ window parameter checking
  271.  
  272. : wfit ( ?--) cr abort" Window won't fit on crt." ;
  273.  
  274. : openwindow ( x,y,width,height,attrib--? )
  275.    depth 5 >=
  276.      if >r 4dup rot + 2+ 24 <=
  277.        if + 2+ 79 <=
  278.          if r> window
  279.          else cr ." ULX and/or WIDTH incorrect." wfit
  280.          then
  281.        else cr ." ULY and/or HEIGHT incorrect." wfit
  282.        then
  283.      else cr ." Incorrect # of parameters specified." quit
  284.      then ;
  285.  
  286. \ close the current window
  287. \ free wcb and buffer memory then unlink window
  288.  
  289. : closewindow ( --) wcbseg @ 0 <>        \ if window exists
  290.    if bufseg wcbseg@                     \ get buffer seg addr
  291.       ulx wcbseg@ uly wcbseg@
  292.       width wcbseg@ 2+ height wcbseg@ 2+
  293.       buf->scn                     \ move data back to screen
  294.       oldx wcbseg@ oldy wcbseg@ at
  295.       bufseg wcbseg@ free drop     \ free buffer seg memory
  296.       wcbseg @ free drop           \ free wcb seg memory
  297.       oldwcbseg wcbseg@ wcbseg !   \ unlink this window
  298.     else cr ." No open windows." cr
  299.     then ;
  300.  
  301. \ position cursor in window
  302. \ if paras out of range do the best and still stay in window
  303.  
  304. : wat ( x,y--)
  305.     swap dup abs width wcbseg@ 1- >    \ x not within window
  306.       if drop width wcbseg@ 1-         \ set x to max in window
  307.       then curx wcbseg!                \ save new cursor x pos
  308.     dup abs height wcbseg@ 1- >        \ y not within window
  309.       if drop height wcbseg@ 1-        \ set y to max in window
  310.       then cury wcbseg!                \ save new cursor y pos
  311.     curx wcbseg@ ulx wcbseg@ + 1+      \ actual cursor x
  312.     cury wcbseg@ uly wcbseg@ + 1+      \ actual cursor y
  313.     at ;
  314.  
  315. \ read window cursor position
  316.  
  317. : rdwcur ( --x,y) curx wcbseg@ cury wcbseg@ ;
  318.  
  319. \ read attribute of character at cursor in window
  320.  
  321. : rdwcha ( x,y--attrib) wat rdchra ;
  322.  
  323. \ scroll window up for blank line at bottom
  324.  
  325. : scrollwindow ( --)
  326.    ulx wcbseg@ 1+ uly wcbseg@ 1+   \ upper left corner to scroll
  327.    ulx wcbseg@  width wcbseg@ +    \ lower right x coordinate
  328.    uly wcbseg@ height wcbseg@ +    \ lower right y coordinate
  329.    1 attrib wcbseg@ scrlup ;       \ up one line
  330.  
  331.                 \ cr in current window
  332. : crout         ( --) rdwcur nip 0 swap wat ;
  333.  
  334.                 \ line feed in current window
  335. : lfout         ( --) rdwcur 1+
  336.     dup height wcbseg@ 1- >     \ cursor out of window
  337.      if 1- scrollwindow
  338.      then wat ;
  339.  
  340.                 \ execute backspace in current window
  341. : bsout         ( --) rdwcur over
  342.                 if swap 1- swap wat else 2drop then ;
  343.  
  344. : bell          ( --) 7 (emit) ;
  345.  
  346. : wemit         ( char--) dup 32 <
  347.     if case                          \ handle controls
  348.          7 of bell   endof
  349.          8 of bsout  endof
  350.         10 of lfout  endof
  351.         13 of crout  endof drop
  352.        endcase
  353.     else                             \ display character
  354.       attrib wcbseg@ 256 * +         \ char now char/attrib
  355.       rdwcur rot chra+               \ output char & adv. cursor
  356.       drop dup width wcbseg@ 1- =    \ at end of line
  357.         if drop lfout crout          \ if do lfcr
  358.         else 1+ curx wcbseg!         \ store new x coordinate
  359.     then then ;
  360.  
  361. : wcr ( --) 13 wemit 10 wemit ;
  362.  
  363. : wtype ( addr,n--) 0 ?do count wemit loop drop ;
  364.  
  365.  
  366. comment:
  367.  
  368. \ use DOS memory manager to give forth a full 64k segment
  369.  
  370. : initialize ( --)
  371.     cr ." Memory management "
  372.     -1 setblock                        \ request FFFF bytes
  373.       if ." initialized." 0 wcbseg !   \ initialize link var
  374.       else ." error." abort
  375.       then cr ;
  376.  
  377. comment;
  378.  
  379.   7 constant normal          15 constant highint
  380. 112 constant reverse        128 constant blink
  381.  
  382. : enterwindow ( x,y,width,height,attrib--) openwindow
  383.     if ['] wemit is emit ['] wcr is cr 0 0 wat then ;
  384.  
  385. : exitwindow ( --) closewindow wcbseg @ 0=
  386.     if ['] (emit) is emit ['] crlf is cr then ;
  387.  
  388. : smash ( --) exitwindow ;
  389.  
  390. : window1 ( --) 0 0 20 10 reverse openwindow ;
  391.  
  392. : window2 ( --) 2 1 70 8 normal openwindow ;
  393.  
  394. : window3 ( --) 7 6 69 10 reverse openwindow ;
  395.  
  396. : window4 ( --) 10 9 59 4 highint openwindow ;
  397.  
  398. : msg1 ( --) " Attitudes are contagious. " wtype ;
  399.  
  400. : msg2 ( --) " Is yours worth catching? " wtype ;
  401.  
  402. : msg3 ( --) "  ** Window 4 ** " wtype ;
  403.  
  404. : msg1out ( --) 0 0 wat 20 0 do msg1 loop ;
  405.  
  406. : msg2out ( --) 0 0 wat 20 0 do msg2 loop ;
  407.  
  408. : msg3out ( --) 0 0 wat 80 0 do msg3 loop ;
  409.  
  410. : fillscreen ( --) 0 0            \ fill with rev video A's
  411.     [ ascii A reverse 256 * + ]   \ calculate char/attrib code
  412.     literal 2048 drawrow ;
  413.  
  414. : wait ( --) 2 tenths ;
  415.  
  416. : demo ( --) fillscreen window1
  417.     if 0 0 wat msg1 wait wcr wait 7 wemit wcr wait
  418.       " Really ?" wtype wait 8 wemit 8 wemit wait
  419.       10 5 wat wait window2
  420.         if msg2out wait window3
  421.           if ( 0 10 wat 24 wtriad wait ) window4
  422.             if msg3out wait closewindow wait closewindow
  423.               wait clearwindow msg2out wait closewindow
  424.               ( 0 wlist wait wait wait ) closewindow
  425.     then then then then dark ;
  426.  
  427.  
  428.