1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
|
// license:BSD-3-Clause
// copyright-holders: Joakim Larsson Edström
/*****************************************************************************
Ericsson PC Monochrome HR Graphics Board 1070
******************************************************************************/
/* PCB layouts and assembly years from online pictures and physical unit.
Ericsson - marked SPVT02 8301 60 53-10, assembled in 1985 indicated by chip dates
+--------------------------------------------------------------------------------------+ ___
| IC1 IC2 IC3 IC4 IC5 +-IC15--EPROM-+ IC6 IC7 IC8 S1 ||
| |8363 65 14-80| ||
| IC9 IC10 IC11 IC12 IC13 IC14|CG 50821 A64 |+------------------++-IC24 EPROM--+ ||
| +-------------+| CRTC HD46505SP-1 ||10-40VP | ||
| IC16 IC17 IC18 IC19 IC20 IC21 IC22 | IC23 HD68A45SP ||402 28 A19 | J4|| not
| +------------------++-------------+ || mounted
| IC25 IC26 IC27 IC28 IC29 IC30 IC31 IC32 IC33 IC34 ||
| O-|__
| IC35 IC36 IC37 IC38 IC39 IC40 IC41 IC42 IC43 IC44 || |
| ||DB15
| IC45 IC46 IC47 IC48 IC49 IC50 IC51 IC52 IC53 IC54 || |
| ||__|
| IC55 IC56 IC57 IC58 IC59 IC60 IC61 IC62 IC63 IC64 O-|
| J1A ||
| IC65 IC66 IC67 IC68 IC69 IC70 IC71 IC72 +--------------------------------------------+|
+-----------------------------------------+ ||||||||| ||||||||||||||||||||||||| |
I85565 A85571 (labels) |
|
IC's (from photos)
------------------------------------------------------------------------------
IC1 74F109 IC26 74F86 IC51 TMS4416-15NL 4 x 16Kbits DRAM
IC2 74LS393 IC27 74LS08 IC52 74ALS574
IC3 74F64 IC28 74F153 IC53 74LS138
IC4 74ALS299 IC29 74LS174 IC54 74F86
IC5 74LS375 IC30 74LS374 IC55 74F109
IC6 74LS151 IC31 74LS374 IC56 74F32
IC7 74LS153 IC32 74ALS574 IC57 74F109
IC8 74LS389? IC33 74LS08 IC58 74F00?
IC9 74F02 IC34 74LS245 IC59 74LS244
IC10 74ALS109 IC35 74F10? IC60 TMS4416-15NL 4 x 16Kbits DRAM
IC11 Crystal 17.040MHz IC36 74LS02 IC61 TMS4416-15NL 4 x 16Kbits DRAM
IC12 74F64 IC37 74LS00 IC62 74ALS574
IC13 74ALS299 IC38 74F374 IC63 74LS138
IC14 PAL? 10-70ART40101 IC39 74LS125 IC64 74LS245
IC15 EPROM 8363 65 14-80 CG 50821 A64 IC40 74LS244 IC65 74LS00
IC16 Crystal 19.170MHz IC41 74LS244 IC66 74LS02
IC17 74LS10 IC42 74LS574 IC67 74LS51
IC18 74F08 IC43 74LS32 IC68 74LS04
IC19 74ALS574 IC44 MC10124 - TTL to MECL converter IC69 74LS153
IC20 74LS299 IC45 74LS109 IC70 74LS109
IC21 74LS273 IC46 74LS00 IC71 74LS138
IC22 74ALS574 IC47 74F194 IC72 74LS139
IC23 CRTC HD46505SP,HD68A45SP IC48 74F04
IC24 EPROM 2764, 10-40 VP 402 28 A19 IC49 74LS174
IC25 74ALS109 IC50 TMS4416-15NL 4 x 16Kbits DRAM
General description
-------------------
The PCB has a 2 bit DIP switch S1 and a DB15 non standard video connector. There is also an unsoldered J4 connector
above the DB15 but no hole prepared for a connector in the plate. Above the J4 connector there is a two pin PCB connector
that probably receives the power for the monitor for the DB15 from the PSU.
Just below IC65 and IC66 there are two labels saying "I 85565" and "A E85571" respectively
Video cable, card DB15 <---> monitor DB25
---------------------------------------------------
Ericsson 2 +VS 4 Ericsson
Monochrome 3 VS return 2 Monochrome HR
HR Graphics 10 +VS 17 Monitors 3111 (Amber) or
Board 1070 11 VS return 15 3712/3715 (Black & White)
4 VSYNC 6
12 VSYNC 19
5 HSYNC 7
13 HSYNC 20
6 High intensity 8
14 High intensity 21
7 Video 9
15 Video 22
8 GND 11
This board is normaly used with an Ericsson monitor due to the non standard connector.
Trivia: https://www.pinterest.se/pin/203084264425177097/
*/
#include "emu.h"
#include "eis_hgb107x.h"
#include "screen.h"
#define LOG_READ (1U << 1)
#define LOG_SETUP (1U << 2)
#define LOG_ROW (1U << 3)
#define LOG_MODE (1U << 4)
#define LOG_CHRG (1U << 5)
#define LOG_STAT (1U << 6)
//#define VERBOSE (LOG_MODE|LOG_SETUP|LOG_ROW)
//#define LOG_OUTPUT_STREAM std::cout
#include "logmacro.h"
#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__)
#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)
#define LOGROW(...) LOGMASKED(LOG_ROW, __VA_ARGS__)
#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__)
#define LOGCHRG(...) LOGMASKED(LOG_CHRG, __VA_ARGS__)
#define LOGSTAT(...) LOGMASKED(LOG_STAT, __VA_ARGS__)
#ifdef _MSC_VER
#define FUNCNAME __func__
#else
#define FUNCNAME __PRETTY_FUNCTION__
#endif
#define MC6845_NAME "mc6845"
enum
{
MDA_TEXT_INTEN = 0,
MDA_TEXT_BLINK,
MDA_LOWRES_TEXT_INTEN,
MDA_LOWRES_TEXT_BLINK
};
#define EPC_MDA_SCREEN "epc_mda_screen" // TODO: use a device finder reference instead
ROM_START( epc )
ROM_REGION(0x2000,"chargen", 0)
ROM_LOAD("8363_65_14_80_cg_50821_a64.bin", 0x00000, 0x2000, CRC(be709786) SHA1(38ab26224bbe66bbe2bb2ccac29b41cbf78bdbf8))
//ROM_LOAD("10_40_vp_402_28_ic_24_a19.bin", 0x00000, 0x2000, CRC(2aa53b92) SHA1(87051a037249eb631d7d2191bc0e925125c60f39))
ROM_END
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
DEFINE_DEVICE_TYPE(ISA8_EPC_MDA, isa8_epc_mda_device, "isa_epc_mda", "Ericsson PC Monochrome HR Graphics Board 1070")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
/* There are two crystals on the board: 19.170Mhz and 17.040MHz TODO: verify use */
/* Text modes uses 720x400 base resolution and the Graphics modes 320/640x200/400 */
/* This matches the difference between the crystals so we assume this for now */
void isa8_epc_mda_device::device_add_mconfig(machine_config &config)
{
screen_device &screen(SCREEN(config, EPC_MDA_SCREEN, SCREEN_TYPE_RASTER));
screen.set_raw(XTAL(19'170'000) / 4, 720, 0, 720, 400, 0, 400);
screen.set_screen_update(MC6845_NAME, FUNC(mc6845_device::screen_update));
HD6845S(config, m_crtc, XTAL(19'170'000) / 16); // clock and divider are guesswork
m_crtc->set_screen(EPC_MDA_SCREEN);
m_crtc->set_show_border_area(false);
m_crtc->set_char_width(8);
m_crtc->set_update_row_callback(FUNC(isa8_epc_mda_device::crtc_update_row));
m_crtc->out_hsync_callback().set(FUNC(isa8_epc_mda_device::hsync_changed));
m_crtc->out_vsync_callback().set(FUNC(isa8_epc_mda_device::vsync_changed));
}
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
const tiny_rom_entry *isa8_epc_mda_device::device_rom_region() const
{
return ROM_NAME( epc );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// isa8_epc_mda_device - constructor
//-------------------------------------------------
isa8_epc_mda_device::isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock) :
isa8_epc_mda_device(mconfig, ISA8_EPC_MDA, tag, owner, clock)
{
}
isa8_epc_mda_device::isa8_epc_mda_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, const XTAL &clock) :
device_t(mconfig, type, tag, owner, clock),
device_isa8_card_interface(mconfig, *this),
m_crtc(*this, MC6845_NAME),
m_soft_chr_gen(nullptr),
m_s1(*this, "S1"),
m_color_mode(0),
m_mode_control2(0),
m_screen(*this, EPC_MDA_SCREEN),
m_io_monitor(*this, "MONITOR"),
m_chargen(*this, "chargen"),
m_installed(false),
m_framecnt(0),
m_mode_control(0),
m_update_row_type(-1),
m_chr_gen(nullptr),
m_vsync(0),
m_hsync(0),
m_pixel(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void isa8_epc_mda_device::device_start()
{
/* Palette for use with the Ericsson Amber Monochrome HR CRT monitor 3111, P3 phospor 602nm 255,183, 0 */
m_3111_pal[0] = rgb_t( 0, 0, 0); // black
m_3111_pal[1] = rgb_t( 143, 103, 0); // dim
m_3111_pal[2] = rgb_t( 191, 137, 0); // normal
m_3111_pal[3] = rgb_t( 255, 183, 0); // bright
/* Palette for use with the Ericsson B&W Monochrome HR CRT monitor 3712/3715 */
m_371x_pal[0] = rgb_t( 0, 0, 0); // black
m_371x_pal[1] = rgb_t( 143, 143, 143); // dim
m_371x_pal[2] = rgb_t( 191, 191, 191); // normal
m_371x_pal[3] = rgb_t( 255, 255, 255); // bright
/* Init a default palette */
m_pal = &m_3111_pal; // In case screen starts rendering before device_reset where we read the settings
m_videoram.resize(0x8000);
set_isa_device();
m_installed = false;
m_hd6845s = subdevice<hd6845s_device>(MC6845_NAME);
}
void isa8_epc_mda_device::device_reset()
{
m_framecnt = 0;
m_mode_control = 0;
m_vsync = 0;
m_hsync = 0;
m_pixel = 0;
m_color_mode = m_s1->read();
LOGSETUP("%s: m_color_mode:%02x\n", FUNCNAME, m_color_mode);
m_pal = (m_io_monitor-> read() & 1) == 1 ? &m_371x_pal : &m_3111_pal;
m_vmode = 0;
if (m_installed == false)
{
m_isa->install_device(0x3b0, 0x3bf, read8sm_delegate(*this, FUNC(isa8_epc_mda_device::io_read)), write8sm_delegate(*this, FUNC(isa8_epc_mda_device::io_write)));
m_isa->install_bank(0xb0000, 0xb7fff, &m_videoram[0]); // Monochrome emulation mode VRAM address
// This check allows a color monitor adapter to be installed at this address range if color emulation is disabled
if (m_color_mode & 1)
{
m_isa->install_device(0x3d0, 0x3df, read8sm_delegate(*this, FUNC(isa8_epc_mda_device::io_read)), write8sm_delegate(*this, FUNC(isa8_epc_mda_device::io_write)));
m_isa->install_bank(0xb8000, 0xbffff, &m_videoram[0]); // Color emulation mode VRAM address, but same 32KB areas as there are only this amount on the board
}
m_installed = true;
}
}
/*
* Register Address table from the manual
* Ericsson name MDA mode CGA mode Standard name
*-------------------------------------------------------------------------------
* 6845 Address Registers 0x3b4 0x3d4 wo CRT Index reg
* 6845 Data Registers 0x3b5 0x3d5 wo CRT Data reg
* Mode Register 1 0x3b8 0x3d8 rw MDA/CGA mode reg (bit 0,1 & 4 incompatible)
* Mode Register 2 0x3bf 0x3df rw CRT/CPU page reg (incompatible w PCjr only)
* Status Register 0x3ba 0x3da r CGA/MDA status reg (incompatible)
* w EGA/VGA feature ccontrol reg (not used by this board)
*/
void isa8_epc_mda_device::io_write(offs_t offset, uint8_t data)
{
LOG("%s: %04x <- %02x\n", FUNCNAME, offset, data);
switch( offset )
{
case 0x04:
//LOGSETUP(" - HD6845S address write\n");
m_hd6845s->address_w( data );
break;
case 0x05:
//LOGSETUP(" - HD6845S register write\n");
m_hd6845s->register_w( data );
break;
case 0x08: // Mode 1 reg
LOGMODE(" - Mode register 1 write: %02x\n", data);
LOGMODE(" MSB attribute: %s\n", (data & 0x20) == 0 ? "intensity" : "blink");
LOGMODE(" Horizontal px: %s\n", (data & 0x10) == 0 ? "320/LR" : "640/HR");
LOGMODE(" Video : %s\n", (data & 0x08) == 0 ? "Disabled" : "Enabled");
LOGMODE(" Mode : %s\n", (data & 0x02) == 0 ? "Text" : "Graphics");
LOGMODE(" Text columns : %d\n", (data & 0x01) == 0 ? 40 : 80);
m_mode_control = data;
m_vmode &= ~(VM_GRAPH | VM_COLS80 | VM_HOR640);
m_vmode |= ((m_mode_control & 0x01) ? VM_COLS80 : 0);
m_vmode |= ((m_mode_control & 0x02) ? VM_GRAPH : 0);
m_vmode |= ((m_mode_control & 0x10) ? VM_HOR640 : 0);
m_update_row_type = ((data & 0x20) == 0 ? MDA_LOWRES_TEXT_INTEN : MDA_LOWRES_TEXT_BLINK);
{
rectangle rect(0, get_xres() - 1, 0, get_yres() -1);
m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50));
}
LOGMODE("Video Mode:%02x\n\n", m_vmode);
break;
case 0x0f: // Mode 2 reg
LOGMODE(" - Mode register 2 write: %02x\n", data);
LOGMODE(" Vertical px : %s\n", (data & MR2_VER400) == 0 ? "200" : "400");
LOGMODE(" Character set: %s\n", (data & MR2_CHRSET) == 0 ? "0" : "1");
LOGMODE(" Emulated : %s\n", (data & MR2_COLEMU) == 0 ? "Color" : "Monochrome");
m_mode_control2 = data;
m_vmode &= ~(VM_MONO | VM_VER400);
m_vmode |= ((m_mode_control2 & 0x04) ? VM_MONO : 0);
m_vmode |= ((m_mode_control2 & 0x80) ? VM_VER400 : 0);
{
rectangle rect(0, get_xres() - 1, 0, get_yres() -1);
m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50));
}
LOGMODE("Video Mode:%02x\n\n", m_vmode);
break;
default:
LOG("EPC MDA: io_write at wrong offset:%02x\n", offset);
}
}
uint8_t isa8_epc_mda_device::io_read(offs_t offset)
{
LOG("%s: %04x <- ???\n", FUNCNAME, offset);
int data = 0xff;
switch( offset )
{
case 0x04:
LOGR(" - hd6845s address read\n");
break;
case 0x05:
LOGR(" - hd6845s register read\n");
data = m_hd6845s->register_r();
break;
case 0x08: // Mode 1 reg
data = m_mode_control;
LOGMODE(" - Mode register 1 read: %02x\n", data);
break;
case 0x0a: // Status reg: b7-6=00 board ID; b3 vert retrace; b0 horiz retrace; b5,4,2,1 unused
data = (m_vsync != 0 ? 0x08 : 0x00) | (m_hsync != 0 ? 0x01 : 0x00);
LOGSTAT(" - Status register read: %02x\n", data);
break;
case 0x0f: // Mode 2 reg
data = m_mode_control2;
LOGMODE(" - Mode register 2 read: %02x\n", data);
break;
default:
LOG("EPC MDA: io_read at wrong offset:%02x\n", offset);
logerror("EPC MDA: io_read at wrong offset:%02x\n", offset);
}
LOG(" !!!: %04x <- %02x\n", offset, data);
return data;
}
WRITE_LINE_MEMBER( isa8_epc_mda_device::hsync_changed )
{
m_hsync = state ? 1 : 0;
}
WRITE_LINE_MEMBER( isa8_epc_mda_device::vsync_changed )
{
m_vsync = state ? 0x80 : 0;
if ( state )
{
m_framecnt++;
}
}
/*
* rW MDA mode control register (see #P138)
*/
void isa8_epc_mda_device::mode_control_w(uint8_t data)
{
m_mode_control = data;
switch( m_mode_control & 0x2a )
{
case 0x08:
m_update_row_type = MDA_TEXT_INTEN;
break;
case 0x28:
m_update_row_type = MDA_TEXT_BLINK;
break;
default:
m_update_row_type = -1;
}
}
/* R- CRT status register (see #P139)
* (EGA/VGA) input status 1 register
* 7 HGC vertical sync in progress
* 6-4 adapter 000 hercules
* 001 hercules+
* 101 hercules InColor
* else unknown
* 3 pixel stream (0 black, 1 white)
* 2-1 reserved
* 0 horizontal drive enable
*/
uint8_t isa8_epc_mda_device::status_r()
{
// Faking pixel stream here
if (!machine().side_effects_disabled())
m_pixel++;
return 0xF0 | (m_pixel & 0x08) | m_hsync;
}
inline int isa8_epc_mda_device::get_xres()
{
return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_HOR640) ? 640 : 320 ) : 720;
}
inline int isa8_epc_mda_device::get_yres()
{
return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_VER400) ? 400 : 200 ) : 400;
}
MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row)
{
// Get som debug data from a couple of rows now and then
if ( y < (16 * 0 + 0x20) && (m_framecnt & 0xff) == 0 )
{
LOGROW("%11.6f %s\n - y:%d chr_base:%d ra:%d ma:%d x_count:%d\n", machine().time().as_double(), FUNCNAME,
y, y % 16, ra, ma, x_count);
}
// Video Off handling
if ((m_mode_control & MR1_VIDEO) == 0)
{
for (int i = 0; i < get_xres(); i++)
{
bitmap.pix(y, i) = rgb_t::black();
}
}
// Graphic modes using only pixeldata, soft fonts are 8x8 or 8x16 but this is transparant to the code
else if ((m_vmode & VM_GRAPH) != 0)
{
logerror("EPC MDA: graphic modes not supported yet\n");
}
// Text modes using one of two 9x16 fonts in character rom
else
{
uint32_t *p = &bitmap.pix(y);
uint16_t chr_base = ra;
// Adjust row pointer if in monochrome text mode as we insert two scanlines per row of characters (see below)
if (m_vmode & VM_MONO)
{
p = &bitmap.pix((y / 14) * 16 + y % 14);
}
// Loop over each character in a row
for ( int i = 0; i < x_count; i++ )
{
uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF;
uint8_t chr = m_videoram[ offset ];
uint8_t attr = m_videoram[ offset + 1 ];
uint8_t data = m_chargen[ ((m_mode_control2 & MR2_CHRSET) ? 0x1000 : 0) + chr_base + chr * 16];
// Default to light text on dark background
uint8_t fg = 2;
uint8_t bg = 0;
if (y == 0 && i == 0) LOGCHRG(" - Offset: %04x Chr: '%c'[%02x] Attr: %02x Chr_base: %04x\n", offset, chr, chr, attr, chr_base);
// Prepare some special monochrome emulation cases
if ( m_vmode & VM_MONO)
{
// Handle invisible characters
if ( (attr & (ATTR_FOREG | ATTR_BACKG)) == 0 )
{
data = 0x00;
}
// Handle reversed characters
else if ( (attr & (ATTR_BACKG)) == ATTR_BACKG )
{
fg = 0;
bg = 2;
}
}
else // prepare some special color emulation cases
{
// Handle invisible characters
if ( (attr & (ATTR_FOREG)) == ((attr & ATTR_BACKG) >> 4))
{
data = 0x00;
}
// Handle reversed characters
else if ( (attr & ATTR_BACKG) == ATTR_BACKG ||
(attr & ATTR_FOREG) == 0 )
{
fg = 0;
bg = 2;
}
}
// Handle intense foreground
if ((attr & ATTR_INTEN) != 0 && fg == 2)
{
fg = 3;
}
// Handle intense background if blinking is disabled
if ((m_mode_control & MR1_BLINK) == 0 &&
(attr & ATTR_BLINK) != 0 && bg == 2)
{
bg = 3;
}
// Handle cursor and blinks
if ( i == (cursor_x))
{
if ( m_framecnt & 0x08 )
{
data = 0xFF;
}
}
else
{
if ( (m_mode_control & MR1_BLINK) &&
( attr & ATTR_BLINK ) && ( m_framecnt & 0x10 ) )
{
data = 0x00;
}
}
*p = (*m_pal)[( data & 0x80 ) ? fg : bg]; p++;
*p = (*m_pal)[( data & 0x40 ) ? fg : bg]; p++;
*p = (*m_pal)[( data & 0x20 ) ? fg : bg]; p++;
*p = (*m_pal)[( data & 0x10 ) ? fg : bg]; p++;
*p = (*m_pal)[( data & 0x08 ) ? fg : bg]; p++;
*p = (*m_pal)[( data & 0x04 ) ? fg : bg]; p++;
*p = (*m_pal)[( data & 0x02 ) ? fg : bg]; p++;
*p = (*m_pal)[( data & 0x01 ) ? fg : bg]; p++;
if (chr >= 0xc0 && chr <= 0xdf)
*p = (*m_pal)[( data & 0x01 ) ? fg : bg]; // 9th pixel col is a copy of col 8
else
*p = (*m_pal)[bg]; // 9th pixel col is just background
p++;
// Insert two extra scanlines in monochrome text mode to get 400 lines and support underline, needs verification on actual hardware.
// The technical manual says that the character box is 9x16 pixels in 80x25 character mode which equals 720x400 resolution but the
// CRTC calls back for only 350 lines. Assumption is that there is hardware adding these lines and that handles underlining. In color
// emulation text mode all 400 lines are called for in 80x25 and this mode does not support underlining according to the technical manual
if ( ra == 13 && (m_vmode & VM_MONO) )
{
uint16_t row = ra + (y / 14) * 16; // Calculate correct row number including the extra 2 lines per each row of characters
for ( int j = 0; j < 9; j++)
{
if (chr >= 0xb3 && chr <= 0xdf) // Handle the meta graphics characters
{
bitmap.pix(row + 1, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg];
bitmap.pix(row + 2, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg];
}
else
{
// Handle underline
bitmap.pix(row + 1, j + i * 9) =(*m_pal)[( attr & ATTR_FOREG ) == ATTR_ULINE ? fg : bg];
bitmap.pix(row + 2, j + i * 9) = (*m_pal)[bg];
}
}
}
}
}
}
//--------------------------------------------------------------------
// Port definitions
//--------------------------------------------------------------------
static INPUT_PORTS_START( epc_mda )
PORT_START( "S1" )
PORT_DIPNAME( 0x01, 0x00, "Color emulation") PORT_DIPLOCATION("S1:1")
PORT_DIPSETTING( 0x00, "Disabled" )
PORT_DIPSETTING( 0x01, "Enabled" )
PORT_DIPUNUSED_DIPLOC(0x02, 0x02, "S1:2")
PORT_START( "MONITOR" )
PORT_CONFNAME( 0x01, 0x00, "Ericsson Monochrome HR Monitors") PORT_CHANGED_MEMBER( DEVICE_SELF, isa8_epc_mda_device, monitor_changed, 0 )
PORT_CONFSETTING( 0x00, "Amber 3111")
PORT_CONFSETTING( 0x01, "B&W 3712/3715")
INPUT_PORTS_END
INPUT_CHANGED_MEMBER( isa8_epc_mda_device::monitor_changed )
{
if ((m_io_monitor->read() & 1) == 1)
{
m_pal = &m_371x_pal;
}
else
{
m_pal = &m_3111_pal;
}
}
ioport_constructor isa8_epc_mda_device::device_input_ports() const
{
return INPUT_PORTS_NAME( epc_mda );
}
|