trunk/src/mess/machine/dec_lk201.c
r26408 | r26409 | |
2 | 2 | DEC LK-201 keyboard |
3 | 3 | Emulation by R. Belmont |
4 | 4 | |
5 | | This is currently the 6805 version; there's also an 8048 version. |
| 5 | This is the later "cost-reduced" 6805 version; there's also an 8048 version. |
6 | 6 | */ |
7 | 7 | |
| 8 | /* LK201-AA keyboard matrix (8048 version) |
| 9 | Source: VCB02 Technical Reference. |
| 10 | |
| 11 | KBD controller scan matrix (PORT 1): 8 x BCD IN => 18 DECIMAL OUT |
| 12 | |
| 13 | Keyboard itself: |
| 14 | 18 x IN (KEYBOARD DRIVE) KBD 17... KBD 0 => |
| 15 | 8 OUT (keyboard data @ D7..D0) |
| 16 | |
| 17 | to => PORT 0 @ KBD controller. |
| 18 | |
| 19 | ________|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
| 20 | ..KBD17:|[R] |F19 |[R] |F20|PF4|N--- N,| Enter |
| 21 | ........| | | | | | NOTE1) |
| 22 | ........| |G22 | |G23|E23|D23|C23| A23 |
| 23 | ........| | | | | | <- - - - - - ? ? |
| 24 | --------|----|----|----|---|---|---|---|--- |
| 25 | ..KBD16:|F18 |PF3 |[R] |N9 |V |N6 |N3 |N |
| 26 | ........|G21 |E22 | |D22|B17|C22|B22|A22 |
| 27 | --------|----|----|----|---|---|---|---|--- |
| 28 | ..KBD15:|F17 |PF2 |[R] |N8 |N5 |-> | N2|N0 |
| 29 | ........| | | | | | | |NOTE 2) |
| 30 | ........|G20 |E21 | |D21|C21|B18|B21| |
| 31 | --------|----|----|----|---|---|---|---|--- |
| 32 | KBD14:|PF1 |Next|Remove ^|N7 |N4 |N1 |N0 |
| 33 | ........| |Scrn| | || | | | |
| 34 | ........|E20 |D18 |E18 |C17|D20|C20|B20|A20 |
| 35 | --------|----|----|----|---|---|---|---|--- |
| 36 | ..KBD13:|Ins.|--- |D0 Prev| { |" |[R]|[R] |
| 37 | ........|Here|- | Scrn. [ |' | | |
| 38 | ........|E17 |E11 |G16 |D17 D11|C11| | |
| 39 | --------|----|----|----|---|---|---|---|--- |
| 40 | ..KBD12:|Find|+ |Help|Se-| } Re- |<- | |
| 41 | ........| |= | |lect ] turn| | |
| 42 | ........|E16 |E12 |G15 |D16 D12|C13| | |
| 43 | --------|----|----|----|---|---|---|---|--- |
| 44 | ..KBD11:Addtnl <X||[R] |) |P NOTE|: |? |
| 45 | .......Options Del| |0 | | 3)|; |/ |
| 46 | ........|G14 | E13|....|E10|D10|...|C10|B10 |
| 47 | --------|----|----|----|---|---|---|---|--- |
| 48 | ..KBD10:|[R] |F12 |[R] |F13| ( |O |L |. |
| 49 | ........|....|(BS)| |(LF) 9 | | | |
| 50 | ........|....|G12 |....|G13|E09|D09|C09|B09 |
| 51 | --------|----|----|----|---|---|---|---|--- |
| 52 | ..KBD_9:|[R] |F11 |[R] |[R]|* |I |K | , |
| 53 | ........|....|ESC | | |8 | | | , |
| 54 | ........|....|G11 |....|...|E08|D08|C08|B08 |
| 55 | --------|----|----|----|---|---|---|---|--- |
| 56 | ..KBD_8:|[R] |Main|[R] Exit|& |U |J |M |
| 57 | ........| |Scrn| | |7 | | | |
| 58 | ........| |G08 | |G09|E07|D07|C07|B07 |
| 59 | --------|----|----|----|---|---|---|---|--- |
| 60 | ..KBD_7:|[R] Cancel[R] Resu ^ |Y |H |N |
| 61 | ........| | | me |6 | | | |
| 62 | ........|....|G07 |G06|E06|D06|C06|B06 |
| 63 | --------|----|----|----|---|---|---|---|--- |
| 64 | ..KBD_6:|[R] |[R] |[R] Inter % |T |G |B |
| 65 | ........|....|....|....rupt| 5 | | | |
| 66 | ........|....|....|....|G05|E05|D05|C05|B05 |
| 67 | --------|----|----|----|---|---|---|---|--- |
| 68 | ..KBD_5: F4 Break [R]|$ |R |F |V |Space |
| 69 | ........|.........|....|4 | | | | |
| 70 | ........ G02 G03 |....|E04 D04 C04 B04 A01-A09 |
| 71 | --------|----|----|----|---|---|---|---|--- |
| 72 | ..KBD_4: [R] |Prt.|[R] |Set|# |E |D |C |
| 73 | ........|....|Scrn|....|-Up|3 | | | |
| 74 | ........|....|G00 |....|G01 E03 D03 C03 B03 |
| 75 | --------|----|----|----|---|---|---|---|--- |
| 76 | ..KBD_3: Hold|@ |[R] |Tab|W |S |X |> |
| 77 | ........|Scrn|2 |....| | | | |< |
| 78 | ........|G99 |E02 |....|D00|D02|C02|B02|B00 |
| 79 | --------|----|----|----|---|---|---|---|--- |
| 80 | ..KBD_2: [R] |[R] |[R] |~ |! |Q |A |Z |
| 81 | ........|..............| |1 |
| 82 | ........|..............|E00 E01 D01 C01 B01 |
| 83 | --------|----|----|----|---|---|---|---|--- |
| 84 | ..KBD_1: Ctrl|Lock|Comp|[R] |
| 85 | ........|C99 |C00 |A99 | |
| 86 | --------|----|----|----|---|---|---|---|--- |
| 87 | ..KBD_0: Shift |
| 88 | ........|B99,B11 |
| 89 | |
| 90 | --- |
| 91 | [R] = Reserved |
| 92 | NOTE 1) N0--N9, N---, N and N. refer to numeric keypad |
| 93 | NOTE 2) N0 can be divided into 2 keys. |
| 94 | Normally only the N0 keyswitch is implemented as a double-sized key. |
| 95 | NOTE 3) Return key occupies 2 positions that are |
| 96 | decoded as the Return (C13) key. |
| 97 | */ |
| 98 | |
8 | 99 | #include "emu.h" |
9 | 100 | #include "dec_lk201.h" |
10 | 101 | #include "cpu/m6805/m6805.h" |
trunk/src/mess/video/vtvideo.c
r26408 | r26409 | |
1 | | /********************************************************************** |
| 1 | /********************************************************************** |
2 | 2 | |
3 | 3 | DEC VT Terminal video emulation |
4 | 4 | [ DC012 and DC011 emulation ] |
5 | 5 | |
6 | 6 | 01/05/2009 Initial implementation [Miodrag Milanovic] |
7 | | Sept. 2013 portions by Karl-Ludwig Deisenhofer. |
| 7 | --/--/2013 portions by Karl-Ludwig Deisenhofer. |
8 | 8 | |
9 | | STATE OF DEC-100 VIDEO AS OF SEPTEMBER 2013 |
10 | | ------------------------------------------- |
11 | | - FURTHER TESTING: do line and character attributes match real hardware? Does soft scrolling work? |
12 | | - LIKELY INCORRECT : implementation of double size attribute in 132 columns mode (additional case) |
| 9 | DEC VIDEO : STATE AS OF NOVEMBER 2013 |
| 10 | ------------------------------------- |
| 11 | - NOT WORKING : scrolling requires implementation of 'scrolling region'. Multiple regions could be present. |
| 12 | Split & a full screen modes exist. Scroll should be synced with beam or DMA. |
| 13 | See 4.7.4 and up in VT manual. |
13 | 14 | |
14 | | - MISSING: undocumented features of DC011 / DC012 - see public domain SQUEEZE.COM pokes: |
15 | | 0f00 => PORT 0C; |
16 | | 0b00 => PORT 0C; |
17 | | 1000 => PORT 04 |
18 | | (SQUEEZE compresses the display in X and Y direction on a real DEC-100 B) |
| 15 | - TESTS REQUIRED : do line and character attributes (plus combinations) match real hardware? |
19 | 16 | |
| 17 | - UNDOCUMENTED FEATURES of DC011 / DC012 (CLUES WANTED) |
| 18 | A. (VT 100): DEC VT terminals are said to have a feature that doubles the number of lines |
| 19 | (50 real lines or just interlaced mode with 500 instead of 250 scanlines?) |
| 20 | |
| 21 | B. (DEC-100-B) fun PD program SQUEEZE.COM _compresses_ display to X/2 and Y/2 |
| 22 | - so picture takes a quarter of the original screen. How does it accomplish this? |
| 23 | |
20 | 24 | - IMPROVEMENTS: |
21 | | - find a more realistic approach for intensity control (bold attribute) |
22 | | - correct phosphor colors (green, white and amber monitors were common) |
| 25 | - exact colors for different VR201 monitors ('paper white', green and amber) |
23 | 26 | |
24 | 27 | Copyright MESS Team. |
25 | 28 | Visit http://mamedev.org for licensing and usage restrictions. |
r26408 | r26409 | |
140 | 143 | } |
141 | 144 | |
142 | 145 | // ****** RAINBOW ****** |
143 | | // 3 color palette, 24 and 48 line modes. |
| 146 | // 4 color (= monochrome intensities) palette, 24 and 48 line modes. |
144 | 147 | void rainbow_video_device::device_reset() |
145 | 148 | { |
| 149 | DEC_MHFU = true; // SET ON COLD BOOT |
| 150 | |
146 | 151 | palette_set_color_rgb(machine(), 0, 0x00, 0x00, 0x00); // black |
147 | | palette_set_color_rgb(machine(), 1, 213, 146, 82); // AMBER (not exact) |
148 | | palette_set_color_rgb(machine(), 2, 255, 193, 129); // AMBER (brighter) |
| 152 | // (rest of the palette is set in the main program) |
149 | 153 | |
150 | 154 | m_height = 24; // <---- DEC-100 |
151 | 155 | m_height_MAX = 48; |
r26408 | r26409 | |
193 | 197 | return m_lba7; |
194 | 198 | } |
195 | 199 | |
| 200 | |
196 | 201 | // Also used by Rainbow-100 ************ |
197 | 202 | WRITE8_MEMBER( vt100_video_device::dc012_w ) |
198 | 203 | { |
| 204 | if (data == 0) |
| 205 | { |
| 206 | if (DEC_MHFU == true) |
| 207 | DEC_MHFU = false; // MHFU is disabled by writing 00 to port 010C. |
| 208 | } else |
| 209 | { |
| 210 | if (DEC_MHFU == false) |
| 211 | DEC_MHFU = true; // TODO: MHFU ENABLE should also reset the MHFU timer. |
| 212 | } |
| 213 | |
199 | 214 | if (!(data & 0x08)) |
200 | 215 | { |
| 216 | // The scroll offset put in 'm_scroll_latch' is a decimal offset controlling 10 scan lines. |
| 217 | // The BIOS first writes the least significant bits, then the 2 most significant bits. |
| 218 | |
| 219 | // If scrolling up (incrementing the scroll latch), the additional line is linked in at the bottom. |
| 220 | // When the scroll latch is incremented back to 0, the top line of the scrolling region must be unlinked. |
| 221 | |
| 222 | // When scrolling down (decrementing the scroll latch), new lines must be linked in at the top of the scroll region |
| 223 | // and unlinked down at the bottom. |
| 224 | |
| 225 | // Note that the scroll latch value will be used during the next frame rather than the current frame. |
| 226 | // All line linking/unlinking should be done during the vertical blanking interval (< 550ms). |
| 227 | |
| 228 | // More on scrolling regions: Rainbow 100 B technical documentation (QV069-GZ) April 1985 page 22 |
| 229 | // Also see VT100 Technical Manual: 4.7.4 Address Shuffling to 4.7.9 Split Screen Smooth Scrolling. |
201 | 230 | if (!(data & 0x04)) |
202 | 231 | { |
203 | 232 | // set lower part scroll |
r26408 | r26409 | |
229 | 258 | // set reverse field off |
230 | 259 | m_reverse_field = 0; |
231 | 260 | break; |
| 261 | |
| 262 | // Writing a 11XX bit combination clears the blink-flip flop (valid for 0x0C - 0x0F): |
232 | 263 | case 0x0c: |
233 | | // set basic attribute to underline |
234 | | m_basic_attribute = 0; |
| 264 | // set basic attribute to underline / blink flip-flop off |
235 | 265 | m_blink_flip_flop = 0; |
| 266 | m_basic_attribute = 0; // (VT-100 without AVO): reverse video is interpreted as underline (basic_attribute 0) |
236 | 267 | break; |
| 268 | |
237 | 269 | case 0x0d: |
238 | | // set basic attribute to reverse video / blink flip-flop off |
239 | | m_basic_attribute = 1; |
| 270 | // (DEC Rainbow 100 DEFAULT) : reverse video with 24 lines / blink flip-flop off |
240 | 271 | m_blink_flip_flop = 0; |
| 272 | m_basic_attribute = 1; // (VT-100 without AVO): reverse video is interpreted as reverse (basic_attribute 1) |
241 | 273 | |
242 | | if (m_height_MAX == 25) break; // VT 100. |
| 274 | if (m_height_MAX == 25) break; // Abort on VT-100 for now. |
243 | 275 | |
244 | 276 | if (m_height != 24) |
245 | 277 | { |
r26408 | r26409 | |
249 | 281 | break; |
250 | 282 | |
251 | 283 | case 0x0e: |
252 | | break; // (DC12) : 'not supported' |
| 284 | m_blink_flip_flop = 0; // 'unsupported' DC012 command. Turn blink flip-flop off. |
| 285 | break; |
253 | 286 | |
254 | | case 0x0f: |
255 | | // (DEC Rainbow 100) : set basic attribute to reverse video / blink flip-flop off |
| 287 | case 0x0f: |
| 288 | // (DEC Rainbow 100): reverse video with 48 lines / blink flip-flop off |
| 289 | m_blink_flip_flop = 0; |
256 | 290 | m_basic_attribute = 1; |
257 | | m_blink_flip_flop = 0; |
258 | 291 | |
259 | | if (m_height_MAX == 25) break; // VT 100. |
| 292 | // 0x0f = 'reserved' on VT 100 |
| 293 | // Abort on VT-100 for now. |
| 294 | if (m_height_MAX == 25) break; |
260 | 295 | |
261 | 296 | if (m_height != 48) |
262 | 297 | { |
r26408 | r26409 | |
435 | 470 | } |
436 | 471 | |
437 | 472 | // ****** RAINBOW ****** |
438 | | // 5 possible character states (normal, reverse, bold, blink, underline) are encoded into display_type. |
| 473 | // 5 possible CHARACTER STATES (normal, reverse, bold, blink, underline) are encoded into display_type. |
| 474 | |
| 475 | // From the VT-180 specs, chapter 6-43 (where multiple attributes are described): |
| 476 | // 1) reverse characters [ XOR of reverse video and reverse screen (A) ] normally have dim backgrounds with black characters (B) |
| 477 | // 2) bold and reverse together give a background of normal intensity |
| 478 | |
| 479 | // 3) blink controls intensity: normal chars vary between A) normal and dim (B) bold chars vary between bright and normal |
| 480 | // 4) blink applied to a |
| 481 | // A) reverse character causes it to alternate between normal and reverse video representation |
| 482 | // B) non-rev. " : alternate between usual intensity and the next lower intensity |
| 483 | // 5) underline causes the 9.th scan to be forced to |
| 484 | // A) white of the same intensity as the characters (for nonreversed characters), |
| 485 | // b) to black (for reverse characters) |
| 486 | |
| 487 | // LINE ATTRIBUTE 'double_height' always is interpreted as 'double width + double height' |
439 | 488 | void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type) |
440 | 489 | { |
441 | | UINT8 xsize, d_xsize; |
| 490 | UINT16 y_preset; |
| 491 | UINT16 x_preset, d_x_preset; |
442 | 492 | if (m_columns == 132) |
443 | | { xsize = 9; |
444 | | d_xsize = 18; |
| 493 | { x_preset = x * 9; |
| 494 | d_x_preset = x * 18; |
445 | 495 | } else |
446 | 496 | { |
447 | | xsize = 10; |
448 | | d_xsize = 20; |
| 497 | x_preset = x * 10; |
| 498 | d_x_preset = x * 20; |
449 | 499 | } |
450 | 500 | |
451 | 501 | UINT8 line = 0; |
452 | | int bit = 0, j=0, invert, bold, blink, underline; |
| 502 | int bit = 0, j = 0; |
| 503 | int fg_intensity; |
| 504 | int back_intensity, back_default_intensity; |
453 | 505 | |
454 | | invert = display_type & 8; // BIT 3 indicates REVERSE |
455 | | bold = (display_type & 16) >> 4; // BIT 4 indicates BOLD |
456 | | blink = display_type & 32; // BIT 5 indicates BLINK |
457 | | underline = display_type & 64; // BIT 6 indicates UNDERLINE |
| 506 | int invert = (display_type & 8) >> 3; // BIT 3 indicates REVERSE |
| 507 | int bold = (display_type & 16) >> 4; // BIT 4 indicates BOLD |
| 508 | int blink = display_type & 32; // BIT 5 indicates BLINK |
| 509 | int underline = display_type & 64; // BIT 6 indicates UNDERLINE |
| 510 | bool blank = (display_type & 0x80) ? true : false; // BIT 7 indicates BLANK |
| 511 | |
458 | 512 | display_type = display_type & 3; |
459 | 513 | |
460 | | int double_width = (display_type == 1) ? 1 : 0; |
| 514 | // CASE 1 A) |
| 515 | // SCREEN ATTRIBUTES (see VT-180 manual 6-30): |
| 516 | // 'reverse field' = reverse video over entire screen (identical on Rainbow-100) |
461 | 517 | |
| 518 | // What does 'base attribute' do on Rainbow-100 ? |
| 519 | // VT-100 interpretation ('without AVO, eigth char.bit defines base attribute') most likely not correct! |
| 520 | // OR 'base attribute' = reverse or underline (depending on the selection of the cursor at SETUP) ?? |
| 521 | // VT-100 manual 4-75 / 4-98 says: reverse = (reverse field H) XOR (reverse video H = base attribute input) |
| 522 | |
| 523 | // For reference: a complete truth table can be taken from TABLE 4-6-4 / VT100 technical manual. |
| 524 | // Following simple IF statements implement it in full. Code should not be shuffled! |
| 525 | invert = invert ^ m_reverse_field ^ m_basic_attribute; |
| 526 | |
| 527 | fg_intensity = bold + 2; // FOREGROUND (FG): normal (2) or bright (3) |
| 528 | |
| 529 | back_intensity = 0; // DO NOT SHUFFLE CODE AROUND !! |
| 530 | if ( (blink != 0) && ( m_blink_flip_flop != 0 ) ) |
| 531 | fg_intensity -= 1; // normal => dim bright => normal (when bold) |
| 532 | |
| 533 | // INVERSION: background gets foreground intensity (reduced by 1). |
| 534 | // _RELIES ON_ on_ previous evaluation of the BLINK signal (fg_intensity). |
| 535 | if (invert != 0) |
| 536 | { |
| 537 | back_intensity = fg_intensity - 1; // BG: normal => dim; dim => OFF; bright => normal |
| 538 | |
| 539 | if (back_intensity != 0) // FG: avoid 'black on black' |
| 540 | fg_intensity = 0; |
| 541 | else |
| 542 | fg_intensity = fg_intensity + 1; // FG: dim => normal; normal => bright |
| 543 | } |
| 544 | |
| 545 | // BG: DEFAULT for entire character (underline overrides this for 1 line) - |
| 546 | back_default_intensity = back_intensity; |
| 547 | |
| 548 | bool double_width = (display_type != 3) ? true : false; // all except normal: double width |
| 549 | bool double_height = (display_type & 1) ? false : true; // 0,2 = double height |
| 550 | |
462 | 551 | for (int i = 0; i < 10; i++) |
463 | 552 | { |
| 553 | y_preset = y * 10 + i; |
| 554 | |
464 | 555 | switch (display_type) |
465 | 556 | { |
466 | | case 0 : // bottom half, double height |
467 | | j = (i >> 1) + 5; break; |
468 | | case 2 : // top half, double height |
469 | | j = (i >> 1); break; |
| 557 | case 0 : // bottom half of 'double height, double width' char. |
| 558 | j = (i >> 1) + 5; |
| 559 | break; |
470 | 560 | |
471 | | default : j = i; break; // 1: double width / 3: normal |
| 561 | case 2 : // top half of 'double height, double width' char. |
| 562 | j = (i >> 1); |
| 563 | break; |
| 564 | |
| 565 | default : // 1: double width |
| 566 | // 3: normal |
| 567 | j = i; |
| 568 | break; |
472 | 569 | } |
| 570 | |
473 | 571 | // modify line since that is how it is stored in rom |
474 | 572 | if (j == 0) j = 15; else j = j - 1; |
475 | 573 | |
476 | 574 | line = m_gfx[code * 16 + j]; |
477 | 575 | |
478 | | if ( i == 8 ) |
| 576 | // UNDERLINED CHARACTERS (CASE 5 - different in 1 line): |
| 577 | back_intensity = back_default_intensity; // 0, 1, 2 |
| 578 | if ( underline != 0 ) |
479 | 579 | { |
480 | | if ( underline != 0 ) line = 0xff; |
481 | | } |
| 580 | if ( i == 8 ) |
| 581 | { |
| 582 | if (invert == 0) |
| 583 | line = 0xff; // CASE 5 A) |
| 584 | else |
| 585 | { line = 0x00; // CASE 5 B) |
| 586 | back_intensity = 0; // OVERRIDE: BLACK BACKGROUND |
| 587 | } |
| 588 | } |
| 589 | } |
482 | 590 | |
483 | | // Code to handle basic attribute from VT-100 |
484 | | if ( m_basic_attribute == 1 ) |
| 591 | for (int b = 0; b < 8; b++) // 0..7 |
485 | 592 | { |
486 | | if ((code & 0x80) == 0x80) |
487 | | invert = 1; |
| 593 | if (blank) |
| 594 | { bit = m_reverse_field ^ m_basic_attribute; |
| 595 | } |
488 | 596 | else |
489 | | invert = 0; |
490 | | } |
| 597 | { |
| 598 | bit = BIT((line << b), 7); |
491 | 599 | |
492 | | if (m_blink_flip_flop > 0) |
493 | | { |
494 | | if ( blink != 0 ) |
495 | | { |
496 | | line = line ^ 0xff; |
| 600 | if (bit > 0) |
| 601 | bit = fg_intensity; |
| 602 | else |
| 603 | bit = back_intensity; |
497 | 604 | } |
498 | | } |
499 | | if (invert != 0) |
500 | | line = line ^ 0xff; |
501 | 605 | |
502 | | for (int b = 0; b < 8; b++) |
503 | | { |
504 | | bit = BIT((line << b), 7) << bold; |
| 606 | // Double, 'double_height + double_width', then normal. |
505 | 607 | if (double_width) |
506 | 608 | { |
507 | | bitmap.pix16(y * 10 + i, x * d_xsize + b * 2) = bit; |
508 | | bitmap.pix16(y * 10 + i, x * d_xsize + b * 2 + 1) = bit; |
| 609 | bitmap.pix16( y_preset, d_x_preset + b * 2 + 1) = bit; |
| 610 | bitmap.pix16( y_preset, d_x_preset + b * 2) = bit; |
| 611 | |
| 612 | if (double_height) |
| 613 | { |
| 614 | bitmap.pix16( 1 + y_preset, d_x_preset + b * 2 + 1) = bit; |
| 615 | bitmap.pix16( 1 + y_preset, d_x_preset + b * 2) = bit; |
| 616 | } |
509 | 617 | } |
510 | 618 | else |
511 | 619 | { |
512 | | bitmap.pix16(y * 10 + i, x * xsize + b) = bit; |
| 620 | bitmap.pix16(y_preset, x_preset + b) = bit; |
513 | 621 | } |
514 | | } |
| 622 | } // for (8 bit) |
515 | 623 | |
| 624 | |
| 625 | // char interleave (X) is filled with last bit |
| 626 | if (double_width) |
| 627 | { |
| 628 | // double chars: 18 or 20 bits |
| 629 | bitmap.pix16(y_preset, d_x_preset + 16) = bit; |
| 630 | bitmap.pix16(y_preset, d_x_preset + 17) = bit; |
516 | 631 | |
517 | | // char interleave is filled with last bit |
518 | | if (double_width) |
519 | | { |
520 | | bitmap.pix16(y * 10 + i, x * d_xsize + 16) = bit; |
521 | | bitmap.pix16(y * 10 + i, x * d_xsize + 17) = bit; |
522 | | bitmap.pix16(y * 10 + i, x * d_xsize + 18) = bit; |
523 | | bitmap.pix16(y * 10 + i, x * d_xsize + 19) = bit; |
| 632 | if (m_columns == 80) |
| 633 | { bitmap.pix16(y_preset, d_x_preset + 18) = bit; |
| 634 | bitmap.pix16(y_preset, d_x_preset + 19) = bit; |
| 635 | } |
524 | 636 | } |
525 | 637 | else |
526 | | { |
527 | | bitmap.pix16(y * 10 + i, x * xsize + 8) = bit; |
528 | | if (m_columns == 80) |
529 | | bitmap.pix16(y * 10 + i, x * xsize + 9) = bit; |
| 638 | { // normal chars: 9 or 10 bits |
| 639 | bitmap.pix16(y_preset, x_preset + 8) = bit; |
| 640 | |
| 641 | if (m_columns == 80) |
| 642 | bitmap.pix16(y_preset, x_preset + 9) = bit; |
530 | 643 | } |
531 | 644 | |
| 645 | } // for |
532 | 646 | |
533 | | } |
534 | 647 | } |
535 | 648 | |
536 | 649 | // ****** RAINBOW ****** |
r26408 | r26409 | |
543 | 656 | int ypos = 0; |
544 | 657 | UINT8 code; |
545 | 658 | int x = 0; |
546 | | UINT8 scroll_region = 1; // binary 1 |
| 659 | UINT8 scroll_region = 1; // DEFAULT TO 1 = PART OF scroll_region |
547 | 660 | UINT8 display_type = 3; // binary 11 |
548 | 661 | UINT16 temp = 0; |
549 | 662 | |
550 | 663 | while (line < (m_height + m_skip_lines)) |
551 | 664 | { |
552 | 665 | code = m_in_ram_func(addr + xpos); |
553 | | if (code == 0xff) |
| 666 | |
| 667 | if ( code == 0x00 ) // TODO: investigate side effect on regular zero character! |
| 668 | display_type |= 0x80; // DEFAULT: filler chars (till end of line) and empty lines (00) will be blanked |
| 669 | else |
| 670 | display_type &= 0x7f; // else activate display. |
| 671 | |
| 672 | if ( code == 0xff ) |
554 | 673 | { |
555 | 674 | // end of line, fill empty till end of line |
556 | 675 | if (line >= m_skip_lines) |
557 | 676 | { |
558 | | // NOTE: display_type is already SHIFTED by 1 ( 1 = DOUBLE WIDTH 40 / 66 ) |
559 | | for (x = xpos; x < ((display_type == 1) ? (m_columns / 2) : m_columns); x++) |
| 677 | // NOTE: display_type is already shifted! All except 3 is DOUBLE WIDTH 40 or 66 chars per line |
| 678 | for (x = xpos; x < ( (display_type != 3) ? (m_columns / 2) : m_columns ); x++) |
560 | 679 | { |
561 | | display_char(bitmap, code, x, ypos, scroll_region, display_type); |
| 680 | display_char(bitmap, code, x, ypos, scroll_region, display_type | 0x80); |
562 | 681 | } |
| 682 | |
563 | 683 | } |
564 | | // move to new data |
| 684 | |
| 685 | // LINE ATTRIBUTE - valid for all chars on next line ** DO NOT SHUFFLE ** |
| 686 | attr_addr = ( 0x1000 | (addr + xpos + 1) & 0x0fff ); |
| 687 | |
| 688 | // MOVE TO NEW DATA |
565 | 689 | temp = m_in_ram_func(addr + xpos + 2) * 256 + m_in_ram_func(addr + xpos + 1); |
566 | | |
567 | 690 | addr = (temp) & 0x0fff; |
568 | | attr_addr = ((temp) & 0x1fff) - 2; |
569 | 691 | |
570 | | // No AVO here. |
571 | | attr_addr |= 0x1000; |
572 | | if (attr_addr > 0x2000) // Ignore attributes beyond 8192 byte limit (SRAM). |
573 | | { |
574 | | scroll_region = 1; // binary 1 <- SET DEFAULTS |
575 | | display_type = 3; // binary 111 |
576 | | } else |
577 | | { |
578 | | temp = m_in_ram_func(attr_addr); |
579 | | scroll_region = (temp) & 1; |
580 | | display_type = (temp >> 1) & 3; |
581 | | } |
| 692 | temp = m_in_ram_func(attr_addr); |
| 693 | scroll_region = (temp) & 1; |
| 694 | display_type = (temp >> 1) & 3; |
582 | 695 | |
583 | 696 | if (line >= m_skip_lines) |
584 | 697 | { |
r26408 | r26409 | |
588 | 701 | line++; |
589 | 702 | } |
590 | 703 | else |
591 | | { |
| 704 | { |
592 | 705 | // display regular char |
593 | 706 | if (line >= m_skip_lines) |
594 | 707 | { |
595 | 708 | attr_addr = 0x1000 | ( (addr + xpos) & 0x0fff ); |
596 | 709 | temp = m_in_ram_func(attr_addr); // get character attribute |
597 | 710 | |
598 | | // TODO: check if reverse bit is treated the same way on real hardware |
| 711 | // CONFIRMED: Reverse active on 1. No attributes = 0x0E |
599 | 712 | // 1 = display char. in REVERSE (encoded as 8) |
600 | 713 | // 0 = display char. in BOLD (encoded as 16) |
601 | 714 | // 0 = display char. w. BLINK (encoded as 32) |
602 | 715 | // 0 = display char. w. UNDERLINE (encoded as 64). |
603 | | display_char(bitmap, code, xpos, ypos, scroll_region, display_type | ( ( (temp & 1)) << 3 ) |
604 | | | ( (2-(temp & 2)) << 3 ) |
605 | | | ( (4-(temp & 4)) << 3 ) |
606 | | | ( (8-(temp & 8)) << 3 ) |
| 716 | display_char(bitmap, code, xpos, ypos, scroll_region, display_type | ( ( (temp & 1)) << 3 ) |
| 717 | | ( (2-(temp & 2)) << 3 ) |
| 718 | | ( (4-(temp & 4)) << 3 ) |
| 719 | | ( (8-(temp & 8)) << 3 ) |
607 | 720 | ); |
608 | | } |
| 721 | |
| 722 | } |
609 | 723 | xpos++; |
610 | | if (xpos > m_columns) |
| 724 | |
| 725 | if (xpos > m_columns ) |
611 | 726 | { |
| 727 | xpos = 0; |
612 | 728 | line++; |
613 | | xpos = 0; |
614 | 729 | } |
615 | | } |
| 730 | } // (else) valid char |
| 731 | |
| 732 | } // while |
| 733 | |
| 734 | |
| 735 | } |
| 736 | |
| 737 | |
| 738 | void rainbow_video_device::palette_select ( int choice ) |
| 739 | { |
| 740 | switch(choice) |
| 741 | { |
| 742 | default: |
| 743 | case 0x01: |
| 744 | palette_set_color_rgb(machine(), 1, 0xff-100, 0xff-100, 0xff-100); // WHITE (dim) |
| 745 | palette_set_color_rgb(machine(), 2, 0xff-50, 0xff-50, 0xff-50); // WHITE NORMAL |
| 746 | palette_set_color_rgb(machine(), 3, 0xff, 0xff, 0xff); // WHITE (brighter) |
| 747 | break; |
| 748 | |
| 749 | case 0x02: |
| 750 | palette_set_color_rgb(machine(), 1, 0 , 200 -50, 0); // GREEN (dim) |
| 751 | palette_set_color_rgb(machine(), 2, 0 , 200, 0); // GREEN (NORMAL) |
| 752 | palette_set_color_rgb(machine(), 3, 0, 200 +50, 0); // GREEN (brighter) |
| 753 | break; |
| 754 | |
| 755 | case 0x03: |
| 756 | palette_set_color_rgb(machine(), 1, 213 - 47, 146 - 47, 82 - 47); // AMBER (dim) |
| 757 | palette_set_color_rgb(machine(), 2, 213, 146, 82); // AMBER (normal - not exact) |
| 758 | palette_set_color_rgb(machine(), 3, 255, 193, 129); // AMBER (brighter) |
| 759 | break; |
616 | 760 | } |
| 761 | } |
617 | 762 | |
| 763 | // ****** RAINBOW ****** |
| 764 | void rainbow_video_device::video_blanking(bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 765 | { |
| 766 | // 'In reverse screen mode, termination forces the beam to the screen background intensity' |
| 767 | // Background intensity means 'dim' (1) according to one source. Most certainly not pitch black. |
| 768 | bitmap.fill( ((m_reverse_field ^ m_basic_attribute) ? 1 : 0) , cliprect); |
618 | 769 | } |
619 | 770 | |
| 771 | int rainbow_video_device::dc012_MHFU() |
| 772 | { |
| 773 | return DEC_MHFU; |
| 774 | } |
| 775 | |
620 | 776 | TIMER_CALLBACK_MEMBER( vt100_video_device::lba7_change ) |
621 | 777 | { |
622 | 778 | m_lba7 = (m_lba7) ? 0 : 1; |
trunk/src/mess/drivers/rainbow.c
r26408 | r26409 | |
6 | 6 | |
7 | 7 | STATE AS OF NOVEMBER 2013 |
8 | 8 | -------------------------- |
9 | | - FATAL: keyboard emulation needs love (inhibits the system from booting with ERROR 50 on cold or ERROR 13 on warm boot). |
10 | | - NOT WORKING: serial (ERROR 60) |
11 | | - NOT WORKING: printer interface (ERROR 40). |
| 9 | - FATAL: keyboard emulation incomplete (inhibits the system from booting with ERROR 50 on cold or ERROR 13 on warm boot). |
| 10 | - NOT WORKING: serial (ERROR 60). |
| 11 | - NOT WORKING: printer interface (ERROR 40). Like error 60 not mission-critical. |
12 | 12 | |
13 | | - NON-CRITICAL: no code for W18 (DSR) jumper. W90 jumper probably not relevant for emulation (VBIAS pin 2 => to unknown register). |
14 | | - NON-CRITICAL: watchdog logic not implemented. MHFLU - ERROR 16 indicated hardware problems or (most often) software crashes on real hardware. |
| 13 | - NON-CRITICAL: watchdog logic (triggered after 108 ms without interrupts) still not exactly by the book. |
15 | 14 | |
| 15 | Timer is reset by TWO sources: the VERT INT L from the DC012, or the MHFU ENB L from the enable flip-flop. |
| 16 | The MHFU gets active if the 8088 has not acknowledged a video processor interrupt within approx. 108 milliseconds. |
| 17 | |
| 18 | BIOS assumes a power-up reset if MHFU detection is disabled - and assumes a MHFU reset if MHFU detection is ENABLED. |
| 19 | Therefore a 'warm boot' within MESS (F3) causes ERROR 16. |
| 20 | |
16 | 21 | - SHOULD BE IMPLEMENTED AS SLOT DEVICES (for now, DIP settings affect 'system_parameter_r' only and are disabled): |
17 | 22 | * Color graphics option (uses NEC upd7220 GDC) |
18 | 23 | * Extended communication option (same as BUNDLE_OPTION ?) |
19 | 24 | |
20 | 25 | - OTHER UPGRADES (NEC_V20 should be easy, the TURBOW is harder to come by) |
21 | | * Suitable Solutions TURBOW286 (12 Mhz, 68-pin, low power AMD N80L286-12 and WAYLAND/EDSUN EL286-88-10-B ( 80286 to 8088 Processor Signal Converter ) |
22 | | / replacement for main cpu with on-board DC 7174 or DT 7174 (?) RTC and changed BOOT ROM labeled 'TBSS1.3 - 3ED4'). |
| 26 | * Suitable Solutions TURBOW286: 12 Mhz, 68-pin, low power AMD N80L286-12 and WAYLAND/EDSUN EL286-88-10-B ( 80286 to 8088 Processor Signal Converter ) |
| 27 | plus DC 7174 or DT 7174 (barely readable). Add-on card, replaces main 8088 cpu (via ribbon cable). Changed BOOT ROM labeled 'TBSS1.3 - 3ED4'. |
23 | 28 | |
24 | 29 | * NEC_V20 (requires modded BOOT ROM because of - at least 2 - hard coded timing loops): |
25 | 30 | 100A: 100B/100+: 100B+ ALTERNATE RECOMMENDATION (fixes RAM size auto-detection problems when V20 is in place. |
26 | | Tested on a 30+ year old live machine. Your mileage may vary) |
| 31 | Tested on a 30+ year old live machine. Your mileage may vary) |
| 32 | |
27 | 33 | Location Data Location Data Loc.|Data |
28 | | 00C6 46 [ increases 'wait for Z80' from approx. 27,5 ms (old value 40) to 30,5 ms ] |
29 | | 0303 00 [ disable CHECKSUM ] |
| 34 | .... .. .... .. ------------------ 00C6 46 [ increases 'wait for Z80' from approx. 27,5 ms (old value 40) to 30,5 ms ] |
| 35 | .... .. .... .. ------------------ 0303 00 [ disable CHECKSUM ] |
30 | 36 | 043F 64 072F 64 <-----------------> 072F 73 [ increases minimum cycle time from 2600 (64) to 3000 ms (73) ] |
31 | | 067D 20 0B36 20 <-----------------> 0B36 20 [ use a value of 20 for NEC_V20 - as in the initial patch. Changes cause VFR - ERROR 10. ] |
| 37 | 067D 20 0B36 20 <-----------------> 0B36 20 [ USE A VALUE OF 20 FOR THE NEC - as in the initial patch! CHANGES CAUSE VFR-ERROR 10 ] |
32 | 38 | 1FFE 2B 3FFE 1B (BIOS CHECKSUM) |
33 | 39 | 1FFF 70 3FFF 88 (BIOS CHECKSUM) |
34 | 40 | |
| 41 | => the 'leaked' DOS 3.10 Beta -for Rainbow- 'should not be used' on rigs with NEC V20. It possibly wasn't tested, but boots and runs well. |
| 42 | => on the NEC, auto detection (of option RAM) fails with the original V20 patch (above, left) |
| 43 | Expect RAM related system crashes after swapping CPUs and altering physical RAM _afterwards_. |
| 44 | Hard coded CPU loops are to blame. Try values from the alternate patch (right). |
| 45 | => AAD/AAM - Intel 8088 honors the second byte (operand), NEC V20 ignores it and always uses base 0Ah (10). |
| 46 | => UNDOCUMENTED: NEC V20 does not have "POP CS" (opcode 0F). There are more differences (opcode D6; the 2 byte POP: 8F Cx; FF Fx instructions) |
| 47 | Commercial programs had to be patched back then (as was the case with Loderunner for PC). |
| 48 | => NEW OPCODES: REPC, REPNC, CHKIND, PREPARE, DISPOSE; BCD string operations (ADD4S, CMP4S, SUB4S), bit-ops (NOT, SET, TEST, ROL4, ROR4) |
| 49 | WARNING: undoc'd opcodes, INS, EXT and 8080 behaviour are unemulated yet! MESS' CPU source has up-to-date info. |
| 50 | |
35 | 51 | Meaning of Diagnostics LEDs (from PC100ESV1.PDF found, e.g., |
36 | 52 | on ftp://ftp.update.uu.se/pub/rainbow/doc/rainbow-docs/ |
37 | 53 | |
r26408 | r26409 | |
95 | 111 | 7-6-5-4 |3-2-1 |
96 | 112 | DIAGNOSTIC-LEDs |J3 | |J2 | |J1 | |
97 | 113 | |------|----8088|Z80-|--|VIDEO|-|PRINTER|-|SERIAL|---| |
98 | | | 2 x 64 K |/KBD.| | |
99 | | | R A M NEC D7201C |P|[W90]| |
100 | | | |O| | |
| 114 | | 2 x 64 K |/KBD.| !!!!!| |
| 115 | | R A M NEC D7201C |P|!W90!| |
| 116 | | |O|!!!!!| |
101 | 117 | | [W6] ROM 1 INTEL 8088 |W| | |
102 | 118 | | (23-020e5-00) |E| | |
103 | 119 | | |R| | |
r26408 | r26409 | |
119 | 135 | W5 + W6 are out when 16K x 8 EPROMS are used |
120 | 136 | / W5 + W6 installed => 32 K x 8 EPROMs (pin 27 = A14) |
121 | 137 | |
122 | | W13, W14, W15, W18, W90 = for manufacturing tests. |
| 138 | W13, W14, W15, W18 = for manufacturing tests. |
123 | 139 | => W13 - W15 affect diagnostic read register (port $0a) |
124 | 140 | => W18 pulls DSR to ground and affects 8251A - port $11 (bit 7) |
125 | | NOTE: THERE IS NO CODE TO PULL DSR YET. |
126 | | => W90 connects pin 2 (Voltage Bias on PWR connector J8) with the communications control register |
127 | | (SH1 - IOWR4 L line according to page 21 of the DEC-100-B field manual) |
128 | 141 | |
129 | | SEEN ON SCHEMATICS - NOT PRESENT ON THIS PCB: |
130 | | W16 pulls J2 printer port pin 1 to GND when set (otherwise pin unconnected) |
131 | | W17 pulls J1 serial port pin 1 to GND when set (otherwise pin unconnected) |
| 142 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| 143 | !! DO NOT SHORT JUMPER / CONNECTOR [W90] ON LIVE HARDWARE !! |
| 144 | !! !! |
| 145 | !! WARNING: CIRCUIT DAMAGE could occur if this jumper is !! |
| 146 | !! set by end users. See PDF document AA-V523A-TV. !! |
| 147 | !! !! |
| 148 | !! W90 connects to pin 2 (Voltage Bias on PWR connector J8)!! |
| 149 | !! and is designed FOR ===> FACTORY TESTS OF THE PSU <=== !! |
| 150 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| 151 | |
| 152 | WIRE CONNECTORS - SEEN ON SCHEMATICS - NOT PRESENT ON DEC-100 B (-A only?): |
| 153 | W16 pulls J2 printer port pin 1 to GND when set (chassis to logical GND). |
| 154 | W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND). |
132 | 155 | ****************************************************************************/ |
133 | 156 | |
| 157 | /* |
| 158 | HARD DISC SIZES AND LIMITS |
| 159 | HARDWARE: the Rainbow winchester controller has a built-in limit of 8 heads and 1024 cylinders (67 MB). Standard geometry is 4 surfaces. |
| 160 | |
| 161 | SOFTWARE: the original DEC boot loader (and FDISK from DOS 3.10) initially allowed a maximum hard disc size of 20 MB. |
| 162 | - DOS 3 has a 1024 cylinder limit (32 MB). |
| 163 | - the custom boot loader that comes with 'WUTIL 3.2' stretches limits to 117 MB and 8 surfaces. |
| 164 | */ |
| 165 | |
| 166 | |
134 | 167 | #include "emu.h" |
135 | 168 | #include "cpu/i86/i86.h" |
136 | 169 | #include "cpu/z80/z80.h" |
r26408 | r26409 | |
144 | 177 | |
145 | 178 | #include "rainbow.lh" // BEZEL - LAYOUT with LEDs for diag 1-7, keyboard 8-11 and floppy 20-21 |
146 | 179 | |
147 | | #define DEC_B_NVMEM_SIZE (256) |
148 | | |
149 | 180 | class rainbow_state : public driver_device |
150 | 181 | { |
151 | 182 | public: |
r26408 | r26409 | |
159 | 190 | m_inp6(*this, "FLOPPY CONTROLLER"), |
160 | 191 | m_inp7(*this, "GRAPHICS OPTION"), |
161 | 192 | m_inp8(*this, "MEMORY PRESENT"), |
| 193 | m_inp9(*this, "MONITOR TYPE"), |
162 | 194 | |
163 | 195 | m_beep(*this, "beeper"), |
164 | 196 | m_crtc(*this, "vt100_video"), |
r26408 | r26409 | |
183 | 215 | required_ioport m_inp6; |
184 | 216 | required_ioport m_inp7; |
185 | 217 | required_ioport m_inp8; |
| 218 | required_ioport m_inp9; |
186 | 219 | |
187 | 220 | required_device<beep_device> m_beep; |
188 | 221 | |
r26408 | r26409 | |
231 | 264 | DECLARE_WRITE8_MEMBER(z80_diskcontrol_write_w); |
232 | 265 | DECLARE_READ8_MEMBER(system_parameter_r); |
233 | 266 | |
| 267 | DECLARE_READ_LINE_MEMBER(dsr_r); |
| 268 | |
234 | 269 | DECLARE_READ_LINE_MEMBER(kbd_rx); |
235 | 270 | DECLARE_WRITE_LINE_MEMBER(kbd_tx); |
236 | 271 | DECLARE_WRITE_LINE_MEMBER(kbd_rxready_w); |
237 | 272 | DECLARE_WRITE_LINE_MEMBER(kbd_txready_w); |
238 | 273 | |
239 | 274 | bool m_SCREEN_BLANK; |
240 | | bool m_COLDBOOT; |
241 | 275 | |
242 | 276 | bool m_zflip; // Z80 alternate memory map with A15 inverted |
243 | 277 | bool m_z80_halted; |
r26408 | r26409 | |
246 | 280 | int m_KBD; |
247 | 281 | int m_beep_counter; |
248 | 282 | |
| 283 | int MHFU_counter; |
| 284 | |
249 | 285 | private: |
250 | 286 | UINT8 m_z80_private[0x800]; // Z80 private 2K |
251 | 287 | UINT8 m_z80_mailbox, m_8088_mailbox; |
252 | 288 | |
253 | 289 | void update_kbd_irq(); |
254 | 290 | virtual void machine_reset(); |
| 291 | void MHFU_reset(); |
255 | 292 | public: |
256 | 293 | UINT32 screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
257 | 294 | INTERRUPT_GEN_MEMBER(vblank_irq); |
r26408 | r26409 | |
262 | 299 | void rainbow_state::machine_start() |
263 | 300 | { |
264 | 301 | m_SCREEN_BLANK = false; |
265 | | m_COLDBOOT = true; |
266 | 302 | |
267 | 303 | save_item(NAME(m_z80_private)); |
268 | 304 | save_item(NAME(m_z80_mailbox)); |
r26408 | r26409 | |
315 | 351 | // - PC-100 A might have had a smaller (NV-)RAM (*) |
316 | 352 | // - ED000 - ED0FF is the area the _DEC-100-B BIOS_ accesses - and checks. |
317 | 353 | |
318 | | // - Specs claim that the CPU has direct access to volatile RAM only. |
| 354 | // - Specs say that the CPU has direct access to volatile RAM only. |
319 | 355 | // So NVRAM is hidden now and loads & saves are triggered within the |
320 | | // 'diagnostic_w' handler (like on real hardware). |
| 356 | // 'diagnostic_w' handler (similar to real hardware). |
321 | 357 | |
322 | | // - Address bits 8-12 are ignored (-> AM_MIRROR). Remove for debugging. |
| 358 | // - Address bits 8-12 are ignored (-> AM_MIRROR). |
323 | 359 | AM_RANGE(0xed000, 0xed0ff) AM_RAM AM_SHARE("vol_ram") AM_MIRROR(0x1f00) |
324 | 360 | AM_RANGE(0xed100, 0xed1ff) AM_RAM AM_SHARE("nvram") |
325 | 361 | |
r26408 | r26409 | |
341 | 377 | AM_RANGE (0x08, 0x08) AM_READ(system_parameter_r) |
342 | 378 | |
343 | 379 | AM_RANGE (0x0a, 0x0a) AM_READWRITE(diagnostic_r, diagnostic_w) |
344 | | // 0x0C Video processor DC012 |
345 | | AM_RANGE (0x0c, 0x0c) AM_DEVWRITE("vt100_video", rainbow_video_device, dc012_w) |
346 | 380 | |
| 381 | // 0x0C Video processor DC012 |
| 382 | AM_RANGE (0x0c, 0x0c) AM_DEVWRITE("vt100_video", rainbow_video_device, dc012_w) |
| 383 | |
347 | 384 | AM_RANGE(0x10, 0x10) AM_DEVREADWRITE("kbdser", i8251_device, data_r, data_w) |
348 | 385 | AM_RANGE(0x11, 0x11) AM_DEVREADWRITE("kbdser", i8251_device, status_r, control_w) |
349 | 386 | |
r26408 | r26409 | |
371 | 408 | |
372 | 409 | /* Input ports */ |
373 | 410 | static INPUT_PORTS_START( rainbow ) |
| 411 | PORT_START("MONITOR TYPE") |
| 412 | PORT_DIPNAME( 0x03, 0x03, "MONOCHROME MONITOR") |
| 413 | PORT_DIPSETTING( 0x01, "PAPER WHITE" ) |
| 414 | PORT_DIPSETTING( 0x02, "GREEN" ) |
| 415 | PORT_DIPSETTING( 0x03, "AMBER" ) |
| 416 | |
374 | 417 | PORT_START("FLOPPY CONTROLLER") |
375 | 418 | PORT_DIPNAME( 0x02, 0x02, "FLOPPY CONTROLLER") PORT_TOGGLE |
376 | 419 | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
377 | 420 | PORT_DIPSETTING( 0x02, DEF_STR( On ) ) |
378 | 421 | |
379 | | PORT_START("MEMORY PRESENT") |
| 422 | PORT_START("GRAPHICS OPTION") |
| 423 | PORT_DIPNAME( 0x00, 0x00, "GRAPHICS OPTION") PORT_TOGGLE |
| 424 | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 425 | PORT_DIPSETTING( 0x04, DEF_STR( On ) ) |
| 426 | |
| 427 | PORT_START("BUNDLE OPTION") |
| 428 | PORT_DIPNAME( 0x00, 0x00, "BUNDLE OPTION") PORT_TOGGLE |
| 429 | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 430 | PORT_DIPSETTING( 0x01, DEF_STR( On ) ) |
| 431 | |
| 432 | PORT_START("MEMORY PRESENT") |
380 | 433 | PORT_DIPNAME( 0xF000, 0x2000, "MEMORY PRESENT") |
381 | 434 | PORT_DIPSETTING( 0x2000, "128 K (BOARD DEFAULT)" ) // NOTE: 0x2000 hard coded in 'system_parameter_r' |
382 | 435 | PORT_DIPSETTING( 0x3000, "192 K (MEMORY OPTION)" ) |
r26408 | r26409 | |
392 | 445 | PORT_DIPSETTING( 0xD000, "832 K (MEMORY OPTION)" ) |
393 | 446 | PORT_DIPSETTING( 0xE000, "896 K (MEMORY OPTION)" ) |
394 | 447 | |
395 | | PORT_START("GRAPHICS OPTION") |
396 | | PORT_DIPNAME( 0x00, 0x00, "GRAPHICS OPTION") PORT_TOGGLE |
397 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
398 | | PORT_DIPSETTING( 0x04, DEF_STR( On ) ) |
399 | | PORT_START("BUNDLE OPTION") |
400 | | PORT_DIPNAME( 0x00, 0x00, "BUNDLE OPTION") PORT_TOGGLE |
401 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
402 | | PORT_DIPSETTING( 0x01, DEF_STR( On ) ) |
403 | | |
404 | 448 | PORT_START("W13") |
405 | | PORT_DIPNAME( 0x02, 0x02, "W13") PORT_TOGGLE |
| 449 | PORT_DIPNAME( 0x02, 0x02, "W13 (FACTORY TEST A, LEAVE OFF)") PORT_TOGGLE |
406 | 450 | PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) |
407 | 451 | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
408 | 452 | PORT_START("W14") |
409 | | PORT_DIPNAME( 0x04, 0x04, "W14") PORT_TOGGLE |
| 453 | PORT_DIPNAME( 0x04, 0x04, "W14 (FACTORY TEST B, LEAVE OFF)") PORT_TOGGLE |
410 | 454 | PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) |
411 | 455 | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
412 | 456 | PORT_START("W15") |
413 | | PORT_DIPNAME( 0x08, 0x08, "W15") PORT_TOGGLE |
| 457 | PORT_DIPNAME( 0x08, 0x08, "W15 (FACTORY TEST C, LEAVE OFF)") PORT_TOGGLE |
414 | 458 | PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) |
415 | 459 | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 460 | // DSR = 1 when switch is OFF - see i8251.c (status_r) |
416 | 461 | PORT_START("W18") |
417 | | PORT_DIPNAME( 0x00, 0x04, "W18") PORT_TOGGLE |
418 | | PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) |
419 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 462 | PORT_DIPNAME( 0x01, 0x00, "W18 (FACTORY TEST D, LEAVE OFF) (8251A: DSR)") PORT_TOGGLE |
| 463 | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 464 | PORT_DIPSETTING( 0x01, DEF_STR( On ) ) |
420 | 465 | INPUT_PORTS_END |
421 | 466 | |
422 | 467 | |
| 468 | void rainbow_state::MHFU_reset() |
| 469 | { |
| 470 | MHFU_counter = 530; // 528 = 110ms |
| 471 | } |
| 472 | |
423 | 473 | void rainbow_state::machine_reset() |
424 | 474 | { |
| 475 | MHFU_reset(); |
| 476 | |
425 | 477 | m_z80->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
426 | 478 | |
427 | 479 | m_zflip = true; |
r26408 | r26409 | |
454 | 506 | |
455 | 507 | UINT32 rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
456 | 508 | { |
457 | | if (m_SCREEN_BLANK) |
458 | | bitmap.fill(get_black_pen(machine()), cliprect); |
459 | | else |
460 | | m_crtc->video_update(bitmap, cliprect); |
| 509 | m_crtc->palette_select( m_inp9->read() ); |
| 510 | |
| 511 | if ( m_SCREEN_BLANK ) |
| 512 | m_crtc->video_blanking(bitmap, cliprect); |
| 513 | else |
| 514 | m_crtc->video_update(bitmap, cliprect); |
461 | 515 | return 0; |
462 | 516 | } |
463 | 517 | |
464 | | // Simulate floating bus for initial RAM detection in low ROM. |
465 | | // WANTED: is a cleaner, more compatible way feasible? |
| 518 | // It is no longer possible to key in the RAM size on the 100-B. |
| 519 | // The DEC-100-B boot ROM probes until a 'flaky' area is found (around F400:xxxx). |
| 520 | |
| 521 | // Unexpected low RAM sizes are an indication of option RAM (at worst: 128 K on board) failure. |
| 522 | // While motherboard errors often render the system unbootable, bad option RAM (> 128 K) |
| 523 | // can be narrowed down with a diagnostic disk and codes from the 'Pocket Service Guide' |
| 524 | // EK-PC100-PS-002 (APPENDIX B.2.2); pc100ps2.pdf |
| 525 | |
| 526 | // Simulate floating bus for initial RAM detection: |
466 | 527 | READ8_MEMBER(rainbow_state::floating_bus_r) |
467 | 528 | { |
468 | 529 | if ( m_maincpu->state_int(I8086_CS) != 0xF400) |
r26408 | r26409 | |
555 | 616 | } |
556 | 617 | |
557 | 618 | READ8_MEMBER(rainbow_state::comm_control_r) |
558 | | { |
559 | | // Our simple COLDBOOT flag is adequate for the initial MHFU test (at BIOS location 00A8). |
560 | | |
561 | | // TODO: on real hardware, MHFU detection is disabled BY WRITING TO 0x10c (=> BIOS assumes power-up reset) |
562 | | // MHFU is enabled by writing to 0x0c. |
563 | | if (m_COLDBOOT) |
564 | | { m_COLDBOOT = 0; |
565 | | return ( 0x20 ); // bit 5 = watchdog detect. |
566 | | } else { |
567 | | return ( 0x00 ); // ERROR 16 is displayed = watchdog triggered |
568 | | } |
| 619 | { |
| 620 | /* |
| 621 | --> What the specs says on how MHFU detection is disabled: |
| 622 | // 1. by first disabling interrupts with CLI |
| 623 | // 2. by writing 0x00 to port 0x10C (handled by 'dc012_w' in vtvideo) |
| 624 | // (3.) MHFU is re-enabled by writing to 0x0c (or automatically after STI - when under BIOS control ?) |
| 625 | */ |
| 626 | return ( ( m_crtc->dc012_MHFU() << 5) // shift status of DC012 - MHFU flag to bit pos.5 |
| 627 | ); |
569 | 628 | } |
570 | 629 | |
571 | 630 | WRITE8_MEMBER(rainbow_state::comm_control_w) |
r26408 | r26409 | |
713 | 772 | INTERRUPT_GEN_MEMBER(rainbow_state::vblank_irq) |
714 | 773 | { |
715 | 774 | device.execute().set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, 0x20); |
| 775 | |
| 776 | MHFU_reset(); |
716 | 777 | } |
717 | 778 | |
718 | 779 | WRITE8_MEMBER( rainbow_state::clear_video_interrupt ) |
r26408 | r26409 | |
766 | 827 | } |
767 | 828 | |
768 | 829 | |
| 830 | READ_LINE_MEMBER(rainbow_state::dsr_r) |
| 831 | { |
| 832 | return m_inp4->read(); // W18 (1/0) |
| 833 | } |
| 834 | |
769 | 835 | // KEYBOARD |
770 | 836 | void rainbow_state::update_kbd_irq() |
771 | 837 | { |
r26408 | r26409 | |
810 | 876 | m_kbd8251->transmit_clock(); |
811 | 877 | m_kbd8251->receive_clock(); |
812 | 878 | |
| 879 | if ( m_crtc->dc012_MHFU() ) // MHFU ENABLED? |
| 880 | { |
| 881 | if (MHFU_counter) |
| 882 | MHFU_counter--; |
| 883 | |
| 884 | if (MHFU_counter == 1) // resets ONCE. |
| 885 | { |
| 886 | printf("*** CPU RESET: MASSIVE HARDWARE FAILURE DETECTED (MHFU LOGIC ~108 ms)\n"); |
| 887 | m_i8088->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 888 | } |
| 889 | } |
| 890 | |
813 | 891 | if (m_beep_counter > 1) |
814 | 892 | m_beep_counter--; |
815 | 893 | else |
r26408 | r26409 | |
870 | 948 | { |
871 | 949 | DEVCB_DRIVER_LINE_MEMBER(rainbow_state, kbd_rx), // rxd in |
872 | 950 | DEVCB_DRIVER_LINE_MEMBER(rainbow_state, kbd_tx), // txd out |
873 | | DEVCB_NULL, // dsr |
| 951 | DEVCB_DRIVER_LINE_MEMBER(rainbow_state, dsr_r), // dsr |
874 | 952 | DEVCB_NULL, // dtr |
875 | 953 | DEVCB_NULL, // rts |
876 | 954 | DEVCB_DRIVER_LINE_MEMBER(rainbow_state, kbd_rxready_w), |
r26408 | r26409 | |
897 | 975 | MCFG_SCREEN_REFRESH_RATE(60) |
898 | 976 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
899 | 977 | MCFG_SCREEN_SIZE(132*10, 49*10) |
900 | | MCFG_SCREEN_VISIBLE_AREA(0, 80*10-1, 0, 25*10-1) |
| 978 | MCFG_SCREEN_VISIBLE_AREA(0, 80 * 10-1, 0, 24 * 10-1) |
901 | 979 | MCFG_SCREEN_UPDATE_DRIVER(rainbow_state, screen_update_rainbow) |
902 | 980 | MCFG_GFXDECODE(rainbow) |
903 | | MCFG_PALETTE_LENGTH(3) |
904 | | MCFG_PALETTE_INIT_OVERRIDE(driver_device, monochrome_amber) |
| 981 | MCFG_PALETTE_LENGTH(4) |
| 982 | |
905 | 983 | MCFG_RAINBOW_VIDEO_ADD("vt100_video", video_interface) |
906 | 984 | |
907 | 985 | /* sound hardware */ |