1 // license:GPL-2.0+
2 // copyright-holders:Raphael Nabet
3 /*
4 733 ASR emulation
5
6 We are emulating a TI Model 733 ASR ("Silent 700") data terminal,
7 interfaced through a TI asynchronous EIA/TTY interface module.
8
9 The ASR features a printer, a keyboard and a tape unit (which is not
10 emulated). The ASR is attached to the computer with a serial interface.
11
12 References:
13 945401-9701 Model 990/4 Computer System Field Maintenance Manual p. C-1,
14 945250-9701 990 Computer Family Systems Handbook pp. 5-9 through 5-16,
15 0943442-9701 Model 990 Computer Reference Manual Preliminary pp. 3-13
16 through 3-21 and 3-39 through 3-44.
17
18 TODO:
19 * separate ASR emulation from EIA interface emulation?
20 * implement tape interface?
21
22 Raphael Nabet 2003
23
24 Rewritten as class
25 Michael Zapf, 2014
26 */
27
28 #include "emu.h"
29 #include "733_asr.h"
30
31 #include <algorithm>
32
33 enum
34 {
35 /*ASROutQueueSize = 32,*/
36
37 asr_window_offset_x = 0,
38 asr_window_offset_y = 0,
39 asr_window_width = 640,
40 asr_window_height = 480,
41 asr_scroll_step = 8
42 };
43
44 enum
45 {
46 AS_wrq_mask = 1 << 3,
47 AS_rrq_mask = 1 << 4,
48 AS_dsr_mask = 1 << 6,
49 AS_int_mask = 1 << 7,
50
51 AM_dtr_mask = 1 << 1,
52 AM_rts_mask = 1 << 2,
53 AM_enint_mask = 1 << 6
54 };
55
56 enum
57 {
58 asrfontdata_size = 96/*128*/*8
59 };
60
61 static const gfx_layout fontlayout =
62 {
63 6, 8, /* 6*8 characters */
64 /*96*/128, /* 96 characters */
65 1, /* 1 bit per pixel */
66 { 0 },
67 { 0, 1, 2, 3, 4, 5, 6, 7 }, /* straightforward layout */
68 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
69 8*8 /* every char takes 8 consecutive bytes */
70 };
71
72 static GFXDECODE_START( gfx_asr733 )
73 GFXDECODE_ENTRY( asr733_chr_region, 0, fontlayout, 0, 1 )
74 GFXDECODE_END
75
76
77 DEFINE_DEVICE_TYPE(ASR733, asr733_device, "asr733", "733 ASR")
78
asr733_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)79 asr733_device::asr733_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
80 : device_t(mconfig, ASR733, tag, owner, clock)
81 , device_gfx_interface(mconfig, *this, gfx_asr733, "palette")
82 , m_screen(*this, "screen")
83 , m_keyint_line(*this)
84 , m_lineint_line(*this)
85 {
86 }
87
88 //-------------------------------------------------
89 // device_start - device-specific startup
90 //-------------------------------------------------
91
device_start()92 void asr733_device::device_start()
93 {
94 int width = m_screen->width();
95 int height = m_screen->height();
96 const rectangle &visarea = m_screen->visible_area();
97
98 m_last_key_pressed = 0x80;
99 m_bitmap = std::make_unique<bitmap_ind16>(width, height);
100
101 m_bitmap->fill(0, visarea);
102
103 m_keyint_line.resolve();
104 m_lineint_line.resolve();
105
106 m_line_timer = timer_alloc(0);
107
108 uint8_t *dst;
109
110 static const unsigned char fontdata6x8[asrfontdata_size] =
111 { /* ASCII characters */
112 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,
113 0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xf8,0x50,0xf8,0x50,0x00,0x00,
114 0x20,0x70,0xc0,0x70,0x18,0xf0,0x20,0x00,0x40,0xa4,0x48,0x10,0x20,0x48,0x94,0x08,
115 0x60,0x90,0xa0,0x40,0xa8,0x90,0x68,0x00,0x10,0x20,0x40,0x00,0x00,0x00,0x00,0x00,
116 0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x00,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x00,
117 0x20,0xa8,0x70,0xf8,0x70,0xa8,0x20,0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00,
118 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,
119 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,
120 0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x00,
121 0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x00,0x70,0x88,0x08,0x30,0x08,0x88,0x70,0x00,
122 0x10,0x30,0x50,0x90,0xf8,0x10,0x10,0x00,0xf8,0x80,0xf0,0x08,0x08,0x88,0x70,0x00,
123 0x70,0x80,0xf0,0x88,0x88,0x88,0x70,0x00,0xf8,0x08,0x08,0x10,0x20,0x20,0x20,0x00,
124 0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x70,0x00,
125 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,
126 0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,
127 0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00,
128 0x70,0x88,0xb8,0xa8,0xb8,0x80,0x70,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,
129 0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,
130 0xf0,0x88,0x88,0x88,0x88,0x88,0xf0,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x00,
131 0xf8,0x80,0x80,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x80,0x98,0x88,0x88,0x70,0x00,
132 0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
133 0x08,0x08,0x08,0x08,0x88,0x88,0x70,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x00,
134 0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x00,
135 0x88,0xc8,0xa8,0x98,0x88,0x88,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
136 0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x08,
137 0xf0,0x88,0x88,0xf0,0x88,0x88,0x88,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,
138 0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
139 0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00,0x88,0x88,0x88,0x88,0xa8,0xd8,0x88,0x00,
140 0x88,0x50,0x20,0x20,0x20,0x50,0x88,0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x00,
141 0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x30,0x20,0x20,0x20,0x20,0x20,0x30,0x00,
142 0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x30,0x10,0x10,0x10,0x10,0x10,0x30,0x00,
143 0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,
144 0x40,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,
145 0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x78,0x00,
146 0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00,0x00,0x00,0x70,0x88,0xf8,0x80,0x78,0x00,
147 0x18,0x20,0x70,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x70,
148 0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x00,
149 0x20,0x00,0x20,0x20,0x20,0x20,0x20,0xc0,0x80,0x80,0x90,0xa0,0xe0,0x90,0x88,0x00,
150 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xf0,0xa8,0xa8,0xa8,0xa8,0x00,
151 0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,
152 0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x08,
153 0x00,0x00,0xb0,0xc8,0x80,0x80,0x80,0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xf0,0x00,
154 0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00,
155 0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00,0x00,0x00,0xa8,0xa8,0xa8,0xa8,0x50,0x00,
156 0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70,
157 0x00,0x00,0xf8,0x10,0x20,0x40,0xf8,0x00,0x08,0x10,0x10,0x20,0x10,0x10,0x08,0x00,
158 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00,
159 0x00,0x68,0xb0,0x00,0x00,0x00,0x00,0x00,0x20,0x50,0x20,0x50,0xa8,0x50,0x00,0x00
160 };
161
162 dst = machine().root_device().memregion(asr733_chr_region)->base();
163
164 memcpy(dst, fontdata6x8, asrfontdata_size);
165 }
166
167 //-------------------------------------------------
168 // device_reset - device-specific reset
169 //-------------------------------------------------
170
device_reset()171 void asr733_device::device_reset()
172 {
173 /*m_OutQueueLen = 0;*/
174
175 m_status = AS_dsr_mask | AS_wrq_mask;
176 m_mode = 0;
177 m_line_timer->adjust(attotime::from_msec(0), 0, attotime::from_hz(60));
178
179 set_interrupt_line();
180 }
181
set_interrupt_line()182 void asr733_device::set_interrupt_line()
183 {
184 if ((m_mode & AM_enint_mask) && (m_new_status_flag)) /* right??? */
185 {
186 m_status |= AS_int_mask;
187 m_keyint_line(ASSERT_LINE);
188 }
189 else
190 {
191 m_status &= ~AS_int_mask;
192 m_keyint_line(CLEAR_LINE);
193 }
194 }
195
196 /* write a single char on screen */
draw_char(int character,int x,int y,int color)197 void asr733_device::draw_char(int character, int x, int y, int color)
198 {
199 gfx(0)->opaque(*m_bitmap, m_bitmap->cliprect(), character-32, color, 0, 0, x+1, y);
200 }
201
linefeed()202 void asr733_device::linefeed()
203 {
204 uint8_t buf[asr_window_width];
205
206 assert(asr_window_offset_x + asr_window_width <= m_bitmap->width());
207 assert(asr_window_offset_y + asr_window_height <= m_bitmap->height());
208 for (int y=asr_window_offset_y; y<asr_window_offset_y+asr_window_height-asr_scroll_step; y++)
209 {
210 std::copy_n(&m_bitmap->pix(y+asr_scroll_step, asr_window_offset_x), asr_window_width, buf);
211 draw_scanline8(*m_bitmap, asr_window_offset_x, y, asr_window_width, buf, palette().pens());
212 }
213
214 const rectangle asr_scroll_clear_window(
215 asr_window_offset_x, /* min_x */
216 asr_window_offset_x+asr_window_width-1, /* max_x */
217 asr_window_offset_y+asr_window_height-asr_scroll_step, /* min_y */
218 asr_window_offset_y+asr_window_height-1 /* max_y */
219 );
220 m_bitmap->fill(0, asr_scroll_clear_window);
221 }
222
transmit(uint8_t data)223 void asr733_device::transmit(uint8_t data)
224 {
225 switch (data)
226 {
227 /* aux device control chars */
228 case 0x05:
229 /* ENQ -> "WRU": ??? */
230 break;
231
232 case 0x11:
233 /* DC1 -> "X-ON": transmit on??? */
234 break;
235
236 case 0x12:
237 /* DC2 -> "X-OFF": transmit off??? */
238 break;
239
240 case 0x13:
241 /* DC3 -> "TAPE": tape on??? */
242 break;
243
244 case 0x14:
245 /* DC4 -> "-T-A-P-E-" ("TAPE" with overstrike): tape off??? */
246 break;
247
248
249 /* printer control chars */
250 case 0x07:
251 /* BELL: 250ms beep */
252 break;
253
254 case 0x08:
255 /* BS: backspace */
256 if (m_x > 0)
257 m_x--;
258 break;
259
260 case 0x0A:
261 /* LF: line feed */
262 linefeed();
263 break;
264
265 case 0x0D:
266 /* CR: carriage return */
267 m_x = 0;
268 break;
269
270
271 default:
272 if ((data < 0x20) || (data == 0x7f) || (data >= 0x80))
273 /* ignore control characters */
274 break;
275
276 if (m_x == 80)
277 {
278 m_x = 0;
279 linefeed();
280 }
281 draw_char(data, asr_window_offset_x + m_x*8, asr_window_offset_y+asr_window_height-8, 0);
282 m_x++;
283 break;
284 }
285
286 m_status |= AS_wrq_mask;
287 m_new_status_flag = 1; /* right??? */
288 set_interrupt_line();
289 }
290
291 #if 0
292 void asr733_device::receive_callback(int dummy)
293 {
294 (void) dummy;
295
296 m_recv_buf = m_OutQueue[m_OutQueueHead];
297 m_OutQueueHead = (m_OutQueueHead + 1) % ASROutQueueSize;
298 m_OutQueueLen--;
299
300 m_status |= AS_rrq_mask;
301 m_new_status_flag = 1; /* right??? */
302 set_interrupt_line();
303 }
304 #endif
305
306 /*
307 0-7: receive buffer
308 8: XMITING transmit in progress, 1 if transmitting
309 9: TIMERR timing error, 1 if error
310 10: RCR reverse channel receive, not used
311 "ASR733/33 ID" 1 -> TTY (???) (2270509-9701 pp. G-9 & G-10)
312 11: WRQ write request, 1 if ready to transmit
313 12: RRQ read request, 1 if ready to receive
314 13: DCD data carrier detect, not used
315 14: DSR data set ready, 1 if online
316 15: INT interrupt, 1 if interrupt
317 */
cru_r(offs_t offset)318 uint8_t asr733_device::cru_r(offs_t offset)
319 {
320 int reply = 0;
321
322 switch (offset >> 3)
323 {
324 case 0:
325 /* receive buffer */
326 reply = m_recv_buf;
327 break;
328
329 case 1:
330 /* status register */
331 reply = m_status;
332 break;
333 }
334
335 return BIT(reply, offset & 7);
336 }
337
338 /*
339 0-7: transmit buffer
340 8: not used
341 9: DTR data terminal ready (set to 1)
342 10: RTS request to send (set to 1)
343 11: CLRWRQ clear write request (write any value to execute)
344 12: CLRRRQ clear read request (write any value to execute)
345 13: CLRNSF clear new status flag - clear DSR/DCD interrupts (write any value to execute)
346 14: enable interrupts, 1 to enable interrupts
347 15: diagnostic mode, 0 for normal mode
348 */
cru_w(offs_t offset,uint8_t data)349 void asr733_device::cru_w(offs_t offset, uint8_t data)
350 {
351 switch (offset)
352 {
353 case 0:
354 case 1:
355 case 2:
356 case 3:
357 case 4:
358 case 5:
359 case 6:
360 case 7:
361 /* transmit buffer */
362 if (data)
363 m_xmit_buf |= 1 << offset;
364 else
365 m_xmit_buf &= ~ (1 << offset);
366 if ((offset == 7) && (m_mode & AM_dtr_mask) && (m_mode & AM_rts_mask)) /* right??? */
367 transmit(m_xmit_buf);
368 break;
369
370 case 8: /* not used */
371 break;
372
373 case 9: /* data terminal ready (set to 1) */
374 case 10: /* request to send (set to 1) */
375 case 14: /* enable interrupts, 1 to enable interrupts */
376 case 15: /* diagnostic mode, 0 for normal mode */
377 if (data)
378 m_mode |= 1 << (offset - 8);
379 else
380 m_mode &= ~ (1 << (offset - 8));
381 if (offset == 14)
382 set_interrupt_line();
383 break;
384
385 case 11: /* clear write request (write any value to execute) */
386 case 12: /* clear read request (write any value to execute) */
387 m_status &= ~ (1 << (offset - 8));
388 set_interrupt_line();
389 break;
390
391 case 13: /* clear new status flag - whatever it means (write any value to execute) */
392 m_new_status_flag = 0;
393 set_interrupt_line();
394 break;
395 }
396 }
397
398 /*
399 Video refresh
400 */
refresh(bitmap_ind16 & bitmap,int x,int y)401 void asr733_device::refresh(bitmap_ind16 &bitmap, int x, int y)
402 {
403 copybitmap(bitmap, *m_bitmap, 0, 0, x, y, m_bitmap->cliprect());
404 }
405
406
407 /*
408 Time callbacks
409 */
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)410 void asr733_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
411 {
412 check_keyboard();
413 m_lineint_line(ASSERT_LINE);
414 m_lineint_line(CLEAR_LINE);
415 }
416
417 static const unsigned char key_translate[3][51] =
418 {
419 { /* unshifted */
420 '1',
421 '2',
422 '3',
423 '4',
424 '5',
425 '6',
426 '7',
427 '8',
428 '9',
429 '0',
430 ':',
431 '-',
432
433 0x1b,
434 'Q',
435 'W',
436 'E',
437 'R',
438 'T',
439 'Y',
440 'U',
441 'I',
442 'O',
443 'P',
444 0x0a,
445 0x0d,
446
447 0,
448 'A',
449 'S',
450 'D',
451 'F',
452 'G',
453 'H',
454 'J',
455 'K',
456 'L',
457 ';',
458 0x08,
459 0,
460
461 0,
462 'Z',
463 'X',
464 'C',
465 'V',
466 'B',
467 'N',
468 'M',
469 ',',
470 '.',
471 '/',
472 0,
473
474 ' '
475 },
476 { /* shifted */
477 '!',
478 '"',
479 '#',
480 '$',
481 '%',
482 '&',
483 '^',
484 '(',
485 ')',
486 ' ',
487 '*',
488 '=',
489
490 0x1b,
491 'Q',
492 'W',
493 'E',
494 'R',
495 'T',
496 'Y',
497 'U',
498 'I',
499 '_',
500 '@',
501 0x0a,
502 0x0d,
503
504 0,
505 'A',
506 'S',
507 'D',
508 'F',
509 'G',
510 'H',
511 'J',
512 0,
513 '/',
514 '+',
515 0x08,
516 0,
517
518 0,
519 'Z',
520 'X',
521 'C',
522 'V',
523 'B',
524 '^',
525 '|',
526 '<',
527 '>',
528 '?',
529 0,
530
531 ' '
532 },
533 { /* control */
534 '1',
535 '2',
536 '3',
537 '4',
538 '5',
539 '6',
540 '7',
541 '8',
542 '9',
543 '0',
544 ':',
545 '-',
546
547 0x1b,
548 0x11,
549 0x17,
550 0x05,
551 0x12,
552 0x14,
553 0x19,
554 0x15,
555 0x09,
556 0x0f,
557 0x10,
558 0x0a,
559 0x0d,
560
561 0,
562 0x01,
563 0x13,
564 0x04,
565 0x06,
566 0x07,
567 0x08,
568 0x0a,
569 0x0b,
570 0x0c,
571 ';',
572 0x08,
573 0,
574
575 0,
576 0x1a,
577 0x18,
578 0x03,
579 0x16,
580 0x02,
581 0x0e,
582 0x0d,
583 ',',
584 '.',
585 '/',
586 0,
587
588 ' '
589 }
590 };
591
592
593 /*
594 keyboard handler: should be called regularly by machine code, for instance
595 every Video Blank Interrupt.
596 */
check_keyboard()597 void asr733_device::check_keyboard()
598 {
599 enum modifier_state_t
600 {
601 /* key modifier states */
602 unshifted = 0, shift, control,
603 /* special value to stop repeat if the modifier state changes */
604 special_debounce = -1
605 } ;
606
607 enum { repeat_delay = 5 /* approx. 1/10s */ };
608
609 //uint16_t key_buf[6];
610 uint16_t key_buf[4];
611 int i, j;
612 modifier_state_t modifier_state;
613 int repeat_mode;
614
615 static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3" };
616
617 /* read current key state */
618 /* 2008-05 FP: in 733_asr.h there are only 4 input ports defined... */
619 /* for (i = 0; i < 6; i++) */
620 for (i = 0; i < 4; i++)
621 {
622 key_buf[i] = ioport(keynames[i])->read();
623 }
624
625 /* process key modifiers */
626 if (key_buf[1] & 0x0200)
627 modifier_state = control;
628 else if ((key_buf[2] & 0x0040) || (key_buf[3] & 0x0002))
629 modifier_state = shift;
630 else
631 modifier_state = unshifted;
632
633 /* test repeat key */
634 repeat_mode = key_buf[2] & 0x0020;
635
636 /* remove modifier keys */
637 key_buf[1] &= ~0x0200;
638 key_buf[2] &= ~0x0060;
639 key_buf[3] &= ~0x0002;
640
641 if (! repeat_mode)
642 /* reset REPEAT timer if the REPEAT key is not pressed */
643 m_repeat_timer = 0;
644
645 if ( !(m_last_key_pressed & 0x80) && (key_buf[m_last_key_pressed >> 4] & (1 << (m_last_key_pressed & 0xf))))
646 {
647 /* last key has not been released */
648 if (modifier_state == m_last_modifier_state)
649 {
650 /* handle REPEAT mode if applicable */
651 if ((repeat_mode) && (++m_repeat_timer == repeat_delay))
652 {
653 if (m_status & AS_rrq_mask)
654 { /* keyboard buffer full */
655 m_repeat_timer--;
656 }
657 else
658 { /* repeat current key */
659 m_status |= AS_rrq_mask;
660 m_new_status_flag = 1; /* right??? */
661 set_interrupt_line();
662 m_repeat_timer = 0;
663 }
664 }
665 }
666 else
667 {
668 m_repeat_timer = 0;
669 m_last_modifier_state = special_debounce;
670 }
671 }
672 else
673 {
674 m_last_key_pressed = 0x80;
675
676 if (m_status & AS_rrq_mask)
677 { /* keyboard buffer full */
678 /* do nothing */
679 }
680 else
681 {
682 //for (i=0; i<6; i++)
683 for (i=0; i<4; i++)
684 {
685 for (j=0; j<16; j++)
686 {
687 if (key_buf[i] & (1 << j))
688 {
689 m_last_key_pressed = (i << 4) | j;
690 m_last_modifier_state = modifier_state;
691
692 m_recv_buf = (int)key_translate[modifier_state][m_last_key_pressed];
693 m_status |= AS_rrq_mask;
694 m_new_status_flag = 1; /* right??? */
695 set_interrupt_line();
696 return;
697 }
698 }
699 }
700 }
701 }
702 }
703
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)704 uint32_t asr733_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
705 {
706 refresh(bitmap, 0, 0);
707 return 0;
708 }
709
710
711 INPUT_PORTS_START( asr733 )
712 PORT_START("KEY0") /* keys 1-16 */ \
PORT_CODE(KEYCODE_1)713 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) \
714 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) \
715 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) \
716 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) \
717 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) \
718 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) \
719 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) \
720 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) \
721 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) \
722 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) \
723 PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_MINUS) \
724 PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_EQUALS) \
725 PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) \
726 PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) \
727 PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) \
728 PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) \
729 \
730 PORT_START("KEY1") /* keys 17-32 */ \
731 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) \
732 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) \
733 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) \
734 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) \
735 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) \
736 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) \
737 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) \
738 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LINE FEED") PORT_CODE(KEYCODE_CLOSEBRACE) \
739 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) \
740 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) \
741 PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) \
742 PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) \
743 PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) \
744 PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) \
745 PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) \
746 PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) \
747 \
748 PORT_START("KEY2") /* keys 33-48 */ \
749 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) \
750 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) \
751 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) \
752 PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) \
753 PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RUB OUT") PORT_CODE(KEYCODE_BACKSPACE) \
754 PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("REPEAT") PORT_CODE(KEYCODE_RALT) \
755 /* hack for my mac that does not disciminate the right ALT key */ \
756 /* PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("REPEAT") PORT_CODE(KEYCODE_LALT) */ \
757 PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) \
758 PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) \
759 PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) \
760 PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) \
761 PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) \
762 PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) \
763 PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) \
764 PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) \
765 PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) \
766 PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) \
767 \
768 PORT_START("KEY3") /* keys 49-51 */ \
769 PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) \
770 PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_RSHIFT) \
771 PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(SPACE)") PORT_CODE(KEYCODE_SPACE)
772 INPUT_PORTS_END
773
774 ioport_constructor asr733_device::device_input_ports() const
775 {
776 return INPUT_PORTS_NAME( asr733 );
777 }
778
779 //-------------------------------------------------
780 // device_add_mconfig - add device configuration
781 //-------------------------------------------------
782
783
device_add_mconfig(machine_config & config)784 void asr733_device::device_add_mconfig(machine_config &config)
785 {
786 PALETTE(config, "palette", palette_device::MONOCHROME_INVERTED);
787
788 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
789 m_screen->set_refresh_hz(60);
790 m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
791 m_screen->set_screen_update(FUNC(asr733_device::screen_update));
792 m_screen->set_size(640, 480);
793 m_screen->set_visarea(0, 640-1, 0, 480-1);
794 m_screen->set_palette("palette");
795 }
796