Post by Shiru on Dec 31, 2007 3:26:35 GMT -5
Ok, finally it here - my first program in pure BEX, which I wrote today (never used BEX before). It is a simple replayer of *.tfd files, which can be exported from TFM Music Maker (SMD-compatible music cross-editor, you can get it on my homepage). With this code you can add music to your BEX programs.
There is no *.tfc (much smaller files) replayer, which available in Z80 assembly and C versions, and there is reason: BEX does not work on my computer, but works on second, which is pretty slow laptop with Vista. So I wrote code on my computer without any testing, and then debugged it on laptop. That took many iterations and was very uncomfortable, so I don't plan to do anything more in BEX until it will work on my computer.
Code still has one unsolved problem. By some reasons, when I try to do busreq on/off in replayer's update function, code is hangs (see for two commented lines). I left this problem to you, fix it if you want to run your code on real console (without fix it will work fine in emulator only).
There is no *.tfc (much smaller files) replayer, which available in Z80 assembly and C versions, and there is reason: BEX does not work on my computer, but works on second, which is pretty slow laptop with Vista. So I wrote code on my computer without any testing, and then debugged it on laptop. That took many iterations and was very uncomfortable, so I don't plan to do anything more in BEX until it will work on my computer.
Code still has one unsolved problem. By some reasons, when I try to do busreq on/off in replayer's update function, code is hangs (see for two commented lines). I left this problem to you, fix it if you want to run your code on real console (without fix it will work fine in emulator only).
'Simple replayer for TFD files exported from TFM Music Maker
'Pure BEX version by Shiru, 31.12.07
'How to use:
' Load your music module into editor, File->Export->TFD file for SMD.
' Now you can use resulted file with this replayer. File can be large
' because no compression used, usually it has size from tens up to
' hundreds of KB, depending from music module (more slides and volume
' effects - larger module)
cls
ink 1
locate 1,1
print "TFD music replayer"
reload musicData 'point to music data (needed only once, right before init)
gosub tfdPlayInit 'init replayer
on VBLANK gosub tfdPlayFrame
enable INTERRUPTVBLANK
mainLoop:
sleep 1 'main loop of your program
goto mainLoop
'Replayer init. Set data read pointer to music data (by RELOAD or RESTORE)
'and GOSUB here. It needed once before playing
tfdPlayInit:
DataPtr&=DataPtr&()+4 'skip TFMD signature
for a=1 to 3 'skip three null-terminated text lines
while 1
read b
if b=0 then exit while
wend
next
vTfdDataPtr&=DataPtr&() 'store current read position
vTfdLoopPtr&=vTfdDataPtr& 'default loop position
vTfdCurrentBank=0 'select bank0
vTfdFrameCnt=0 'frame counter
vTfdWaitCnt=0 'wait counter
pokeint &hA11100,&h100 'busreq on
pokeint &hA11200,&h100 'reset Z80 and YM2612
pokeint &hA11200,0
pokeint &hA11100,0 'busreq off
return
'Replayer update. GOSUB here each frame (1/50sec) to play music.
'Note that for NTSC system you must do speed compensation to
'make music play at normal speed. In this example that done
'simply by skipping every 6th frame
tfdPlayFrame:
vTfdFrameCnt++ 'increment frame counter
if TvType()=0 then 'speed compensation for NTSC
if vTfdFrameCnt%6=0 then return
endif
if vTfdWaitCnt then 'skip frames if needed
vTfdWaitCnt--
else
vTfdDataTemp&=DataPtr&() 'store current read position
DataPtr&=vTfdDataPtr& 'set read position of music data
while 1
read vTag
if vTag<&hFA then 'write to YM2612 register
read vData 'read data
if vTag<&h30 then
curBank=0 'writes below 0x30 always goes to bank0
else
curBank=vTfdCurrentBank
endif
adrReg&=&hA04000+curBank
adrVal&=&hA04001+curBank
if vTag=&h28 then 'correction for bank1 Key On/Off event
if vTfdCurrentBank then
vData=vData+4
endif
endif
'pokeint &hA11100,&h0100 'busreq on
while peek(&hA04000).7 'wait for busy
wend
poke adrReg&,vTag 'write YM2612 register number
while peek(&hA04000).7 'wait for busy
wend
poke adrVal&,vData 'write YM2612 register data
'pokeint &hA11100,&h0000 'busreq off
elseif vTag=&hFF then 'single frame
vTfdCurrentBank=0
exit while
elseif vTag=&hFE then 'few frames
vTfdCurrentBank=0
read vTfdWaitCnt
vTfdWaitCnt=vTfdWaitCnt+2
exit while
elseif vTag=&hFD then 'select bank1
vTfdCurrentBank=2
elseif vTag=&hFC then 'select bank0
vTfdCurrentBank=0
elseif vTag=&hFB then 'end of data
DataPtr&=vTfdLoopPtr& 'jump to loop position
elseif vTag=&hFA then 'loop position
vTfdLoopPtr&=DataPtr&() 'remember read position
endif
wend
vTfdDataPtr&=DataPtr&() 'store read position of music data
DataPtr&=vTfdDataTemp& 'restore current read position
endif
return
musicData:
datafile music.tfd,BIN