4.22.6 KBDVBASE
typedef struct
{
void (*kb_midivec)(); /* MIDI interrupt vector */
void (*kb_vkbderr)(); /* Keyboard error vector */
void (*kb_vmiderr)(); /* MIDI error vector */
void (*kb_statvec)(); /* Keyboard status */
void (*kb_mousevec)(); /* Keyboard mouse status */
void (*kb_clockvec)(); /* Keyboard clock */
void (*kb_joyvec)(); /* Keyboard joystick status */
void (*kb_midisys)(); /* System Midi vector */
void (*kb_kbdsys)(); /* Keyboard vector */
int8_t drvstat; /* Keyboard driver status */
} KBDVBASE;
Note: For the elements kb_clockvec and kb_joyvec one should note that the address of the packet is passed in register A0 and on the stack; also, the routines should be terminated with an RTS, and if possible run for no more than 1ms.
The element drvstat contains a non-zero value when the IKBD is in the process of sending a packet.
Is there a description available what sort of data is passed into those routines? For joystick a apointer in a0, but to what sort of data does this point? A single byte? Two bytes per stick?
I remember writing my own handler but what to use to intercept the official ones?
typedef struct
{
char header; /* 0xfe joystick 0, 0xff joystick 1 */
char val; /* bits 0..3 set/clear for the four possible motion directions and bit 7 for the fire button */
} JOYEVENT;
...unless you send an interrogate joystick command (0x16) to the IKBD, and are using 2 joysticks. In that case, the header byte will be 0xfd, followed by 2 bytes for the current state of the 2 joysticks.
simonsunnyboy wrote: ↑Mon Aug 15, 2022 7:54 pm
Is the header byte always the first one pointed to by a0 so one can distinguish between them?
This should be the case.
I think you however need to make sure the IKBD is not in the middle of a transfer when you exchange the vectors (only do that if the drvstat member is 0) to avoid getting out of sync. You'll probably need to block interrupts to implement the vector exchange properly.
Indeed...if I understand correctly, the commented portions in _JoyISR are actually routines to be placed into the joystick packet handler slot?
Sequence of events:
IKBD ==> isr@0x118() ==> KBDVBASE.ikbdsys() ==> KBDVBASE.kb_joyvec()
isr@0x118 determines which ACIA initiated the interrupt (MIDI or IKBD), then in the case of the IKBD, calls ikbdsys(). This is where the IKBD parser is, and in turn calls kb_joyvec, kb_mousevec etc. So kb_joyvec receives the decoded joystick packed in full.
Indeed...if I understand correctly, the commented portions in _JoyISR are actually routines to be placed into the joystick packet handler slot?
The commented out old assembly version handles just joystick data. The assembly code that is actually used in the game, also simulates 2 joysticks with 9 + 9 keyboard keys. I.e. C-code does not need to care whether whether joystick or keyboard is used by either of the players.
Only limit is that many keyboards do not support pressing that many keys down at the same time, so if both players use a keyboard, they may be able to affect each other's input. This is not a bug in the assembly, game C-code or TOS, but a property of the given keyboard, and how it's wired.
Dunno whether that is useful in this case. If someone else is already using the joystick, you are in trouble. Also you certainly don't want to call the previous handler, since that will probably read the ACIA data register again.
I didn't necessarily plan to make use of the old vector as stored within the XBRA block but sometimes it could be useful to see if it has been replaced at all and by what software.
I am thinking more from a global emulator state perspective, e.g. inspecting if it really is in place or not.