home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / C-ASM_VI.ARJ / PROGASM.ZIP / PROG088.ASM < prev    next >
Assembly Source File  |  1988-05-25  |  12KB  |  327 lines

  1.  
  2. ;************************************************************************
  3. ; Set Cursor:                                                           *
  4. ; This procedure will expand the two cursor masks into                  *
  5. ; four planes.  The expanded masks will be stored                       *
  6. ; after the last visible scan line at A000:(640/8*350).                 *
  7. ; Entry:        AND_Mask - 2x16 bytes with AND mask                     *
  8. ;               XOR_Mask - 2x16 bytes with XOR mask                     *
  9. ;               BG_Color - Foreground color                             *
  10. ;               FG_Color - Background color                             *
  11. ;************************************************************************
  12.  
  13.  
  14. YSIZE           EQU     350
  15. HBYTES          EQU     80
  16. CUR_HEIGHT      EQU     16
  17. GRFSEG          EQU     0A000H
  18.  
  19. AND_SAVE        EQU     (YSIZE*HBYTES+0)
  20. XOR_SAVE        EQU     (YSIZE*HBYTES+2)
  21. CUR_SAVE        EQU     (YSIZE*HBYTES+4)
  22.  
  23. AND_Mask        EQU     [BP+4]
  24. XOR_Mask        EQU     [BP+6]
  25. BG_Color        EQU     [BP+8]
  26. FG_Color        EQU     [BP+10]
  27.  
  28. Last_Cursor     DW      0
  29.  
  30.         PUBLIC  _Set_Cursor
  31.  
  32. _Set_Cursor     PROC NEAR
  33.         PUSH    BP
  34.         MOV     BP,SP
  35.         PUSH    SI
  36.         PUSH    DI
  37.         PUSH    ES                      ; always save seg regs
  38.         PUSH    DS
  39.  
  40.         MOV     AX,GRFSEG               ;Point ES to video ram.
  41.         MOV     ES,AX
  42.  
  43.         ;Set EGA to use SET/RESET register to fill with background color
  44.  
  45.         MOV     DX,3CEH                 ; enable use of reset register
  46.         MOV     AL,1
  47.         OUT     DX,AL
  48.         INC     DX
  49.         MOV     AL,0Fh
  50.         OUT     DX,AL
  51.         DEC     DX                      ; move color into reset register
  52.         XOR     AL,AL
  53.         OUT     DX,AL
  54.         INC     DX
  55.         MOV     AX,BG_Color
  56.         OUT     DX,AL
  57.  
  58.         ; Fill with background
  59.  
  60.         MOV     DI,AND_SAVE             ;Pointer to save area (AND and XOR)
  61.         MOV     CX,CUR_HEIGHT           ;Number of scanlines to do
  62. Back_Loop1:
  63.         STOSW                           ;16 bits for AND mask
  64.         STOSW                           ;16 bits for XOR mask
  65.         ADD     DI,HBYTES-4             ;Point to next scanline
  66.         LOOP    Back_Loop1
  67.  
  68.         ; Change foreground bits for the AND mask save area
  69.  
  70.         MOV     AX,FG_Color             ;Load SET/RESET with foreground color
  71.         OUT     DX,AL
  72.         DEC     DX                      ;Select BIT MASK register
  73.         MOV     AL,8
  74.         OUT     DX,AL
  75.         INC     DX
  76.         MOV     CX,CUR_HEIGHT           ;Initialize counter
  77.         MOV     DI,AND_Save             ;Get pointer to AND save area
  78.         MOV     SI,AND_Mask             ;Get pointer to AND mask
  79.  
  80. Fore_Loop1:
  81.         LODSB                           ;Fetch next byte from the mask
  82.         OUT     DX,AL                   ;Set BIT MASK REGISTER using cursor mas
  83.         MOV     AH,ES:[DI]              ;Latch data
  84.         STOSB                           ;Write next 8 bits
  85.         LODSB                           ;Fetch next byte from the mask
  86.         OUT     DX,AL                   ;Set BIT MASK REGISTER using cursor mas
  87.         MOV     AH,ES:[DI]              ;Latch data
  88.         STOSB                           ;Write next 8 bits
  89.         ADD     DI,HBYTES-2
  90.         LOOP    Fore_Loop1
  91.  
  92.         ; Change foreground bits for the XOR mask save area
  93.  
  94.         MOV     CX,CUR_HEIGHT           ;Initialize counter
  95.         MOV     DI,XOR_Save             ;Get pointer to XOR save area
  96.         MOV     SI,XOR_Mask             ;Get pointer to XOR mask
  97.  
  98. Fore_Loop2:
  99.         LODSB                           ;Fetch next byte from the mask
  100.         OUT     DX,AL                   ;Set BIT MASK REGISTER using cursor mas
  101.         MOV     AH,ES:[DI]              ;Latch data
  102.         STOSB                           ;Write next 8 bits
  103.         LODSB                           ;Fetch next byte from the mask
  104.         OUT     DX,AL                   ;Set BIT MASK REGISTER using cursor mas
  105.         MOV     AH,ES:[DI]              ;Latch data
  106.         STOSB                           ;Write next 8 bits
  107.         ADD     DI,HBYTES-2
  108.         LOOP    Fore_Loop2
  109.  
  110.         ;Setup EGA registers for data copy (WRITE LATCH write mode)
  111.  
  112.         MOV     DX,3CEH                 ;Restore graphics controller
  113.         MOV     AL,1                    ;Disable use of SET/RESET
  114.         OUT     DX,AL
  115.         INC     DX
  116.         XOR     AL,AL
  117.         OUT     DX,AL
  118.         DEC     DX
  119.         MOV     AL,8                    ;Enable all 8 bits for write
  120.         OUT     DX,AL
  121.         INC     DX
  122.         MOV     AL,0FFH
  123.         OUT     DX,AL
  124.         DEC     DX
  125.         MOV     AL,5                    ;Select WRITE LATCH write mode
  126.         OUT     DX,AL
  127.         INC     DX
  128.         MOV     AL,1
  129.         OUT     DX,AL
  130.  
  131.         ;Copy upper left corner into save area (this is needed for first
  132.         ;call to Move_Cursor procedure, because it always restores and
  133.         ;we need meaningfull data for the first restore).
  134.  
  135.         MOV     SI,0                    ;Copy from upper left
  136.         MOV     CS:Last_Cursor,SI       ;Keep where it came from
  137.         MOV     DI,CUR_SAVE             ;Copy to cursor save area
  138.         MOV     AX,ES                   ;Point DS to display buffer
  139.         MOV     DS,AX
  140.         MOV     CX,CUR_HEIGHT           ;Number of lines to copy
  141. Set_Copy_Loop:
  142.         MOVSB                           ;Copy 24 bits from next raster
  143.         MOVSB
  144.         MOVSB
  145.         ADD     DI,HBYTES-3             ;Update pointers to next raster
  146.         ADD     SI,HBYTES-3
  147.         LOOP    Set_Copy_Loop
  148.  
  149.         ;Restore normal write mode
  150.  
  151.         XOR     AL,AL                   ;WRITE MODE register is still selected
  152.         OUT     DX,AL                   ;so load it with value 0
  153.  
  154.         ;Clean up and return
  155.  
  156.         POP     DS                      ;Restore segment registers
  157.         POP     ES
  158.         POP     DI
  159.         POP     SI
  160.         MOV     SP,BP
  161.         POP     BP
  162.         RET
  163. _Set_Cursor     ENDP
  164.  
  165. ;************************************************************************
  166. ; Move_Cursor:                                                          *
  167. ; This procedure is used to move the cursor from one                    *
  168. ; location to another.                                                  *
  169. ; Entry:        Curs_X - Position of the new cursor                     *
  170. ;               Curs_Y                                                  *
  171. ;************************************************************************
  172.  
  173. FUNC_AND        EQU     1
  174. FUNC_XOR        EQU     3
  175.  
  176. Curs_X          EQU     [BP+4]
  177. Curs_Y          EQU     [BP+6]
  178.  
  179.         PUBLIC  _Move_Cursor
  180.  
  181. _Move_Cursor    PROC    NEAR
  182.         PUSH    BP
  183.         MOV     BP,SP
  184.         PUSH    SI
  185.         PUSH    DI
  186.         PUSH    ES                      ; always save seg regs
  187.         PUSH    DS
  188.  
  189.         CALL    _Remove_Cursor          ;Restore last location
  190.  
  191.         ;Setup EGA registers for data copy (WRITE LATCH write mode)
  192.  
  193.         MOV     DX,3CEH                 ;Address of GRAPICS controller
  194.         MOV     AL,5                    ;Select WRITE LATCH write mode
  195.         OUT     DX,AL
  196.         INC     DX
  197.         MOV     AL,1
  198.         OUT     DX,AL
  199.  
  200.         ;Copy next location of the cursor to the save area
  201.  
  202.         MOV     AX,Curs_Y               ;Convert cursor X,Y to offset
  203.         MOV     BX,HBYTES
  204.         MUL     BX
  205.         MOV     SI,Curs_X
  206.         SHR     SI,1
  207.         SHR     SI,1
  208.         SHR     SI,1
  209.         ADD     SI,AX
  210.         MOV     CS:Last_Cursor,SI       ;Keep location so we can restore later
  211.         MOV     AX,GRFSEG               ;Point ES and DS to display buffer
  212.         MOV     DS,AX
  213.         MOV     ES,AX
  214.         MOV     DI,CUR_SAVE             ;Pointer to save area
  215.         MOV     CX,CUR_HEIGHT           ;Number of lines to copy
  216. Move_Copy_Loop:
  217.         MOVSB                           ;Copy 16 bits from next raster
  218.         MOVSB
  219.         MOVSB
  220.         ADD     DI,HBYTES-3             ;Update pointers to next raster
  221.         ADD     SI,HBYTES-3
  222.         LOOP    Move_Copy_Loop
  223.  
  224.         ;Restore normal write mode
  225.  
  226.         MOV     DX,3CFH
  227.         MOV     AL,0                    ;WRITE MODE register is still selected
  228.         OUT     DX,AL                   ;so load it with value 0
  229.  
  230.         ;Use BITBLT procedure to copy AND and XOR masks of the cursor
  231.  
  232.         MOV     AX,FUNC_AND             ;Push function on the stack
  233.         PUSH    AX
  234.         MOV     AX,CUR_HEIGHT           ;Push width and height
  235.         PUSH    AX
  236.         PUSH    AX
  237.         PUSH    WORD PTR Curs_Y         ;Push x and y of destination
  238.         PUSH    WORD PTR Curs_X
  239.         MOV     AX,YSIZE                ;Push x and y of source
  240.         PUSH    AX
  241.         MOV     AX,0
  242.         PUSH    AX
  243.         CALL    _BitBlt
  244.         ADD     SP,14
  245.  
  246.         MOV     AX,FUNC_XOR             ;Push function on the stack
  247.         PUSH    AX
  248.         MOV     AX,CUR_HEIGHT           ;Push width and height
  249.         PUSH    AX
  250.         PUSH    AX
  251.         PUSH    WORD PTR Curs_Y         ;Push x and y of destination
  252.         PUSH    WORD PTR Curs_X
  253.         MOV     AX,YSIZE                ;Push x and y of source
  254.         PUSH    AX
  255.         MOV     AX,16
  256.         PUSH    AX
  257.         CALL    _BitBlt
  258.         ADD     SP,14
  259.  
  260.         ;Clean up and return
  261.  
  262.         POP     DS                      ;Restore segment registers
  263.         POP     ES
  264.         POP     DI
  265.         POP     SI
  266.         MOV     SP,BP
  267.         POP     BP
  268.         RET
  269. _Move_Cursor    ENDP
  270.  
  271. ;************************************************************************
  272. ; Remove_Cursor:                                                        *
  273. ; This procedure is used to remove the cursor from the screen           *
  274. ; and to restore the screen to its original appearance                  *
  275. ;************************************************************************
  276.  
  277.         PUBLIC  _Remove_Cursor
  278.  
  279. _Remove_Cursor  PROC NEAR
  280.         PUSH    BP
  281.         MOV     BP,SP
  282.         PUSH    SI
  283.         PUSH    DI
  284.         PUSH    ES                      ; always save seg regs
  285.         PUSH    DS
  286.  
  287.         ;Setup EGA registers for data copy (WRITE LATCH write mode)
  288.  
  289.         MOV     DX,3CEH                 ;Address of GRAPICS controller
  290.         MOV     AL,5                    ;Select WRITE LATCH write mode
  291.         OUT     DX,AL
  292.         INC     DX
  293.         MOV     AL,1
  294.         OUT     DX,AL
  295.  
  296.         ;Copy save area back to last location of the cursor
  297.  
  298.         MOV     AX,0A000H               ;Set up segment pointers
  299.         MOV     ES,AX
  300.         MOV     DS,AX
  301.         MOV     DI,CS:Last_Cursor       ;Copy to last X,Y of cursor
  302.         MOV     SI,CUR_SAVE             ;Copy form cursor save area
  303.         MOV     CX,CUR_HEIGHT           ;Number of lines to copy
  304. Rest_Copy_Loop:
  305.         MOVSB                           ;Copy 16 bits from next raster
  306.         MOVSB
  307.         MOVSB
  308.         ADD     DI,HBYTES-3             ;Update pointers to next raster
  309.         ADD     SI,HBYTES-3
  310.         LOOP    Rest_Copy_Loop
  311.  
  312.         ;Restore normal write mode
  313.  
  314.         MOV     AL,0                    ;WRITE MODE register is still selected
  315.         OUT     DX,AL                   ;so load it with value 0
  316.  
  317.         ;Clean up and return
  318.  
  319.         POP     DS                      ;Restore segment registers
  320.         POP     ES
  321.         POP     DI
  322.         POP     SI
  323.         MOV     SP,BP
  324.         POP     BP
  325.         RET
  326. _Remove_Cursor  ENDP
  327.