home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / turbopas / tavid12.arc / VIDEO2.ASM < prev   
Assembly Source File  |  1988-12-22  |  21KB  |  877 lines

  1. TITLE 'Direct Video Routines'
  2.  
  3. ;
  4. ; Author: David Bennett - Version 1.0 - Date: 11/9/88
  5. ;
  6. ; This is a module of direct video writing routines for TASM.  Please see the
  7. ; file VIDEO.DOC for more information.  Examples of most routines are set forth
  8. ; in VIDDEMO.ASM.
  9. ;
  10. ; -Dave
  11. ;v1.2, Toad Hall tweak
  12. ; -    This version is a "standalone" program that should be compiled
  13. ;    separately.  Save the .OBJ file for later incorporation via LINK
  14. ;    with your main program.
  15. ;    Globals are right at the top (which you, of course, will declare
  16. ;    as externals in YOUR program.
  17.  
  18.  
  19. Comment ~
  20. Move the following lines to YOUR program (and uncomment them!):
  21.     EXTRN    MoveXY_DI: NEAR,    MoveXY_SI: NEAR
  22.     EXTRN    EGAInstalled: NEAR,    GetVideoMode: NEAR
  23.     EXTRN    DWriteCh: NEAR,        DWriteChNA: NEAR
  24.     EXTRN    DWriteStr: NEAR,    DWriteStrNA: NEAR
  25.     EXTRN    DFillCh: NEAR,        DFillChNA: NEAR
  26.     EXTRN    DFillAttr: NEAR,    StoreToMem: NEAR
  27.     EXTRN    StoreToScr: NEAR,    CursorOff: NEAR
  28.     EXTRN    CursorOn: NEAR
  29.  
  30.     EXTRN    baseOfScreen : WORD
  31.     EXTRN    snowcheck: BYTE,    videomode: BYTE
  32. end of Comment ~
  33.  
  34. CSeg    SEGMENT PUBLIC PARA 'CODE'
  35.     ASSUME    CS:CSeg,DS:CSeg
  36.  
  37.     PUBLIC    MoveXY_DI,MoveXY_SI,EGAInstalled,GetVideoMode
  38.     PUBLIC    DWriteCh,DWriteChNA,DWriteStr,DWriteStrNA
  39.     PUBLIC    DFillCh,DFillChNA,DFillAttr,StoreToMem,StoreToScr
  40.     PUBLIC    CursorOff,CursorOn
  41.  
  42.     PUBLIC    baseOfScreen,snowcheck,videomode
  43.  
  44. baseOfScreen    DW    CGASEG        ; Offset for current vid mode
  45. snowcheck    DB    0        ; Check for retrace 1/0
  46. videomode    DB    0        ; Current BIOS INT 10 vid mode
  47.  
  48.     INCLUDE    VIDEO1.INC        ;various definitions
  49.  
  50. ; ------
  51. ; Macros
  52. ; ------
  53.  
  54. WaitRetrace    MACRO
  55.     LOCAL    WaitNoH, WaitH, WaitX
  56. ;
  57. ; This macro waits for the horizontial retrace signal from the
  58. ; monitor before continuing. Interrupts should be disabled B4
  59. ; calling this routine with CLI. Of course, make sure int's are
  60. ; reenabled afterwards with STI.
  61. ;
  62. ; Modifies
  63. ;    DX, AL
  64. ;
  65.     mov    dx, 3DAh        ; CGA status register
  66. WaitNoH:
  67.     in    al, dx            ; Get 6845 Status
  68.     test    al,8            ; Check vert retrace
  69.     jnz    WaitX            ;   In Progress? go
  70.     rcr    al,1            ; Wait for end of
  71.     jc    WaitNoH            ;   horizontal retrace
  72. WaitH:
  73.     in    al, dx            ; Get 6845 status again
  74.     rcr    al, 1            ; Wait for horizontial
  75.     jnc    WaitH            ;   retrace
  76. WaitX:
  77. ENDM
  78.  
  79. ; ----------------
  80. ; Video Procedures
  81. ; ----------------
  82.  
  83. MoveXY_DI    proc    near
  84. ;
  85. ; This procedure moves to the offset indicated by an X & Y cusor
  86. ; location.
  87. ;
  88. ; Input
  89. ;    AH = Row
  90. ;    AL = Column
  91. ; Output
  92. ;    DI = Memory Offset
  93. ;
  94.     push    cx        ; Save CX
  95.     xor    cl, cl        ; Clear CL
  96.     mov    ch, ah        ; CX = Row * 256
  97.     dec    ch        ; CX = (Row - 1) {0-24 Based}
  98.     shr    cx, 1        ; CX = Row * 128
  99.     mov    di, cx        ; Store in DI
  100.     shr    di, 1        ; DI = Row * 64
  101.     shr    di, 1        ; DI = Row * 32
  102.     add    di, cx        ; DI = (Row * 128)+(Row * 32) {Row*160}
  103.     xor    ch, ch        ; Clear CH register
  104.     mov    cl, al        ; CX = Columns
  105.     dec    cx        ; Make 0-79
  106.     shl    cx, 1        ; Account for attribute
  107.     add    di, cx        ; DI = (Row * 160) + (Col * 2)
  108.     pop    cx        ; Restore CX register
  109.     ret
  110.  
  111. MoveXY_DI    endp
  112.  
  113. MoveXY_SI    proc    near
  114. ;
  115. ; This procedure moves to the offset indicated by an X & Y cusor
  116. ; location.
  117. ;
  118. ; Input
  119. ;    AH = Row
  120. ;    AL = Column
  121. ; Output
  122. ;    SI = Memory Offset - Points 1 byte beyond null of str displayed
  123. ;
  124.     push    cx        ; Save CX
  125.     xor    cl, cl        ; Clear CL
  126.     mov    ch, ah        ; CX = Row * 256
  127.     dec    ch        ; CX = (Row - 1) {0-24 Based}
  128.     shr    cx, 1        ; CX = Row * 128
  129.     mov    si, cx        ; Store in SI
  130.     shr    si, 1        ; SI = Row * 64
  131.     shr    si, 1        ; SI = Row * 32
  132.     add    si, cx        ; SI = (Row * 128)+(Row * 32) {Row*160}
  133.     xor    ch, ch        ; Clear CH register
  134.     mov    cl, al        ; CX = Columns
  135.     dec    cx        ; Make 0-79
  136.     shl    cx, 1        ; Account for attribute
  137.     add    si, cx        ; DI = (Row * 160) + (Col * 2)
  138.     pop    cx        ; Restore CX register
  139.     ret
  140.  
  141. MoveXY_SI    endp
  142.  
  143. EGAInstalled    proc    near
  144. ;
  145. ; This procedure checks to see if the current adapter card is an
  146. ; EGA.
  147. ;
  148. ; Output
  149. ;    AL = 1 if EGA Adapter is found / 0 if not
  150. ; Modified
  151. ;    AX
  152. ;
  153.     push    bx        ; Store used registers
  154.     push    cx
  155.     mov    ax, 1200h    ; BIOS INT 10 function 12h
  156.     mov    bx, 10h        ; sub-func 10h (Get EGA info)
  157.     mov    cx, 0FFFFh    ; lite all bits of CX
  158.     int    10h        ; call INT 10
  159.     xor    ax, ax        ; Clear AX reg
  160.     cmp    cx, 0FFFFh    ; If CX not modified by INT call
  161.     je    EI_Done        ;   then this is not an EGA
  162.      inc    AL        ; Increment AL to show this is EGA
  163. EI_Done:
  164.     pop    cx        ; Restore regs
  165.     pop    bx
  166.     ret
  167.  
  168. EGAInstalled    endp
  169.  
  170. GetVideoMode    proc    near
  171. ;
  172. ; This procedure checks the video mode and sets the baseOfScreen
  173. ; accordingly.  It also sets snowcheck to 1 if adapter is a CGA.
  174. ;
  175. ; Output
  176. ;    baseOfScreen
  177. ;    videomode
  178. ;    snowcheck
  179. ; Uses
  180. ;    EGAInstalled
  181. ;
  182.     push    ax            ; Store registers
  183.     push    di
  184.     push    DS
  185.     mov    ax,CS
  186.     mov    DS,ax
  187.  
  188.     mov    di, CGASEG        ; move offset of CGA to DI
  189.     mov    ah, 0Fh            ; INT 10 get vid mode func
  190.     int    10h            ; get the video mode
  191.     xor    ah, ah            ; clear the AH reg
  192.     mov    videomode, al        ; place mode into videomode
  193.     cmp    al, 7            ; Is this a mono screen?
  194.     jne    NotMono            ; if not jump to NotMono
  195.      mov    di, MONOSEG        ; move offset of mono to DI
  196.      mov    snowcheck, 0        ; NEVER CHECK RETRACE ON MONO!
  197.      jmp    short GVM_Done
  198.  
  199. NotMono:                ; Process CGA/EGA/VGA adap.
  200.     call    EGAInstalled        ; Check for EGA adap.
  201.     rcr    al, 1            ; Move bit 1 to carry flag
  202.     jc    GVM_Done        ; If EGA then no snow check
  203.      mov    snowcheck, 1        ; Not EGA so set snow check
  204. GVM_Done:
  205.     mov    baseOfScreen, di    ; Move DI to base of screen
  206.     pop    DS            ; Restore regs
  207.     pop    di
  208.     pop    ax
  209.     ret
  210.  
  211. GetVideoMode    endp
  212.  
  213. DWriteCH    proc    near
  214. ;
  215. ; Writes a character to the screen using direct memory access.
  216. ;
  217. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  218. ;
  219. ; Input
  220. ;    AH    Row on screen 1-25
  221. ;    AL    Column on screen 1-80
  222. ;    BH    Video Attribute
  223. ;    BL    Character
  224. ;    CX    Number of times
  225. ; Output
  226. ;    Screen memory (B000:0000 or 8000 CGA/MONO
  227. ;
  228.     push    ax        ; Store the registers
  229.     push    cx
  230.     push    dx
  231.     push    ES
  232.     push    di
  233.  
  234.     call    MoveXY_DI    ; Set DI to row / column offset
  235.     mov    ES,baseOfScreen    ; Move screen seg to ES
  236.     mov    al,snowcheck    ; Move snow check to al
  237.     rcr    al, 1        ; snowcheck
  238.     jnc    DWC_NoWait    ; if no snowcheck goto FW_NoWait
  239. DWC_Next:
  240.     cli            ; Disable interrupts
  241.     WaitRetrace        ; Macro to wait for horiz retrace
  242.     mov    ax, bx        ; Move char/attr into AX
  243.     stosw            ; Move char/attr to screen
  244.     sti            ; Enable interrupts
  245.     loop    DWC_Next    ; Repeat CX times
  246.     jmp    short DWC_Exit    ; Exit this routine
  247.  
  248. DWC_NoWait:
  249.     mov    ax, bx        ; Move char/attr into AX
  250.     rep    stosw        ; Move char/attr to screen CX times
  251.  
  252. DWC_Exit:
  253.     pop    di        ; Restore the registers
  254.     pop    ES
  255.     pop    dx
  256.     pop    cx
  257.     pop    ax
  258.     ret
  259.  
  260. DWriteCH    endp
  261.  
  262. DWriteCHNA    proc    near
  263. ;
  264. ; Writes a character to the screen using direct memory access.
  265. ; This procedure does not disturb current attr setting.
  266. ;
  267. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  268. ;
  269. ; Input
  270. ;    AH    Row on screen 1-25
  271. ;    AL    Column on screen 1-80
  272. ;    BL    Character
  273. ;    CX    Number of times
  274. ; Output
  275. ;    Screen memory (B000:0000 or 8000 CGA/MONO
  276. ;
  277.     push    ax        ; Store the registers
  278.     push    cx
  279.     push    dx
  280.     push    ES
  281.     push    di
  282.  
  283.     call    MoveXY_DI    ; Set DI to row / column offset
  284.     mov    ES,baseOfScreen    ; Move screen seg to ES
  285.     mov    al,snowcheck    ; Move snow check to al
  286.     rcr    al, 1        ; snowcheck
  287.     jnc    DWCN_NoWait    ; if no snowcheck goto FW_NoWait
  288.  
  289. DWCN_Next:
  290.     cli            ; Disable interrupts
  291.     WaitRetrace        ; Macro to wait for horiz retrace
  292.     mov    al, bl        ; Move char into al
  293.     stosb            ; Move char to screen
  294.     sti            ; Enable interrupts
  295.     inc    di        ; Skip over attr
  296.     loop    DWCN_Next    ; Repeat CX times
  297.     jmp    short DWCN_Exit    ; Exit this routine
  298.  
  299. DWCN_NoWait:
  300.     mov    al, bl        ; Move char into AX
  301. DWCN_NoWaitLoop:
  302.     stosb            ; Move char to screen
  303.     inc    di        ; Skip over attr
  304.     loop    DWCN_NoWaitLoop ; Repeat CX times
  305.  
  306. DWCN_Exit:
  307.     pop    di        ; Restore the registers
  308.     pop    ES
  309.     pop    dx
  310.     pop    cx
  311.     pop    ax
  312.     ret
  313.  
  314. DWriteCHNA    endp
  315.  
  316. DWriteStr    proc    near
  317. ;
  318. ; This procedure writes a null delimited string to the screen using
  319. ; direct memory access.
  320. ;
  321. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  322. ;
  323. ; Input
  324. ;    DS:SI    Null terminated string to print
  325. ;    AH    Row on screen 1-25
  326. ;    AL    Column on screen 1-80
  327. ;    BH    Video Attribute
  328. ; Output
  329. ;    Screen memory (B000:0000 or 8000 CGA/MONO
  330. ; Modifies
  331. ;    SI - Points 1 byte beyond null of str displayed
  332. ;
  333.     push    ax        ; Store the registers
  334.     push    bx
  335.     push    cx
  336.     push    dx
  337.     push    ES
  338.     push    di
  339.  
  340.     call    MoveXY_DI    ; Set DI to row / column offset
  341.     mov    ES,baseOfScreen    ; Move screen seg to ES
  342.     mov    cl,snowcheck    ; Move snow check to al
  343.     cld            ; Clear the direction flag
  344.     rcr    cl, 1        ; snowcheck
  345.     mov    ah, bh        ; Place video attr in AH
  346.     jnc    DWS_NoWait    ; if no snowcheck goto DWS_NoWait
  347.  
  348. DWS_Next:
  349.     lodsb            ; Get a character from source
  350.     or    al, al        ; Check for NULL
  351.     jz    DWS_Exit    ; If NULL then exit
  352.     mov    bx, ax        ; Store video word into BX
  353.     cli            ; Disable interrupts
  354.     WaitRetrace        ; Macro to wait for horiz retrace
  355.     mov    ax, bx        ; Move word back to AX...
  356.     stosw            ; Move word to screen
  357.     sti            ; Enable interrupts
  358.     jmp    DWS_Next    ; Continue
  359.  
  360. DWS_NoWait:
  361.     lodsb            ; Get a character from string
  362.     or    al, al        ; Check for NULL
  363.     jz    DWS_Exit    ; If NULL then exit
  364.      stosw            ; Move word to screen
  365.      loop    DWS_NoWait    ; Continue
  366. DWS_Exit:
  367.     pop    di        ; Restore the registers
  368.     pop    ES
  369.     pop    dx
  370.     pop    cx
  371.     pop    bx
  372.     pop    ax
  373.     ret
  374.  
  375. DWriteStr    endp
  376.  
  377. DWriteStrNA    proc    near
  378. ;
  379. ; This procedure writes a null delimited string to the screen using
  380. ; direct memory access, attribute is not changed.
  381. ;
  382. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  383. ;
  384. ; Input
  385. ;    DS:SI    Null terminated string to print
  386. ;    AH    Row on screen 1-25
  387. ;    AL    Column on screen 1-80
  388. ; Output
  389. ;    Screen memory (B000:0000 or 8000 CGA/MONO)
  390. ; Modifies
  391. ;    SI - Points 1 byte beyond null of str displayed
  392. ;
  393.     push    ax        ; Store the registers
  394.     push    bx
  395.     push    cx
  396.     push    dx
  397.     push    ES
  398.     push    di
  399.  
  400.     call    MoveXY_DI    ; Set DI to screen offset pos
  401.     mov    ES,baseOfScreen    ; Move screen seg to ES
  402.     mov    cl,snowcheck    ; Move snow check to cl
  403.     cld            ; Clear the direction flag
  404.     rcr    cl, 1        ; snowcheck
  405.     jnc    DWSN_NoWait    ; if no snowcheck goto DWSN_NoWait
  406.  
  407. DWSN_Next:
  408.     lodsb            ; Get a character from source
  409.     or    al, al        ; Check for NULL
  410.     jz    DWSN_Exit    ; If NULL then exit
  411.     mov    bx, ax        ; Store video word into BX
  412.     cli            ; Turn off interrupts
  413.     WaitRetrace        ; Macro - Waits for horiz retrace
  414.     mov    ax, bx        ; Move word back to AX...
  415.     stosb            ; Move word to screen
  416.     sti            ; Enable interrupts
  417.     inc    di        ; Skip the attribute.
  418.     jmp    DWSN_Next    ; Continue
  419.  
  420. DWSN_NoWait:
  421.     lodsb            ; Get a character from string
  422.     or    al, al        ; Check for NULL
  423.     jz    DWSN_Exit    ; If NULL then exit
  424.      stosb            ; Store the byte on screen
  425.      inc    di        ; Skip attribute byte
  426.      loop    DWSN_NoWait    ; Continue
  427. DWSN_Exit:
  428.     pop    di        ; Restore the registers
  429.     pop    ES
  430.     pop    dx
  431.     pop    cx
  432.     pop    bx
  433.     pop    ax
  434.     ret
  435.  
  436. DWriteStrNA    endp
  437.  
  438. DFillCH    proc    near
  439. ;
  440. ; This procedure fills an area of the screen with the specified
  441. ; character and attribute.
  442. ;
  443. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  444. ;
  445. ; Input
  446. ;    AH    = Top Row
  447. ;    AL    = Left Column
  448. ;    BH    = Number of rows
  449. ;    BL    = Number of columns
  450. ;    DH    = Attribute
  451. ;    DL    = Character
  452. ;
  453.     push    ax            ; Store Registers
  454.     push    bx
  455.     push    cx
  456.     push    dx
  457.     push    ES
  458.     push    di
  459.  
  460.     mov    ES,baseOfScreen    ; Move screen seg to ES
  461.     mov    cl,snowcheck    ; Move snow check to CL
  462.  
  463.     cld            ; Clear the direction flag
  464.     rcr    cl, 1        ; snowcheck
  465.     mov    ch, 0        ; Clear CH
  466.     jnc    DFC_NoWait    ; if no snowcheck goto DFC_NoWait
  467.  
  468. DFC_Top:
  469.     mov    cl, bl        ; Load the number of columns
  470.     call    MoveXY_DI    ; Set DI to screen offset pos
  471.     push    ax        ; Store Registers AX, BX
  472.     push    bx
  473.     mov    bx,dx        ;video word into BX            v1.1
  474.  
  475. DFC_Next:
  476.     cli            ; Turn off interrupts
  477. ;    push    dx        ; Store video word
  478.     mov    bx,ax        ;store video word            v1.1
  479.     WaitRetrace        ; Macro - Waits for horiz retrace
  480. ;    pop    dx        ; Restore video word
  481. ;    mov    ax, dx        ; Move word into AX
  482.     mov    ax,bx        ;restore video word            v1.1
  483.     stosw            ; Move word to screen
  484.     sti            ; Enable interrupts
  485.     loop    DFC_Next    ; Continue
  486.  
  487.     pop    bx        ; Restore registers BX, AX
  488.     pop    ax
  489.     inc    ah        ; Next row
  490.     dec    bh        ; Decrement the number of rows done
  491. ;v1.1 the dec will set ZF appropriately if 0'ed
  492. ;    or    bh, bh        ; Check Number of columns
  493.     jnz    DFC_Top        ; Do next column if not done
  494.     jmp    short DFC_Exit    ; Exit routine
  495.  
  496. DFC_NoWait:
  497.     mov    cl, bl        ; Load the number of columns
  498.     call    MoveXY_DI    ; Set DI to screen offset pos
  499.     push    ax        ; Store the char/attr
  500.     mov    ax, dx        ; Move char/attr into ax
  501.     rep    stosw        ; Thats it!
  502.     pop    ax        ; Restore the char/attr
  503.     inc    ah        ; Next row
  504.     dec    bh        ; Decrement number of rows done
  505.     or    bh, bh        ; Check number of columns
  506.     jnz    DFC_NoWait    ; Do next column
  507.  
  508. DFC_Exit:
  509.     pop    di        ; Restore registers
  510.     pop    ES
  511.     pop    dx
  512.     pop    cx
  513.     pop    bx
  514.     pop    ax
  515.     ret
  516.  
  517. DFillCH    endp
  518.  
  519. DFillCHNA    proc    near
  520. ;
  521. ; This procedure fills an area of the screen with the specified
  522. ; character. Attribute remains the same.
  523. ;
  524. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  525. ;
  526. ; Input
  527. ;    AH    = Top Row
  528. ;    AL    = Left Column
  529. ;    BH    = Number of rows
  530. ;    BL    = Number of columns
  531. ;    DL    = Character
  532. ;
  533.     push    ax            ; Store Registers
  534.     push    bx
  535.     push    cx
  536.     push    dx
  537.     push    ES
  538.     push    di
  539.  
  540.     mov    ES,baseOfScreen    ; Move screen seg to ES
  541.     mov    cl,snowcheck    ; Move snow check to CL
  542.  
  543.     cld            ; Clear the direction flag
  544.     rcr    cl, 1        ; snowcheck
  545.     mov    ch, 0        ; Clear CH
  546.     jnc    DFCN_NoWait    ; if no snowcheck goto DFCN_NoWait
  547.  
  548. DFCN_Top:
  549.     mov    cl, bl        ; Load the number of columns
  550.     call    MoveXY_DI    ; Set DI to screen offset pos
  551.     push    ax        ; Store Registers AX, BX
  552.     push    bx
  553.     mov    bx,dx        ;char into BX                v1.1
  554.  
  555. DFCN_Next:
  556.     cli            ; Turn off interrupts
  557. ;    push    dx        ; Save video word
  558.     WaitRetrace        ; Macro - Waits for horiz retrace
  559. ;    pop    dx        ; Restore video word
  560. ;    mov    al, dl        ; Move character into al
  561.     mov    al,bl        ;move char into AL            v1.1
  562.     stosb            ; Move word to screen
  563.     sti            ; Enable interrupts
  564.     inc    di        ; Skip attr
  565.     loop    DFCN_Next    ; Continue
  566.  
  567.     pop    bx        ; Restore registers BX, AX
  568.     pop    ax
  569.     inc    ah        ; Next row
  570.     dec    bh        ; Decrement the number of rows done
  571.     or    bh, bh        ; Check Number of columns
  572.     jnz    DFCN_Top    ; Do next column if not done
  573.     jmp    short DFCN_Exit    ; Exit routine
  574.  
  575. DFCN_NoWait:
  576.     mov    cl, bl        ; Load the number of columns
  577.     call    MoveXY_DI    ; Set DI to screen offset pos
  578.     push    ax        ; Store the row/col info
  579.     mov    al, dl        ; Move char into ax
  580. DFCN_NoWaitLoop:
  581.     stosb            ; Thats it!
  582.     inc    di        ; Skip over attr
  583.     loop    DFCN_NoWaitLoop ; Loop for all columns
  584.     pop    ax        ; Restore the row/col info
  585.     inc    ah        ; Next row
  586.     dec    bh        ; Decrement number of rows done
  587.     or    bh, bh        ; Check number of columns
  588.     jnz    DFCN_NoWait    ; Do next column
  589.  
  590. DFCN_Exit:
  591.     pop    di        ; Restore registers
  592.     pop    ES
  593.     pop    dx
  594.     pop    cx
  595.     pop    bx
  596.     pop    ax
  597.     ret
  598.  
  599. DFillCHNA    endp
  600.  
  601. DFillAttr    proc    near
  602. ;
  603. ; This procedure fills an area of the screen with the specified
  604. ; attribute. Character remains the same.
  605. ;
  606. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  607. ;
  608. ; Input
  609. ;    AH    = Top Row
  610. ;    AL    = Left Column
  611. ;    BH    = Number of rows
  612. ;    BL    = Number of columns
  613. ;    DH    = Attribute
  614. ;
  615.     push    ax            ; Store Registers
  616.     push    bx
  617.     push    cx
  618.     push    dx
  619.     push    ES
  620.     push    di
  621.  
  622.     mov    ES,baseOfScreen    ; Move screen seg to ES
  623.     mov    cl,snowcheck    ; Move snow check to CL
  624.  
  625.     cld            ; Clear the direction flag
  626.     rcr    cl, 1        ; snowcheck
  627.     mov    ch, 0        ; Clear CH
  628.     jnc    DFA_NoWait    ; if no snowcheck goto DFA_NoWait
  629.  
  630. DFA_Top:
  631.     mov    cl, bl        ; Load the number of columns
  632.     call    MoveXY_DI    ; Set DI to screen offset pos
  633.     push    ax        ; Store Registers AX, BX
  634.     push    bx
  635.     mov    bx,dx        ;save attrib in BH            v1.1
  636.  
  637. DFA_Next:
  638.     cli            ; Turn off interrupts
  639. ;    push    dx        ; Save attribute in DH
  640.     WaitRetrace        ; Macro - Waits for horiz retrace
  641. ;    pop    dx        ; Restore attr
  642.     inc    di        ; Skip character
  643. ;    mov    al, dh        ; Move attr into al
  644.     mov    al,bh        ;move attr into AL            v1.1
  645.     stosb            ; Move attr to screen
  646.     sti            ; Enable interrupts
  647.     loop    DFA_Next    ; Continue
  648.  
  649.     pop    bx        ; Restore registers BX, AX
  650.     pop    ax
  651.     inc    ah        ; Next row
  652.     dec    bh        ; Decrement the number of rows done
  653.     or    bh, bh        ; Check Number of columns
  654.     jnz    DFA_Top        ; Do next column if not done
  655.     jmp    short DFA_Exit    ; Exit routine
  656.  
  657. DFA_NoWait:
  658.     mov    cl, bl        ; Load the number of columns
  659.     call    MoveXY_DI    ; Set DI to screen offset pos
  660.     push    ax        ; Store the row/col info
  661.     mov    al, dh        ; Move attr into ax
  662. DFA_NoWaitLoop:
  663.     inc    di        ; Skip over character
  664.     stosb            ; Thats it!
  665.     loop    DFA_NoWaitLoop  ; Loop for all columns
  666.     pop    ax        ; Restore the row/col info
  667.     inc    ah        ; Next row
  668.     dec    bh        ; Decrement number of rows done
  669.     or    bh, bh        ; Check number of columns
  670.     jnz    DFA_NoWait    ; Do next column
  671.  
  672. DFA_Exit:
  673.     pop    di        ; Restore registers
  674.     pop    ES
  675.     pop    dx
  676.     pop    cx
  677.     pop    bx
  678.     pop    ax
  679.     ret
  680.  
  681. DFillAttr    endp
  682.  
  683. StoreToMem    proc    near
  684. ;
  685. ; This procedure moves an image from the screen to the designated
  686. ; memory area.
  687. ;
  688. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  689. ;
  690. ; Input
  691. ;    AH    = Top Row
  692. ;    AL    = Left Column
  693. ;    BH    = Number of rows
  694. ;    BL    = Number of columns
  695. ;    ES:DI    = Memory Destination
  696. ; Modifies
  697. ;    DI
  698. ;
  699.     push    ax
  700.     push    bx
  701.     push    cx
  702.     push    dx
  703.     push    DS        ; Store registers
  704.     push    si
  705.  
  706.     mov DS,baseOfScreen    ; Move screen seg to DS mov cl,
  707.     mov cl,snowcheck    ; Move snow check to CL
  708.  
  709.     cld            ; Clear the direction flag
  710.     rcr    cl, 1        ; snowcheck
  711.     mov    ch, 0        ; Clear CH
  712.     jnc    STM_NoWait    ; if no snowcheck goto STM_NoWait
  713.  
  714. STM_Top:
  715.     mov    cl, bl        ; Load the number of columns
  716.     call    MoveXY_SI    ; Set SI to screen offset pos
  717.     push    ax        ; Store row/column info
  718.     push    bx        ; Store number of row/columns info
  719.  
  720. STM_Next:
  721.     lodsw            ; Get a char/word from screen
  722.     mov    bx, ax        ; Store video word into BX
  723.     cli            ; Turn off interrupts
  724.     WaitRetrace        ; Macro - Waits for horiz retrace
  725.     mov    ax, bx        ; Move word back to AX...
  726.     stosw            ; Move word to memory
  727.     sti            ; Enable interrupts
  728.     loop    STM_Next    ; Continue
  729.     pop    bx        ; Restore number of row/columns info
  730.     pop    ax        ; Restore row/column info
  731.     inc    ah        ; Next row
  732.     dec    bh        ; Decrement the number of rows done
  733.     or    bh, bh        ; Check Number of columns
  734.     jnz    STM_Top        ; Do next column if not done
  735.     jmp    short STM_Exit    ; Exit routine
  736.  
  737. STM_NoWait:
  738.     mov    cl, bl        ; Load the number of columns
  739.     call    MoveXY_SI    ; Set SI to screen offset pos
  740.     rep    movsw        ; Thats it!
  741.     inc    ah        ; Next row
  742.     dec    bh        ; Decrement number of rows done
  743.     or    bh, bh        ; Check number of columns
  744.     jnz    STM_NoWait    ; Do next column
  745.  
  746. STM_Exit:
  747.     pop    si
  748.     pop    DS
  749.     pop    dx
  750.     pop    cx
  751.     pop    bx
  752.     pop    ax
  753.     ret
  754.  
  755. StoreToMem    endp
  756.  
  757. StoreToScr    proc    near
  758. ;
  759. ; This procedure moves an image from memory to the designated
  760. ; screen location.
  761. ;
  762. ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  763. ;
  764. ; Input
  765. ;    AH    = Top Row
  766. ;    AL    = Left Column
  767. ;    BH    = Number of rows
  768. ;    BL    = Number of columns
  769. ;    DS:SI    = Memory Area of image
  770. ; Modifies
  771. ;    SI
  772. ;
  773.     push    ax            ; Store Registers
  774.     push    bx
  775.     push    cx
  776.     push    dx
  777.     push    ES
  778.     push    di
  779.  
  780.     mov    ES,baseOfScreen    ; Move screen seg to ES
  781.     mov    cl,snowcheck    ; Move snow check to CL
  782.  
  783.     cld            ; Clear the direction flag
  784.     rcr    cl, 1        ; snowcheck
  785.     mov    ch, 0        ; Clear CH
  786.     jnc    STS_NoWait    ; if no snowcheck goto STS_NoWait
  787.  
  788. STS_Top:
  789.     mov    cl, bl        ; Load the number of columns
  790.     call    MoveXY_DI    ; Set DI to screen offset pos
  791.     push    ax        ; Store Registers AX, BX
  792.     push    bx
  793.  
  794. STS_Next:
  795.     lodsw            ; Get a char/word from memory
  796.     mov    bx, ax        ; Store video word into BX
  797.     cli            ; Turn off interrupts
  798.     WaitRetrace        ; Macro - Waits for horiz retrace
  799.     mov    ax, bx        ; Move word back to AX...
  800.     stosw            ; Move word to screen
  801.     sti            ; Enable interrupts
  802.     loop    STS_Next    ; Continue
  803.  
  804.     pop    bx        ; Restore registers BX, AX
  805.     pop    ax
  806.     inc    ah        ; Next row
  807.     dec    bh        ; Decrement the number of rows done
  808.     or    bh, bh        ; Check Number of columns
  809.     jnz    STS_Top        ; Do next column if not done
  810.     jmp    short STS_Exit    ; Exit routine
  811.  
  812. STS_NoWait:
  813.     mov    cl, bl        ; Load the number of columns
  814.     call    MoveXY_DI    ; Set DI to screen offset pos
  815.     rep    movsw        ; Thats it!
  816.     inc    ah        ; Next row
  817.     dec    bh        ; Decrement number of rows done
  818.     or    bh, bh        ; Check number of columns
  819.     jnz    STS_NoWait    ; Do next column
  820.  
  821. STS_Exit:
  822.     pop    di        ; Restore registers
  823.     pop    ES
  824.     pop    dx
  825.     pop    cx
  826.     pop    bx
  827.     pop    ax
  828.     ret
  829.  
  830. StoreToScr    endp
  831.  
  832. CursorOff    proc    near
  833. ;
  834. ; This procedure simply turns the Cursor off
  835. ;
  836.  
  837.     push    ax
  838.     push    bx
  839.     push    cx
  840.     push    dx
  841.     mov    ah, 03h        ; BIOS INT 10 func 3 (Get Cursor pos)
  842.     int    10h        ; Call INT 10
  843.     or    ch, 0100000b    ; Turn on cursor bit
  844.     mov    ah, 01h        ; BIOS INT 10 func 1 (Set cursor type)
  845.     int    10h        ; Call INT 10
  846.     pop    dx
  847.     pop    cx
  848.     pop    bx
  849.     pop    ax
  850.     ret
  851.  
  852. CursorOff    endp
  853.  
  854. CursorOn    proc    near
  855. ;
  856. ; This procedure simply turns the Cursor on
  857. ;
  858.     push    ax
  859.     push    bx
  860.     push    cx
  861.     push    dx
  862.     mov    ah, 03h        ; BIOS INT 10 func 3 (Get Cursor pos)
  863.     int    10h        ; Call INT 10
  864.     and    ch, 1011111b    ; Turn off cursor bit
  865.     mov    ah, 01h        ; BIOS INT 10 func 1 (Set cursor type)
  866.     int    10h        ; Call INT 10
  867.     pop    dx
  868.     pop    cx
  869.     pop    bx
  870.     pop    ax
  871.     ret
  872.  
  873. CursorOn    endp
  874.  
  875. CSeg    ENDS
  876.     END
  877.