home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / chasm2.zip / ZAPSTUFF.ASM < prev   
Assembly Source File  |  1986-04-06  |  21KB  |  458 lines

  1. ;===================================================
  2. ; module ZapStuff
  3. ;
  4. ; Module of external procedures for Turbo Pascal.
  5. ; Provides high speed direct write screen output.
  6. ;
  7. ; In Turbo, declare as:
  8. ;
  9. ; procedure ZapStuff;
  10. ;    external 'zapstuff.com';
  11. ;
  12. ; procedure ZapStr(var Str: AnyString; Row, Column, Attribute, Video: byte);
  13. ;    external zapstuff[0];
  14. ;
  15. ; procedure ZapClrEOL(Row, Column, Attribute, Video: byte);
  16. ;    external zapstuff[3];
  17. ;
  18. ; procedure ZapClrBox(ulrow, ulcolumn, lrrow, lrcol, attribute: byte);
  19. ;    external zapstuff[6];
  20. ;
  21. ; See page 211 of the Turbo Pascal version 3 manual for
  22. ; a discussion of this declaration syntax.
  23. ;===================================================
  24.  
  25. bios_data    equ   40H
  26. equip_flag   equ   [10H]
  27. crt_status   equ   3DAH       ;crt status port on 6845 controller chip
  28. mono_seg     equ   0B000H
  29. color_seg    equ   0B800H
  30.  
  31. ;==========================================================
  32. ; The following structures mimic the contents of the stack
  33. ; for calls to each of the procedures.  Note that byte
  34. ; parameters occupy an entire word on the stack.
  35. ;==========================================================
  36.  
  37. strstack        struc                       ;simulate stack contents
  38. str_old_bp      dw      0000H               ;saved bp register
  39. str_ret_addr    dw      0000H               ;return address to turbo pascal
  40. str_video       dw      0000H               ;5th param: video output method
  41. str_attrib      dw      0000H               ;4th param: attribute byte
  42. str_col         dw      0000H               ;3rd param: column
  43. str_row         dw      0000H               ;2nd param: row
  44. str_str_offs    dw      0000H               ;1st param: offset of string
  45. str_str_seg     dw      0000H               ;1st param: segment of string
  46.                 endstruc
  47.  
  48. eolstack        struc
  49. eol_old_bp      dw      0000H               ;saved bp register
  50. eol_ret_addr    dw      0000H               ;return address to turbo pascal
  51. eol_video       dw      0000H               ;4th param: video output method
  52. eol_attrib      dw      0000H               ;3rd param: video attribute
  53. eol_col         dw      0000H               ;2nd param: column
  54. eol_row         dw      0000H               ;1st param: row
  55.                 endstruc
  56.  
  57. cbstack         struc
  58. cb_old_bp       dw      0000H               ;saved bp register
  59. cb_ret_addr     dw      0000H               ;return address to turbo pascal
  60. cb_attrib       dw      0000H               ;5th param: video attribute
  61. cb_lrc          dw      0000H               ;4th param: lower right column
  62. cb_lrr          dw      0000H               ;3rd param: lower right row
  63. cb_ulc          dw      0000H               ;2nd param: upper left column
  64. cb_ulr          dw      0000H               ;1st param: upper left row
  65.                 endstruc
  66.  
  67. ;==================================
  68. ; Entry Point
  69. ;
  70. ; Jump table to various procedures
  71. ;==================================
  72.             org  0
  73. enterstr    jmp  zapstr      ;print a string
  74. enterclreol jmp  zapclreol   ;clear to the end of line
  75. enterclrbox jmp  zapclrbox   ;clear out a defined area
  76.  
  77. ;=======================================================================
  78. ; procedure ZapStr(var Str: AnyString; Row, Column, Attribute, Video: byte);
  79. ;
  80. ; Outputs a string at the specified screen location, using the given attribute.
  81. ;
  82. ; The output method depends on the value of parameter VIDEO:
  83. ;
  84. ;    0 = direct write to hardware, no delay
  85. ;    1 = direct write to hardware, but only during screen retrace
  86. ;    2 = write via BIOS
  87. ;========================================================================
  88. zapstr          proc    near
  89.  
  90.                 push    bp                   ;establish stack
  91.                 mov     bp, sp               ;  addressability
  92.                 push    ds                   ;save state
  93.                 push    es                   ; ditto
  94.  
  95.                 lds     si, str_str_offs[bp] ;set up to access string
  96.                 xor     ch, ch               ;CX <== length of string
  97.                 mov     cl, [si]             ; ditto
  98.                 cmp     cl, 0                ;any characters to write?
  99.                 je      str_exit             ;exit if not
  100.                 inc     si                   ;SI <== pointer to first char
  101.  
  102.                 mov     dl, str_video[bp]    ;which video method?
  103.                 cmp     dl, 2                ; -BIOS calls?
  104.                 jl      str_direct           ; if not use direct write
  105.                 call    str_bios             ; if so, use bios calls
  106.                 jmps    str_exit             ; and exit
  107.                 ;=====================================
  108.                 ; Set up for both direct write flavors
  109.                 ; After this fragment, the following
  110.                 ; register assignments hold:
  111.                 ;
  112.                 ;   ES:DI  pointer into video buffer
  113.                 ;   DS:SI  pointer to 1st string character
  114.                 ;   CX: length of string
  115.                 ;   AH: video attribute byte
  116.                 ;   DL: video output method
  117.                 ;=====================================
  118. str_direct      xor     ah, ah               ;AX <== column number
  119.                 mov     al, str_col[bp]      ;get column
  120.                 xor     bh, bh               ;BX <== row number
  121.                 mov     bl, str_row[bp]      ;get row
  122.                 call    calc_offset          ;DI <== offset into buffer
  123.                 call    set_video_seg        ;set up ES to access video buffer
  124.                 mov     ah, str_attrib[bp]   ;AH <== video attribute
  125.                 jc      str_use_dw           ;monochrome always direct write
  126.                 rcr     dl                   ;retrace only mode?
  127.                 jc      str_use_dwr          ;yes
  128. str_use_dw      call    str_dw               ;else use direct write
  129.                 jmps    str_exit             ;and done
  130. str_use_dwr     call    str_dwr              ;use direct write/retrace
  131.                                              ;fall through to exit
  132.  
  133. str_exit        pop     es                   ;restore state
  134.                 pop     ds                   ; ditto
  135.                 pop     bp                   ; ditto
  136.                 ret     12                   ;clear params and return
  137.                 endp                         ;zapstr
  138. ;=================================================
  139. ; STR_BIOS
  140. ;
  141. ; Write string to the screen using BIOS calls.
  142. ; Slow as a dog, but safe.
  143. ;
  144. ; Assumptions:
  145. ;
  146. ;    DS:SI         pointer to string
  147. ;    CX            length of string
  148. ;==================================================
  149. str_bios        proc     near
  150.                 mov     di, cx               ;DI <== string length
  151.  
  152.                 mov     ah, 03               ;get current cursor position
  153.                 mov     bh, 0                ;active page number
  154.                 int     10H                  ;call BIOS
  155.                 push    dx                   ;save cursor position for restore
  156.  
  157.                 mov     dl, str_col[bp]      ;get column
  158.                 dec     dl                   ;correct for 0,0 origin
  159.                 mov     dh, str_row[bp]      ;get row
  160.                 dec     dh                   ;correct for 0,0 origin
  161.                 mov     bl, str_attrib[bp]   ;get attribute byte
  162.  
  163.                 mov     cx, 1                ;write only one char per call
  164.                 mov     bh, 0                ;work on page 0
  165. str_bios_loop   mov     ah, 2                ;set cursor position
  166.                 int     10H                  ;with BIOS call
  167.  
  168.                 lodsb                        ;AH <== next character
  169.                 mov     ah, 9                ;write char/attrib
  170.                 int     10H                  ;with BIOS call
  171.  
  172.                 inc     dl                   ;bump current column
  173.                 dec     di                   ;used up one char
  174.                 jnz     str_bios_loop        ;loop til out of chars
  175.  
  176.                 pop     dx                   ;restore cursor
  177.                 mov     ah, 2                ;  ditto
  178.                 int     10H                  ;  ditto
  179.                 ret                          ;and return
  180.                 endp
  181.  
  182. ;====================================================
  183. ; Str_DW
  184. ;
  185. ; Full speed direct write of string to video buffer.
  186. ;
  187. ; Assumptions:
  188. ;
  189. ;   DS:SI points to first character of string
  190. ;   ES:DI points to desired location in video buffer
  191. ;   CX    has length of string
  192. ;   AH    has desired video attribute byte
  193. ;
  194. ; Note that we read char *bytes* from the string,
  195. ; but write char/attrib *words* to buffer.
  196. ;====================================================
  197. str_dw          proc    near
  198.                 cld                          ;8088 --> autoincrement mode
  199. str_dw_loop     lodsb                        ;get a char from string
  200.                 stosw                        ;put char and attrib in buffer
  201.                 loop    str_dw_loop          ;continue till done
  202.                 ret                          ;done, so exit
  203.                 endp
  204. ;====================================================
  205. ; Str_DWR
  206. ;
  207. ; String direct write during retrace.
  208. ;
  209. ; Assumptions:
  210. ;
  211. ;   DS:SI points to first character of string
  212. ;   ES:DI points to desired location in video buffer
  213. ;   CX    has length of string
  214. ;   AH    has desired video attribute byte
  215. ;=====================================================
  216. str_dwr         proc    near
  217.                                              ;preload stuff for fast action
  218.                 mov     bh, 9                ;mask to detect both retraces
  219.                 mov     dx, crt_status       ;pointer to crt controller chip
  220.  
  221.                 cld                          ;8088 --> autoincrement mode
  222. str_stall       in      al, dx               ;throw away any current horiz.
  223.                 rcr     al                   ;retrace so we catch the next
  224.                 jc      str_stall            ;*full* one.  This one may be
  225.                                              ;half over already.
  226.  
  227.                 lodsb                        ;get the next char
  228.                 mov     bl, al               ;save it, we need AL
  229.                 cli                          ;we're busy, let the phone ring
  230. str_wait        in      al, dx               ;watch for retrace
  231.                 and     al, bh               ;either horiz or vert
  232.                 jz      str_wait             ;not yet? loop
  233.  
  234.                 mov     al, bl               ;recover char
  235.                 stosw                        ;stuff it into the buffer
  236.                 sti                          ;answer the phone
  237.                 loop    str_stall            ;loop til done
  238.                 ret
  239.                 endp
  240.  
  241. ;============================================
  242. ; ZapClrEOL
  243. ;
  244. ; Starting from the indicated row and column,
  245. ; clear to the end of the line.
  246. ;============================================
  247. zapclreol       proc    near
  248.                 push    bp                   ;establish stack
  249.                 mov     bp, sp               ;  addressability
  250.                 push    ds                   ;save state
  251.                 push    es                   ; ditto
  252.  
  253.                 mov     dl, eol_video[bp]    ;which video method?
  254.                 cmp     dl, 2                ;bios call?
  255.                 jne     eol_direct           ;if not, use direct write
  256.                 call    eol_bios             ;otherwise use bios calls
  257.                 jmps    eol_exit
  258.  
  259.                 ;======================================
  260.                 ; Set up for both direct write flavors
  261.                 ;======================================
  262. eol_direct      mov     cx, 81               ;calculate bytes to clear
  263.                 mov     ax, eol_col[bp]      ;AX <== column
  264.                 mov     bx, eol_row[bp]      ;BX <== row
  265.                 sub     cx, ax               ;CX <== bytes to clear
  266.  
  267.                 call    calc_offset          ;DI <== offset into buffer
  268.                 call    set_video_seg        ;set up ES to access video buffer
  269.                 mov     ah, eol_attrib[bp]   ;AH <== video attribute
  270.                 mov     al, ' '              ;fill with spaces
  271.                 jc      eol_use_dw           ;monochrome always direct write
  272.                 rcr     dl                   ;retrace only mode?
  273.                 jc      eol_use_dwr          ;yes
  274. eol_use_dw      call    eol_dw               ;no, use direct write
  275.                 jmps    eol_exit             ;then exit
  276. eol_use_dwr     call    eol_dwr              ;use write during retrace
  277.                 jmps    eol_exit             ;then exit
  278.  
  279. eol_exit        pop     es                   ;restore state
  280.                 pop     ds                   ; ditto
  281.                 pop     bp                   ; ditto
  282.                 ret     8                    ;clear params and return
  283.                 endp                         ;zapclreol
  284.  
  285. ;===============================================
  286. ; Char_DW
  287. ;
  288. ; Direct write of character(s) to video buffer.
  289. ; Assumptions:
  290. ;
  291. ;    ES:DI   pointer into video buffer
  292. ;    AX      char/attribute
  293. ;    CX      repetition factor
  294. ;===============================================
  295. eol_dw          proc    near
  296.                 cld                          ;8088 <== autoincrement mode
  297.                 rep                          ;do it
  298.                 stosw
  299.                 ret
  300.                 endp
  301.  
  302. ;===============================================
  303. ; EOL_DWR
  304. ;
  305. ; Direct write of character(s) to video buffer,
  306. ; during retrace interval.
  307. ; Assumptions:
  308. ;
  309. ;    ES:DI   pointer into video buffer
  310. ;    AX      char/attribute
  311. ;    CX      repetition factor
  312. ;===============================================
  313. eol_dwr         proc    near
  314.                                              ;preload stuff for fast action
  315.                 mov     bl, al               ;save character
  316.                 mov     bh, 9                ;mask to detect both retraces
  317.                 mov     dx, crt_status       ;pointer to crt controller chip
  318.                 cld                          ;8088 --> autoincrement mode
  319.  
  320. eol_stall       in      al, dx               ;throw away any current horiz.
  321.                 rcr     al                   ;retrace so we catch the next
  322.                 jc      eol_stall            ;*full* one.  This one may be
  323.                                              ;half over already.
  324.  
  325.                 cli                          ;we're busy, let the phone ring
  326. eol_wait        in      al, dx               ;watch for retrace
  327.                 and     al, bh               ;either horiz or vert
  328.                 jz      eol_wait             ;not yet? loop
  329.  
  330.                 mov     al, bl               ;recover char
  331.                 stosw                        ;stuff it into the buffer
  332.                 sti                          ;answer the phone
  333.                 loop    eol_stall            ;loop til done
  334.                 ret
  335.                 endp
  336.  
  337. ;=============================================
  338. ; EOL_BIOS
  339. ;
  340. ; Write character(s) to screen using BIOS call.
  341. ;=============================================
  342. eol_bios        proc    near
  343.                 mov     ah,  03              ;current cursor position?
  344.                 mov     bh,  0               ;  on page 0
  345.                 int     10H                  ;  with BIOS call
  346.                 push    dx                   ;  save position on stack
  347.  
  348.                 mov     cx, 81               ;calculate bytes to clear
  349.                 mov     dx, eol_col[bp]      ;AX <== column
  350.                 mov     ax, eol_row[bp]      ;DX <== row
  351.                 sub     cx, dx               ;CX <== bytes to clear
  352.  
  353.                 mov     dh, al               ;DH,DL <== row, column
  354.                 dec     dh                   ;correct for 0,0 origin
  355.                 dec     dl                   ;  ditto
  356.  
  357.                 mov     ah, 2                ;set cursor position
  358.                 mov     bh, 0                ;work on page 0
  359.                 int     10H
  360.  
  361.                 mov     al, ' '              ;fill with space chars
  362.                 mov     bl,  eol_attrib[bp]  ;get video attribute for clear
  363.                 mov     ah, 9                ;call BIOS for write operation
  364.                 int     10H
  365.  
  366.                 mov     ah, 02               ;restore cursor position
  367.                 mov     bh, 0                ;  ditto
  368.                 pop     dx                   ;  ditto
  369.                 int     10H                  ;  ditto
  370.  
  371.                 ret                          ;and exit
  372.                 endp
  373.  
  374. ;==============================================
  375. ; ZapClrBox
  376. ;
  377. ; Clears the specifed area of the video screen.
  378. ;==============================================
  379. zapclrbox      proc    near
  380.                push    bp                   ;establish stack
  381.                mov     bp, sp               ;  addressability
  382.  
  383.                mov     ch, cb_ulr[bp]       ;define upper left corner
  384.                dec     ch                   ;BIOS defines upper left 0,0
  385.                mov     cl, cb_ulc[bp]       ;
  386.                dec     cl
  387.                mov     dh, cb_lrr[bp]       ;define lower right corner
  388.                dec     dh
  389.                mov     dl, cb_lrc[bp]       ;  ditto
  390.                dec     dl
  391.                mov     bh, cb_attrib[bp]    ;attribute to fill with
  392.                mov     ax, 0600H            ;scroll entire window up
  393.  
  394.                int     10H                  ;call bios
  395.  
  396.                pop     bp                   ; ditto
  397.                ret     10                   ;clear params and return
  398.                endp                         ;zapclreol
  399. ;===========================================
  400. ; SET_VIDEO_SEG
  401. ;
  402. ; Points ES at the appropriate video buffer
  403. ; depending on which display adapter is installed.
  404. ; Returns with carry flag clear if color card,
  405. ; set for monochrome.
  406. ;===========================================
  407. set_video_seg   proc    near                 ;points ES at video buffer
  408.                 push    ds                   ;set up to read equipment flag
  409.                 mov     ax, bios_data        ; ditto
  410.                 mov     ds, ax               ; ditto
  411.                 mov     ax, equip_flag       ;get flag
  412.                 and     ax, 30H              ;look at monitor bits only
  413.                 cmp     ax, 30H              ;is this the monochrome monitor?
  414.                 je      set_video_mono       ;yep, skip.
  415.                 mov     ax, color_seg        ;nope.  Use color segment
  416.                 mov     es, ax
  417.                 clc                          ;set carry to indicate color
  418.                 jmps    set_video_exit       ;and exit
  419.  
  420. set_video_mono  mov     ax, mono_seg         ;yep, use monochrome segment
  421.                 mov     es, ax
  422.                 stc                          ;set carry to indicate monochrome
  423.  
  424. set_video_exit  pop     ds
  425.                 ret
  426.                 endp
  427.  
  428. ;========================================================
  429. ; CALC_OFFSET
  430. ;
  431. ; Input:  AX   screen column
  432. ;         BX   screen row
  433. ;
  434. ; Output: DI   offset into video buffer
  435. ;         AX   trash
  436. ;         BX   trash
  437. ;
  438. ; Shifts and adds are used in place of multiplication
  439. ; for optimum speed.  MUL requires a minimum of 74 clocks.
  440. ; The optimized "multiply by 160" sequence uses only 19 clocks.
  441. ;===============================================================
  442. calc_offset     proc    near
  443.                 dec     bx                   ;rows past #1
  444.                 mov     di, bx               ;multiply row by 160
  445.                 shl     di                   ;times 2
  446.                 shl     di                   ;times 2 makes 4
  447.                 add     di, bx               ;1 more makes 5
  448.                 shl     di                   ;times 2 makes 10
  449.                 shl     di                   ;times 2 makes 20
  450.                 shl     di                   ;times 2 makes 40
  451.                 shl     di                   ;times 2 makes 80
  452.                 shl     di                   ;times 2 makes 160
  453.                 dec     ax                   ;columns past #1
  454.                 shl     ax                   ;column x 2 (2 bytes/char)
  455.                 add     di, ax               ;di now has offset in buffer
  456.                 ret                          ;return to caller
  457.                 endp
  458.