463 lines
11 KiB
NASM
463 lines
11 KiB
NASM
;Actual DIS server routines
|
|
;==========================
|
|
;note: lines with TEMP! are temporary to be replaced by smarter
|
|
;techniques in the future...
|
|
|
|
LOCALS
|
|
.386
|
|
ALIGN 16
|
|
|
|
;±±±±±±±±±±±±±±±±±±±± Variables ±±±±±±±±±±±±±±±±±±
|
|
exitflag dw 0 ;1=exit key pressed
|
|
indemoflag dw 0 ;1=inside the great big ultra cool demo
|
|
passmuscode dw 0
|
|
|
|
ALIGN 4
|
|
msgarea0 db 64 dup(0)
|
|
msgarea1 db 64 dup(0)
|
|
msgarea2 db 64 dup(0)
|
|
msgarea3 db 64 dup(0)
|
|
|
|
;±±±±±±±±±±±±±± List of service routines ±±±±±±±±±±±±
|
|
service0 LABEL WORD
|
|
dw OFFSET version_0
|
|
dw OFFSET waitb_1
|
|
dw OFFSET exit_2
|
|
dw OFFSET indemo_3
|
|
dw OFFSET loader_4
|
|
dw OFFSET msgarea_5
|
|
dw OFFSET muscode_6
|
|
dw OFFSET setcopper_7
|
|
dw OFFSET fastvmode_8
|
|
dw OFFSET musframe_9
|
|
dw OFFSET sync_10
|
|
service9 LABEL WORD
|
|
|
|
;±±±±±±±±±±±±±±±±±±±± General stuff ±±±±±±±±±±±±±±±±±±
|
|
|
|
dis_oldint dd ?
|
|
|
|
dis_setint PROC NEAR
|
|
push ds
|
|
xor ax,ax
|
|
mov ds,ax
|
|
mov ax,word ptr ds:[0fch*4+0]
|
|
mov bx,word ptr ds:[0fch*4+2]
|
|
mov word ptr cs:dis_oldint[0],ax
|
|
mov word ptr cs:dis_oldint[2],bx
|
|
mov word ptr ds:[0fch*4+0],OFFSET dis_int
|
|
mov word ptr ds:[0fch*4+2],cs
|
|
pop ds
|
|
ret
|
|
dis_setint ENDP
|
|
|
|
dis_resetint PROC NEAR
|
|
xor ax,ax
|
|
mov ds,ax
|
|
mov ax,word ptr cs:dis_oldint[0]
|
|
mov bx,word ptr cs:dis_oldint[2]
|
|
mov word ptr ds:[0fch*4+0],ax
|
|
mov word ptr ds:[0fch*4+2],bx
|
|
ret
|
|
dis_resetint ENDP
|
|
|
|
dw 0fc0h ;signature for dis
|
|
dw 0fc0h ;installation check
|
|
dis_int PROC FAR ;interrupt 0fch server, BX=function number
|
|
sti
|
|
shl bx,1
|
|
cmp bx,(service9-service0)
|
|
jae @@1
|
|
call cs:service0[bx]
|
|
@@1: iret
|
|
dis_int ENDP
|
|
|
|
;±±±±±±±±±±±±±±±±±±±± Service Routines ±±±±±±±±±±±±±±±±±±
|
|
|
|
;entry: -
|
|
; exit: AX=version
|
|
;descr: -
|
|
version_0 PROC NEAR
|
|
;indemo?
|
|
IFDEF INDEMO
|
|
mov ax,1
|
|
ELSE
|
|
mov ax,0
|
|
ENDIF
|
|
mov cs:indemoflag,ax
|
|
;initialize
|
|
mov cs:passmuscode,0
|
|
mov cs:exitflag,0
|
|
;return version
|
|
mov ax,0100h
|
|
ret
|
|
version_0 ENDP
|
|
|
|
ff PROC FAR
|
|
IFDEF INDEMO
|
|
push es
|
|
mov es,cs:stmikseg
|
|
mov bx,es:_np_ord
|
|
inc bx
|
|
xor ax,ax
|
|
push ax
|
|
push bx
|
|
call _zgotosong
|
|
add sp,4
|
|
pop es
|
|
ENDIF
|
|
ret
|
|
ff ENDP
|
|
|
|
checkkeys PROC NEAR
|
|
IFDEF INDEMO
|
|
cmp cs:forcebreak,0
|
|
jne @@3
|
|
ENDIF
|
|
call ctrldown
|
|
jc @@6
|
|
mov ah,1 ;TEMP!
|
|
int 16h
|
|
jz @@3
|
|
mov ah,0
|
|
int 16h
|
|
cmp al,'0'
|
|
jne @@9
|
|
pusha
|
|
push ds
|
|
push es
|
|
mov ax,0fcfch
|
|
mov bx,1
|
|
int 33h
|
|
pop es
|
|
pop ds
|
|
popa
|
|
ret
|
|
@@9: cmp al,'9'
|
|
jne @@8
|
|
pusha
|
|
push ds
|
|
push es
|
|
mov ax,0fcfch
|
|
mov bx,2
|
|
int 33h
|
|
pop es
|
|
pop ds
|
|
popa
|
|
ret
|
|
@@8: cmp al,'1'
|
|
jne @@5
|
|
call ff
|
|
@@5: cmp al,27
|
|
jne @@4
|
|
@@6: mov cs:exitflag,1
|
|
@@4: mov cs:passmuscode,1
|
|
@@3: ret
|
|
checkkeys ENDP
|
|
|
|
;entry: -
|
|
; exit: -
|
|
;descr: Waits for border start
|
|
waitb_1 PROC NEAR
|
|
call checkkeys
|
|
IFDEF INDEMO
|
|
sti
|
|
mov ax,cs:copperframecount
|
|
@@v: cmp cs:copperframecount,ax
|
|
je @@v
|
|
@@q: mov ax,cs:copperframecount
|
|
mov cs:copperframecount,0
|
|
ELSE
|
|
mov dx,3dah
|
|
@@1: in al,dx
|
|
test al,8
|
|
jnz @@1
|
|
@@2: in al,dx
|
|
test al,8
|
|
jz @@2
|
|
mov ax,1 ;number of frames taken ;TEMP!
|
|
ENDIF
|
|
ret
|
|
waitb_1 ENDP
|
|
|
|
;entry: -
|
|
; exit: AX=return
|
|
;descr: returns 1 if part should exit.
|
|
exit_2 PROC NEAR
|
|
call checkkeys
|
|
mov ax,cs:exitflag
|
|
ret
|
|
exit_2 ENDP
|
|
|
|
;entry: -
|
|
; exit: AX=return
|
|
;descr: returns 1 if inside demo (and not testing from dos)
|
|
indemo_3 PROC NEAR
|
|
mov ax,cs:indemoflag
|
|
ret
|
|
indemo_3 ENDP
|
|
|
|
;entry: AX=area desired (0..3)
|
|
; exit: DX:AX=pointer to msgarea
|
|
;descr: returns a pointer to interpart communications area.
|
|
; There is ONLY 64 bytes of space in the area, DON'T OVERFLOW IT :-)
|
|
msgarea_5 PROC NEAR
|
|
cmp ax,1
|
|
je @@1
|
|
cmp ax,2
|
|
je @@2
|
|
cmp ax,3
|
|
je @@3
|
|
@@0: mov dx,cs
|
|
mov ax,OFFSET msgarea0
|
|
ret
|
|
@@1: mov dx,cs
|
|
mov ax,OFFSET msgarea1
|
|
ret
|
|
@@2: mov dx,cs
|
|
mov ax,OFFSET msgarea2
|
|
ret
|
|
@@3: mov dx,cs
|
|
mov ax,OFFSET msgarea3
|
|
ret
|
|
msgarea_5 ENDP
|
|
|
|
;Loader functions (not for parts)
|
|
;entry: AX=0/1
|
|
; exit: -
|
|
;descr: AX=0: restores dos process id
|
|
; AX=1: sets dos process id to the loader
|
|
; AX=100h: call _zloadinstrument(dx)
|
|
; AX=101h: call _zinitmodule(dx:0)
|
|
; This is used to load the music in name of the loader!
|
|
loader_4 PROC NEAR
|
|
IFDEF INDEMO
|
|
call loaderservices
|
|
ENDIF
|
|
ret
|
|
loader_4 ENDP
|
|
|
|
;entry: AX=code you want (are waiting for)
|
|
; exit: AX=current code,BX=row
|
|
muscode_6 PROC NEAR
|
|
push ax
|
|
call checkkeys
|
|
pop ax
|
|
IFDEF INDEMO
|
|
push es
|
|
mov es,cs:stmikseg
|
|
mov ax,es:_np_zinfo
|
|
mov bx,es:_np_row
|
|
mov cx,es:_np_ord
|
|
mov dx,-32
|
|
cmp es:_np_zplus,0
|
|
je @@1a
|
|
cmp es:_np_zplus,1
|
|
je @@1b
|
|
cmp es:_np_zplus,2
|
|
je @@1e
|
|
@@1eb: cmp bx,32
|
|
ja @@1b
|
|
@@1e: mov dx,bx
|
|
cmp dx,32
|
|
jb @@1a
|
|
mov dx,-32
|
|
jmp @@1a
|
|
@@1b: ;plus coming
|
|
mov dx,bx
|
|
sub dx,64
|
|
cmp dx,-32
|
|
jge @@1a
|
|
mov dx,-32
|
|
@@1a: mov bx,es:_np_row
|
|
pop es
|
|
ELSE
|
|
cmp cs:passmuscode,0
|
|
jne @@1
|
|
xor ax,ax
|
|
ENDIF
|
|
ret
|
|
@@1: mov cs:passmuscode,0
|
|
ret
|
|
muscode_6 ENDP
|
|
|
|
;entry: AX=number of copper interrupt to capture:
|
|
; 0=after display start (about scan line 25)
|
|
; 1=just before retrace (AVOID USING THIS IF POSSIBLE)
|
|
; 2=in the retrace
|
|
; DX:CX=far pointer to routine (0:0=remove routine)
|
|
; The routine pointed to must end in a RETF. It must save any
|
|
; 386 registers it uses (including FS/GS)
|
|
; exit: -
|
|
;descr: sets the specified copper interrupt to call the specified routine.
|
|
; IMPORTANT: The part must reset the copper int before it exits!
|
|
setcopper_7 PROC NEAR
|
|
IFDEF INDEMO
|
|
or dx,dx
|
|
jnz @@1
|
|
or cx,cx
|
|
jnz @@1
|
|
mov dx,cs
|
|
mov cx,OFFSET copper_intretf
|
|
@@1: cmp ax,0
|
|
jne @@2
|
|
mov word ptr cs:copper_int0[0],cx
|
|
mov word ptr cs:copper_int0[2],dx
|
|
@@2: cmp ax,1
|
|
jne @@3
|
|
mov word ptr cs:copper_int1[0],cx
|
|
mov word ptr cs:copper_int1[2],dx
|
|
@@3: cmp ax,2
|
|
jne @@4
|
|
mov word ptr cs:copper_int2[0],cx
|
|
mov word ptr cs:copper_int2[2],dx
|
|
@@4: ENDIF
|
|
ret
|
|
setcopper_7 ENDP
|
|
|
|
;entry: AX=area (0..3) containing the saved VGA state.
|
|
; exit: -
|
|
;descr: Quicksets the desired vga mode (takes one frame)
|
|
fastvmode_8 PROC NEAR ;DOESN'T WORK!-(
|
|
IFDEF INDEMO
|
|
push si
|
|
push ds
|
|
call msgarea_5 ;dx:ax=ds:ax
|
|
mov si,ax
|
|
mov ax,cs
|
|
mov ds,ax
|
|
;data now at ds:si
|
|
push si
|
|
call waitb_1
|
|
pop si
|
|
mov dx,3dah
|
|
in al,dx
|
|
;Syncronous reset
|
|
mov dx,3c4h
|
|
mov ax,0200h
|
|
out dx,ax
|
|
;Clear CRTC protection flag
|
|
mov dx,3d4h
|
|
mov al,011h
|
|
out dx,al
|
|
inc dx
|
|
in al,dx
|
|
and al,not 128
|
|
out dx,al
|
|
;Set misc register
|
|
mov al,ds:[si]
|
|
inc si
|
|
mov dx,3c2h
|
|
out dx,al
|
|
;Set Sequencer (3C4)
|
|
mov dx,3c4h
|
|
xor al,al
|
|
REPT 04h+1
|
|
mov ah,ds:[si]
|
|
inc si
|
|
out dx,ax
|
|
inc al
|
|
ENDM
|
|
;Set CRTC (3D4)
|
|
mov dx,3d4h
|
|
xor al,al
|
|
REPT 018h+1
|
|
mov ah,ds:[si]
|
|
inc si
|
|
out dx,ax
|
|
inc al
|
|
ENDM
|
|
;Set GFX controller (3CE)
|
|
mov dx,3ceh
|
|
xor al,al
|
|
REPT 08h+1
|
|
mov ah,ds:[si]
|
|
inc si
|
|
out dx,ax
|
|
inc al
|
|
ENDM
|
|
;Set Attribute controller (3C0)
|
|
mov dx,3dah
|
|
in al,dx
|
|
mov dx,3c0h
|
|
zzz=0
|
|
REPT 014h+1
|
|
mov al,zzz
|
|
out dx,al
|
|
mov al,ds:[si]
|
|
out dx,al
|
|
inc si
|
|
zzz=zzz+1
|
|
ENDM
|
|
;Enable display, enable PEL mask
|
|
mov dx,3c0h
|
|
mov al,20h
|
|
out dx,al
|
|
mov dx,3c6h
|
|
mov al,0ffh
|
|
out dx,al
|
|
pop ds
|
|
pop si
|
|
ELSE
|
|
mov ax,13h
|
|
int 10h
|
|
ENDIF
|
|
ret
|
|
fastvmode_8 ENDP
|
|
|
|
;entry: AX=1 : set frame to DX
|
|
; AX=0 : read frame to AX
|
|
; exit: AX=frame)
|
|
;descr: controls/returns music frame numbers
|
|
musframe_9 PROC NEAR
|
|
IFDEF INDEMO
|
|
push es
|
|
mov es,cs:stmikseg
|
|
cmp ax,0
|
|
je @@1
|
|
mov es:_np_zframe,dx
|
|
@@1: mov ax,es:_np_zframe
|
|
pop es
|
|
ELSE
|
|
xor ax,ax
|
|
ENDIF
|
|
ret
|
|
musframe_9 ENDP
|
|
|
|
IFDEF INDEMO
|
|
ordersync1 LABEL BYTE ;startpart
|
|
dw 0000h,0
|
|
dw 0200h,1
|
|
dw 0300h,2
|
|
dw 032fh,3
|
|
dw 042fh,4
|
|
dw 052fh,5
|
|
dw 062fh,6
|
|
dw 072fh,7
|
|
dw 082fh,8
|
|
dw 0900h,9
|
|
dw 0d00h,10
|
|
;dw 0800h,8
|
|
;dw 0c00h,9
|
|
;dw 0f00h,10
|
|
dw 3d00h,1
|
|
dw 3f00h,2
|
|
dw 4100h,3
|
|
dw 4200h,4
|
|
ENDIF
|
|
|
|
sync_10 PROC NEAR
|
|
IFDEF INDEMO
|
|
mov es,cs:stmikseg
|
|
mov dh,byte ptr es:_np_ord
|
|
mov dl,byte ptr es:_np_row
|
|
mov bx,OFFSET ordersync1
|
|
mov cx,16
|
|
@@2: cmp dx,cs:[bx]
|
|
jbe @@1
|
|
add bx,4
|
|
loop @@2
|
|
@@1: mov ax,cs:[bx-2]
|
|
ENDIF
|
|
ret
|
|
sync_10 ENDP
|