Polling the Joystick statuses crash. (fixed)

The RetroNET NABU-LIB z88dk C Library for creating games and software.
Post Reply
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Polling the Joystick statuses crash. (fixed)

Post by productiondave »

Hi,

I was working with Jeff Stone over on Discord, and he was asking about why his code crashes. The intention is to write a simple program that reports the status of the two joysticks.

I have found that the following code works perfectly when I do *NOT* define DISABLE_VDP. However if I do DISABLE_VDP, the program crashes and the system warm boots. The crash is not immediate. It works for a few joystick state changes before crashing.

I don't know if this is only a CP/M thing or not.

It feels to me like there is some kind of conflict between the VDP interrupt and the Keyboard interrupt? The crash never happens when VDP is enabled.

Code: Select all

#define DISABLE_HCCA_RX_INT
#define DISABLE_CURSOR

// #define DISABLE_VDP          // If you dssable VDP in NABU-LIB, the program crashes and CP/M warm boots.
// #define DISABLE_KEYBOARD_INT // The NABU-LIB functions for the joystick depend on the KBD interrupts.

#include <stdio.h>
#include "NABU-LIB.h"

uint8_t status0, lastStatus0, status1, lastStatus1 = 0; //Record the status of the joystick in these vars.

uint8_t main(void) {

    /*The NABU Keyboard Controller only reports changes to the joystick.
    * NABU-LIB tracks these in a global variable which allows us to poll the
    * Joystick.  It's possible that Marduk and Ishkur CP/M do not manage the
    * joystick input in the same way as DJ's CloudCP/M BIOS.
    * 
    * To do this without NABU-LIB, you will need to write code to handle the
    * Keyboard interrupt yourself.
    */

    initNABULib();
    
    // Here I am basically tracking the status of the joystick as reported by
    // NABU-LIB and printing a message to the screen if it changes.
    printf("Joystick Test Program:\n");
    printf("Move the Joystick and press the button.\n");
    printf("Hit Q to quit.\n\n");

    while(1) {
        status0 = getJoyStatus(0);           
        if (status0 != lastStatus0) {
            if(status0 & Joy_Left) {
                printf("J0 - LEFT ... ");
            } else if (status0 & Joy_Right) {
                printf("J0 - RIGHT ... ");
            } else if (status0 & Joy_Up) {
                printf("J0 - UP ... ");
            } else if (status0 & Joy_Down) {
                printf("J0 - DOWN ... ");
            } else if (status0 & Joy_Button) {
                printf("J0 - BUTTON ... ");
            } else {
                printf("J0 - RESET\n");
            }

            lastStatus0 = status0;
        }
        
        status1 = getJoyStatus(1);
        if (status1 != lastStatus1) {
            if(status1 & Joy_Left) {
                printf("J0 - LEFT\n");
            } else if (status1 & Joy_Right) {
                printf("J0 - RIGHT\n");
            } else if (status1 & Joy_Up) {
                printf("J0 - UP\n");
            } else if (status1 & Joy_Down) {
                printf("J0 - DOWN\n");
            } else if (status1 & Joy_Button) {
                printf("J0 - BUTTON\n");
            } else {
                printf("J0 - RESET");
            }

            lastStatus1 = status1;
        }

        if (isKeyPressed()) {
            uint8_t key = getChar();
            if (key == 'q' || key == 'Q') {
                printf("Exiting...\n");
                break;
            }
        }

    }
    return 0;
}

User avatar
DJ Sures
Posts: 345
Joined: Tue Mar 28, 2023 8:36 pm
Location: nabu.ca
Contact:

Re: Polling the Joystick statuses crashes when VDP_DISABLE is defined.

Post by DJ Sures »

Reviewing that code, the vdp interrupts are not enabled. they are only enabled when the nabulib function is called to enable "vdp_enableVDPReadyInt()"

I'll take a quick peek and see what's going on for u.
User avatar
DJ Sures
Posts: 345
Joined: Tue Mar 28, 2023 8:36 pm
Location: nabu.ca
Contact:

Re: Polling the Joystick statuses crashes when VDP_DISABLE is defined.

Post by DJ Sures »

ooooh i think i figured it out. strange one but i got a handle on it - stay tuned
User avatar
productiondave
Posts: 117
Joined: Tue Mar 28, 2023 10:01 pm

Re: Polling the Joystick statuses crashes when VDP_DISABLE is defined.

Post by productiondave »

DJ Sures wrote: Mon Apr 03, 2023 3:16 am Reviewing that code, the vdp interrupts are not enabled. they are only enabled when the nabulib function is called to enable "vdp_enableVDPReadyInt()"

I'll take a quick peek and see what's going on for u.
Yeah I wasn't sure. It's something to do with the VDP though.

Staying tuned.
User avatar
DJ Sures
Posts: 345
Joined: Tue Mar 28, 2023 8:36 pm
Location: nabu.ca
Contact:

Re: Polling the Joystick statuses crashes when VDP_DISABLE is defined.

Post by DJ Sures »

So it was a good one - I overlooked something. I got so excited about EXX that swaps bc, de, hl into shadow registers a while ago. This is recommended for interrupts. However, I re-enable interruptions in the bios by writing VT and parsing emulation. So what happens is the screen is being written to while the interrupt is re-enabled, and the keyboard interrupt is also calling EXX, which swaps the registers back. So this means the shadow registers and everything backed up for the BIOS BDOS call were mangled.

It would take a very particular timing for that to happen - and that little program made it happen :)

The fact that VDP enable/disable had an effect was because it knocked the very slight timing off - masking the issue.
Post Reply