Previous 199869 Revisions Next

r31343 Sunday 20th July, 2014 at 20:39:03 UTC by Tafoid
(MESS) VTVIDEO: Added new interlaced mode.  Also handle cases where undocumented delays / skip lines are poked (SQUINT; VIDEO.PAS).  [Bavarese]
[src/mess/video]vtvideo.c vtvideo.h

trunk/src/mess/video/vtvideo.c
r31342r31343
11/**********************************************************************
2DEC VT Terminal video emulation
3[ DC012 and DC011 emulation ]
24
3    DEC VT Terminal video emulation
4    [ DC012 and DC011 emulation ]
5Copyright MESS Team.
6Visit http://mamedev.org for licensing and usage restrictions.
57
6    01/05/2009 Initial implementation [Miodrag Milanovic]
7    Portions (2013, 2014) by Karl-Ludwig Deisenhofer.
801/05/2009 Initial implementation [Miodrag Milanovic]
9Portions (2013, 2014) by Karl-Ludwig Deisenhofer.
810
9    DEC VIDEO : STATE AS OF MARCH 2014
10    ----------------------------------
11    - TESTS REQUIRED : do line and character attributes (plus combinations) match real hardware?
11DEC VIDEO : STATE AS OF JULY 2014
12---------------------------------
13Code developed with Rainbow-100 hardware in mind (a PC-like machine with a video circuit similar to a VT100 equipped w. AVO)
14Details (termination characters, option hardware, MHFU watchdog) differ when compared to VT.
1215
16As of July 2014, the Rainbow video section is more mature than the 'VT100_VIDEO' part (essentially unchanged since 2009).
17List of features not yet ported to VT: line doubler; 48 line mode; soft scroll; intensity / palette, AVO (ext.attributes)
18
19FIXME: work out the differences and identify common code between VT and Rainbow. Unify different code trees.
20
21- REQUIRED TODOS / TESTS :
22  * do line and character attributes (plus combinations) match real hardware?
23  * how does the AVO fit in?
24 
1325- SCROLLING REGIONS / SPLIT SCREEN SCROLLING UNTESTED (if you open > 1 file with the VAX editor EDT)
1426  See VT100 Technical Manual: 4.7.4 Address Shuffling to 4.7.9 Split Screen Smooth Scrolling.
1527  More on scrolling regions: Rainbow 100 B technical documentation (QV069-GZ) April 1985 page 22
28 
29- NEW - INTERLACED MODE (Rainbow only):
30  Vertical resolution increases from 240 to 480, while the refresh rate halves (flickers on CRTs).
31  To accomplish this, the display controller repeats even lines in odd scans.
32  VTVIDEO activates line doubling in 24 line, interlaced mode only.
33 
34  Although the DC12 has the ability to display 48 lines, most units are low on screen RAM and
35  won't even show 80 x 48. -> REASON: (83 x 48 = 3984 Byte) > (screen RAM) minus 'scratch area'
36  On a VT-180, BIOS scratch requires up to 700 bytes used for SETUP, flags, SILO, keyboard.
37 
38- POSSIBLE IMPROVEMENTS:
39 
40* exact colors for different VR201 monitors ('paper white', green and amber)
1641
17- INTERLACED MODE UNEMULATED:
18  There is no RAM (on a Rainbow-100) to hold twice as many vertical lines, so the video chip
19  doubles existing ones.           Flickers on CRTs and is of dubious value on modern hosts.
42* ACCURATE VIDEO DELAYS:
43  Position of the first visible scanline (relative to the vertical reset) depends on
44  content of fill bytes at the beginning of screen RAM.
2045
21- FUN WITH DC011 / DC012 REGISTERS (clues wanted):
22  Public domain program SQUEEZE.COM (for DEC-100-B) _compresses_ display to X/2 and Y/2
23  so picture takes a quarter of the original screen. How does it accomplish this?
46  Six invisible, linked lines are initially provided (at location $EE000+ on a Rainbow).
47  Real-world DC hardware parses the (circular) chain until interrupted by blanking.
48  BIOS assumes 2 lines are omitted @ 60 and 5 lines are at 50 Hertz (-> longer blank).
2449
25    - IMPROVEMENTS:
26  exact colors for different VR201 monitors ('paper white', green and amber)
50  VTVIDEO keeps it simple and skips up to 6 lines considered 'illegal' (offset < $12).
51  Works even in cases where undocumented delays or lines are poked (SQUINT; VIDEO.PAS).
2752
28    Copyright MESS Team.
29    Visit http://mamedev.org for licensing and usage restrictions.
30
53  Accurate timings for 4 modes (from VT-180 manual 6-30 on):
54  Vertical frequency = (2 * HF = 31.468 Khz) / DIVIDER
55  - 50 NI: (2 * HF = 31.468 Khz) / 630
56  - 50 interlaced: (2 * HF = 31.468 Khz) / 629
57  - 60 NI: (2 * HF = 31.468 Khz) / 524
58  - 60 interlaced: (2 * HF = 31.468 Khz) / 525
3159**********************************************************************/
3260
3361#include "emu.h"
3462#include "video/vtvideo.h"
3563
3664/***************************************************************************
37    PARAMETERS
65PARAMETERS
3866***************************************************************************/
3967
4068#define VERBOSE         0
r31342r31343
4775
4876
4977vt100_video_device::vt100_video_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
50               : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
51                  device_video_interface(mconfig, *this),
52                  m_read_ram(*this),
53                  m_write_clear_video_interrupt(*this),
54                  m_char_rom_tag(""),
55                  m_palette(*this, "palette")
78: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
79device_video_interface(mconfig, *this),
80m_read_ram(*this),
81m_write_clear_video_interrupt(*this),
82m_char_rom_tag(""),
83m_palette(*this, "palette")
5684{
5785}
5886
5987
6088vt100_video_device::vt100_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
61               : device_t(mconfig, VT100_VIDEO, "VT100 Video", tag, owner, clock, "vt100_video", __FILE__),
62                  device_video_interface(mconfig, *this),
63                  m_read_ram(*this),
64                  m_write_clear_video_interrupt(*this),
65                  m_char_rom_tag(""),
66                  m_palette(*this, "palette")
89: device_t(mconfig, VT100_VIDEO, "VT100 Video", tag, owner, clock, "vt100_video", __FILE__),
90device_video_interface(mconfig, *this),
91m_read_ram(*this),
92m_write_clear_video_interrupt(*this),
93m_char_rom_tag(""),
94m_palette(*this, "palette")
6795{
6896}
6997
7098
7199rainbow_video_device::rainbow_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
72               : vt100_video_device(mconfig, RAINBOW_VIDEO, "Rainbow Video", tag, owner, clock, "rainbow_video", __FILE__)
100: vt100_video_device(mconfig, RAINBOW_VIDEO, "Rainbow Video", tag, owner, clock, "rainbow_video", __FILE__)
73101{
74102}
75103
r31342r31343
88116   assert(m_gfx != NULL);
89117
90118   // LBA7 is scan line frequency update
91   machine().scheduler().timer_pulse(attotime::from_nsec(31778), timer_expired_delegate(FUNC(vt100_video_device::lba7_change),this));
119   machine().scheduler().timer_pulse(attotime::from_nsec(31778), timer_expired_delegate(FUNC(vt100_video_device::lba7_change), this));
92120
93121   save_item(NAME(m_lba7));
94122   save_item(NAME(m_scroll_latch));
r31342r31343
98126   save_item(NAME(m_columns));
99127   save_item(NAME(m_height));
100128   save_item(NAME(m_height_MAX));
101   save_item(NAME(m_skip_lines));
129   save_item(NAME(m_fill_lines));
102130   save_item(NAME(m_frequency));
103131   save_item(NAME(m_interlaced));
104132}
r31342r31343
127155
128156   m_columns = 80;
129157   m_frequency = 60;
158
130159   m_interlaced = 1;
131   m_skip_lines = 2; // for 60Hz
160   m_fill_lines = 2; // for 60Hz
161   recompute_parameters();
132162}
133163
134164// ****** RAINBOW ******
r31342r31343
155185   m_basic_attribute = 0;
156186
157187   m_columns = 80;
158   m_frequency = 60;
159   m_interlaced = 1;
160   m_skip_lines = 2; // for 60Hz
188   
189   m_frequency = 60;
190
191   m_interlaced = 1;
192   m_fill_lines = 2; // for 60Hz (not in use any longer -> detected)
193   recompute_parameters();
161194}
162195
163196/***************************************************************************
164    IMPLEMENTATION
197IMPLEMENTATION
165198***************************************************************************/
166199
167200// Also used by Rainbow-100 ************
168201void vt100_video_device::recompute_parameters()
169202{
203   rectangle visarea;
170204   int horiz_pix_total = 0;
171   int vert_pix_total = 0;
172   rectangle visarea;
173205
174   vert_pix_total  = m_height  * 10;
206   // RAINBOW: 240 scan lines in non-interlaced mode (480 interlaced). VT-100 : same (?)
207   m_linedoubler = false; // 24 "true" lines (240)  -OR-  48 lines with NO ghost lines (true 480)
208   if ((m_interlaced) && (m_height == 24))
209      m_linedoubler = true; // 24 lines with 'double scan' (false 480)
175210
176   if (m_columns == 132) {
177      horiz_pix_total = m_columns * 9; // display 1 less filler pixel in 132 char. mode (DEC-100)
178   }
179   else {
211   int vert_pix_total = ((m_linedoubler == false) ? m_height : m_height_MAX) * 10;
212
213   if (m_columns == 132)
214      horiz_pix_total = m_columns * 9; // display 1 less filler pixel in 132 char. mode
215   else
180216      horiz_pix_total = m_columns * 10; // normal 80 character mode.
181   }
182217
183218   visarea.set(0, horiz_pix_total - 1, 0, vert_pix_total - 1);
219   machine().first_screen()->configure(horiz_pix_total, vert_pix_total, visarea, HZ_TO_ATTOSECONDS((m_interlaced == 0) ? m_frequency : (m_frequency/2) ));
184220
185   m_screen->configure(horiz_pix_total, vert_pix_total, visarea, m_screen->frame_period().attoseconds);
221   if (VERBOSE)
222   {
223      printf("\n(RECOMPUTE) HPIX: %d - VPIX: %d", horiz_pix_total, vert_pix_total);
224      printf("\n(RECOMPUTE) FREQUENCY: %d", (m_interlaced == 0) ? m_frequency : (m_frequency / 2));
225      if (m_interlaced)
226         printf("\n(RECOMPUTE) * INTERLACED *");
227      if (m_linedoubler)
228         printf("\n(RECOMPUTE) * LINEDOUBLER *");
229   }
186230}
187231
188232
189READ8_MEMBER( vt100_video_device::lba7_r )
233READ8_MEMBER(vt100_video_device::lba7_r)
190234{
191235   return m_lba7;
192236}
193237
194238
195239// Also used by Rainbow-100 ************
196WRITE8_MEMBER( vt100_video_device::dc012_w )
240WRITE8_MEMBER(vt100_video_device::dc012_w)
197241{
242
198243   // TODO: writes to 10C/0C should be treated differently (emulation disables the watchdog too often).
199244   // - see 3.1.3.9.5 DC012 Programming Information (PC-100 spec)
200245   if (data == 0) // MHFU is disabled by writing 00 to port 010C.
201246   {
202            //if (MHFU_FLAG == true)
203            //  printf("MHFU  *** DISABLED *** \n");
204247            MHFU_FLAG = false;
205248            MHFU_counter = 0;
249
250      if (VERBOSE)
251      {
252         if (MHFU_FLAG == true)
253            printf("MHFU  *** DISABLED *** %ul \n", offset);
206254   }
255   }
207256   else
208   {           // RESET
209            //if (MHFU_FLAG == false)
210            //  printf("MHFU  ___ENABLED___ \n");
257   {   
258      // RESET
211259            MHFU_FLAG = true;
260      MHFU_counter = 0;
212261
213            MHFU_counter = 0;
262      if (VERBOSE)
263      {
264         if (MHFU_FLAG == false)
265            printf("MHFU  ___ENABLED___ %ul \n", offset);
214266   }
267   }
215268
216269   if (!(data & 0x08))
217270   {
r31342r31343
239292         case 0x09:
240293            // clear vertical frequency interrupt;
241294            m_write_clear_video_interrupt(0);
242
243295            break;
244296         case 0x0a:
245297            // set reverse field on
r31342r31343
264316
265317            if (m_height_MAX == 25) break; //  Abort on VT-100 for now.
266318
267            if (m_height != 24)
268            {
269319               m_height = 24;  // (DEC Rainbow 100) : 24 line display
270320               recompute_parameters();
271            }
272321            break;
273322
274323         case 0x0e:
275            m_blink_flip_flop = 0;  // 'unsupported' DC012 command. Turn blink flip-flop off.
324         m_blink_flip_flop = 0;  // 'unsupported' DC012 command. Turns blink flip-flop off (11XX).
276325            break;
277326
278327         case 0x0f:
r31342r31343
284333            //  Abort on VT-100 for now.
285334            if (m_height_MAX == 25) break;
286335
287            if (m_height != 48)
288            {
289336               m_height = 48;   // (DEC Rainbow 100) : 48 line display
290337               recompute_parameters();
291            }
292338            break;
293339      }
294340   }
295341}
296342
297
298WRITE8_MEMBER( vt100_video_device::dc011_w )
343// Writing to DC011 resets internal counters (& disturbs display) on real hardware.
344WRITE8_MEMBER(vt100_video_device::dc011_w)
299345{
300   if (!BIT(data, 5))
346   if (!BIT(data, 5))
301347   {
302      UINT8 col = m_columns;
348      m_interlaced = 1; 
349
303350      if (!BIT(data, 4))
304      {
305351         m_columns = 80;
306      }
307352      else
308      {
309353         m_columns = 132;
310354      }
311      if (col != m_columns)
312      {
313         recompute_parameters();
314      }
315      m_interlaced = 1;
316   }
317355   else
318356   {
357      m_interlaced = 0;
358
319359      if (!BIT(data, 4))
320360      {
321361         m_frequency = 60;
322         m_skip_lines = 2;
362         m_fill_lines = 2; 
323363      }
324364      else
325365      {
326366         m_frequency = 50;
327         m_skip_lines = 5;
367         m_fill_lines = 5;
328368      }
329      m_interlaced = 0;
330369   }
370
371   recompute_parameters();
331372}
332373
333WRITE8_MEMBER( vt100_video_device::brightness_w )
374WRITE8_MEMBER(vt100_video_device::brightness_w)
334375{
335376   //m_palette->set_pen_color(1, data, data, data);
336377}
r31342r31343
347388   {
348389      switch (display_type)
349390      {
350         case 0 : // bottom half, double height
391      case 0: // bottom half, double height
351392                  j = (i >> 1) + 5; break;
352         case 1 : // top half, double height
393      case 1: // top half, double height
353394                  j = (i >> 1); break;
354         case 2 : // double width
355         case 3 : // normal
395      case 2: // double width
396      case 3: // normal
356397                  j = i;  break;
357         default : j = 0; break;
398      default: j = 0; break;
358399      }
359400      // modify line since that is how it is stored in rom
360401      if (j == 0) j = 15; else j = j - 1;
r31342r31343
415456   if (m_read_ram(0) != 0x7f)
416457      return;
417458
418   while (line < (m_height + m_skip_lines))
459   while (line < (m_height + m_fill_lines))
419460   {
420461      code = m_read_ram(addr + xpos);
421462      if (code == 0x7f)
422463      {
423464         // end of line, fill empty till end of line
424         if (line >= m_skip_lines)
465         if (line >= m_fill_lines)
425466         {
426467            for (x = xpos; x < ((display_type == 2) ? (m_columns / 2) : m_columns); x++)
427468            {
r31342r31343
430471         }
431472         // move to new data
432473         temp = m_read_ram(addr + xpos + 1) * 256 + m_read_ram(addr + xpos + 2);
433         addr = (temp) & 0x1fff;
474         addr = (temp)& 0x1fff;
434475         // if A12 is 1 then it is 0x2000 block, if 0 then 0x4000 (AVO)
435476         if (addr & 0x1000) addr &= 0xfff; else addr |= 0x2000;
436477         scroll_region = (temp >> 15) & 1;
437478         display_type  = (temp >> 13) & 3;
438         if (line >= m_skip_lines)
479         if (line >= m_fill_lines)
439480         {
440481            ypos++;
441482         }
r31342r31343
445486      else
446487      {
447488         // display regular char
448         if (line >= m_skip_lines)
489         if (line >= m_fill_lines)
449490         {
450491            display_char(bitmap, code, xpos, ypos, scroll_region, display_type);
451492         }
r31342r31343
461502}
462503
463504// ****** RAINBOW ******
505// Display 10 scan lines (or 20 in interlaced mode) for one character @ position X/Y
506// NOTE: X or Y indicate a character position!
507
464508// 5 possible CHARACTER STATES (normal, reverse, bold, blink, underline) are encoded into display_type.
465
466509// From the VT-180 specs, chapter 6-43 (where multiple attributes are described):
467510//  1) reverse characters [ XOR of reverse video and reverse screen (A) ] normally have dim backgrounds with black characters (B)
468511//  2) bold and reverse together give a background of normal intensity
r31342r31343
474517//  5) underline causes the 9.th scan to be forced to
475518//       A) white of the same intensity as the characters (for nonreversed characters),
476519//       b) to black (for reverse characters)
520// LINE ATTRIBUTE 'double_height' always is interpreted as 'double width + double height'
477521
478// LINE ATTRIBUTE 'double_height' always is interpreted as 'double width + double height'
522// ATTRIBUTES:   No attributes = 0x0E
523// 1 = display char. in REVERSE   (encoded as 8 in display_type)  HIGH ACTIVE
524// 0 = display char. in BOLD      (encoded as 16 in display_type) LOW ACTIVE
525// 0 = display char. w. BLINK     (encoded as 32 in display_type) LOW ACTIVE
526// 0 = display char. w. UNDERLINE (encoded as 64 in display_type) LOW ACTIVE
479527void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type)
480528{
529   UINT16 x_preset = x << 3; // x_preset = x * 9 (= 132 column mode)
530   x_preset += x;
531
532   if (m_columns == 80)
533      x_preset += x; //        x_preset = x * 10 (80 column mode)
534
481535   UINT16 y_preset;
482   UINT16 x_preset, d_x_preset;
483   if (m_columns == 132)
484   {
485      x_preset = x * 9;
486         d_x_preset = x * 18;
487   }
488   else
489   {
490         x_preset   = x * 10;
491         d_x_preset = x * 20;
492   }
493536
537   UINT16 CHARPOS_y_preset = y << 3; // CHARPOS_y_preset = y * 10;
538   CHARPOS_y_preset += y;
539   CHARPOS_y_preset += y;
540
541   UINT16 DOUBLE_x_preset = x_preset << 1; // 18 for 132 column mode, else 20 (x_preset * 2)
542
494543   UINT8 line = 0;
495544   int bit = 0, j = 0;
496545   int fg_intensity;
497546   int back_intensity, back_default_intensity;
498547
499   int invert = (display_type &  8) >> 3; // BIT 3 indicates REVERSE
500   int bold = (display_type & 16) >> 4;   // BIT 4 indicates BOLD
501   int blink  = display_type &  32;       // BIT 5 indicates BLINK
502   int underline = display_type & 64;     // BIT 6 indicates UNDERLINE
503   bool blank = (display_type & 0x80) ? true : false; // BIT 7 indicates BLANK
548   int invert = (display_type & 8) ? 1 : 0; // REVERSE
549   int bold  = (display_type & 16) ? 0 : 1; // BIT 4
550   int blink = (display_type & 32) ? 0 : 1; // BIT 5
551   int underline = (display_type & 64) ? 0 : 1; // BIT 6
552   bool blank = (display_type & 128) ? true : false; // BIT 7
504553
505554   display_type = display_type & 3;
506555
r31342r31343
508557   // 'reverse field' = reverse video over entire screen
509558
510559   // For reference: a complete truth table can be taken from TABLE 4-6-4 / VT100 technical manual.
511   // Following simple IF statements implement it in full. Code segments should not be shuffled.
560   // Following IF statements implement it in full. Code segments should not be shuffled.
512561   invert = invert ^ m_reverse_field ^ m_basic_attribute;
513562
514563   fg_intensity = bold + 2;   // FOREGROUND (FG):  normal (2) or bright (3)
515564
516565   back_intensity = 0; // DO NOT SHUFFLE CODE AROUND !!
517   if ( (blink != 0) && ( m_blink_flip_flop != 0 ) )
566   if ((blink != 0) && (m_blink_flip_flop != 0))
518567      fg_intensity -= 1; // normal => dim    bright => normal (when bold)
519568
520569   // INVERSION: background gets foreground intensity (reduced by 1).
r31342r31343
539588   if (scroll_region != 0)
540589      smooth_offset = m_last_scroll; // valid after VBI
541590
591   int i = 0;
542592   int extra_scan_line = 0;
543   for (int scan_line = 0; scan_line < 10; scan_line++)
593   for (int scan_line = 0; scan_line < (m_linedoubler ? 20 : 10); scan_line++)
544594   {
545      y_preset = y * 10 + scan_line;
595      y_preset = CHARPOS_y_preset + scan_line;
546596
547      int i = scan_line + smooth_offset; // offset to bitmap in char-rom (+ scroll)
548      if (i > 9) // SMOOTH SCROLL - fill previous scan line:
597      // 'i' points to char-rom (plus scroll offset; if active) -
598      // IF INTERLACED: odd lines = even lines
599      i = (m_linedoubler ? (scan_line >> 1) : scan_line) + smooth_offset;
600
601      if (i > 9) // handle everything in one loop (in case of smooth scroll):
549602      {
550603         extra_scan_line += 1;
551         i = smooth_offset - extra_scan_line; // correct bitmap
552604
553         y_preset -= scan_line;
554         if (y > 0)
555            y_preset -= extra_scan_line;  // Y * 10  - extra_scan_line
605         // Fetch appropriate character bitmap (one scan line) -
606         // IF INTERLACED: no odd lines
607         i = smooth_offset - (m_linedoubler ? (extra_scan_line >> 1) : extra_scan_line);
608
609         if (CHARPOS_y_preset >= extra_scan_line) // If result not negative...
610            y_preset = CHARPOS_y_preset - extra_scan_line; // correct Y pos.
611         else
612         {
613            y_preset = (m_linedoubler ? 480 : 240) - extra_scan_line;
614            i = 0; // (should be always empty)
556615         }
616      }
557617
558618      switch (display_type)
559619      {
560         case 0 :  // bottom half of 'double height, double width' char.
620      case 0:  // bottom half of 'double height, double width' char.
561621                  j = (i >> 1) + 5;
562622                  break;
563623
564         case 2 :  // top half of 'double height, double width' char.
624      case 2:  // top half of 'double height, double width' char.
565625                  j = (i >> 1);
566626                  break;
567627
568         default : // 1: double width
628      default: // 1: double width
569629                  // 3: normal
570630                  j = i;
571631                  break;
r31342r31343
574634      // modify line since that is how it is stored in rom
575635      if (j == 0) j = 15; else j = j - 1;
576636
577      line = m_gfx[ (code << 4) + j]; // code * 16
637      line = m_gfx[(code << 4) + j]; // code * 16
578638
579639      // UNDERLINED CHARACTERS (CASE 5 - different in 1 line):
580640      back_intensity = back_default_intensity; // 0, 1, 2
581      if ( underline != 0 )
641      if (underline != 0)
582642      {
583         if ( i == 8 )
643         if (i == 8)
584644         {
585645               if (invert == 0)
586646                  line = 0xff; // CASE 5 A)
r31342r31343
611671         // Double, 'double_height + double_width', then normal.
612672         if (double_width)
613673         {
614            bitmap.pix16( y_preset, d_x_preset + (b << 1) + 1) = bit;
615            bitmap.pix16( y_preset, d_x_preset + (b << 1)    ) = bit;
674            bitmap.pix16(y_preset, DOUBLE_x_preset + (b << 1) + 1) = bit;
675            bitmap.pix16(y_preset, DOUBLE_x_preset + (b << 1)) = bit;
616676
617677            if (double_height)
618678            {
619                  bitmap.pix16( 1 + y_preset, d_x_preset + (b << 1) + 1) = bit;
620                  bitmap.pix16( 1 + y_preset, d_x_preset + (b << 1)    ) = bit;
679               bitmap.pix16(1 + y_preset, DOUBLE_x_preset + (b << 1) + 1) = bit;
680               bitmap.pix16(1 + y_preset, DOUBLE_x_preset + (b << 1)) = bit;
621681            }
622682         }
623683         else
r31342r31343
630690      if (double_width)
631691      {
632692         // double chars: 18 or 20 bits
633         bitmap.pix16(y_preset, d_x_preset + 16) = bit;
634         bitmap.pix16(y_preset, d_x_preset + 17) = bit;
693         bitmap.pix16(y_preset, DOUBLE_x_preset + 16) = bit;
694         bitmap.pix16(y_preset, DOUBLE_x_preset + 17) = bit;
635695
636696         if (m_columns == 80)
637697         {
638            bitmap.pix16(y_preset, d_x_preset + 18) = bit;
639            bitmap.pix16(y_preset, d_x_preset + 19) = bit;
698            bitmap.pix16(y_preset, DOUBLE_x_preset + 18) = bit;
699            bitmap.pix16(y_preset, DOUBLE_x_preset + 19) = bit;
640700         }
641701      }
642702      else
r31342r31343
660720   int ypos = 0;
661721   UINT8 code;
662722   int x = 0;
663   UINT8 scroll_region = 1;  // DEFAULT TO 1 = PART OF scroll_region
664   UINT8 display_type = 3;  // binary 11
723   UINT8 scroll_region = 0;  // DEFAULT TO 0 = NOT PART OF scroll_region
724   UINT8 display_type = 3;  // NORMAL DISPLAY - binary 11
665725   UINT16 temp = 0;
666726
667   while (line < (m_height + m_skip_lines))
727   if (m_read_ram(0) != 0xff) // video uninitialized?
728      return;
729
730   // Skip fill (0xFF) lines and put result in ADDR.
731   for (int xp = 1; xp <= 6; xp += 1) // beware of circular references
668732   {
733      // Fetch LINE ATTRIBUTE before it is gone
734      attr_addr = 0x1000 | ((addr + 1) & 0x0fff);
735
736      temp = m_read_ram(addr + 2) * 256 + m_read_ram(addr + 1);
737      addr = (temp)& 0x0fff;
738
739      temp = m_read_ram(attr_addr);
740      scroll_region = (temp)& 1;
741      display_type = (temp >> 1) & 3;
742
743      if (addr >= 0x12)
744         break;
745   }
746
747   int vert_charlines_MAX = ((m_linedoubler == false) ? m_height : m_height_MAX);
748   while (line < vert_charlines_MAX )
749   {
669750      code = m_read_ram(addr + xpos);
670751
671      if ( code == 0x00 )        // TODO: investigate side effect on regular zero character!
752      if (code == 0x00)        // TODO: investigate side effect on regular zero character!
672753            display_type |= 0x80; // DEFAULT: filler chars (till end of line) and empty lines (00) will be blanked
673754      else
674755            display_type &= 0x7f; // else activate display.
675756
676      if ( code == 0xff )
757      if (code == 0xff) // end of line, fill empty till end of line
677758      {
678         // end of line, fill empty till end of line
679         if (line >= m_skip_lines)
759         // HINT: display_type is already shifted! All except 3 is DOUBLE WIDTH 40 or 66 chars per line
760         for (x = xpos; x < ((display_type != 3) ? (m_columns / 2) : m_columns); x++)
680761         {
681            // NOTE: display_type is already shifted! All except 3 is DOUBLE WIDTH 40 or 66 chars per line
682            for (x = xpos; x < ( (display_type != 3) ? (m_columns / 2) : m_columns );  x++)
683            {
684762               display_char(bitmap, code, x, ypos, scroll_region, display_type | 0x80);
685763            }
686764
687         }
688
689765         //  LINE ATTRIBUTE - valid for all chars on next line  ** DO NOT SHUFFLE **
690         attr_addr = 0x1000 | ( (addr + xpos + 1) & 0x0fff );
766         attr_addr = 0x1000 | ((addr + xpos + 1) & 0x0fff);
691767
692768         // MOVE TO NEW DATA
693769         temp = m_read_ram(addr + xpos + 2) * 256 + m_read_ram(addr + xpos + 1);
694         addr = (temp) & 0x0fff;
770         addr = (temp)& 0x0fff;
695771
696772         temp = m_read_ram(attr_addr);
697         scroll_region = (temp) & 1;
773         scroll_region = (temp)& 1;
698774         display_type  = (temp >> 1) & 3;
699775
700         if (line >= m_skip_lines)
701         {
702            ypos++;
703         }
776         ypos++;            // Y + 1 in non-interlaced mode
777         if (m_linedoubler)
778            ypos++;        // Y + 2 in 'double scan' mode (see -> 'display_char')
779
780         if (ypos > vert_charlines_MAX) // prevent invalid Y pos.
781            break;
782
704783         xpos = 0;
705784         line++;
706785      }
707786      else
708787      {
709         // display regular char
710         if (line >= m_skip_lines)
711         {
712            attr_addr = 0x1000 | ( (addr + xpos) & 0x0fff );
713            temp = m_read_ram(attr_addr); // get character attribute
788         attr_addr = 0x1000 | ((addr + xpos) & 0x0fff);
789         temp = (m_read_ram(attr_addr) & 15) << 3; // get character attributes
714790
715            // CONFIRMED: Reverse active on 1.  No attributes = 0x0E
716            // 1 = display char. in REVERSE   (encoded as 8)
717            // 0 = display char. in BOLD      (encoded as 16)
718            // 0 = display char. w. BLINK     (encoded as 32)
719            // 0 = display char. w. UNDERLINE (encoded as 64).
720            display_char(bitmap, code, xpos, ypos, scroll_region, display_type | (   (    (temp & 1)) << 3 )
721                                                                  | ( (2-(temp & 2)) << 3 )
722                                                                  | ( (4-(temp & 4)) << 3 )
723                                                                  | ( (8-(temp & 8)) << 3 )
724                                                               );
791         // see 'display_char' for an explanation of attribute encoding -
792         display_char(bitmap, code, xpos, ypos, scroll_region, display_type | temp);
725793
726         }
727794         xpos++;
728
729         if (xpos > m_columns )
795         if (xpos > m_columns)
730796         {
731797            xpos = 0;
732798            line++;
r31342r31343
735801
736802   } // while
737803
738
739804}
740805
741806void rainbow_video_device::notify_vblank(bool v)
r31342r31343
753818   v_last = v;
754819}
755820
756void rainbow_video_device::palette_select ( int choice )
821void rainbow_video_device::palette_select(int choice)
757822{
758   switch(choice)
823   switch (choice)
759824   {
760825         default:
761826         case 0x01:
762                  m_palette->set_pen_color(1, 0xff-100, 0xff-100, 0xff-100);  // WHITE (dim)
763                  m_palette->set_pen_color(2, 0xff-50, 0xff-50, 0xff-50);     // WHITE NORMAL
827      m_palette->set_pen_color(1, 0xff - 100, 0xff - 100, 0xff - 100);  // WHITE (dim)
828      m_palette->set_pen_color(2, 0xff - 50, 0xff - 50, 0xff - 50);     // WHITE NORMAL
764829                  m_palette->set_pen_color(3, 0xff, 0xff, 0xff);              // WHITE (brighter)
765830                  break;
766831
r31342r31343
772837
773838         case 0x03:
774839                  m_palette->set_pen_color(1, 213 - 47, 146 - 47, 82 - 47); // AMBER (dim)
775                  m_palette->set_pen_color(2, 213,      146,      82     ); // AMBER (NORMAL)
776                  m_palette->set_pen_color(3, 255,      193,      129    ); // AMBER (brighter)
840      m_palette->set_pen_color(2, 213, 146, 82); // AMBER (NORMAL)
841      m_palette->set_pen_color(3, 255, 193, 129); // AMBER (brighter)
777842                  break;
778843   }
779844}
r31342r31343
783848{
784849   // 'In reverse screen mode, termination forces the beam to the screen background intensity'
785850   // Background intensity means 'dim' (1) according to one source.
786   bitmap.fill( ((m_reverse_field ^ m_basic_attribute) ? 1 : 0) , cliprect);
851   bitmap.fill(((m_reverse_field ^ m_basic_attribute) ? 1 : 0), cliprect);
787852}
788853
789854
r31342r31343
801866            return MHFU_counter;
802867
803868         case -100:          // -100 : RESET and ENABLE MHFU counter
804            //printf("-100 MHFU  * reset and ENABLE * \n");
869      if (VERBOSE)
870         printf("-100 MHFU  * reset and ENABLE * \n");
805871            MHFU_counter = 0;
806872
807            //if (MHFU_FLAG == false)
808            //  printf("-100 MHFU  ___ENABLED___\n");
873      if (VERBOSE)
874      {
875         if (MHFU_FLAG == false)
876            printf("-100 MHFU  ___ENABLED___\n");
877      }
809878            MHFU_FLAG = true;
810879
811880            return -100;
r31342r31343
816885   } // switch
817886}
818887
819TIMER_CALLBACK_MEMBER( vt100_video_device::lba7_change )
888TIMER_CALLBACK_MEMBER(vt100_video_device::lba7_change)
820889{
821890   m_lba7 = (m_lba7) ? 0 : 1;
822891}
823892
824static MACHINE_CONFIG_FRAGMENT( vt100_video )
825   MCFG_PALETTE_ADD_MONOCHROME_GREEN("palette")
893static MACHINE_CONFIG_FRAGMENT(vt100_video)
894MCFG_PALETTE_ADD_MONOCHROME_GREEN("palette")
826895MACHINE_CONFIG_END
827896
828897//-------------------------------------------------
r31342r31343
832901
833902machine_config_constructor vt100_video_device::device_mconfig_additions() const
834903{
835   return MACHINE_CONFIG_NAME( vt100_video );
904   return MACHINE_CONFIG_NAME(vt100_video);
836905}
837906
838static MACHINE_CONFIG_FRAGMENT( rainbow_video )
839   MCFG_PALETTE_ADD("palette", 4)
907static MACHINE_CONFIG_FRAGMENT(rainbow_video)
908MCFG_PALETTE_ADD("palette", 4)
840909MACHINE_CONFIG_END
841910
842911//-------------------------------------------------
r31342r31343
846915
847916machine_config_constructor rainbow_video_device::device_mconfig_additions() const
848917{
849   return MACHINE_CONFIG_NAME( rainbow_video );
918   return MACHINE_CONFIG_NAME(rainbow_video);
850919}
trunk/src/mess/video/vtvideo.h
r31342r31343
6565   UINT8 m_columns;
6666   UINT8 m_height;
6767   UINT8 m_height_MAX;
68   UINT8 m_skip_lines;
68   UINT8 m_fill_lines;
6969   UINT8 m_frequency;
7070   UINT8 m_interlaced;
7171
r31342r31343
7474   
7575   bool m_notify_vblank;
7676   int m_last_scroll;
77
78   bool m_linedoubler;
7779};
7880
7981

Previous 199869 Revisions Next


© 1997-2024 The MAME Team