mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-04-16 16:06:53 +02:00
iokbd keysc: space optimizations for SH3
* Reduce the keyboard queue size from 64 to 32, which is more than enough even for real-time games with multiple key presses. * Pack the driver_event_t structure of the keyboard driver to make it 4 bytes rather than 6 bytes. Combined with the previous item, this saves 256 bytes off the BSS section (which is 3% of the SH3's static RAM). * As part of a debugging attempt, updated the watchdog delay code in iokbd_delay() to make it usable in the current version of gint. * Restored port registers more aggressively in iokbd_row().
This commit is contained in:
parent
03715344a4
commit
a99bffe7f4
4 changed files with 35 additions and 28 deletions
|
@ -117,12 +117,12 @@ enum
|
||||||
/* Size of the buffer event queue, can be customized using gint's configure
|
/* Size of the buffer event queue, can be customized using gint's configure
|
||||||
script before compiling the library. Better be a power of 2. */
|
script before compiling the library. Better be a power of 2. */
|
||||||
#ifndef KEYBOARD_QUEUE_SIZE
|
#ifndef KEYBOARD_QUEUE_SIZE
|
||||||
#define KEYBOARD_QUEUE_SIZE 64
|
#define KEYBOARD_QUEUE_SIZE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Keyboard frequency analysis, must be at least 64 for the keyboard to work,
|
/* Keyboard frequency analysis, must be at least 64 for the keyboard to work,
|
||||||
and at most 32768 for the extra timer to support it. Better if a power of 2.
|
and at most 32768 for the extra timer to support it. Better if a power of 2.
|
||||||
TODO: Add a configure or runtime setting for KEYBOARD_SCAN_FREQUENCY */
|
TODO: Add a runtime setting for KEYBOARD_SCAN_FREQUENCY */
|
||||||
#ifndef KEYBOARD_SCAN_FREQUENCY
|
#ifndef KEYBOARD_SCAN_FREQUENCY
|
||||||
#define KEYBOARD_SCAN_FREQUENCY 128
|
#define KEYBOARD_SCAN_FREQUENCY 128
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,7 +25,7 @@ GINLINE const tlb_data_t *tlb_data(uint way, uint E)
|
||||||
return (void *)addr;
|
return (void *)addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tlb_mapped_memort() - count amount of mapped memory */
|
/* tlb_mapped_memory() - count amount of mapped memory */
|
||||||
void tlb_mapped_memory(uint32_t *p_rom, uint32_t *p_ram)
|
void tlb_mapped_memory(uint32_t *p_rom, uint32_t *p_ram)
|
||||||
{
|
{
|
||||||
uint32_t rom = 0, ram = 0;
|
uint32_t rom = 0, ram = 0;
|
||||||
|
|
|
@ -21,26 +21,30 @@ static void iokbd_delay(void)
|
||||||
);
|
);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Watchdog delay version */
|
uint8_t volatile *WTCSRr = (void *)0xffffff86;
|
||||||
|
uint16_t volatile *WTCSRw = (void *)0xffffff86;
|
||||||
|
uint16_t volatile *WTCNTw = (void *)0xffffff84;
|
||||||
|
|
||||||
|
/* Watchdog delay version, each of the values between this and 0xff
|
||||||
|
account for 256 clock cycles on Pphi. This is roughly equivalent to
|
||||||
|
2048 nop, lasting ~70 µs */
|
||||||
const int delay = 0xf4;
|
const int delay = 0xf4;
|
||||||
|
|
||||||
/* Disable the watchdog timer interrupt and reset configuration */
|
/* Disable the watchdog timer interrupt and reset configuration */
|
||||||
INTC.IPRB.BIT._WDT = 0;
|
*WTCSRw = 0xa500;
|
||||||
WDT.WTCSR.WRITE = 0xa500;
|
|
||||||
|
|
||||||
/* Set the delay, input on Pphi / 256 and start counting */
|
/* Set the delay, input on Pphi / 256 and start counting */
|
||||||
WDT.WTCNT.WRITE = 0x5a00 | (delay & 0xff);
|
*WTCNTw = 0x5a00 | (delay & 0xff);
|
||||||
WDT.WTCSR.WRITE = 0xa505;
|
*WTCSRw = 0xa505;
|
||||||
WDT.WTCSR.WRITE = 0xa585;
|
*WTCSRw = 0xa585;
|
||||||
|
|
||||||
/* Actively wait for overflow, then clear the interrupt flag */
|
/* Actively wait for overflow, then clear the interrupt flag */
|
||||||
while((WDT.WTCSR.READ.BYTE & 0x08) == 0);
|
while((*WTCSRr & 0x08) == 0);
|
||||||
WDT.WTCSR.WRITE = 0xa500 | (WDT.WTCSR.READ.BYTE & 0xf7);
|
*WTCSRw = 0xa500 | (*WTCSRr & 0xf7);
|
||||||
|
|
||||||
/* Reset configuration, counter, and re-enabled interrupt */
|
/* Reset configuration, counter, and re-enabled interrupt */
|
||||||
WDT.WTCSR.WRITE = 0xa500;
|
*WTCSRw = 0xa500;
|
||||||
WDT.WTCSR.WRITE = 0x5a00;
|
*WTCNTw = 0x5a00;
|
||||||
INTC.IPRB.BIT._WDT = GINT_INTP_WDT;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +56,11 @@ uint8_t iokbd_row(int row)
|
||||||
if((unsigned)row > 9) return 0x00;
|
if((unsigned)row > 9) return 0x00;
|
||||||
row ^= 1;
|
row ^= 1;
|
||||||
|
|
||||||
|
int orig_PBCR = PFC.PBCR;
|
||||||
|
int orig_PMCR = PFC.PMCR;
|
||||||
|
int orig_PBDR = PFC.PBDR;
|
||||||
|
int orig_PMDR = PFC.PMDR;
|
||||||
|
|
||||||
/* This will enable output (01) on @row, input (10) everywhere else */
|
/* This will enable output (01) on @row, input (10) everywhere else */
|
||||||
uint16_t ctrl_mask = 0x0003 << ((row & 7) * 2);
|
uint16_t ctrl_mask = 0x0003 << ((row & 7) * 2);
|
||||||
/* Enable output (0) on @row, input (1) everywhere else */
|
/* Enable output (0) on @row, input (1) everywhere else */
|
||||||
|
@ -81,25 +90,23 @@ uint8_t iokbd_row(int row)
|
||||||
/* Set @row to 0, everything else to 1 */
|
/* Set @row to 0, everything else to 1 */
|
||||||
PFC.PBDR = 0xff;
|
PFC.PBDR = 0xff;
|
||||||
PFC.PMDR = PFC.PMDR & data_mask;
|
PFC.PMDR = PFC.PMDR & data_mask;
|
||||||
|
iokbd_delay();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now read the input data from the keyboard! */
|
/* Now read the input data from the keyboard! */
|
||||||
uint8_t input = ~PFC.PADR;
|
uint8_t input = ~PFC.PADR;
|
||||||
iokbd_delay();
|
iokbd_delay();
|
||||||
|
|
||||||
/* Reset the port configuration. I don't know why the intermediate step
|
/* Reset the port configuration */
|
||||||
is necessary; refer to SimLo's documentation. */
|
PFC.PBCR = orig_PBCR;
|
||||||
PFC.PBCR = 0xaaaa;
|
PFC.PMCR = orig_PMCR;
|
||||||
PFC.PMCR = (PFC.PMCR & 0xff00) | 0x00aa;
|
|
||||||
iokbd_delay();
|
|
||||||
PFC.PBCR = 0x5555;
|
|
||||||
PFC.PMCR = (PFC.PMCR & 0xff00) | 0x0055;
|
|
||||||
iokbd_delay();
|
iokbd_delay();
|
||||||
|
|
||||||
/* Now also reset the data registers. This was forgotten from SimLo's
|
/* Now also reset the data registers. This was forgotten from SimLo's
|
||||||
CheckKeyRow() and blows up everything. */
|
CheckKeyRow() and blows up everything. */
|
||||||
PFC.PBDR = 0x00;
|
PFC.PBDR = orig_PBDR;
|
||||||
PFC.PMDR = PFC.PMDR & 0xf0;
|
PFC.PMDR = orig_PMDR;
|
||||||
|
iokbd_delay();
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,9 @@ GDATA static uint8_t current[12] = { 0 };
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t time; /* Locally unique time identifier */
|
uint16_t time; /* Locally unique time identifier */
|
||||||
uint8_t row; /* Row number */
|
|
||||||
uint8_t changed; /* Keys that changed state */
|
uint8_t changed; /* Keys that changed state */
|
||||||
uint8_t kind; /* Type of change, either KEYEV_DOWN or KEYEV_UP */
|
uint8_t row :4; /* Row number */
|
||||||
|
uint8_t kind :4; /* Type of change, either KEYEV_DOWN or KEYEV_UP */
|
||||||
|
|
||||||
} driver_event_t;
|
} driver_event_t;
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ static void keysc_frame(void)
|
||||||
if(!diff) continue;
|
if(!diff) continue;
|
||||||
|
|
||||||
/* Update internal status if the event could be pushed */
|
/* Update internal status if the event could be pushed */
|
||||||
driver_event_t ev = { time, row, diff, KEYEV_UP };
|
driver_event_t ev = { time, diff, row, KEYEV_UP };
|
||||||
if(!buffer_push(ev)) state[row] &= scan[row];
|
if(!buffer_push(ev)) state[row] &= scan[row];
|
||||||
}
|
}
|
||||||
for(int row = 0; row < 12; row++)
|
for(int row = 0; row < 12; row++)
|
||||||
|
@ -111,7 +111,7 @@ static void keysc_frame(void)
|
||||||
int diff = scan[row] & ~state[row];
|
int diff = scan[row] & ~state[row];
|
||||||
if(!diff) continue;
|
if(!diff) continue;
|
||||||
|
|
||||||
driver_event_t ev = { time, row, diff, KEYEV_DOWN };
|
driver_event_t ev = { time, diff, row, KEYEV_DOWN };
|
||||||
if(!buffer_push(ev)) state[row] |= scan[row];
|
if(!buffer_push(ev)) state[row] |= scan[row];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue