home *** CD-ROM | disk | FTP | other *** search
- ; VGAMOIRE.COM
-
- ; Structured pattern generator to show off the undocumented
- ; 320x400 256 color mode of the IBM VGA as revealed by
- ; Michael Abrash in his "On Graphics" column in the
- ; January/February 1989 issue of Programmer's Journal, Volume 7.1
-
-
- VGA_SEGMENT equ 0A000h
- SC_INDEX equ 3C4h
- GC_INDEX equ 3CEh
- CRTC_INDEX equ 3D4h
- MAP_MASK equ 2
- MEMORY_MODE equ 4
- MAX_SCAN_LINE equ 9
- START_ADDRESS_HIGH equ 0Ch
- UNDERLINE equ 14h
- MODE_CONTROL equ 17h
- READ_MAP equ 4
- GRAPHICS_MODE equ 5
- MISCELLANEOUS equ 6
- SCREEN_WIDTH equ 320
- SCREEN_HEIGHT equ 400
-
- tab equ 9
- lf equ 10
- cr equ 13
-
-
- CONSTANT_TO_INDEXED_REGISTER macro ADDRESS, INDEX, VALUE
- mov dx, ADDRESS
- mov ax, (VALUE shl 8) + INDEX
- out dx, ax
- endm
-
- code segment
- org 100h
- assume cs:code, ds:code
-
-
- Begin:
-
- push cs
- pop ds
-
- mov ax, VGA_SEGMENT
- mov es, ax
-
- call Set320x400Mode
-
- mov ah, 2Ch
- int 21h
- mov Random, dx
-
- mov si, 256 ; ColorCount
-
- call Randy
- mov bp, ax
- call DoCircles
-
- MainLoop:
- call MakeRandomPalette
-
- cmp PageNo, 0
- je SetPage1
- mov ax, 0A800h
- mov es, ax
- CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,0
- mov PageNo, 0
- jmp Start
- SetPage1:
- mov ax, 0A000h
- mov es, ax
- CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,80h
- mov PageNo, 1
-
- Start:
- call Randy
- and ax, 0003h
- cmp al, 0
- je Circ
- cmp al, 1
- je Sqar
- cmp al, 2
- je TiltCirc
- jmp TiltSqar
-
- Circ:
- call Randy
- inc ax
- mov bp, ax
- call DoCircles
- jmp CheckKey
-
- Sqar:
- call Randy
- inc ax
- mov bp, ax
- call DoSquares
- jmp CheckKey
-
- TiltCirc:
- call Randy
- inc ax
- mov bp, ax
- call DoTiltCircles
- jmp CheckKey
-
- TiltSqar:
- call Randy
- inc ax
- mov bp, ax
- call DoTiltSquares
-
- CheckKey:
- mov ah, 0Bh
- int 21h
- cmp al, 0
- jne GetOut
- jmp MainLoop
-
- GetOut:
- mov ax, 0003h ; Back to Text Mode
- int 10h
-
- mov ax, 4C00h
- int 21h
-
- PageNo dw 1
-
-
- DoCircles proc near
-
- mov bl, 00010001b ; Plane Mask bit
- mov di, 0 ; Video memory pointer
-
- mov cx, 0 ; For Y := 0 to 399 do
- ForYCirc:
- push cx
- mov cx, 0 ; For X := 0 to 319 do
- ForXCirc:
- mov ax, bp ; Get IterateCnt
- mul cx ; DX:AX := IterateCnt * X
- add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
-
- mov dx, SC_INDEX ; Select the correct plane
- mov ah, bl
- mov al, MAP_MASK
- out dx, ax
-
- mov ax, si ; Poke Color
- mov byte ptr es:[di], al
-
- rol bl, 1 ; Rotate for next plane
- cmp bl, 00010001b ; Did we rotate four times?
- jne DoNextXCirc ; If not then do the next pixel
- inc di ; Otherwise bump the Video MemPtr
-
- DoNextXCirc:
- inc cx ; Next X
- cmp cx, 320
- jl ForXCirc
-
- pop cx
-
- mov ax, bp ; Get IterateCnt
- mul cx ; DX:AX := IterateCnt * Y
- add si, ax ; ColorCount := ColorCount + (IterateCnt * Y)
-
- inc cx ; Next Y
- cmp cx, 400
- jl ForYCirc
-
- ret
-
- DoCircles endp
-
-
- DoTiltCircles proc near
-
- mov bl, 00010001b ; Plane Mask bit
- mov di, 0 ; Video memory pointer
-
- mov cx, 0 ; For Y := 0 to 399 do
- ForYTiltCirc:
- push cx
- mov cx, 0 ; For X := 0 to 319 do
- ForXTiltCirc:
- mov ax, bp ; Get IterateCnt
- mul cx ; DX:AX := IterateCnt * X
- add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
-
- mov dx, SC_INDEX ; Select the correct plane
- mov ah, bl
- mov al, MAP_MASK
- out dx, ax
-
- mov ax, si ; Poke Color
- mov byte ptr es:[di], al
-
- rol bl, 1 ; Rotate for next plane
- cmp bl, 00010001b ; Did we rotate four times?
- jne DoNextXTiltCirc ; If not then do the next pixel
- inc di ; Otherwise bump the Video MemPtr
-
- DoNextXTiltCirc:
- inc cx ; Next X
- cmp cx, 320
- jl ForXTiltCirc
-
- pop cx
-
- mov ax, bp ; Get IterateCnt
- mul cx ; DX:AX := IterateCnt * Y
- sub si, ax ; ColorCount := ColorCount - (IterateCnt * Y)
-
- inc cx ; Next Y
- cmp cx, 400
- jl ForYTiltCirc
-
- ret
-
- DoTiltCircles endp
-
-
- DoSquares proc near
-
- mov bl, 00010001b ; Plane Mask bit
- mov di, 0 ; Video memory pointer
-
- mov cx, 0 ; For Y := 0 to 399 do
- ForYSqr:
- mov CurrY, cx
- push cx
- mov cx, 0 ; For X := 0 to 319 do
- ForXSqr:
- mov CurrX, cx
- mov ax, bp ; Get IterateCnt
- mov dx, CurrY ; Get current Y
- mul dx ; DX:AX := IterateCnt * Y
- add si, ax ; ColorCount := ColorCount + (IterateCnt * Y)
-
- mov dx, SC_INDEX ; Select the correct plane
- mov ah, bl
- mov al, MAP_MASK
- out dx, ax
-
- mov ax, si ; Poke Color
- mov byte ptr es:[di], al
-
- rol bl, 1 ; Rotate for next plane
- cmp bl, 00010001b ; Did we rotate four times?
- jne DoNextXSqr ; If not then do the next pixel
- inc di ; Otherwise bump the Video MemPtr
-
- DoNextXSqr:
- inc cx ; Next X
- cmp cx, 320
- jl ForXSqr
-
- pop cx
-
- mov ax, bp ; Get IterateCnt
- mov dx, CurrX ; Get current X
- mul dx ; DX:AX := IterateCnt * X
- add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
-
- inc cx ; Next Y
- cmp cx, 400
- jl ForYSqr
-
- ret
-
- CurrX dw (?)
- CurrY dw (?)
-
- DoSquares endp
-
-
- DoTiltSquares proc near
-
- mov bl, 00010001b ; Plane Mask bit
- mov di, 0 ; Video memory pointer
-
- mov cx, 0 ; For Y := 0 to 399 do
- ForYTiltSqr:
- mov CurrTiltY, cx
- push cx
- mov cx, 0 ; For X := 0 to 319 do
- ForXTiltSqr:
- mov CurrTiltX, cx
- mov ax, bp ; Get IterateCnt
- mov dx, CurrTiltY ; Get current Y
- mul dx ; DX:AX := IterateCnt * Y
- add si, ax ; ColorCount := ColorCount + (IterateCnt * Y)
-
- mov dx, SC_INDEX ; Select the correct plane
- mov ah, bl
- mov al, MAP_MASK
- out dx, ax
-
- mov ax, si ; Poke Color
- mov byte ptr es:[di], al
-
- rol bl, 1 ; Rotate for next plane
- cmp bl, 00010001b ; Did we rotate four times?
- jne DoNextXTiltSqr ; If not then do the next pixel
- inc di ; Otherwise bump the Video MemPtr
-
- DoNextXTiltSqr:
- inc cx ; Next X
- cmp cx, 320
- jl ForXTiltSqr
-
- pop cx
-
- mov ax, bp ; Get IterateCnt
- mov dx, CurrTiltX ; Get current X
- mul dx ; DX:AX := IterateCnt * X
- add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
-
- inc cx ; Next Y
- cmp cx, 400
- jl ForYTiltSqr
-
- ret
-
- CurrTiltX dw (?)
- CurrTiltY dw (?)
-
- DoTiltSquares endp
-
-
- Randy proc near
-
- ; Returns a pseudo random integer in AX
-
- GetTime:
- mov ah, 2Ch
- int 21h
-
- mov ax, Random
- add ax, 13
- mul dx
- add dx, 23
- mul dx
- shr dx, 1
- shr dx, 1
- shr dx, 1
- add ax, dx
- and ax, 7FFFh
- mov Random, ax
-
- ret
-
- Random dw (?)
-
- Randy endp
-
-
- MakeRandomPalette proc near
-
- call Randy
- mov byte ptr RED, al
- call Randy
- mov byte ptr GREEN, al
- call Randy
- mov byte ptr BLUE, al
-
- mov cx, 0
- NextPal:
- mov al, cl
- mov dx, 03C8h ; Set Write PEL Address
- out dx, al
- inc dx
-
- mov al, byte ptr RED ; Get RED
- and al, 3Fh
- out dx, al
-
- mov al, byte ptr GREEN ; Get GREEN
- and al, 3Fh
- out dx, al
-
- mov al, byte ptr BLUE ; Get BLUE
- and al, 3Fh
- out dx, al
-
- inc byte ptr RED
- inc byte ptr GREEN
- inc byte ptr BLUE
- inc cx
- cmp cx, 256
- jl NextPal
-
- ret
-
- RED db (?)
- GREEN db (?)
- BLUE db (?)
-
- MakeRandomPalette endp
-
-
- Set320x400Mode proc near
-
- mov ax, 0013h
- int 10h
-
- mov dx, SC_INDEX
- mov al, MEMORY_MODE
- out dx, al
- inc dx
- in al, dx
- and al, NOT 08h
- or al, 04h
- out dx, al
- mov dx, GC_INDEX
- mov al, GRAPHICS_MODE
- out dx, al
- inc dx
- in al, dx
- and al, NOT 10h
- out dx, al
- dec dx
- mov al, MISCELLANEOUS
- out dx, al
- inc dx
- in al, dx
- and al, NOT 02h
- out dx, al
-
- CONSTANT_TO_INDEXED_REGISTER SC_INDEX, MAP_MASK, 0Fh
-
- mov ax, VGA_SEGMENT
- mov es, ax
- sub di, di
- mov ax, di
- mov cx, 8000h
- rep stosw
-
- mov dx, CRTC_INDEX
- mov al, MAX_SCAN_LINE
- out dx, al
- inc dx
- in al, dx
- and al, NOT 1Fh
- out dx, al
- dec dx
-
- mov al, UNDERLINE
- out dx, al
- inc dx
- in al, dx
- and al, NOT 40h
- out dx, al
- dec dx
- mov al, MODE_CONTROL
- out dx, al
- inc dx
- in al, dx
- or al, 40h
- out dx, al
-
- ret
-
- Set320x400Mode endp
-
-
- code ends
-
- End Begin