home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / graphics / vesa24_2.zip / VGA24_2.ASM < prev    next >
Assembly Source File  |  1993-04-09  |  26KB  |  1,272 lines

  1. ;----------------------------vga.asm--------------------------------
  2. ; Modified for CIRRUS bank set and rgb input values 12/30/92
  3. ;
  4. ; Title: vga.asm   ren vga41.asm  ren vga24.asm by Don Lewis
  5. ; Date: 6/18/92
  6. ; Author: Randy Buckland (randy@ncsu.edu)
  7. ;
  8. ; Description:
  9. ;    This is a VERY basic set of routines to provide high speed SVGA
  10. ; graphics for IBM-PC compatibiles that have a VGA interface that supports
  11. ; a VESA driver. These routines assume a 256-color mode and will not work
  12. ; for any type of mode. The following routines are provided:
  13. ;
  14. ; vgainit(int vesa_mode)
  15. ; vgapoint(int row, int column, int pixel_value)
  16. ; vgahline(int row, int start_column, int end_column, int pixel_value)
  17. ; vgaline(int x1, int y1, int x2, int y2, int pixel_value)
  18. ; vgasetcolor(char *colors, int start, int count)
  19. ; vgafill(int row, int column, int width, int height, int pixel_value)
  20. ; vgarect(char *source, int source_width, int row, int column,
  21. ;        int width, int height)
  22. ;
  23. ;******** ADDED by Don Lewis, (djlewis@ualr.edu or djlewis@spider.ualr.edu)
  24. ; This works fine with 8bit VGA. Just pass color in red and rest is ignored.
  25. ; The original vgafill() was simply modified and vgapoint probably will be to.
  26. ; These modifications works with 8,15,16 and 24 bit VESA modes.
  27. ;
  28. ; vga_point(int,int,uchar r,uchar g,uchar b)
  29. ; vgapoint_rgb(int row, int column, uchar r, uchar g, uchar b)
  30. ; vgafill(int,int,int,int,uchar r,uchar g,uchar b)
  31. ; vgaline(int,int,int,int,uchar r,uchar g,uchar b)
  32. ;
  33. .model    large,c
  34. include macros.asm
  35.  
  36. ;
  37. ; Global data for the VGA support routines
  38. ;
  39. vgadata    segment word public 'VGADATA'
  40.  
  41. Block        dw    0        ; Current video memory block accessable
  42. BlockSz        dw    0        ; Size of a video block in K
  43. BlockShift    dw    0        ; Amount to shift bits by
  44. BlockEnd    dw    0        ; Last valid address in block
  45. BlockMask    dw    0        ; Mask used for block/offset operations
  46.  
  47. WinAddr        dw    0        ; Segment addr of window A block
  48. WinGran        dw    0        ; Window Granularity 12/10/92 djl
  49. ;WinFunc    dd    0        ; Far pointer to windowing function
  50. ScanWidth    dw    0        ; Width of a scan line
  51. BytesPerPixel   dw      0        ; BytesPerPixel  12/30/92 djl
  52. BitsPerPixel    dw    0        ; BitsPerPixel value
  53.  
  54. ShiftMask    dw    0        ; pixel shift mask 15 and 16bit modes
  55. shift        dw    0        ; pixel adjustment 15 and 16 bit modes
  56.  
  57. public screen_width,screen_height
  58. screen_width    dw    640        ; Width of screen
  59. screen_height    dw    480        ; Height of screen
  60.  
  61. public mouse_x, mouse_y
  62. mouse_x        dw    0
  63. mouse_y        dw    0
  64.  
  65. public text_height, text_drop
  66. text_height     dw      16
  67. text_drop       dw      4
  68.  
  69. vgadata    ends
  70.  
  71. vgacode segment word public 'VGACODE'
  72.     assume  cs:vgacode,ds:vgadata
  73.  
  74. ;
  75. ; Set current video memory block. This procedure assumes that ds already
  76. ; points to the vgadata segment. This routine will not modify any registers.
  77. ;
  78. ; Parameters:
  79. ;    - block number to change to
  80. ;
  81. vgablock proc near
  82.     push bp
  83.     mov bp,sp
  84.     push cx        ; stay with no register modification. djl
  85.     push dx
  86.  
  87.     mov dx,[bp+4]    ; Start of video memory
  88.     cmp dx,Block
  89.     je l1
  90.             ;Window Granularity must be used to adjust bank. djl
  91.     mov cx,WinGran  ;BankNum offset adjustment for cards of
  92.     shl dl,cl    ;varying window granularity. djl
  93.     mov Block,dx
  94.  
  95.     push ax
  96.     push bx
  97.  
  98.     mov ax,4f05h    ; VESA set memory block
  99.     mov bx,0000h    ; Set window A
  100.     int 10h
  101.  
  102.     pop bx
  103.     pop ax
  104. l1:
  105.     pop dx
  106.     pop cx        ; stay with no register modification. djl
  107.     mov sp,bp
  108.     pop bp
  109.     ret
  110. vgablock endp
  111.  
  112.  
  113.  
  114. ;
  115. ; Calculate block and offset values for a given row/column. Assumes that ds
  116. ; points to vgadata. Does NOT preserve registers. Returns block value in
  117. ; dx and offset in ax.
  118. ;
  119. ; Parameters:
  120. ;    - row value
  121. ;    - column value
  122. ;
  123. vgaoffset proc near
  124.     push bp
  125.     mov bp,sp
  126.  
  127.     mov ax,[bp+4]        ; Get row
  128.     mul ScanWidth        ; Get starting block and offset in dx:ax
  129.  
  130. ; New code for 24bit pixel offset
  131.     push dx
  132.     mov bx,ax        ; Save old ax
  133.     xor ax,ax
  134.     mov ax,[bp+6]             ; get column
  135. ;    mul word PTR BytesPerPixel
  136.     mul BytesPerPixel
  137.     and ax,7FFFh
  138.     add ax,bx        ; Add column offset
  139.     pop dx
  140.  
  141.     ;add ax,[bp+6]    ; Add start column offset
  142.     jnc la1
  143.     inc dx        ; Just crossed block boundery
  144. la1:
  145.     mov cx,BlockShift ; Get block size mask
  146.     cmp cx,0        ; Is block size 64K?
  147.     je la2           ; Yes, skip this section
  148.  
  149.     mov bx,ax    ; Save old ax
  150.     rol ax,cl
  151.     and ax,BlockMask ; Save high bits
  152.     rol dx,cl
  153.     add dx,ax    ; Add high bits to block value.
  154.  
  155.     mov ax,bx
  156.     rol ax,cl
  157.     or ax,BlockMask    ; Set undesirable bits
  158.     xor ax,BlockMask ; Clear bad bits
  159.     ror ax,cl
  160. ;
  161. ; Set active block to calculated block if needed
  162. ;
  163. la2:
  164.     cmp dx,Block
  165.     je la3
  166.     push dx
  167.     call vgablock
  168.     pop dx
  169. la3:
  170.  
  171.     mov sp,bp
  172.     pop bp
  173.     ret
  174. vgaoffset endp
  175.  
  176. ;
  177. ; Draw a single point in Red, Green, Blue for 15, 16 and 24 bit colour
  178. ; Added by Don Lewis to work with internal functions
  179. ; Parameters:
  180. ;    - Row of point
  181. ;    - Column of point
  182. ;    - r,g,b
  183. ;
  184. ; 24bit format bit pattern 'bbbbbbbbggggggggrrrrrrrr' 3 bytes
  185. ; 16bit                    '00000000bbbbbggggggrrrrr' 2 bytes
  186. ; 15bit                    '        0bbbbbgggggrrrrr' 2 bytes
  187. ;
  188. draw_rgb proc near
  189.     Prefix
  190.     push bx
  191.     push cx
  192.     push dx
  193. ;
  194. ; Draw point
  195. ;
  196.     cmp BitsPerPixel,24     ; Is it 24bits per pixel
  197.     jne isit15_16        ; if not goto isit15_16
  198.     mov ax,[bp+8]        ; al has blue pixel value
  199.     cld                     ; clear direction flag to increment
  200.     stosb                   ; write a byte in al to address in es:di
  201.     mov ax,[bp+6]         ; al has green pixel value
  202.     stosb
  203.     mov ax,[bp+4]          ; al has red pixel value
  204.     stosb
  205.     jmp fini                ; All three bytes written. Finish
  206. ;
  207. isit15_16:
  208.     cmp BitsPerPixel,16    ; Is it 16bits per pixel
  209.     mov Shift,3        ; adjust red bits shift factor
  210.     mov ShiftMask,255    ; adjust red/green bits mask
  211.     je drawit               ; Go write the color data else its 15bit
  212.     mov Shift,2             ; adjust for 15bits per pixel
  213.     mov ShiftMask,127       ; adjust red/green bit mask
  214. drawit:
  215.     mov cl,5        ; shift bits up factor
  216.     xor ax,ax        ; clear reg
  217.     mov bx,[bp+6]        ; get green value
  218.     and bx,00ffh
  219.     shl bx,cl        ; shift green up 5bits
  220.     mov ax,[bp+8]        ; get blue value
  221.     and ax,00FFh
  222.     add ax,bx        ; put portion of green with blue
  223.     cld
  224.     stosb            ; write the blue green value
  225.     mov ax,[bp+4]        ; get red value
  226.     and ax,00FFh
  227.     mov cx,Shift        ; get 15 or 16 bit shift factor
  228.     shl ax,cl        ; move red to correct position
  229.     add al,bh        ; put remaining green value with red
  230.     and ax,Shiftmask    ; mask unwanted bits
  231.     stosb            ; write the red green value
  232. fini:
  233.     pop dx                  ; Clean house and leave
  234.     pop cx
  235.     pop bx
  236.     Postfix
  237. draw_rgb endp
  238.  
  239.  
  240. ;
  241. ; Initialize the display
  242. ; Parameters:
  243. ;    Mode value to use
  244. ;
  245. public vgainit
  246. vgainit    proc far
  247. ;
  248. ; Set up call frame
  249. ;
  250.     Prefix
  251.     sub sp,256    ; Make local variable space
  252. ;
  253.     mov ax,vgadata    ; Load address of data segment
  254.     mov ds,ax    ; Set DS register
  255.  
  256. ;
  257. ; Get VGA information and set desired mode
  258. ;
  259.     mov ax,4f02h    ; VESA set mode function
  260.     mov bx,[bp+6]    ; Any mode I want !
  261.     int 10h
  262.  
  263.     push ss
  264.     pop es        ; Load es with value of ss
  265.     mov di,sp    ; Point index at 256 byte temp space
  266.     mov cx,[bp+6]
  267.     mov ax,4f01h    ; VESA get Super VGA mode information
  268.     int 10h
  269.  
  270.     mov ax,es:[di+4]  ;WinGranularity in k added 12/10/1992 djl
  271.     mov WinGran,ax
  272.     mov ax,es:[di+6]  ;WinSize in k
  273.     mov BlockSz,ax
  274.  
  275.     mov ax,es:[di+8]
  276.     mov WinAddr,ax    ;WinASegment  usually a000h
  277.  
  278. ;    mov ax,es:[di+12]        ;was rem ed from here by R.B.
  279. ;    mov word ptr WinFunc,ax  ;
  280.  
  281. ;    mov ax,es:[di+14]        ;
  282. ;    mov word ptr WinFunc+2,ax  ; to here
  283.  
  284.     mov ax,es:[di+16]
  285.     mov ScanWidth,ax      ;BytesPerScanLine
  286.  
  287.     mov ax,es:[di+25]     ;BitsPerPixel added 12/30/92 djl
  288.     and ax,255            ; djl
  289.     mov BitsPerPixel,ax    ; djl
  290.     cmp ax,15             ;is it a 15 bit mode? djl
  291.     jne lb0               ;skip if not 15 bit mode. djl
  292.     inc al                ;else force 15 bit modes to 16 bit modes. djl
  293. lb0:                          ;
  294.     shr al,3              ;convert BitsPerPixel to BytesPerPixel, djl
  295.     mov BytesPerPixel,ax    ;end of addition 12/30/92 djl
  296. ;
  297. ; Calculate block shift and end values
  298. ;
  299.     mov ax,BlockSz    ;ax = WinSize
  300.     mov bx,10
  301.     mov cx,03ffh
  302. lb1:
  303.     sar ax,1          ;divide ax by 2
  304.     inc bx            ;bx + 1
  305.     sal cx,1          ;multiply cx by 2
  306.     inc cx            ;cx + 1
  307.     cmp ax,1          ;compare ax to 1
  308.     ja lb1            ;jump short if above(CF=0 and ZF=0)
  309.  
  310.     mov ax,16
  311.     sub ax,bx         ;ax - bx = ax
  312.     mov BlockShift, ax
  313.     mov BlockEnd, cx
  314.     not cx
  315.     xchg ax,cx
  316.     rol ax,cl
  317.     mov BlockMask,ax
  318.  
  319. ;
  320. ; Set to start block
  321. ;
  322.     xor ax,ax
  323.     push ax
  324.     call vgablock
  325.     pop ax
  326.  
  327. ;
  328. ; Remove call frame and exit
  329. ;
  330.     add sp,256
  331.     Postfix
  332. vgainit    endp
  333.  
  334. ;
  335. ; Draw a single point
  336. ;
  337. ; Parameters:
  338. ;    - Row of point
  339. ;    - Column of point
  340. ;    - Pixel value to use
  341. ;
  342. public vgapoint
  343. vgapoint proc far
  344.     Prefix
  345.  
  346.     mov ax,vgadata    ; Load address of data segment
  347.     mov ds,ax    ; Set DS register
  348. ;
  349. ; Load window pointers
  350. ;
  351.     mov ax,WinAddr
  352.     mov es,ax        ; Set ES to point to video memory
  353.     push [bp+8] ; Column
  354.     push [bp+6] ; Row
  355.     call vgaoffset
  356.     add sp,4
  357.  
  358. ;
  359. ; Draw point in 8bit modes
  360. ;
  361.     mov di,ax    ; Put offset in index regester
  362.     mov ax,[bp+10]    ; bl has pixel value
  363.     cld
  364.     stosb
  365. ;
  366.     Postfix
  367. vgapoint endp
  368.  
  369. ;
  370. ; Draw a single point Red, Green, Blue. BY Don Lewis
  371. ; to be called from external C routine
  372. ;
  373. ; Parameters:
  374. ;    - Row of point
  375. ;    - Column of point
  376. ;    - r,g,b
  377. ;
  378. public vgapoint_rgb
  379. vgapoint_rgb proc far
  380.     Prefix
  381.  
  382.     mov ax,vgadata    ; Load address of data segment
  383.     mov ds,ax    ; Set DS register
  384. ;
  385. ; Load window pointers
  386. ;
  387.     mov ax,WinAddr  ; Get video memory start
  388.     mov es,ax    ; Set ES to point to video memory
  389.  
  390.     push [bp+8] ; Column
  391.     push [bp+6] ; Row
  392.     call vgaoffset
  393.     add sp,4
  394.  
  395. ;
  396. ; Draw point
  397. ;
  398.     mov di,ax        ; Put offset in index regester
  399.     push [bp+14]
  400.     push [bp+12]
  401.     push [bp+10]
  402.     call draw_rgb
  403.     add sp,6
  404.  
  405. ;    mov di,ax        ; Put offset in index regester
  406. ;    cmp BitsPerPixel,24     ; Is it 24bits per pixel
  407. ;    jne dr1516        ; if not goto dr1516
  408. ;    mov ax,[bp+14]        ; bl has blue pixel value
  409. ;    cld
  410. ;    stosb
  411. ;    mov ax,[bp+12]         ; bl has green pixel value
  412. ;    stosb
  413. ;    mov ax,[bp+10]      ; bl has red pixel value
  414. ;    stosb
  415. ;    jmp finish
  416. ;dr1516:
  417. ;    cmp BitsPerPixel,16    ; Is it 16bits per pixel
  418. ;    mov Shift,3        ; adjust red bits shift factor
  419. ;    mov ShiftMask,255    ; adjust red bits mask
  420. ;    je draw
  421. ;    mov Shift,2             ; adjust for 15bits per pixel
  422. ;    mov ShiftMask,127
  423. ;draw:
  424. ;    mov cl,5        ; shift up factor
  425. ;    xor ax,ax        ; clear reg
  426. ;    mov bx,[bp+12]        ; get green value
  427. ;    shl bx,cl        ; shift green up 5bits
  428. ;    mov ax,[bp+14]        ; get blue value
  429. ;    add ax,bx        ; put portion of green with blue
  430. ;    cld
  431. ;    stosb            ; write the blue green value
  432. ;    mov ax,[bp+10]        ; get red value
  433. ;    mov cx,Shift        ; get 15 or 16 bit shift factor
  434. ;    shl ax,cl        ; move red to correct position
  435. ;    add al,bh        ; put remaining green value with red
  436. ;    and ax,Shiftmask    ; mask unwanted bits
  437. ;    stosb            ; write the red green value
  438. finish:
  439.     Postfix
  440. vgapoint_rgb endp
  441.  
  442.  
  443.  
  444. ;
  445. ; Draw a horizontal line. Line is assumed to start on even boundry and
  446. ; have length be an even value for speed.
  447. ;
  448. ; Parameters:
  449. ;    - Row for line
  450. ;    - Start column
  451. ;    - End column
  452. ;    - Pixel value
  453. ;
  454. public vgahline
  455. vgahline proc far
  456.     Prefix
  457. ;
  458.     mov    ax,vgadata    ; Load address of data segment
  459.     mov    ds,ax        ; Set DS register
  460. ;
  461. ; Load window pointers
  462. ;
  463.     mov ax,WinAddr
  464.     mov es,ax        ; Set ES to point to video memory
  465.  
  466.     push [bp+8]             ; Beginning Column
  467.     push [bp+6]             ; Row
  468.     call vgaoffset
  469.     add sp,4
  470.  
  471. ;
  472. ; Setup control parameters for line draw.
  473. ;
  474.     mov di, ax        ; Offset in di
  475.     mov ax,[bp+12]          ; Pixel color
  476.     mov ah,al        ; ax has duplicated pixel value in bl and bh
  477.  
  478.     mov cx,BlockEnd        ; Last point in counter
  479.     sub cx,di        ; cx has number of legal bytes-1
  480.  
  481.     mov bx,[bp+10]          ; Ending column
  482.     sub bx,[bp+8]        ; bx has number to write - 1
  483.  
  484.     cmp bx,cx
  485.     ja lc1
  486.     mov cx,bx        ; Won't need a block change
  487. lc1:
  488.     sub bx,cx        ; ax has number of words after block change
  489.     inc cx
  490.     ror cx,1
  491.     ror bx,1
  492.  
  493. ;
  494. ; Draw the line
  495. ;
  496.     even
  497. lc4:
  498.     cld
  499.     rep stosw
  500.  
  501.     cmp bx,0
  502.     je lc5
  503.  
  504. ;
  505. ; Handle block change and continue
  506. ;
  507.     inc dx
  508.     push dx
  509.     call vgablock
  510.     pop dx
  511.  
  512.     mov cx,bx
  513.     xor bx,bx
  514.     xor di,di
  515.     jmp lc4
  516.  
  517. ;
  518. ; Finish up
  519. ;
  520. lc5:
  521.     Postfix
  522. vgahline endp
  523.  
  524.  
  525.  
  526. ;
  527. ; Draw a line using bresenham's algorithm.
  528. ;
  529. ; Parameters:
  530. ;    - x1
  531. ;    - y1
  532. ;    - x2
  533. ;    - y2
  534. ;    - Pixel value
  535. ;
  536. ; Locals:
  537. ;    [bp-10] DX
  538. ;    [bp-12] DY
  539. ;    [bp-14] incr1
  540. ;    [bp-16] incr2
  541. ;
  542. public vgaline
  543. vgaline proc far
  544.     Prefix
  545.     sub sp,8
  546. ;
  547.     mov    ax,vgadata    ; Load address of data segment
  548.     mov    ds,ax        ; Set DS register
  549. ;
  550. ; Load window pointers
  551. ;
  552.     mov ax,WinAddr
  553.     mov es,ax        ; Set ES to point to video memory
  554.  
  555.     push [bp+8]
  556.     push [bp+6]
  557.     call vgaoffset
  558.     add sp,4
  559.     mov di,ax
  560.  
  561. ;
  562. ; Initialize for line draw
  563. ;
  564.     mov ax,[bp+8]        ; Get x1
  565.     sub ax,[bp+12]        ; Sub x2
  566.     jg ld1            ; Skip if positive
  567.     neg ax
  568. ld1:    mov [bp-10],ax        ; Save DX
  569.  
  570.     mov ax,[bp+6]        ; Get y1
  571.     sub ax,[bp+10]        ; sub y2
  572.     jg ld2            ; Skip if positive
  573.     neg ax
  574. ld2:    mov [bp-12],ax        ; Save DY
  575.  
  576.     cmp ax,[bp-10]        ; See if DY>DX
  577.     jle xline        ; Go do X oriented version
  578.     jmp yline        ; Go do Y oriented version
  579.  
  580. ;
  581. ; X oriented version of draw line. Slope must be between -1 and 1 inclusive
  582. ;
  583. xline:
  584.     mov cx, [bp-10]        ; cx has increment control
  585.  
  586.     sal ax,1        ; DY*2
  587.     mov [bp-14],ax        ; Save incr1
  588.     sub ax,[bp-10]        ; 2*dy - dx
  589.     mov bx,ax        ; bx has D value
  590.  
  591.     mov ax,[bp-12]        ; Get DY
  592.     sub ax,[bp-10]        ; (DY-DX)
  593.     sal ax,1        ; 2*(DY-DX)
  594.     mov [bp-16],ax        ; Save incr2
  595.  
  596.     mov word ptr [bp-10],0  ; Assume going to left
  597.     mov ax,[bp+8]        ; Get x1
  598.     sub ax,[bp+12]        ; x1-x2
  599.     jg ld3
  600.     mov word ptr [bp-10],1    ; Going to right
  601. ld3:
  602.     mov word ptr [bp-12],0    ; Assume going up
  603.     mov ax,[bp+6]        ; Get y1
  604.     sub ax,[bp+10]        ; y1-y2
  605.     jg ld5
  606.     mov word ptr [bp-12],1    ; Going down
  607. ld5:
  608.  
  609. ;
  610. ; Main X oriented drawing loop.
  611. ;    ax = pixel value
  612. ;    bx = d
  613. ;    cx = loop control
  614. ;    dx = block number
  615. ;    di = block offset
  616. ;
  617.     cmp BitsPerPixel,8      ; If 8bit mode continue else goto
  618.     jne drwrgb1             ; draw_rgb routine
  619.     mov ax,[bp+14]
  620.     mov es:[di],al        ; Write first pixel
  621.     jmp ldd5
  622. drwrgb1:
  623.     push [bp+18]
  624.     push [bp+16]
  625.     push [bp+14]
  626.     call draw_rgb
  627.     add sp,6
  628. ldd5:
  629.     cmp cx,0        ; Check if done
  630.     je xloopend
  631.  
  632. xloop:
  633.     cmp word ptr [bp-10],0    ; See if going left?
  634.     je ld7
  635. ;    inc di            ; going right
  636.     add di,BytesPerPixel
  637.     jnc ld8
  638.     inc dx
  639.     push dx
  640.     call vgablock
  641.     pop dx
  642.     jmp ld8
  643. ld7:
  644. ;    dec di            ; going left
  645.     sub di,BytesPerPixel
  646.     jnc ld8
  647.     dec dx
  648.     push dx
  649.     call vgablock
  650.     pop dx
  651. ld8:
  652.     cmp bx,0        ; test d<0
  653.     jge ld9
  654.     add bx,[bp-14]        ; d = d + incr1
  655.     jmp ld11
  656. ld9:
  657.     add bx,[bp-16]        ; d = d + incr2
  658.     cmp word ptr [bp-12],0    ; See if going up
  659.     je ld10
  660.     add di,ScanWidth    ; Go to next line
  661.     jnc ld11
  662.     inc dx
  663.     push dx
  664.     call vgablock
  665.     pop dx
  666.     jmp ld11
  667. ld10:
  668.     sub di,ScanWidth    ; Go to previous line
  669.     jnc ld11
  670.     dec dx
  671.     push dx
  672.     call vgablock
  673.     pop dx
  674. ld11:
  675.     cmp BitsPerPixel,8      ; If 8bit continue else
  676.     jne drwrgb2             ; call draw_rgb
  677.     mov es:[di],al        ; Write next pixel
  678.     jmp ldd11
  679. drwrgb2:
  680.     push [bp+18]
  681.     push [bp+16]
  682.     push [bp+14]
  683.     call draw_rgb
  684.     add sp,6
  685. ldd11:
  686.     loop xloop
  687. xloopend:
  688.     jmp done
  689.  
  690.  
  691. ;
  692. ; Y oriented version of draw line. Slope must be outside -1 and 1 inclusive
  693. ;
  694. yline:
  695.     mov cx, [bp-12]        ; cx has increment control
  696.  
  697.     mov ax, [bp-10]
  698.     sal ax,1        ; DX*2
  699.     mov [bp-14],ax        ; Save incr1
  700.     sub ax,[bp-12]        ; 2*dx - dy
  701.     mov bx,ax        ; bx has D value
  702.  
  703.     mov ax,[bp-10]        ; Get DX
  704.     sub ax,[bp-12]        ; (DX-DY)
  705.     sal ax,1        ; 2*(DX-DY)
  706.     mov [bp-16],ax        ; Save incr2
  707.  
  708.     mov word ptr [bp-10],0  ; Assume going to left
  709.     mov ax,[bp+8]        ; Get x1
  710.     sub ax,[bp+12]        ; x1-x2
  711.     jg ld12
  712.     mov word ptr [bp-10],1    ; Going to right
  713. ld12:
  714.     mov word ptr [bp-12],0    ; Assume going up
  715.     mov ax,[bp+6]        ; Get y1
  716.     sub ax,[bp+10]        ; y1-y2
  717.     jg ld13
  718.     mov word ptr [bp-12],1    ; Going down
  719. ld13:
  720.  
  721. ;
  722. ; Main Y oriented drawing loop.
  723. ;    ax = pixel value
  724. ;    bx = d
  725. ;    cx = loop control
  726. ;    dx = block number
  727. ;    di = block offset
  728. ;
  729.     cmp BitsPerPixel,8      ; Is it 8bit mode
  730.     jne drwrgb3             ;  no. call draw_rgb
  731.     mov ax,[bp+14]
  732.     mov es:[di],al        ; Write first pixel
  733.     jmp ldd13
  734. drwrgb3:
  735.     push [bp+18]
  736.     push [bp+16]
  737.     push [bp+14]
  738.     call draw_rgb
  739.     add sp,6
  740. ldd13:    cmp cx,0        ; Check if done
  741.     je yloopend
  742.  
  743. yloop:
  744.     cmp word ptr [bp-12],0    ; See if going up?
  745.     je ld14
  746.     add di,ScanWidth    ; going down
  747.     jnc ld15
  748.     inc dx
  749.     push dx
  750.     call vgablock
  751.     pop dx
  752.     jmp ld15
  753. ld14:
  754.     sub di,ScanWidth    ; going up
  755.     jnc ld15
  756.     dec dx
  757.     push dx
  758.     call vgablock
  759.     pop dx
  760. ld15:
  761.     cmp bx,0        ; test d<0
  762.     jge ld16
  763.     add bx,[bp-14]        ; d = d + incr1
  764.     jmp ld18
  765. ld16:
  766.     add bx,[bp-16]        ; d = d + incr2
  767.     cmp word ptr [bp-10],0    ; See if going left
  768.     je ld17
  769. ;    inc di            ; Go right
  770.     add di,BytesPerPixel
  771.     jnc ld18
  772.     inc dx
  773.     push dx
  774.     call vgablock
  775.     pop dx
  776.     jmp ld18
  777. ld17:
  778. ;    dec di            ; Go left
  779.     sub di,BytesPerPixel
  780.     jnc ld18
  781.     dec dx
  782.     push dx
  783.     call vgablock
  784.     pop dx
  785. ld18:
  786.     cmp BitsPerPixel,8      ; Is it 8bit mode
  787.     jne drwrgb4
  788.     mov es:[di],al        ; Write next pixel
  789.     jmp ld18
  790. drwrgb4:
  791.     push [bp+18]
  792.     push [bp+16]
  793.     push [bp+14]
  794.     call draw_rgb
  795.     add sp,6
  796. ldd18:
  797.     loop yloop
  798. yloopend:
  799.  
  800. ;
  801. ; Clear stack and exit
  802. ;
  803. done:
  804.     add sp,8
  805.     Postfix
  806. vgaline endp
  807.  
  808.  
  809.  
  810. ;
  811. ; Set colors from an array of rgb values.
  812. ;
  813. ; Parameters:
  814. ;    - Array of colors
  815. ;    - Start index
  816. ;    - Number of colors
  817. ;
  818. public vgasetcolor
  819. vgasetcolor proc far
  820.     Prefix
  821.  
  822.     les dx,[bp+6]        ; Get address of colormap
  823.     mov bx,[bp+10]        ; Get first color index
  824.     mov cx,[bp+12]        ; Get Number of indexes
  825.     mov ax,1012h        ; Set block of color registers function
  826.     int 10h
  827.  
  828.     Postfix
  829. vgasetcolor endp
  830.  
  831.  
  832.  
  833. ;
  834. ; Fill a rectangular region with a given pixel value. Region is assumed to
  835. ; start on a even address and be an even width. Width and height values
  836. ; must be positive. Width and height values get modified.
  837. ;
  838. ; Parameters:
  839. ;    - Row for upper left corner
  840. ;    - Column for upper left corner
  841. ;    - Width of rectangle
  842. ;    - Height of rectangle
  843. ;    - Pixel value
  844. ;
  845. ; Locals
  846. ;    [bp-10] LineSkip
  847. ;
  848. public vgafill
  849. vgafill proc far
  850.     Prefix
  851.     sub sp,2
  852. ;
  853.     mov    ax,vgadata    ; Load address of data segment
  854.     mov    ds,ax        ; Set DS register
  855.  
  856. ;
  857. ; Load window pointers
  858. ;
  859.     mov ax,WinAddr
  860.     mov es,ax        ; Set ES to point to video memory
  861.  
  862.     push [bp+8]
  863.     push [bp+6]
  864.     call vgaoffset
  865.     add sp,4
  866.     mov di, ax        ; Offset in di
  867.  
  868.  
  869. ;
  870. ; Setup control parameters for line draw.
  871. ;
  872.     mov bx,ScanWidth        ; Get BytesPerScanLine
  873. ;
  874.     push dx            ; save for later
  875.    ; added 1/2/92, djl, Adjust line offset value
  876.     mov ax,[bp+10]          ; added to adjust for 15 16 or 24bit modes
  877.     mul BytesPerPixel       ; columns times BytesPerPixel, djl
  878.  
  879.     sub bx,ax
  880.    ;
  881.     mov [bp-10], bx        ; Amount to skip to get to next line
  882.  
  883.     mov ax,[bp+14]          ; Get 8bit pixel value
  884.     mov ah,al        ; ax has duplicated pixel value in al and ah
  885.     pop dx
  886.     even
  887. linestart:
  888.     mov cx,BlockEnd        ; Last point in counter
  889.     sub cx,di               ; cx has number of bytes till block change
  890.                 ;
  891.     mov bx,[bp+10]        ; bx has number of bytes in line
  892.     cmp BitsPerPixel,8      ; If 8bit mode skip counter adjustment, djl
  893.     je lee1                 ; skip if 8bit, djl
  894.     shl bx,1        ; else multiply width of fill by two, djl
  895. lee1:
  896.     dec bx                  ;
  897.     cmp bx,cx               ;
  898.     ja le1
  899.     mov cx,bx        ; Wont need a block change
  900. le1:
  901.     sub bx,cx        ; ax has number of words after block change
  902.     inc cx
  903.     ror cx,1
  904.     ror bx,1
  905. ;
  906. ; Draw the line
  907. ;
  908.  
  909.     even
  910. le4:
  911.     cmp BitsPerPixel,8
  912.     jne drwit
  913.     cld
  914.     rep stosw
  915.     jmp lee4
  916. drwit:
  917. ;    mov cx,[bp+10]
  918. loopit:
  919.     push [bp+18]
  920.     push [bp+16]
  921.     push [bp+14]
  922.     call draw_rgb
  923.     add sp,6
  924.     add di,BytesPerPixel
  925.     loop loopit
  926. lee4:
  927.     cmp di,0        ; Check for exact alignment
  928.     je le5
  929.     cmp bx,0
  930.     je le6
  931.  
  932. ;
  933. ; Handle block change and continue
  934. ;
  935. le5:
  936.     inc dx
  937.     push dx
  938.     call vgablock
  939.     pop dx
  940.  
  941.     cmp bx,0
  942.     je le6
  943.  
  944.     mov cx,bx
  945.     xor bx,bx
  946.     xor di,di
  947.     jmp le4
  948.  
  949. ;
  950. ; Set up for next line
  951. ;
  952. le6:
  953.     dec word ptr [bp+12]
  954.     je le7
  955.  
  956.     add di,[bp-10]        ; Go to start of next line
  957.     jnc linestart
  958.  
  959.     inc dx            ; Bump block pointer
  960.     push dx
  961.     call vgablock
  962.     pop dx
  963.     jmp linestart
  964.  
  965. ;
  966. ; Finish up
  967. ;
  968. le7:
  969.     add sp,2
  970.     Postfix
  971. vgafill endp
  972.  
  973.  
  974. ;
  975. ; Copy a given rectangle into display memory at the specified address.
  976. ; All pixels from the source rectangle are copied with no masking.
  977. ; Coordinates are assumed to be correct and wraparound accounted for by
  978. ; the calling routine. The start address and rectangle width are assumed
  979. ; to be even values to permit faster copy. The passed values may be modified
  980. ; and should not be retained by the calling routine.
  981. ;
  982. ; Parameters:
  983. ;    - Far pointer to source rectangle
  984. ;    - Total width of source memory
  985. ;    - Row for upper left corner
  986. ;    - Column for upper left corner
  987. ;    - Width of rectangle
  988. ;    - Height of rectangle
  989. ;
  990. ; Locals
  991. ;    [bp-10] LineSkip
  992. ;
  993. public vgarect
  994. vgarect proc far
  995.     Prefix
  996.     sub sp,2
  997. ;
  998.     mov    ax,vgadata    ; Load address of data segment
  999.     mov    ds,ax        ; Set DS register
  1000.  
  1001. ;
  1002. ; Load window pointers
  1003. ;
  1004.     mov ax,WinAddr
  1005.     mov es,ax        ; Set ES to point to video memory
  1006.  
  1007.     push [bp+14]
  1008.     push [bp+12]
  1009.     call vgaoffset
  1010.     add sp,4
  1011.  
  1012. ;
  1013. ; Setup control parameters for line draw.
  1014. ;
  1015.     mov di, ax        ; Offset for output memory in di
  1016.  
  1017.     mov bx,ScanWidth
  1018.     sub bx,[bp+16]
  1019.     mov [bp-10], bx        ; Amount to skip to get to next line on output
  1020.  
  1021.     mov bx,[bp+10]
  1022.     sub bx,[bp+16]
  1023.     mov [bp+10], bx        ; Amount to go to next line on input data
  1024.  
  1025.     mov si, [bp+6]        ; Offset for input memory
  1026.  
  1027.     even
  1028. flinestart:
  1029.     mov cx,BlockEnd        ; Last point in counter
  1030.     sub cx,di               ; cx has number of bytes till block change
  1031.  
  1032.     mov bx,[bp+16]        ; bx has number of bytes in line
  1033.     dec bx
  1034.  
  1035.     cmp bx,cx
  1036.     ja lf1
  1037.     mov cx,bx        ; Won't need a block change
  1038. lf1:
  1039.     sub bx,cx        ; bx has number of words after block change
  1040.     inc cx
  1041.     ror cx,1
  1042.     ror bx,1
  1043.  
  1044.  
  1045. ;
  1046. ; Draw the line
  1047. ;
  1048.     even
  1049. lf4:
  1050.     push ds            ; Save segment for vgadata
  1051.     mov ax, [bp+8]
  1052.     mov ds,ax        ; Set segment for source rectangle
  1053.  
  1054.     cld
  1055.     rep movsw
  1056.  
  1057.     pop ds            ; Get segment for vgadata
  1058.     cmp di,0        ; Check for exact alignment
  1059.     je lf5
  1060.     cmp bx,0
  1061.     je lf6
  1062.  
  1063. ;
  1064. ; Handle block change and continue
  1065. ;
  1066. lf5:
  1067.     inc dx
  1068.     push dx
  1069.     call vgablock
  1070.     pop dx
  1071.  
  1072.     cmp bx,0
  1073.     je lf6
  1074.  
  1075.     mov cx,bx
  1076.     xor bx,bx
  1077.     xor di,di
  1078.     jmp lf4
  1079.  
  1080. ;
  1081. ; Set up for next line
  1082. ;
  1083. lf6:
  1084.     dec word ptr [bp+18]
  1085.     je lf7
  1086.  
  1087.     add si,[bp+10]        ; Goto next line in input
  1088.     add di,[bp-10]        ; Go to start of next line on output
  1089.     jnc flinestart
  1090.  
  1091.     inc dx            ; Bump block pointer
  1092.     push dx
  1093.     call vgablock
  1094.     pop dx
  1095.     jmp flinestart
  1096.  
  1097. ;
  1098. ; Finish up
  1099. ;
  1100. lf7:
  1101.     add sp,2
  1102.     Postfix
  1103. vgarect endp
  1104.  
  1105.  
  1106. ;
  1107. ; Copy a given rectangle into display memory at the specified address.
  1108. ; All pixels from the source rectangle are copied unless they have the
  1109. ; value 0. Coordinates are assumed to be correct and wraparound accounted
  1110. ; for by the calling routine. The passed values may be modified
  1111. ; and should not be retained by the calling routine.
  1112. ;
  1113. ; Parameters:
  1114. ;    - Far pointer to source rectangle
  1115. ;    - Total width of source memory
  1116. ;    - Row for upper left corner
  1117. ;    - Column for upper left corner
  1118. ;    - Width of rectangle
  1119. ;    - Height of rectangle
  1120. ;
  1121. ; Locals
  1122. ;    [bp-10] LineSkip
  1123. ;
  1124. public vgarect2
  1125. vgarect2 proc far
  1126.     Prefix
  1127.     sub sp,2
  1128. ;
  1129.     mov    ax,vgadata    ; Load address of data segment
  1130.     mov    ds,ax        ; Set DS register
  1131.  
  1132. ;
  1133. ; Load window pointers
  1134. ;
  1135.     mov ax,WinAddr
  1136.     mov es,ax        ; Set ES to point to video memory
  1137.  
  1138.     push [bp+14]
  1139.     push [bp+12]
  1140.     call vgaoffset
  1141.     add sp,4
  1142.  
  1143. ;
  1144. ; Setup control parameters for line draw.
  1145. ;
  1146.     mov di, ax        ; Offset for output memory in di
  1147.  
  1148.     mov bx,ScanWidth
  1149.     sub bx,[bp+16]
  1150.     mov [bp-10], bx        ; Amount to skip to get to next line on output
  1151.  
  1152.     mov bx,[bp+10]
  1153.     sub bx,[bp+16]
  1154.     mov [bp+10], bx        ; Amount to go to next line on input data
  1155.  
  1156.     mov si, [bp+6]        ; Offset for input memory
  1157.  
  1158.     even
  1159. glinestart:
  1160.     mov cx,BlockEnd        ; Last point in counter
  1161.     sub cx,di               ; cx has number of bytes till block change
  1162.  
  1163.     mov bx,[bp+16]        ; bx has number of bytes in line
  1164.     dec bx
  1165.  
  1166.     cmp bx,cx
  1167.     ja lg1
  1168.     mov cx,bx        ; Won't need a block change
  1169. lg1:
  1170.     sub bx,cx        ; bx has number of bytes after block change
  1171.     inc cx
  1172.  
  1173. ;
  1174. ; Draw the line
  1175. ;
  1176.     even
  1177. lg4:
  1178.     push ds            ; Save segment for vgadata
  1179.     mov ax, [bp+8]
  1180.     mov ds,ax        ; Set segment for source rectangle
  1181.  
  1182.     cld
  1183. lg8:    lodsb
  1184.     or al,al        ; Test for 0
  1185.     jz lg9
  1186.     stosb
  1187.     jmp lg10
  1188. lg9:    inc di
  1189. lg10:    loop lg8
  1190.  
  1191.     pop ds            ; Get segment for vgadata
  1192.     cmp di,0        ; Check for exact alignment
  1193.     je lg5
  1194.     cmp bx,0
  1195.     je lg6
  1196.  
  1197. ;
  1198. ; Handle block change and continue
  1199. ;
  1200. lg5:
  1201.     inc dx
  1202.     push dx
  1203.     call vgablock
  1204.     pop dx
  1205.  
  1206.     cmp bx,0
  1207.     je lg6
  1208.  
  1209.     mov cx,bx
  1210.     xor bx,bx
  1211.     xor di,di
  1212.     jmp lg4
  1213.  
  1214. ;
  1215. ; Set up for next line
  1216. ;
  1217. lg6:
  1218.     dec word ptr [bp+18]
  1219.     je lg7
  1220.  
  1221.     add si,[bp+10]        ; Goto next line in input
  1222.     add di,[bp-10]        ; Go to start of next line on output
  1223.     jnc glinestart
  1224.  
  1225.     inc dx            ; Bump block pointer
  1226.     push dx
  1227.     call vgablock
  1228.     pop dx
  1229.     jmp glinestart
  1230.  
  1231. ;
  1232. ; Finish up
  1233. ;
  1234. lg7:
  1235.     add sp,2
  1236.     Postfix
  1237. vgarect2 endp
  1238.  
  1239.  
  1240.  
  1241. ;
  1242. ; Handle mouse and keyboard I/O
  1243. ; If a keyboard key or mouse button is pressed, return a value indicating
  1244. ; what was pressed. Also, maintain the mouse position values for external
  1245. ; reference.
  1246. ;
  1247. vgagetbutton proc far
  1248.     mov ah,0
  1249.     int 16h
  1250.     xor ah,ah               ; Don't want scan code
  1251.     ret
  1252. vgagetbutton endp
  1253.  
  1254.  
  1255.  
  1256. ;
  1257. ; Display a text string at a given location
  1258. ;
  1259. ; Parameters:
  1260. ;    - row
  1261. ;    - column
  1262. ;    - character string
  1263. ;    - pixel value for foreground
  1264. ;
  1265. vgatext proc far
  1266.     ret
  1267. vgatext endp
  1268.  
  1269.  
  1270. vgacode    ends
  1271.     end
  1272.