trunk/src/emu/video/tms9928a.c
| r18101 | r18102 | |
| 70 | 70 | E Gray 0.80 0.47 0.47 0.80 0.80 0.80 204 204 204 |
| 71 | 71 | F White 1.00 0.47 0.47 1.00 1.00 1.00 255 255 255 |
| 72 | 72 | */ |
| 73 | | static const rgb_t tms9928a_palette[16] = |
| 73 | static const rgb_t tms9928a_palette[TMS9928A_PALETTE_SIZE] = |
| 74 | 74 | { |
| 75 | 75 | RGB_BLACK, |
| 76 | 76 | RGB_BLACK, |
| r18101 | r18102 | |
| 93 | 93 | tms9928a_device::tms9928a_device( const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, bool is_50hz, bool is_reva ) |
| 94 | 94 | : device_t( mconfig, type, name, tag, owner, clock ), |
| 95 | 95 | device_memory_interface(mconfig, *this), |
| 96 | | m_space_config("vram", ENDIANNESS_BIG, 8, 14) |
| 96 | m_space_config("vram",ENDIANNESS_BIG, 8, 14, 0, NULL, *ADDRESS_MAP_NAME(memmap)) |
| 97 | 97 | { |
| 98 | 98 | m_50hz = is_50hz; |
| 99 | 99 | m_reva = is_reva; |
| 100 | | static_set_addrmap(*this, AS_DATA, ADDRESS_MAP_NAME(memmap)); |
| 100 | // static_set_addrmap(*this, AS_DATA, ADDRESS_MAP_NAME(memmap)); |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | |
| 104 | 104 | tms9928a_device::tms9928a_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock ) |
| 105 | 105 | : device_t( mconfig, TMS9928A, "TMS9928A", tag, owner, clock ), |
| 106 | 106 | device_memory_interface(mconfig, *this), |
| 107 | | m_space_config("vram", ENDIANNESS_BIG, 8, 14) |
| 107 | m_space_config("vram",ENDIANNESS_BIG, 8, 14, 0, NULL, *ADDRESS_MAP_NAME(memmap)) |
| 108 | 108 | { |
| 109 | 109 | m_50hz = false; |
| 110 | 110 | m_reva = true; |
| 111 | | static_set_addrmap(*this, AS_DATA, ADDRESS_MAP_NAME(memmap)); |
| 111 | // static_set_addrmap(*this, AS_DATA, ADDRESS_MAP_NAME(memmap)); |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | |
| r18101 | r18102 | |
| 163 | 163 | { |
| 164 | 164 | // update backdrop colour to transparent if EXTVID bit is set |
| 165 | 165 | if ((m_Regs[7] & 15) == 0) |
| 166 | | palette_set_color(machine(), 0, MAKE_ARGB(m_Regs[0] & 1 ? 0 : 255,0,0,0)); |
| 166 | m_palette[0] = MAKE_ARGB(m_Regs[0] & 1 ? 0 : 255,0,0,0); |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | |
| r18101 | r18102 | |
| 280 | 280 | int raw_vpos = m_screen->vpos(); |
| 281 | 281 | int vpos = raw_vpos * m_vertical_size / m_screen->height(); |
| 282 | 282 | UINT16 BackColour = m_Regs[7] & 15; |
| 283 | | UINT16 *p = &m_tmpbmp.pix16(vpos); |
| 283 | UINT32 *p = &m_tmpbmp.pix32(vpos); |
| 284 | 284 | |
| 285 | 285 | int y = vpos - m_top_border; |
| 286 | 286 | |
| r18101 | r18102 | |
| 288 | 288 | { |
| 289 | 289 | /* Draw backdrop colour */ |
| 290 | 290 | for ( int i = 0; i < TMS9928A_TOTAL_HORZ; i++ ) |
| 291 | | p[i] = BackColour; |
| 291 | p[i] = m_palette[BackColour]; |
| 292 | 292 | |
| 293 | 293 | /* vblank is set at the last cycle of the first inactive line */ |
| 294 | 294 | if ( y == 193 ) |
| r18101 | r18102 | |
| 303 | 303 | |
| 304 | 304 | /* Left border */ |
| 305 | 305 | for ( int i = 0; i < TMS9928A_HORZ_DISPLAY_START; i++ ) |
| 306 | | p[i] = BackColour; |
| 306 | p[i] = m_palette[BackColour]; |
| 307 | 307 | |
| 308 | 308 | /* Active display */ |
| 309 | 309 | |
| r18101 | r18102 | |
| 319 | 319 | UINT8 charcode = m_vram_space->read_byte( addr ); |
| 320 | 320 | UINT8 pattern = m_vram_space->read_byte( m_pattern + ( charcode << 3 ) + ( y & 7 ) ); |
| 321 | 321 | UINT8 colour = m_vram_space->read_byte( m_colour + ( charcode >> 3 ) ); |
| 322 | | UINT16 fg = (colour >> 4) ? (colour >> 4) : BackColour; |
| 323 | | UINT16 bg = (colour & 15) ? (colour & 15) : BackColour; |
| 322 | rgb_t fg = m_palette[(colour >> 4) ? (colour >> 4) : BackColour]; |
| 323 | rgb_t bg = m_palette[(colour & 15) ? (colour & 15) : BackColour]; |
| 324 | 324 | |
| 325 | 325 | for ( int i = 0; i < 8; pattern <<= 1, i++ ) |
| 326 | 326 | p[x+i] = ( pattern & 0x80 ) ? fg : bg; |
| r18101 | r18102 | |
| 332 | 332 | //if (vpos==100 ) popmessage("TMS9928A MODE 1"); |
| 333 | 333 | { |
| 334 | 334 | UINT16 addr = m_nametbl + ( ( y >> 3 ) * 40 ); |
| 335 | | UINT16 fg = (m_Regs[7] >> 4) ? (m_Regs[7] >> 4) : BackColour; |
| 336 | | UINT16 bg = BackColour; |
| 335 | rgb_t fg = m_palette[(m_Regs[7] >> 4) ? (m_Regs[7] >> 4) : BackColour]; |
| 336 | rgb_t bg = m_palette[BackColour]; |
| 337 | 337 | |
| 338 | 338 | /* Extra 6 pixels left border */ |
| 339 | 339 | for ( int x = TMS9928A_HORZ_DISPLAY_START; x < TMS9928A_HORZ_DISPLAY_START + 6; x++ ) |
| r18101 | r18102 | |
| 364 | 364 | UINT16 charcode = m_vram_space->read_byte( addr ) + ( ( y >> 6 ) << 8 ); |
| 365 | 365 | UINT8 pattern = m_vram_space->read_byte( m_pattern + ( ( charcode & m_patternmask ) << 3 ) + ( y & 7 ) ); |
| 366 | 366 | UINT8 colour = m_vram_space->read_byte( m_colour + ( ( charcode & m_colourmask ) << 3 ) + ( y & 7 ) ); |
| 367 | | UINT16 fg = (colour >> 4) ? (colour >> 4) : BackColour; |
| 368 | | UINT16 bg = (colour & 15) ? (colour & 15) : BackColour; |
| 367 | rgb_t fg = m_palette[(colour >> 4) ? (colour >> 4) : BackColour]; |
| 368 | rgb_t bg = m_palette[(colour & 15) ? (colour & 15) : BackColour]; |
| 369 | 369 | |
| 370 | 370 | for ( int i = 0; i < 8; pattern <<= 1, i++ ) |
| 371 | 371 | p[x+i] = ( pattern & 0x80 ) ? fg : bg; |
| r18101 | r18102 | |
| 377 | 377 | //if (vpos==100) popmessage("TMS9928A MODE1+2"); |
| 378 | 378 | { |
| 379 | 379 | UINT16 addr = m_nametbl + ( ( y >> 3 ) * 40 ); |
| 380 | | UINT16 fg = (m_Regs[7] >> 4) ? (m_Regs[7] >> 4) : BackColour; |
| 381 | | UINT16 bg = BackColour; |
| 380 | rgb_t fg = m_palette[(m_Regs[7] >> 4) ? (m_Regs[7] >> 4) : BackColour]; |
| 381 | rgb_t bg = m_palette[BackColour]; |
| 382 | 382 | |
| 383 | 383 | /* Extra 6 pixels left border */ |
| 384 | 384 | for ( int x = TMS9928A_HORZ_DISPLAY_START; x < TMS9928A_HORZ_DISPLAY_START + 6; x++ ) |
| r18101 | r18102 | |
| 408 | 408 | { |
| 409 | 409 | UINT8 charcode = m_vram_space->read_byte( addr ); |
| 410 | 410 | UINT8 colour = m_vram_space->read_byte( m_pattern + ( charcode << 3 ) + ( ( y >> 2 ) & 7 ) ); |
| 411 | | UINT16 fg = (colour >> 4) ? (colour >> 4) : BackColour; |
| 412 | | UINT16 bg = (colour & 15) ? (colour & 15) : BackColour; |
| 411 | rgb_t fg = m_palette[(colour >> 4) ? (colour >> 4) : BackColour]; |
| 412 | rgb_t bg = m_palette[(colour & 15) ? (colour & 15) : BackColour]; |
| 413 | 413 | |
| 414 | 414 | p[x+0] = p[x+1] = p[x+2] = p[x+3] = fg; |
| 415 | 415 | p[x+4] = p[x+5] = p[x+6] = p[x+7] = bg; |
| r18101 | r18102 | |
| 420 | 420 | case 5: case 7: /* MODE bogus */ |
| 421 | 421 | //if (vpos==100 ) popmessage("TMS9928A MODE bogus"); |
| 422 | 422 | { |
| 423 | | UINT16 fg = (m_Regs[7] >> 4) ? (m_Regs[7] >> 4) : BackColour; |
| 424 | | UINT16 bg = BackColour; |
| 423 | rgb_t fg = m_palette[(m_Regs[7] >> 4) ? (m_Regs[7] >> 4) : BackColour]; |
| 424 | rgb_t bg = m_palette[BackColour]; |
| 425 | 425 | |
| 426 | 426 | /* Extra 6 pixels left border */ |
| 427 | 427 | for ( int x = TMS9928A_HORZ_DISPLAY_START; x < TMS9928A_HORZ_DISPLAY_START + 6; x++ ) |
| r18101 | r18102 | |
| 448 | 448 | { |
| 449 | 449 | UINT8 charcode = m_vram_space->read_byte( addr ); |
| 450 | 450 | UINT8 colour = m_vram_space->read_byte( m_pattern + ( ( ( charcode + ( ( y >> 2 ) & 7 ) + ( ( y >> 6 ) << 8 ) ) & m_patternmask ) << 3 ) ); |
| 451 | | UINT16 fg = (colour >> 4) ? (colour >> 4) : BackColour; |
| 452 | | UINT16 bg = (colour & 15) ? (colour & 15) : BackColour; |
| 451 | rgb_t fg = m_palette[(colour >> 4) ? (colour >> 4) : BackColour]; |
| 452 | rgb_t bg = m_palette[(colour & 15) ? (colour & 15) : BackColour]; |
| 453 | 453 | |
| 454 | 454 | p[x+0] = p[x+1] = p[x+2] = p[x+3] = fg; |
| 455 | 455 | p[x+4] = p[x+5] = p[x+6] = p[x+7] = bg; |
| r18101 | r18102 | |
| 542 | 542 | if ( ! ( spr_drawn[ colission_index ] & 0x02 ) ) |
| 543 | 543 | { |
| 544 | 544 | spr_drawn[ colission_index ] |= 0x02; |
| 545 | | p[ TMS9928A_HORZ_DISPLAY_START + colission_index - 32 ] = sprcol; |
| 545 | p[ TMS9928A_HORZ_DISPLAY_START + colission_index - 32 ] = m_palette[sprcol]; |
| 546 | 546 | } |
| 547 | 547 | } |
| 548 | 548 | } |
| r18101 | r18102 | |
| 567 | 567 | |
| 568 | 568 | /* Right border */ |
| 569 | 569 | for ( int i = TMS9928A_HORZ_DISPLAY_START + 256; i < TMS9928A_TOTAL_HORZ; i++ ) |
| 570 | | p[i] = BackColour; |
| 570 | p[i] = m_palette[BackColour]; |
| 571 | 571 | } |
| 572 | 572 | |
| 573 | 573 | /* Schedule next callback */ |
| r18101 | r18102 | |
| 575 | 575 | } |
| 576 | 576 | |
| 577 | 577 | |
| 578 | | UINT32 tms9928a_device::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 578 | UINT32 tms9928a_device::screen_update( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect ) |
| 579 | 579 | { |
| 580 | 580 | copybitmap( bitmap, m_tmpbmp, 0, 0, 0, 0, cliprect ); |
| 581 | 581 | return 0; |
| r18101 | r18102 | |
| 600 | 600 | |
| 601 | 601 | void tms9928a_device::device_start() |
| 602 | 602 | { |
| 603 | | m_screen = machine().device<screen_device>( m_screen_tag ); |
| 603 | astring tempstring; |
| 604 | m_screen = downcast<screen_device *>(machine().device(siblingtag(tempstring,m_screen_tag))); |
| 604 | 605 | assert( m_screen != NULL ); |
| 605 | 606 | |
| 606 | 607 | m_top_border = m_50hz ? TMS9928A_VERT_DISPLAY_START_PAL : TMS9928A_VERT_DISPLAY_START_NTSC; |
| r18101 | r18102 | |
| 616 | 617 | |
| 617 | 618 | m_line_timer = timer_alloc(TIMER_LINE); |
| 618 | 619 | |
| 619 | | palette_set_colors(machine(), 0, tms9928a_palette, TMS9928A_PALETTE_SIZE); |
| 620 | /* copy default palette into working palette */ |
| 621 | for (int i = 0; i < TMS9928A_PALETTE_SIZE; i++) |
| 622 | { |
| 623 | m_palette[i] = tms9928a_palette[i]; |
| 624 | } |
| 620 | 625 | |
| 621 | 626 | save_item(NAME(m_Regs[0])); |
| 622 | 627 | save_item(NAME(m_Regs[1])); |
| r18101 | r18102 | |
| 641 | 646 | save_item(NAME(m_spriteattribute)); |
| 642 | 647 | save_item(NAME(m_spritepattern)); |
| 643 | 648 | save_item(NAME(m_mode)); |
| 649 | save_item(NAME(m_palette)); |
| 644 | 650 | } |
| 645 | 651 | |
| 646 | 652 | |