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 | 1002 | case 5: |
| 1003 | 1003 | counter = (s->count - d) & 0xffff; |
| 1004 | 1004 | break; |
| 1005 | + case 3: | |
| 1006 | + /* XXX: may be incorrect for odd counts */ | |
| 1007 | + counter = s->count - ((2 * d) % s->count); | |
| 1008 | + break; | |
| 1005 | 1009 | default: |
| 1006 | 1010 | counter = s->count - (d % s->count); |
| 1007 | 1011 | break; |
| ... | ... | @@ -1031,7 +1035,7 @@ static int pit_get_out(PITChannelState *s) |
| 1031 | 1035 | out = 0; |
| 1032 | 1036 | break; |
| 1033 | 1037 | case 3: |
| 1034 | - out = (d % s->count) < (s->count >> 1); | |
| 1038 | + out = (d % s->count) < ((s->count + 1) >> 1); | |
| 1035 | 1039 | break; |
| 1036 | 1040 | case 4: |
| 1037 | 1041 | case 5: |
| ... | ... | @@ -1074,7 +1078,7 @@ static int pit_get_out_edges(PITChannelState *s) |
| 1074 | 1078 | ret = d2 - d1; |
| 1075 | 1079 | break; |
| 1076 | 1080 | case 3: |
| 1077 | - v = s->count - (s->count >> 1); | |
| 1081 | + v = s->count - ((s->count + 1) >> 1); | |
| 1078 | 1082 | d1 = (d1 + v) / s->count; |
| 1079 | 1083 | d2 = (d2 + v) / s->count; |
| 1080 | 1084 | ret = d2 - d1; |
| ... | ... | @@ -1090,6 +1094,36 @@ static int pit_get_out_edges(PITChannelState *s) |
| 1090 | 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 | 1127 | static inline void pit_load_count(PITChannelState *s, int val) |
| 1094 | 1128 | { |
| 1095 | 1129 | if (val == 0) |
| ... | ... | @@ -1185,7 +1219,7 @@ uint32_t pit_ioport_read(CPUX86State *env, uint32_t addr) |
| 1185 | 1219 | void speaker_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
| 1186 | 1220 | { |
| 1187 | 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 | 1225 | uint32_t speaker_ioport_read(CPUX86State *env, uint32_t addr) |
| ... | ... | @@ -1463,7 +1497,6 @@ void serial_received_byte(SerialState *s, int ch) |
| 1463 | 1497 | serial_update_irq(); |
| 1464 | 1498 | break; |
| 1465 | 1499 | case 'd': |
| 1466 | - // tb_flush(); | |
| 1467 | 1500 | cpu_set_log(CPU_LOG_ALL); |
| 1468 | 1501 | break; |
| 1469 | 1502 | case TERM_ESCAPE: |
| ... | ... | @@ -2128,7 +2161,7 @@ uint32_t kbd_read_status(CPUX86State *env, uint32_t addr) |
| 2128 | 2161 | KBDState *s = &kbd_state; |
| 2129 | 2162 | int val; |
| 2130 | 2163 | val = s->status; |
| 2131 | -#if defined(DEBUG_KBD) | |
| 2164 | +#if defined(DEBUG_KBD) && 0 | |
| 2132 | 2165 | printf("kbd: read status=0x%02x\n", val); |
| 2133 | 2166 | #endif |
| 2134 | 2167 | return val; | ... | ... |