; -----------------------------------------------------------------------------
; SMALLPAL.ASM by Aleksandr Koltsoff in 1994
; -----------------------------------------------------------------------------
; Released to the public domain -> Do whatever you like with it!!!
; -----------------------------------------------------------------------------

; Can it get smaller than this??? Try it out!!!
; If you can do it in fewer bytes (79) then contact me :

; Cray'Z Russian aka Aleksandr Koltsoff
; Kuukkelintie 36 B 12
; FIN 96400 Rovaniemi
; Europe

; Or Call to Putrefaction of Perfection BBBS v.32bis (8/N/1) :
; +358(9)60-366233 (leave messages to Aleksandr Koltsoff)

; Or send E@Mail to :
; InterNet < aleksandr.koltsoff@laol.edu.fi (account works until 1.4.1995)
; FidoNet  < 2:229/366 Aleksandr Koltsoff (account is in PoP BBBS)

; Remember that the new version must do exactly the same as this one (you
; can omit the beeps, but otherwise it should do everything this one does):

; 1. First fill screen with character 0DBh and color 7.
; 2. Use the same colors that are used in this program when fading
; 3. Syncronize with VGA (vertical retraces)
; 4. Do NOT call other programs (could reduce the size using this method)

; Assembled with TASM 3.0 (Although should assemble with TASM 1.0 as well)
; No priviledged instructions used (8086 compatible)
; VGA required (probably will do something odd if no VGA)
; Works only in mode 3 (or other similar modes), altough changes the
; palette in other modes as well.

; 9.12.94 One coder just got it two bytes smaller (one was replacing the 
; out dx, al with out dx, ax and other by removing one ret from the program)

.model tiny
.code
org 100h
start:
        mov ah, 0b8h    ; AX = B800
        mov es, ax      ; ES = B800
        mov cx, 7DBh    ; CH = 7 CL = DB
        mov ax, cx      ; AL = 7 (color) AH = DB (character)
                        ; DI = 0
        rep stosw       ; Fill screen with cool characters

        mov dh, 3       ; DX = 03xxh
        mov bl, 63      ; BX = 63
        mov ah, bl      ; AH = 63
        mov cx, bx      ; CX = 63
        mov bp, offset SetPalWaitRetrace
        call bp         ; Set color 7 and wait for retrace

fadeloop:
        mov bl, cl      ; BL(Red)   = Loop counter
        mov ah, cl      ; AH(Green) = Loop counter
        call bp         ; Set color 7 and wait for retrace
        loop fadeloop

        ; BL R = 0
        ; AH G = 0
        ; BH B = 0
        mov cl, 63
fadeback:
        call bp         ; Set color 7 and wait for retrace
        inc bh          ; BH(Blue) = BH + 1
        loop fadeback
        ; BL R = 0
        ; AH G = 0
        ; BH B = 63

        mov cl, 63
fadeloop2:
        mov ah, 63
        sub ah, cl      ; AH(Green) = 63 - (63 downto 0)
        call bp         ; Set color 7 and wait for retrace
        loop fadeloop2

; If don't want the beeps then erase following 5 instructions. Size will
; reduce to 79 bytes (original version)

;        mov ah, 2       ; Print one character
;        mov dl, 7       ; Character = ASCII(7) [Beep/Bell]
;        int 21h         ; Print once
;        int 21h         ; Twice
;        int 21h         ; Three times

; Terminates program

        ret

setpalwaitretrace proc
        mov   dl, 0c8h          ; DX = 3c8h (VGA Palette DAC Index - register)
        mov   al, 7             ; Choose color 7 to change
        out   dx, al            ; Select color 7
        inc   dx                ; DX = 3c9h (VGA Palette DAC Data - register)

        mov   al, bl
        out   dx, al            ; Set color 7's Red component
        mov   al, ah
        out   dx, al            ; Set color 7's Green component
        mov   al, bh
        out   dx, al            ; Set color 7's Blue component

waitretrace:
        mov   dl, 0DAh          ; DX = 3DAh (VGA Misc Register #1)
l1:
        in    al, dx            ; Read value from VGA(Misc#1)
        test  al, 8             ; Bit 4 set? (Bit 4 is set when a vertical
                                ; retrace is not occuring)
        jnz   l1                ; Bit set, so wait for vertical refresh
l2:
        in    al, dx            ; Read value from VGA(Misc#1)
        test  al, 8
        jz    l2                ; Wait until vertical retrace begins
        ret                     ; Return to main program
setpalwaitretrace endp

END start




