trunk/src/mess/drivers/pc9801.c
| r19312 | r19313 | |
| 276 | 276 | #define UPD1990A_TAG "upd1990a" |
| 277 | 277 | #define UPD8251_TAG "upd8251" |
| 278 | 278 | |
| 279 | | #define DEBUG_PCG 1 |
| 280 | | |
| 281 | 279 | class pc9801_state : public driver_device |
| 282 | 280 | { |
| 283 | 281 | public: |
| r19312 | r19313 | |
| 555 | 553 | // find memory regions |
| 556 | 554 | m_char_rom = memregion("chargen")->base(); |
| 557 | 555 | m_kanji_rom = memregion("kanji")->base(); |
| 556 | |
| 557 | m_pcg_ram = auto_alloc_array(machine(), UINT8, 0x200000); |
| 558 | |
| 559 | state_save_register_global_pointer(machine(), m_pcg_ram, 0x200000); |
| 558 | 560 | } |
| 559 | 561 | |
| 560 | 562 | UINT32 pc9801_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| r19312 | r19313 | |
| 564 | 566 | /* graphics */ |
| 565 | 567 | m_hgdc2->screen_update(screen, bitmap, cliprect); |
| 566 | 568 | m_hgdc1->screen_update(screen, bitmap, cliprect); |
| 567 | | |
| 568 | 569 | return 0; |
| 569 | 570 | } |
| 570 | 571 | |
| r19312 | r19313 | |
| 614 | 615 | UINT8 char_size,interlace_on; |
| 615 | 616 | UINT8 kanji_on; |
| 616 | 617 | UINT16 tile; |
| 618 | UINT8 pcg_sel, pcg_lr; |
| 617 | 619 | |
| 618 | 620 | if(state->m_video_ff[DISPLAY_REG] == 0) //screen is off |
| 619 | 621 | return; |
| r19312 | r19313 | |
| 636 | 638 | if(kanji_on) |
| 637 | 639 | kanji_on--; |
| 638 | 640 | |
| 641 | pcg_sel = 0; |
| 642 | pcg_lr = 0; |
| 643 | |
| 639 | 644 | if(kanji_on == 0) |
| 640 | 645 | { |
| 641 | 646 | tile = state->m_video_ram_1[(tile_addr*2) & 0x1fff] & 0x00ff; |
| 642 | | knj_tile = state->m_video_ram_1[(tile_addr*2+1) & 0x1fff] & 0x7f; |
| 643 | | if((tile & 0xe0) == 0 && knj_tile) // kanji select |
| 647 | knj_tile = state->m_video_ram_1[(tile_addr*2+1) & 0x1fff] & 0xff; |
| 648 | if((tile & 0xe0) == 0 && knj_tile) // kanji select, TODO |
| 644 | 649 | { |
| 645 | 650 | tile <<= 8; |
| 646 | | tile |= knj_tile; |
| 651 | tile |= (knj_tile & 0x7f); |
| 647 | 652 | /* annoying kanji bit-swap applied on the address bus ... */ |
| 648 | 653 | tile = BITSWAP16(tile,7,15,14,13,12,11,6,5,10,9,8,4,3,2,1,0); |
| 649 | 654 | tile &= 0x1fff; |
| 650 | 655 | kanji_on = 2; |
| 651 | 656 | } |
| 657 | else if(tile == 0x56 && knj_tile) |
| 658 | { |
| 659 | pcg_sel = 1; |
| 660 | tile = knj_tile & 0x7f; |
| 661 | pcg_lr = (knj_tile & 0x80) >> 7; |
| 662 | } |
| 652 | 663 | } |
| 653 | 664 | attr = (state->m_video_ram_1[(tile_addr*2 & 0x1fff) | 0x2000] & 0x00ff); |
| 654 | 665 | |
| r19312 | r19313 | |
| 671 | 682 | if(res_x > 640 || res_y > char_size*25) //TODO |
| 672 | 683 | continue; |
| 673 | 684 | |
| 674 | | if(kanji_on) |
| 685 | tile_data = 0; |
| 686 | |
| 687 | if(!secret) |
| 675 | 688 | { |
| 676 | | tile_data = secret ? 0 : (state->m_kanji_rom[tile*0x20+yi*2+(kanji_on & 1)]); |
| 689 | if(kanji_on) |
| 690 | tile_data = (state->m_kanji_rom[tile*0x20+yi*2+(kanji_on & 1)]); |
| 691 | else if(pcg_sel) |
| 692 | tile_data = (state->m_pcg_ram[0xac000*2+tile*0x40+yi*2+pcg_lr]); |
| 693 | else |
| 694 | tile_data = (state->m_char_rom[tile*char_size+interlace_on*0x800+yi]); |
| 677 | 695 | } |
| 678 | | else |
| 679 | | tile_data = secret ? 0 : (state->m_char_rom[tile*char_size+interlace_on*0x800+yi]); |
| 680 | 696 | |
| 681 | 697 | if(reverse) { tile_data^=0xff; } |
| 682 | 698 | if(u_line && yi == 7) { tile_data = 0xff; } |
| r19312 | r19313 | |
| 687 | 703 | |
| 688 | 704 | if(yi >= char_size) |
| 689 | 705 | pen = 0; |
| 706 | else if(pcg_sel) |
| 707 | { |
| 708 | pen = 0; |
| 709 | if(color & 1) pen |= ((tile_data >> (7-xi) & 1) ? 1 : 0); |
| 710 | if(color & 2) pen |= ((tile_data >> (7-xi) & 1) ? 2 : 0); |
| 711 | if(color & 4) pen |= ((tile_data >> (7-xi) & 1) ? 4 : 0); |
| 712 | } |
| 690 | 713 | else |
| 691 | 714 | pen = (tile_data >> (7-xi) & 1) ? color : 0; |
| 692 | 715 | |
| r19312 | r19313 | |
| 1106 | 1129 | switch((offset & 0xe) + 1) |
| 1107 | 1130 | { |
| 1108 | 1131 | case 0x09://cg window font read |
| 1109 | | return m_pcg_ram[((m_font_addr & 0x7f7f) << 4) | m_font_lr | (m_font_line & 0x0f)]; |
| 1132 | { |
| 1133 | UINT32 pcg_offset; |
| 1134 | |
| 1135 | pcg_offset = m_font_addr << 6; |
| 1136 | pcg_offset|= m_font_line; |
| 1137 | pcg_offset|= m_font_lr; |
| 1138 | return m_pcg_ram[pcg_offset]; |
| 1139 | } |
| 1110 | 1140 | } |
| 1111 | 1141 | |
| 1112 | 1142 | printf("Read to undefined port [%02x]\n",offset+0xa0); |
| r19312 | r19313 | |
| 1165 | 1195 | return; |
| 1166 | 1196 | case 0x05: |
| 1167 | 1197 | //printf("%02x\n",data); |
| 1168 | | m_font_line = data & 0x1f; |
| 1169 | | m_font_lr = data & 0x20 ? 0x000 : 0x800; |
| 1198 | m_font_line = ((data & 0x1f) << 1); |
| 1199 | m_font_lr = ((data & 0x20) >> 5) ^ 1; |
| 1170 | 1200 | return; |
| 1171 | 1201 | case 0x09: //cg window font write |
| 1172 | 1202 | { |
| 1173 | | //printf("W\n"); |
| 1174 | | m_pcg_ram[((m_font_addr & 0x7f7f) << 4) | m_font_lr | m_font_line] = data; |
| 1203 | UINT32 pcg_offset; |
| 1204 | |
| 1205 | pcg_offset = m_font_addr << 6; |
| 1206 | pcg_offset|= m_font_line; |
| 1207 | pcg_offset|= m_font_lr; |
| 1208 | //printf("%04x %02x %02x %08x\n",m_font_addr,m_font_line,m_font_lr,pcg_offset); |
| 1209 | m_pcg_ram[pcg_offset] = data; |
| 1175 | 1210 | return; |
| 1176 | 1211 | } |
| 1177 | 1212 | } |
| r19312 | r19313 | |
| 2901 | 2936 | m_rtc->oe_w(1); |
| 2902 | 2937 | |
| 2903 | 2938 | m_ipl_rom = memregion("ipl")->base(); |
| 2904 | | m_pcg_ram = auto_alloc_array(machine(), UINT8, 0x80000); |
| 2905 | | |
| 2906 | | state_save_register_global_pointer(machine(), m_pcg_ram, 0x80000); |
| 2907 | 2939 | } |
| 2908 | 2940 | |
| 2909 | 2941 | MACHINE_START_MEMBER(pc9801_state,pc9801f) |