DOSSEG .286 .MODEL SMALL .STACK 200h .CODE ASSUME CS:@code, DS:@code ;====- DATA -===== VgaSeg dw 0a000h ;segment for VGA SegCode dw ? Numcolors dw 200 ;# of colors to rotate NumColors3 dw 200*3 ;# of colors*3 StartAt db 1 ;color to start rotate at PalIndex dw 0 ;color to start write at- increased every time ;to produce the rotating effect PalIndexVel dw 1 ;amount PalIndex Changes for each screen Palette LABEL BYTE i=0 REPT 63 db i,i/2,i/3 ;63 increasing colors i=i+1 ENDM i=63 REPT 63 db i,i/2,i/3 ;63 decreasing colors i=i-1 ENDM i=0 REPT 32 db i/2,i/3,i ;32 incr colors i=i+2 ENDM i=63 REPT 32 db i/2,i/3,i ;32 decr colors i=i-2 ENDM db 10*3 dup (0) ;buffer out to 200 colors total ;========- SubRoutines -======== WriteLines PROC NEAR pusha mov es,cs:[VgaSeg] mov di,10*320 mov al,200-20 WrLiLoop: mov ah,al mov cx,160 rep stosw dec al jne WrLiLoop popa ret WriteLines ENDP RotatePalette PROC NEAR pusha call WritePalette mov ds,cs:[SegCode] mov ax,[PalIndexVel] add [PalIndex],ax ;change the palette index mov ax,[PalIndex] ;are we over the number of colors? mov bx,[NumColors] cmp ax,bx jl NotTooHigh sub [PalIndex],bx ;add [Numcolors] to the index jmp NotTooLow NotTooHigh: cmp ax,0 jge NotTooLow add [PalIndex],bx ;subtract [Numcolors] to the index NotTooLow: popa ret RotatePalette ENDP WritePalette PROC NEAR mov ds,cs:[SegCode] cld mov dx,[PalIndex] mov bx,dx add bx,bx ;This just multiplies add bx,dx ;bx by three ( bx = bx + 2*bx ) mov si,offset Palette mov dx,03c8h mov ax,[PalIndex] add al,[StartAt] out dx,al ;start writing at [PalIndex]+[StartAt] inc dx mov cx,[NumColors3] sub cx,bx ;get the number of colors to write rep outsb mov al,[StartAt] dec dx ;point to palette index out dx,al ;out the number we want to start writing at inc dx mov cx,bx ;get the number of colors to write rep outsb ;note that SI is already where we want it ret WritePalette ENDP ;well, that's all there is to it ;====- CODE -==== Start: mov ax,cs mov ds,ax mov es,ax mov [SegCode],ax mov ax,0013h ;changes to 320x200x256 graphics mode int 10h call WriteLines MainLoop: mov dx,3dah VRT: in al,dx test al,8 jnz VRT ;wait until Verticle Retrace starts call RotatePalette mov dx,3dah NoVRT: in al,dx test al,8 jz NoVRT ;wait until Verticle Retrace ends ;so that we dont rotate more than once a frame mov ah,1 ;wait for a keypress int 16h jz MainLoop mov ah,0 int 16h ;get the key neg cs:[PalIndexVel] cmp al," " je MainLoop mov ax,0003h ;changes to 80x25x16 text mode int 10h mov ax,4c00h ;terminate process and int 21h ;return control to DOS End START