PCem

view src/keyboard_xt.c @ 132:2b9cea0be424

Improvements to PC speaker - fixes sound on Beyond Castle Wolfenstein and probably other games as well.
author TomW
date Wed Jul 16 20:44:29 2014 +0100
parents 6425afff950f
children
line source
1 #include "ibm.h"
2 #include "io.h"
3 #include "mem.h"
4 #include "pic.h"
5 #include "sound.h"
6 #include "sound_speaker.h"
7 #include "timer.h"
9 #include "keyboard.h"
10 #include "keyboard_xt.h"
12 #define STAT_PARITY 0x80
13 #define STAT_RTIMEOUT 0x40
14 #define STAT_TTIMEOUT 0x20
15 #define STAT_LOCK 0x10
16 #define STAT_CD 0x08
17 #define STAT_SYSFLAG 0x04
18 #define STAT_IFULL 0x02
19 #define STAT_OFULL 0x01
21 struct
22 {
23 int wantirq;
24 uint8_t key_waiting;
26 uint8_t pa;
27 uint8_t pb;
28 } keyboard_xt;
30 static uint8_t key_queue[16];
31 static int key_queue_start = 0, key_queue_end = 0;
33 void keyboard_xt_poll()
34 {
35 keybsenddelay += (1000 * TIMER_USEC);
36 if (keyboard_xt.wantirq)
37 {
38 keyboard_xt.wantirq = 0;
39 keyboard_xt.pa = keyboard_xt.key_waiting;
40 picint(2);
41 pclog("keyboard_xt : take IRQ\n");
42 }
43 if (key_queue_start != key_queue_end && !keyboard_xt.pa)
44 {
45 keyboard_xt.key_waiting = key_queue[key_queue_start];
46 pclog("Reading %02X from the key queue at %i\n", keyboard_xt.key_waiting, key_queue_start);
47 key_queue_start = (key_queue_start + 1) & 0xf;
48 keyboard_xt.wantirq = 1;
49 }
50 }
52 void keyboard_xt_adddata(uint8_t val)
53 {
54 key_queue[key_queue_end] = val;
55 pclog("keyboard_xt : %02X added to key queue at %i\n", val, key_queue_end);
56 key_queue_end = (key_queue_end + 1) & 0xf;
57 return;
58 }
60 void keyboard_xt_write(uint16_t port, uint8_t val, void *priv)
61 {
62 pclog("keyboard_xt : write %04X %02X %02X\n", port, val, keyboard_xt.pb);
63 /* if (ram[8] == 0xc3)
64 {
65 output = 3;
66 }*/
67 switch (port)
68 {
69 case 0x61:
70 pclog("keyboard_xt : pb write %02X %02X %i %02X %i\n", val, keyboard_xt.pb, !(keyboard_xt.pb & 0x40), keyboard_xt.pb & 0x40, (val & 0x40));
71 if (!(keyboard_xt.pb & 0x40) && (val & 0x40)) /*Reset keyboard*/
72 {
73 pclog("keyboard_xt : reset keyboard\n");
74 keyboard_xt_adddata(0xaa);
75 }
76 keyboard_xt.pb = val;
77 ppi.pb = val;
79 speaker_gated = val & 1;
80 speaker_enable = val & 2;
81 if (speaker_enable)
82 was_speaker_enable = 1;
83 pit_set_gate(2, val & 1);
85 if (val & 0x80)
86 {
87 keyboard_xt.pa = 0;
88 picintc(2);
89 }
90 break;
91 }
92 }
94 uint8_t keyboard_xt_read(uint16_t port, void *priv)
95 {
96 uint8_t temp;
97 pclog("keyboard_xt : read %04X ", port);
98 switch (port)
99 {
100 case 0x60:
101 if (keyboard_xt.pb & 0x80)
102 {
103 if (VGA)
104 temp = 0x4D;
105 else if (MDA)
106 temp = 0x7D;
107 else
108 temp = 0x6D;
109 }
110 else
111 {
112 temp = keyboard_xt.pa;
113 if (key_queue_start == key_queue_end)
114 {
115 keyboard_xt.wantirq = 0;
116 }
117 else
118 {
119 keyboard_xt.key_waiting = key_queue[key_queue_start];
120 key_queue_start = (key_queue_start + 1) & 0xf;
121 keyboard_xt.wantirq = 1;
122 }
123 }
124 break;
126 case 0x61:
127 temp = keyboard_xt.pb;
128 break;
130 case 0x62:
131 if (keyboard_xt.pb & 0x08)
132 {
133 if (VGA)
134 temp = 4;
135 else if (MDA)
136 temp = 7;
137 else
138 temp = 6;
139 }
140 else
141 temp = 0xD;
142 temp |= (ppispeakon ? 0x20 : 0);
143 break;
145 default:
146 pclog("\nBad XT keyboard read %04X\n", port);
147 //dumpregs();
148 //exit(-1);
149 }
150 pclog("%02X\n", temp);
151 return temp;
152 }
154 void keyboard_xt_reset()
155 {
156 keyboard_xt.wantirq = 0;
158 keyboard_scan = 1;
159 }
161 void keyboard_xt_init()
162 {
163 //return;
164 io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL);
165 keyboard_xt_reset();
166 keyboard_send = keyboard_xt_adddata;
167 keyboard_poll = keyboard_xt_poll;
169 timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
170 }