home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 235_01 / direct.asm < prev    next >
Assembly Source File  |  1987-06-17  |  20KB  |  672 lines

  1.         PAGE   60,132
  2.         TITLE  Routines to do direct screen I/O
  3.  
  4. ;  011  12-Dec-86  direct.asm
  5.  
  6. ;       Copyright (c) 1986 by Blue Sky Software.  All rights reserved.
  7.  
  8.  
  9. _TEXT   SEGMENT  BYTE PUBLIC 'CODE'
  10. _TEXT   ENDS
  11. CONST   SEGMENT  WORD PUBLIC 'CONST'
  12. CONST   ENDS
  13. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  14. _BSS    ENDS
  15. _DATA   SEGMENT  WORD PUBLIC 'DATA'
  16. _DATA   ENDS
  17.  
  18. DGROUP  GROUP   CONST,  _BSS,   _DATA
  19.         ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
  20.  
  21. _DATA   SEGMENT
  22.         EXTRN   _screen:DWORD
  23.         EXTRN   _cursor:DWORD
  24.         EXTRN   _vid_attrib:BYTE
  25.         EXTRN   _vid_snow:BYTE
  26.         boxloc  dw    0           ; stores the starting offset to the dialog box
  27. _DATA   ENDS
  28.  
  29. _TEXT      SEGMENT
  30.  
  31. ;******************************************************************************
  32. ;
  33. ;  gotorc(r,c)    move 'cursor' to specified row, col
  34. ;
  35. ;******************************************************************************
  36.  
  37.         PUBLIC _gotorc
  38.  
  39. _gotorc PROC   NEAR
  40.         push    bp
  41.         mov     bp,sp
  42.  
  43.         mov     ax,[bp+4]                      ; row to ax
  44.         mov     cl,5
  45.         shl     ax,cl                          ; row * 32
  46.         mov     bx,ax
  47.         shl     ax,1
  48.         shl     ax,1                           ; row * 128
  49.         add     ax,bx                          ; row * 160
  50.  
  51.         mov     bx,[bp+6]                      ; col to bx
  52.         shl     bx,1                           ; col * 2
  53.  
  54.         add     ax,bx                          ; row * 160 + col * 2 = cursor
  55.         mov     WORD PTR _cursor,ax
  56.  
  57.         mov     sp,bp
  58.         pop     bp
  59.         ret
  60.  
  61. _gotorc ENDP
  62.  
  63. ;******************************************************************************
  64. ;
  65. ;  disp_str(s)    display a string at current location
  66. ;
  67. ;******************************************************************************
  68.  
  69.         PUBLIC  _disp_str
  70.  
  71. _disp_str  PROC NEAR
  72.         push    bp
  73.         mov     bp,sp
  74.         push    di
  75.         push    si
  76.         mov     si,[bp+4]
  77.  
  78.         mov     ah,_vid_attrib         ; attribute byte to ah
  79.         les     di,DWORD PTR _cursor   ; cursor ptr to es:di
  80.  
  81.         jmp     SHORT tst_ch           ; skip to load/test code
  82.  
  83. chloop:
  84.  
  85.         IFDEF  nosnow                  ; if adapter doesn't snow, its quick
  86.            stosw                       ; store char and attrib to es:[di++]
  87.         ELSE                           ; well, its not so quick or easy....
  88.            mov    cx,1
  89.            call   stvideo
  90.         ENDIF
  91.  
  92. tst_ch: lodsb                          ; string char to al
  93.         or      al,al                  ; done when char = 0
  94.         jne     chloop
  95.  
  96.         mov     WORD PTR _cursor,di    ; update cursor offset
  97.  
  98.         pop     si
  99.         pop     di
  100.         mov     sp,bp
  101.         pop     bp
  102.         ret
  103. _disp_str ENDP
  104.  
  105. ;******************************************************************************
  106. ;
  107. ;   disp_char(ch)   display a single char at current location
  108. ;
  109. ;******************************************************************************
  110.  
  111.         PUBLIC  _disp_char
  112.  
  113. _disp_char  PROC NEAR
  114.         push    bp
  115.         mov     bp,sp
  116.         push    di
  117.  
  118.         les     di,DWORD PTR _cursor   ; cursor loc to es:di
  119.  
  120.         mov     al,[bp+4]              ; get char to store in video memory
  121.         mov     ah,_vid_attrib         ; get video attribute
  122.  
  123.         IFDEF nosnow
  124.            stosw                       ; store 'em and update di
  125.         ELSE
  126.            mov  cx,1
  127.            call stvideo
  128.         ENDIF
  129.  
  130.         mov     WORD PTR _cursor,di    ; update cursor offset
  131.  
  132.         pop     di
  133.         mov     sp,bp
  134.         pop     bp
  135.         ret
  136. _disp_char      ENDP
  137.  
  138.  
  139. ;******************************************************************************
  140. ;
  141. ;   disp_rep(ch,cnt)   display a single char cnt times at current location
  142. ;
  143. ;******************************************************************************
  144.  
  145.         PUBLIC  _disp_rep
  146.  
  147. _disp_rep  PROC NEAR
  148.         push    bp
  149.         mov     bp,sp
  150.         push    di
  151.  
  152.         les     di,DWORD PTR _cursor   ; cursor loc to es:di
  153.  
  154.         mov     al,[bp+4]              ; get char to store in video memory
  155.         mov     ah,_vid_attrib         ; get video attribute
  156.         mov     cx,[bp+6]              ; rep count to cx
  157.  
  158.         IFDEF  nosnow
  159.            rep stosw                   ; store 'em and update di
  160.         ELSE
  161.            call stvideo
  162.         ENDIF
  163.  
  164.         mov     WORD PTR _cursor,di    ; update cursor offset
  165.  
  166.         pop     di
  167.         mov     sp,bp
  168.         pop     bp
  169.         ret
  170. _disp_rep  ENDP
  171.  
  172.  
  173. ;******************************************************************************
  174. ;
  175. ;       insert_line(r,n)   insert a line at row, effects n lines
  176. ;
  177. ;******************************************************************************
  178.  
  179.         PUBLIC _insert_line
  180.  
  181. _insert_line PROC NEAR
  182.  
  183.         push    bp
  184.         mov     bp,sp
  185.         push    di
  186.         push    si
  187.  
  188.         mov     bx,[bp+4]              ; ( r + n - 1) * 160 - 2 =
  189.         add     bx,[bp+6]              ;   end of new last row
  190.         dec     bx
  191.         mov     ax,160
  192.         imul    bx
  193.         dec     ax
  194.         dec     ax
  195.         mov     si,ax                  ;   (but its the source for the move)
  196.  
  197.         add     ax,160                 ; call addr of dest (where new last
  198.         mov     di,ax                  ;   line will go)
  199.  
  200.         std                            ; to insert a row, need to go backwards
  201.  
  202.         call    scroll_video           ; scroll the video buffer
  203.  
  204.         mov     al,20h                 ; fill the inserted line with blanks
  205.         mov     ah,_vid_attrib
  206.         mov     cx,80
  207.         IFDEF  nosnow
  208.            rep stosw
  209.         ELSE
  210.            call stvideo
  211.         ENDIF
  212.  
  213.         cld                            ; C expects it this way
  214.  
  215.         pop     si
  216.         pop     di
  217.         mov     sp,bp
  218.         pop     bp
  219.         ret
  220.  
  221. _insert_line ENDP
  222.  
  223.  
  224. ;******************************************************************************
  225. ;
  226. ;       delete_line(r,n)   delete a line at row, effects n lines
  227. ;
  228. ;******************************************************************************
  229.  
  230.         PUBLIC _delete_line
  231.  
  232. _delete_line PROC NEAR
  233.  
  234.         push    bp
  235.         mov     bp,sp
  236.         push    di
  237.         push    si
  238.  
  239.         mov     ax,160                 ; get row
  240.         imul    WORD PTR [bp+4]        ;   turn into offset in video ram
  241.         mov     di,ax
  242.  
  243.         add     ax,160                 ; calc offset of next row
  244.         mov     si,ax
  245.  
  246.         call    scroll_video           ; scroll the video buffer
  247.  
  248.         mov     al,20h                 ; fill the last line with blanks
  249.         mov     ah,_vid_attrib
  250.         mov     cx,80
  251.         IFDEF  nosnow
  252.            rep stosw
  253.         ELSE
  254.            call stvideo
  255.         ENDIF
  256.  
  257.         pop     si
  258.         pop     di
  259.         mov     sp,bp
  260.         pop     bp
  261.         ret
  262. _delete_line  ENDP
  263.  
  264.  
  265. ;*****************************************************************************
  266. ;
  267. ;   scroll_video   support routine for insert/delete line
  268. ;
  269. ;*****************************************************************************
  270.  
  271. scroll_video PROC NEAR
  272.  
  273.         mov     ax,80                  ; get # rows to move and
  274.         imul    WORD PTR [bp+6]        ;   turn into # words to move
  275.         mov     cx,ax
  276.  
  277.         IFNDEF  nosnow
  278.            mov  al,_vid_snow           ; movideo needs vid_snow - get it
  279.         ENDIF                          ;   before ds gets changed
  280.  
  281.         push    ds                     ; save current ds
  282.         mov     bx,WORD PTR _screen+2  ; segment address of video ram
  283.         mov     ds,bx                  ; moving to/from video ram
  284.         mov     es,bx
  285.  
  286.         IFDEF   nosnow
  287.            rep movsw                   ; scroll the data in the video buffer
  288.         ELSE
  289.            call movideo
  290.         ENDIF
  291.  
  292.         pop    ds                      ; restore ds
  293.  
  294.         ret
  295.  
  296. scroll_video ENDP
  297.  
  298.  
  299. ;******************************************************************************
  300. ;
  301. ;       scrcpy(to,from)
  302. ;       char far *to, far *from;
  303. ;
  304. ;       copy screen image from to
  305. ;
  306. ;******************************************************************************
  307.  
  308.         PUBLIC  _scrcpy
  309.  
  310. _scrcpy PROC NEAR
  311.  
  312.         push    bp
  313.         mov     bp,sp
  314.         push    di
  315.         push    si
  316.         push    ds
  317.  
  318.         IFNDEF  nosnow
  319.         mov     al,_vid_snow           ; flag for movideo
  320.         ENDIF
  321.  
  322.         les     di,[bp+4]              ; es:di is to address
  323.         lds     si,[bp+8]              ; ds:si is from address
  324.         mov     cx,80*25               ; HARDCODED screen size in words
  325.  
  326.         IFDEF   nosnow                 ; move the screen image
  327.         rep movsw
  328.         ELSE
  329.         call    movideo
  330.         ENDIF
  331.  
  332.         pop     ds
  333.         pop     si
  334.         pop     di
  335.         mov     sp,bp
  336.         pop     bp
  337.         ret
  338.  
  339. _scrcpy ENDP
  340.  
  341.  
  342. ;******************************************************************************
  343. ;
  344. ;       popup(row,col,nrows,ncols,savp)
  345. ;
  346. ;       pop up a dialog box on the screen starting at row,col.
  347. ;       If savp is not NULL, the current contents of the video ram
  348. ;       under the box are saved.
  349. ;
  350. ;******************************************************************************
  351.  
  352.         PUBLIC  _popup
  353.  
  354. _popup  PROC NEAR
  355.         push    bp
  356.         mov     bp,sp
  357.         push    di
  358.         push    si
  359.  
  360.         mov     ax,160                         ; calc offset to start of
  361.         imul    WORD PTR [bp+4]                ; dialog box -
  362.         mov     cx,[bp+6]                      ; row * 160 + (col << 1)
  363.         shl     cx,1
  364.         add     ax,cx
  365.  
  366.         mov     si,ax                          ; si now -> box start offset
  367.         mov     boxloc,si                      ; save it for later
  368.  
  369.         mov     di,[bp+12]                     ; get savp, the save addr ptr
  370.         or      di,di                          ; does user want contents saved?
  371.         je      skipsave
  372.  
  373.         mov     dx,si                          ; save current row offset
  374.  
  375.         mov     bh, BYTE PTR [bp+8]            ; nrows to bh
  376.         mov     bl, BYTE PTR [bp+10]           ; ncols to bl
  377.  
  378.         mov     ax,ds                          ; set es and ds so str instrs
  379.         mov     es,ax                          ; work the way we want
  380.         mov     cx,WORD PTR _screen+2          ; ds points to video ram
  381.         mov     ds, cx
  382.  
  383.         IFNDEF  nosnow
  384.            mov  al,es: _vid_snow               ; movideo needs _vid_snow
  385.            push ax
  386.         ENDIF
  387.  
  388. nxtrow: mov     cl,bl                          ; move ncols to cx
  389.         xor     ch,ch
  390.  
  391.         IFDEF   nosnow
  392.            rep movsw                           ; move data
  393.         ELSE
  394.            pop  ax                             ; get/save _vid_snow
  395.            push ax
  396.            call movideo
  397.         ENDIF
  398.  
  399.         add     dx,160                         ; calc offset of next row
  400.         mov     si,dx
  401.  
  402.         dec     bh                             ; one more row done, any more?
  403.         jnz     nxtrow
  404.  
  405.         IFNDEF  nosnow
  406.            pop  ax                             ; clear stack
  407.         ENDIF
  408.  
  409.         mov     ax,es                          ; restore the ds reg
  410.         mov     ds,ax
  411.  
  412.         mov     si,boxloc                      ; reget box starting offset
  413.  
  414. skipsave:
  415.  
  416.         mov     di,si                          ; video ram is now the dest
  417.         mov     es,WORD PTR _screen+2          ; video ram segment
  418.  
  419.         mov     al,201                         ; disp the upper left corner
  420.         mov     ah,_vid_attrib                 ; the video attrib to use
  421.         IFDEF  nosnow
  422.            stosw                               ; store in video ram
  423.         ELSE
  424.            mov  cx,1
  425.            call stvideo
  426.         ENDIF
  427.  
  428.         mov     cx,[bp+10]                     ; now do the horizontal line
  429.         dec     cx                             ; its ncols - 2 long
  430.         dec     cx
  431.         mov     [bp+10],cx                     ; ncols - 2 is used again
  432.         mov     al,205                         ; horizontal bar char
  433.         IFDEF   nosnow
  434.            rep stosw
  435.         ELSE
  436.            call stvideo
  437.         ENDIF
  438.  
  439.         mov     al,187                         ; disp the upper right corner
  440.         IFDEF   nosnow
  441.            stosw                               ; store in video ram
  442.         ELSE
  443.            mov  cx,1
  444.            call stvideo
  445.         ENDIF
  446.  
  447.         ; now do the blank lines in the body of the box
  448.  
  449.         mov     bx,[bp+8]                      ; the body is nrows - 2 long
  450.         dec     bx
  451.         dec     bx
  452.  
  453.         add     si,160                         ; bump row offset
  454.         mov     di,si
  455.  
  456. rownxt: mov     al,186                         ; do the left vertical bar
  457.         IFDEF   nosnow
  458.            stosw                               ; store in video ram
  459.         ELSE
  460.            mov  cx,1
  461.            call stvideo
  462.         ENDIF
  463.  
  464.         mov     cx,[bp+10]                     ; now all the blanks
  465.         mov     al,32
  466.         IFDEF   nosnow
  467.            rep stosw
  468.         ELSE
  469.            call stvideo
  470.         ENDIF
  471.  
  472.         mov     al,186                         ; do the right vertical bar
  473.         IFDEF   nosnow
  474.            stosw                               ; store in video ram
  475.         ELSE
  476.            mov  cx,1
  477.            call stvideo
  478.         ENDIF
  479.  
  480.         add     si,160                         ; bump row offset
  481.         mov     di,si
  482.  
  483.         dec     bx                             ; another row done
  484.         jnz     rownxt
  485.  
  486.         ; now do the bottom row of the box
  487.  
  488.         mov     al,200                         ; disp the lower left corner
  489.         IFDEF   nosnow
  490.            stosw                               ; store in video ram
  491.         ELSE
  492.            mov  cx,1
  493.            call stvideo
  494.         ENDIF
  495.  
  496.         mov     cx,[bp+10]                     ; now do the horizontal line
  497.         mov     al,205                         ; horizontal bar char
  498.         IFDEF   nosnow
  499.            rep stosw
  500.         ELSE
  501.            call stvideo
  502.         ENDIF
  503.  
  504.         mov     al,188                         ; disp the lower right corner
  505.         IFDEF   nosnow
  506.            stosw                               ; store in video ram
  507.         ELSE
  508.            mov  cx,1
  509.            call stvideo
  510.         ENDIF
  511.  
  512.         pop     si                             ; done, exit
  513.         pop     di
  514.         mov     sp,bp
  515.         pop     bp
  516.         ret
  517. _popup  ENDP
  518.  
  519.  
  520. ;******************************************************************************
  521. ;
  522. ;       popdwn(row,col,nrows,ncols,savp)
  523. ;
  524. ;       Remove a pop up dialog box from the screen by restoring the prior
  525. ;       contents from savp.
  526. ;
  527. ;******************************************************************************
  528.  
  529.         PUBLIC  _popdwn
  530.  
  531. _popdwn PROC NEAR
  532.         push    bp
  533.         mov     bp,sp
  534.         push    di
  535.         push    si
  536.  
  537.         mov     ax,160                         ; calc offset to start of
  538.         imul    WORD PTR [bp+4]                ; dialog box -
  539.         mov     cx,[bp+6]                      ; row * 160 + (col << 1)
  540.         shl     cx,1
  541.         add     ax,cx
  542.  
  543.         mov     di,ax                          ; di now -> box start offset
  544.  
  545.         mov     si,[bp+12]                     ; get savp, the save addr ptr
  546.  
  547.         mov     dx,di                          ; save current row offset
  548.  
  549.         mov     bh, BYTE PTR [bp+8]            ; nrows to bh
  550.         mov     bl, BYTE PTR [bp+10]           ; ncols to bl
  551.  
  552.         mov     es,WORD PTR _screen+2          ; oh yea, es points to video ram
  553.  
  554. next:   mov     cl,bl                          ; move ncols to cx
  555.         xor     ch,ch
  556.  
  557.         IFDEF  nosnow
  558.            rep movsw                           ; move data
  559.         ELSE
  560.            mov  al,_vid_snow
  561.            call movideo
  562.         ENDIF
  563.  
  564.         add     dx,160                         ; calc offset of next row
  565.         mov     di,dx
  566.  
  567.         dec     bh                             ; one more row done, any more?
  568.         jnz     next
  569.  
  570.         pop     si
  571.         pop     di
  572.         mov     sp,bp
  573.         pop     bp
  574.         ret
  575. _popdwn ENDP
  576.  
  577.         IFNDEF  nosnow
  578.  
  579. ;******************************************************************************
  580. ;
  581. ;   movideo - move data to/from video memory
  582. ;           - current video mode must be passed in al
  583. ;
  584. ;******************************************************************************
  585.  
  586. movideo PROC NEAR
  587.  
  588.         test    al,1                   ; do we need to check for snow?
  589.         jnz     goslow
  590.  
  591.         rep  movsw                     ; no snow, full speed ahead
  592.         ret                            ; that's all there is to it
  593.  
  594. goslow: push    dx                     ; it's a cga, go slow time
  595.  
  596.         mov     dx,03dah               ; dx = cga status port address
  597.  
  598. wait1:  in      al,dx                  ; get retrace status
  599.         test    al,8                   ; vertical retrace?
  600.         jnz     mov_it                 ; yes, go get the char
  601.         ror     al,1                   ; low bit set? (horizontal retrace)
  602.         jc      wait1                  ; current retrace may be almost done
  603.  
  604.         cli                            ; no interrupts until char loaded
  605.  
  606. wait2:  in      al,dx                  ; wait for start of next retrace
  607.         ror     al,1
  608.         jnc     wait2
  609.  
  610. mov_it: movsw                          ; move word to/from video ram
  611.  
  612.         sti                            ; allow interrupts
  613.  
  614.         loop    wait1                  ; all chars transfered?
  615.  
  616.         pop     dx                     ; restore dx
  617.  
  618.         ret
  619.  
  620. movideo ENDP
  621.  
  622.  
  623. ;******************************************************************************
  624. ;
  625. ;  stvideo - store the word in ax to video ram cx times
  626. ;
  627. ;******************************************************************************
  628.  
  629. stvideo PROC NEAR
  630.  
  631.         test    _vid_snow,1            ; do we need to slow for no snow?
  632.         jnz     slowgo
  633.  
  634.         rep  stosw                     ; no snow, full speed ahead
  635.         ret                            ; that's all there is to it
  636.  
  637. slowgo: push    bx                     ; snow, go slow
  638.         push    dx
  639.  
  640.         mov     dx,03dah               ; dx = cga status port address
  641.         mov     bx,ax
  642.  
  643. wait3:  in      al,dx                  ; get retrace status
  644.         test    al,8                   ; vertical retrace?
  645.         jnz     sto_it                 ; yes, go get the char
  646.         ror     al,1                   ; low bit set? (horizontal retrace)
  647.         jc      wait3                  ; current retrace may be almost done
  648.  
  649.         cli                            ; no interrupts until char loaded
  650.  
  651. wait4:  in      al,dx                  ; wait for start of next retrace
  652.         ror     al,1
  653.         jnc     wait4
  654.  
  655. sto_it: mov     ax,bx
  656.         stosw                          ; store word to video ram
  657.  
  658.         sti                            ; allow interrupts
  659.  
  660.         loop    wait3                  ; all chars transfered?
  661.  
  662.         pop     dx                     ; restore dx & bx
  663.         pop     bx
  664.  
  665.         ret
  666. stvideo ENDP
  667.  
  668.         ENDIF
  669.  
  670. _TEXT   ENDS
  671.         END
  672.