;███████████████████████████████████████████████████████████████████████████████
; COPPER.COM - 512 bytes copper demo
;███████████████████████████████████████████████████████████████████████████████
model tiny
codeseg
p286
org 100h
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
; CODE
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
MAIN: mov ax,13h
int 10h
;░░░░░░░░░░ Initialize copper bars
call InitBars
;░░░░░░░░░░ Set copper palette
mov si,offset pal
mov cx,3*barheight*barcount
mov al,1
mov dx,3C8h
out dx,al
inc dx
rep outsb
;░░░░░░░░░░ Save palette for fading
call GetPalette
mov ax,0A000h
mov es,ax
;░░░░░░░░░░ Mainloop
@MainLoop:
call CalcBars
cmp Frame,MaxFrame
ja @Move
inc Frame
call WaitVREnd
call SetPalette
@Move: call WaitVRStart
call DrawBars
;░░░░░░░░░░ Repeat until keypressed
mov ah,1
int 16h
jz @MainLoop
;░░░░░░░░░░ Fade to black, but keep the bars moving
@MainLoop2:
call CalcBars
call WaitVREnd
call SetPalette
call WaitVRStart
call DrawBars
dec Frame
jnz @MainLoop2
;░░░░░░░░░░ Read key pressed and exit
@OUT: xor ah,ah
int 16h
mov ax,3
int 10h
ret
;▒▒▒▒▒▒▒▒▒▒ GetPalette
;▒▒▒▒▒▒▒▒▒▒ Gets palette for fading
;▒▒▒▒▒▒▒▒▒▒ Assumes: ES=data
;▒▒▒▒▒▒▒▒▒▒ Destroys: ax,bx,cx,dx,di
GetPalette PROC NEAR
xor ax,ax
mov bl,MaxFrame
mov cx,768
mov dx,3C7h
mov di,offset palette
out dx,al
inc dx
inc dx
@GetLoop:
in al,dx
shl ax,8
div bl
stosb
loop @GetLoop
ret
endp
;▒▒▒▒▒▒▒▒▒▒ SetPalette
;▒▒▒▒▒▒▒▒▒▒ Sets whole palette
;▒▒▒▒▒▒▒▒▒▒ Assumes: DS=data
;▒▒▒▒▒▒▒▒▒▒ Destroys: ax,bx,cx,dx,si
SetPalette PROC NEAR
xor ax,ax
mov bl,Frame
mov cx,768
mov dx,3C8h
mov si,offset palette
out dx,al
inc dx
@SetLoop:
lodsb
mul bl
shr ax,8
out dx,al
loop @SetLoop
ret
endp
;▒▒▒▒▒▒▒▒▒▒ WaitVRStart
;▒▒▒▒▒▒▒▒▒▒ Waits Vertical Retrace to begin
;▒▒▒▒▒▒▒▒▒▒ Assumes: nothing
;▒▒▒▒▒▒▒▒▒▒ Destroys: ax,dx
WaitVRStart PROC NEAR
mov dx,3DAh
@WaitStart:
in al,dx
test al,8
jz @WaitStart
ret
endp
;▒▒▒▒▒▒▒▒▒▒ WaitVREnd
;▒▒▒▒▒▒▒▒▒▒ Waits Vertical Retrace to end
;▒▒▒▒▒▒▒▒▒▒ Assumes: Nothing
;▒▒▒▒▒▒▒▒▒▒ Destroys: ax,dx
WaitVREnd PROC NEAR
mov dx,3DAh
@WaitEnd:
in al,dx
test al,8
jnz @WaitEnd
ret
endp
;▒▒▒▒▒▒▒▒▒▒ InitBars
;▒▒▒▒▒▒▒▒▒▒ Initializes copper bars
;▒▒▒▒▒▒▒▒▒▒ Assumes: nothing
;▒▒▒▒▒▒▒▒▒▒ Destroys: ax,bx,cx,si
InitBars PROC NEAR
xor si,si
mov cx,barcount
mov bx,1
mov ax,257 ; ah=al=1
@Init1: mov [si+TheBars.Y],bx ; save Y
mov [si+TheBars.C],ax ; set color
mov [si+TheBars.Dir],al ; going up
mov [si+TheBars.NewDI],64000 ; old position
add si,(size bar) ; next bar
add bx,barheight*2
add al,barheight
add ah,barheight
loop @Init1
ret
endp
;▒▒▒▒▒▒▒▒▒▒ CalcBars
;▒▒▒▒▒▒▒▒▒▒ Calculates next positions for bars
;▒▒▒▒▒▒▒▒▒▒ Assumes: nothing
;▒▒▒▒▒▒▒▒▒▒ Destroys: ax,bx,cx,dx,si
CalcBars PROC NEAR
xor si,si
mov cx,barcount ; process all bars
@CalcLoop:
mov ax,[si+TheBars.Y] ; load Y
mov dx,[si+TheBars.NewDI] ; load previous position
mov bl,[si+TheBars.Dir] ; test for direction
or bl,bl
jz @GoingDown
@GoingUp:
add dx,320*barheight
dec ax
jnz @BarOK
mov [si+TheBars.Dir],0 ; if on top then change dir
jmp @BarOK
@GoingDown:
inc ax
cmp ax,200-barheight ; on bottom?
jb @BarOK
mov [si+TheBars.Dir],1 ; if on bottom then change dir
@BarOK: mov [si+TheBars.Y],ax ; set new Y
shl ax,6
mov di,ax
shl ax,2
add di,ax
mov [si+TheBars.OldDI],dx ; save previous position
mov [si+TheBars.NewDI],di ; save new position
add si,(size bar) ; next bar
loop @CalcLoop
ret
endp
;▒▒▒▒▒▒▒▒▒▒ DrawBars
;▒▒▒▒▒▒▒▒▒▒ Draws copper bars
;▒▒▒▒▒▒▒▒▒▒ Assumes: ES=A000
;▒▒▒▒▒▒▒▒▒▒ Destroys: ax,bx,cx,dx,si,di
DrawBars PROC NEAR
xor si,si
mov bx,barcount ; process all bars
@MoveLoop:
mov di,[si+TheBars.OldDI]
mov cx,160 ; erase one line behind
xor ax,ax
rep stosw
mov di,[si+TheBars.NewDI]
mov dx,barheight
mov ax,[si+TheBars.C]
@DrawLoop: ; draw bar into new position
mov cx,160
rep stosw
add ax,257 ; increase ah and al
dec dx
jnz @DrawLoop
add si,(size bar) ; next bar
dec bx
jnz @MoveLoop
ret
endp
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
; DATA
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
;▒▒▒▒▒▒▒▒▒▒ Copper bar structure
bar struc
Y dw ? ; Y - coordinate
OldDI dw ? ; Old position
NewDI dw ? ; New position
C dw ? ; Base color for bar
Dir db ? ; 0=down, anything else=up
ends
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░ INITIALIZED DATA ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
barheight equ 11 ; height of the bar
barcount equ 5 ; count of bars
MaxFrame equ 100 ; frames for fading
;▒▒▒▒▒▒▒▒▒▒ Copper bars palette
Pal:
include Copper.Pal ; Include palette
Frame db 0 ; Current frame in fading
;░░░░░░░░░░░░░░░░░░░░░░░ ZERO DATA - TO BE REMOVED ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
db 0FFh ; End of file -Marker
TheBars bar barcount dup (?)
Palette: ; Palette for fading
db 768 dup (?)
end MAIN
;███████████████████████████████████████████████████████████████████████████████
END
;███████████████████████████████████████████████████████████████████████████████