diff options
author | 2014-03-26 11:28:27 +0000 | |
---|---|---|
committer | 2014-03-26 11:28:27 +0000 | |
commit | cbe4fa6ab9c764d845936969c418650a1e0eb8c5 (patch) | |
tree | 4cba9618954972c967f9afdbebb8cfa8aee9d4ed /src/emu/bus/isa/aga.c | |
parent | 937bfafb3a958c5d910de4264db805abaefa52d8 (diff) |
aga is isa device now, aga/cga cleanup (nw)
note that aga should be extended out of isa_cga in future
Diffstat (limited to 'src/emu/bus/isa/aga.c')
-rw-r--r-- | src/emu/bus/isa/aga.c | 975 |
1 files changed, 975 insertions, 0 deletions
diff --git a/src/emu/bus/isa/aga.c b/src/emu/bus/isa/aga.c new file mode 100644 index 00000000000..819aea4467b --- /dev/null +++ b/src/emu/bus/isa/aga.c @@ -0,0 +1,975 @@ +/***************************************************************************** + * + * aga.c + * + ****************************************************************************/ +#include "aga.h" +#include "video/cgapal.h" + +#define CGA_HCLK (XTAL_14_31818MHz/8) +#define CGA_LCLK (XTAL_14_31818MHz/16) + +#define AGA_SCREEN_NAME "screen" +#define AGA_MC6845_NAME "mc6845_aga" + + +static INPUT_PORTS_START( aga ) + PORT_START( "cga_config" ) + PORT_CONFNAME( 0x03, 0x00, "CGA character set") + PORT_CONFSETTING(0x00, DEF_STR( Normal )) + PORT_CONFSETTING(0x01, "Alternative") + PORT_CONFNAME( 0x1C, 0x00, "CGA monitor type") + PORT_CONFSETTING(0x00, "Colour RGB") + PORT_CONFSETTING(0x04, "Mono RGB") + PORT_CONFSETTING(0x08, "Colour composite") + PORT_CONFSETTING(0x0C, "Television") + PORT_CONFSETTING(0x10, "LCD") + PORT_CONFNAME( 0xE0, 0x00, "CGA chipset") + PORT_CONFSETTING(0x00, "IBM") + PORT_CONFSETTING(0x20, "Amstrad PC1512") + PORT_CONFSETTING(0x40, "Amstrad PPC512") + PORT_CONFSETTING(0x60, "ATI") + PORT_CONFSETTING(0x80, "Paradise") +INPUT_PORTS_END + +#define CGA_MONITOR (m_cga_config->read()&0x1C) +#define CGA_MONITOR_COMPOSITE 0x08 /* Colour composite */ + +const device_type ISA8_AGA = &device_creator<isa8_aga_device>; + +//------------------------------------------------- +// isa8_aga_device - constructor +//------------------------------------------------- + +isa8_aga_device::isa8_aga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t( mconfig, ISA8_AGA, "AGA", tag, owner, clock, "aga", __FILE__), + device_isa8_card_interface(mconfig, *this), + m_palette(*this, "palette"), + m_mc6845(*this, AGA_MC6845_NAME), + m_cga_config(*this, "cga_config"), + m_mda_mode_control(0), + m_mda_status(0), + m_cga_mode_control(0), + m_cga_color_select(0), + m_cga_status(0), + m_framecnt(0), + m_vsync(0), + m_hsync(0) +{ +} + +isa8_aga_device::isa8_aga_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) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_isa8_card_interface(mconfig, *this), + m_palette(*this, "palette"), + m_mc6845(*this, AGA_MC6845_NAME), + m_cga_config(*this, "cga_config"), + m_mda_mode_control(0), + m_mda_status(0), + m_cga_mode_control(0), + m_cga_color_select(0), + m_cga_status(0), + m_framecnt(0), + m_vsync(0), + m_hsync(0) +{ +} +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void isa8_aga_device::device_start() +{ + if (m_palette != NULL && !m_palette->started()) + throw device_missing_dependencies(); + + m_mode = AGA_COLOR; + m_mda_chr_gen = memregion("gfx1")->base() + 0x1000; + m_cga_chr_gen = memregion("gfx1")->base(); + m_videoram = auto_alloc_array(machine(), UINT8, 0x10000); + + set_isa_device(); + m_isa->install_memory(0xb0000, 0xbffff, 0, 0, read8_delegate(FUNC(isa8_aga_device::pc_aga_videoram_r),this), write8_delegate(FUNC(isa8_aga_device::pc_aga_videoram_w),this)); + m_isa->install_device(0x3b0, 0x3bf, 0, 0, read8_delegate( FUNC(isa8_aga_device::pc_aga_mda_r), this ), write8_delegate( FUNC(isa8_aga_device::pc_aga_mda_w), this ) ); + m_isa->install_device(0x3d0, 0x3df, 0, 0, read8_delegate( FUNC(isa8_aga_device::pc_aga_cga_r), this ), write8_delegate( FUNC(isa8_aga_device::pc_aga_cga_w), this ) ); + + /* Initialise the cga palette */ + int i; + + for ( i = 0; i < CGA_PALETTE_SETS * 16; i++ ) + { + m_palette->set_pen_color( i, cga_palette[i][0], cga_palette[i][1], cga_palette[i][2] ); + } + + i = 0x8000; + for ( int r = 0; r < 32; r++ ) + { + for ( int g = 0; g < 32; g++ ) + { + for ( int b = 0; b < 32; b++ ) + { + m_palette->set_pen_color( i, r << 3, g << 3, b << 3 ); + i++; + } + } + } + + UINT8 *gfx = &memregion("gfx1")->base()[0x8000]; + /* just a plain bit pattern for graphics data generation */ + for (i = 0; i < 256; i++) + gfx[i] = i; +} + +ROM_START( aga ) + ROM_REGION(0x8100,"gfx1", 0) + ROM_LOAD("50146 char d1.0 euro.u16", 0x00000, 0x02000, CRC(1305dcf5) SHA1(aca488a16ae4ff05a1f4d14574379ff49cd48343)) //D1.0 +ROM_END + +const rom_entry *isa8_aga_device::device_rom_region() const +{ + return ROM_NAME( aga ); +} + +ioport_constructor isa8_aga_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( aga ); +} + + + +const device_type ISA8_AGA_PC200 = &device_creator<isa8_aga_pc200_device>; + +//------------------------------------------------- +// isa8_aga_pc200_device - constructor +//------------------------------------------------- + +isa8_aga_pc200_device::isa8_aga_pc200_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + isa8_aga_device( mconfig, ISA8_AGA_PC200, "AGA PC200", tag, owner, clock, "aga_pc200", __FILE__), + m_port8(0), + m_portd(0), + m_porte(0) +{ +} + +ROM_START( aga_pc200 ) + ROM_REGION(0x08100,"gfx1", 0) + ROM_LOAD("40109.ic159", 0x00000, 0x08000, CRC(a8b67639) SHA1(99663bfb61798526e092205575370c2ad34249a1)) +ROM_END + +const rom_entry *isa8_aga_pc200_device::device_rom_region() const +{ + return ROM_NAME( aga_pc200 ); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void isa8_aga_pc200_device::device_start() +{ + if (m_palette != NULL && !m_palette->started()) + throw device_missing_dependencies(); + + m_mode = AGA_COLOR; + m_mda_chr_gen = memregion("gfx1")->base() + 0x1000; + m_cga_chr_gen = memregion("gfx1")->base(); + m_videoram = auto_alloc_array(machine(), UINT8, 0x10000); + + set_isa_device(); + m_isa->install_memory(0xb0000, 0xbffff, 0, 0, read8_delegate(FUNC(isa8_aga_pc200_device::pc200_videoram_r),this), write8_delegate(FUNC(isa8_aga_pc200_device::pc200_videoram_w),this)); + m_isa->install_device(0x3b0, 0x3bf, 0, 0, read8_delegate( FUNC(isa8_aga_device::pc_aga_mda_r), this ), write8_delegate( FUNC(isa8_aga_device::pc_aga_mda_w), this ) ); + m_isa->install_device(0x3d0, 0x3df, 0, 0, read8_delegate( FUNC(isa8_aga_pc200_device::pc200_cga_r), this ), write8_delegate( FUNC(isa8_aga_pc200_device::pc200_cga_w), this ) ); + + /* Initialise the cga palette */ + int i; + + for ( i = 0; i < CGA_PALETTE_SETS * 16; i++ ) + { + m_palette->set_pen_color( i, cga_palette[i][0], cga_palette[i][1], cga_palette[i][2] ); + } + + i = 0x8000; + for ( int r = 0; r < 32; r++ ) + { + for ( int g = 0; g < 32; g++ ) + { + for ( int b = 0; b < 32; b++ ) + { + m_palette->set_pen_color( i, r << 3, g << 3, b << 3 ); + i++; + } + } + } + + UINT8 *gfx = &memregion("gfx1")->base()[0x8000]; + /* just a plain bit pattern for graphics data generation */ + for (i = 0; i < 256; i++) + gfx[i] = i; +} + +WRITE_LINE_MEMBER( isa8_aga_device::hsync_changed ) +{ + m_hsync = state ? 1 : 0; +} + + +WRITE_LINE_MEMBER( isa8_aga_device::vsync_changed ) +{ + m_vsync = state ? 8 : 0; + if ( state ) + { + m_framecnt++; + } +} + + + + + +static MC6845_UPDATE_ROW( aga_update_row ) +{ + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + if ( aga->m_update_row ) + { + aga->m_update_row( device, bitmap, cliprect, ma, ra, y, x_count, cursor_x, param ); + } +} + + +static MC6845_INTERFACE( mc6845_aga_intf ) +{ + false, /* show border area */ + 0,0,0,0, /* visarea adjustment */ + 8, /* numbers of pixels per video memory address */ + NULL, /* begin_update */ + aga_update_row, /* update_row */ + NULL, /* end_update */ + DEVCB_NULL, /* on_de_changed */ + DEVCB_NULL, /* on_cur_changed */ + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, isa8_aga_device, hsync_changed), /* on_hsync_changed */ + DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, isa8_aga_device, vsync_changed), /* on_vsync_changed */ + NULL +}; + +MACHINE_CONFIG_FRAGMENT( pcvideo_aga ) + MCFG_SCREEN_ADD( AGA_SCREEN_NAME, RASTER ) + MCFG_SCREEN_RAW_PARAMS( XTAL_14_31818MHz,912,0,640,262,0,200 ) + MCFG_SCREEN_UPDATE_DEVICE( AGA_MC6845_NAME, mc6845_device, screen_update ) + + MCFG_PALETTE_ADD( "palette", /* CGA_PALETTE_SETS * 16*/ 65536 ) + + MCFG_MC6845_ADD( AGA_MC6845_NAME, MC6845, AGA_SCREEN_NAME, XTAL_14_31818MHz/8, mc6845_aga_intf ) +MACHINE_CONFIG_END + +machine_config_constructor isa8_aga_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( pcvideo_aga ); +} + +/************************************* + * + * row update functions + * + *************************************/ + +/* colors need fixing in the mda_text_* functions ! */ +static MC6845_UPDATE_ROW( mda_text_inten_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT8 *videoram = aga->m_videoram; + UINT32 *p = &bitmap.pix32(y); + UINT16 chr_base = ( ra & 0x08 ) ? 0x800 | ( ra & 0x07 ) : ra; + int i; + + if ( y == 0 ) logerror("mda_text_inten_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ma + i ) << 1 ) & 0x0FFF; + UINT8 chr = videoram[ offset ]; + UINT8 attr = videoram[ offset + 1 ]; + UINT8 data = aga->m_mda_chr_gen[ chr_base + chr * 8 ]; + UINT8 fg = ( attr & 0x08 ) ? 3 : 2; + UINT8 bg = 0; + + if ( ( attr & ~0x88 ) == 0 ) { + data = 0x00; + } + + switch( attr ) { + case 0x70: + bg = 2; + fg = 0; + break; + case 0x78: + bg = 2; + fg = 1; + break; + case 0xF0: + bg = 3; + fg = 0; + break; + case 0xF8: + bg = 3; + fg = 1; + break; + } + + if ( i == cursor_x || ( attr & 0x07 ) == 0x01 ) { + data = 0xFF; + } + + *p = palette[( data & 0x80 ) ? fg : bg]; p++; + *p = palette[( data & 0x40 ) ? fg : bg]; p++; + *p = palette[( data & 0x20 ) ? fg : bg]; p++; + *p = palette[( data & 0x10 ) ? fg : bg]; p++; + *p = palette[( data & 0x08 ) ? fg : bg]; p++; + *p = palette[( data & 0x04 ) ? fg : bg]; p++; + *p = palette[( data & 0x02 ) ? fg : bg]; p++; + *p = palette[( data & 0x01 ) ? fg : bg]; p++; + if ( ( chr & 0xE0 ) == 0xC0 ) { + *p = palette[( data & 0x01 ) ? fg : bg]; p++; + } else { + *p = palette[bg]; p++; + } + } +} + + +static MC6845_UPDATE_ROW( mda_text_blink_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + UINT8 *videoram = aga->m_videoram; + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT32 *p = &bitmap.pix32(y); + UINT16 chr_base = ( ra & 0x08 ) ? 0x800 | ( ra & 0x07 ) : ra; + int i; + + if ( y == 0 ) logerror("mda_text_blink_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ma + i ) << 1 ) & 0x0FFF; + UINT8 chr = videoram[ offset ]; + UINT8 attr = videoram[ offset + 1 ]; + UINT8 data = aga->m_mda_chr_gen[ chr_base + chr * 8 ]; + UINT8 fg = ( attr & 0x08 ) ? 3 : 2; + UINT8 bg = 0; + + if ( ( attr & ~0x88 ) == 0 ) { + data = 0x00; + } + + switch( attr ) { + case 0x70: + case 0xF0: + bg = 2; + fg = 0; + break; + case 0x78: + case 0xF8: + bg = 2; + fg = 1; + break; + } + + if ( i == cursor_x ) { + data = 0xFF; + } else { + if ( ( attr & 0x07 ) == 0x01 ) { + data = 0xFF; + } + if ( ( attr & 0x80 ) && ( aga->m_framecnt & 0x40 ) ) { + data = 0x00; + } + } + + *p = palette[( data & 0x80 ) ? fg : bg]; p++; + *p = palette[( data & 0x40 ) ? fg : bg]; p++; + *p = palette[( data & 0x20 ) ? fg : bg]; p++; + *p = palette[( data & 0x10 ) ? fg : bg]; p++; + *p = palette[( data & 0x08 ) ? fg : bg]; p++; + *p = palette[( data & 0x04 ) ? fg : bg]; p++; + *p = palette[( data & 0x02 ) ? fg : bg]; p++; + *p = palette[( data & 0x01 ) ? fg : bg]; p++; + if ( ( chr & 0xE0 ) == 0xC0 ) { + *p = palette[( data & 0x01 ) ? fg : bg]; p++; + } else { + *p = palette[bg]; p++; + } + } +} + + +static MC6845_UPDATE_ROW( cga_text_inten_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + UINT8 *videoram = aga->m_videoram; + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT32 *p = &bitmap.pix32(y); + int i; + + if ( y == 0 ) logerror("cga_text_inten_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ma + i ) << 1 ) & 0x3fff; + UINT8 chr = videoram[ offset ]; + UINT8 attr = videoram[ offset +1 ]; + UINT8 data = aga->m_cga_chr_gen[ chr * 16 + ra ]; + UINT16 fg = attr & 0x0F; + UINT16 bg = ( attr >> 4 ) & 0x07; + + if ( i == cursor_x ) { + data = 0xFF; + } + + *p = palette[( data & 0x80 ) ? fg : bg]; p++; + *p = palette[( data & 0x40 ) ? fg : bg]; p++; + *p = palette[( data & 0x20 ) ? fg : bg]; p++; + *p = palette[( data & 0x10 ) ? fg : bg]; p++; + *p = palette[( data & 0x08 ) ? fg : bg]; p++; + *p = palette[( data & 0x04 ) ? fg : bg]; p++; + *p = palette[( data & 0x02 ) ? fg : bg]; p++; + *p = palette[( data & 0x01 ) ? fg : bg]; p++; + } +} + +static MC6845_UPDATE_ROW( cga_text_inten_alt_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT8 *videoram = aga->m_videoram; + UINT32 *p = &bitmap.pix32(y); + int i; + + if ( y == 0 ) logerror("cga_text_inten_alt_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ma + i ) << 1 ) & 0x3fff; + UINT8 chr = videoram[ offset ]; + UINT8 attr = videoram[ offset +1 ]; + UINT8 data = aga->m_cga_chr_gen[ chr * 16 + ra ]; + UINT16 fg = attr & 0x0F; + + if ( i == cursor_x ) { + data = 0xFF; + } + + *p = palette[( data & 0x80 ) ? fg : 0]; p++; + *p = palette[( data & 0x40 ) ? fg : 0]; p++; + *p = palette[( data & 0x20 ) ? fg : 0]; p++; + *p = palette[( data & 0x10 ) ? fg : 0]; p++; + *p = palette[( data & 0x08 ) ? fg : 0]; p++; + *p = palette[( data & 0x04 ) ? fg : 0]; p++; + *p = palette[( data & 0x02 ) ? fg : 0]; p++; + *p = palette[( data & 0x01 ) ? fg : 0]; p++; + } +} + +static MC6845_UPDATE_ROW( cga_text_blink_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT8 *videoram = aga->m_videoram; + UINT32 *p = &bitmap.pix32(y); + int i; + + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ma + i ) << 1 ) & 0x3fff; + UINT8 chr = videoram[ offset ]; + UINT8 attr = videoram[ offset +1 ]; + UINT8 data = aga->m_cga_chr_gen[ chr * 16 + ra ]; + UINT16 fg = attr & 0x0F; + UINT16 bg = (attr >> 4) & 0x07; + + if ( i == cursor_x ) { + data = 0xFF; + } else { + if ( ( attr & 0x80 ) && ( aga->m_framecnt & 0x10 ) ) { + data = 0x00; + } + } + + *p = palette[( data & 0x80 ) ? fg : bg]; p++; + *p = palette[( data & 0x40 ) ? fg : bg]; p++; + *p = palette[( data & 0x20 ) ? fg : bg]; p++; + *p = palette[( data & 0x10 ) ? fg : bg]; p++; + *p = palette[( data & 0x08 ) ? fg : bg]; p++; + *p = palette[( data & 0x04 ) ? fg : bg]; p++; + *p = palette[( data & 0x02 ) ? fg : bg]; p++; + *p = palette[( data & 0x01 ) ? fg : bg]; p++; + } +} + +static MC6845_UPDATE_ROW( cga_text_blink_alt_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT8 *videoram = aga->m_videoram; + UINT32 *p = &bitmap.pix32(y); + int i; + + if ( y == 0 ) logerror("cga_text_blink_alt_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ma + i ) << 1 ) & 0x3fff; + UINT8 chr = videoram[ offset ]; + UINT8 attr = videoram[ offset +1 ]; + UINT8 data = aga->m_cga_chr_gen[ chr * 16 + ra ]; + UINT16 fg = attr & 0x07; + UINT16 bg = 0; + + if ( i == cursor_x ) { + data = 0xFF; + } else { + if ( ( attr & 0x80 ) && ( aga->m_framecnt & 0x10 ) ) { + data = 0x00; + bg = ( attr >> 4 ) & 0x07; + } + } + + *p = palette[( data & 0x80 ) ? fg : bg]; p++; + *p = palette[( data & 0x40 ) ? fg : bg]; p++; + *p = palette[( data & 0x20 ) ? fg : bg]; p++; + *p = palette[( data & 0x10 ) ? fg : bg]; p++; + *p = palette[( data & 0x08 ) ? fg : bg]; p++; + *p = palette[( data & 0x04 ) ? fg : bg]; p++; + *p = palette[( data & 0x02 ) ? fg : bg]; p++; + *p = palette[( data & 0x01 ) ? fg : bg]; p++; + } +} + +static MC6845_UPDATE_ROW( cga_gfx_4bppl_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT8 *videoram = aga->m_videoram; + UINT32 *p = &bitmap.pix32(y); + int i; + + if ( y == 0 ) logerror("cga_gfx_4bppl_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( y & 1 ) << 13 ); + UINT8 data = videoram[ offset ]; + + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + + data = videoram[ offset + 1 ]; + + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + } +} + +static MC6845_UPDATE_ROW( cga_gfx_4bpph_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + UINT8 *videoram = aga->m_videoram; + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT32 *p = &bitmap.pix32(y); + int i; + + if ( y == 0 ) logerror("cga_gfx_4bpph_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( y & 1 ) << 13 ); + UINT8 data = videoram[ offset ]; + + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + + data = videoram[ offset + 1 ]; + + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data >> 4]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + *p = palette[data & 0x0F]; p++; + } +} + +static MC6845_UPDATE_ROW( cga_gfx_2bpp_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + UINT8 *videoram = aga->m_videoram; + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT32 *p = &bitmap.pix32(y); + int i; + +// if ( y == 0 ) logerror("cga_gfx_2bpp_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( y & 1 ) << 13 ); + UINT8 data = videoram[ offset ]; + + *p = palette[aga->m_cga_palette_lut_2bpp[ ( data >> 6 ) & 0x03 ]]; p++; + *p = palette[aga->m_cga_palette_lut_2bpp[ ( data >> 4 ) & 0x03 ]]; p++; + *p = palette[aga->m_cga_palette_lut_2bpp[ ( data >> 2 ) & 0x03 ]]; p++; + *p = palette[aga->m_cga_palette_lut_2bpp[ data & 0x03 ]]; p++; + + data = videoram[ offset+1 ]; + + *p = palette[aga->m_cga_palette_lut_2bpp[ ( data >> 6 ) & 0x03 ]]; p++; + *p = palette[aga->m_cga_palette_lut_2bpp[ ( data >> 4 ) & 0x03 ]]; p++; + *p = palette[aga->m_cga_palette_lut_2bpp[ ( data >> 2 ) & 0x03 ]]; p++; + *p = palette[aga->m_cga_palette_lut_2bpp[ data & 0x03 ]]; p++; + } +} + +static MC6845_UPDATE_ROW( cga_gfx_1bpp_update_row ) { + isa8_aga_device *aga = downcast<isa8_aga_device *>(device->owner()); + UINT8 *videoram = aga->m_videoram; + const rgb_t *palette = aga->m_palette->palette()->entry_list_raw(); + UINT32 *p = &bitmap.pix32(y); + UINT8 fg = aga->m_cga_color_select & 0x0F; + int i; + + if ( y == 0 ) logerror("cga_gfx_1bpp_update_row\n"); + for ( i = 0; i < x_count; i++ ) { + UINT16 offset = ( ( ( ma + i ) << 1 ) & 0x1fff ) | ( ( ra & 1 ) << 13 ); + UINT8 data = videoram[ offset ]; + + *p = palette[( data & 0x80 ) ? fg : 0]; p++; + *p = palette[( data & 0x40 ) ? fg : 0]; p++; + *p = palette[( data & 0x20 ) ? fg : 0]; p++; + *p = palette[( data & 0x10 ) ? fg : 0]; p++; + *p = palette[( data & 0x08 ) ? fg : 0]; p++; + *p = palette[( data & 0x04 ) ? fg : 0]; p++; + *p = palette[( data & 0x02 ) ? fg : 0]; p++; + *p = palette[( data & 0x01 ) ? fg : 0]; p++; + + data = videoram[ offset + 1 ]; + + *p = palette[( data & 0x80 ) ? fg : 0]; p++; + *p = palette[( data & 0x40 ) ? fg : 0]; p++; + *p = palette[( data & 0x20 ) ? fg : 0]; p++; + *p = palette[( data & 0x10 ) ? fg : 0]; p++; + *p = palette[( data & 0x08 ) ? fg : 0]; p++; + *p = palette[( data & 0x04 ) ? fg : 0]; p++; + *p = palette[( data & 0x02 ) ? fg : 0]; p++; + *p = palette[( data & 0x01 ) ? fg : 0]; p++; + } +} + +/************************************* + * + * AGA MDA/CGA read/write handlers + * + *************************************/ + +READ8_MEMBER ( isa8_aga_device::pc_aga_mda_r ) +{ + UINT8 data = 0xFF; + + if ( m_mode == AGA_MONO ) { + switch( offset ) + { + case 0: case 2: case 4: case 6: + /* return last written mc6845 address value here? */ + break; + case 1: case 3: case 5: case 7: + data = m_mc6845->register_r(space, offset); + break; + case 10: + data = m_vsync | 0x08 | m_hsync; + break; + /* 12, 13, 14 are the LPT1 ports */ + } + } + return data; +} + +WRITE8_MEMBER ( isa8_aga_device::pc_aga_mda_w ) +{ + if ( m_mode == AGA_MONO ) { + switch( offset ) + { + case 0: case 2: case 4: case 6: + m_mc6845->address_w( space, offset, data ); + break; + case 1: case 3: case 5: case 7: + m_mc6845->register_w( space, offset, data ); + break; + case 8: + m_mda_mode_control = data; + + switch( m_mda_mode_control & 0x2a ) { + case 0x08: + m_update_row = mda_text_inten_update_row; + break; + case 0x28: + m_update_row = mda_text_blink_update_row; + break; + default: + m_update_row = NULL; + } + break; + } + } +} + + +READ8_MEMBER ( isa8_aga_device::pc_aga_cga_r ) +{ + UINT8 data = 0xFF; + + if ( m_mode == AGA_COLOR ) { + switch( offset ) { + case 0: case 2: case 4: case 6: + /* return last written mc6845 address value here? */ + break; + case 1: case 3: case 5: case 7: + data = m_mc6845->register_r( space, offset); + break; + case 10: + data = m_vsync | ( ( data & 0x40 ) >> 4 ) | m_hsync; + break; + } + } + return data; +} + +void isa8_aga_device::set_palette_luts(void) +{ + /* Setup 2bpp palette lookup table */ + if ( m_cga_mode_control & 0x10 ) + { + m_cga_palette_lut_2bpp[0] = 0; + } + else + { + m_cga_palette_lut_2bpp[0] = m_cga_color_select & 0x0F; + } + if ( m_cga_mode_control & 0x04 ) + { + m_cga_palette_lut_2bpp[1] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 3; + m_cga_palette_lut_2bpp[2] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 4; + m_cga_palette_lut_2bpp[3] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 7; + } + else + { + if ( m_cga_color_select & 0x20 ) + { + m_cga_palette_lut_2bpp[1] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 3; + m_cga_palette_lut_2bpp[2] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 5; + m_cga_palette_lut_2bpp[3] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 7; + } + else + { + m_cga_palette_lut_2bpp[1] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 2; + m_cga_palette_lut_2bpp[2] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 4; + m_cga_palette_lut_2bpp[3] = ( ( m_cga_color_select & 0x10 ) >> 1 ) | 6; + } + } + //logerror("2bpp lut set to %d,%d,%d,%d\n", cga.palette_lut_2bpp[0], cga.palette_lut_2bpp[1], cga.palette_lut_2bpp[2], cga.palette_lut_2bpp[3]); +} + + +WRITE8_MEMBER (isa8_aga_device:: pc_aga_cga_w ) +{ + if ( m_mode == AGA_COLOR ) { + + switch(offset) { + case 0: case 2: case 4: case 6: + m_mc6845->address_w( space, offset, data ); + break; + case 1: case 3: case 5: case 7: + m_mc6845->register_w( space, offset, data ); + break; + case 8: + m_cga_mode_control = data; + + //logerror("mode set to %02X\n", m_cga_mode_control & 0x3F ); + switch ( m_cga_mode_control & 0x3F ) { + case 0x08: case 0x09: case 0x0C: case 0x0D: + m_mc6845->set_hpixels_per_column( 8 ); + m_update_row = cga_text_inten_update_row; + break; + case 0x0A: case 0x0B: case 0x2A: case 0x2B: + m_mc6845->set_hpixels_per_column( 8 ); + if ( CGA_MONITOR == CGA_MONITOR_COMPOSITE ) { + m_update_row = cga_gfx_4bppl_update_row; + } else { + m_update_row = cga_gfx_2bpp_update_row; + } + break; + case 0x0E: case 0x0F: case 0x2E: case 0x2F: + m_mc6845->set_hpixels_per_column( 8 ); + m_update_row = cga_gfx_2bpp_update_row; + break; + case 0x18: case 0x19: case 0x1C: case 0x1D: + m_mc6845->set_hpixels_per_column( 8 ); + m_update_row = cga_text_inten_alt_update_row; + break; + case 0x1A: case 0x1B: case 0x3A: case 0x3B: + m_mc6845->set_hpixels_per_column( 8 ); + if ( CGA_MONITOR == CGA_MONITOR_COMPOSITE ) { + m_update_row = cga_gfx_4bpph_update_row; + } else { + m_update_row = cga_gfx_1bpp_update_row; + } + break; + case 0x1E: case 0x1F: case 0x3E: case 0x3F: + m_mc6845->set_hpixels_per_column( 16 ); + m_update_row = cga_gfx_1bpp_update_row; + break; + case 0x28: case 0x29: case 0x2C: case 0x2D: + m_mc6845->set_hpixels_per_column( 8 ); + m_update_row = cga_text_blink_update_row; + break; + case 0x38: case 0x39: case 0x3C: case 0x3D: + m_mc6845->set_hpixels_per_column( 8 ); + m_update_row = cga_text_blink_alt_update_row; + break; + default: + m_update_row = NULL; + break; + } + + set_palette_luts(); + break; + case 9: + m_cga_color_select = data; + set_palette_luts(); + break; + } + } +} + +/*************************************/ + +void isa8_aga_device::pc_aga_set_mode( AGA_MODE mode) +{ + m_mode = mode; + + switch (m_mode) { + case AGA_COLOR: + m_mc6845->set_clock( XTAL_14_31818MHz/8 ); + break; + case AGA_MONO: + m_mc6845->set_clock( 16257000/9 ); + break; + case AGA_OFF: + break; + } +} + + +WRITE8_MEMBER ( isa8_aga_device::pc_aga_videoram_w ) +{ + switch (m_mode) { + case AGA_COLOR: + if (offset>=0x8000) + m_videoram[offset-0x8000]=data; + break; + case AGA_MONO: + m_videoram[offset]=data; + break; + case AGA_OFF: break; + } +} + +READ8_MEMBER( isa8_aga_device::pc_aga_videoram_r ) +{ + switch (m_mode) { + case AGA_COLOR: + if (offset>=0x8000) return m_videoram[offset-0x8000]; + return 0; + case AGA_MONO: + return m_videoram[offset]; + case AGA_OFF: break; + } + return 0; +} + +READ8_MEMBER( isa8_aga_pc200_device::pc200_videoram_r ) +{ + switch (m_mode) + { + default: + if (offset>=0x8000) return m_videoram[offset-0x8000]; + return 0; + case AGA_MONO: + return m_videoram[offset]; + } + return 0; +} + +WRITE8_MEMBER ( isa8_aga_pc200_device::pc200_videoram_w ) +{ + switch (m_mode) + { + default: + if (offset>=0x8000) + m_videoram[offset-0x8000]=data; + break; + case AGA_MONO: + m_videoram[offset]=data; + break; + } +} + +// in reality it is of course only 1 graphics adapter, +// but now cga and mda are splitted in mess +WRITE8_MEMBER( isa8_aga_pc200_device::pc200_cga_w ) +{ + pc_aga_cga_w(space, offset,data,mem_mask); + switch(offset) { + case 4: + m_portd |= 0x20; + break; + case 8: + m_port8 = data; + m_portd |= 0x80; + break; + case 0xe: + m_portd = 0x1f; + if (data & 0x80) + m_portd |= 0x40; + +/* The bottom 3 bits of this port are: + * Bit 2: Disable AGA + * Bit 1: Select MDA + * Bit 0: Select external display (monitor) rather than internal display + * (TV for PC200; LCD for PPC512) */ + if ((m_porte & 7) != (data & 7)) + { + if (data & 4) + pc_aga_set_mode(AGA_OFF); + else if (data & 2) + pc_aga_set_mode(AGA_MONO); + else + pc_aga_set_mode(AGA_COLOR); + } + m_porte = data; + break; + + default: + break; + } +} + +READ8_MEMBER ( isa8_aga_pc200_device::pc200_cga_r ) +{ + UINT8 result = 0xff; + + switch(offset) { + case 8: + result = m_port8; + break; + + case 0xd: + // after writing 0x80 to 0x3de, bits 7..5 of 0x3dd from the 2nd read must be 0 + result=m_portd; + m_portd&=0x1f; + break; + + case 0xe: + // 0x20 low cga + // 0x10 low special + result = machine().root_device().ioport("DSW0")->read() & 0x38; + break; + + default: + result = pc_aga_cga_r(space, offset, mem_mask); + break; + } + return result; +} |