;=============================================================================;
; This is a loader for the PowerGrid. It's fairly simple, but looks pretty    ;
; decent... Because I'm such a damn nice guy, I figgered I'd release this     ;
; source to the public.                                                       ;
;                                                                             ;
; I dont expect this source to go un-ripped, so I wont even bother asking. I  ;
; also doubt someone will give us credit for ripping the code, so I'm gonna   ;
; forget that too. However, I do ask that a greet goes out to the group. Hey, ;
; dont cost ya nothin'...                                                     ;
;                                                                             ;
; Anyway, have at it. It's mostly uncommented, so if you just want to rip it  ;
; you'll have to work at it. ;>                                               ;
;                                                                             ;
; Heyya to: the Psychic Monks, Avalanche, TEI, Aardvark, Future Crew, iCE,    ;
; Admire, Occult and Mental Design. Also to Snibble, Mr. Fanatic, alpha,      ;
; Crimson Blade, Eternal Darkness, Cavalier, RetroSpec, Soul Rebel and the    ;
; rest of the IRC regulars - too damn numerous to name.                       ;
;                                                                             ;
; -Friar Tuck/iCE Coding Coordinator                                          ;
;=============================================================================;
        ;-------------------------------;
        ; General Mumbo-Jumbo           ;
        .model tiny                     ;
        .code                           ;
        jmp ep                          ;
        .386p                           ;
        ;-------------------------------;
        ; Subroutines:                  ;
        ; SimplexAdlib                  ;
        include adlib.asm               ;
        ; Writer                        ;
        include wr.asm                  ;
        ; Lens                          ;
        include lens.asm                ;
        ;-------------------------------;
        ; Timing Border                 ;
        ; Used for testing system speed ;
;BORDER equ 1                           ;;
        ;-------------------------------;
        ; Esc Pressed?                  ;
@escpressed macro                       ;
        in   al,60h                     ;
        cmp  al,1                       ;
endm @escpressed                        ;
        ;-------------------------------;
        ; Sync to the video card        ;
wait_vrt:                               ;
        mov     dx,3dah                 ;
wvr02:  in      al,dx                   ;
        test    al,8                    ;
        jz      wvr02                   ;
wvr01:  in      al,dx                   ;
        test    al,8                    ;
        jnz     wvr01                   ;
        ret                             ;
;---------------------------------------;
; write_pal - write our pal             ;
; CX = number of entries from zero      ;
;---------------------------------------;
write_pal proc                          ;
        push dx                         ;
        push si                         ;
        push ax                         ;
        push cx                         ;
        xor ax,ax                       ;
        mov dx,03C8h                    ;
        out dx,al                       ;
        inc dx                          ;
        mov si,offset pal               ;
wp01:   lodsb                           ;
        out dx,al                       ;
        loop wp01                       ;
        pop cx                          ;
        pop ax                          ;
        pop si                          ;
        pop dx                          ;
        ret                             ;
write_pal endp                          ;
;---------------------------------------;
; do_XXXX - rotate color XXX            ;
; CL up, CH left.                       ;
;---------------------------------------;
do_blues:                               ;
        push cx                         ;
        push 5                          ;
        mov si,offset blue              ;
        jmp dr_st                       ;
do_green:                               ;
        push cx                         ;
        push 4                          ;
        mov si,offset green             ;
        jmp dr_st                       ;
do_reds:                                ;
        push cx                         ;
        push 3                          ;
        mov si,offset red               ;
dr_st:  mov di,offset tmp               ;
        mov bx,cx                       ;
        mov cx,16                       ;
drs03:  rep movsd                       ;
        mov cx,bx                       ;
        and cx,07h                      ;
        jz dr_01                        ;
        call up                         ;
dr_01:  mov cl,bh                       ;
        and cx,07h                      ;
        jz dr_done                      ;
        call left                       ;
dr_done:                                ;
        pop bx                          ;
        mov di,bx                       ;
        mov dx,387                      ;
        mov si,offset tmp               ;
        mov cx,64                       ;
dr02:   lodsb                           ;
        mov byte ptr cs:pal[bx],al      ;
        add bx,3                        ;
        loop dr02                       ;
        pop cx                          ;
        ret                             ;
        ;-------------------------------;
        ; Rotate up CX times            ;
up proc                                 ;
        mov dx,cx                       ;
up_01:  mov di,offset tmp8              ;
        mov si,offset tmp               ;
        mov cx,64                       ;
        rep movsb                       ;
        mov si,offset tmp8              ;
        movsd                           ;
        movsd                           ;
        dec dx                          ;
        jnz up_01                       ;
        ret                             ;
up endp                                 ;
        ;-------------------------------;
        ; Rotate left CX times          ;
left proc                               ;
        mov dx,cx                       ;
lf_01:  mov si,offset tmp               ;
        mov di,si                       ;
        dec di                          ;
        cld                             ;
        mov cx,16                       ;
        rep movsd                       ;
        mov di,offset tmp_end           ;
        mov si,di                       ;
        mov cx,8                        ;
        sub si,cx                       ;
lf_02:  mov al,byte ptr ds:[si]         ;
        mov byte ptr es:[di],al         ;
        sub si,8                        ;
        sub di,8                        ;
        loop lf_02                      ;
        dec dx                          ;
        jnz lf_01                       ;
        cld                             ;
        ret                             ;
left endp                               ;
        ;-------------------------------;
        ; PRIMARY LOOP ROUTINE          ;
move_em proc                            ;
me00:   ;-------------------------------;
        ; Align with the retrace        ;
        call wait_vrt                   ;
        ;-------------------------------;
        ; Set our border (if used)      ;
ifdef BORDER                            ;
        mov dx,03C8h                    ;
        mov al,0FFh                     ;
        out dx,al                       ;
        inc dx                          ;
        mov al,03Fh                     ; white
        out dx,al                       ;
        out dx,al                       ;
        out dx,al                       ;
endif                                   ;
        mov cx,255                      ;
        call write_pal                  ;
        ;-------------------------------;
        ; Different color for lens      ;
ifdef BORDER                            ;
        mov dx,03C8h                    ;
        mov ax,00FFh                    ;
        out dx,ax                       ;
        inc dx                          ;
        xor ax,ax                       ;
        out dx,al                       ;
        mov al,03Fh                     ; blue
        out dx,al                       ;
endif                                   ;
        ;-------------------------------;
        ; Do the Lens                   ;
        mov ax,cs:[lens_x]              ;
        add ax,cs:[lens_xi]             ;
        cmp ax,270                      ;
        jl me03                         ;
        mov cs:[lens_xi],-1             ;
        jmp short me04                  ;
me03:   cmp ax,0                        ;
        jg me04                         ;
        mov cs:[lens_xi],1              ;
me04:   mov cs:[lens_x],ax              ;
        mov bx,ax                       ;
        mov ax,cs:[lens_y]              ;
        add ax,cs:[lens_yi]             ;
        cmp ax,600                      ;
        jl me05                         ;
        mov cs:[lens_yi],-3             ;
        jmp short me06                  ;
me05:   cmp ax,0                        ;
        jg me06                         ;
        mov cs:[lens_yi],3              ;
me06:   mov cs:[lens_y],ax              ;
        sar ax,2                        ;
        mov cx,ax                       ;
        call do_lens                    ;
        ;-------------------------------;
        ; Different color for letter    ;
ifdef BORDER                            ;
        mov dx,03C8h                    ;
        mov ax,3FFFh                    ;
        out dx,ax                       ;
        inc dx                          ;
        xor ax,ax                       ;
        out dx,al                       ;
        out dx,al                       ;
endif                                   ;
        ;-------------------------------;
        ; Plot a letter                 ;
        push es                         ;
        mov ax,0A000h                   ;
        mov es,ax                       ;
        cmp cs:[pauseflag],1            ;
        jne me01                        ;
        call pause_wrds                 ;
        jmp short me02                  ;
me01:   call do_words                   ;
me02:   pop es                          ;
        ;-------------------------------;
        ; Set border for grid           ;
ifdef BORDER                            ;
        mov dx,03C8h                    ;
        mov ax,0FFh                     ;
        out dx,ax                       ;
        inc dx                          ;
        mov al,03Fh                     ; green
        out dx,al                       ;
        xor ax,ax                       ;
        out dx,al                       ;
endif                                   ;
        ;-------------------------------;
        ; The SIN/COS pointers          ;
        add cs:[b_lmove],2              ;
        add cs:[b_umove],3              ;
        inc dword ptr cs:[democount]    ;
        ;-------------------------------;
        ; Set up the Left/Up Rotations  ;
        mov bx,cs:[b_lmove]             ;
        and bx,03FFh                    ;
        mov cl,byte ptr cs:sin256[bx]   ;
        mov bx,cs:[b_umove]             ;
        and bx,03FFh                    ;
        mov ch,byte ptr cs:cos256[bx]   ;
me07:                                   ;
        ;-------------------------------;
        ; Do the rotations              ;
        call do_blues                   ;
        call do_reds                    ;
        call do_green                   ;
        ;-------------------------------;
        ; Set border for music          ;
ifdef BORDER                            ;
        mov dx,03C8h                    ;
        mov ax,0FFFFh                   ;
        out dx,ax                       ;
        inc dx                          ;
        mov al,03Fh                     ; White
        out dx,al                       ;
        out dx,al                       ;
endif                                   ;
        ;-------------------------------;
        ; Do the Music                  ;
        push ds                         ;
        mov ax,seg ains3                ;
        mov ds,ax                       ;
        call a_dorow                    ;
        pop ds                          ;
        ;-------------------------------;
        ; Turn off border, all done :)  ;
ifdef BORDER                            ;
        mov dx,03C8h                    ;
        mov ax,0FFh                     ;
        out dx,ax                       ;
        inc dx                          ;
        xor ax,ax                       ;
        out dx,al                       ;
        out dx,al                       ;
endif                                   ;
        ;-------------------------------;
        ; Check for a keypress          ;
        @escpressed                     ;
        jnz me00                        ;
        ret                             ;
move_em endp                            ;
        ;-------------------------------;
        ; Draw the initial screens      ;
drawscr:                                ;
        pusha                           ;
        push es                         ;
        push ds                         ;
        mov ax,[datseg]                 ;
        mov ds,ax                       ;
        ;-------------------------------;
        ; Write the empty pal           ;
        mov dx,03C8h                    ;
        mov al,0                        ;
        out dx,al                       ;
        inc dx                          ;
        mov cx,768                      ;
ds00:   out dx,al                       ;
        loop ds00                       ;
        mov ax,0A000h                   ;
        mov es,ax                       ;
        ;-------------------------------;
        ; Draw the rotated grid         ;
        mov di,14400                    ;
        mov cx,110                      ;
ds01:   push cx                         ;
        mov cx,320                      ;
ds02:   cmp cx,2                        ;
        jg  ds03                        ;
        mov al,72                       ;
        jmp short ds05                  ;
ds03:   cmp cx,319                      ;
        jl  ds04                        ;
        mov al,73                       ;
        jmp short ds05                  ;
ds04:   mov ax,cs:[y]                   ;
        sal ax,3                        ;
        add ax,cs:[x]                   ;
        and ax,03Fh                     ;
        add ax,1                        ;
ds05:   mov byte ptr es:[di],al         ;
        mov byte ptr ds:[di],al         ;
        inc di                          ;
        inc cs:[x]                      ;
        and cs:[x],07h                  ;
        loop ds02                       ;
        mov cs:[x],0                    ;
        inc cs:[y]                      ;
        and cs:[y],07h                  ;
        pop cx                          ;
        loop ds01                       ;
        ;-------------------------------;
        ; Line at top and bottom        ;
        mov di,14400                    ;
        mov cx,639                      ;
        mov al,73                       ;
ds06:   mov byte ptr es:[di],al         ;
        mov byte ptr ds:[di],al         ;
        inc di                          ;
        loop ds06                       ;
        mov di,49281                    ;
        mov cx,639                      ;
        mov al,72                       ;
ds07:   mov byte ptr es:[di],al         ;
        mov byte ptr ds:[di],al         ;
        inc di                          ;
        loop ds07                       ;
        ;-------------------------------;
        ; The POWERGRID Logo            ;
        mov si,offset pgridscr2         ;
        mov di,49920                    ;
        mov cx,BYTE_TOT+320             ;
ds08:   mov al,byte ptr cs:[si]         ;
        inc si                          ;
        add al,82                       ;
        mov byte ptr ds:[di],al         ;
        mov byte ptr es:[di],al         ;
        inc di                          ;
        loop ds08                       ;
        mov si,offset pgridscr          ;
        mov di,320                      ;
        mov cx,BYTE_TOT+320             ;
ds09:   mov al,byte ptr cs:[si]         ;
        inc si                          ;
        add al,82                       ;
        mov byte ptr ds:[di],al         ;
        mov byte ptr es:[di],al         ;
        inc di                          ;
        loop ds09                       ;
        ;-------------------------------
        xor di,di
        mov al,74
        mov cx,8
d__0:   push cx
        mov cx,40
d__1:   mov byte ptr es:[di],al
        mov byte ptr ds:[di],al
        inc di
        loop d__1
        pop cx
        inc al
        loop d__0
        ;-------------------------------;
        ; Set up a benchmark border     ;
ifdef BORDER                            ;
        mov di,316                      ;
        mov cx,200                      ;
        mov eax,-1                      ;
ds10:   mov dword ptr es:[di],eax       ;
        mov dword ptr ds:[di],eax       ;
        add di,320                      ;
        loop ds10                       ;
endif                                   ;
        ;-------------------------------;
        ; Set the Bitmap colors.        ;
        pop ds                          ;
        pop es                          ;
        mov di,offset pal               ;
        mov si,offset pgridpal          ;
        add di,246                      ;
        mov cx,COLOR_TOT*3              ;
ds11:   lodsb                           ;
;        xor ah,ah                       ;
;        mov bx,ax                       ;
;        sal bx,1                        ;
;        add ax,bx                       ;
;        sar al,2                        ;
        stosb                           ;
        loop ds11                       ;
        popa                            ;
        mov cx,768                      ;
        call write_pal                  ;
        ret                             ;
        ;-------------------------------;
        ;-------------------------------;
        ;-------------------------------;
        ; ENTRY POINT                   ;
        ; do some basic setup.          ;
ep:     mov ax,cs                       ;
        mov ds,ax                       ;
        mov es,ax                       ;
        mov ss,ax                       ;
        mov sp,offset endstack          ;
        ;-------------------------------;
        ; Detect 386                    ;
        mov ax,02000h                   ;
        push ax                         ;
        popf                            ;
        pushf                           ;
        pop ax                          ;
        test ax,02000h                  ;
        jz ending                       ;
        ;-------------------------------;
        ; Various inits                 ;
        cld                             ;
        @writer_init                    ;
        ;-------------------------------;
        ; Allocate extra screen         ;
        mov ah,48h                      ;
        mov bx,4000                     ;
        int 21h                         ;
        jc ending                       ;
        mov [datseg],ax                 ;
        ;-------------------------------;
        push ds                         ;
        mov ax,seg ains3                ;
        mov ds,ax                       ;
        call a_init                     ;
        call a_init                     ;
        call a_init                     ;
        pop ds                          ;
        ;-------------------------------;
        ; Shut down the interrupts      ;
        mov  al,01111010b               ;
        out  21h,al                     ;
        ;-------------------------------;
        ; Set up the Video Mode         ;
        mov ax,0013h                    ;
        int 10h                         ;
        ;-------------------------------;
        ; Draw the startup screen       ;
        call drawscr                    ;
        ;-------------------------------;
        ; Plot the Letters and the rest ;
        call move_em                    ;
        ;-------------------------------;
        ; Reinstate the interrupts      ;
        mov  al,0                       ;
        out  21h,al                     ;
        push ds                         ;
        mov ax,seg ains3                ;
        mov ds,ax                       ;
        call a_init                     ;
        pop ds                          ;
        ;-------------------------------;
        ; Release memory                ;
        mov ax,[datseg]                 ;
        mov es,ax                       ;
        mov ah,49h                      ;
        int 21h                         ;
        ;-------------------------------;
        ;-------------------------------;
        ; Do Final ANSI Image           ;
ending: mov ax,0003h                    ;
        int 10h                         ;
        mov ax,0B800h                   ;
        mov es,ax                       ;
        xor di,di                       ;
        mov si,offset finalimage        ;
        mov cx,1000                     ;
        rep movsd                       ;
        mov ax,0200h                    ;
        xor bx,bx                       ;
        mov dx,1600h                    ;
        int 10h                         ;
        mov ax,4C00h                    ;
        int 21h                         ;
        ;-------------------------------;
        ; Data                          ;
        ;-------------------------------;
        ; Font                          ;
        include newfont.dat             ;
        ; Lens Data                     ;
        include lens.dat                ;
        ; Sin/Cos table                 ;
        include sc256.dat               ;
        ; Final ANSI screen             ;
        include pg_final.dat            ;
        ; Music                         ;
        include ad_data.dat             ;
        ; PowerGrid Bitmap              ;
        include pgrid_sc.dat            ;
        ;-------------------------------;
        ; VARS                          ;
lens_x  dw      10                      ;
lens_xi dw      1                       ;
lens_y  dw      40                      ;
lens_yi dw      3                       ;
b_umove dw      0                       ;
b_lmove dw      0                       ;
        ; Palettes.                     ;
blue    db     30,30,30,30,30,30,30,30  ;
        db     30,15,15,15,15,15,15,15  ;
        db     30,15, 0, 0, 0, 0, 0,15  ;
        db     30,15, 0, 0, 0, 0, 0,15  ;
        db     30,15, 0, 0, 0, 0, 0,15  ;
        db     30,15, 0, 0, 0, 0, 0,15  ;
        db     30,15, 0, 0, 0, 0, 0,15  ;
        db     30,15,15,15,15,15,15,15  ;
red     db     10,10,10,10,10,10,10,10  ;
        db     10, 4, 4, 4, 4, 4, 4, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 4, 4, 4, 4, 4, 4  ;
green   db     10,10,10,10,10,10,10,10  ;
        db     10, 4, 4, 4, 4, 4, 4, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 0, 0, 0, 0, 0, 4  ;
        db     10, 4, 4, 4, 4, 4, 4, 4  ;
        ;-------------------------------;
        ; Palette work areas            ;
        ; And other Vars                ;
tmp8    db      8 dup(0)                ;
tmp     db      63 dup(0)               ;
tmp_end db      0                       ;
pal     db      198 dup(0)              ;
        ;-------------------------------;
        ; Word colors                   ;
        db      17h,17h,17h             ;
        db      1Fh,1Fh,1Fh             ;
        db      27h,27h,27h             ;
        db      2Fh,2Fh,2Fh             ;
        db      37h,37h,37h             ;
        db      3Fh,3Fh,3Fh             ;
        ;-------------------------------;
        ; Border colors                 ;
        db      0Fh,0Fh,1Fh             ;
        db      17h,17h,2Fh             ;
        ;-------------------------------;
        ; Picture palettes              ;
        db      549 dup(0)              ;
bmove label word                        ;
democount dd    0                       ;
wr_offs dw      0                       ;
x       dw      0                       ;
y       dw      0                       ;
datseg  dw      0                       ;
startstack      dw 200h dup(0)          ;
endstack        dw 0                    ;
        end
