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