Implemented some undocumented PIT behavior.

This commit is contained in:
OBattler
2023-05-24 22:14:57 +02:00
parent 9a60ca1e77
commit ab733b7f6c
2 changed files with 17 additions and 15 deletions

View File

@@ -23,7 +23,7 @@ typedef struct {
uint8_t m, ctrl, uint8_t m, ctrl,
read_status, latch, read_status, latch,
s1_det, l_det, s1_det, l_det,
bcd, pad; bcd, incomplete;
uint16_t rl; uint16_t rl;

View File

@@ -139,6 +139,9 @@ ctr_load_count(ctr_t *ctr)
pit_log("ctr->count = %i\n", l); pit_log("ctr->count = %i\n", l);
ctr->null_count = 0; ctr->null_count = 0;
ctr->newcount = !!(l & 1); ctr->newcount = !!(l & 1);
/* Undocumented feature - writing MSB after reload after writing LSB causes an instant reload. */
ctr->incomplete = !!(ctr->wm & 0x80);
} }
static void static void
@@ -146,16 +149,13 @@ ctr_tick(ctr_t *ctr)
{ {
uint8_t state = ctr->state; uint8_t state = ctr->state;
if (state == 1) { if ((state & 0x03) == 0x01) {
/* This is true for all modes */ /* This is true for all modes */
ctr_load_count(ctr); ctr_load_count(ctr);
ctr->state = 2; ctr->state++;
if ((ctr->m & 0x07) == 0x01) if (((ctr->m & 0x07) == 0x01) && (ctr->state == 2))
ctr_set_out(ctr, 0); ctr_set_out(ctr, 0);
return; } else switch (ctr->m & 0x07) {
}
switch (ctr->m & 0x07) {
case 0: case 0:
/* Interrupt on terminal count */ /* Interrupt on terminal count */
switch (state) { switch (state) {
@@ -176,11 +176,6 @@ ctr_tick(ctr_t *ctr)
case 1: case 1:
/* Hardware retriggerable one-shot */ /* Hardware retriggerable one-shot */
switch (state) { switch (state) {
case 1:
ctr_load_count(ctr);
ctr->state = 2;
ctr_set_out(ctr, 0);
break;
case 2: case 2:
if (ctr->count >= 1) { if (ctr->count >= 1) {
ctr_decrease_count(ctr); ctr_decrease_count(ctr);
@@ -191,6 +186,7 @@ ctr_tick(ctr_t *ctr)
} }
break; break;
case 3: case 3:
case 6:
ctr_decrease_count(ctr); ctr_decrease_count(ctr);
break; break;
} }
@@ -267,6 +263,7 @@ ctr_tick(ctr_t *ctr)
if ((ctr->gate != 0) || (ctr->m != 4)) { if ((ctr->gate != 0) || (ctr->m != 4)) {
switch (state) { switch (state) {
case 0: case 0:
case 6:
ctr_decrease_count(ctr); ctr_decrease_count(ctr);
break; break;
case 2: case 2:
@@ -310,9 +307,12 @@ static void
ctr_set_state_1(ctr_t *ctr) ctr_set_state_1(ctr_t *ctr)
{ {
uint8_t mode = (ctr->m & 0x03); uint8_t mode = (ctr->m & 0x03);
int do_reload = !!ctr->incomplete || (ctr->state == 0);
if ((mode == 0) || ((mode > 1) && (ctr->state == 0))) ctr->incomplete = 0;
ctr->state = 1;
if (do_reload)
ctr->state = 1 + ((mode == 1) << 2);
} }
static void static void
@@ -607,6 +607,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv)
} }
} }
extern uint8_t *ram;
static uint8_t static uint8_t
pit_read(uint16_t addr, void *priv) pit_read(uint16_t addr, void *priv)
{ {