Hello i'm writing a game for school project and i'm having problems to play an audio file. I was able to play the file but the problem is that then the program freezes and stop responding to the user
The music file code
proc read Near ; Read next sample
push bx
push cx
push dx
mov ah, 3Fh
mov bx, [filehandle]
mov cx, 1
lea dx, [Buffer]
int 21h
jc errorcode
mov al, [Buffer]
xor ah, ah
mov bx, 54
mul bx
; mov ax, dx ; Result is in DX because we need to div by 65536 which is all of AX
shr ax, 8
pop dx
pop cx
pop bx
ret
endp
proc br Near; Print line break
push dx
push ax
mov dl, 10
mov ah, 2
int 21h
mov dl, 13
mov ah, 2
int 21h
pop ax
pop dx
ret
endp
proc PlayMusic Near
mov ah, 3Dh
xor al, al
lea dx, [filename]
int 21h
mov [filehandle], ax
call br
mov al, 90h
out 43h, al
in al, 61h
or al, 3
out 61h, al
cli
mov ax, 0
totalloop:
call read ; Read file
out 42h, al ; Send data
mov bx, ax
mov cx, [delay]
portloop:
loop portloop
mov ax, bx
out 42h, ax ; Send data
mov cx, [delay]
rloop:
loop rloop
call read
jmp totalloop
ret
errorcode:
; Close
sti
mov al, 86h
out 43h, al
mov ah, 3Eh
mov bx, [filehandle]
int 21h
pop dx
pop cx
pop bx
ret
endp PlayMusic
and after i call this proc i'm calling int 16h to read a key from the user but the music file blocks the IO someone have an idea what I need to do? sorry for my bad English by the way and i'm kind of new in assembly so i'm not so good
What you want to do is "parallelize" your game code (without using threads). There are few options on how to do this:
interleave the code
This is the easiest way to implement. So you should have your game architecture like this:
This architecture will allow the game to run all its task in "parallel". If your tasks are slower you can interleave the music a bit more
if any task is really slow then you need to interleave the sound into it directly otherwise you would have choppy sound. Here is an example of this (without sound):
And this is with sound (but not a game):
You need to make your keyboard test non blocking. Taken from my No Signal demo it is done like this:
play the sound using PIT as generator
I did not use this but IIRC the PIT can be configured to play a constant frequency with the speaker. So instead of setting Speaker on/off you just set its frequency per each frame or so ... This will play in the background during which time the CPU can do other stuff...
play the sound in background using PIT as timer
For much better timing and playing the sound in the background parallel to your game code you can move the sound playing to the PIT ISR entirely which can operate at
1193180.0/16bit_divider Hz
so set the PIT to target sound sampling frequency. Set the ISR for it and fetch/play single bit in it....If you use PWM and multiple of sampling frequency you can turn Speaker into DAC playing even PCM
*.wav
files.In this case you do not have the sound code interleaved in the game loop at all.
DO NOT FORGET TO SET PIT FREQUENCY BACK TO 18.2 Hz BEFORE EXIT because MS-DOS and games use it for timing. Many games can be speed-up by changing the PIT frequency alone. Also when you change PIT frequency and ISR it is a good idea to call the original ISR with 18.2Hz frequency from your new ISR.
For more info about PC MS-DOS and games see:
*.hlp
format (you needWindows6.1-KB917607
patch for Win7+ as they stopped supporting it)This is the best for starting with assembly I know of:
but it is in Czech for Z80 CPU and I do not know of any translations ....