This is a small program that displays 3 copper bars at the same time. The program is richly commented and should be quite easy to understand.
The source and a compiled version is available for download (1917 bytes).;---------------------------------------------------------------------
; COPPER3 - 3 simultaneous copper bars, 79 bytes! - final version by
; Tylisha C. Andersen - notable contributions by T.Remmel and J.Neil
;---------------------------------------------------------------------
b equ
w equ
.model tiny
.code
org 100h
;---------------------------------------------------------------------
main: pop bx ; zero bx by popping the return address
;
m_1: push bx ; write 3 positions and increments
inc bx ; the jpo instruction jumps when there are
push bx ; an odd number of set bits in the lower 8
jpo m_1 ; bits of the result; this is true for
; 1 (01b) and 2 (10b), but false for 3 (11b)
m_2: cli ; disable interrupts
mov ah,8 ; ah = 8 for vertical retrace
mov cx,390 ; for each of 390 scanlines:
;
m_3: mov dx,03DAh ; dx = IS1 port, wait for retrace
m_4: in al,dx ; retrace could be vertical or horizontal
and al,ah ; due to the design of the VGA this ends in
jnz m_4 ; the horizontal retrace if ah = 01h, but in
m_5: in al,dx ; the active vertical period if ah = 08h,
and al,ah ; which is exactly what we need
jz m_5
mov dl,0C8h ; dx = DAC write select port
xchg ax,bx ; al = 0, select DAC register 0
out dx,al
inc dx
mov si,sp ; si = ptr. to position data list
mov bl,3 ; for each of 3 colors:
m_6: lodsw ; ax = increment - tricky use of loop,
loop m_7 ; jumps when cx <> 1 to test for last line
; if on last scanline, then
sub [si],ax ; add increment to position, if this puts it
cmp w [si],-263 ; out of range, then bounce
ja m_7 ; 263 is the max. position of the top of a
neg w [si-2] ; bar without it going off the screen
m_7: inc cx ; restore cx (it was decremented by 'loop')
lodsw ; ax = position, si now = next color
add ax,cx ; ax = line + position
cmp ax,127 ; if it's not inside the bar, then set the
jbe m_8 ; color to 0 (xor al,al); otherwise...
xor al,al
m_8: cmp al,64 ; if it's greater than 64, this means it's
jb m_9 ; on the top part where it is fading out, so
not al ; we negate it (the top 2 bits are ignored)
m_9: out dx,al ; set color intensity, and loop (remember,
dec bx ; parity is only on the lower 8 bits, so it
jpo m_6 ; doesn't matter what bh contains)
mov ah,1 ; ah = 01h for horiz. retrace, key check
loop m_3 ; loop
int 16h ; check for key press (enables interrupts)
jz m_2 ; loop while no key pressed
int 20h ; return to DOS
end main