home *** CD-ROM | disk | FTP | other *** search
/ The Party 1994: Try This At Home / disk_image.bin / source / gallery / a_vga.asm < prev    next >
Assembly Source File  |  1994-06-14  |  14KB  |  611 lines

  1. ;  A_VGA.ASM -- graphics routines  // A.R-M. 7/93
  2.  
  3.         IDEAL
  4.         MODEL Compact, Pascal
  5.         Radix 16
  6.         P286
  7.  
  8.         FARDATA S_Finale
  9.  
  10. EXTRN W_Finale : Byte
  11.  
  12.         DATASEG
  13.  
  14. PUBLIC CurrentPage, CurrentBase
  15.  
  16. PageOffsets    DW   0, 16000d, 32000d, 48000d
  17.                                 ; start offsets for pages 0,1,2,3
  18.                                 ; (only need 0,1,2 for animation)
  19.  
  20. CurrentBase    DW   0
  21. CurrentPage    DW   0
  22.  
  23.         CODESEG
  24.  
  25. PUBLIC RasterOff         ; disables raster
  26. PUBLIC RasterOn          ; enables raster
  27. PUBLIC InitPageMode      ; Init VGA 13h mode & tweak it for 4 planes
  28. PUBLIC SetActivePage     ; (pageno:byte) Set CurrentPage value
  29. PUBLIC SetViewPage       ; (pageno:byte) Set display start addr
  30.  
  31. PUBLIC BlankPage         ; Sets whole page to 0
  32.  
  33. PUBLIC MapColumn         ; (X,Y:Pointer; X0,X1,Y0,Y1:Word; Ofs:Word)
  34.                          ; Map X[X0..X1] onto Y[Y0..Y1,Ofs]
  35.  
  36. PUBLIC FillColumn        ; (Y:Pointer; Y0,Y1:Word; Ofs:Word; C:Byte)
  37.                          ; Fills Y[Y0..Y1,Ofs] with C
  38.  
  39. PUBLIC PlotFullScreen    ; (Y:Pointer; Y0,Y1,Ofs,X:Word) Plots stored screen image
  40.  
  41. PUBLIC FilterColumn      ; (Y:Pointer; Y0,Y1:Word; Ofs:Word; Filt:Byte)
  42.                          ; adds Filt to lower nibble of ea. byte in
  43.                          ; ScreenColumns[Y0..Y1,Ofs]
  44.  
  45. PUBLIC DumpColumns       ; (Columns:pointer;ScreenOffset,LoY,HiY,ColumnMask : Word)
  46.                          ; Dump ScreenColumns to screen
  47.  
  48. ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  49.  
  50. PUBLIC PonPaletaInicial
  51. PUBLIC PonPaletaFinal
  52.  
  53. ; Las dos paletas
  54.  
  55. PALETA_INICIAL:
  56.         DB      0,   0,   0
  57.         DB     30,   0,   0
  58.         DB     30,   0,   0
  59.         DB     30,   0,   0
  60.         DB     30,   0,   0
  61.         DB     30,   0,   0
  62.         DB     30,   0,   0
  63.         DB     30,   0,   0
  64.         DB     30,   0,   0
  65.         DB     30,   0,   0
  66.         DB     30,   0,   0
  67.         DB     30,   0,   0
  68.         DB     30,   0,   0
  69.         DB     30,   0,   0
  70.         DB     30,   0,   0
  71.         DB     30,   0,   0
  72.  
  73. PALETA_FINAL:
  74.         DB      0,   0,   0
  75.         DB      0,  30,   0
  76.         DB      0,  30,   0
  77.         DB      0,  30,   0
  78.         DB      0,  30,   0
  79.         DB      0,  30,   0
  80.         DB      0,  30,   0
  81.         DB      0,  30,   0
  82.         DB      0,  30,   0
  83.         DB      0,  30,   0
  84.         DB      0,  30,   0
  85.         DB      0,  30,   0
  86.         DB      0,  30,   0
  87.         DB      0,  30,   0
  88.         DB      0,  30,   0
  89.         DB      0,  30,   0
  90.  
  91. MACRO   PonPaleta  nombre
  92.         LOCAL @@1
  93.  
  94.         mov bl,0
  95.         mov di, offset nombre
  96.  
  97.         mov cx, 16d
  98. @@1:
  99.         mov dx, 3c8h
  100.         mov al,bl
  101.         out dx, al
  102.         inc dx
  103.         mov al, [cs:(di+0)]
  104.         out dx,al
  105.         mov al, [cs:(di+1)]
  106.         out dx,al
  107.         mov al, [cs:(di+2)]
  108.         out dx,al
  109.  
  110.         add bl,16d
  111.         add di,3
  112.         loop @@1
  113. ENDM
  114.  
  115.  
  116.         PROC PonPaletaInicial NEAR
  117.           PonPaleta PALETA_INICIAL
  118.         ret
  119.         ENDP
  120.  
  121.  
  122.         PROC PonPaletaFinal NEAR
  123.           PonPaleta PALETA_FINAL
  124.         ret
  125.         ENDP
  126.  
  127.  
  128.  
  129. ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  130.  
  131. ; // RGB Palette  (not worth wasting DS space for this)
  132.  
  133. RGBPalette:
  134.         RADIX 10
  135.         INCLUDE "data\PALETTE.inc"
  136.         RADIX 16
  137.  
  138. ; // RasterOff
  139.  
  140.       PROC RasterOff NEAR
  141.       USES ax, dx
  142.  
  143.           mov dx,3c4
  144.           mov al,01
  145.           out dx,al
  146.           nop
  147.           inc dx
  148.           in al,dx
  149.           or al,00100000b   ; screen inhibit bit 5 on
  150.           out dx,al
  151.  
  152.           dec dx
  153.           mov al,2
  154.           out dx,al          ; always leave idx reg prg'd to 2!
  155.       ret
  156.       ENDP
  157.  
  158.  
  159. ; // RasterOn
  160.  
  161.       PROC RasterOn NEAR
  162.       USES ax, dx
  163.  
  164.           mov dx,3c4
  165.           mov al,01
  166.           out dx,al
  167.           nop
  168.           inc dx
  169.           in al,dx
  170.           and al,11011111b   ; screen inhibit bit 5 on
  171.           out dx,al
  172.  
  173.           dec dx
  174.           mov al,2
  175.           out dx,al          ; leave idx reg prg'd to 2
  176.       ret
  177.       ENDP
  178.  
  179.  
  180. ; // InitPageMode
  181.  
  182. ; Kind'a copied this little routine from Wolfenstein 3D... you know?  O:-)
  183.  
  184.       PROC InitPageMode NEAR
  185. P386
  186.       USES eax, cx, dx, si
  187.  
  188. ; Assumes VGA is already in standard 320x200x256 mode 13h
  189. ; (initialized by BIOS call AX=0013/INT 10) when called.
  190.  
  191.         mov dx, 3c4
  192.         mov al, 4              ; Seq mem mode reg
  193.         out dx, al
  194.  
  195.         mov dx, 3c5
  196.         in al, dx
  197.         and al, 11110111b
  198.         mov dx, 3c5            ; <- extra ops like this one slow down
  199.         out dx, al             ;    port writes, just to be on the
  200.                                ;    safe side...
  201.  
  202.         mov dx, 3d4
  203.         mov al, 14             ; UL reg
  204.         out dx, al
  205.  
  206.         mov dx, 3d5
  207.         in al, dx
  208.         and al, 10111111b
  209.         mov dx, 3d5
  210.         out dx, al
  211.  
  212.         mov dx, 3d4
  213.         mov al, 17             ; CRTC mode ctrl reg.
  214.         out dx, al
  215.         mov dx, 3d5
  216.         in al, dx
  217.         or al, 01000000b
  218.         mov dx, 3d5
  219.         out dx, al
  220.  
  221.         mov dx, 3c4
  222.         mov al, 2
  223.         out dx, al             ; set index to map mask reg
  224.  
  225. ; Load color palette
  226.  
  227.         push ds
  228.         mov ax, seg RGBPalette
  229.         mov ds, ax
  230.         mov si, offset RGBPalette
  231.  
  232.         xor al, al
  233.         mov dx, 3c8
  234.         out dx, al
  235.         inc dx
  236.         mov cx, 300
  237.         cld
  238.         rep outsb
  239.         pop ds
  240.  
  241. ; / JCAB: si tocas algo por aquí, no te olvides de dejar el
  242. ;/        índice en 3c4 programado a 2 antes de salir!! :-)
  243.  
  244.         ret
  245. P286
  246.       ENDP
  247.  
  248.  
  249. ; // SetActivePage
  250.  
  251.       PROC SetActivePage NEAR
  252.       ARG pageNo : Byte
  253.       USES ax, bx
  254.  
  255.         mov bl, [pageNo]
  256.         xor bh,bh
  257.         mov [CurrentPage], bx
  258.         mov dl, bl
  259.         shl bl,1
  260.         xor bh,bh
  261.         mov ax, [PageOffsets+bx]
  262.         mov [CurrentBase], ax         ; Update current base addr
  263.  
  264.         ret
  265.       ENDP
  266.  
  267.  
  268. ; // SetViewPage
  269.  
  270.       PROC SetViewPage NEAR
  271.       ARG pageNo : Byte
  272.       USES ax, bx, dx
  273.  
  274.         ; wait for next end of VR
  275.  
  276.         mov dx, 3da
  277. @@waitVR:
  278.         in al, dx
  279.         test al,8
  280.         jz @@waitVR    ; wait till in VR
  281. @@whileVR:
  282.         in al, dx
  283.         test al,8
  284.         jnz @@whileVR   ; wait till end of VR
  285.  
  286.         mov bl, [pageNo]
  287.         shl bl,1
  288.         xor bh,bh
  289.         mov bx, [PageOffsets+bx]
  290.  
  291.         mov dx, 3d4
  292.         mov al, 0c
  293.         mov ah, bh
  294.         cli   ; This should stop some of those sporadic screen hops...
  295.         out dx, ax       ; SEND HIGH BYTE
  296.         mov al, 0dh      ; whoops! "0d" means "0 decimal"!
  297.         mov ah, bl
  298.         out dx, ax       ; SEND LOW BYTE
  299.         sti
  300.         ret
  301.       ENDP
  302.  
  303.  
  304. ; // BlankPage
  305.  
  306.       PROC BlankPage NEAR
  307. P386
  308.       USES es, eax, dx, ecx, edi
  309.  
  310.         mov dx, 3c5
  311.         mov al, 0f
  312.         out dx, al
  313.  
  314.         mov ax, 0a000
  315.         mov es, ax
  316.  
  317.         movzx edi, [word ptr CurrentBase]
  318.  
  319.         mov ecx, 4000d
  320.         xor eax,eax
  321.         cld
  322.         rep stosd
  323.  
  324.         ret
  325. P286
  326.       ENDP
  327.  
  328.  
  329. ; // Map Column
  330.  
  331.       PROC MapColumn NEAR
  332.       ARG X : FAR PTR BYTE, Y : FAR PTR BYTE, \
  333.           X0:Word, X1:Word, Y0:Word, Y1:Word, \
  334.           Ofs : Word
  335.         pusha
  336.         push ds
  337.         push es
  338.  
  339.         les di, [Y]
  340.         add di, [Ofs]
  341.         mov ax, [Y0]
  342.         shl ax,2
  343.         add di,ax        ; es:di -> destination
  344.  
  345.         lds si, [X]
  346.         add si, [X0]     ; ds:si -> source
  347.  
  348.         mov cx, [Y1]
  349.         sub cx, [Y0]     ; cx = Y1-Y0 = dY
  350.         mov bx, [X1]
  351.         sub bx, [X0]     ; bx = X1-X0 = dX
  352.         cmp cx, bx       ; Compare dX w/ dY, and enter the proper...
  353.         jb  @@horizontal ;  ...Bresenham algorithm (hor or ver line)
  354.  
  355. ; ////// dX <= dY - "vertical line" //////
  356.  
  357. @@vertical:              ; use up some symbol space... hey, it's free!  ;-)
  358.  
  359.         shl bx,1         ; bx = 2dX = increment for d<0
  360.         mov dx, bx
  361.         sub dx, cx       ; dx = 2dX-dY = initial value for d
  362.         mov bp, dx       ; (running out of regs here...)
  363.         sub bp, cx       ; bp = 2dX-2dY = 2(dX-dY) = inc for d>=0
  364.                          ; cx = dY (from before) = no. of steps
  365.  
  366.         mov al, [ds:si]  ; get value from X
  367. @@VerLoop:
  368.         mov [es:di], al
  369.         add di,4
  370.         or dx, dx
  371.         jns @@V1         ; jmp if d>=0  (last add dx,??? set SF)
  372.  
  373.         add dx, bx       ; if d<0, update d...
  374.         loop @@VerLoop   ; ...and keep looping
  375.         jmp @@V2
  376. @@V1:                    ; if d>=0, step X
  377.         mov al, [ds:si]
  378.         inc si
  379.         add dx, bp       ;   increment d
  380.         loop @@VerLoop
  381. @@V2:
  382.         mov [es:di], al  ; draw that last pixel!
  383.         jmp @@leave
  384.  
  385. ; ////// dX > dY - "horizontal line" //////
  386.  
  387. @@horizontal:
  388.         xchg bx, cx      ; cx=dX & bx=dY now
  389.         shl bx,1         ; bx = 2dY = increment for d<0
  390.         mov dx, bx
  391.         sub dx, cx       ; dx = 2dY - dX = initial d
  392.         mov bp, dx
  393.         sub bp, cx       ; bp = 2dY - 2dX = 2(dY-dX) = inc for d>=0
  394.                          ; cx = dX = no. pts.
  395.         or dx,dx
  396.  
  397. @@HorLoop:
  398.         inc si           ; inc source ptr
  399.         or dx, dx
  400.         jns @@H1
  401.  
  402.         add dx, bx       ; d<0, update d & loop
  403.         loop @@HorLoop
  404.         jmp @@H2
  405. @@H1:
  406.         mov al,[ds:si]
  407.         mov [es:di], al  ; copy src to destination
  408.         add di,4
  409.         add dx, bp
  410.         loop @@HorLoop
  411. @@H2:
  412.         mov [es:di], al ; copy the last pixel
  413.  
  414. @@leave:
  415.         pop es
  416.         pop ds
  417.         popa
  418.         ret
  419.       ENDP
  420.  
  421.  
  422. ; // Fill Column
  423.  
  424.       PROC FillColumn NEAR
  425.       ARG Y : FAR PTR Byte, Y0:Word, Y1:Word, Ofs:Word, C:Byte
  426.         pusha
  427.         push ds
  428.  
  429.         lds di, [Y]
  430.         add di, [Ofs]
  431.         mov ax, [Y0]
  432.         mov cx, ax
  433.         shl ax,2
  434.         add di, ax
  435.         sub cx, [Y1]
  436.         neg cx
  437.         inc cx
  438.  
  439.         mov al, [C]
  440. @@fill:
  441.         mov [ds:di], al
  442.         add di,4
  443.         loop @@fill
  444.  
  445.         pop ds
  446.         popa
  447.         ret
  448.       ENDP
  449.  
  450.  
  451. ; // PlotFullScreen
  452.  
  453.       PROC PlotFullScreen NEAR
  454.       ARG Y : FAR PTR Byte, Y0:Word, Y1:Word, Ofs:Word, X:Word
  455.         pusha
  456.         push ds
  457.         push es
  458.  
  459.         lds di, [Y]
  460.         add di, [Ofs]
  461.         mov ax, [Y0]
  462.         mov cx, ax
  463.         shl ax,2
  464.         add di, ax
  465.         sub cx, [Y1]
  466.         neg cx
  467.         inc cx
  468.  
  469.         mov ax, seg w_Finale
  470.         mov es,ax
  471.         mov si, offset w_Finale
  472.         mov ax, [Y0]
  473.         mov bh,al
  474.         xor bl,bl
  475.         shl ax,6
  476.         add ax, bx
  477.  
  478.         add ax,[X]
  479. ;        add ax,320d
  480. ;        sub ax,[X] ;*
  481.         add si,ax
  482.  
  483. @@copy:
  484.         mov al,[es:si]
  485.         add si,320d
  486.         mov [ds:di], al
  487.         add di,4
  488.         loop @@copy
  489.  
  490.         pop es
  491.         pop ds
  492.         popa
  493.         ret
  494.       ENDP
  495.  
  496.  
  497. ; // Filter Column
  498.  
  499.       PROC FilterColumn NEAR
  500.       ARG Y : FAR PTR Byte, Y0:Word, Y1:Word, Ofs:Word, Filt:Byte
  501.         pusha
  502.         push ds
  503.  
  504.         lds di, [Y]
  505.         add di, [Ofs]
  506.         mov ax, [Y0]
  507.         mov cx, ax
  508.         shl ax,2
  509.         add di, ax
  510.         sub cx, [Y1]
  511.         neg cx
  512.         inc cx
  513.  
  514.         mov dl, [Filt]
  515. @@FilterLoop:
  516.         mov al, [di]
  517.         mov bh, al             ; al = bh = color byte
  518.         and al, 00001111b      ; lower nibble: lightness bits
  519.         sub al, dl             ; darken color
  520.         jnle @@1               ; below black? (<=0 ?)
  521.         mov al,1               ; if so then make lightness=0
  522. @@1:    and bh,11110000b
  523.         add al, bh             ; put lightness nibble back in place
  524.         mov [di],al            ; save, & do next
  525.         add di,4
  526.         loop @@FilterLoop
  527.  
  528.         pop ds
  529.         popa
  530.         ret
  531.       ENDP
  532.  
  533.  
  534. ; // DumpColumns
  535.  
  536. ;     ...as fast as you can, that is  :-(
  537.  
  538.       PROC DumpColumns NEAR
  539.       ARG Columns : FAR PTR Byte, \
  540.           ScreenOffset : Word, Y0 : Word, Y1 : Word, \
  541.           ColumnMask : Word
  542.         pusha
  543.         push ds
  544.         push es
  545.  
  546.         mov dx, 3c5
  547.         mov ax, [ColumnMask]
  548.         out dx, al              ; set mask
  549.  
  550.         mov ax, 0a000
  551.         mov es, ax
  552.         mov di, [CurrentBase]
  553.         add di, [ScreenOffset]        ; es:di -> screen start addr
  554.  
  555.         mov ax, [Y0]
  556.         shl ax,4
  557.         add di, ax
  558.         shl ax,2
  559.         add di, ax                    ; ax=ax+80*Y0
  560.  
  561.         lds si, [Columns]             ; ds:si -> columns
  562.         mov ax, [Y0]
  563.         shl ax,2
  564.         add si, ax                    ; +4*Y0
  565.  
  566.         mov ax, 199d
  567.         add ax, [Y0]
  568.         sub ax, [Y1]           ; ax = 200-(Y1-Y0+1) = no.blocks to skip
  569.         mov bx, ax              ; bx = ax
  570.         shl ax,1
  571.         add bx, ax              ;    + 2*ax
  572.         shl ax,2                ;    + 8*ax
  573.         add bx, ax              ; bx = #blocks * 11 bytes/block
  574.  
  575.         add bx, offset ColumnEntryPoint        ; bx = entry address
  576.  
  577.         jmp bx
  578.  
  579. P386
  580.  
  581. ; Copies by dwords. Actually, I think it doesn't make much of a
  582. ; difference (it's the VGA slowing us down, not the CPU), and, besides,
  583. ; dumping by bytes would leave my hands free to improve the renderer -?
  584.  
  585. ColumnEntryPoint:
  586.         ROW = 0
  587.         REPT 200d
  588.           HERE = $
  589.           ROW = ROW + 1
  590.           mov eax, [si+4*(200d-ROW)]
  591.           mov [es:di+80d*(200d-ROW)], eax
  592.           BLOCKSIZE = $-HERE
  593.           IF BLOCKSIZE GT 11d
  594.  
  595.              Display "Block is > 11d bytes long!"
  596.              ERR
  597.           ENDIF
  598.           REPT 11d-BLOCKSIZE   ;; fill in so each block is
  599.             cld                ;; exactly 11d bytes long
  600.           ENDM                 ;; (that's the worst-case size
  601.         ENDM                   ;; of the 2 ops above)
  602. P286
  603.         pop es
  604.         pop ds
  605.         popa
  606.         ret
  607.       ENDP
  608.  
  609.  
  610.         END
  611.