Commit c2655080670e25f13756d00ab1548a364b7ddd01

Authored by bellard
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
... ... @@ -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;
... ...