1 // license:LGPL-2.1+
2 // copyright-holders:Angelo Salese
3 /***************************************************************************
4
5 Acorn Archimedes KART interface
6
7 TODO:
8 - FIFO
9
10 ***************************************************************************/
11
12 #include "emu.h"
13 #include "machine/aakart.h"
14
15
16
17 //**************************************************************************
18 // GLOBAL VARIABLES
19 //**************************************************************************
20
21 // device type definition
22 DEFINE_DEVICE_TYPE(AAKART, aakart_device, "aakart", "Acorn Archimedes KART")
23
24 #define HRST 0xff
25 #define RAK1 0xfe
26 #define RAK2 0xfd
27 #define BACK 0x3f
28 #define SMAK 0x33 /* keyboard + mouse ack */
29 #define MACK 0x32 /* mouse ack */
30 #define SACK 0x31 /* keyboard ack */
31 #define NACK 0x30 /* no data ack */
32 #define RQID 0x20
33
34 //**************************************************************************
35 // LIVE DEVICE
36 //**************************************************************************
37
38 //-------------------------------------------------
39 // aakart_device - constructor
40 //-------------------------------------------------
41
aakart_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)42 aakart_device::aakart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
43 : device_t(mconfig, AAKART, tag, owner, clock), m_rxtimer(nullptr),
44 m_txtimer(nullptr), m_mousetimer(nullptr), m_keybtimer(nullptr),
45 m_out_tx_cb(*this),
46 m_out_rx_cb(*this),
47 m_tx_latch(0), m_rx(0), m_new_command(0), m_status(0), m_mouse_enable(0), m_keyb_enable(0)
48 {
49 }
50
51
52 //-------------------------------------------------
53 // device_validity_check - perform validity checks
54 // on this device
55 //-------------------------------------------------
56
device_validity_check(validity_checker & valid) const57 void aakart_device::device_validity_check(validity_checker &valid) const
58 {
59 }
60
61
62 //-------------------------------------------------
63 // device_start - device-specific startup
64 //-------------------------------------------------
65
device_start()66 void aakart_device::device_start()
67 {
68 m_out_tx_cb.resolve_safe();
69 m_out_rx_cb.resolve_safe();
70 m_rxtimer = timer_alloc(RX_TIMER);
71 m_rxtimer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
72 m_txtimer = timer_alloc(TX_TIMER);
73 m_txtimer->adjust(attotime::from_hz(1), 0, attotime::from_hz(clock()));
74 m_mousetimer = timer_alloc(MOUSE_TIMER);
75 m_mousetimer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
76 m_keybtimer = timer_alloc(KEYB_TIMER);
77 m_keybtimer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
78 }
79
80 //-------------------------------------------------
81 // device_reset - device-specific reset
82 //-------------------------------------------------
83
device_reset()84 void aakart_device::device_reset()
85 {
86 m_status = STATUS_HRST;
87 m_new_command = 0;
88 m_rx = -1;
89 m_keyb_enable = 0;
90 m_mouse_enable = 0;
91 m_queue_size = 0;
92 }
93
94 //-------------------------------------------------
95 // device_timer - handler timer events
96 //-------------------------------------------------
97
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)98 void aakart_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
99 {
100 if(id == TX_TIMER && m_new_command)
101 {
102 switch(m_tx_latch)
103 {
104 case 0x00:
105 case 0x01:
106 case 0x02:
107 case 0x03:
108 case 0x04:
109 case 0x05:
110 case 0x06:
111 case 0x07:
112 // ---- -x-- scroll lock
113 // ---- --x- num lock
114 // ---- ---x caps lock
115 break;
116 case 0x20:
117 m_rx = 0x81;
118 m_out_tx_cb(ASSERT_LINE);
119 break;
120 case 0x30:
121 case 0x31:
122 case 0x32:
123 case 0x33:
124 m_keyb_enable = m_tx_latch & 1;
125 m_mouse_enable = (m_tx_latch & 2) >> 1;
126 if(m_queue_size)
127 {
128 m_rx = m_queue[0] & 0xff;
129 m_out_tx_cb(ASSERT_LINE);
130 }
131 break;
132 case 0x3f:
133 if(m_queue_size)
134 {
135 m_rx = (m_queue[0] >> 8) & 0xff;
136 m_out_tx_cb(ASSERT_LINE);
137
138 m_queue_size--;
139 for(int i=0; i<m_queue_size; i++)
140 m_queue[i] = m_queue[i + 1];
141 }
142 break;
143 case 0xfd:
144 m_rx = 0xfd;
145 m_out_tx_cb(ASSERT_LINE);
146 break;
147 case 0xfe:
148 m_rx = 0xfe;
149 m_out_tx_cb(ASSERT_LINE);
150 break;
151 case 0xff:
152 m_rx = 0xff;
153 m_out_tx_cb(ASSERT_LINE);
154 break;
155 default:
156 //printf("%02x %02x %02x\n",m_tx_latch,m_rx_latch,m_keyb_enable);
157 break;
158 }
159
160 m_new_command = 0;
161 m_out_rx_cb(ASSERT_LINE);
162 }
163 else if(id == TX_TIMER && m_queue_size && (m_keyb_enable || m_mouse_enable))
164 {
165 m_rx = m_queue[0] & 0xff;
166 m_out_tx_cb(ASSERT_LINE);
167 }
168 }
169
170 //**************************************************************************
171 // READ/WRITE HANDLERS
172 //**************************************************************************
173
174
read()175 uint8_t aakart_device::read()
176 {
177 m_out_tx_cb(CLEAR_LINE);
178 //machine().debug_break();
179 return m_rx;
180 }
181
write(uint8_t data)182 void aakart_device::write(uint8_t data)
183 {
184 // if(m_new_command) printf("skip cmd %02x\n",data);
185
186 m_tx_latch = data;
187 m_out_rx_cb(CLEAR_LINE);
188 m_new_command |= 1;
189 }
190
send_keycode_down(uint8_t row,uint8_t col)191 void aakart_device::send_keycode_down(uint8_t row, uint8_t col)
192 {
193 //printf("keycode down\n");
194 if (m_keyb_enable && m_queue_size < 0x10)
195 m_queue[m_queue_size++] = ((col | 0xc0) << 8) | (row | 0xc0);
196 }
197
send_keycode_up(uint8_t row,uint8_t col)198 void aakart_device::send_keycode_up(uint8_t row, uint8_t col)
199 {
200 //printf("keycode up\n");
201 if (m_keyb_enable && m_queue_size < 0x10)
202 m_queue[m_queue_size++] = ((col | 0xd0) << 8) | (row | 0xd0);
203 }
204
send_mouse(uint8_t x,uint8_t y)205 void aakart_device::send_mouse(uint8_t x, uint8_t y)
206 {
207 if (m_mouse_enable && m_queue_size < 0x10)
208 m_queue[m_queue_size++] = ((y & 0x7f) << 8) | (x & 0x7f);
209 }
210