1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4
5 Luxor ABC 1600 Mover emulation
6
7 **********************************************************************/
8
9 #include "emu.h"
10 #include "includes/abc1600.h"
11 #include "abc1600.lh"
12 #include "render.h"
13
14 //#define VERBOSE 1
15 #include "logmacro.h"
16
17
18 //**************************************************************************
19 // CONSTANTS / MACROS
20 //**************************************************************************
21
22 // video RAM
23 #define VIDEORAM_SIZE 0x40000
24 #define VIDEORAM16_MASK 0x3ffff
25 #define VIDEORAM8_MASK 0x7fffe
26
27
28 // flag register
29 #define L_P BIT(m_flag, 0)
30 #define BLANK BIT(m_flag, 1)
31 #define PIX_POL BIT(m_flag, 2)
32 #define FRAME_POL BIT(m_flag, 3)
33 #define HOLD_FY BIT(m_flag, 4)
34 #define HOLD_FX BIT(m_flag, 5)
35 #define COMP_MOVE BIT(m_flag, 6)
36 #define REPLACE BIT(m_flag, 7)
37
38
39
40 //**************************************************************************
41 // DEVICE DEFINITIONS
42 //**************************************************************************
43
44 DEFINE_DEVICE_TYPE(ABC1600_MOVER, abc1600_mover_device, "abc1600mover", "ABC 1600 Mover")
45
46
vram_map(address_map & map)47 void abc1600_mover_device::vram_map(address_map &map)
48 {
49 map(0x00000, 0x7ffff).rw(FUNC(abc1600_mover_device::video_ram_r), FUNC(abc1600_mover_device::video_ram_w));
50 }
51
crtc_map(address_map & map)52 void abc1600_mover_device::crtc_map(address_map &map)
53 {
54 map(0x00, 0x00).mirror(0xfe).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w));
55 map(0x01, 0x01).mirror(0xfe).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
56 }
57
iowr0_map(address_map & map)58 void abc1600_mover_device::iowr0_map(address_map &map)
59 {
60 map(0x00, 0x00).mirror(0xff).r(FUNC(abc1600_mover_device::iord0_r));
61 map(0x00, 0x00).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsx_hb_w));
62 map(0x01, 0x01).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsx_lb_w));
63 map(0x02, 0x02).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsy_hb_w));
64 map(0x03, 0x03).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsy_lb_w));
65 map(0x04, 0x04).mirror(0xf8).w(FUNC(abc1600_mover_device::ldtx_hb_w));
66 map(0x05, 0x05).mirror(0xf8).w(FUNC(abc1600_mover_device::ldtx_lb_w));
67 map(0x06, 0x06).mirror(0xf8).w(FUNC(abc1600_mover_device::ldty_hb_w));
68 map(0x07, 0x07).mirror(0xf8).w(FUNC(abc1600_mover_device::ldty_lb_w));
69 }
70
iowr1_map(address_map & map)71 void abc1600_mover_device::iowr1_map(address_map &map)
72 {
73 map(0x00, 0x00).mirror(0xff).nopr();
74 map(0x00, 0x00).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfx_hb_w));
75 map(0x01, 0x01).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfx_lb_w));
76 map(0x02, 0x02).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfy_hb_w));
77 map(0x03, 0x03).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfy_lb_w));
78 map(0x05, 0x05).mirror(0xf8).w(FUNC(abc1600_mover_device::wrml_w));
79 map(0x07, 0x07).mirror(0xf8).w(FUNC(abc1600_mover_device::wrdl_w));
80 }
81
iowr2_map(address_map & map)82 void abc1600_mover_device::iowr2_map(address_map &map)
83 {
84 map(0x00, 0x00).mirror(0xff).nopr();
85 map(0x00, 0x00).mirror(0xf8).w(FUNC(abc1600_mover_device::wrmask_strobe_hb_w));
86 map(0x01, 0x01).mirror(0xf8).w(FUNC(abc1600_mover_device::wrmask_strobe_lb_w));
87 map(0x02, 0x02).mirror(0xf8).w(FUNC(abc1600_mover_device::enable_clocks_w));
88 map(0x03, 0x03).mirror(0xf8).w(FUNC(abc1600_mover_device::flag_strobe_w));
89 map(0x04, 0x04).mirror(0xf8).w(FUNC(abc1600_mover_device::endisp_w));
90 }
91
92
mover_map(address_map & map)93 void abc1600_mover_device::mover_map(address_map &map)
94 {
95 map(0x00000, 0x3ffff).ram();
96 }
97
98
99 //-------------------------------------------------
100 // ROM( abc1600_mover )
101 //-------------------------------------------------
102
103 ROM_START( abc1600_mover )
104 ROM_REGION16_BE( 0x2000, "wrmsk", 0 )
CRC(bc737538)105 ROM_LOAD16_BYTE( "wrmskl 6490362-01.1g", 0x0001, 0x1000, CRC(bc737538) SHA1(80e2c3757eb7f713018808d6e41ebef612425028) )
106 ROM_LOAD16_BYTE( "wrmskh 6490363-01.1j", 0x0000, 0x1000, CRC(6b7c9f0b) SHA1(7155a993adcf08a5a8a2f22becf9fd66fda698be) )
107
108 ROM_REGION( 0x200, "shinf", 0 )
109 ROM_LOAD( "shinf 6490361-01.1f", 0x000, 0x200, CRC(20260f8f) SHA1(29bf49c64e7cc7592e88cde2768ac57c7ce5e085) )
110
111 ROM_REGION16_BE( 0x40, "drmsk", 0 )
112 ROM_LOAD16_BYTE( "drmskl 6490359-01.1k", 0x01, 0x20, CRC(6e71087c) SHA1(0acf67700d6227f4b315cf8fb0fb31c0e7fb9496) )
113 ROM_LOAD16_BYTE( "drmskh 6490358-01.1l", 0x00, 0x20, CRC(a4a9a9dc) SHA1(d8575c0335d6021cbb5f7bcd298b41c35294a80a) )
114
115 ROM_REGION( 0x104, "plds", 0 )
116 ROM_LOAD( "drmsk 6490360-01.1m", 0x000, 0x104, CRC(5f7143c1) SHA1(1129917845f8e505998b15288f02bf907487e4ac) ) // PAL16L8 mover word mixer @ 1m,1n,1t,2t
117 ROM_END
118
119
120 //-------------------------------------------------
121 // rom_region - device-specific ROM region
122 //-------------------------------------------------
123
124 const tiny_rom_entry *abc1600_mover_device::device_rom_region() const
125 {
126 return ROM_NAME( abc1600_mover );
127 }
128
129
130 //-------------------------------------------------
131 // mc6845
132 //-------------------------------------------------
133
get_crtca(uint16_t ma,uint8_t ra,uint8_t column)134 inline uint16_t abc1600_mover_device::get_crtca(uint16_t ma, uint8_t ra, uint8_t column)
135 {
136 /*
137
138 bit description
139
140 CRTCA0 0
141 CRTCA1 0
142 CRTCA2 CC1/MA1
143 CRTCA3 CC2/MA2
144 CRTCA4 CC3/MA3
145 CRTCA5 CC4/MA4
146 CRTCA6 RA0
147 CRTCA7 RA1
148 CRTCA8 RA2
149 CRTCA9 RA3
150 CRTCA10 CR0/MA8
151 CRTCA11 CR1/MA9
152 CRTCA12 CR2/MA10
153 CRTCA13 CR3/MA11
154 CRTCA14 CR4/MA12
155 CRTCA15 CR5/MA13
156
157 */
158
159 uint8_t cc = (ma & 0xff) + column;
160 uint8_t cr = ma >> 8;
161
162 return (cr << 10) | ((ra & 0x0f) << 6) | ((cc << 1) & 0x3c);
163 }
164
MC6845_UPDATE_ROW(abc1600_mover_device::crtc_update_row)165 MC6845_UPDATE_ROW(abc1600_mover_device::crtc_update_row)
166 {
167 int x = 0;
168 const pen_t *pen = m_palette->pens();
169
170 for (int column = 0; column < x_count; column += 2)
171 {
172 uint16_t dma = get_crtca(ma, ra, column);
173
174 // data is read out of video RAM in nibble mode by strobing CAS 4 times
175 for (int cas = 0; cas < 4; cas++)
176 {
177 uint16_t data = read_videoram(dma + cas);
178
179 for (int bit = 0; bit < 16; bit++)
180 {
181 int color = ((BIT(data, 15) ^ PIX_POL) && !BLANK) && de;
182
183 bitmap.pix(vbp + y, hbp + x++) = pen[color];
184
185 data <<= 1;
186 }
187 }
188 }
189 }
190
MC6845_ON_UPDATE_ADDR_CHANGED(abc1600_mover_device::crtc_update)191 MC6845_ON_UPDATE_ADDR_CHANGED( abc1600_mover_device::crtc_update )
192 {
193 }
194
195 //-------------------------------------------------
196 // device_add_mconfig - add device configuration
197 //-------------------------------------------------
198
device_add_mconfig(machine_config & config)199 void abc1600_mover_device::device_add_mconfig(machine_config &config)
200 {
201 config.set_default_layout(layout_abc1600);
202
203 screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER, rgb_t::green()));
204 screen.set_screen_update(FUNC(abc1600_mover_device::screen_update));
205 screen.set_raw(XTAL(64'000'000), 0x3e0, 0, 0x300, 0x433, 0, 0x400);
206
207 PALETTE(config, m_palette, palette_device::MONOCHROME);
208
209 SY6845E(config, m_crtc, XTAL(64'000'000)/32);
210 m_crtc->set_screen(SCREEN_TAG);
211 m_crtc->set_show_border_area(true);
212 m_crtc->set_char_width(32);
213 m_crtc->set_update_row_callback(FUNC(abc1600_mover_device::crtc_update_row));
214 m_crtc->set_on_update_addr_change_callback(FUNC(abc1600_mover_device::crtc_update));
215 }
216
217
218 //**************************************************************************
219 // LIVE DEVICE
220 //**************************************************************************
221
222 //-------------------------------------------------
223 // abc1600_mover_device - constructor
224 //-------------------------------------------------
225
abc1600_mover_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)226 abc1600_mover_device::abc1600_mover_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
227 device_t(mconfig, ABC1600_MOVER, tag, owner, clock),
228 device_memory_interface(mconfig, *this),
229 m_space_config("vram", ENDIANNESS_BIG, 16, 18, -1, address_map_constructor(FUNC(abc1600_mover_device::mover_map), this)),
230 m_crtc(*this, "sy6845e"),
231 m_palette(*this, "palette"),
232 m_wrmsk_rom(*this, "wrmsk"),
233 m_shinf_rom(*this, "shinf"),
234 m_drmsk_rom(*this, "drmsk")
235 {
236 }
237
238
239 //-------------------------------------------------
240 // device_start - device-specific startup
241 //-------------------------------------------------
242
device_start()243 void abc1600_mover_device::device_start()
244 {
245 // state saving
246 save_item(NAME(m_endisp));
247 save_item(NAME(m_clocks_disabled));
248 save_item(NAME(m_gmdi));
249 save_item(NAME(m_wrm));
250 save_item(NAME(m_ms));
251 save_item(NAME(m_ds));
252 save_item(NAME(m_flag));
253 save_item(NAME(m_xsize));
254 save_item(NAME(m_ysize));
255 save_item(NAME(m_udx));
256 save_item(NAME(m_udy));
257 save_item(NAME(m_xfrom));
258 save_item(NAME(m_xto));
259 save_item(NAME(m_yto));
260 save_item(NAME(m_ty));
261 save_item(NAME(m_mfa));
262 save_item(NAME(m_mta));
263 save_item(NAME(m_sh));
264 save_item(NAME(m_mdor));
265 save_item(NAME(m_hold_1w_cyk));
266 save_item(NAME(m_wrms0));
267 save_item(NAME(m_wrms1));
268 save_item(NAME(m_rmc));
269 save_item(NAME(m_cmc));
270 }
271
272
273 //-------------------------------------------------
274 // device_reset - device-specific reset
275 //-------------------------------------------------
276
device_reset()277 void abc1600_mover_device::device_reset()
278 {
279 // disable display
280 m_clocks_disabled = 1;
281 m_endisp = 0;
282 }
283
284
285 //-------------------------------------------------
286 // memory_space_config - return a description of
287 // any address spaces owned by this device
288 //-------------------------------------------------
289
memory_space_config() const290 device_memory_interface::space_config_vector abc1600_mover_device::memory_space_config() const
291 {
292 return space_config_vector {
293 std::make_pair(0, &m_space_config)
294 };
295 }
296
297
298 //-------------------------------------------------
299 // read_videoram -
300 //-------------------------------------------------
301
read_videoram(offs_t offset)302 inline uint16_t abc1600_mover_device::read_videoram(offs_t offset)
303 {
304 return space().read_word((offset & VIDEORAM16_MASK) << 1);
305 }
306
307
308 //-------------------------------------------------
309 // write_videoram -
310 //-------------------------------------------------
311
write_videoram(offs_t offset,uint16_t data,uint16_t mask)312 inline void abc1600_mover_device::write_videoram(offs_t offset, uint16_t data, uint16_t mask)
313 {
314 uint16_t old_data = read_videoram(offset);
315
316 space().write_word((offset & VIDEORAM16_MASK) << 1, (data & mask) | (old_data & (mask ^ 0xffff)));
317 }
318
319
320 //-------------------------------------------------
321 // video_ram_r -
322 //-------------------------------------------------
323
video_ram_r(offs_t offset)324 uint8_t abc1600_mover_device::video_ram_r(offs_t offset)
325 {
326 offs_t addr = (offset & VIDEORAM8_MASK) >> 1;
327 uint8_t data = 0;
328
329 if (offset & 0x01)
330 {
331 data = read_videoram(addr) & 0xff;
332 }
333 else
334 {
335 data = read_videoram(addr) >> 8;
336 }
337
338 return data;
339 }
340
341
342 //-------------------------------------------------
343 // video_ram_w -
344 //-------------------------------------------------
345
video_ram_w(offs_t offset,uint8_t data)346 void abc1600_mover_device::video_ram_w(offs_t offset, uint8_t data)
347 {
348 offs_t addr = (offset & VIDEORAM8_MASK) >> 1;
349
350 if (offset & 0x01)
351 {
352 if (REPLACE)
353 {
354 // WRPORT_LB
355 m_wrm = (m_wrm & 0xff00) | data;
356 LOG("WRM LB %02x -> %04x\n", data, m_wrm);
357 }
358 else
359 {
360 // DATAPORT_LB
361 m_gmdi = (m_gmdi & 0xff00) | data;
362 LOG("GMDI LB %02x -> %04x\n", data, m_gmdi);
363 }
364
365 write_videoram(addr, m_gmdi, m_wrm & 0x00ff);
366
367 LOG("Video RAM write LB to %05x : %04x\n", addr, read_videoram(addr));
368 }
369 else
370 {
371 if (REPLACE)
372 {
373 // WRPORT_HB
374 m_wrm = (data << 8) | (m_wrm & 0xff);
375 LOG("WRM HB %02x -> %04x\n", data, m_wrm);
376 }
377 else
378 {
379 // DATAPORT_HB
380 m_gmdi = (data << 8) | (m_gmdi & 0xff);
381 LOG("GMDI HB %02x -> %04x\n", data, m_gmdi);
382 }
383
384 write_videoram(addr, m_gmdi, m_wrm & 0xff00);
385
386 LOG("Video RAM write HB to %05x : %04x\n", addr, read_videoram(addr));
387 }
388 }
389
390
391 //-------------------------------------------------
392 // iord0_r -
393 //-------------------------------------------------
394
iord0_r()395 uint8_t abc1600_mover_device::iord0_r()
396 {
397 /*
398
399 bit description
400
401 0 0
402 1 SCREENPOS
403 2
404 3
405 4
406 5
407 6 VSYNC
408 7 BUSY
409
410 */
411
412 uint8_t data = 0;
413
414 // monitor orientation (portrait/landscape)
415 data |= machine().render().first_target()->view() << 1;
416
417 // vertical sync
418 data |= m_crtc->vsync_r() << 6;
419
420 return data;
421 }
422
423
424 //-------------------------------------------------
425 // ldsx_hb_w -
426 //-------------------------------------------------
427
ldsx_hb_w(uint8_t data)428 void abc1600_mover_device::ldsx_hb_w(uint8_t data)
429 {
430 /*
431
432 bit description
433
434 0 XSIZE8
435 1 XSIZE9
436 2 U/D* Y
437 3 U/D* X
438 4
439 5
440 6
441 7
442
443 */
444
445 LOG("%s LDSX HB: %02x\n", machine().describe_context(), data);
446
447 m_xsize = ((data & 0x03) << 8) | (m_xsize & 0xff);
448 m_udy = BIT(data, 2);
449 m_udx = BIT(data, 3);
450 }
451
452
453 //-------------------------------------------------
454 // ldsx_lb_w -
455 //-------------------------------------------------
456
ldsx_lb_w(uint8_t data)457 void abc1600_mover_device::ldsx_lb_w(uint8_t data)
458 {
459 /*
460
461 bit description
462
463 0 XSIZE0
464 1 XSIZE1
465 2 XSIZE2
466 3 XSIZE3
467 4 XSIZE4
468 5 XSIZE5
469 6 XSIZE6
470 7 XSIZE7
471
472 */
473
474 LOG("%s LDSX LB: %02x\n", machine().describe_context(), data);
475
476 m_xsize = (m_xsize & 0x300) | data;
477 }
478
479
480 //-------------------------------------------------
481 // ldsy_hb_w -
482 //-------------------------------------------------
483
ldsy_hb_w(uint8_t data)484 void abc1600_mover_device::ldsy_hb_w(uint8_t data)
485 {
486 /*
487
488 bit description
489
490 0 YSIZE8
491 1 YSIZE9
492 2 YSIZE10
493 3 YSIZE11
494 4
495 5
496 6
497 7
498
499 */
500
501 LOG("%s LDSY HB: %02x\n", machine().describe_context(), data);
502
503 m_ysize = ((data & 0x0f) << 8) | (m_ysize & 0xff);
504 }
505
506
507 //-------------------------------------------------
508 // ldsy_lb_w -
509 //-------------------------------------------------
510
ldsy_lb_w(uint8_t data)511 void abc1600_mover_device::ldsy_lb_w(uint8_t data)
512 {
513 /*
514
515 bit description
516
517 0 YSIZE0
518 1 YSIZE1
519 2 YSIZE2
520 3 YSIZE3
521 4 YSIZE4
522 5 YSIZE5
523 6 YSIZE6
524 7 YSIZE7
525
526 */
527
528 LOG("%s LDSY LB: %02x\n", machine().describe_context(), data);
529
530 m_ysize = (m_ysize & 0xf00) | data;
531 }
532
533
534 //-------------------------------------------------
535 // ldtx_hb_w -
536 //-------------------------------------------------
537
ldtx_hb_w(uint8_t data)538 void abc1600_mover_device::ldtx_hb_w(uint8_t data)
539 {
540 /*
541
542 bit description
543
544 0 XTO8, MTA4
545 1 XTO9, MTA5
546 2
547 3
548 4
549 5
550 6
551 7
552
553 */
554
555 LOG("%s LDTX HB: %02x\n", machine().describe_context(), data);
556
557 m_xto = ((data & 0x03) << 8) | (m_xto & 0xff);
558 m_mta = (m_mta & 0x3ffcf) | ((data & 0x03) << 4);
559 }
560
561
562 //-------------------------------------------------
563 // ldtx_lb_w -
564 //-------------------------------------------------
565
ldtx_lb_w(uint8_t data)566 void abc1600_mover_device::ldtx_lb_w(uint8_t data)
567 {
568 /*
569
570 bit description
571
572 0 XTO0
573 1 XTO1
574 2 XTO2
575 3 XTO3
576 4 XTO4, MTA0
577 5 XTO5, MTA1
578 6 XTO6, MTA2
579 7 XTO7, MTA3
580
581 */
582
583 LOG("%s LDTX LB: %02x\n", machine().describe_context(), data);
584
585 m_xto = (m_xto & 0x300) | data;
586 m_mta = (m_mta & 0x3fff0) | (data >> 4);
587 }
588
589
590 //-------------------------------------------------
591 // ldty_hb_w -
592 //-------------------------------------------------
593
ldty_hb_w(uint8_t data)594 void abc1600_mover_device::ldty_hb_w(uint8_t data)
595 {
596 /*
597
598 bit description
599
600 0 YTO8, MTA14
601 1 YTO9, MTA15
602 2 YTO10, MTA16
603 3 YTO11, MTA17
604 4
605 5
606 6
607 7
608
609 */
610
611 LOG("%s LDTY HB: %02x\n", machine().describe_context(), data);
612
613 if (L_P) return;
614
615 m_ty = ((data & 0x0f) << 8) | (m_yto & 0xff);
616 m_yto = ((data & 0x0f) << 8) | (m_yto & 0xff);
617 m_mta = ((data & 0x0f) << 14) | (m_mta & 0x3fff);
618 }
619
620
621 //-------------------------------------------------
622 // ldty_lb_w -
623 //-------------------------------------------------
624
ldty_lb_w(uint8_t data)625 void abc1600_mover_device::ldty_lb_w(uint8_t data)
626 {
627 /*
628
629 bit description
630
631 0 YTO0, MTA6
632 1 YTO1, MTA7
633 2 YTO2, MTA8
634 3 YTO3, MTA9
635 4 YTO4, MTA10
636 5 YTO5, MTA11
637 6 YTO6, MTA12
638 7 YTO7, MTA13
639
640 */
641
642 LOG("%s LDTY LB: %02x\n", machine().describe_context(), data);
643
644 if (L_P) return;
645
646 m_ty = (m_ty & 0xf00) | data;
647 m_yto = (m_yto & 0xf00) | data;
648 m_mta = (m_mta & 0x3c03f) | (data << 6);
649 }
650
651
652 //-------------------------------------------------
653 // ldfx_hb_w -
654 //-------------------------------------------------
655
ldfx_hb_w(uint8_t data)656 void abc1600_mover_device::ldfx_hb_w(uint8_t data)
657 {
658 /*
659
660 bit description
661
662 0 XFROM8, MFA4
663 1 XFROM9, MFA5
664 2
665 3
666 4
667 5
668 6
669 7
670
671 */
672
673 LOG("%s LDFX HB: %02x\n", machine().describe_context(), data);
674
675 m_xfrom = ((data & 0x03) << 8) | (m_xfrom & 0xff);
676 m_mfa = (m_mfa & 0x3ffcf) | ((data & 0x03) << 4);
677 }
678
679
680 //-------------------------------------------------
681 // ldfx_lb_w -
682 //-------------------------------------------------
683
ldfx_lb_w(uint8_t data)684 void abc1600_mover_device::ldfx_lb_w(uint8_t data)
685 {
686 /*
687
688 bit description
689
690 0 XFROM0
691 1 XFROM1
692 2 XFROM2
693 3 XFROM3
694 4 XFROM4, MFA0
695 5 XFROM5, MFA1
696 6 XFROM6, MFA2
697 7 XFROM7, MFA3
698
699 */
700
701 LOG("%s LDFX LB: %02x\n", machine().describe_context(), data);
702
703 m_xfrom = (m_xfrom & 0x300) | data;
704 m_mfa = (m_mfa & 0x3fff0) | (data >> 4);
705 }
706
707
708 //-------------------------------------------------
709 // ldfy_hb_w -
710 //-------------------------------------------------
711
ldfy_hb_w(uint8_t data)712 void abc1600_mover_device::ldfy_hb_w(uint8_t data)
713 {
714 /*
715
716 bit description
717
718 0 MFA14
719 1 MFA15
720 2 MFA16
721 3 MFA17
722 4
723 5
724 6
725 7
726
727 */
728
729 LOG("%s LDFY HB: %02x\n", machine().describe_context(), data);
730
731 m_mfa = ((data & 0x0f) << 14) | (m_mfa & 0x3fff);
732 }
733
734
735 //-------------------------------------------------
736 // ldfy_lb_w -
737 //-------------------------------------------------
738
ldfy_lb_w(uint8_t data)739 void abc1600_mover_device::ldfy_lb_w(uint8_t data)
740 {
741 /*
742
743 bit description
744
745 0 MFA6
746 1 MFA7
747 2 MFA8
748 3 MFA9
749 4 MFA10
750 5 MFA11
751 6 MFA12
752 7 MFA13
753
754 */
755
756 LOG("%s LDFY LB: %02x\n", machine().describe_context(), data);
757
758 m_mfa = (m_mfa & 0x3c03f) | (data << 6);
759
760 mover();
761 }
762
763
764 //-------------------------------------------------
765 // wrml_w -
766 //-------------------------------------------------
767
wrml_w(offs_t offset,uint8_t data)768 void abc1600_mover_device::wrml_w(offs_t offset, uint8_t data)
769 {
770 /*
771
772 bit description
773
774 0 MOVE CYK CLK
775 1 DISP CYC SEL / DISP CYK PRE FETCH (+1 PIXCLK)
776 2 DATA CLK
777 3 _DISP MEM WE
778 4 _CAS HB
779 5 DTACK CLK / BLANK TEST (+2 PIXCLK)
780 6 DISPREC CLK
781 7 _RAS HB
782
783 */
784
785 LOG("MS %u : %02x\n", (offset >> 4) & 0x0f, data);
786
787 if (m_clocks_disabled)
788 {
789 m_ms[(offset >> 4) & 0x0f] = data;
790 }
791 }
792
793
794 //-------------------------------------------------
795 // wrdl_w -
796 //-------------------------------------------------
797
wrdl_w(offs_t offset,uint8_t data)798 void abc1600_mover_device::wrdl_w(offs_t offset, uint8_t data)
799 {
800 /*
801
802 bit description
803
804 0 MOVE CYK CLK
805 1 DISP CYC SEL / DISP CYK PRE FETCH (+1 PIXCLK)
806 2 DATA CLK
807 3 _DISP MEM WE
808 4 _CAS HB
809 5 DTACK CLK / BLANK TEST (+2 PIXCLK)
810 6 DISPREC CLK
811 7 _RAS HB
812
813 */
814
815 LOG("WS %u : %02x\n", (offset >> 4) & 0x0f, data);
816
817 if (m_clocks_disabled)
818 {
819 m_ds[(offset >> 4) & 0x0f] = data;
820 }
821 }
822
823
824 //-------------------------------------------------
825 // wrmask_strobe_hb_w -
826 //-------------------------------------------------
827
wrmask_strobe_hb_w(uint8_t data)828 void abc1600_mover_device::wrmask_strobe_hb_w(uint8_t data)
829 {
830 if (REPLACE)
831 {
832 // DATAPORT_HB
833 m_gmdi = (data << 8) | (m_gmdi & 0xff);
834 LOG("GMDI HB %04x\n", m_gmdi);
835 }
836 else
837 {
838 // WRPORT_HB
839 m_wrm = (data << 8) | (m_wrm & 0xff);
840 LOG("WRM HB %04x\n", m_gmdi);
841 }
842 }
843
844
845 //-------------------------------------------------
846 // wrmask_strobe_lb_w -
847 //-------------------------------------------------
848
wrmask_strobe_lb_w(uint8_t data)849 void abc1600_mover_device::wrmask_strobe_lb_w(uint8_t data)
850 {
851 if (REPLACE)
852 {
853 // DATAPORT_LB
854 m_gmdi = (m_gmdi & 0xff00) | data;
855 LOG("GMDI LB %04x\n", m_gmdi);
856 }
857 else
858 {
859 // WRPORT_LB
860 m_wrm = (m_wrm & 0xff00) | data;
861 LOG("WRM LB %04x\n", m_gmdi);
862 }
863 }
864
865
866 //-------------------------------------------------
867 // enable_clocks_w -
868 //-------------------------------------------------
869
enable_clocks_w(uint8_t data)870 void abc1600_mover_device::enable_clocks_w(uint8_t data)
871 {
872 LOG("ENABLE CLOCKS\n");
873 m_clocks_disabled = 0;
874 }
875
876
877 //-------------------------------------------------
878 // flag_strobe_w -
879 //-------------------------------------------------
880
flag_strobe_w(uint8_t data)881 void abc1600_mover_device::flag_strobe_w(uint8_t data)
882 {
883 /*
884
885 bit description
886
887 0 L/_P FLAG
888 1 BLANK FLAG
889 2 PIX POL
890 3 FRAME POL
891 4 HOLD FY
892 5 HOLD FX
893 6 COMP MOVE FLAG
894 7 REPLACE/SET & RESET
895
896 */
897
898 m_flag = data;
899 LOG("FLAG %02x\n", m_flag);
900 }
901
902
903 //-------------------------------------------------
904 // endisp_w -
905 //-------------------------------------------------
906
endisp_w(uint8_t data)907 void abc1600_mover_device::endisp_w(uint8_t data)
908 {
909 m_endisp = 1;
910 LOG("ENDISP\n");
911 }
912
913
914
915 //**************************************************************************
916 // MOVER
917 //**************************************************************************
918
919 //-------------------------------------------------
920 // clock_mfa_x -
921 //-------------------------------------------------
922
clock_mfa_x()923 inline void abc1600_mover_device::clock_mfa_x()
924 {
925 uint16_t mfa_y = m_mfa >> 6;
926 uint8_t mfa_x = m_mfa & 0x3f;
927
928 if (!HOLD_FX)
929 {
930 mfa_x += m_udx ? 1 : -1;
931 mfa_x &= 0x3f;
932 }
933
934 m_mfa = (mfa_y << 6) | mfa_x;
935 }
936
937
938 //-------------------------------------------------
939 // clock_mfa_y -
940 //-------------------------------------------------
941
clock_mfa_y()942 inline void abc1600_mover_device::clock_mfa_y()
943 {
944 uint16_t mfa_y = m_mfa >> 6;
945 uint8_t mfa_x = m_mfa & 0x3f;
946
947 if (!HOLD_FY)
948 {
949 mfa_y += m_udy ? 1 : -1;
950 mfa_y &= 0xfff;
951 }
952
953 m_mfa = (mfa_y << 6) | mfa_x;
954 }
955
956
957 //-------------------------------------------------
958 // clock_mta_x -
959 //-------------------------------------------------
960
clock_mta_x()961 inline void abc1600_mover_device::clock_mta_x()
962 {
963 uint16_t mta_y = m_mta >> 6;
964 uint8_t mta_x = m_mta & 0x3f;
965
966 mta_x += m_udx ? 1 : -1;
967 mta_x &= 0x3f;
968
969 m_mta = (mta_y << 6) | mta_x;
970 }
971
972
973 //-------------------------------------------------
974 // clock_mta_y -
975 //-------------------------------------------------
976
clock_mta_y()977 inline void abc1600_mover_device::clock_mta_y()
978 {
979 uint16_t mta_y = m_mta >> 6;
980 uint8_t mta_x = m_mta & 0x3f;
981
982 mta_y += m_udy ? 1 : -1;
983 mta_y &= 0xfff;
984
985 m_mta = (mta_y << 6) | mta_x;
986 }
987
988
989 //-------------------------------------------------
990 // load_mfa_x -
991 //-------------------------------------------------
992
load_mfa_x()993 inline void abc1600_mover_device::load_mfa_x()
994 {
995 uint16_t mfa_y = m_mfa >> 6;
996 uint8_t mfa_x = m_xfrom >> 4;
997
998 m_mfa = (mfa_y << 6) | mfa_x;
999 }
1000
1001
1002 //-------------------------------------------------
1003 // load_mta_x -
1004 //-------------------------------------------------
1005
load_mta_x()1006 inline void abc1600_mover_device::load_mta_x()
1007 {
1008 uint16_t mta_y = m_mta >> 6;
1009 uint8_t mta_x = m_xto >> 4;
1010
1011 m_mta = (mta_y << 6) | mta_x;
1012 }
1013
1014
1015 //-------------------------------------------------
1016 // load_xy_reg -
1017 //-------------------------------------------------
1018
load_xy_reg()1019 inline void abc1600_mover_device::load_xy_reg()
1020 {
1021 if (L_P) return;
1022
1023 uint16_t sum = m_xto + m_xsize;
1024
1025 m_xto = sum & 0x3ff;
1026 m_yto = m_ty & 0xfff;
1027 m_mta = (m_ty << 6) | (sum >> 4);
1028 }
1029
1030
1031 //-------------------------------------------------
1032 // compare_mta_x -
1033 //-------------------------------------------------
1034
compare_mta_x()1035 inline void abc1600_mover_device::compare_mta_x()
1036 {
1037 uint8_t mta_x_end = ((m_xto + m_xsize) >> 4) & 0x3f;
1038 uint8_t mta_x = m_mta & 0x3f;
1039
1040 if (mta_x == mta_x_end)
1041 {
1042 m_cmc = 0;
1043 }
1044
1045 m_wrms1 = m_cmc & m_amm;
1046 }
1047
1048
1049 //-------------------------------------------------
1050 // compare_mta_y -
1051 //-------------------------------------------------
1052
compare_mta_y()1053 inline void abc1600_mover_device::compare_mta_y()
1054 {
1055 int mta_y_end = (m_yto + m_ysize) & 0xfff;
1056 uint16_t mta_y = m_mta >> 6;
1057
1058 if (mta_y == mta_y_end)
1059 {
1060 m_rmc = 0;
1061 }
1062 }
1063
1064
1065 //-------------------------------------------------
1066 // get_shinf -
1067 //-------------------------------------------------
1068
get_shinf()1069 inline void abc1600_mover_device::get_shinf()
1070 {
1071 /*
1072
1073 bit description
1074
1075 A0 XFROM0
1076 A1 XFROM1
1077 A2 XFROM2
1078 A3 XFROM3
1079 A4 XTO0
1080 A5 XTO1
1081 A6 XTO2
1082 A7 XTO3
1083 A8 U/D* X
1084
1085 */
1086
1087 uint16_t shinf_addr = (m_udx << 8) | ((m_xto & 0x0f) << 4) | (m_xfrom & 0x0f);
1088 uint8_t shinf = m_shinf_rom[shinf_addr];
1089
1090 m_sh = shinf & 0x0f;
1091 m_hold_1w_cyk = BIT(shinf, 5);
1092 }
1093
1094
1095 //-------------------------------------------------
1096 // get_drmsk -
1097 //-------------------------------------------------
1098
get_drmsk()1099 inline uint16_t abc1600_mover_device::get_drmsk()
1100 {
1101 /*
1102
1103 bit description
1104
1105 A0 SH0
1106 A1 SH1
1107 A2 SH2
1108 A3 SH3
1109 A4 U/D* X
1110
1111 */
1112
1113 uint16_t drmsk_addr = (m_udx << 4) | (m_sh & 0x0f);
1114 return m_drmsk_rom[drmsk_addr];
1115 }
1116
1117
1118 //-------------------------------------------------
1119 // get_wrmsk - get mover write mask
1120 //-------------------------------------------------
1121
get_wrmsk()1122 inline uint16_t abc1600_mover_device::get_wrmsk()
1123 {
1124 /*
1125
1126 bit description
1127
1128 A0 XTO0
1129 A1 XTO1
1130 A2 XTO2
1131 A3 XTO3
1132 A4 XSIZE0
1133 A5 XSIZE1
1134 A6 XSIZE2
1135 A7 XSIZE3
1136 A8 U/D* X
1137 A9 ANDED MASKS
1138 A10 WRMS0
1139 A11 WRMS1
1140
1141 */
1142
1143 uint16_t wrmsk_addr = (m_wrms1 << 11) | (m_wrms0 << 10) | ((!m_wrms1 && !m_wrms0) << 9) | (m_udx << 8) | ((m_xsize & 0x0f) << 4) | (m_xto & 0x0f);
1144 return m_wrmsk_rom[wrmsk_addr] ^ 0xffff;
1145 }
1146
1147
1148 //-------------------------------------------------
1149 // barrel_shift -
1150 //-------------------------------------------------
1151
barrel_shift(uint16_t gmdr)1152 inline uint16_t abc1600_mover_device::barrel_shift(uint16_t gmdr)
1153 {
1154 uint16_t rot = gmdr;
1155
1156 for (int sh = 0; sh < m_sh; sh++)
1157 {
1158 int msb = BIT(rot, 15);
1159 rot <<= 1;
1160 rot |= msb;
1161 }
1162
1163 return rot;
1164 }
1165
1166
1167 //-------------------------------------------------
1168 // word_mixer -
1169 //-------------------------------------------------
1170
word_mixer(uint16_t rot)1171 inline uint16_t abc1600_mover_device::word_mixer(uint16_t rot)
1172 {
1173 uint16_t drmsk = get_drmsk();
1174 uint16_t gmdi = (rot & drmsk) | (m_mdor & (drmsk ^ 0xffff));
1175
1176 if (COMP_MOVE)
1177 {
1178 gmdi ^= 0xffff;
1179 }
1180
1181 m_mdor = rot;
1182
1183 return gmdi;
1184 }
1185
1186
1187 //-------------------------------------------------
1188 // mover -
1189 //-------------------------------------------------
1190
mover()1191 void abc1600_mover_device::mover()
1192 {
1193 LOG("XFROM %u XSIZE %u YSIZE %u XTO %u YTO %u MFA %05x MTA %05x U/D*X %u U/D*Y %u\n", m_xfrom, m_xsize, m_ysize, m_xto, m_yto, m_mfa, m_mta, m_udx, m_udy);
1194
1195 m_amm = 1;
1196
1197 m_rmc = 1;
1198 get_shinf();
1199
1200 do
1201 {
1202 compare_mta_y();
1203
1204 load_mfa_x();
1205 load_mta_x();
1206 m_cmc = 1;
1207 m_wrms0 = 0;
1208
1209 if (m_hold_1w_cyk)
1210 {
1211 // read one word in advance
1212 uint16_t gmdr = read_videoram(m_mfa);
1213 uint16_t rot = barrel_shift(gmdr);
1214 word_mixer(rot);
1215
1216 clock_mfa_x();
1217 }
1218
1219 do
1220 {
1221 compare_mta_x();
1222
1223 uint16_t gmdr = read_videoram(m_mfa);
1224 uint16_t rot = barrel_shift(gmdr);
1225 uint16_t gmdi = word_mixer(rot);
1226 uint16_t mask = get_wrmsk();
1227
1228 write_videoram(m_mta, gmdi, mask);
1229
1230 clock_mfa_x();
1231 clock_mta_x();
1232
1233 m_wrms0 = 1;
1234 }
1235 while (m_cmc);
1236
1237 clock_mfa_y();
1238 clock_mta_y();
1239 }
1240 while (m_rmc);
1241
1242 load_xy_reg();
1243
1244 m_amm = 0;
1245 }
1246
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)1247 uint32_t abc1600_mover_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
1248 {
1249 if (m_endisp)
1250 {
1251 bitmap.fill(m_palette->pen(FRAME_POL), cliprect);
1252 m_crtc->screen_update(screen, bitmap, cliprect);
1253 }
1254 else
1255 {
1256 bitmap.fill(rgb_t::black(), cliprect);
1257 }
1258
1259 return 0;
1260 }
1261