home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / ASSEMBLE / 80X0992 / DRAWIMAG.ASM < prev    next >
Assembly Source File  |  1992-07-30  |  14KB  |  377 lines

  1. ;
  2. ;  DRAWIMAG.ASM
  3. ;
  4. ;  Author: Matt Pritchard
  5. ;  released to the public domain
  6. ;
  7.         
  8.         VGA_SEGMENT     EQU     0A000H          ;Vga Memory Segment
  9.         SCREEN_XWIDTH   EQU     360             ;Screen width in Pixels
  10.         SCREEN_WIDTH    EQU     90              ;Screen width in bytes
  11.  
  12.         GC_INDEX        EQU     03CEH           ;VGA Graphics Controller
  13.         SC_INDEX        EQU     03C4H           ;VGA Sequence controller
  14.         CRTC_INDEX      EQU     03D4H           ;VGA CRT Controller
  15.         MISC_OUTPUT     EQU     03C2H           ;VGA Misc Register
  16.         MAP_MASK        EQU     02              ;Map Register #
  17.         READ_MAP        EQU     04              ;Read Map Register #
  18.  
  19. ;DRAWIMAGE (IconImageSeg%, IconImageOfs%, Xpos%, Ypos%, Width%, Hieght%) 
  20. ; % = 16 bit integer value passed BY VALUE on stack. 
  21. ;Draws a variable sized Image, only the non zero pixels. 
  22. ;The width of the image must be a multiple of 4. 
  23. ;Preserves:  DS, SI, DI, BP 
  24. ;Sets:       Dir flag - Clear 
  25. ;Destroys:   AX, BX, CX, DX, ES, Flags
  26.  
  27. DI_STACK        STRUC
  28.         DI_Jump         DW      ?       ;Jump Table offset
  29.         DI_Repeat       DB      ?,?     ;# of 16 byte repeat copies
  30.         DI_NextL        DW      ?       ;Offset to next line start
  31.         DI_Addr         DW      ?       ;Saved Image Address
  32.                         DW      ?       ;Saved DI
  33.                         DW      ?       ;Saved SI
  34.                         DW      ?       ;Saved DS
  35.                         DW      ?       ;Saved BP
  36.                         DD      ?       ;Save Caller Addr
  37.         DI_YSIZE        DW      ?       ;Height of Image
  38.         DI_XSIZE        DW      ?       ;Width of Image (mult of 4)
  39.         DI_YPOS         DW      ?       ;Y pos of Image (Upper left)
  40.         DI_XPOS         DW      ?       ;X pos of Image (Upper left)
  41.         DI_IOFF         DW      ?       ;Offset of image data
  42.         DI_ISEG         DW      ?       ;Segment of image data DI_STACK
  43. ENDS
  44.  
  45.         PUBLIC    DRAWIMAGE
  46.  
  47.         .CODE
  48.  
  49.         ;Table for Inline (Unrolled loop) entry
  50.  
  51. JumpTable       DW      @Copy0,  @Copy1,  @Copy2,  @Copy3
  52.                 DW      @Copy4,  @Copy5,  @Copy6,  @Copy7
  53.                 DW      @Copy8,  @Copy9,  @Copy10, @Copy11
  54.                 DW      @Copy12, @Copy13, @Copy14, @Copy15
  55.  
  56. DRAWIMAGE   PROC    FAR
  57.  
  58.         PUSH    BP                      ;Save Bp
  59.         PUSH    DS                      ;Save Data Seg
  60.         PUSH    SI                      ;
  61.         PUSH    DI                      ;
  62.  
  63.         SUB     SP, 8                   ;Alloc Temp Stack Variables
  64.  
  65.         MOV     BP, SP                  ;Set to address of bp
  66.  
  67.         MOV     AX, VGA_SEGMENT         ;VGA Graphics Segment
  68.         MOV     ES, AX                  ;ES for Vga pixel access
  69.  
  70.         ;Setup all our stack variables
  71.  
  72.         MOV     BX, [BP].DI_XSIZE       ;Get image width
  73.         SHR     BX, 1                   ;Get width /2
  74.         MOV     SI, BX                  ;Put (Width/4)*2 in SI
  75.         SHR     BX, 1                   ;Get Width /4
  76.         MOV     [BP].DI_XSIZE, BX       ;Save width/4 as width
  77.         MOV     DX, SCREEN_WIDTH        ;Get Screen width (bytes)
  78.         SUB     DX, AX                  ;Get Dist to start of next line
  79.         MOV     [BP].DI_NextL, DX       ;Save info for later
  80.         AND     SI, 000Fh               ;Get (width/4) mod 16
  81.         MOV     AX, CS:JumpTable[SI]    ;Get 1st pass jump addr
  82.         MOV     [BP].DI_Jump, AX        ;Save for reference...
  83.  
  84.         MOV     CL, 4                   ;4 shifts = /16
  85.         SHR     BX, CL                  ;Get (Width/4) / 16
  86.         INC     BL                      ;Add 1 for 0 fall through
  87.         MOV     [BP].DI_Repeat, BL      ;Save Repeat block count
  88.  
  89.         ;Compute address of Image on Screen
  90.  
  91.         MOV     AX, SCREEN_WIDTH        ;Get Screen width (bytes)
  92.         MUL     [BP].DI_YPOS            ;AX = Ypos * Screen Width
  93.  
  94.         MOV     DI, [BP].DI_XPOS        ;Get Xpos
  95.         MOV     CX, DI                  ;Copy of Xpos in CX
  96.         SHR     DI, 1                   ;XByte = Xpos/4
  97.         SHR     DI, 1
  98.  
  99.         ADD     DI, AX                  ;Addr = Xpos/4 + Ypos*Screen Width
  100.         MOV     [BP].DI_Addr,DI         ;Save Screen starting Write Addr
  101.  
  102.         MOV     AX, 1102h               ;Plane Mask & Plane Select
  103.         AND     CL, 3                   ;Get Plane # in CL (Xpos AND 3)
  104.         SHL     AH, CL                  ;Set Mask to correct plane
  105.  
  106.         MOV     DX, SC_INDEX            ;Setup to select plane
  107.         OUT     DX, AX                  ;Select Plane...
  108.         INC     DX                      ;Future OUTs will be plane select
  109.  
  110.         MOV     DS, [BP].DI_ISEG        ;Get Image SEGMENT in DS
  111.  
  112.         MOV     CH,04h                  ;4 Planes to Draw
  113.  
  114.         CLD                             ;String copy opcodes forward
  115.  
  116.         ;Copy a plane (1/4) of the image data
  117.  
  118. @DI_Copy_Plane:
  119.  
  120.         MOV     SI,[BP].DI_IOFS         ;Get image start addr in (DS:)SI
  121.         MOV     DI,[BP].DI_Addr         ;Get Image write addr in (ES:)DI
  122.         MOV     CL,[BP].DI_Repeat       ;Get block repeat count
  123.         MOV     DX,[BP].DI_YSIZE        ;Get # of lines to copy
  124.         MOV     BX,[BP].DI_Jump         ;Get starting addr
  125.  
  126.         JMP     NEAR [BX]               ;skip to correct starting point
  127.  
  128.         ;Copy a block of 16 pixels
  129.         ;Loop unrolled to x16 for maximum performance
  130.  
  131. @DI_Copy_Loop:
  132.  
  133.         MOV     AL,[SI]                 ;Read Byte #1
  134.         OR      AL,AL                   ;Byte = 0?
  135.         JZ      @ND1                    ;If so, Don't Draw
  136.         MOV     ES:[DI],AL              ;Draw byte #1
  137.  
  138. @ND1:
  139.         INC     DI                      ;Advance Dest Addr
  140.         ADD     SI,4                    ;Skip to Next Byte in same plane
  141.  
  142. @Copy15:
  143.         MOV     AL,[SI]                 ;Read Byte #2
  144.         OR      AL,AL                   ;Byte =0?
  145.         JZ      @ND2                    ;If so, Don't Draw
  146.         MOV     ES:[DI],AL              ;Draw byte #2
  147.  
  148. @ND2:
  149.         INC     DI                      ;Advance Dest Addr
  150.         ADD     SI,4                    ;Skip to Next Byte in same plane
  151.  
  152. @Copy14:
  153.         MOV     AL,[SI]                 ;Read Byte #3
  154.         OR      AL,AL                   ;Byte =0?
  155.         JZ      @ND3                    ;If so, Don't Draw
  156.         MOV     ES:[DI],AL              ;Draw byte #3
  157.  
  158. @ND3:
  159.         INC     DI                      ;Advance Dest Addr
  160.         ADD     SI,4                    ;Skip to Next Byte in same plane
  161.  
  162. @Copy13:
  163.         MOV     AL,[SI]                 ;Read Byte #4
  164.         OR      AL,AL                   ;Byte =0?
  165.         JZ      @ND4                    ;If so, Don't Draw
  166.         MOV     ES:[DI],AL              ;Draw byte #4
  167.  
  168. @ND4:
  169.         INC     DI                      ;Advance Dest Addr
  170.         ADD     SI,4                    ;Skip to Next Byte in same plane
  171.  
  172. @Copy12:
  173.         MOV     AL,[SI]                 ;Read Byte #5
  174.         OR      AL,AL                   ;Byte =0?
  175.         JZ      @ND5                    ;If so, Don't Draw
  176.         MOV     ES:[DI],AL              ;Draw byte #5
  177.  
  178. @ND5:
  179.         INC     DI                      ;Advance Dest Addr
  180.         ADD     SI,4                    ;Skip to Next Byte in same plane
  181.  
  182. @Copy11:
  183.         MOV     AL,[SI]                 ;Read Byte #6
  184.         OR      AL,AL                   ;Byte =0?
  185.         JZ      @ND6                    ;If so, Don't Draw
  186.         MOV     ES:[DI],AL              ;Draw byte #6
  187.  
  188. @ND6:
  189.         INC     DI                      ;Advance Dest Addr
  190.         ADD     SI,4                    ;Skip to Next Byte in same plane
  191.  
  192. @Copy10:
  193.         MOV     AL,[SI]                 ;Read Byte #7
  194.         OR      AL,AL                   ;Byte =0?
  195.         JZ      @ND7                    ;If so, Don't Draw
  196.         MOV     ES:[DI],AL              ;Draw byte #7
  197.  
  198. @ND7:
  199.         INC     DI                      ;Advance Dest Addr
  200.         ADD     SI,4                    ;Skip to Next Byte in same plane
  201.  
  202. @Copy9:
  203.         MOV     AL,[SI]                 ;Read Byte #8
  204.         OR      AL,AL                   ;Byte =0?
  205.         JZ      @ND8                    ;If so, Don't Draw
  206.         MOV     ES:[DI],AL              ;Draw byte #8
  207.  
  208. @ND8:
  209.         INC     DI                      ;Advance Dest Addr
  210.         ADD     SI,4                    ;Skip to Next Byte in same plane
  211.  
  212. @Copy8:
  213.         MOV     AL,[SI]                 ;Read Byte #9
  214.         OR      AL,AL                   ;Byte =0?
  215.         JZ      @ND9                    ;If so, Don't Draw
  216.         MOV     ES:[DI],AL              ;Draw byte #9
  217.  
  218. @ND9:
  219.         INC     DI                      ;Advance Dest Addr
  220.         ADD     SI,4                    ;Skip to Next Byte in same plane
  221. @Copy7:
  222.         MOV     AL,[SI]                 ;Read Byte #10
  223.         OR      AL,AL                   ;Byte =0?
  224.         JZ      @ND10                   ;If so, Don't Draw
  225.         MOV     ES:[DI],AL              ;Draw byte #10
  226.  
  227. ;Routine: CLEAR_VGA_SCREEN (*Color%)
  228. ;  Sets the Entire Screen to one Color
  229. ;
  230. ;BASIC: DECLARE SUB CLEAR.VGA ALIAS "CLEAR_VGA_SCREEN" 
  231. ;(BYVAL ColorNum%) 
  232. ;C:     pascal void CLEAR_VGA_SCREEN ( int ColorNum );
  233.  
  234. CVS_STACK STRUC
  235.                 DW      ?       ;saved DI
  236.                 DW      ?       ;saved BP
  237.                 DD      ?       ;Caller
  238.     CVS_COLOR   DB      ?,?     ;Color to Fill With CVS_STACK ENDS
  239.  
  240.     PUBLIC      CLEAR_VGA_SCREEN
  241.  
  242. CLEAR_VGA_SCREEN        PROC    FAR
  243.  
  244.     PUSH    BP                  ; Save registers
  245.     PUSH    DI
  246.  
  247.     MOV     BP,SP               ; Setup Stack frame
  248.  
  249.     MOV     DX, SC_INDEX        ; Select All Panes
  250.     MOV     AX, 0F02H           ; Map Mask (02) = 0F
  251.     OUT     DX, AX
  252.  
  253.     MOV     AX, VGA_SEGMENT     ; Point to VGA memory
  254.     MOV     ES, AX
  255.     MOV     DI, 0
  256.  
  257.     MOV     AL,[BP].CVS_COLOR   ; Get Color to set
  258.     MOV     AH,AL               ; Copy for Word Write
  259.  
  260.     MOV     CX, 10800           ; # of bytes in 360x240 mode
  261.     REP     STOSW               ; Blast it!
  262.  
  263.     POP     DI                  ; restore registers
  264.     POP     BP
  265.  
  266.     RET     2                   ; exit & clean up stack
  267.  
  268. CLEAR_VGA_SCREEN        ENDP
  269.  
  270. ;Routine: SETPOINT (*Xpos1, *Ypos1%, *ColorNum%) 
  271. ;   Sets a single pixel in 360x240 256 color mode 
  272. ;BASIC: DECLARE SUB SETPOINT (BYVAL X%, BYVAL Y%, BYVAL ColorNum%) 
  273. ;C:     pascal void SETPOINT (int Xpos, int Ypos, int ColorNum);
  274.  
  275.  
  276. SP_STACK STRUC
  277.                 DW      ?       ;saved BP
  278.                 DD      ?       ;Caller
  279.     SETP_COLOR  DB      ?,?     ;Pixel color
  280.     SETP_YPOS   DW      ?       ;Pixel Y pos
  281.     SETP_XPOS   DW      ?       ;Pixel X pos SP_STACK ENDS
  282.  
  283.     PUBLIC SETPOINT
  284.  
  285. SETPOINT    PROC    FAR
  286.  
  287.     PUSH    BP                  ;Save base pointer
  288.  
  289.     MOV     BP,SP               ;Set up stack frame
  290.  
  291.     MOV     AX, SCREEN_WIDTH    ;Get Screen Line Width
  292.     MUL     [BP].SETP_YPOS      ;AX = Ypos * 90
  293.  
  294.     MOV     BX,[BP].SETP_XPOS   ;Get Xpos
  295.     MOV     CX, BX              ;Save copy of Xpos
  296.     SHR     BX, 1               ;XByte = Xpos/4
  297.     SHR     BX, 1
  298.  
  299.     ADD     BX,AX               ;BX = 90 * Ypos + Xpos/4
  300.  
  301.     MOV     AX, 0102h           ;Plane Mask & Select Register
  302.     AND     CL, 3               ;Get plane # from Xpos
  303.     SHL     AH, CL              ;Shift to Get Plane Value
  304.     MOV     DX, SC_INDEX        ;Setup to select plane
  305.  
  306.     OUT     DX, AX              ;Select Plane...
  307.  
  308.     MOV     AX,VGA_SEGMENT      ;Setup Vga Segment
  309.     MOV     ES,AX
  310.  
  311.     MOV     AL,[BP].SETP_COLOR  ;Get Color
  312.  
  313.     MOV     ES:[BX], AL         ;Draw Point
  314.  
  315.     POP     BP                  ;Restore Bp
  316.  
  317.     RET     6                   ;Exit and Clean up Stack
  318.  
  319. SETPOINT    ENDP
  320.  
  321. ;Routine: int READPOINT (*Xpos, *Ypos%)
  322. ;    Returns the color of single pixel in AX 
  323. ;BASIC: DECLARE FUNCTION READPOINT% (BYVAL X%, BYVAL Y%) 
  324. ;C:     pascal int READPOINT( int Xpos, int Ypos );
  325.  
  326. RP_STACK STRUC
  327.                 DW      ?       ;saved Bp
  328.                 DD      ?       ;Caller
  329.     RP_YPOS     DW      ?       ;Pixel Y pos
  330.     RP_XPOS     DW      ?       ;Pixel X pos RP_STACK ENDS
  331.  
  332.     PUBLIC      READPOINT
  333.  
  334. READPOINT        PROC    FAR
  335.  
  336.     PUSH    BP
  337.  
  338.     MOV     BP,SP               ;Set up stack frame
  339.  
  340.     MOV     AX, SCREEN_WIDTH    ;Get Screen Line Width
  341.     MUL     [BP].RP_YPOS        ;AX = Ypos * Screen Width
  342.  
  343.     MOV     BX,[BP].RP_XPOS     ;Get Xpos
  344.     MOV     CX, BX              ;Save Copy of Xpos
  345.     SHR     BX, 1               ;XByte = Xpos/4
  346.     SHR     BX, 1
  347.  
  348.     ADD     BX,AX               ;BX = Screen_Width * Ypos + Xpos/4
  349.  
  350.     MOV     AL, READ_MAP        ;GC Read Mask Register
  351.     MOV     AH, CL              ;Get Xpos
  352.     AND     AH, 3               ;& mask out Plane #
  353.     MOV     DX, GC_INDEX        ;Setup to select Read Mask
  354.  
  355.     OUT     DX, AX              ;Select Plane...
  356.  
  357.     MOV     AX,VGA_SEGMENT      ;Setup Vga Segment
  358.     MOV     ES,AX
  359.  
  360.     XOR     AX,AX               ;Clear Return Value
  361.  
  362.     MOV     AL,ES:[BX]          ;Get Color of Pixel
  363.  
  364.     POP     BP                  ;Restore registers
  365.  
  366.     RET     4                   ;Exit and Clean up Stack
  367.  
  368. READPOINT        ENDP
  369.  
  370. ; EOF DRAWIMAG.ASM
  371.