summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/video/dgn_beta.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/video/dgn_beta.c')
-rw-r--r--src/mess/video/dgn_beta.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/mess/video/dgn_beta.c b/src/mess/video/dgn_beta.c
new file mode 100644
index 00000000000..3881af5e88c
--- /dev/null
+++ b/src/mess/video/dgn_beta.c
@@ -0,0 +1,303 @@
+/*
+ video/dgn_beta.c
+
+The Dragon Beta uses a 68B45 for it's display generation, this is used in the
+conventional wat with a character generator ROM in the two text modes, which are
+standard 40x25 and 80x25. In adition to the 6845 there is some TTL logic which
+provides colour and attributes. In text modes the video ram is organised as pairs
+of character and attribute, in alternate bytes.
+
+The attributes decode as follows :-
+
+ 7-6-5-4-3-2-1-0
+ f-u-F-F-F-B-B-B
+
+ f=flash
+ u=underline
+
+ FFF = foreground colour
+ BBB = bakcground colour
+
+ 000 black
+ 001 red
+ 010 green
+ 011 yellow
+ 100 blue
+ 101 magenta
+ 110 cyan
+ 111 white
+
+ If flash is true, foreground and background colours will be exchanged.
+
+It is interesting to note that the 6845 uses 16 bit wide access to the ram, in contrast
+to the 8 bit accesses from the CPUs, this allows each increment of the MA lines to move
+2 bytes at a time, and therefore feed both the character rom and the attribute decode
+circuit simultaniously.
+
+The RAM addresses are made up of two parts, the MA0..13 from the 6845, plus two output
+lines from the 6821 PIA, I28, the lines are BP6 and PB7, with PB7 being the most
+significant. This effectivly allows the 6845 access to the first 128K of memory, as there
+are 16 address lines, accessing a 16 bit wide memory.
+
+The relationship between how the cpu sees the RAM, and the way the 6845 sees it is simply
+CPU addr=2x6845 addr. So for the default video address of $1F000, the CPU sees this as
+being at $1F000 (after DAT trasnlation). The 6845 is programmed to start it's MA lines
+counting at $3800, plus A14 and A15 being supplied by PB6 and PB7 from I28, gives an address
+of $F800, which is the same as $1F000 / 2.
+
+I am currently at this time not sure of how any of the graphics modes, work, this will need
+further investigation.
+
+However the modes supported are :-
+
+Text Modes
+ width height colours
+ 40 25 8
+ 80 25 8
+Graphics modes
+ 320 256 4
+ 320 256 16
+ 640 512 4
+ 640 256 4**
+ 640 512 2
+
+Looking at the parts of the circuit sheet that I have seen it looks like the graphics modes
+are driven using a combination of the 6845 MA and RA lines to address more than 64K or memory
+which is needed for some of the modes above (specifically, 640x512x4, which needs 80K).
+
+2006-11-30, Text mode is almost completely implemented, in both 40 and 80 column modes.
+I have made a start on implementing the graphics modes of the beta, drawing from technical
+documents, from the project, this is still a work in progress. I have however managed to get
+it to display a distorted graphical image, so I know I am going in the correct direction !
+
+** 2006-12-05, this mode is not documented in any of the printed documentation, however it
+is supported and displayed by the graphics test rom, it is basically the 640x512x4 mode with
+half the number of vertical lines, and in non-interlaced mode.
+
+It seems that the 640x512 modes operate the 6845 in interlaced mode, just how this affects
+the access to the video memory is unclear to me at the moment.
+
+*/
+
+#include "emu.h"
+#include "includes/dgn_beta.h"
+
+/* GCtrl bitmasks, infered from bits of Beta schematic */
+#define GCtrlWI 0x01
+#define GCtrlSWChar 0x02 /* Character set select */
+#define GCtrlHiLo 0x04 /* Hi/Lo res graphics, Hi=1, Lo=0 */
+#define GCtrlChrGfx 0x08 /* Character=1 / Graphics=0 */
+#define GCtrlControl 0x10 /* Control bit, sets direct drive mode */
+#define GCtrlFS 0x20 /* labeled F/S, not yet sure of function Fast or Slow scan ? */
+#define GCtrlAddrLines 0xC0 /* Top two address lines for text mode */
+
+#define IsTextMode (state->m_GCtrl & GCtrlChrGfx) ? 1 : 0 // Is this text mode ?
+#define IsGfx16 ((~state->m_GCtrl & GCtrlChrGfx) && (~state->m_GCtrl & GCtrlControl)) ? 1 : 0 // is this 320x256x16bpp mode
+#define IsGfx2 ((state->m_GCtrl & GCtrlHiLo) && (~state->m_GCtrl & GCtrlFS)) ? 1 : 0 // Is this a 2 colour mode
+#define SWChar (state->m_GCtrl & GCtrlSWChar)>>1 // Swchar bit
+
+static MC6845_UPDATE_ROW( dgnbeta_update_row )
+{
+ dgn_beta_state *state = device->machine().driver_data<dgn_beta_state>();
+ const rgb_t *palette = palette_entry_list_raw(bitmap.palette());
+ UINT8 *videoram = state->m_videoram;
+ UINT32 *p = &bitmap.pix32(y);
+ int i;
+ if(IsTextMode)
+ {
+ UINT8 *chr_gen = state->memregion("gfx1")->base();
+ for ( i = 0; i < x_count; i++ )
+ {
+ UINT32 offset = ( ( ma + i ) | ((state->m_GCtrl & GCtrlAddrLines)<<8)) << 1;
+ UINT8 chr = videoram[ offset ];
+ UINT8 attr = videoram[ offset +1 ];
+
+ /* Extract non-colour attributes, in character set 1, undeline is used */
+ /* We will extract the colours below, when we have decoded inverse */
+ /* to indicate a double height character */
+ int UnderLine=(attr & 0x40) >> 6; // Underline active
+ int FlashChar=(attr & 0x80) >> 7; // Flashing char
+
+ // underline is active for character set 0, on character row 9
+ int ULActive=(UnderLine && (ra==9) && ~SWChar);
+
+ /* Invert forground and background if flashing char and flash acive */
+ int Invert=(FlashChar & state->m_FlashBit);
+
+ /* Underline inverts flash */
+ if (ULActive)
+ Invert=~Invert;
+
+ /* Cursor on also inverts */
+ if (i == cursor_x)
+ Invert=~Invert;
+
+ UINT16 fg = 0;
+ UINT16 bg = 0;
+
+ /* Invert colours if invert is true */
+ if(!Invert)
+ {
+ fg = (attr & 0x38) >> 3;
+ bg = (attr & 0x07);
+ }
+ else
+ {
+ bg = (attr & 0x38) >> 3;
+ fg = (attr & 0x07);
+ }
+
+
+
+ UINT8 data = chr_gen[ chr * 16 + ra ];
+
+ *p = palette[( data & 0x80 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x80 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x40 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x40 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x20 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x20 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x10 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x10 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x08 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x08 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x04 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x04 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x02 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x02 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x01 ) ? fg : bg]; p++;
+ *p = palette[( data & 0x01 ) ? fg : bg]; p++;
+ }
+
+ }
+ else
+ {
+ for ( i = 0; i < x_count; i++ )
+ {
+ UINT32 offset = ((((ma + i ) & 0x1FFF) << 3) | (ra & 0x07)) << 1;
+
+ UINT8 Lo = videoram[ offset ];
+ UINT8 Hi = videoram[ offset +1 ];
+ UINT16 Word = (Hi<<8) | Lo;
+ int Red;
+ int Green;
+ int Blue;
+ int Intense;
+ int Colour;
+ int Dot;
+
+ /* If contol is low then we are plotting 4 bit per pixel, 16 colour mode */
+ /* This directly drives the colour output lines, from the pixel value */
+ /* If Control is high, then we lookup the colour from the LS670 4x4 bit */
+ /* palate register */
+ if (IsGfx16)
+ {
+ Intense =(Lo & 0x0F);
+ Red =(Lo & 0xF0)>>4;
+ Green =(Hi & 0x0F);
+ Blue =(Hi & 0xF0)>>4;
+ Colour=((Intense&0x08) | (Red&0x08)>>1) | ((Green&0x08)>>2) | ((Blue&0x08)>>3);
+
+ for (Dot=0;Dot<4;Dot++)
+ {
+ *p = palette[Colour]; p++;
+ *p = palette[Colour]; p++;
+ *p = palette[Colour]; p++;
+ *p = palette[Colour]; p++;
+
+ Intense =Intense<<1;
+ Red =Red<<1;
+ Green =Green<<1;
+ Blue =Blue<<1;
+ }
+ }
+ else if (IsGfx2)
+ {
+ for (Dot=0;Dot<16;Dot=Dot+1)
+ {
+ Colour=state->m_ColourRAM[((Word&0x8000)>>15)];
+
+ *p = palette[Colour]; p++;
+
+ Hi=(Word&0x8000) >> 15;
+ Word=((Word<<1)&0xFFFE) | Hi;
+ }
+ }
+ else
+ {
+ for (Dot=0;Dot<8;Dot++)
+ {
+ Colour=state->m_ColourRAM[((Word&0x8000)>>14) | ((Word&0x80)>>7)];
+ *p = palette[Colour]; p++;
+ *p = palette[Colour]; p++;
+
+ Hi=(Word&0x8000) >> 15;
+ Word=((Word<<1)&0xFFFE) | Hi;
+ }
+ }
+ }
+ }
+
+}
+
+static WRITE_LINE_DEVICE_HANDLER( dgnbeta_vsync_changed )
+{
+ dgn_beta_state *st = device->machine().driver_data<dgn_beta_state>();
+
+ st->m_beta_VSync=state;
+ if (!st->m_beta_VSync)
+ {
+ st->m_FlashCount++;
+ if(st->m_FlashCount==10)
+ {
+ st->m_FlashCount=0; // Reset counter
+ st->m_FlashBit=(!st->m_FlashBit) & 0x01; // Invert flash bit.
+ }
+ }
+
+ dgn_beta_frame_interrupt(device->machine(), state);
+}
+
+const mc6845_interface dgnbeta_crtc6845_interface =
+{
+ "screen",
+ 16 /*?*/,
+ NULL,
+ dgnbeta_update_row,
+ NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_LINE(dgnbeta_vsync_changed),
+ NULL
+};
+
+
+/* Set video control register from I28 port B, the control register is laid out as */
+/* follows :- */
+/* bit function */
+/* 0 WI, unknown */
+/* 1 Character set select, drives A12 of character rom in text mode */
+/* 2 High (1) or Low(0) resolution if in graphics mode. */
+/* 3 Text (1) or Graphics(0) mode */
+/* 4 Control bit, Selects between colour palate and drirect drive */
+/* 5 F/S bit, 1=80 bytes/line, 0=40bytes/line */
+/* 6 Effective A14, to ram, in text mode */
+/* 7 Effective A15, to ram, in text mode */
+/* the top two address lines for the video ram, are supplied by the BB6 and PB7 on */
+/* 6821-I28, this allows the 6845 to access the full 64K address range, however */
+/* since the ram data is addressed as a 16bit wide unit, this allows the 6845 */
+/* access to the first 128K or ram. */
+void dgnbeta_vid_set_gctrl(running_machine &machine, int data)
+{
+ dgn_beta_state *state = machine.driver_data<dgn_beta_state>();
+ state->m_GCtrl=data;
+}
+
+
+/* Write handler for colour, pallate ram */
+WRITE8_HANDLER(dgnbeta_colour_ram_w)
+{
+ dgn_beta_state *state = space->machine().driver_data<dgn_beta_state>();
+ state->m_ColourRAM[offset]=data&0x0f; /* Colour ram 4 bit and write only to CPU */
+}