Implemented some undocumented PIT behavior.
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
30
src/pit.c
30
src/pit.c
@@ -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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user