diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-01-04 16:07:06 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-01-04 16:07:06 +0000 |
commit | c2655080670e25f13756d00ab1548a364b7ddd01 (patch) | |
tree | e9d6ecaa60e7e0bc2acd5674ee36c09ad4f21017 /vl.c | |
parent | dd4e27d8101425b807df672df754eaa242c64351 (diff) |
more precise PIT gate emulation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@499 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'vl.c')
-rw-r--r-- | vl.c | 43 |
1 files changed, 38 insertions, 5 deletions
@@ -1002,6 +1002,10 @@ static int pit_get_count(PITChannelState *s) case 5: counter = (s->count - d) & 0xffff; break; + case 3: + /* XXX: may be incorrect for odd counts */ + counter = s->count - ((2 * d) % s->count); + break; default: counter = s->count - (d % s->count); break; @@ -1031,7 +1035,7 @@ static int pit_get_out(PITChannelState *s) out = 0; break; case 3: - out = (d % s->count) < (s->count >> 1); + out = (d % s->count) < ((s->count + 1) >> 1); break; case 4: case 5: @@ -1074,7 +1078,7 @@ static int pit_get_out_edges(PITChannelState *s) ret = d2 - d1; break; case 3: - v = s->count - (s->count >> 1); + v = s->count - ((s->count + 1) >> 1); d1 = (d1 + v) / s->count; d2 = (d2 + v) / s->count; ret = d2 - d1; @@ -1090,6 +1094,36 @@ static int pit_get_out_edges(PITChannelState *s) return ret; } +/* val must be 0 or 1 */ +static inline void pit_set_gate(PITChannelState *s, int val) +{ + switch(s->mode) { + default: + case 0: + case 4: + /* XXX: just disable/enable counting */ + break; + case 1: + case 5: + if (s->gate < val) { + /* restart counting on rising edge */ + s->count_load_time = cpu_get_ticks(); + s->count_last_edge_check_time = s->count_load_time; + } + break; + case 2: + case 3: + if (s->gate < val) { + /* restart counting on rising edge */ + s->count_load_time = cpu_get_ticks(); + s->count_last_edge_check_time = s->count_load_time; + } + /* XXX: disable/enable counting */ + break; + } + s->gate = val; +} + static inline void pit_load_count(PITChannelState *s, int val) { if (val == 0) @@ -1185,7 +1219,7 @@ uint32_t pit_ioport_read(CPUX86State *env, uint32_t addr) void speaker_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) { speaker_data_on = (val >> 1) & 1; - pit_channels[2].gate = val & 1; + pit_set_gate(&pit_channels[2], val & 1); } uint32_t speaker_ioport_read(CPUX86State *env, uint32_t addr) @@ -1463,7 +1497,6 @@ void serial_received_byte(SerialState *s, int ch) serial_update_irq(); break; case 'd': - // tb_flush(); cpu_set_log(CPU_LOG_ALL); break; case TERM_ESCAPE: @@ -2128,7 +2161,7 @@ uint32_t kbd_read_status(CPUX86State *env, uint32_t addr) KBDState *s = &kbd_state; int val; val = s->status; -#if defined(DEBUG_KBD) +#if defined(DEBUG_KBD) && 0 printf("kbd: read status=0x%02x\n", val); #endif return val; |