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,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;