| www.retrosoftware.co.uk http://www.retrosoftware.co.uk/forum/ |
|
| How do you program sounds direct to the Hardware? http://www.retrosoftware.co.uk/forum/viewtopic.php?f=73&t=744 |
Page 1 of 1 |
| Author: | PitfallJ [ Tue Feb 28, 2012 3:43 pm ] |
| Post subject: | How do you program sounds direct to the Hardware? |
Hi, So how do you program sounds direct to the Hardware. I guess I would lose envelope support but I reckon I could write something myself - and it would also free up page 8 for my own use. I've been trying to finish a mini-game I've been working on which is a Mode2 side scroller and I've been finding when I exceed a frame the displays gets all corrupted. (Probably because the screen scrolls too far and doesn't get deleted at the edge.) Anyway - time is very important - RTW's hardware keyscan code made a great difference so I was thinking replacing the OSWORD sound calls I make would make a difference as well - I'm right on the edge of the 50th and I'm playing 2 track music. In fact if you press loads of keys simultaneously it frames-out so I'm thinking the system IRQ handler (which I pass on to) is up to something and I'd like to get rid of it. I discovered reading FE45 gives me a clock I can time code with like this: Code: LDA &FE45 STA clk1 JSR _MAINLOOP LDA &FE45 STA clk2 When it gets to $1A I'm out of time. Following on from sound I guess it would would useful to know how to read the joystick and set the palette in Hardware as well - I think that would just about cover everything! - PJ |
|
| Author: | RichTW [ Tue Feb 28, 2012 9:22 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
I don't have time to go into much detail now, but just to say that if you need the extra speed push, then getting rid of the OS IRQ handler is certainly the way to go. Writing your own sound handler is not really tricky, but be warned that the code and related tables will certainly take up more space than you would save by freeing up page 8. Prettty much everything you need to know about programming the sound chip is in the AUG at page 419 onwards. Note that it's addressed via the System VIA Port A (&FE41/&FE4F) along with the keyboard, so you have to disable the keyboard by writing 11 to &FE40 before doing the sound chip writes. Have a look at my Blurp blog entry on sound - http://www.retrosoftware.co.uk/wiki/ind ... ry20101102 - and the old forum post of mine that I linked to, which might help a bit. When I have more time, I can try to expand on some of this, but it's quite a big topic which can hardly be done justice in a small reply... |
|
| Author: | PitfallJ [ Wed Feb 29, 2012 4:58 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
Hi, Thanks for that - I now have music playing direct to the hardware and cycles to spare! That saved the day. Here's my code - I'd appreciate any comments: Code: .freq_sel: EQUB &E0,&C0,&A0,&80 .volume_sel: EQUB &F0,&D0,&B0,&90 ; ; ; X - midi note ; Y - channel ; ._MAKE_SOUND_HW: SEI ; Set all portA bits as output LDA #&FF STA &FE43 ; channel select + freq low LDA midi2bbc_low,X ORA freq_sel,Y JSR _DIRECT0 ; freq high LDA midi2bbc_high,X JSR _DIRECT0 ; channel + volume LDA volume_sel,Y JSR _DIRECT0 CLI RTS ._DIRECT0: STA &FE41 ;set volume or frequency in DataPort A LDA #0 STA &FE40 ;\Output register B NOP NOP NOP NOP LDA #8 STA &FE40 ;\Output register B RTS The midi2bbc tables are based on: table = 4,000,000 / (32 * frequency) low is value&15 and high is value>>4 The codes based on the AUG example. I'm not sure why I have to toggle a bit on $FE40 but it doesn't seem to work without it. I didn't seem to need to do: Code: LDA #11 ;(that 11 is decimal isn't it?) STA $FE40 Just need to make some envelope type control now... -PJ |
|
| Author: | RichTW [ Wed Feb 29, 2012 5:12 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
Yep, that looks fine. I'd be inclined to add an extra NOP between pulling the sound enable low and high, to guarantee that 16us passes ok. As for why it's necessary, Tom Walker once told me the reason: Tom Walker wrote: Internally the SN chip divides the incoming clock (4mhz) by 32, which it then uses to clock everything else. I guess it only checks the write signal for a high->low transition at one point (presumably the beginning), so you need to hold it for a whole 32 cycles (16 from the 6502 point of view) to ensure it actually sees it. So now we know.It's only necessary to set keyboard enable high (by writing &0B to &FE40) if you've previously pulled it low (by writing &03 to &FE40) in order to read keys. If you do that anyway after checking for keypresses, all will be well. Be careful if you're handling sound inside an interrupt routine though, because if your key checking code is interrupted, this will screw up. Two solutions: either disable interrupts around your key checking code, or (better), move your key checking code into the VSync interrupt and have it set bits in a location which can be polled in your main loop. The advantage of this approach is also that your interrupt routine can put the results of the joystick control into the same bits, and so your main loop will get joystick control "for free". |
|
| Author: | RichTW [ Wed Feb 29, 2012 5:38 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
Joystick control by direct hardware access is a bit of a pain by the way. Main problem is that the ADC hardware lives in a different location on BBCs and Masters, so you'll have to take that into account, depending on the results of OSBYTE 0. The joystick fire button is easy: this just comes from bit 4 of &FE40 (remembering to configure bits 4-7 as read bits by writing &0F to &FE42). Reading the joystick direction is a bit more involved. You have to set off two ADC conversions, one on channel 0 (X direction) and the other on channel 1 (Y direction). If you do this in 8 bit mode, the results will arrive more quickly. Here's how Blurp does it (I assemble &FEC0 as the address of the ADC, like a BBC B, and self-modify this to &FE18 at startup if it's running on a Master): At initialisation time (once only): 1) turn off interrupts 2) poll bit 6 of FEC0 and wait for it to be clear (this signifies that an ADC conversion is already in process - you want to ignore the interrupt that this would generate, and as far as I know, there's no way to abort/cancel the conversion). 3) write &10 to &FE4D to clear the ADC interrupt flag 4) write &90 to &FE4E to enable ADC interrupts In the VSync IRQ handler: 1) Poll joystick button. If pressed (bit 4 of FE40 clear), this means that a joystick is connected (force the fire button to be pressed by insisting on "Press SPACE or FIRE" to begin 2) If a joystick is connected, write 0 to &FEC0. This sets off an ADC conversion on channel 0 with 8-bit precision. When the conversion is finished, an interrupt will be generated which you can check at the beginning of your handler. In the ADC IRQ handler: 1) Acknowledge the ADC IRQ by reading from &FE40 and throwing away the result. 2) Load &FEC0. Bit 0 tells us if the result is from ADC channel 0 or 1. 3) If it's channel 0, then bits 4-5 tell us whether the joystick is left, centred or right: Code: 00 = right (I think) Then write 1 to &FEC0 to start an ADC conversion on channel 1.11 = left 01 or 10 = centred. 4) If it's channel 1, then read bits 4-5 to tell whether the joystick is up, centred or down. Bit of a brisk overview but hopefully you get the idea. Incidentally, even if you're doing it OS-legally, there are some things you can do to get slightly better performance: OSBYTE 16 with X=2 will ensure that only 1 joystick is polled OSBYTE 190 with X=8 will do 8 bit conversion which is much quicker. |
|
| Author: | PitfallJ [ Sun Apr 01, 2012 3:16 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
So.... I finally got round to running the direct sound access code on a real BBC (a master) and would you believe it but it doesn't work. Even worse it works fine in the emulators but not on the real thing. I've been hammering away at it for more than a day now and can't solve it.... it seems like if I change the frequency and volume at the same time the sound chip only picks up the last thing I do. Also it seems to prefer it if I do it in the Interrupt and not outside. (Even with SEI/CLI covering the code). I even checked the OS disassembly to see what that's doing and changed my access code to what they are using: Code: ._DIRECT1: ;; SEI STY tempyy LDY #&FF ;System VIA port A all outputs STY &FE43 ;set STA &FE4F ;output A on port A INY ;Y=0 STY &FE40 ;enable sound chip LDY #&02 ;set and .rloopa: DEY ;execute short delay BNE rloopa LDY #&08 ;then disable sound chip again STY &FE40 ; LDY #&04 ;set delay .rloopb: DEY ;and loop delay BNE rloopb LDY tempyy ;; CLI RTS ;and exit I notice they use $FE4F instead of $FE41 - I'm not sure what the difference is there. My setting code is like follows: Code: LDA volumea ORA #&90 JSR _DIRECT1 LDX freqa LDA Midi2bbc_low,X ORA #&80 JSR _DIRECT1 LDA Midi2bbc_high,X JSR _DIRECT1 ...similarly for the other two channels. The only other thing I've tried is adding this at the top Code: LDA #&0F STA &FE42 to write enable the latch register at $FE40 |
|
| Author: | RichTW [ Sun Apr 01, 2012 6:16 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
If you have the keyboard enabled for reading, make sure to disable it before writing to the sound chip, with Code: LDA #15
STA &FE42 LDA #11 STA &FE40 |
|
| Author: | PitfallJ [ Sun Apr 01, 2012 6:35 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
Man ..... Thanks! Thanks! Thanks! It work's perfectly now - I was totally stuffed before - didn't have a clue what was wrong... so frustrating - so I wonder what's wrong with B-em and Beebem? I if ever finish my project (which is a lot closer to being finished now...) they can be tested with my disk. Thanks again - I'm sooo happy. - PJ |
|
| Author: | TomW [ Sun Apr 01, 2012 8:59 pm ] |
| Post subject: | Re: How do you program sounds direct to the Hardware? |
PitfallJ wrote: so I wonder what's wrong with B-em and Beebem? Neither currently emulate contention on the slow data bus. What causes the issue is that the System VIA is trying to drive the bus with the sound data, but the keyboard is also driving it with that data. The result is a mess. The in-progress B-em v2.2 does emulate contention, and hence this fails like on a real beeb! |
|
| Page 1 of 1 | All times are UTC [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|