diff options
Diffstat (limited to 'trunk/src/emu/video/h63484.c')
-rw-r--r-- | trunk/src/emu/video/h63484.c | 1204 |
1 files changed, 1204 insertions, 0 deletions
diff --git a/trunk/src/emu/video/h63484.c b/trunk/src/emu/video/h63484.c new file mode 100644 index 00000000000..8ba7d562ff8 --- /dev/null +++ b/trunk/src/emu/video/h63484.c @@ -0,0 +1,1204 @@ +/*************************************************************************** + + HD63484 ACRTC (rewrite in progress) + + TODO: + - 8-bit support for FIFO, parameters and command values + - execution cycles; + +***************************************************************************/ + +#include "emu.h" +#include "h63484.h" + +#define LOG 1 +#define FIFO_LOG 0 + +// default address map +static ADDRESS_MAP_START( h63484_vram, AS_0, 8, h63484_device ) + AM_RANGE(0x00000, 0x7ffff) AM_RAM + AM_RANGE(0x80000, 0xfffff) AM_NOP +ADDRESS_MAP_END + + +//------------------------------------------------- +// h63484_device - constructor +//------------------------------------------------- + +h63484_device::h63484_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, H63484, "H63484", tag, owner, clock), + device_memory_interface(mconfig, *this), + m_ar(0), + m_sr(0), + m_fifo_ptr(-1), + m_fifo_r_ptr(-1), + m_cr(0), + m_param_ptr(0), + m_rwp_dn(0), + m_org_dpa(0), + m_org_dn(0), + m_org_dpd(0), + m_cl0(0), + m_cl1(0), + m_dcr(0), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 20, 0, NULL, *ADDRESS_MAP_NAME(h63484_vram)) +{ + m_shortname = "h63484"; +} + +enum +{ + FIFO_READ = 0, + FIFO_WRITE +}; + +enum +{ + FIFO_EMPTY = -1, + FIFO_PARAMETER, + FIFO_COMMAND +}; + +#define H63484_SR_CER 0x80 // Command Error +#define H63484_SR_ARD 0x40 // Area Detect +#define H63484_SR_CED 0x20 // Command End +#define H63484_SR_LPD 0x10 // Light Pen Strobe Detect +#define H63484_SR_RFF 0x08 // Read FIFO Full +#define H63484_SR_RFR 0x04 // Read FIFO Ready +#define H63484_SR_WFR 0x02 // Write FIFO Ready +#define H63484_SR_WFE 0x01 // Write FIFO Empty + + +static const char *const acrtc_regnames[0x100/2] = +{ + "FIFO Entry", // 0x00 + "Command Control (CCR)", // 0x02 + "Operation Mode (OMR)", // 0x04 + "Display Control (DCR)", // 0x06 + "(Undefined)", // 0x08 + "(Undefined)", // 0x0a + "(Undefined)", // 0x0c + "(Undefined)", // 0x0e + "(Undefined)", // 0x10 + "(Undefined)", // 0x12 + "(Undefined)", // 0x14 + "(Undefined)", // 0x16 + "(Undefined)", // 0x18 + "(Undefined)", // 0x1a + "(Undefined)", // 0x1c + "(Undefined)", // 0x1e + "(Undefined)", // 0x20 + "(Undefined)", // 0x22 + "(Undefined)", // 0x24 + "(Undefined)", // 0x26 + "(Undefined)", // 0x28 + "(Undefined)", // 0x2a + "(Undefined)", // 0x2c + "(Undefined)", // 0x2e + "(Undefined)", // 0x30 + "(Undefined)", // 0x32 + "(Undefined)", // 0x34 + "(Undefined)", // 0x36 + "(Undefined)", // 0x38 + "(Undefined)", // 0x3a + "(Undefined)", // 0x3c + "(Undefined)", // 0x3e + "(Undefined)", // 0x40 + "(Undefined)", // 0x42 + "(Undefined)", // 0x44 + "(Undefined)", // 0x46 + "(Undefined)", // 0x48 + "(Undefined)", // 0x4a + "(Undefined)", // 0x4c + "(Undefined)", // 0x4e + "(Undefined)", // 0x50 + "(Undefined)", // 0x52 + "(Undefined)", // 0x54 + "(Undefined)", // 0x56 + "(Undefined)", // 0x58 + "(Undefined)", // 0x5a + "(Undefined)", // 0x5c + "(Undefined)", // 0x5e + "(Undefined)", // 0x60 + "(Undefined)", // 0x62 + "(Undefined)", // 0x64 + "(Undefined)", // 0x66 + "(Undefined)", // 0x68 + "(Undefined)", // 0x6a + "(Undefined)", // 0x6c + "(Undefined)", // 0x6e + "(Undefined)", // 0x70 + "(Undefined)", // 0x72 + "(Undefined)", // 0x74 + "(Undefined)", // 0x76 + "(Undefined)", // 0x78 + "(Undefined)", // 0x7a + "(Undefined)", // 0x7c + "(Undefined)", // 0x7e + "Raster Count (RCR)", // 0x80 + "Horizontal Sync (HSR)", // 0x82 + "Horizontal Display (HDR)", // 0x84 + "Vertical Sync (VSR)", // 0x86 + "Vertical Display (VDR)", // 0x88 + "Split Screen Width (SSW) 0x8a", // 0x8a + "Split Screen Width (SSW) 0x8c", // 0x8c + "Split Screen Width (SSW) 0x8e", // 0x8e + "Blink Control (BCR)", // 0x90 + "Horizontal Window Display (HWR)", // 0x92 + "Vertical Window Display (VWR) 0x94", // 0x94 + "Vertical Window Display (VWR) 0x96", // 0x96 + "Graphic Cursor (GCR0)", // 0x98 + "Graphic Cursor (GCR1)", // 0x9a + "Graphic Cursor (GCR2)", // 0x9c + "(Undefined)", // 0x9e + "(Undefined)", // 0xa0 + "(Undefined)", // 0xa2 + "(Undefined)", // 0xa4 + "(Undefined)", // 0xa6 + "(Undefined)", // 0xa8 + "(Undefined)", // 0xaa + "(Undefined)", // 0xac + "(Undefined)", // 0xae + "(Undefined)", // 0xb0 + "(Undefined)", // 0xb2 + "(Undefined)", // 0xb4 + "(Undefined)", // 0xb6 + "(Undefined)", // 0xb8 + "(Undefined)", // 0xba + "(Undefined)", // 0xbc + "(Undefined)", // 0xbe + // upper screen + "Raster Address 0 (RAR0)", // 0xc0 + "Memory Width 0 (MWR0)", // 0xc2 + "Start Address 0 (SAR0) 0xc4", // 0xc4 + "Start Address 0 (SAR0) 0xc6", // 0xc6 + // base screen + "Raster Address 1 (RAR1)", // 0xc8 + "Memory Width 1 (MWR1)", // 0xca + "Start Address 1 (SAR1) 0xcc", // 0xcc + "Start Address 1 (SAR1) 0xce", // 0xce + // lower screen + "Raster Address 2 (RAR2)", // 0xd0 + "Memory Width 2 (MWR2)", // 0xd2 + "Start Address 2 (SAR2) 0xd4", // 0xd4 + "Start Address 2 (SAR2) 0xd6", // 0xd6 + // window screen + "Raster Address 3 (RAR3)", // 0xd8 + "Memory Width 3 (MWR3)", // 0xda + "Start Address 3 (SAR3) 0xdc", // 0xdc + "Start Address 3 (SAR3) 0xde", // 0xde + // block cursor 1 + "Block Cursor 1 (BCUR1) 0xe0", + "Block Cursor 1 (BCUR1) 0xe2", + // block cursor 2 + "Block Cursor 2 (BCUR2) 0xe4", + "Block Cursor 2 (BCUR2) 0xe6", + "Cursor Definition (CDR)", + "Zoom Factor (ZFR)", + "Lightpen Address (LPAR) 0xec", + "Lightpen Address (LPAR) 0xee", + "(Undefined)", // 0xf0 + "(Undefined)", // 0xf2 + "(Undefined)", // 0xf4 + "(Undefined)", // 0xf6 + "(Undefined)", // 0xf8 + "(Undefined)", // 0xfa + "(Undefined)", // 0xfc + "(Undefined)" // 0xfe +}; + +static const char *const wpr_regnames[0x20] = +{ + "Color 0 (CL0)", + "Color 1 (CL1)", + "Color Comparison (COMP)", + "Edge Color (EDG)", + "Mask (MASK)", + "Pattern RAM Control (PRC) 0x05", + "Pattern RAM Control (PRC) 0x06", + "Pattern RAM Control (PRC) 0x07", + "Area Definition (ADR) 0x08", + "Area Definition (ADR) 0x09", + "Area Definition (ADR) 0x0a", + "Area Definition (ADR) 0x0b", + "Read Write Pointer (RWP) H", + "Read Write Pointer (RWP) L", + "(Undefined)", + "(Undefined)", + "Drawing Pointer (DP) H", + "Drawing Pointer (DP) L", + "Current Pointer (CP) H", + "Current Pointer (CP) L", + "(Undefined)", // 0x14 + "(Undefined)", + "(Undefined)", // 0x16 + "(Undefined)", + "(Undefined)", // 0x18 + "(Undefined)", + "(Undefined)", // 0x1a + "(Undefined)", + "(Undefined)", // 0x1c + "(Undefined)", + "(Undefined)", // 0x1e + "(Undefined)" +}; + +enum +{ + COMMAND_INVALID = -1, + COMMAND_ORG, + COMMAND_WPR, + COMMAND_RPR, + COMMAND_WPTN, + COMMAND_RPTN, + COMMAND_DRD, + COMMAND_DWT, + COMMAND_DMOD, + COMMAND_RD, + COMMAND_WT, + COMMAND_MOD, + COMMAND_CLR, + COMMAND_SCLR, + COMMAND_CPY, + COMMAND_SCPY, + COMMAND_AMOVE, + COMMAND_RMOVE, + COMMAND_ALINE, + COMMAND_RLINE, + COMMAND_ARCT, + COMMAND_RRCT, + COMMAND_APLL, + COMMAND_RPLL, + COMMAND_APLG, + COMMAND_RPLG, + COMMAND_CRCL, + COMMAND_ELPS, + COMMAND_AARC, + COMMAND_RARC, + COMMAND_AEARC, + COMMAND_REARC, + COMMAND_AFRCT, + COMMAND_RFRCT, + COMMAND_PAINT, + COMMAND_DOT, + COMMAND_PTN, + COMMAND_AGCPY, + COMMAND_RGCPY +}; + +#define H63484_COMMAND_ORG 0x0400 // p: 2 +#define H63484_COMMAND_WPR 0x0800 // & ~0x1f p: 1 +#define H63484_COMMAND_RPR 0x0c00 // & ~0x1f p: 0 +#define H63484_COMMAND_WPTN 0x1800 // & ~0xf p: 1 + n +#define H63484_COMMAND_RPTN 0x1c00 // & ~0xf p: 1 +#define H63484_COMMAND_DRD 0x2400 // p: 2 +#define H63484_COMMAND_DWT 0x2800 // p: 2 +#define H63484_COMMAND_DMOD 0x2c00 // & ~3 p: 2 +#define H63484_COMMAND_RD 0x4400 // p: 0 +#define H63484_COMMAND_WT 0x4800 // p: 1 +#define H63484_COMMAND_MOD 0x4c00 // & ~3 p: 1 +#define H63484_COMMAND_CLR 0x5800 // p: 3 +#define H63484_COMMAND_SCLR 0x5c00 // & ~3 p: 3 +#define H63484_COMMAND_CPY 0x6000 // & ~0x0f03 p: 4 +#define H63484_COMMAND_SCPY 0x7000 // & ~0x0f03 p: 4 +#define H63484_COMMAND_AMOVE 0x8000 // p: 2 +#define H63484_COMMAND_RMOVE 0x8400 // p: 2 +#define H63484_COMMAND_ALINE 0x8800 // & ~0x00ff p: 2 +#define H63484_COMMAND_RLINE 0x8c00 // & ~0x00ff p: 2 +#define H63484_COMMAND_ARCT 0x9000 // & ~0x00ff p: 2 +#define H63484_COMMAND_RRCT 0x9400 // & ~0x00ff p: 2 +#define H63484_COMMAND_APLL 0x9800 // & ~0x00ff p: 1 + n +#define H63484_COMMAND_RPLL 0x9c00 // & ~0x00ff p: 1 + n +#define H63484_COMMAND_APLG 0xa000 // & ~0x00ff p: 1 + n +#define H63484_COMMAND_RPLG 0xa400 // & ~0x00ff p: 1 + n +#define H63484_COMMAND_CRCL 0xa800 // & ~0x01ff p: 1 +#define H63484_COMMAND_ELPS 0xac00 // & ~0x01ff p: 3 +#define H63484_COMMAND_AARC 0xb000 // & ~0x01ff p: 4 +#define H63484_COMMAND_RARC 0xb400 // & ~0x01ff p: 4 +#define H63484_COMMAND_AEARC 0xb800 // & ~0x01ff p: 6 +#define H63484_COMMAND_REARC 0xbc00 // & ~0x01ff p: 6 +#define H63484_COMMAND_AFRCT 0xc000 // & ~0x00ff p: 2 +#define H63484_COMMAND_RFRCT 0xc400 // & ~0x00ff p: 2 +#define H63484_COMMAND_PAINT 0xc800 // & ~0x01ff p: 0 +#define H63484_COMMAND_DOT 0xcc00 // & ~0x00ff p: 0 +#define H63484_COMMAND_PTN 0xd000 // & ~0x0fff p: 1 +#define H63484_COMMAND_AGCPY 0xe000 // & ~0x0fff p: 4 +#define H63484_COMMAND_RGCPY 0xf000 // & ~0x0fff p: 4 + + +/*------------------------------------------------- + ROM( h63484 ) +-------------------------------------------------*/ + +// devices +const device_type H63484 = &device_creator<h63484_device>; + + +ROM_START( h63484 ) + ROM_REGION( 0x100, "h63484", 0 ) + ROM_LOAD( "h63484.bin", 0x000, 0x100, NO_DUMP ) /* internal control ROM */ +ROM_END + +//------------------------------------------------- +// memory_space_config - return a description of +// any address spaces owned by this device +//------------------------------------------------- + +const address_space_config *h63484_device::memory_space_config(address_spacenum spacenum) const +{ + return (spacenum == AS_0) ? &m_space_config : NULL; +} + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const rom_entry *h63484_device::device_rom_region() const +{ + return ROM_NAME( h63484 ); +} + +//------------------------------------------------- +// readbyte - read a byte at the given address +//------------------------------------------------- + +inline UINT8 h63484_device::readbyte(offs_t address) +{ + return space()->read_byte(address); +} + + +//------------------------------------------------- +// writebyte - write a byte at the given address +//------------------------------------------------- + +inline void h63484_device::writebyte(offs_t address, UINT8 data) +{ + space()->write_byte(address, data); +} + + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void h63484_device::device_config_complete() +{ + // inherit a copy of the static data + const h63484_interface *intf = reinterpret_cast<const h63484_interface *>(static_config()); + if (intf != NULL) + *static_cast<h63484_interface *>(this) = *intf; + + // or initialize to defaults if none provided + else + { + // ... + } +} + +inline void h63484_device::fifo_w_clear() +{ + int i; + + for (i = 0; i < 16; i++) + m_fifo[i] = 0; + + m_fifo_ptr = -1; + + m_sr |= H63484_SR_WFR; + m_sr |= H63484_SR_WFE; +} + +inline void h63484_device::queue_w(UINT8 data) +{ + if (m_fifo_ptr < 15) + { + m_fifo_ptr++; + + m_fifo[m_fifo_ptr] = data; + + if (m_fifo_ptr == 16) + m_sr &= ~H63484_SR_WFR; + + m_sr &= ~H63484_SR_WFE; + } + else + { + // TODO what happen? somebody set us up the bomb + printf("FIFO?\n"); + } +} + +inline void h63484_device::dequeue_w(UINT8 *data) +{ + int i; + + *data = m_fifo[0]; + + if (m_fifo_ptr > -1) + { + for (i = 0; i < 15; i++) + m_fifo[i] = m_fifo[i + 1]; + + m_fifo[15] = 0; + + m_fifo_ptr--; + + m_sr |= H63484_SR_WFR; + + if (m_fifo_ptr == -1) + m_sr |= H63484_SR_WFE; + + } +} + +inline void h63484_device::fifo_r_clear() +{ + int i; + + for (i = 0; i < 16; i++) + m_fifo_r[i] = 0; + + m_fifo_r_ptr = -1; + + m_sr &= ~H63484_SR_RFR; + m_sr &= ~H63484_SR_RFF; +} + +inline void h63484_device::queue_r(UINT8 data) +{ + if (m_fifo_r_ptr < 15) + { + m_fifo_r_ptr++; + + m_fifo_r[m_fifo_r_ptr] = data; + + if (m_fifo_r_ptr == 16) + m_sr |= H63484_SR_RFF; + + m_sr |= H63484_SR_RFR; + } + else + { + // TODO what happen? somebody set us up the bomb + printf("FIFO?\n"); + } +} + +inline void h63484_device::dequeue_r(UINT8 *data) +{ + int i; + + *data = m_fifo_r[0]; + + if (m_fifo_r_ptr > -1) + { + for (i = 0; i < 15; i++) + m_fifo_r[i] = m_fifo_r[i + 1]; + + m_fifo_r[15] = 0; + + m_fifo_r_ptr--; + + m_sr &= ~H63484_SR_RFF; + + if (m_fifo_r_ptr == -1) + m_sr &= ~H63484_SR_RFR; + } +} + +//------------------------------------------------- +// recompute_parameters - +//------------------------------------------------- + +inline void h63484_device::recompute_parameters() +{ + if(m_hc == 0 || m_vc == 0) //bail out if screen params aren't valid + return; + + printf("HC %d HSW %d HDS %d HDW %d HWS %d HWW %d\n",m_hc,m_hsw,m_hds,m_hdw,m_hws,m_hww); + printf("VC %d VDS %d VSW %d VWS %d VWW %d\n",m_vc,m_vds,m_vsw,m_vws,m_vww); +} + +/*------------------------------------------------- + ADDRESS_MAP( h63484 ) +-------------------------------------------------*/ + +READ8_MEMBER( h63484_device::vram_r ) +{ + return m_vram[offset]; +} + +WRITE8_MEMBER( h63484_device::vram_w ) +{ + m_vram[offset] = data; +} + + +/***************************************************************************** + IMPLEMENTATION +*****************************************************************************/ + +int h63484_device::translate_command(UINT16 data) +{ + /* annoying switch-case sequence, but it's the only way to get invalid commands ... */ + switch (data) + { + case H63484_COMMAND_ORG: return COMMAND_ORG; + case H63484_COMMAND_DRD: return COMMAND_DRD; + case H63484_COMMAND_DWT: return COMMAND_DWT; + case H63484_COMMAND_RD: return COMMAND_RD; + case H63484_COMMAND_WT: return COMMAND_WT; + case H63484_COMMAND_CLR: return COMMAND_CLR; + case H63484_COMMAND_AMOVE: return COMMAND_AMOVE; + case H63484_COMMAND_RMOVE: return COMMAND_RMOVE; + } + + switch(data & ~0x3) + { + case H63484_COMMAND_DMOD: return COMMAND_DMOD; + case H63484_COMMAND_MOD: return COMMAND_MOD; + case H63484_COMMAND_SCLR: return COMMAND_SCLR; + } + + switch(data & ~0xf) + { + case H63484_COMMAND_WPTN: return COMMAND_WPTN; + case H63484_COMMAND_RPTN: return COMMAND_RPTN; + } + + switch(data & ~0x1f) + { + case H63484_COMMAND_WPR: return COMMAND_WPR; + case H63484_COMMAND_RPR: return COMMAND_RPR; + } + + switch(data & ~0x0f03) + { + case H63484_COMMAND_CPY: return COMMAND_CPY; + case H63484_COMMAND_SCPY: return COMMAND_SCPY; + } + + switch(data & ~0x00ff) + { + case H63484_COMMAND_ALINE: return COMMAND_ALINE; + case H63484_COMMAND_RLINE: return COMMAND_RLINE; + case H63484_COMMAND_ARCT: return COMMAND_ARCT; + case H63484_COMMAND_RRCT: return COMMAND_RRCT; + case H63484_COMMAND_APLL: return COMMAND_APLL; + case H63484_COMMAND_RPLL: return COMMAND_RPLL; + case H63484_COMMAND_APLG: return COMMAND_APLG; + case H63484_COMMAND_RPLG: return COMMAND_RPLG; + case H63484_COMMAND_AFRCT: return COMMAND_AFRCT; + case H63484_COMMAND_RFRCT: return COMMAND_RFRCT; + case H63484_COMMAND_DOT: return COMMAND_DOT; + } + + switch(data & ~0x01ff) + { + case H63484_COMMAND_CRCL: return COMMAND_CRCL; + case H63484_COMMAND_ELPS: return COMMAND_ELPS; + case H63484_COMMAND_AARC: return COMMAND_AARC; + case H63484_COMMAND_RARC: return COMMAND_RARC; + case H63484_COMMAND_AEARC: return COMMAND_AEARC; + case H63484_COMMAND_REARC: return COMMAND_REARC; + case H63484_COMMAND_PAINT: return COMMAND_PAINT; + } + + switch(data & ~0x0fff) + { + case H63484_COMMAND_PTN: return COMMAND_PTN; + case H63484_COMMAND_AGCPY: return COMMAND_AGCPY; + case H63484_COMMAND_RGCPY: return COMMAND_RGCPY; + } + + return COMMAND_INVALID; +} + +inline void h63484_device::command_end_seq() +{ + //h63484->param_ptr = 0; + m_sr |= H63484_SR_CED; + + /* TODO: we might need to be more aggressive and clear the params in there */ +} + +void h63484_device::command_wpr_exec() +{ + switch(m_cr & 0x1f) + { + case 0x00: // color 0 + m_cl0 = m_pr[0]; + break; + case 0x01: // color 1 + m_cl1 = m_pr[0]; + break; + case 0x0c: // Read Write Pointer H + m_rwp_dn = (m_pr[0] & 0xc000) >> 14; + m_rwp[m_rwp_dn] = (m_rwp[m_rwp_dn] & 0x00fff) | ((m_pr[0] & 0x00ff) << 12); + break; + case 0x0d: // Read Write Pointer L + m_rwp[m_rwp_dn] = (m_rwp[m_rwp_dn] & 0xff000) | ((m_pr[0] & 0xfff0) >> 4); + break; + default: + if(LOG) printf("%s -> %02x\n",wpr_regnames[m_cr & 0x1f],m_pr[0]); + break; + } +} + +void h63484_device::command_clr_exec() +{ + INT16 ax, ay; + UINT16 d; + INT16 x,y; + int inc_x,inc_y; + UINT32 offset; + UINT8 data_r; + UINT8 res; + + d = m_pr[0]; + ax = m_pr[1]; + ay = m_pr[2]; + + inc_x = (ax < 0) ? -1 : 1; + inc_y = (ay < 0) ? -1 : 1; + + offset = m_rwp[m_rwp_dn] & 0xfffff; + + for(y=0;y!=ay;y+=inc_y) + { + for(x=0;x!=ax;x+=inc_x) + { + offset = (m_rwp[m_rwp_dn] + (x >> 1) + y * m_mwr[m_rwp_dn]) & 0xfffff; /* TODO: address if bpp != 4 */ + data_r = readbyte(offset); + res = (d >> (((x & 2) << 2) ^ 8)) & 0xff; + + switch(m_cr & 3) + { + case 0: // replace + if(x & 1) + res = (res & 0x0f) | (data_r & 0xf0); + else + res = (res & 0xf0) | (data_r & 0x0f); + break; + case 1: // OR + if(x & 1) + res = (res & 0xff) | (data_r & 0xf0); + else + res = (res & 0xff) | (data_r & 0x0f); + break; + case 2: // AND + if(x & 1) + res = (res & 0x0f) | ((res & 0xf0) & (data_r & 0xf0)); + else + res = (res & 0xf0) | ((res & 0x0f) & (data_r & 0x0f)); + break; + case 3: // EOR + if(x & 1) + res = (res & 0x0f) | ((res & 0xf0) ^ (data_r & 0xf0)); + else + res = (res & 0xf0) | ((res & 0x0f) ^ (data_r & 0x0f)); + break; + } + + writebyte(offset,res); + } + } + + m_rwp[m_rwp_dn] = offset; +} + +void h63484_device::command_cpy_exec() +{ + INT16 ax, ay; + UINT32 src_offset,dst_offset; + //int inc_x,inc_y; + + src_offset = ((m_pr[0] & 0xff) << 12) | ((m_pr[1]&0xfff0) >> 4); + ax = m_pr[2]; + ay = m_pr[3]; + + //inc_x = (ax < 0) ? -1 : 1; + //inc_y = (ay < 0) ? -1 : 1; + + dst_offset = m_rwp[m_rwp_dn] & 0xfffff; + + printf("%08x %08x %d %d\n",src_offset,dst_offset,ax,ay); + + // ... +} + +void h63484_device::command_rct_exec() +{ + INT16 dX, dY; + UINT8 col; //, area, opm; + UINT32 offset; + int inc_x,inc_y; + int i; + UINT8 res,data_r; + +// area = (m_cr & 0xe0) >> 5; + col = (m_cr & 0x18) >> 3; +// opm = (m_cr & 0x07); + dX = m_pr[0]; + dY = m_pr[1]; + + offset = m_rwp[m_rwp_dn] & 0xfffff; + + inc_x = (dX < 0) ? -1 : 1; + inc_y = (dY < 0) ? -1 : 1; + + printf("%d %d\n",dX,dY); + + /* + 3<-2 + | ^ + v | + 0->1 + */ + + /* 0 -> 1 */ + for(i=0;i<dX;i+=inc_x) + { + offset = (((i + m_cpx) >> 1) + (0 + m_cpy) * m_mwr[m_rwp_dn]) & 0xfffff; /* TODO: address if bpp != 4 */ + data_r = readbyte(offset); + + if((i + m_cpx) & 1) + res = (col & 0x0f) | (data_r & 0xf0); + else + res = (col & 0xf0) | (data_r & 0x0f); + + writebyte(offset,res); + } + + /* 1 -> 2 */ + for(i=0;i<dY;i+=inc_y) + { + offset = (((dX + m_cpx) >> 1) + (i + m_cpy) * m_mwr[m_rwp_dn]) & 0xfffff; /* TODO: address if bpp != 4 */ + data_r = readbyte(offset); + + if((dX + m_cpx) & 1) + res = (col & 0x0f) | (data_r & 0xf0); + else + res = (col & 0xf0) | (data_r & 0x0f); + + writebyte(offset,res); + } + + /* 2 -> 3 */ + for(i=0;i<dX;i+=inc_x) + { + offset = (((i + m_cpx) >> 1) + (dY + m_cpy) * m_mwr[m_rwp_dn]) & 0xfffff; /* TODO: address if bpp != 4 */ + data_r = readbyte(offset); + + if((i + m_cpx) & 1) + res = (col & 0x0f) | (data_r & 0xf0); + else + res = (col & 0xf0) | (data_r & 0x0f); + + writebyte(offset,res); + } + + /* 3 -> 4 */ + for(i=0;i<dY;i+=inc_y) + { + offset = (((0 + m_cpx) >> 1) + (i + m_cpy) * m_mwr[m_rwp_dn]) & 0xfffff; /* TODO: address if bpp != 4 */ + data_r = readbyte(offset); + + if((0 + m_cpx) & 1) + res = (col & 0x0f) | (data_r & 0xf0); + else + res = (col & 0xf0) | (data_r & 0x0f); + + writebyte(offset,res); + } + + + m_cpx += dX; + m_cpy += dY; +} + +void h63484_device::process_fifo() +{ + UINT8 data; + + dequeue_w(&data); + + if (m_sr & H63484_SR_CED) + { + m_cr = (data & 0xff) << 8; + dequeue_w(&data); + m_cr |= data & 0xff; + m_param_ptr = 0; + m_sr &= ~H63484_SR_CED; + } + else + { + m_pr[m_param_ptr] = (data & 0xff) << 8; + dequeue_w(&data); + m_pr[m_param_ptr] |= (data & 0xff); + m_param_ptr++; + } + + switch (translate_command(m_cr)) + { + case COMMAND_INVALID: + printf("H63484 '%s' Invalid Command Byte %02x\n", tag(), m_cr); + m_sr |= H63484_SR_CER; // command error + break; + + case COMMAND_ORG: + if (m_param_ptr == 2) + { + m_org_dn = (m_pr[0] & 0xc000) >> 14; + m_org_dpa = ((m_pr[0] & 0xff) << 12) | ((m_pr[1] & 0xfff0) >> 4); + m_org_dpd = (m_pr[1] & 0xf); + // TODO: CP = 0 + command_end_seq(); + } + break; + + case COMMAND_WPR: // 0x0800 & ~0x1f + if (m_param_ptr == 1) + { + command_wpr_exec(); + command_end_seq(); + } + break; + + case COMMAND_WPTN: + if(m_param_ptr == 1) + { + m_dn = m_pr[0]; // number of param words + + //if(m_dn > 0x10 || m_dn == 0) + // fatalerror("stop!"); + } + + if(m_param_ptr == (1 + m_dn)) + { + int pra = m_cr & 0xf; + int i; + + for(i=0;i<m_dn;i++) + m_pram[(i + pra) & 0xf] = m_pr[1 + i]; + + command_end_seq(); + } + + break; + + case COMMAND_RD: + if (m_param_ptr == 0) + { + queue_r(readbyte((m_rwp[m_rwp_dn]+0) & 0xfffff)); + queue_r(readbyte((m_rwp[m_rwp_dn]+1) & 0xfffff)); + m_rwp[m_rwp_dn]+=2; + m_rwp[m_rwp_dn]&=0xfffff; + command_end_seq(); + } + break; + + case COMMAND_WT: + if (m_param_ptr == 1) + { + writebyte(((m_rwp[m_rwp_dn]+0) & 0xfffff),(m_pr[0] & 0xff00) >> 8); + writebyte(((m_rwp[m_rwp_dn]+1) & 0xfffff),(m_pr[0] & 0x00ff) >> 0); + m_rwp[m_rwp_dn]+=2; + m_rwp[m_rwp_dn]&=0xfffff; + command_end_seq(); + } + + case COMMAND_CLR: + if (m_param_ptr == 3) + { + command_clr_exec(); + command_end_seq(); + } + break; + + case COMMAND_CPY: + if (m_param_ptr == 4) + { + command_cpy_exec(); + command_end_seq(); + } + break; + + case COMMAND_AMOVE: + if (m_param_ptr == 2) + { + m_cpx = m_pr[0]; + m_cpy = m_pr[1]; + command_end_seq(); + } + break; + + case COMMAND_RRCT: + if (m_param_ptr == 2) + { + command_rct_exec(); + command_end_seq(); + } + break; + + case COMMAND_RMOVE: + if (m_param_ptr == 2) + { + m_cpx += (INT16)m_pr[0]; + m_cpy += (INT16)m_pr[1]; + command_end_seq(); + } + break; + + default: + printf("%04x\n",m_cr); + fatalerror("stop!"); + break; + } +} + +void h63484_device::exec_abort_sequence() +{ + fifo_w_clear(); + fifo_r_clear(); + m_sr = H63484_SR_WFR | H63484_SR_WFE | H63484_SR_CED; // hard-set to 0x23 +} + +UINT16 h63484_device::video_registers_r(int offset) +{ + UINT16 res; + + res = 0; + + switch(offset) + { + case 0x06: + res = m_dcr; + break; + + case 0x80: + res = m_screen->vpos() & 0xfff; // Raster Count + break; + + default: + if(LOG) printf("%s R\n",acrtc_regnames[m_ar/2]); + break; + } + + return res; +} + +void h63484_device::video_registers_w(int offset) +{ + UINT16 vreg_data; + + vreg_data = (m_vreg[offset]<<8)|(m_vreg[offset+1]&0xff); + + switch(offset) + { + case 0x00: // FIFO entry + queue_w((vreg_data & 0xff00) >> 8); + queue_w((vreg_data & 0x00ff) >> 0); + if(FIFO_LOG) printf("%s -> %04x\n",acrtc_regnames[m_ar/2],vreg_data); + process_fifo(); + break; + + case 0x02: // Command Entry + + if(vreg_data & 0x8000) // abort sequence (ABT) + exec_abort_sequence(); + + /* + x--- ---- ---- ---- ABorT + -x-- ---- ---- ---- PauSE + ... + ---- -xxx ---- ---- Graphic Bit Mode (bpp) + ---- ---- xxxx xxxx irq mask, directly correlated to sr + */ + m_ccr = vreg_data; + break; + + case 0x06: + m_dcr = vreg_data; + break; + + case 0x82: // Horizontal Sync Register + m_hc = ((vreg_data & 0xff00) >> 8) + 1; + m_hsw = vreg_data & 0x1f; + recompute_parameters(); + break; + case 0x84: // Horizontal Display Register + m_hds = ((vreg_data & 0xff00) >> 8) + 1; + m_hdw = ((vreg_data & 0x00ff) >> 8) + 1; + recompute_parameters(); + break; + case 0x92: // Horizontal Window Register + m_hws = ((vreg_data & 0xff00) >> 8) + 1; + m_hww = ((vreg_data & 0x00ff) >> 8) + 1; + recompute_parameters(); + break; + + case 0x86: // Vertical Sync Register + m_vc = (vreg_data & 0xfff); + recompute_parameters(); + break; + case 0x88: // Vertical Display Register + m_vds = ((vreg_data & 0xff00) >> 8) + 1; + m_vsw = (vreg_data & 0x1f); + recompute_parameters(); + break; + case 0x94: // Vertical Window Register A + m_vws = (vreg_data & 0xfff) + 1; + recompute_parameters(); + break; + case 0x96: // Vertical Window Register B + m_vww = (vreg_data & 0xfff); + recompute_parameters(); + break; + + case 0xc2: // Memory Width Register + case 0xca: + case 0xd2: + case 0xda: + m_mwr[(offset & 0x18) >> 3] = vreg_data & 0xfff; // pitch + m_mwr_chr[(offset & 0x18) >> 3] = (vreg_data & 0x8000) >> 15; + break; + + case 0xc4: // Start Address Register + case 0xcc: + case 0xd4: + case 0xdc: + m_sar[(offset & 0x18) >> 3] = ((vreg_data & 0xf) << 16) | (m_sar[(offset & 0x18) >> 3] & 0xffff); + m_sda[(offset & 0x18) >> 3] = (vreg_data & 0x0f00) >> 8; + break; + + case 0xc6: // Start Address Register + case 0xce: + case 0xd6: + case 0xde: + m_sar[(offset & 0x18) >> 3] = (vreg_data & 0xffff) | (m_sar[(offset & 0x18) >> 3] & 0xf0000); + break; + + default: + if(LOG) printf("%s -> %04x\n",acrtc_regnames[m_ar/2],vreg_data); + break; + } +} + +READ16_MEMBER( h63484_device::status_r ) +{ + return m_sr; +} + +READ16_MEMBER( h63484_device::data_r ) +{ + int res; + + res = 0xffff; + + if(m_ar == 0) // FIFO read + { + UINT8 data; + + dequeue_r(&data); + res = (data & 0xff) << 8; + dequeue_r(&data); + res |= data & 0xff; + } + else + res = video_registers_r(m_ar); + + return res; +} + +WRITE16_MEMBER( h63484_device::address_w ) +{ + if(ACCESSING_BITS_0_7) + m_ar = data & 0xff; +} + +WRITE16_MEMBER( h63484_device::data_w ) +{ + if(ACCESSING_BITS_8_15) + m_vreg[m_ar] = (data & 0xff00) >> 8; + + if(ACCESSING_BITS_0_7) + m_vreg[m_ar+1] = (data & 0xff); + + video_registers_w(m_ar); + + if(m_ar & 0x80) + { + m_ar+=2; + m_ar &= 0xff; // TODO: what happens if it overflows? + } +} + +void h63484_device::device_start() +{ + m_screen = machine().device<screen_device>(m_screen_tag); + + //h63484->space = device->memory().space(AS_0); + m_vram = auto_alloc_array_clear(machine(), UINT8, 1 << 20); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void h63484_device::device_reset() +{ + // ... +} + +//------------------------------------------------- +// draw_graphics_line - +//------------------------------------------------- + +void h63484_device::draw_graphics_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int y, int layer_n) +{ + int x; + int pitch; + int base_offs; + + pitch = m_mwr[layer_n]; + base_offs = m_sar[layer_n]; + + for(x=0;x<pitch * 4;x+=4) + { + UINT16 data; + + data = readbyte(base_offs + (x >> 1) + y * pitch * 2); + + m_display_cb(this, bitmap, y, x+3, (data >> 4) & 0xf); + m_display_cb(this, bitmap, y, x+2, data & 0xf); + + data = readbyte(base_offs + ((x + 2) >> 1) + y * pitch * 2); + + m_display_cb(this, bitmap, y, x+1, (data >> 4) & 0xf); + m_display_cb(this, bitmap, y, x+0, data & 0xf); + } +} + +//------------------------------------------------- +// update_screen - +//------------------------------------------------- + +UINT32 h63484_device::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + if(m_dcr & 0x8000) // correct? + { + int y; + + for(y=cliprect.min_y;y<cliprect.max_y;y++) + { + if (m_display_cb) + draw_graphics_line(bitmap,cliprect, y, 1); + } + } + return 0; +} |