; COPPER.ASM -- Copper bars
Ideal
Model Tiny
P186
CodeSeg
Org 100h
;**************************** Main Program
Proc Prog
mov di,offset Buffer ;Clear the buffer
xor ax,ax
mov cx,500
rep stosw
mov di,offset Buffer+400 ;DI = middle of buffer
mov cx,63 ;63 shades
Pal1: stosb ;Store color
inc ax ;Next color
loop Pal1 ;Loop back
mov cx,63 ;63 shades
Pal2: stosb ;Store color
dec ax ;Next color
loop Pal2 ;Loop back
mov si,140 ;SI, DI, BP = positions
mov di,140
mov bp,140
mov bx,2 ;BX, CX, DX = speeds
mov cx,-3
mov dx,-1
MainLoop: add si,bx ;Advance red value
jg $+4
neg bx ;Bounce if needed
cmp si,270
jl $+4
neg bx
add di,cx ;Advance green value
jg $+4
neg cx ;Bounce if needed
cmp di,270
jl $+4
neg cx
add bp,dx ;Advance blue value
jg $+4
neg dx ;Bounce if needed
cmp bp,270
jl $+4
neg dx
push si di bp ;Do the copper effect
call Copper
mov ah,1 ;Loop while no key pressed
int 16h
jz MainLoop
ret ;Return
EndP Prog
;**************************** Copper -- One frame of copper effect
Red equ bp+8
Green equ bp+6
Blue equ bp+4
Proc Copper
push bp ;Set up stack frame
mov bp,sp
pusha ;Save all registers
cli ;Disable interrupts
mov dx,03DAh ;DX = IS1 port
VRet1: in al,dx ;Wait for active period
test al,8
jz VRet1
VRet2: in al,dx
test al,8
jnz VRet2
mov cx,400 ;400 lines, BX = buffer
mov bx,offset Buffer
LineLoop: mov dx,03DAh ;DX = IS1 port
HRet1: in al,dx ;Wait for horizontal retrace
test al,1
jnz HRet1
HRet2: in al,dx
test al,1
jz HRet2
mov dx,03C8h ;Setting color 0
xor al,al
out dx,al
inc dx
mov si,cx ;Set red value
sub si,[Red]
mov al,[bx+si+400]
out dx,al
mov si,cx ;Set green value
sub si,[Green]
mov al,[bx+si+400]
out dx,al
mov si,cx ;Set blue value
sub si,[Blue]
mov al,[bx+si+400]
out dx,al
loop LineLoop ;Loop back
sti ;Enable interrupts
popa ;Restore registers
pop bp ;Delete stack frame
ret 6 ;Return
EndP Copper
Buffer:
End Prog