Commit c2655080670e25f13756d00ab1548a364b7ddd01
1 parent
dd4e27d8
more precise PIT gate emulation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@499 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
38 additions
and
5 deletions
vl.c
@@ -1002,6 +1002,10 @@ static int pit_get_count(PITChannelState *s) | @@ -1002,6 +1002,10 @@ static int pit_get_count(PITChannelState *s) | ||
1002 | case 5: | 1002 | case 5: |
1003 | counter = (s->count - d) & 0xffff; | 1003 | counter = (s->count - d) & 0xffff; |
1004 | break; | 1004 | break; |
1005 | + case 3: | ||
1006 | + /* XXX: may be incorrect for odd counts */ | ||
1007 | + counter = s->count - ((2 * d) % s->count); | ||
1008 | + break; | ||
1005 | default: | 1009 | default: |
1006 | counter = s->count - (d % s->count); | 1010 | counter = s->count - (d % s->count); |
1007 | break; | 1011 | break; |
@@ -1031,7 +1035,7 @@ static int pit_get_out(PITChannelState *s) | @@ -1031,7 +1035,7 @@ static int pit_get_out(PITChannelState *s) | ||
1031 | out = 0; | 1035 | out = 0; |
1032 | break; | 1036 | break; |
1033 | case 3: | 1037 | case 3: |
1034 | - out = (d % s->count) < (s->count >> 1); | 1038 | + out = (d % s->count) < ((s->count + 1) >> 1); |
1035 | break; | 1039 | break; |
1036 | case 4: | 1040 | case 4: |
1037 | case 5: | 1041 | case 5: |
@@ -1074,7 +1078,7 @@ static int pit_get_out_edges(PITChannelState *s) | @@ -1074,7 +1078,7 @@ static int pit_get_out_edges(PITChannelState *s) | ||
1074 | ret = d2 - d1; | 1078 | ret = d2 - d1; |
1075 | break; | 1079 | break; |
1076 | case 3: | 1080 | case 3: |
1077 | - v = s->count - (s->count >> 1); | 1081 | + v = s->count - ((s->count + 1) >> 1); |
1078 | d1 = (d1 + v) / s->count; | 1082 | d1 = (d1 + v) / s->count; |
1079 | d2 = (d2 + v) / s->count; | 1083 | d2 = (d2 + v) / s->count; |
1080 | ret = d2 - d1; | 1084 | ret = d2 - d1; |
@@ -1090,6 +1094,36 @@ static int pit_get_out_edges(PITChannelState *s) | @@ -1090,6 +1094,36 @@ static int pit_get_out_edges(PITChannelState *s) | ||
1090 | return ret; | 1094 | return ret; |
1091 | } | 1095 | } |
1092 | 1096 | ||
1097 | +/* val must be 0 or 1 */ | ||
1098 | +static inline void pit_set_gate(PITChannelState *s, int val) | ||
1099 | +{ | ||
1100 | + switch(s->mode) { | ||
1101 | + default: | ||
1102 | + case 0: | ||
1103 | + case 4: | ||
1104 | + /* XXX: just disable/enable counting */ | ||
1105 | + break; | ||
1106 | + case 1: | ||
1107 | + case 5: | ||
1108 | + if (s->gate < val) { | ||
1109 | + /* restart counting on rising edge */ | ||
1110 | + s->count_load_time = cpu_get_ticks(); | ||
1111 | + s->count_last_edge_check_time = s->count_load_time; | ||
1112 | + } | ||
1113 | + break; | ||
1114 | + case 2: | ||
1115 | + case 3: | ||
1116 | + if (s->gate < val) { | ||
1117 | + /* restart counting on rising edge */ | ||
1118 | + s->count_load_time = cpu_get_ticks(); | ||
1119 | + s->count_last_edge_check_time = s->count_load_time; | ||
1120 | + } | ||
1121 | + /* XXX: disable/enable counting */ | ||
1122 | + break; | ||
1123 | + } | ||
1124 | + s->gate = val; | ||
1125 | +} | ||
1126 | + | ||
1093 | static inline void pit_load_count(PITChannelState *s, int val) | 1127 | static inline void pit_load_count(PITChannelState *s, int val) |
1094 | { | 1128 | { |
1095 | if (val == 0) | 1129 | if (val == 0) |
@@ -1185,7 +1219,7 @@ uint32_t pit_ioport_read(CPUX86State *env, uint32_t addr) | @@ -1185,7 +1219,7 @@ uint32_t pit_ioport_read(CPUX86State *env, uint32_t addr) | ||
1185 | void speaker_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) | 1219 | void speaker_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
1186 | { | 1220 | { |
1187 | speaker_data_on = (val >> 1) & 1; | 1221 | speaker_data_on = (val >> 1) & 1; |
1188 | - pit_channels[2].gate = val & 1; | 1222 | + pit_set_gate(&pit_channels[2], val & 1); |
1189 | } | 1223 | } |
1190 | 1224 | ||
1191 | uint32_t speaker_ioport_read(CPUX86State *env, uint32_t addr) | 1225 | uint32_t speaker_ioport_read(CPUX86State *env, uint32_t addr) |
@@ -1463,7 +1497,6 @@ void serial_received_byte(SerialState *s, int ch) | @@ -1463,7 +1497,6 @@ void serial_received_byte(SerialState *s, int ch) | ||
1463 | serial_update_irq(); | 1497 | serial_update_irq(); |
1464 | break; | 1498 | break; |
1465 | case 'd': | 1499 | case 'd': |
1466 | - // tb_flush(); | ||
1467 | cpu_set_log(CPU_LOG_ALL); | 1500 | cpu_set_log(CPU_LOG_ALL); |
1468 | break; | 1501 | break; |
1469 | case TERM_ESCAPE: | 1502 | case TERM_ESCAPE: |
@@ -2128,7 +2161,7 @@ uint32_t kbd_read_status(CPUX86State *env, uint32_t addr) | @@ -2128,7 +2161,7 @@ uint32_t kbd_read_status(CPUX86State *env, uint32_t addr) | ||
2128 | KBDState *s = &kbd_state; | 2161 | KBDState *s = &kbd_state; |
2129 | int val; | 2162 | int val; |
2130 | val = s->status; | 2163 | val = s->status; |
2131 | -#if defined(DEBUG_KBD) | 2164 | +#if defined(DEBUG_KBD) && 0 |
2132 | printf("kbd: read status=0x%02x\n", val); | 2165 | printf("kbd: read status=0x%02x\n", val); |
2133 | #endif | 2166 | #endif |
2134 | return val; | 2167 | return val; |