planet-strike/ID_SD_A.ASM
2013-07-08 00:00:00 +00:00

538 lines
9.6 KiB
NASM

;
; ID_SD_A.ASM
; Id Sound Manager assembly stuff
.286C
IDEAL
MODEL MEDIUM,C
JUMPS
INCLUDE 'ID_SD.EQU'
DEBUG = 0
EXTRN SDL_DigitizedDone:FAR
EXTRN alOut:FAR
;============================================================================
DATASEG
EXTRN sqActive:WORD
EXTRN ssSample:DWORD
EXTRN ssLengthLeft:WORD
EXTRN ssControl:WORD
EXTRN ssStatus:WORD
EXTRN ssData:WORD
EXTRN ssOn:BYTE
EXTRN ssOff:BYTE
EXTRN pcSound:DWORD
EXTRN pcLengthLeft:WORD
EXTRN pcLastSample:BYTE
EXTRN pcSoundLookup:WORD
EXTRN alSound:DWORD
EXTRN alBlock:WORD
EXTRN alLengthLeft:WORD
EXTRN alTimeCount:DWORD
EXTRN sqHack:DWORD
EXTRN sqHackPtr:DWORD
EXTRN sqHackLen:WORD
EXTRN sqHackSeqLen:WORD
EXTRN sqHackTime:DWORD
EXTRN sqPlayedOnce:WORD
EXTRN HackCount:WORD
EXTRN TimeCount:WORD
EXTRN LocalTime:WORD
EXTRN TimerCount:WORD
EXTRN TimerDivisor:WORD
EXTRN t0OldService:DWORD
EXTRN SoundMode:WORD
EXTRN DigiMode:WORD
EXTRN SoundNumber:WORD
EXTRN SoundPriority:WORD
count_time dw ?
count_fx dw ?
IF 0
pcdtab db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
db 10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
ENDIF
;============================================================================
CODESEG
MyDS dw ?
pcindicate dw ?
extreme dw ?
PROC SDL_SetDS
PUBLIC SDL_SetDS
mov ax,ds
mov [cs:MyDS],ds
ret
ENDP
;
; COMMONSTART
; Macro used for common prefix code
;
MACRO COMMONSTART
IF DEBUG
push dx
push ax
mov dx,STATUS_REGISTER_1
in al,dx
mov dx,ATR_INDEX
mov al,ATR_OVERSCAN
out dx,al
mov al,4 ; red
out dx,al
ENDIF
push ds
push ax
mov ds,[cs:MyDS]
inc [HackCount]
ENDM
;
; DOFX
; Macro used to do the sound effects code
;
MACRO DOFX
les di,[pcSound] ; PC sound effects
mov ax,es
or ax,di
jz @@nopc ; nil pointer - no PC sound effect going
mov bl,[es:di] ; Get the byte
inc [WORD PTR pcSound] ; Increment pointer
cmp [pcLastSample],bl ; Is this sample the same as last?
jz @@pcsame ; Yep - don't do anything
mov [pcLastSample],bl ; No, save it for next time
or bl,bl
jz @@pcoff ; If 0, turn sounds off
xor bh,bh
shl bx,1
mov bx,[pcSoundLookup+bx] ; Use byte as index into frequency table
mov al,0b6h ; Write to channel 2 (speaker) timer
out pcTAccess,al
mov al,bl
out pcTimer,al ; Low byte
mov al,bh
out pcTimer,al ; High byte
in al,pcSpeaker ; Turn the speaker & gate on
or al,3
out pcSpeaker,al
jmp @@pcsame
@@pcoff:
in al,pcSpeaker ; Turn the speaker & gate off
and al,0fch ; ~3
out pcSpeaker,al
@@pcsame:
dec [pcLengthLeft] ; Decrement length
jnz @@nopc ; If not 0, we're not done with the sound
mov ax,0
mov [WORD PTR pcSound],ax ; Zero the pointer
mov [WORD PTR pcSound + 2],ax
mov [SoundNumber],ax ; Indicate no sound
mov [SoundPriority],ax ; with no priority
in al,pcSpeaker ; Turn the speaker off
and al,0fdh ; ~2
out pcSpeaker,al
@@nopc:
les di,[alSound] ; AdLib sound effects
mov ax,es
or ax,di
jz @@noal ; nil pointer - no AdLib effect going
xor ah,ah
mov al,[es:di]
or al,al
jz @@aldone
CALL alOut C,alFreqL,ax
mov ax,[alBlock]
@@aldone:
CALL alOut C,alFreqH,ax
inc [WORD PTR alSound]
dec [alLengthLeft]
jnz @@noal
mov ax,0
mov [WORD PTR alSound],ax ; Zero the pointer
mov [WORD PTR alSound + 2],ax
mov [SoundNumber],ax ; Indicate no sound
mov [SoundPriority],ax ; with no priority
CALL alOut C,alFreqH,ax ; Turn off the sound
@@noal:
ENDM
;
;
;
MACRO TIME
cmp [count_time],2
jb @@notime
add [LocalTime],1
adc [LocalTime+2],0
add [TimeCount],1
adc [TimeCount+2],0
mov [count_time],0
@@notime:
ENDM
;
; COMMONEND
; Macro used for common suffix code
;
MACRO COMMONEND
@@fullexit:
pop es
popa
@@nosave:
mov ax,[TimerDivisor]
add [TimerCount],ax
jnc @@myack
pushf
call [t0OldService]
jmp @@out
@@myack:
mov al,20h
out 20h,al
@@out:
pop ax
pop ds
IF DEBUG
mov dx,STATUS_REGISTER_1
in al,dx
mov dx,ATR_INDEX
mov al,ATR_OVERSCAN
out dx,al
mov al,3 ; blue
out dx,al
mov al,20h ; normal
out dx,al
pop ax
pop dx
ENDIF
iret
ENDM
IF 0
;
; SDL_IndicatePC
;
PROC SDL_IndicatePC on:WORD
PUBLIC SDL_IndicatePC
mov ax,[on]
mov [cs:pcindicate],ax
ret
ENDP
;
; SDL_t0ExtremeAsmService
; Timer 0 ISR 7000Hz interrupts
;
PROC SDL_t0ExtremeAsmService
PUBLIC SDL_t0ExtremeAsmService
push ax
mov al,[BYTE PTR cs:pcindicate]
or al,al
jz @@done
push ds
push es
pusha
mov ds,[cs:MyDS]
les di,[pcSound]
mov ax,es
or ax,di
jz @@donereg ; nil pointer
mov bl,[es:di] ; Get the byte
inc [WORD PTR pcSound] ; Increment pointer
and bl,11100000b ; Nuke some of the precision (DEBUG - do this in the table)
xor bh,bh
mov ah,[pcdtab+bx] ; Translate the byte
in al,pcSpeaker
and al,11111100b
or al,ah
out pcSpeaker,al
dec [pcLengthLeft]
jnz @@donereg
mov [WORD PTR pcSound],0 ; We're done with this sample
mov [WORD PTR pcSound+2],0
in al,pcSpeaker
and al,11111100b
out pcSpeaker,al
call SDL_DigitizedDone
@@donereg:
popa
pop es
pop ds
@@done:
inc [cs:extreme]
cmp [cs:extreme],10
jae @@tofast
mov al,20h
out 20h,al
pop ax
iret
@@tofast:
mov [cs:extreme],0
pop ax
; jmp SDL_t0FastAsmService ; Drops through to SDL_t0FastAsmService
ENDP
ENDIF
;
; SDL_t0FastAsmService
; Timer 0 ISR for 700Hz interrupts
;
PROC SDL_t0FastAsmService
PUBLIC SDL_t0FastAsmService
COMMONSTART
inc [count_fx] ; Time to do PC/AdLib effects & time?
cmp [count_fx],5
jae @@dofull
mov ax,[sqActive] ; Is the sequencer active?
or ax,ax
jnz @@dofull
mov ax,[WORD PTR ssSample] ; Is there a sample for the Sound Src?
or ax,[WORD PTR ssSample+2]
jz @@nosave
@@dofull:
pusha
push es
cmp [count_fx],5
jb @@nofx
mov [count_fx],0
DOFX
inc [count_time]
TIME
@@nofx:
mov ax,[sqActive]
or ax,ax
jz @@nosq
mov ax,[sqHackLen]
or ax,ax
jz @@sqdone
les di,[sqHackPtr]
@@sqloop:
mov ax,[WORD PTR sqHackTime+2]
cmp ax,[WORD PTR alTimeCount+2]
ja @@sqdone
mov ax,[WORD PTR sqHackTime]
cmp ax,[WORD PTR alTimeCount]
ja @@sqdone
mov ax,[es:di+2] ; Get time to next event
add ax,[WORD PTR alTimeCount]
mov [WORD PTR sqHackTime],ax
mov ax,[WORD PTR alTimeCount+2]
adc ax,0
mov [WORD PTR sqHackTime+2],ax
mov ax,[es:di] ; Get register/value pair
xor bh,bh
mov bl,ah
xor ah,ah
CALL alOut C,ax,bx
add di,4
mov [WORD PTR sqHackPtr],di
sub [sqHackLen],4
jnz @@sqloop
@@sqdone:
add [WORD PTR alTimeCount],1
adc [WORD PTR alTimeCount+2],0
mov ax,[sqHackLen]
or ax,ax
jnz @@nosq
mov ax,[WORD PTR sqHack] ; Copy pointer
mov [WORD PTR sqHackPtr],ax
mov ax,[WORD PTR sqHack+2]
mov [WORD PTR sqHackPtr+2],ax
mov ax,[sqHackSeqLen] ; Copy length
mov [sqHackLen],ax
mov [WORD PTR sqPlayedOnce],1
mov ax,0
mov [WORD PTR alTimeCount],ax ; Reset time counts
mov [WORD PTR alTimeCount+2],ax
mov [WORD PTR sqHackTime],ax
mov [WORD PTR sqHackTime+2],ax
@@nosq:
les di,[ssSample] ; Get pointer to Sound Source sample
mov ax,es
or ax,di
jz @@ssdone ; If nil, skip this
@@ssloop:
mov dx,[ssStatus] ; Check to see if FIFO has any empty slots
in al,dx
test al,40h
jnz @@ssdone ; Nope - don't push any more data out
mov dx,[ssData]
mov al,[es:di] ; al = *ssSample
out dx,al ; Pump the value out
mov dx,[ssControl] ; Pulse printer select
mov al,[ssOff]
out dx,al
push ax
pop ax
mov al,[ssOn]
out dx,al
push ax ; Delay a short while
pop ax
inc di
mov [WORD PTR ssSample],di ; ssSample++
dec [ssLengthLeft]
jnz @@ssloop
mov [WORD PTR ssSample],0 ; We're done with this sample
mov [WORD PTR ssSample+2],0
call SDL_DigitizedDone
@@ssdone:
COMMONEND
ENDP
;
; SDL_t0SlowAsmService
; Timer 0 ISR for 140Hz interrupts
;
PROC SDL_t0SlowAsmService
PUBLIC SDL_t0SlowAsmService
IF DEBUG
push dx
push ax
mov dx,STATUS_REGISTER_1
in al,dx
mov dx,ATR_INDEX
mov al,ATR_OVERSCAN
out dx,al
mov al,4 ; red
out dx,al
ENDIF
push ds
push ax
mov ds,[cs:MyDS]
inc [count_time]
TIME
mov ax,[WORD PTR pcSound] ; Is there a PC sound effect going?
or ax,[WORD PTR pcSound+2]
jnz @@dofull
mov ax,[WORD PTR alSound] ; Is there an AdLib sound effect going?
or ax,[WORD PTR alSound+2]
jz @@nosave
@@dofull:
pusha
push es
DOFX
COMMONEND
ENDP
END