SecondReality/DIS/DISINT.ASM
2017-09-24 01:45:36 +02:00

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