home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / f88 / qvideo.bak < prev    next >
Text File  |  1988-06-07  |  12KB  |  410 lines

  1. \ QVIDEO.SEQ    Fast video routine LINKAGE.             by Tom Zimmer
  2. \               with additions by Mike Sperl
  3.  
  4. DECIMAL
  5.  
  6.                 \ ARRAY OF SPACES FOR FAST SPACES OUTPUT
  7. CREATE QSPS     80 ALLOT
  8.        QSPS     80 BLANK
  9.  
  10. CODE FIX.COUNTERS   ( A1 N1 --- A1 N1 x y ) \ see QTYPE
  11.     POP CX
  12.     PUSH CX             \ save N1
  13.     MOV AX, #) #OUT
  14.     PUSH AX             \ column ( x )
  15.     ADD AX, CX          \ will string go past eol?
  16.     MOV CX, # 79        \ eol == 79
  17.     CMP AX, CX
  18. <= IF
  19.         MOV #) #OUT AX  \ ok, bump out
  20.     ELSE
  21.         MOV #) #OUT CX
  22.     THEN
  23.     MOV AX, #) #LINE
  24.     MOV CX, # 24
  25.     CMP AX, CX          \ are we on line 24?
  26.  <= IF
  27.         MOV #) #LINE AX
  28.         PUSH AX         \ row ( y )
  29.         NEXT
  30.     THEN
  31.     MOV #) #LINE CX
  32.     PUSH CX            \ row ( y )
  33.     NEXT
  34. END-CODE
  35.  
  36. DEFER QTYPE
  37.  
  38. : (QTYPE)         ( A1 N1 --- ) \ optimized for the cga card
  39.     ?DUP
  40.     IF      PRINTING @
  41.             IF      (TYPE)
  42.             ELSE    FIX.COUNTERS   \ optimizes the next two lines
  43. \                    #OUT @ 2DUP + 79 MIN #OUT ! ( a1 n1 x -- )
  44. \                    #LINE @ 24 MIN DUP #LINE ! ( a1 n1 x y -- )
  45.                     VTYPE
  46.             THEN
  47.     ELSE    DROP
  48.     THEN    ;
  49.  
  50. ' (QTYPE) IS QTYPE
  51.  
  52. : QEMIT         ( C1 --- )
  53.                 SP@ 1 QTYPE DROP ;
  54.  
  55. : QSPACES       ( N1 --- )      \ FAST SPACE PRINTING TO SCREEN
  56.                 0 MAX 80 MIN QSPS SWAP QTYPE ;
  57.  
  58. \ ' QSPACES IS SRCSPACES
  59.  
  60. : QVINIT        ( --- )         \ Initialize the source segment
  61.                 ?CS: typeseg !
  62.                 DEFERS SEGSET ;
  63.  
  64. ' QVINIT IS SEGSET
  65.  
  66. ?CS: typeseg !                    \ Initialize typeseg for immediate use.
  67.  
  68. : FAST          ( --- )
  69.                 ['] QTYPE     IS TYPE ;
  70.  
  71. : SLOW          ( --- )
  72.                 ['] (TYPE)    IS TYPE ;
  73.  
  74. FAST            \ Select the high speed video drivers.
  75.  
  76. \ ---------------------------------------------------------
  77. comment:
  78.     Extensions for pop-up screens and paging by Mike Sperl.
  79. They work with with page 0 on the monochrome card, and pages
  80. 0..3 on the cga card.  They have not been tested on all possible 
  81. combinations of hardware.  Please address comments etc. to me
  82. c/o the NCFB BBS.
  83.  
  84.     These words support 2 methods of writing to the screen: ." 
  85. and type.
  86.  
  87.     The following can be used with ." to pop up a screen-full of 
  88. text on the cga without any snow or the blinking that occurs when 
  89. a lot of text is written even with the modified VTYPE (see 
  90. video.seq). Text is written to a buffer in ram, after first 
  91. initializing it by calling MBUF.INIT once and clearing it by 
  92. calling CLEAR.MSEGB each time before using the buffer. After 
  93. executing these two words, and before using ." , replace IBM-AT 
  94. by MAT and (QTYPE) by (QTYPEM) with: 
  95.             ['] MAT IS AT
  96.             ['] (QTYPEM) IS QTYPE
  97. and don't forget to:
  98.             ['] IBM-AT IS AT
  99.             ['] (QTYPE) IS QTYPE ( or FAST)
  100. when done writing to the buffer.  Transfer the text to the screen
  101. with MOVEM after first setting the ( cga) page by PAGEx and turn on
  102. the page with x >PAGE afterwards, if you are using various pages
  103. (0 .. 3) of the cga card.
  104.  
  105.     (qtypem) or ." leaves x and y on the stack, so (qtypem) has 
  106. to 2DROP them, or rewrite ." - sorry about that. 
  107.  
  108.     To use TYPE, use:
  109.             ['] (QTYPET) IS QTYPE
  110. Don't change AT.  And after you have filled the buffer, write it 
  111. to the display with MOVEM as before and do:
  112.             ['] (QTYPE) IS QTYPE ( or FAST)
  113. to restore forth.
  114.  
  115.     MBUF.PREP, MBUF.TYPE, and MBUF.OFF are houskeeping words you
  116. may use if you wish.
  117.  
  118.     Most of this is assembler for speed.
  119. comment;
  120.  
  121. ONLY FORTH ALSO DEFINITIONS
  122.  
  123. DECIMAL
  124.  
  125. 0 CONSTANT MSEGB   \ to hold addr of ram buffer 
  126.  
  127. PREFIX
  128. CODE PAGE0 ( -- )
  129.     MOV #) PAGE# # 0
  130.     NEXT
  131. C;
  132.  
  133. CODE PAGE1 ( -- )
  134.     MOV #) PAGE# # 1
  135.     NEXT
  136. C;
  137.  
  138. CODE PAGE2 ( -- )
  139.     MOV #) PAGE# # 2
  140.     NEXT
  141. C;
  142.  
  143. CODE PAGE3 ( -- )
  144.     MOV #) PAGE# # 3
  145.     NEXT
  146. C;
  147.  
  148. POSTFIX
  149. ( CALLOC and FREE are borrowed from WINDOW.SEQ.)
  150. \ tell DOS to allocate memory BYTES
  151. CODE CALLOC ( #bytes -- seg t | n1 n2 f )
  152.     BX POP 
  153.     4 # CL MOV 
  154.     BX CL SHR       \ bytes/16 = para
  155.     BX INC          \ round up
  156.     72 # AH MOV 
  157.     33 INT          \ func. code 48h, int 21h
  158.  U< IF  BX PUSH     \ largest size available
  159.         AX PUSH     \ err code: 7 or 8 
  160.         AX AX XOR   \ false flag
  161.     ELSE AX PUSH    \ sucess! seg addr
  162.         -1 # AX MOV \ true flag
  163.     THEN 
  164.     1PUSH
  165. END-CODE
  166.  
  167. \ tell DOS to free memory segment
  168. CODE FREE ( seg -- -1 | n 0 )
  169.     AX POP 
  170.     ES PUSH 
  171.     AX ES MOV          \ error code F
  172.     73 # AH MOV 
  173.     33 INT             \ func code 4Ah, int 21h
  174.     ES POP
  175.  U< IF AX PUSH         \ err code, 7, 8, or 9
  176.         AX AX XOR      \ if carry, then false flag
  177.     ELSE -1 # AX MOV   \ sucess! - true flag
  178.     THEN 
  179.     1PUSH
  180. END-CODE
  181.  
  182. PREFIX
  183. HEX
  184. CODE >PAGE   ( n -- ) \ display page n = 0..3
  185.     POP AX
  186.     MOV AH, # 5
  187.     INT 10
  188.     NEXT 
  189. C;
  190.  
  191. CODE CLEAR    \ clear the stack
  192.     PUSH #) CSP
  193.     POP SP
  194.     NEXT
  195. C;
  196.  
  197. \ This word clears one page.  DARK clears ALL FOUR pages!
  198. CODE CLS    ( -- ) \ clear a cga or mono display page fast
  199.     CLD             \ without snow
  200.     PUSH SI
  201.     PUSH ES           \ save forth
  202.     MOV BX, #) PAGE#  \ 0 - 3 for cga
  203.     MOV AX, # 1000  \ 4096 bytes per page
  204.     MUL BX
  205.     MOV DI, AX      \ this page
  206.     MOV ES, #) VIDEO-SEG
  207.     MOV CX, # 7D0   \ 2000 words
  208.     MOV AX, CS: #) ENABLE_VAL   \ fetch enable val
  209.     CMP AL, # 0     \ monochrome? (test)
  210.     0<>
  211.     IF              \ if so, do nothing
  212.     MOV DX, # 3DA   \ address cga status port
  213.     MOV BX, # 1     \ mask
  214.     BEGIN
  215.         IN AL, DX   \ fetch status
  216.         TEST AL, BL \ mask vertical retrace bit
  217.     0<> UNTIL       \ until retrace seen
  218.     MOV DL, # D8    \ address cga control reg
  219.     MOV AL, # 25    \ this val disables the crt
  220.     OUT DX, AL      \ display is disabled
  221.     THEN
  222.     MOV AX, # 720   \ a blank with attrib 7
  223.     REP STOSW       \ write the page
  224.     MOV AX, CS: #) ENABLE_VAL   \ fetch enable val
  225.     CMP AL, # 0          \ monochrome? (test)
  226.     0<> IF                \ we didn't disable scr \ jz ret
  227.     MOV AX, # 29    \ enable val 29H for mode 3
  228.     MOV DX, # 3d8   \ adress cga mode control reg
  229.     OUT DX, AL      \ send the enable value
  230.     THEN
  231.     POP ES
  232.     POP SI          \ restore forth
  233.     NEXT
  234. C;
  235.  
  236. DECIMAL
  237. : MBUF.INIT     ( --- )  \ Allocate the buffer
  238. \    0 =: MSEGB           \ add error checking if desired
  239.     4096 CALLOC
  240.     IF =: MSEGB
  241.     ELSE ABORT" MBUF allocation failure."
  242.     THEN ;
  243.  
  244. \ substitute for IBM-AT when using the ram buffer
  245. CODE MAT   ( x y x y -- addr.in.mseg x y ) \ x, y for the rest of AT !!!
  246.     POP AX        \ y
  247.     MOV BX, # 160
  248.     MUL BX
  249.     POP BX        \ x
  250.     POP BX        \ y
  251.     POP DX        \ x
  252.     SHL DX, # 1
  253.     ADD AX, DX    \ addr in mseg = 160y + 2x
  254.     SHR DX, # 1
  255.     PUSH AX       \ addr in mseg
  256.     PUSH DX       \ x
  257.     PUSH BX       \ y
  258.     NEXT
  259. C;
  260.  
  261. \ place text in ram buffer w/ ." or TYPE preparatory to writing
  262. \ to screen.   Each ." *MUST* be preceeded by an 'x y at'.
  263. LABEL MTYPE1
  264.     LODSB
  265.     STOSW           \ write the char and its attribute byte
  266.     LOOP MTYPE1
  267.     POP ES                          \ restore ES
  268.     POP SI                          \ Restore IP
  269.     MOV BX, CS      MOV DS, BX      \ restore DS
  270.     NEXT
  271. CODE MTYPE         ( addr a1 n1 --- ) \ to msegb, use w/ MAT
  272.     POP CX          \ length
  273.     POP BX          \ $addr
  274.     POP DI          \ addr in msegb
  275.     XCHG SI, BX     \ SI is the source
  276.     PUSH BX         \ Save SI == IP
  277.     PUSH ES         \ save ES == list segment
  278.     MOV ES, #) ' MSEGB 3 +
  279.     MOV DS, #) typeseg      \ source segment
  280.     MOV AX, CS: #) ATTRIB     \ display attributes
  281.     XCHG AH, AL
  282.     JMP MTYPE1
  283. END-CODE
  284.  
  285. \ substitute one of these for QTYPE when using the ram buffer
  286.  
  287. : (QTYPEM)   ( addr a1 n1 --- ) \ to msegb (use w/ ." on cga card)
  288.     ?DUP
  289.     IF MTYPE   \ fix.counters not wanted!
  290.     ELSE 2DROP
  291.     THEN ;
  292.  
  293. : (QTYPET)   ( a1 n1 --- ) \ to msegb (use w/ type on cga card)
  294.     ?DUP
  295.     IF
  296.        FIX.COUNTERS 2DUP ( a1 n1 x y x y -- )
  297.        MAT 2DROP -ROT ( msegb.addr $addr count -- )
  298.        MTYPE
  299.     ELSE DROP
  300.     THEN ;
  301.  
  302. LABEL MOVEM2
  303.     WORD LODS
  304.     WORD STOS       \ write the attribute and char
  305.     LOOP MOVEM2       \ loop till cx is zero
  306.     MOV AX, # 41    \ enable val 29H for mode 3
  307.     MOV DX, # 984   \ adress cga mode control reg
  308.     OUT DX, AL      \ send the enable value
  309.     POP ES          \ restore ES
  310.     POP SI          \ Restore IP
  311.     MOV BX, CS      MOV DS, BX      \ restore DS
  312.     NEXT
  313. LABEL MOVEM1
  314.     CLD
  315.     MOV BX, # 1     \ mask - bit 3
  316.     MOV DX, # 986   \ address cga status port
  317.     BEGIN
  318.         IN AL, DX   \ fetch status
  319.         TEST AL, BX \ mask vertical retrace bit (test)
  320.     0<> UNTIL       \ until retrace seen
  321.     MOV DL, # 216   \ address control reg
  322.     MOV AL, # 37    \ this val disables the crt
  323.     OUT DX, AL      \ display is disabled
  324.     JMP MOVEM2
  325. \ write to screen from ram buffer
  326. CODE MOVEM      ( -- ) \ from msegb to video-seg
  327.     PUSH SI         \ save SI == IP
  328.     PUSH ES         \ save ES == list segment
  329.     MOV CX, # 2000   \ length
  330.     MOV SI, # 0
  331.     MOV DI, # 0
  332.     MOV AX, # 4096    \ offset per page
  333.     MOV BX, #) PAGE#
  334.     MUL BX
  335.     ADD DI, AX      \ offset to the active page
  336.     MOV ES, #) VIDEO-SEG   \ destination segment
  337.     MOV DS, #) ' MSEGB 3 + \ source segment
  338.     JMP MOVEM1
  339. END-CODE
  340.  
  341. \ write from screen to ram buffer (for windows)
  342. CODE MOVE>M      ( -- ) \ from msegb to video-seg
  343.     PUSH SI         \ save SI == IP
  344.     PUSH ES         \ save ES == list segment
  345.     MOV CX, # 2000   \ length
  346.     MOV SI, # 0
  347.     MOV DI, # 0
  348.     MOV AX, # 4096    \ offset per page
  349.     MOV BX, #) PAGE#
  350.     MUL BX
  351.     ADD SI, AX      \ offset to the active page
  352.     MOV ES, #) ' MSEGB 3 + \ source segment
  353.     MOV DS, #) VIDEO-SEG   \ destination segment
  354.     JMP MOVEM1
  355. END-CODE
  356.  
  357. HEX PREFIX
  358. CODE CLEAR.MSEGB    ( -- ) \ clear ram to attrib
  359.     CLD 
  360.     PUSH SI
  361.     PUSH ES           \ save forth
  362.     MOV AX, CS: #) ATTRIB     \ display attributes
  363.     XCHG AH, AL
  364.     MOV AL, # 20   \ a blank
  365.     MOV DI, # 0
  366. \    MOV BX, # ' MSEGB
  367.     MOV ES, #) ' MSEGB 3 +
  368.     MOV CX, # 7d0   \ 2000 words
  369.     REP STOSW       \ write the page
  370.     POP ES
  371.     POP SI          \ restore forth
  372.     NEXT
  373. C;
  374.  
  375. DECIMAL
  376.  
  377. \ the housekeeping words: clear the buffer only once for each screen
  378. : MBUF.PREP  \ for use with ." *ONLY* (don't use with TYPE)
  379.     CLEAR.MSEGB
  380.     ['] (QTYPEM) IS QTYPE
  381.     ['] MAT IS AT ;
  382.  
  383. : MBUF.TYPE \ prepare to TYPE to ram buffer
  384.     CLEAR.MSEGB
  385.     ['] (QTYPET) IS QTYPE ;
  386.  
  387. : MBUF.OFF  \ return to standard forth
  388.     ['] (QTYPE) IS QTYPE
  389.     ['] IBM-AT IS AT ;
  390.  
  391. comment:
  392. AT and DARK are *INTERESTING* words.  Note that they
  393. are not deferred!  They are worth studying.
  394. comment;
  395.  
  396. \ These two words are useful for interspersing ." and TYPE on 
  397. \ the same screen.
  398. \ You may use
  399. \          " string" $.
  400. \ with TYPE instead of ." and avoid this switching!
  401. \ (see AISTRING.SEQ for $.)
  402. : P->T    \ to use TYPE after using ." on the same screen
  403.     ['] (QTYPET) IS QTYPE
  404.     ['] IBM-AT IS AT ;
  405.  
  406. : T->P    \ to use ." after using TYPE on the same screen
  407.     ['] (QTYPEM) IS QTYPE
  408.     ['] MAT IS AT ;
  409.  
  410.