src/mess/video/tms3556.c
| r13270 | r13271 | |
| 14 | 14 | #include "emu.h" |
| 15 | 15 | #include "tms3556.h" |
| 16 | 16 | |
| 17 | | typedef struct |
| 18 | | { |
| 19 | | /* registers */ |
| 20 | | UINT8 controlRegs[8]; |
| 21 | | UINT16 addressRegs[8]; |
| 22 | | UINT16 writePtr; |
| 23 | | /* register interface */ |
| 24 | | int reg_ptr; |
| 25 | | int reg_access_phase; |
| 26 | | int magical_mystery_flag; |
| 27 | | /* memory */ |
| 28 | | UINT8 *vram; |
| 29 | | int vram_size; |
| 30 | | /* scanline counter */ |
| 31 | | int scanline; |
| 32 | | /* blinking */ |
| 33 | | int blink, blink_count; |
| 34 | | /* background color for current line */ |
| 35 | | int bg_color; |
| 36 | | /* current offset in name table */ |
| 37 | | int name_offset; |
| 38 | | /* c/g flag (mixed mode only) */ |
| 39 | | int cg_flag; |
| 40 | | /* character line counter (decrements from 10, 0 when we have reached last |
| 41 | | line of character row) */ |
| 42 | | int char_line_counter; |
| 43 | | /* double height phase flags (one per horizontal character position) */ |
| 44 | | int dbl_h_phase[40]; |
| 45 | | } vdp_t; |
| 46 | | static vdp_t vdp; |
| 17 | //************************************************************************** |
| 18 | // MACROS / CONSTANTS |
| 19 | //************************************************************************** |
| 47 | 20 | |
| 48 | | #define TOP_BORDER 1 |
| 49 | | #define BOTTOM_BORDER 1 |
| 50 | | #define LEFT_BORDER 8 |
| 51 | | #define RIGHT_BORDER 8 |
| 52 | | #define TOTAL_WIDTH (320 + LEFT_BORDER + RIGHT_BORDER) |
| 53 | | #define TOTAL_HEIGHT (250 + TOP_BORDER + BOTTOM_BORDER) |
| 21 | #define LOG 0 |
| 54 | 22 | |
| 55 | | /* if DOUBLE_WIDTH set, the horizontal resolution is doubled */ |
| 56 | | #define DOUBLE_WIDTH 1 |
| 23 | //************************************************************************** |
| 24 | // GLOBAL VARIABLES |
| 25 | //************************************************************************** |
| 57 | 26 | |
| 58 | | #define TMS3556_MODE_OFF 0 |
| 59 | | #define TMS3556_MODE_TEXT 1 |
| 60 | | #define TMS3556_MODE_BITMAP 2 |
| 61 | | #define TMS3556_MODE_MIXED 3 |
| 27 | // devices |
| 28 | const device_type TMS3556 = &device_creator<tms3556_device>; |
| 62 | 29 | |
| 63 | | /*static const char *const tms3556_mode_names[] = { "DISPLAY OFF", "TEXT", "GRAPHIC", "MIXED" };*/ |
| 64 | 30 | |
| 65 | | static PALETTE_INIT(tms3556); |
| 31 | // default address map |
| 32 | static ADDRESS_MAP_START( tms3556, AS_0, 8 ) |
| 33 | AM_RANGE(0x0000, 0xffff) AM_RAM |
| 34 | ADDRESS_MAP_END |
| 66 | 35 | |
| 36 | //------------------------------------------------- |
| 37 | // memory_space_config - return a description of |
| 38 | // any address spaces owned by this device |
| 39 | //------------------------------------------------- |
| 67 | 40 | |
| 68 | | #if 0 |
| 69 | | #pragma mark BUS INTERFACE |
| 70 | | #endif |
| 71 | | /* |
| 72 | | bus interface |
| 73 | | */ |
| 41 | const address_space_config *tms3556_device::memory_space_config(address_spacenum spacenum) const |
| 42 | { |
| 43 | return (spacenum == AS_0) ? &m_space_config : NULL; |
| 44 | } |
| 74 | 45 | |
| 75 | | /* |
| 76 | | tms3556_vram_r |
| 77 | 46 | |
| 78 | | read a byte from tms3556 VRAM port |
| 79 | | */ |
| 80 | | READ8_HANDLER(tms3556_vram_r) |
| 47 | //************************************************************************** |
| 48 | // INLINE HELPERS |
| 49 | //************************************************************************** |
| 50 | |
| 51 | //------------------------------------------------- |
| 52 | // readbyte - read a byte at the given address |
| 53 | //------------------------------------------------- |
| 54 | |
| 55 | inline UINT8 tms3556_device::readbyte(offs_t address) |
| 81 | 56 | { |
| 82 | | int reply; |
| 57 | return space()->read_byte(address); |
| 58 | } |
| 83 | 59 | |
| 84 | | if (vdp.magical_mystery_flag) |
| 60 | |
| 61 | //------------------------------------------------- |
| 62 | // writebyte - write a byte at the given address |
| 63 | //------------------------------------------------- |
| 64 | |
| 65 | inline void tms3556_device::writebyte(offs_t address, UINT8 data) |
| 66 | { |
| 67 | space()->write_byte(address, data); |
| 68 | } |
| 69 | |
| 70 | |
| 71 | //************************************************************************** |
| 72 | // LIVE DEVICE |
| 73 | //************************************************************************** |
| 74 | |
| 75 | //------------------------------------------------- |
| 76 | // tms3556_device - constructor |
| 77 | //------------------------------------------------- |
| 78 | |
| 79 | tms3556_device::tms3556_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 80 | : device_t(mconfig, TMS3556, "Texas Instruments VDP TMS3556", tag, owner, clock), |
| 81 | device_memory_interface(mconfig, *this), |
| 82 | m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, NULL, *ADDRESS_MAP_NAME(tms3556)), |
| 83 | m_write_ptr(0), |
| 84 | m_reg_ptr(0), |
| 85 | m_reg_access_phase(0), |
| 86 | m_magical_mystery_flag(0), |
| 87 | m_scanline(0) |
| 88 | { |
| 89 | for (int i = 0; i < 8; i++) |
| 85 | 90 | { |
| 86 | | vdp.writePtr = ((vdp.controlRegs[2] << 8) | vdp.controlRegs[1]) + 1; |
| 87 | | vdp.magical_mystery_flag = 0; |
| 91 | m_control_regs[i] = 0; |
| 92 | m_address_regs[i] = 0; |
| 88 | 93 | } |
| 94 | } |
| 89 | 95 | |
| 90 | | reply = vdp.vram[vdp.addressRegs[1]]; |
| 91 | | vdp.addressRegs[1] ++; |
| 92 | 96 | |
| 93 | | return reply; |
| 97 | //------------------------------------------------- |
| 98 | // device_start - device-specific startup |
| 99 | //------------------------------------------------- |
| 100 | |
| 101 | void tms3556_device::device_start() |
| 102 | { |
| 103 | // register for state saving |
| 104 | save_item(NAME(m_control_regs)); |
| 105 | save_item(NAME(m_address_regs)); |
| 106 | save_item(NAME(m_write_ptr)); |
| 107 | save_item(NAME(m_reg_ptr)); |
| 108 | save_item(NAME(m_reg_access_phase)); |
| 109 | save_item(NAME(m_magical_mystery_flag)); |
| 110 | save_item(NAME(m_scanline)); |
| 111 | save_item(NAME(m_blink)); |
| 112 | save_item(NAME(m_blink_count)); |
| 113 | save_item(NAME(m_bg_color)); |
| 114 | save_item(NAME(m_name_offset)); |
| 115 | save_item(NAME(m_cg_flag)); |
| 116 | save_item(NAME(m_char_line_counter)); |
| 117 | save_item(NAME(m_dbl_h_phase)); |
| 94 | 118 | } |
| 95 | 119 | |
| 96 | | /* |
| 97 | | tms3556_vram_w |
| 98 | 120 | |
| 99 | | write a byte to tms3556 VRAM port |
| 100 | | */ |
| 101 | | WRITE8_HANDLER(tms3556_vram_w) |
| 121 | /*static const char *const tms3556_mode_names[] = { "DISPLAY OFF", "TEXT", "GRAPHIC", "MIXED" };*/ |
| 122 | |
| 123 | |
| 124 | //------------------------------------------------- |
| 125 | // vram_r - VRAM read |
| 126 | //------------------------------------------------- |
| 127 | |
| 128 | READ8_MEMBER( tms3556_device::vram_r ) |
| 102 | 129 | { |
| 103 | | if (vdp.magical_mystery_flag) |
| 130 | if (LOG) logerror("TMS3556 VRAM Read: %06x\n", offset); |
| 131 | |
| 132 | if (m_magical_mystery_flag) |
| 104 | 133 | { |
| 105 | | vdp.writePtr = (vdp.controlRegs[2] << 8) | vdp.controlRegs[1]; |
| 106 | | vdp.magical_mystery_flag = 0; |
| 134 | m_write_ptr = ((m_control_regs[2] << 8) | m_control_regs[1]) + 1; |
| 135 | m_magical_mystery_flag = 0; |
| 107 | 136 | } |
| 108 | 137 | |
| 109 | | vdp.vram[vdp.writePtr] = data; |
| 110 | | vdp.writePtr++; |
| 138 | return readbyte(m_address_regs[1]++); |
| 111 | 139 | } |
| 112 | 140 | |
| 113 | | /* |
| 114 | | tms3556_reg_r |
| 141 | //------------------------------------------------- |
| 142 | // vram_w - VRAM write |
| 143 | //------------------------------------------------- |
| 115 | 144 | |
| 116 | | read a byte from tms3556 register port |
| 117 | | */ |
| 118 | | READ8_HANDLER(tms3556_reg_r) |
| 145 | WRITE8_MEMBER( tms3556_device::vram_w ) |
| 119 | 146 | { |
| 147 | if (LOG) logerror("TMS3556 VRAM Write: %06x = %02x\n", offset, data); |
| 148 | |
| 149 | if (m_magical_mystery_flag) |
| 150 | { |
| 151 | m_write_ptr = (m_control_regs[2] << 8) | m_control_regs[1]; |
| 152 | m_magical_mystery_flag = 0; |
| 153 | } |
| 154 | |
| 155 | writebyte(m_write_ptr++, data); |
| 156 | } |
| 157 | |
| 158 | |
| 159 | //------------------------------------------------- |
| 160 | // reg_r - read from register port |
| 161 | //------------------------------------------------- |
| 162 | |
| 163 | READ8_MEMBER( tms3556_device::reg_r ) |
| 164 | { |
| 165 | if (LOG) logerror("TMS3556 Reg Read: %06x\n", offset); |
| 166 | |
| 120 | 167 | int reply = 0; |
| 121 | 168 | |
| 122 | | if (vdp.reg_ptr < 8) |
| 169 | if (m_reg_ptr < 8) |
| 123 | 170 | { |
| 124 | | reply = vdp.controlRegs[vdp.reg_ptr]; |
| 125 | | vdp.reg_access_phase = 0; |
| 171 | reply = m_control_regs[m_reg_ptr]; |
| 172 | m_reg_access_phase = 0; |
| 126 | 173 | } |
| 127 | | /*else |
| 128 | | { // ??? |
| 129 | | }*/ |
| 174 | else |
| 175 | { |
| 176 | // ??? |
| 177 | } |
| 130 | 178 | |
| 131 | 179 | return reply; |
| 132 | 180 | } |
| 133 | 181 | |
| 134 | | /* |
| 135 | | tms3556_reg_w |
| 182 | //------------------------------------------------- |
| 183 | // reg_w - write to register port |
| 184 | //------------------------------------------------- |
| 136 | 185 | |
| 137 | | write a byte to tms3556 register port |
| 138 | | */ |
| 139 | | WRITE8_HANDLER(tms3556_reg_w) |
| 186 | WRITE8_MEMBER( tms3556_device::reg_w ) |
| 140 | 187 | { |
| 141 | | if ((vdp.reg_access_phase == 3) && (data)) |
| 142 | | vdp.reg_access_phase = 0; /* ???????????? */ |
| 143 | | switch (vdp.reg_access_phase) |
| 188 | if (LOG) logerror("TMS3556 Reg Write: %06x = %02x\n", offset, data); |
| 189 | |
| 190 | if ((m_reg_access_phase == 3) && (data)) |
| 191 | m_reg_access_phase = 0; /* ???????????? */ |
| 192 | |
| 193 | switch (m_reg_access_phase) |
| 144 | 194 | { |
| 145 | 195 | case 0: |
| 146 | | vdp.reg_ptr = data & 0x0f; |
| 147 | | vdp.reg_access_phase = 1; |
| 196 | m_reg_ptr = data & 0x0f; |
| 197 | m_reg_access_phase = 1; |
| 148 | 198 | break; |
| 199 | |
| 149 | 200 | case 1: |
| 150 | | if (vdp.reg_ptr < 8) |
| 201 | if (m_reg_ptr < 8) |
| 151 | 202 | { |
| 152 | | vdp.controlRegs[vdp.reg_ptr] = data; |
| 153 | | vdp.reg_access_phase = 0; |
| 154 | | if (vdp.reg_ptr == 2) |
| 155 | | vdp.magical_mystery_flag = 1; |
| 203 | m_control_regs[m_reg_ptr] = data; |
| 204 | m_reg_access_phase = 0; |
| 205 | if (m_reg_ptr == 2) |
| 206 | m_magical_mystery_flag = 1; |
| 156 | 207 | } |
| 157 | | else if (vdp.reg_ptr == 9) |
| 208 | else if (m_reg_ptr == 9) |
| 158 | 209 | { /* I don't understand what is going on, but it is the only way to |
| 159 | 210 | get this to work */ |
| 160 | | vdp.addressRegs[vdp.reg_ptr-8] = ((vdp.controlRegs[2] << 8) | vdp.controlRegs[1]) + 1; |
| 161 | | vdp.reg_access_phase = 0; |
| 162 | | vdp.magical_mystery_flag = 0; |
| 211 | m_address_regs[m_reg_ptr - 8] = ((m_control_regs[2] << 8) | m_control_regs[1]) + 1; |
| 212 | m_reg_access_phase = 0; |
| 213 | m_magical_mystery_flag = 0; |
| 163 | 214 | } |
| 164 | 215 | else |
| 165 | 216 | { |
| 166 | | vdp.addressRegs[vdp.reg_ptr-8] = (vdp.addressRegs[vdp.reg_ptr-8] & 0xff00) | vdp.controlRegs[1]; |
| 167 | | vdp.reg_access_phase = 2; |
| 168 | | vdp.magical_mystery_flag = 0; |
| 217 | m_address_regs[m_reg_ptr - 8] = (m_control_regs[m_reg_ptr - 8] & 0xff00) | m_control_regs[1]; |
| 218 | m_reg_access_phase = 2; |
| 219 | m_magical_mystery_flag = 0; |
| 169 | 220 | } |
| 170 | 221 | break; |
| 222 | |
| 171 | 223 | case 2: |
| 172 | | vdp.addressRegs[vdp.reg_ptr-8] = (vdp.addressRegs[vdp.reg_ptr-8] & 0x00ff) | (vdp.controlRegs[2] << 8); |
| 173 | | if ((vdp.reg_ptr <= 10) || (vdp.reg_ptr == 15)) |
| 174 | | vdp.addressRegs[vdp.reg_ptr-8] ++; |
| 224 | m_address_regs[m_reg_ptr - 8] = (m_control_regs[m_reg_ptr - 8] & 0x00ff) | (m_control_regs[2] << 8); |
| 225 | if ((m_reg_ptr <= 10) || (m_reg_ptr == 15)) |
| 226 | m_address_regs[m_reg_ptr - 8]++; |
| 175 | 227 | else |
| 176 | | vdp.addressRegs[vdp.reg_ptr-8] += 2; |
| 177 | | vdp.reg_access_phase = 3; |
| 228 | m_address_regs[m_reg_ptr - 8] += 2; |
| 229 | m_reg_access_phase = 3; |
| 178 | 230 | break; |
| 231 | |
| 179 | 232 | case 3: |
| 180 | | vdp.reg_access_phase = 0; |
| 233 | m_reg_access_phase = 0; |
| 181 | 234 | break; |
| 182 | 235 | } |
| 183 | 236 | } |
| 184 | 237 | |
| 185 | 238 | |
| 186 | | #if 0 |
| 187 | | #pragma mark - |
| 188 | | #pragma mark INITIALIZATION CODE |
| 189 | | #endif |
| 190 | | /* |
| 191 | | initialization code |
| 192 | | */ |
| 239 | //------------------------------------------------- |
| 240 | // redraw code |
| 241 | //------------------------------------------------- |
| 193 | 242 | |
| 194 | | /* |
| 195 | | MCFG_tms3556 |
| 196 | 243 | |
| 197 | | machine struct initialization helper |
| 198 | | */ |
| 199 | | MACHINE_CONFIG_FRAGMENT( tms3556 ) |
| 200 | | /* video hardware */ |
| 201 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 202 | | MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) |
| 203 | | MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 204 | | #if DOUBLE_WIDTH |
| 205 | | MCFG_SCREEN_SIZE(TOTAL_WIDTH*2, TOTAL_HEIGHT*2) |
| 206 | | MCFG_SCREEN_VISIBLE_AREA(0, TOTAL_WIDTH*2-1, 0, TOTAL_HEIGHT*2-1) |
| 207 | | #else |
| 208 | | MCFG_SCREEN_SIZE(TOTAL_WIDTH, TOTAL_HEIGHT*2) |
| 209 | | MCFG_SCREEN_VISIBLE_AREA(0, TOTAL_WIDTH-1, 0, TOTAL_HEIGHT*2-1) |
| 210 | | #endif |
| 211 | | MCFG_SCREEN_UPDATE(generic_bitmapped) |
| 212 | | MCFG_PALETTE_LENGTH(8) |
| 213 | | MCFG_PALETTE_INIT(tms3556) |
| 244 | //------------------------------------------------- |
| 245 | // draw_line_empty - draw an empty line (used for |
| 246 | // top and bottom borders, and screen off mode) |
| 247 | //------------------------------------------------- |
| 214 | 248 | |
| 215 | | MCFG_VIDEO_START(generic_bitmapped) |
| 216 | | MACHINE_CONFIG_END |
| 217 | | |
| 218 | | |
| 219 | | /* |
| 220 | | PALETTE_INIT( tms3556 ) |
| 221 | | |
| 222 | | Create our 8-color RGB palette |
| 223 | | */ |
| 224 | | static PALETTE_INIT( tms3556 ) |
| 249 | void tms3556_device::draw_line_empty(UINT16 *ln) |
| 225 | 250 | { |
| 226 | | int i, red, green, blue; |
| 227 | | |
| 228 | | /* create the 8 color palette */ |
| 229 | | for (i=0;i<8;i++) |
| 230 | | { |
| 231 | | red = (i & 1) ? 255 : 0; /* red */ |
| 232 | | green = (i & 2) ? 255 : 0; /* green */ |
| 233 | | blue = (i & 4) ? 255 : 0; /* blue */ |
| 234 | | palette_set_color_rgb(machine, i, red, green, blue); |
| 235 | | } |
| 236 | | } |
| 237 | | |
| 238 | | /* |
| 239 | | tms3556_init |
| 240 | | |
| 241 | | tms3556 core init (called at video init time) |
| 242 | | */ |
| 243 | | void tms3556_init(running_machine &machine, int vram_size) |
| 244 | | { |
| 245 | | memset(&vdp, 0, sizeof (vdp)); |
| 246 | | |
| 247 | | vdp.vram_size = vram_size; |
| 248 | | |
| 249 | | /* allocate VRAM */ |
| 250 | | vdp.vram = auto_alloc_array(machine, UINT8, 0x10000); |
| 251 | | memset (vdp.vram, 0, 0x10000); |
| 252 | | if (vdp.vram_size < 0x10000) |
| 253 | | { |
| 254 | | /* set unavailable RAM to 0xff */ |
| 255 | | memset(vdp.vram + vdp.vram_size, 0xff, (0x10000 - vdp.vram_size) ); |
| 256 | | } |
| 257 | | } |
| 258 | | |
| 259 | | /* |
| 260 | | tms3556_reset |
| 261 | | |
| 262 | | tms3556 reset (should be called at machine init time) |
| 263 | | */ |
| 264 | | void tms3556_reset(void) |
| 265 | | { |
| 266 | | int i; |
| 267 | | |
| 268 | | /* register reset */ |
| 269 | | for (i=0;i<8;i++) |
| 270 | | { |
| 271 | | vdp.controlRegs[i] = 0; |
| 272 | | vdp.addressRegs[i] = 0; |
| 273 | | } |
| 274 | | vdp.writePtr = 0; |
| 275 | | vdp.reg_ptr = 0; |
| 276 | | vdp.reg_access_phase = 0; |
| 277 | | vdp.magical_mystery_flag = 0; |
| 278 | | vdp.scanline = 0; |
| 279 | | } |
| 280 | | |
| 281 | | |
| 282 | | #if 0 |
| 283 | | #pragma mark - |
| 284 | | #pragma mark REDRAW CODE |
| 285 | | #endif |
| 286 | | /* |
| 287 | | redraw code |
| 288 | | */ |
| 289 | | |
| 290 | | /* |
| 291 | | tms3556_draw_line_empty |
| 292 | | |
| 293 | | draw an empty line (used for top and bottom borders, and screen off mode) |
| 294 | | */ |
| 295 | | static void tms3556_draw_line_empty(UINT16 *ln) |
| 296 | | { |
| 297 | 251 | int i; |
| 298 | 252 | |
| 299 | | for (i=0; i<TOTAL_WIDTH; i++) |
| 300 | | #if DOUBLE_WIDTH |
| 301 | | *ln++ = vdp.bg_color; |
| 253 | for (i = 0; i < TMS3556_TOTAL_WIDTH; i++) |
| 254 | #if TMS3556_DOUBLE_WIDTH |
| 255 | *ln++ = m_bg_color; |
| 302 | 256 | #endif |
| 303 | | *ln++ = vdp.bg_color; |
| 257 | *ln++ = m_bg_color; |
| 304 | 258 | } |
| 305 | 259 | |
| 306 | | /* |
| 307 | | tms3556_draw_line_text_common |
| 308 | 260 | |
| 309 | | draw a line of text (called by tms3556_draw_line_text and |
| 310 | | tms3556_draw_line_mixed) |
| 311 | | */ |
| 312 | | static void tms3556_draw_line_text_common(UINT16 *ln) |
| 261 | //------------------------------------------------- |
| 262 | // draw_line_text_common - draw a line of text |
| 263 | // (called by draw_line_text and draw_line_mixed) |
| 264 | //------------------------------------------------- |
| 265 | |
| 266 | void tms3556_device::draw_line_text_common(UINT16 *ln) |
| 313 | 267 | { |
| 314 | 268 | int pattern, x, xx, i, name_offset; |
| 315 | 269 | UINT16 fg, bg; |
| 316 | | UINT8 *nametbl, *patterntbl[4]; |
| 270 | offs_t nametbl_base; |
| 271 | offs_t patterntbl_base[4]; |
| 317 | 272 | int name_hi, name_lo; |
| 318 | 273 | int pattern_ix; |
| 319 | 274 | int alphanumeric_mode, dbl_w, dbl_h, dbl_w_phase = 0; |
| 320 | 275 | |
| 276 | nametbl_base = m_address_regs[2]; |
| 277 | for (i = 0; i < 4; i++) |
| 278 | patterntbl_base[i] = m_address_regs[i + 3]; |
| 321 | 279 | |
| 322 | | nametbl = vdp.vram + vdp.addressRegs[2]; |
| 323 | | for (i=0; i<4; i++) |
| 324 | | patterntbl[i] = vdp.vram + vdp.addressRegs[i+3]; |
| 325 | | |
| 326 | | for (xx=0; xx<LEFT_BORDER; xx++) |
| 327 | | #if DOUBLE_WIDTH |
| 328 | | *ln++ = vdp.bg_color; |
| 280 | for (xx = 0; xx < TMS3556_LEFT_BORDER; xx++) |
| 281 | #if TMS3556_DOUBLE_WIDTH |
| 282 | *ln++ = m_bg_color; |
| 329 | 283 | #endif |
| 330 | | *ln++ = vdp.bg_color; |
| 284 | *ln++ = m_bg_color; |
| 331 | 285 | |
| 332 | | name_offset = vdp.name_offset; |
| 286 | name_offset = m_name_offset; |
| 333 | 287 | |
| 334 | | for (x=0;x<40;x++) |
| 288 | for (x = 0; x < 40; x++) |
| 335 | 289 | { |
| 336 | | name_hi = nametbl[name_offset]; |
| 337 | | name_lo = nametbl[name_offset+1]; |
| 290 | name_hi = readbyte(nametbl_base + name_offset); |
| 291 | name_lo = readbyte(nametbl_base + name_offset + 1); |
| 338 | 292 | pattern_ix = ((name_hi >> 2) & 2) | ((name_hi >> 4) & 1); |
| 339 | | alphanumeric_mode = (pattern_ix < 2) || ((pattern_ix == 3) && !(vdp.controlRegs[7] & 0x08)); |
| 293 | alphanumeric_mode = (pattern_ix < 2) || ((pattern_ix == 3) && !(m_control_regs[7] & 0x08)); |
| 340 | 294 | fg = (name_hi >> 5) & 0x7; |
| 341 | 295 | if (alphanumeric_mode) |
| 342 | 296 | { |
| 343 | 297 | if (name_hi & 4) |
| 344 | 298 | { /* inverted color */ |
| 345 | 299 | bg = fg; |
| 346 | | fg = vdp.bg_color; |
| 300 | fg = m_bg_color; |
| 347 | 301 | } |
| 348 | 302 | else |
| 349 | | bg = vdp.bg_color; |
| 303 | bg = m_bg_color; |
| 350 | 304 | dbl_w = name_hi & 0x2; |
| 351 | 305 | dbl_h = name_hi & 0x1; |
| 352 | 306 | } |
| r13270 | r13271 | |
| 356 | 310 | dbl_w = 0; |
| 357 | 311 | dbl_h = 0; |
| 358 | 312 | } |
| 359 | | if ((name_lo & 0x80) && vdp.blink) |
| 313 | if ((name_lo & 0x80) && m_blink) |
| 360 | 314 | fg = bg; /* blink off time */ |
| 361 | 315 | if (! dbl_h) |
| 362 | 316 | { /* single height */ |
| 363 | | pattern = patterntbl[pattern_ix][(name_lo & 0x7f) + 128*vdp.char_line_counter]; |
| 364 | | if (vdp.char_line_counter == 0) |
| 365 | | vdp.dbl_h_phase[x] = 0; |
| 317 | pattern = readbyte(patterntbl_base[pattern_ix] + (name_lo & 0x7f) + 128 * m_char_line_counter); |
| 318 | if (m_char_line_counter == 0) |
| 319 | m_dbl_h_phase[x] = 0; |
| 366 | 320 | } |
| 367 | 321 | else |
| 368 | 322 | { /* double height */ |
| 369 | | if (! vdp.dbl_h_phase[x]) |
| 323 | if (! m_dbl_h_phase[x]) |
| 370 | 324 | /* first phase: pattern from upper half */ |
| 371 | | pattern = patterntbl[pattern_ix][(name_lo & 0x7f) + 128*(5+(vdp.char_line_counter>>1))]; |
| 325 | pattern = readbyte(patterntbl_base[pattern_ix] + (name_lo & 0x7f) + 128 * (5 + (m_char_line_counter >> 1))); |
| 372 | 326 | else |
| 373 | 327 | /* second phase: pattern from lower half */ |
| 374 | | pattern = patterntbl[pattern_ix][(name_lo & 0x7f) + 128*(vdp.char_line_counter>>1)]; |
| 375 | | if (vdp.char_line_counter == 0) |
| 376 | | vdp.dbl_h_phase[x] = ! vdp.dbl_h_phase[x]; |
| 328 | pattern = readbyte(patterntbl_base[pattern_ix] + (name_lo & 0x7f) + 128 * (m_char_line_counter >> 1)); |
| 329 | if (m_char_line_counter == 0) |
| 330 | m_dbl_h_phase[x] = !m_dbl_h_phase[x]; |
| 377 | 331 | } |
| 378 | | if (! dbl_w) |
| 332 | if (!dbl_w) |
| 379 | 333 | { /* single width */ |
| 380 | | for (xx=0;xx<8;xx++) |
| 334 | for (xx = 0; xx < 8; xx++) |
| 381 | 335 | { |
| 382 | 336 | UINT16 color = (pattern & 0x80) ? fg : bg; |
| 383 | | #if DOUBLE_WIDTH |
| 337 | #if TMS3556_DOUBLE_WIDTH |
| 384 | 338 | *ln++ = color; |
| 385 | 339 | #endif |
| 386 | | *ln++ = color; |
| 340 | *ln++ = color; |
| 387 | 341 | pattern <<= 1; |
| 388 | 342 | } |
| 389 | 343 | dbl_w_phase = 0; |
| r13270 | r13271 | |
| 393 | 347 | if (dbl_w_phase) |
| 394 | 348 | /* second phase: display right half */ |
| 395 | 349 | pattern <<= 4; |
| 396 | | for (xx=0;xx<4;xx++) |
| 350 | for (xx = 0; xx < 4; xx++) |
| 397 | 351 | { |
| 398 | 352 | UINT16 color = (pattern & 0x80) ? fg : bg; |
| 399 | | #if DOUBLE_WIDTH |
| 353 | #if TMS3556_DOUBLE_WIDTH |
| 400 | 354 | *ln++ = color; *ln++ = color; |
| 401 | 355 | #endif |
| 402 | | *ln++ = color; *ln++ = color; |
| 356 | *ln++ = color; *ln++ = color; |
| 403 | 357 | pattern <<= 1; |
| 404 | 358 | } |
| 405 | 359 | dbl_w_phase = !dbl_w_phase; |
| r13270 | r13271 | |
| 407 | 361 | name_offset += 2; |
| 408 | 362 | } |
| 409 | 363 | |
| 410 | | for (xx=0; xx<RIGHT_BORDER; xx++) |
| 411 | | #if DOUBLE_WIDTH |
| 412 | | *ln++ = vdp.bg_color; |
| 364 | for (xx = 0; xx < TMS3556_RIGHT_BORDER; xx++) |
| 365 | #if TMS3556_DOUBLE_WIDTH |
| 366 | *ln++ = m_bg_color; |
| 413 | 367 | #endif |
| 414 | | *ln++ = vdp.bg_color; |
| 368 | *ln++ = m_bg_color; |
| 415 | 369 | |
| 416 | | if (vdp.char_line_counter == 0) |
| 417 | | vdp.name_offset = name_offset; |
| 370 | if (m_char_line_counter == 0) |
| 371 | m_name_offset = name_offset; |
| 418 | 372 | } |
| 419 | 373 | |
| 420 | | /* |
| 421 | | tms3556_draw_line_bitmap_common |
| 422 | 374 | |
| 423 | | draw a line of bitmap (called by tms3556_draw_line_bitmap and |
| 424 | | tms3556_draw_line_mixed) |
| 425 | | */ |
| 426 | | static void tms3556_draw_line_bitmap_common(UINT16 *ln) |
| 375 | //------------------------------------------------- |
| 376 | // draw_line_bitmap_common - draw a line of bitmap |
| 377 | // (called by draw_line_bitmap and draw_line_mixed) |
| 378 | //------------------------------------------------- |
| 379 | |
| 380 | void tms3556_device::draw_line_bitmap_common(UINT16 *ln) |
| 427 | 381 | { |
| 428 | 382 | int x, xx; |
| 429 | | UINT8 *nametbl; |
| 383 | offs_t nametbl_base; |
| 430 | 384 | int name_b, name_g, name_r; |
| 431 | 385 | |
| 386 | nametbl_base = m_address_regs[2]; |
| 432 | 387 | |
| 433 | | nametbl = vdp.vram + vdp.addressRegs[2]; |
| 434 | | |
| 435 | | for (xx=0; xx<LEFT_BORDER; xx++) |
| 436 | | #if DOUBLE_WIDTH |
| 437 | | *ln++ = vdp.bg_color; |
| 388 | for (xx = 0; xx < TMS3556_LEFT_BORDER; xx++) |
| 389 | #if TMS3556_DOUBLE_WIDTH |
| 390 | *ln++ = m_bg_color; |
| 438 | 391 | #endif |
| 439 | | *ln++ = vdp.bg_color; |
| 392 | *ln++ = m_bg_color; |
| 440 | 393 | |
| 441 | | for (x=0;x<40;x++) |
| 394 | for (x = 0; x < 40; x++) |
| 442 | 395 | { |
| 443 | | name_b = nametbl[vdp.name_offset]; |
| 444 | | name_g = nametbl[vdp.name_offset+1]; |
| 445 | | name_r = nametbl[vdp.name_offset+2]; |
| 446 | | for (xx=0;xx<8;xx++) |
| 396 | name_b = readbyte(nametbl_base + m_name_offset); |
| 397 | name_g = readbyte(nametbl_base + m_name_offset + 1); |
| 398 | name_r = readbyte(nametbl_base + m_name_offset + 2); |
| 399 | for (xx = 0; xx < 8; xx++) |
| 447 | 400 | { |
| 448 | 401 | UINT16 color = ((name_b >> 5) & 0x4) | ((name_g >> 6) & 0x2) | ((name_r >> 7) & 0x1); |
| 449 | | #if DOUBLE_WIDTH |
| 402 | #if TMS3556_DOUBLE_WIDTH |
| 450 | 403 | *ln++ = color; |
| 451 | 404 | #endif |
| 452 | | *ln++ = color; |
| 405 | *ln++ = color; |
| 453 | 406 | name_b <<= 1; |
| 454 | 407 | name_g <<= 1; |
| 455 | 408 | name_r <<= 1; |
| 456 | 409 | } |
| 457 | | vdp.name_offset += 3; |
| 410 | m_name_offset += 3; |
| 458 | 411 | } |
| 459 | 412 | |
| 460 | | for (xx=0; xx<RIGHT_BORDER; xx++) |
| 461 | | #if DOUBLE_WIDTH |
| 462 | | *ln++ = vdp.bg_color; |
| 413 | for (xx = 0; xx < TMS3556_RIGHT_BORDER; xx++) |
| 414 | #if TMS3556_DOUBLE_WIDTH |
| 415 | *ln++ = m_bg_color; |
| 463 | 416 | #endif |
| 464 | | *ln++ = vdp.bg_color; |
| 417 | *ln++ = m_bg_color; |
| 465 | 418 | } |
| 466 | 419 | |
| 467 | | /* |
| 468 | | tms3556_draw_line_text |
| 469 | 420 | |
| 470 | | draw a line in text mode |
| 471 | | */ |
| 472 | | static void tms3556_draw_line_text(UINT16 *ln) |
| 421 | //------------------------------------------------- |
| 422 | // draw_line_text - draw a line in text mode |
| 423 | //------------------------------------------------- |
| 424 | |
| 425 | void tms3556_device::draw_line_text(UINT16 *ln) |
| 473 | 426 | { |
| 474 | | if (vdp.char_line_counter == 0) |
| 475 | | vdp.char_line_counter = 10; |
| 476 | | vdp.char_line_counter--; |
| 477 | | tms3556_draw_line_text_common(ln); |
| 427 | if (m_char_line_counter == 0) |
| 428 | m_char_line_counter = 10; |
| 429 | m_char_line_counter--; |
| 430 | draw_line_text_common(ln); |
| 478 | 431 | } |
| 479 | 432 | |
| 480 | | /* |
| 481 | | tms3556_draw_line_bitmap |
| 482 | 433 | |
| 483 | | draw a line in bitmap mode |
| 484 | | */ |
| 485 | | static void tms3556_draw_line_bitmap(UINT16 *ln) |
| 486 | | { |
| 487 | | UINT8 *nametbl; |
| 434 | //------------------------------------------------- |
| 435 | // draw_line_bitmap - draw a line in bitmap mode |
| 436 | //------------------------------------------------- |
| 488 | 437 | |
| 489 | | |
| 490 | | tms3556_draw_line_bitmap_common(ln); |
| 491 | | nametbl = vdp.vram + vdp.addressRegs[2]; |
| 492 | | vdp.bg_color = (nametbl[vdp.name_offset] >> 5) & 0x7; |
| 493 | | vdp.name_offset += 2; |
| 438 | void tms3556_device::draw_line_bitmap(UINT16 *ln) |
| 439 | { |
| 440 | draw_line_bitmap_common(ln); |
| 441 | m_bg_color = (readbyte(m_address_regs[2] + m_name_offset) >> 5) & 0x7; |
| 442 | m_name_offset += 2; |
| 494 | 443 | } |
| 495 | 444 | |
| 496 | | /* |
| 497 | | tms3556_draw_line_mixed |
| 498 | 445 | |
| 499 | | draw a line in mixed mode |
| 500 | | */ |
| 501 | | static void tms3556_draw_line_mixed(UINT16 *ln) |
| 502 | | { |
| 503 | | UINT8 *nametbl; |
| 446 | //------------------------------------------------- |
| 447 | // draw_line_mixed - draw a line in mixed mode |
| 448 | //------------------------------------------------- |
| 504 | 449 | |
| 505 | | |
| 506 | | if (vdp.cg_flag) |
| 450 | void tms3556_device::draw_line_mixed(UINT16 *ln) |
| 451 | { |
| 452 | if (m_cg_flag) |
| 507 | 453 | { /* bitmap line */ |
| 508 | | tms3556_draw_line_bitmap_common(ln); |
| 509 | | nametbl = vdp.vram + vdp.addressRegs[2]; |
| 510 | | vdp.bg_color = (nametbl[vdp.name_offset] >> 5) & 0x7; |
| 511 | | vdp.cg_flag = (nametbl[vdp.name_offset] >> 4) & 0x1; |
| 512 | | vdp.name_offset += 2; |
| 454 | draw_line_bitmap_common(ln); |
| 455 | m_bg_color = (readbyte(m_address_regs[2] + m_name_offset) >> 5) & 0x7; |
| 456 | m_cg_flag = (readbyte(m_address_regs[2] + m_name_offset) >> 4) & 0x1; |
| 457 | m_name_offset += 2; |
| 513 | 458 | } |
| 514 | 459 | else |
| 515 | 460 | { /* text line */ |
| 516 | | if (vdp.char_line_counter == 0) |
| 517 | | vdp.char_line_counter = 10; |
| 518 | | vdp.char_line_counter--; |
| 519 | | tms3556_draw_line_text_common(ln); |
| 520 | | if (vdp.char_line_counter == 0) |
| 461 | if (m_char_line_counter == 0) |
| 462 | m_char_line_counter = 10; |
| 463 | m_char_line_counter--; |
| 464 | draw_line_text_common(ln); |
| 465 | if (m_char_line_counter == 0) |
| 521 | 466 | { |
| 522 | | nametbl = vdp.vram + vdp.addressRegs[2]; |
| 523 | | vdp.bg_color = (nametbl[vdp.name_offset] >> 5) & 0x7; |
| 524 | | vdp.cg_flag = (nametbl[vdp.name_offset] >> 4) & 0x1; |
| 525 | | vdp.name_offset += 2; |
| 467 | m_bg_color = (readbyte(m_address_regs[2] + m_name_offset) >> 5) & 0x7; |
| 468 | m_cg_flag = (readbyte(m_address_regs[2] + m_name_offset) >> 4) & 0x1; |
| 469 | m_name_offset += 2; |
| 526 | 470 | } |
| 527 | 471 | } |
| 528 | 472 | } |
| 529 | 473 | |
| 530 | | /* |
| 531 | | tms3556_draw_line |
| 532 | 474 | |
| 533 | | draw a line. If non-interlaced mode, duplicate the line. |
| 534 | | */ |
| 535 | | static void tms3556_draw_line(bitmap_t *bmp, int line) |
| 475 | //------------------------------------------------- |
| 476 | // draw_line - draw a line. If non-interlaced mode, |
| 477 | // duplicate the line. |
| 478 | //------------------------------------------------- |
| 479 | |
| 480 | void tms3556_device::draw_line(bitmap_t *bmp, int line) |
| 536 | 481 | { |
| 537 | | int double_lines; |
| 482 | int double_lines = 0; |
| 538 | 483 | UINT16 *ln, *ln2 = NULL; |
| 539 | 484 | |
| 540 | | double_lines = 0; |
| 541 | | |
| 542 | | #if 0 |
| 543 | | if ( vdp.controlRegs[4] & 0x?? ) |
| 544 | | { // interlaced mode |
| 545 | | ln = BITMAP_ADDR16(bmp, line, vdp.field); |
| 546 | | } |
| 547 | | else |
| 548 | | #endif |
| 485 | // if (m_control_regs[4] & 0x??) |
| 486 | // { // interlaced mode |
| 487 | // ln = BITMAP_ADDR16(bmp, line, m_field); |
| 488 | // } |
| 489 | // else |
| 549 | 490 | { /* non-interlaced mode */ |
| 550 | 491 | ln = BITMAP_ADDR16(bmp, line, 0); |
| 551 | 492 | ln2 = BITMAP_ADDR16(bmp, line, 1); |
| 552 | 493 | double_lines = 1; |
| 553 | 494 | } |
| 554 | 495 | |
| 555 | | if ((line < TOP_BORDER) || (line >= (TOP_BORDER + 250))) |
| 556 | | { /* draw top and bottom borders */ |
| 557 | | tms3556_draw_line_empty(ln); |
| 496 | if ((line < TMS3556_TOP_BORDER) || (line >= (TMS3556_TOP_BORDER + 250))) |
| 497 | { |
| 498 | /* draw top and bottom borders */ |
| 499 | draw_line_empty(ln); |
| 558 | 500 | } |
| 559 | 501 | else |
| 560 | | { /* draw useful area */ |
| 561 | | switch (vdp.controlRegs[6] >> 6) |
| 502 | { |
| 503 | /* draw useful area */ |
| 504 | switch (m_control_regs[6] >> 6) |
| 562 | 505 | { |
| 563 | 506 | case TMS3556_MODE_OFF: |
| 564 | | tms3556_draw_line_empty(ln); |
| 507 | draw_line_empty(ln); |
| 565 | 508 | break; |
| 566 | 509 | case TMS3556_MODE_TEXT: |
| 567 | | tms3556_draw_line_text(ln); |
| 510 | draw_line_text(ln); |
| 568 | 511 | break; |
| 569 | 512 | case TMS3556_MODE_BITMAP: |
| 570 | | tms3556_draw_line_bitmap(ln); |
| 513 | draw_line_bitmap(ln); |
| 571 | 514 | break; |
| 572 | 515 | case TMS3556_MODE_MIXED: |
| 573 | | tms3556_draw_line_mixed(ln); |
| 516 | draw_line_mixed(ln); |
| 574 | 517 | break; |
| 575 | 518 | } |
| 576 | 519 | } |
| 577 | 520 | |
| 578 | 521 | if (double_lines) |
| 579 | | memcpy (ln2, ln, TOTAL_WIDTH*(DOUBLE_WIDTH ? 2 : 1) * 2); |
| 522 | memcpy (ln2, ln, TMS3556_TOTAL_WIDTH * (TMS3556_DOUBLE_WIDTH ? 2 : 1) * 2); |
| 580 | 523 | } |
| 581 | 524 | |
| 582 | 525 | |
| 583 | | /* |
| 584 | | tms3556_interrupt_start_vblank |
| 526 | //------------------------------------------------- |
| 527 | // interrupt_start_vblank - Do vblank-time tasks |
| 528 | //------------------------------------------------- |
| 585 | 529 | |
| 586 | | Do vblank-time tasks |
| 587 | | */ |
| 588 | | static void tms3556_interrupt_start_vblank(void) |
| 530 | void tms3556_device::interrupt_start_vblank(void) |
| 589 | 531 | { |
| 590 | | int i; |
| 591 | | |
| 592 | | |
| 593 | 532 | /* at every frame, vdp switches fields */ |
| 594 | | //vdp.field = !vdp.field; |
| 533 | //m_field = !m_field; |
| 595 | 534 | |
| 596 | 535 | /* color blinking */ |
| 597 | | if (vdp.blink_count) |
| 598 | | vdp.blink_count--; |
| 599 | | if (!vdp.blink_count) |
| 536 | if (m_blink_count) |
| 537 | m_blink_count--; |
| 538 | if (!m_blink_count) |
| 600 | 539 | { |
| 601 | | vdp.blink = !vdp.blink; |
| 602 | | vdp.blink_count = 60; /*no idea what the real value is*/ |
| 540 | m_blink = !m_blink; |
| 541 | m_blink_count = 60; /*no idea what the real value is*/ |
| 603 | 542 | } |
| 604 | 543 | /* reset background color */ |
| 605 | | vdp.bg_color = (vdp.controlRegs[7] >> 5) & 0x7; |
| 544 | m_bg_color = (m_control_regs[7] >> 5) & 0x7; |
| 606 | 545 | /* reset name offset */ |
| 607 | | vdp.name_offset = 0; |
| 546 | m_name_offset = 0; |
| 608 | 547 | /* reset character line counter */ |
| 609 | | vdp.char_line_counter = 0; |
| 548 | m_char_line_counter = 0; |
| 610 | 549 | /* reset c/g flag */ |
| 611 | | vdp.cg_flag = 0; |
| 550 | m_cg_flag = 0; |
| 612 | 551 | /* reset double height phase flags */ |
| 613 | | for (i=0; i<40; i++) |
| 614 | | vdp.dbl_h_phase[i] = 0; |
| 552 | memset(m_dbl_h_phase, 0, sizeof(m_dbl_h_phase)); |
| 615 | 553 | } |
| 616 | 554 | |
| 617 | | /* |
| 618 | | tms3556_interrupt |
| 619 | 555 | |
| 620 | | scanline handler |
| 621 | | */ |
| 622 | | void tms3556_interrupt(running_machine &machine) |
| 556 | //------------------------------------------------- |
| 557 | // interrupt - scanline handler |
| 558 | //------------------------------------------------- |
| 559 | |
| 560 | void tms3556_device::interrupt(running_machine &machine) |
| 623 | 561 | { |
| 624 | 562 | /* check for start of vblank */ |
| 625 | | if (vdp.scanline == 310) /*no idea what the real value is*/ |
| 626 | | tms3556_interrupt_start_vblank(); |
| 563 | if (m_scanline == 310) /*no idea what the real value is*/ |
| 564 | interrupt_start_vblank(); |
| 627 | 565 | |
| 628 | 566 | /* render the current line */ |
| 629 | | if ((vdp.scanline >= 0) && (vdp.scanline < TOTAL_HEIGHT)) |
| 567 | if ((m_scanline >= 0) && (m_scanline < TMS3556_TOTAL_HEIGHT)) |
| 630 | 568 | { |
| 631 | 569 | //if (!video_skip_this_frame()) |
| 632 | | tms3556_draw_line(machine.generic.tmpbitmap, vdp.scanline); |
| 570 | draw_line(machine.generic.tmpbitmap, m_scanline); |
| 633 | 571 | } |
| 634 | 572 | |
| 635 | | if (++vdp.scanline == 313) |
| 636 | | vdp.scanline = 0; |
| 573 | if (++m_scanline == 313) |
| 574 | m_scanline = 0; |
| 637 | 575 | } |
| 638 | | |
src/mess/drivers/exelv.c
| r13270 | r13271 | |
| 49 | 49 | * everything |
| 50 | 50 | */ |
| 51 | 51 | |
| 52 | #define ADDRESS_MAP_MODERN |
| 53 | |
| 52 | 54 | #include "emu.h" |
| 53 | 55 | #include "deprecat.h" |
| 54 | 56 | #include "cpu/tms7000/tms7000.h" |
| 55 | 57 | #include "video/tms3556.h" |
| 56 | 58 | #include "sound/tms5220.h" |
| 57 | 59 | #include "audio/spchroms.h" |
| 58 | | /*#include "imagedev/cartslot.h" |
| 59 | | #include "imagedev/cassette.h"*/ |
| 60 | //#include "imagedev/cartslot.h" |
| 61 | //#include "imagedev/cassette.h" |
| 60 | 62 | |
| 61 | 63 | |
| 62 | 64 | class exelv_state : public driver_device |
| 63 | 65 | { |
| 64 | 66 | public: |
| 65 | 67 | exelv_state(const machine_config &mconfig, device_type type, const char *tag) |
| 66 | | : driver_device(mconfig, type, tag) { } |
| 68 | : driver_device(mconfig, type, tag), |
| 69 | m_maincpu(*this, "maincpu"), |
| 70 | m_tms3556(*this, "tms3556"), |
| 71 | m_tms5220c(*this, "tms5220c") |
| 72 | { } |
| 67 | 73 | |
| 74 | required_device<cpu_device> m_maincpu; |
| 75 | required_device<tms3556_device> m_tms3556; |
| 76 | required_device<tms5220c_device> m_tms5220c; |
| 77 | |
| 78 | virtual void machine_start(); |
| 79 | virtual void machine_reset(); |
| 80 | |
| 81 | virtual void video_start(); |
| 82 | |
| 83 | DECLARE_READ8_MEMBER( mailbox_wx319_r ); |
| 84 | DECLARE_WRITE8_MEMBER( mailbox_wx318_w ); |
| 85 | DECLARE_READ8_MEMBER( tms7020_porta_r ); |
| 86 | DECLARE_WRITE8_MEMBER( tms7020_porta_w ); |
| 87 | DECLARE_READ8_MEMBER( tms7020_portb_r ); |
| 88 | DECLARE_WRITE8_MEMBER( tms7020_portb_w ); |
| 89 | DECLARE_READ8_MEMBER( tms7041_porta_r ); |
| 90 | DECLARE_WRITE8_MEMBER( tms7041_porta_w ); |
| 91 | DECLARE_READ8_MEMBER( tms7041_portb_r ); |
| 92 | DECLARE_WRITE8_MEMBER( tms7041_portb_w ); |
| 93 | DECLARE_READ8_MEMBER( tms7041_portc_r ); |
| 94 | DECLARE_WRITE8_MEMBER( tms7041_portc_w ); |
| 95 | DECLARE_READ8_MEMBER( tms7041_portd_r ); |
| 96 | DECLARE_WRITE8_MEMBER( tms7041_portd_w ); |
| 97 | |
| 68 | 98 | /* tms7020 i/o ports */ |
| 69 | 99 | UINT8 m_tms7020_porta; |
| 70 | 100 | UINT8 m_tms7020_portb; |
| r13270 | r13271 | |
| 81 | 111 | }; |
| 82 | 112 | |
| 83 | 113 | |
| 84 | | /* |
| 85 | | video initialization |
| 86 | | */ |
| 87 | | static VIDEO_START( exelv ) |
| 88 | | { |
| 89 | | VIDEO_START_CALL( generic_bitmapped ); |
| 90 | | tms3556_init(machine, /*0x8000*/0x10000); /* tms3556 with 32 kb of video RAM */ |
| 91 | | } |
| 92 | | |
| 93 | | |
| 94 | | static MACHINE_RESET( exelv ) |
| 95 | | { |
| 96 | | static const spchroms_interface exelv_speech_intf = { "tms5220c" }; |
| 97 | | |
| 98 | | tms3556_reset(); |
| 99 | | spchroms_config( machine, &exelv_speech_intf ); |
| 100 | | memory_set_bankptr( machine, "bank1", machine.region("user1")->base() + 0x0200 ); |
| 101 | | } |
| 102 | | |
| 103 | 114 | static INTERRUPT_GEN( exelv_hblank_interrupt ) |
| 104 | 115 | { |
| 105 | | tms3556_interrupt(device->machine()); |
| 116 | exelv_state *exelv = device->machine().driver_data<exelv_state>(); |
| 117 | exelv->m_tms3556->interrupt(device->machine()); |
| 106 | 118 | } |
| 107 | 119 | |
| 108 | 120 | #ifdef UNUSED_FUNCTION |
| r13270 | r13271 | |
| 191 | 203 | */ |
| 192 | 204 | |
| 193 | 205 | |
| 194 | | static READ8_HANDLER(mailbox_wx319_r) |
| 206 | READ8_MEMBER(exelv_state::mailbox_wx319_r) |
| 195 | 207 | { |
| 196 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 197 | | return state->m_wx319; |
| 208 | return m_wx319; |
| 198 | 209 | } |
| 199 | 210 | |
| 200 | 211 | |
| 201 | | static WRITE8_HANDLER(mailbox_wx318_w) |
| 212 | WRITE8_MEMBER(exelv_state::mailbox_wx318_w) |
| 202 | 213 | { |
| 203 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 204 | 214 | logerror("wx318 write 0x%02x\n", data); |
| 205 | | |
| 206 | | state->m_wx318 = data; |
| 215 | m_wx318 = data; |
| 207 | 216 | } |
| 208 | 217 | |
| 209 | 218 | |
| r13270 | r13271 | |
| 218 | 227 | A6 - |
| 219 | 228 | A7 - |
| 220 | 229 | */ |
| 221 | | static READ8_HANDLER(tms7020_porta_r) |
| 230 | READ8_MEMBER(exelv_state::tms7020_porta_r) |
| 222 | 231 | { |
| 223 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 224 | 232 | logerror("tms7020_porta_r\n"); |
| 225 | | |
| 226 | | return ( state->m_tms7041_portb & 0x80 ) ? 0x01 : 0x00; |
| 233 | return ( m_tms7041_portb & 0x80 ) ? 0x01 : 0x00; |
| 227 | 234 | } |
| 228 | 235 | |
| 229 | 236 | |
| 230 | | static WRITE8_HANDLER(tms7020_porta_w) |
| 237 | WRITE8_MEMBER(exelv_state::tms7020_porta_w) |
| 231 | 238 | { |
| 232 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 233 | 239 | logerror("tms7020_porta_w: data = 0x%02x\n", data); |
| 234 | | |
| 235 | | state->m_tms7020_porta = data; |
| 240 | m_tms7020_porta = data; |
| 236 | 241 | } |
| 237 | 242 | |
| 238 | 243 | |
| r13270 | r13271 | |
| 247 | 252 | B6 - |
| 248 | 253 | B7 - |
| 249 | 254 | */ |
| 250 | | static READ8_HANDLER(tms7020_portb_r) |
| 255 | READ8_MEMBER(exelv_state::tms7020_portb_r) |
| 251 | 256 | { |
| 252 | 257 | logerror("tms7020_portb_r\n"); |
| 253 | | |
| 254 | 258 | return 0x00; |
| 255 | 259 | } |
| 256 | 260 | |
| 257 | 261 | |
| 258 | | static WRITE8_HANDLER(tms7020_portb_w) |
| 262 | WRITE8_MEMBER(exelv_state::tms7020_portb_w) |
| 259 | 263 | { |
| 260 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 261 | 264 | logerror("tms7020_portb_w: data = 0x%02x\n", data); |
| 262 | | |
| 263 | | state->m_tms7020_portb = data; |
| 265 | m_tms7020_portb = data; |
| 264 | 266 | } |
| 265 | 267 | |
| 266 | 268 | |
| r13270 | r13271 | |
| 275 | 277 | A6 - X1 SCLK A9 |
| 276 | 278 | A7 - TMS5220 RDY |
| 277 | 279 | */ |
| 278 | | static READ8_HANDLER(tms7041_porta_r) |
| 280 | READ8_MEMBER(exelv_state::tms7041_porta_r) |
| 279 | 281 | { |
| 280 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 281 | | device_t *tms5220c = space->machine().device( "tms5220c" ); |
| 282 | 282 | UINT8 data = 0x00; |
| 283 | 283 | |
| 284 | 284 | logerror("tms7041_porta_r\n"); |
| 285 | 285 | |
| 286 | | data |= ( state->m_tms7020_portb & 0x01 ) ? 0x04 : 0x00; |
| 287 | | data |= tms5220_intq_r( tms5220c ) ? 0x08 : 0x00; |
| 288 | | data |= ( state->m_tms7020_portb & 0x02 ) ? 0x10 : 0x00; |
| 289 | | data |= tms5220_readyq_r( tms5220c ) ? 0x80 : 0x00; |
| 286 | data |= (m_tms7020_portb & 0x01 ) ? 0x04 : 0x00; |
| 287 | data |= tms5220_intq_r(m_tms5220c) ? 0x08 : 0x00; |
| 288 | data |= (m_tms7020_portb & 0x02) ? 0x10 : 0x00; |
| 289 | data |= tms5220_readyq_r(m_tms5220c) ? 0x80 : 0x00; |
| 290 | 290 | |
| 291 | 291 | return data; |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | 294 | |
| 295 | | static WRITE8_HANDLER(tms7041_porta_w) |
| 295 | WRITE8_MEMBER(exelv_state::tms7041_porta_w) |
| 296 | 296 | { |
| 297 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 298 | 297 | logerror("tms7041_porta_w: data = 0x%02x\n", data); |
| 299 | | |
| 300 | | state->m_tms7041_porta = data; |
| 298 | m_tms7041_porta = data; |
| 301 | 299 | } |
| 302 | 300 | |
| 303 | 301 | |
| r13270 | r13271 | |
| 312 | 310 | B6 - W - REV6 WX319-11 |
| 313 | 311 | B7 - W - TMS7020 port A bit 0 (REV3) |
| 314 | 312 | */ |
| 315 | | static READ8_HANDLER(tms7041_portb_r) |
| 313 | READ8_MEMBER(exelv_state::tms7041_portb_r) |
| 316 | 314 | { |
| 317 | | UINT8 data = 0xFF; |
| 318 | | |
| 315 | UINT8 data = 0xff; |
| 319 | 316 | logerror("tms7041_portb_r\n"); |
| 320 | | |
| 321 | 317 | return data; |
| 322 | 318 | } |
| 323 | 319 | |
| 324 | 320 | |
| 325 | | static WRITE8_HANDLER(tms7041_portb_w) |
| 321 | WRITE8_MEMBER(exelv_state::tms7041_portb_w) |
| 326 | 322 | { |
| 327 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 328 | | device_t *tms5220c = space->machine().device( "tms5220c" ); |
| 329 | | |
| 330 | 323 | logerror("tms7041_portb_w: data = 0x%02x\n", data); |
| 331 | 324 | |
| 332 | | tms5220_wsq_w( tms5220c, ( data & 0x01 ) ? 1 : 0 ); |
| 333 | | tms5220_rsq_w( tms5220c, ( data & 0x02 ) ? 1 : 0 ); |
| 325 | tms5220_wsq_w(m_tms5220c, (data & 0x01) ? 1 : 0); |
| 326 | tms5220_rsq_w(m_tms5220c, (data & 0x02) ? 1 : 0); |
| 334 | 327 | |
| 335 | | cputag_set_input_line(space->machine(), "maincpu", TMS7000_IRQ1_LINE, ( data & 0x04 ) ? CLEAR_LINE : ASSERT_LINE); |
| 328 | device_set_input_line(m_maincpu, TMS7000_IRQ1_LINE, (data & 0x04) ? CLEAR_LINE : ASSERT_LINE); |
| 336 | 329 | |
| 337 | 330 | /* Check for low->high transition on B6 */ |
| 338 | | if ( ! ( state->m_tms7041_portb & 0x40 ) && ( data & 0x40 ) ) |
| 331 | if (!(m_tms7041_portb & 0x40) && (data & 0x40)) |
| 339 | 332 | { |
| 340 | | logerror("wx319 write 0x%02x\n", state->m_tms7041_portc); |
| 341 | | state->m_wx319 = state->m_tms7041_portc; |
| 333 | logerror("wx319 write 0x%02x\n", m_tms7041_portc); |
| 334 | m_wx319 = m_tms7041_portc; |
| 342 | 335 | } |
| 343 | 336 | |
| 344 | | state->m_tms7041_portb = data; |
| 337 | m_tms7041_portb = data; |
| 345 | 338 | } |
| 346 | 339 | |
| 347 | 340 | |
| 348 | 341 | /* |
| 349 | 342 | TMS7041 PORT C - connected to mailbox WX318 and WX319 data bits |
| 350 | 343 | */ |
| 351 | | static READ8_HANDLER(tms7041_portc_r) |
| 344 | READ8_MEMBER(exelv_state::tms7041_portc_r) |
| 352 | 345 | { |
| 353 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 354 | | UINT8 data = 0xFF; |
| 355 | | |
| 346 | UINT8 data = 0xff; |
| 356 | 347 | logerror("tms7041_portc_r\n"); |
| 357 | 348 | |
| 358 | 349 | /* Check if wx318 output is enabled */ |
| 359 | | if ( ! ( state->m_tms7041_portb & 0x20 ) ) |
| 360 | | { |
| 361 | | data = state->m_wx318; |
| 362 | | } |
| 350 | if (!(m_tms7041_portb & 0x20)) |
| 351 | data = m_wx318; |
| 363 | 352 | |
| 364 | 353 | return data; |
| 365 | 354 | } |
| 366 | 355 | |
| 367 | 356 | |
| 368 | | static WRITE8_HANDLER(tms7041_portc_w) |
| 357 | WRITE8_MEMBER(exelv_state::tms7041_portc_w) |
| 369 | 358 | { |
| 370 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 371 | 359 | logerror("tms7041_portc_w: data = 0x%02x\n", data); |
| 372 | | |
| 373 | | state->m_tms7041_portc = data; |
| 360 | m_tms7041_portc = data; |
| 374 | 361 | } |
| 375 | 362 | |
| 376 | 363 | |
| r13270 | r13271 | |
| 385 | 372 | D6 - TMS5220 D1 |
| 386 | 373 | D7 - TMS5220 D0 |
| 387 | 374 | */ |
| 388 | | static READ8_HANDLER(tms7041_portd_r) |
| 375 | READ8_MEMBER(exelv_state::tms7041_portd_r) |
| 389 | 376 | { |
| 390 | | UINT8 data = 0xFF; |
| 391 | | |
| 377 | UINT8 data = 0xff; |
| 392 | 378 | logerror("tms7041_portd_r\n"); |
| 393 | | |
| 394 | 379 | return data; |
| 395 | 380 | } |
| 396 | 381 | |
| 397 | 382 | |
| 398 | | static WRITE8_HANDLER(tms7041_portd_w) |
| 383 | WRITE8_MEMBER(exelv_state::tms7041_portd_w) |
| 399 | 384 | { |
| 400 | | exelv_state *state = space->machine().driver_data<exelv_state>(); |
| 401 | | device_t *tms5220c = space->machine().device( "tms5220c" ); |
| 402 | | |
| 403 | 385 | logerror("tms7041_portd_w: data = 0x%02x\n", data); |
| 404 | 386 | |
| 405 | | tms5220_data_w( tms5220c, 0, BITSWAP8(data,0,1,2,3,4,5,6,7) ); |
| 406 | | |
| 407 | | state->m_tms7041_portd = data; |
| 387 | tms5220_data_w(m_tms5220c, 0, BITSWAP8(data,0,1,2,3,4,5,6,7)); |
| 388 | m_tms7041_portd = data; |
| 408 | 389 | } |
| 409 | 390 | |
| 410 | 391 | /* |
| r13270 | r13271 | |
| 432 | 413 | @>f800-@>ffff: tms7020/tms7040 internal ROM |
| 433 | 414 | */ |
| 434 | 415 | |
| 435 | | static ADDRESS_MAP_START(tms7020_mem, AS_PROGRAM, 8) |
| 416 | static ADDRESS_MAP_START(tms7020_mem, AS_PROGRAM, 8, exelv_state) |
| 436 | 417 | //AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w)/* tms7020 internal RAM */ |
| 437 | 418 | AM_RANGE(0x0080, 0x00ff) AM_NOP |
| 438 | 419 | //AM_RANGE(0x0100, 0x010b) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w)/* tms7020 internal I/O ports */ |
| 439 | 420 | //AM_RANGE(0x010c, 0x01ff) AM_READWRITE(SMH_NOP, SMH_NOP) /* external I/O ports */ |
| 440 | | AM_RANGE(0x012d, 0x0012d) AM_READWRITE(tms3556_reg_r/*right???*/, tms3556_reg_w) |
| 441 | | AM_RANGE(0x012e, 0x0012e) AM_READWRITE(tms3556_vram_r/*right???*/, tms3556_vram_w) |
| 421 | AM_RANGE(0x012d, 0x0012d) AM_DEVREADWRITE("tms3556", tms3556_device, reg_r/*right???*/, reg_w) |
| 422 | AM_RANGE(0x012e, 0x0012e) AM_DEVREADWRITE("tms3556", tms3556_device, vram_r/*right???*/, vram_w) |
| 442 | 423 | AM_RANGE(0x0130, 0x00130) AM_READWRITE(mailbox_wx319_r, mailbox_wx318_w) |
| 443 | 424 | AM_RANGE(0x0200, 0x7fff) AM_ROMBANK("bank1") /* system ROM */ |
| 444 | 425 | AM_RANGE(0x8000, 0xbfff) AM_NOP |
| r13270 | r13271 | |
| 448 | 429 | ADDRESS_MAP_END |
| 449 | 430 | |
| 450 | 431 | |
| 451 | | static ADDRESS_MAP_START(tms7020_port, AS_IO, 8) |
| 432 | static ADDRESS_MAP_START(tms7020_port, AS_IO, 8, exelv_state) |
| 452 | 433 | AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READWRITE(tms7020_porta_r, tms7020_porta_w) |
| 453 | 434 | AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_READWRITE(tms7020_portb_r, tms7020_portb_w) |
| 454 | 435 | ADDRESS_MAP_END |
| 455 | 436 | |
| 456 | 437 | |
| 457 | | static ADDRESS_MAP_START(tms7041_map, AS_PROGRAM, 8) |
| 438 | static ADDRESS_MAP_START(tms7041_map, AS_PROGRAM, 8, exelv_state) |
| 458 | 439 | AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("tms7041",0x0000) |
| 459 | 440 | ADDRESS_MAP_END |
| 460 | 441 | |
| 461 | 442 | |
| 462 | | static ADDRESS_MAP_START(tms7041_port, AS_IO, 8) |
| 443 | static ADDRESS_MAP_START(tms7041_port, AS_IO, 8, exelv_state) |
| 463 | 444 | AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READWRITE(tms7041_porta_r, tms7041_porta_w) |
| 464 | 445 | AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_READWRITE(tms7041_portb_r, tms7041_portb_w) |
| 465 | 446 | AM_RANGE(TMS7000_PORTC, TMS7000_PORTC) AM_READWRITE(tms7041_portc_r, tms7041_portc_w) |
| r13270 | r13271 | |
| 467 | 448 | ADDRESS_MAP_END |
| 468 | 449 | |
| 469 | 450 | |
| 470 | | static ADDRESS_MAP_START(tms7040_mem, AS_PROGRAM, 8) |
| 451 | static ADDRESS_MAP_START(tms7040_mem, AS_PROGRAM, 8, exelv_state) |
| 471 | 452 | //AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w)/* tms7040 internal RAM */ |
| 472 | 453 | AM_RANGE(0x0080, 0x00ff) AM_NOP |
| 473 | 454 | //AM_RANGE(0x0100, 0x010b) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w)/* tms7020 internal I/O ports */ |
| 474 | 455 | //AM_RANGE(0x010c, 0x01ff) AM_READWRITE(SMH_NOP, SMH_NOP) /* external I/O ports */ |
| 475 | | AM_RANGE(0x012d, 0x0012d) AM_READWRITE(tms3556_reg_r/*right???*/, tms3556_reg_w) |
| 476 | | AM_RANGE(0x012e, 0x0012e) AM_READWRITE(tms3556_vram_r/*right???*/, tms3556_vram_w) |
| 456 | AM_RANGE(0x012d, 0x0012d) AM_DEVREADWRITE("tms3556", tms3556_device, reg_r/*right???*/, reg_w) |
| 457 | AM_RANGE(0x012e, 0x0012e) AM_DEVREADWRITE("tms3556", tms3556_device, vram_r/*right???*/, vram_w) |
| 477 | 458 | AM_RANGE(0x0130, 0x00130) AM_READWRITE(mailbox_wx319_r, mailbox_wx318_w) |
| 478 | 459 | AM_RANGE(0x0200, 0x7fff) AM_ROMBANK("bank1") /* system ROM */ |
| 479 | 460 | AM_RANGE(0x8000, 0xbfff) AM_NOP |
| r13270 | r13271 | |
| 483 | 464 | ADDRESS_MAP_END |
| 484 | 465 | |
| 485 | 466 | |
| 486 | | static ADDRESS_MAP_START(tms7042_map, AS_PROGRAM, 8) |
| 467 | static ADDRESS_MAP_START(tms7042_map, AS_PROGRAM, 8, exelv_state) |
| 487 | 468 | AM_RANGE(0xe000, 0xefff) AM_ROM AM_REGION("tms7042",0x0000) |
| 488 | 469 | AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("tms7042",0x0000) /* Duplicated until a proper dump surfaces */ |
| 489 | 470 | ADDRESS_MAP_END |
| r13270 | r13271 | |
| 507 | 488 | }; |
| 508 | 489 | |
| 509 | 490 | |
| 491 | static PALETTE_INIT( exelv ) |
| 492 | { |
| 493 | int i, red, green, blue; |
| 494 | |
| 495 | /* create the 8 color palette */ |
| 496 | for (i = 0; i < 8; i++) |
| 497 | { |
| 498 | red = (i & 1) ? 255 : 0; /* red */ |
| 499 | green = (i & 2) ? 255 : 0; /* green */ |
| 500 | blue = (i & 4) ? 255 : 0; /* blue */ |
| 501 | palette_set_color_rgb(machine, i, red, green, blue); |
| 502 | } |
| 503 | } |
| 504 | |
| 505 | |
| 506 | /* Video Initialization */ |
| 507 | |
| 508 | void exelv_state::video_start() |
| 509 | { |
| 510 | video_start_generic_bitmapped(machine()); |
| 511 | } |
| 512 | |
| 513 | |
| 514 | /* Machine Initialization */ |
| 515 | |
| 516 | void exelv_state::machine_start() |
| 517 | { |
| 518 | UINT8 *rom = machine().region("user1")->base(); |
| 519 | memory_configure_bank(machine(), "bank1", 0, 1, rom, 0x8000 - 0x200); |
| 520 | memory_set_bank(machine(), "bank1", 0); |
| 521 | |
| 522 | /* register for state saving */ |
| 523 | state_save_register_global(machine(), m_tms7020_porta); |
| 524 | state_save_register_global(machine(), m_tms7020_portb); |
| 525 | state_save_register_global(machine(), m_tms7041_porta); |
| 526 | state_save_register_global(machine(), m_tms7041_portb); |
| 527 | state_save_register_global(machine(), m_tms7041_portc); |
| 528 | state_save_register_global(machine(), m_tms7041_portd); |
| 529 | state_save_register_global(machine(), m_wx318); |
| 530 | state_save_register_global(machine(), m_wx319); |
| 531 | } |
| 532 | |
| 533 | void exelv_state::machine_reset() |
| 534 | { |
| 535 | static const spchroms_interface exelv_speech_intf = {"tms5220c"}; |
| 536 | spchroms_config(machine(), &exelv_speech_intf); |
| 537 | } |
| 538 | |
| 510 | 539 | static MACHINE_CONFIG_START( exl100, exelv_state ) |
| 511 | 540 | /* basic machine hardware */ |
| 512 | 541 | MCFG_CPU_ADD("maincpu", TMS7000_EXL, XTAL_4_9152MHz) /* TMS7020 */ |
| r13270 | r13271 | |
| 521 | 550 | MCFG_QUANTUM_PERFECT_CPU("maincpu") |
| 522 | 551 | MCFG_QUANTUM_PERFECT_CPU("tms7041") |
| 523 | 552 | |
| 524 | | MCFG_MACHINE_RESET( exelv ) |
| 553 | MCFG_TMS3556_ADD("tms3556") |
| 525 | 554 | |
| 526 | 555 | /* video hardware */ |
| 527 | | MCFG_FRAGMENT_ADD(tms3556) |
| 556 | MCFG_SCREEN_ADD("screen", RASTER) |
| 557 | MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) |
| 558 | MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 559 | #if TMS3556_DOUBLE_WIDTH |
| 560 | MCFG_SCREEN_SIZE(TMS3556_TOTAL_WIDTH*2, TMS3556_TOTAL_HEIGHT*2) |
| 561 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH*2-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 562 | #else |
| 563 | MCFG_SCREEN_SIZE(TMS3556_TOTAL_WIDTH, TMS3556_TOTAL_HEIGHT*2) |
| 564 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 565 | #endif |
| 566 | MCFG_SCREEN_UPDATE(generic_bitmapped) |
| 567 | MCFG_PALETTE_LENGTH(8) |
| 568 | MCFG_PALETTE_INIT(exelv) |
| 528 | 569 | |
| 529 | | MCFG_SCREEN_MODIFY("screen") |
| 530 | 570 | MCFG_SCREEN_REFRESH_RATE(50) |
| 531 | 571 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 532 | 572 | |
| 533 | | MCFG_VIDEO_START(exelv) |
| 534 | | |
| 535 | 573 | /* sound */ |
| 536 | 574 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 537 | 575 | MCFG_SOUND_ADD("tms5220c", TMS5220C, 640000) |
| r13270 | r13271 | |
| 554 | 592 | MCFG_QUANTUM_PERFECT_CPU("maincpu") |
| 555 | 593 | MCFG_QUANTUM_PERFECT_CPU("tms7042") |
| 556 | 594 | |
| 557 | | MCFG_MACHINE_RESET( exelv ) |
| 595 | MCFG_TMS3556_ADD("tms3556") |
| 558 | 596 | |
| 559 | 597 | /* video hardware */ |
| 560 | | MCFG_FRAGMENT_ADD(tms3556) |
| 598 | MCFG_SCREEN_ADD("screen", RASTER) |
| 599 | MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) |
| 600 | MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 601 | #if TMS3556_DOUBLE_WIDTH |
| 602 | MCFG_SCREEN_SIZE(TMS3556_TOTAL_WIDTH*2, TMS3556_TOTAL_HEIGHT*2) |
| 603 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH*2-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 604 | #else |
| 605 | MCFG_SCREEN_SIZE(TMS3556_TOTAL_WIDTH, TMS3556_TOTAL_HEIGHT*2) |
| 606 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 607 | #endif |
| 608 | MCFG_SCREEN_UPDATE(generic_bitmapped) |
| 609 | MCFG_PALETTE_LENGTH(8) |
| 610 | MCFG_PALETTE_INIT(exelv) |
| 561 | 611 | |
| 562 | | MCFG_SCREEN_MODIFY("screen") |
| 563 | 612 | MCFG_SCREEN_REFRESH_RATE(50) |
| 564 | 613 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 565 | 614 | |
| 566 | | MCFG_VIDEO_START(exelv) |
| 567 | | |
| 568 | 615 | /* sound */ |
| 569 | 616 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 570 | 617 | MCFG_SOUND_ADD("tms5220c", TMS5220C, 640000) |
| r13270 | r13271 | |
| 610 | 657 | ROM_END |
| 611 | 658 | |
| 612 | 659 | |
| 613 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ |
| 614 | | COMP( 1984, exl100, 0, 0, exl100, exelv, 0, "Exelvision", "EXL 100" , GAME_NOT_WORKING) |
| 615 | | COMP( 1986, exeltel,exl100, 0, exeltel, exelv, 0, "Exelvision", "Exeltel" , GAME_NOT_WORKING) |
| 660 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ |
| 661 | COMP(1984, exl100, 0, 0, exl100, exelv, 0, "Exelvision", "EXL 100", GAME_NOT_WORKING) |
| 662 | COMP(1986, exeltel, exl100, 0, exeltel, exelv, 0, "Exelvision", "Exeltel", GAME_NOT_WORKING) |