|
Post by jday6809 on Sept 30, 2022 16:52:19 GMT -5
Alright, so...here's a tough problem that only presents itself in the actual hardware, but works correctly in VIDE. My hunch is that by adding 3 channel sound effects / music, I've messed up the joystick 1 polling somehow. Can sound channel manipulation interfere with joystick readings? General details follow:
On both hardware and Vide, Joystick 1 button one ($C812) and button two ($C813) correctly show #0 when no buttons are pressed during my custom menu screens. However, when I get to the action portion of my game... suddenly both buttons are non-zero ($C812 contains a #1) even though no button is pressed. They both show as #0 in Vide, but on hardware they are non-zero.
It was working fine on a previous version, but I changed a lot of code between versions. The main difference between the working version and the newer non-working version is that I added three channel dynamically changing 'music' and sound effects by manipulating the sound channels. Please ignore the horrible code that I'm about to show you...it's hacky, I copied some of it... but I was trying to get the right sound before cleaning it up and simplifying the weirdness. It does work and sound correctly in VIDE and the Hardware, but I'm thinking it might be part of the problem with my Joystick readings on actual hardware. Just hard to fix, when everything runs / reads perfectly in VIDE. Not shown below, but some of my sound code LDA / STA into $C807... that seems suspiciously close to Joystick memory space, right?
EngineNoise_V3:
lda shot_sound_flag ;Get shot Flag
bne do_shot_snd
lda jumping_counter
bne do_jump_snd
ldb EngineRPMs
aslb
aslb
negb
addb #-50
lda #$04 ;Select Register 4 (Voice 3 Frequency)
jsr $F256 ;Modify Register
ldb TurboSetting
negb
addb #10
lda #$05 ;Select Register 5 (Voice 3 Frequency)
jsr $F256 ;Modify Register
ldb #15 ;Volume=#$0f
lda #10 ;Register 10 (Voice 3 Volume)
jsr $F256 ;Modify Register rts
Thoughts? Need more info?
|
|
|
Post by Malban on Sept 30, 2022 18:49:40 GMT -5
First let me say, I know that Vide is in that "button" (PSG) department not 100% correct. I also have a report from gauze lying a few years here...
I just never looked at that (probably because I never had a problem ...). To explain the background about buttons and sound...
There is no "button" memory space or joystick memory space - in the sense that IO or states map directly to the location. The memory locations you mention: C812 ... are just that - memory locations. The BIOS writes to these when you call the joystick button routines.
Hardware wise the buttons are connected to the IO ports of the PSG (sound) chip. The BIOS button routine queries the PSG chip about its IO ports and puts the results (after masking etc) in the memory location you mentioned. So sound and buttons are handled actually by the same CHIP.
A possibly culprit is register 7, which handles not only the sound channels, but also whether the IO ports of the PSG are in INPUT/OUTPUT state. But it will not be as simple as that, because I'm pretty sure that this is emulated correctly.
Sounds "stupid" but does it behave differently on a real vectrex, when you have a joystick in the second joystick port? (one thing Vide does not emulate correctly is a "non plugged in second joystick" - because the real machine shows erratic behaviour reading the "empty" joystick port).
The code you displayed - does not explain anything (to me) :-(. However if you are willing to share the code - I can look at it and probably figure it out. But I would need the full code (or at least a fully working example code). If I find the issue I'll update Vide accordingly. (you have my email - don't you?)
Cheers Malban
|
|
|
Post by jday6809 on Sept 30, 2022 19:48:11 GMT -5
Thanks, Malban. I'll email you the full code later tonight. I'm still thrilled every time I jump into VIDE, it's remarkably accurate to the real hardware...so I really have no complaints. This is truly the first issue that I couldn't replicate in the emulated environment so that says a lot for the work you've done. . I'll try plugging in the 2nd joystick trick in a bit, and then I'll try to add some helpful code comments before sending my code along to you. No rush, I know you have a ton of other things going on in your life as well. Thanks in advance!
|
|
|
Post by jday6809 on Sept 30, 2022 20:52:48 GMT -5
Okay Malban,
I emailed the code to your vide contact email. Good luck, and no rush! Thanks for ALL you do for this community.
|
|
|
Post by jday6809 on Sept 30, 2022 22:27:40 GMT -5
Malban! You were right (of course). It was that register 7 issue. You see, I was switching the sound channels from tone to noise depending on whether I needed to do a certain sound effect or music. I did this by the following command:
ldb #$F8 (or D8, or whatever) lda #$07 the register that I want to set jsr $F256 the command that puts it all together and sets the 3 sound channels to that ldb setting.
Problem is, as you mentioned... register 7 affects the joystick as well (on real hardware). To test that, I just typed in:
ldb #$00 lda #$07 jsr $F256
and put it in the code right before the jsr wait_recal (for PracticeMode1 game-loop). Now my buttons work for a split second before the sound kicks in. Messes up the music, obviously... but at least I know how to get buttons working on my real Vectrex.
POST Correction:
Okay, just found a better solution... ldb #$38 (which is 00111000 binary for all 3 sound channels tone, no noise) lda #$07 jsr $F256
and I tried putting it after the wait_recal for PracticeMode1 game loop
Seems to work better. Now I have the correct sound, and the buttons work... but not...quite... as smooth. I'll keep playing around with re-arranging some code to remove the stutter that appears on actual hardware.
PracticeMode1:
CLR Vec_Music_Flag ; I cleared this, trying to get 0 in Vec_Button_1_1 CLR Vec_Btn_State ; I cleared this, trying to get 0 in Vec_Button_1_1 CLR TurnDirection CLR Gas_Pressed JSR Wait_Recal ldb #$38 lda #$07 jsr $F256 JSR Read_Btns LDA Vec_Button_1_1 BEQ button_1_1_not ...... everything else stays the same.
|
|
|
Post by Malban on Oct 1, 2022 3:36:28 GMT -5
Actually what you SHOULD do is the following:
ldb Vec_Snd_Shadow+7 ; read the shadow value of register 7 andb #%11000000 ; AND all bits you want to keep, clear all other orb #%00111000 ; set all bits that need setting ...
That way you insure you only set/clear bits that need setting/clearing and touch no other. Of course the "bits" must be fitted to you current setup.
If you play tunes in seperate channels and the channels do not know about each other, than
this is the only way to ensure each channel keeps its designated setup (tone/noise enabled/disabled).
Cheers Malban
|
|
|
Post by Malban on Oct 1, 2022 4:21:45 GMT -5
I'm starting to remember the difficulties I had with the output/input ports joystick wise - I just looked at the code. It is a paradox, which I can not explain.
Let me paint a picture of Vide's internal handling. Internally Vide has following entyties (classes)
- Vecx
- PSG - SerialPort - Joystick
The Vecx (Vectrex) has one PSG chip. The PSG "knows" the SerialPort, and into the serialport a device can be set (in your case a Joystick). If the PSG Register 7 is set in the PSG class, it messages the SerialPort the IO enable state - and thus the Joystick KNOWS that state.
The IO ports of the PSG can be read either from VecX (the vectrex querying the state of the buttons), or the states can be queried from Joystick (in case of the Joystick this does not make sense, but think of a VecVoice, which might be plugged into the Joystick port - that one also "reads" the ports from device direction).
The PSG can be set to input mode (data is expected from the external device - normal joystick mode!) or output mode (vectrex is sending data to the joystick port).
There are as such 4 different settings which must be considered handling "button" values:
1) from VecX, input mode (this is the normal joystick mode) 2) from Joystick, output mode (this is e.g. the VecVoice waiting for a command sequence from the vectrex) and two "illegal" states
3) from VecX, output mode (Vectrex is asking the buttons value, but the IO ports output TO the device)
4) from Joystick, input mode (VecVoice is expecting data from the Vectrex, but the IO ports are in input mode (receiving data from VecVoice))
The problem you are(were) having is, that you used state 3. It SHOULD be as you learned from your Vectrex, that the buttons are then not queried and you always read "no button pressed". Also that SEEMS to be the correct value (I tested it some time ago).
... and than comes Alex Herbert ... Let me quote my own documentation:
That is the paradox I can not explain. That should not be working - but it does. And because of that I implemented 3) so that Vide also knows the output state of the buttons, and these appear to work correctly.
I will implement a "hack" into Vide - that 3) will be handled "correctyl" if the "Serial port 0" is used and 3) will be handled "incorrectly" if "Serial port 1" is used.
This is hacky - but will work until programmers rediscover Port 1.
Cheers Malban
|
|
|
Post by jday6809 on Oct 3, 2022 9:48:45 GMT -5
Malban, Thanks for detailing all this out! I had been simply copying and pasting code from some of the VIDE examples without really digging into what was going on. Had a bit of a chance to dig in a bit more this weekend and found this site as well. roadsidethoughts.com/vectrex/vectrex-programmable-sound-generator.htmSo, I'm a bit confused. According to my understanding of the site above...$OE is the register that controls psg input/output mode, and later on in the page it mentions that bits 6 and 7 determine the input / output direction. From my experience (and from what you described so well above), just changing bits 6 and 7 to zero in my case allowed the joystick inputs to be read. However... further reading in www.msx.org/wiki/PSG_Registers (for MSX computers, NOT Vectrex... but maybe similar in regards to PSG) it seems that the writer recommends register 6 (port A) be set to 0 (input) and register 7 (port b) to 1 (output) for proper functioning. So does that sound like the proper setup for the Vectrex to you? But I'm also confused, because both of those websites show 6 and 7 are also the registers to toggle noise period, noise/tone enable ...so I guess I need to really keep digging further into this when I get a chance to research more. Oh, and thanks also for pointing out my error in putting an ldb %00111000 into register 7... when I only need modify that one bit. I'm pretty new to bit-wise operations, and still have a hard time grasping some basic concepts.
|
|
|
Post by Malban on Oct 3, 2022 15:21:14 GMT -5
I am not sure what to say.
John Hall describes the PSG correctly - and the same as I did. $07 is the "enable/disable" register for noise/sound and IO $0E is the actual PORT that can be either input or output
This means if bit 6 of register 7 is 0, than the IO port is switched to INPUT. This means, you can READ Register $0e of the PSG chip. This means if bit 6 of register 7 is 1, than the IO port is switched to OUTPUT. This means, you can WRITE to Register $0e of the PSG chip.
Now - there are different versions of the PSG: AY 8910, AY 8912 and some other. Our "Vectrex" version (the AY 8912) only has ONE IO port - that is the said register $0e.
Other PSG version may have NO IO Port at all, or have two IO ports.
If there are two IO ports, than one is called port A and the other port B.
Since the Vectrex has only one PSG IO port it does not really matter - but ours is PORT A, and for port A bit 6 of the enable register ($07) is responsible and the actual IO register is said register $0e.
Other PSG chips have TWO IO Ports... than bit 7 of the enable register ($07) is responsible for the additional port B and the actual IO register is register $0f.
MSX computers also use the PSG chip - for normal functioning bit 6 (of the enable register) set to 0 is a good thing. "We" don't care about bit 7 - so the recomendation... is not relevant for us.
--- To make it clear: Register 7 of the PSG chip is responsible for several tasks.
- enable/disable of Sound Channel A - enable/disable of Sound Channel B
- enable/disable of Sound Channel C
- enable/disable of Noise Channel A - enable/disable of Noise Channel B - enable/disable of Noise Channel C
- set IO port A to input/output - set IO port B to input/output
So yes that is a multifunctional register!
One "Register" consists of 8 bits. The highest bit is called bit 7 and the lowest bit - bit 0.
What you read on the MSX board says:
BIT 7 of register 7 is responsible for Port B BIT 6 of register 7 is responsible for Port A
I copy and paste now from John Halls site the complete documentation of all BITS of Register 7!
--- To make it more clear. The PSG chip is not only a sound chip, it was designed to also help with input and output (both port A and B (if available)). This has per se nothing to do with sound - it is just that the designers of the chip thought:
"Hey if a computer/machine outputs sound - than it probably also has needs to have some input/output ports - let us provide this functionality as well!" (today they would probably have added USB or something like that).
Cheers Malban
|
|
|
Post by jday6809 on Oct 3, 2022 19:48:53 GMT -5
Thanks Malban,
I can't thank you enough for taking the time to re-document / compile all that info together into your comment above, and sorry I couldn't get the mental picture before. I was confused what to do with $OE, which you helped me to realize is what we are manipulating by toggling bit 6 of register 7. I shouldn't have looked into the msx stuff at all, since they have that extra i/o port that is irrelevant for Vectrex. So, yep... thanks again for spelling it out for me. Hopefully this thread will keep future coders from confusing themselves as I did. Have a great rest of your week, Malban!
|
|