shelves/new_menus/src/mess/drivers/pc9801.c
| r29304 | r29305 | |
| 683 | 683 | DECLARE_WRITE8_MEMBER(pc9821_ext2_video_ff_w); |
| 684 | 684 | |
| 685 | 685 | DECLARE_FLOPPY_FORMATS( floppy_formats ); |
| 686 | UPD7220_DISPLAY_PIXELS_MEMBER( hgdc_display_pixels ); |
| 687 | UPD7220_DRAW_TEXT_LINE_MEMBER( hgdc_draw_text ); |
| 686 | 688 | |
| 687 | 689 | private: |
| 688 | 690 | UINT8 m_sdip_read(UINT16 port, UINT8 sdip_offset); |
| r29304 | r29305 | |
| 781 | 783 | return 0; |
| 782 | 784 | } |
| 783 | 785 | |
| 784 | | static UPD7220_DISPLAY_PIXELS( hgdc_display_pixels ) |
| 786 | UPD7220_DISPLAY_PIXELS_MEMBER( pc9801_state::hgdc_display_pixels ) |
| 785 | 787 | { |
| 786 | | pc9801_state *state = device->machine().driver_data<pc9801_state>(); |
| 787 | | const rgb_t *palette = state->m_palette->palette()->entry_list_raw(); |
| 788 | const rgb_t *palette = m_palette->palette()->entry_list_raw(); |
| 788 | 789 | int xi; |
| 789 | 790 | int res_x,res_y; |
| 790 | 791 | UINT8 pen; |
| 791 | 792 | UINT8 interlace_on; |
| 792 | 793 | UINT8 colors16_mode; |
| 793 | 794 | |
| 794 | | if(state->m_video_ff[DISPLAY_REG] == 0) //screen is off |
| 795 | if(m_video_ff[DISPLAY_REG] == 0) //screen is off |
| 795 | 796 | return; |
| 796 | 797 | |
| 797 | | // popmessage("%02x %d",state->m_video_ff[INTERLACE_REG],device->machine().first_screen()->visible_area().max_y + 1); |
| 798 | | // interlace_on = ((device->machine().first_screen()->visible_area().max_y + 1) >= 400) ? 1 : 0; |
| 799 | | interlace_on = state->m_video_ff[INTERLACE_REG]; |
| 800 | | colors16_mode = (state->m_ex_video_ff[ANALOG_16_MODE]) ? 16 : 8; |
| 798 | // popmessage("%02x %d",m_video_ff[INTERLACE_REG],machine().first_screen()->visible_area().max_y + 1); |
| 799 | // interlace_on = ((machine().first_screen()->visible_area().max_y + 1) >= 400) ? 1 : 0; |
| 800 | interlace_on = m_video_ff[INTERLACE_REG]; |
| 801 | colors16_mode = (m_ex_video_ff[ANALOG_16_MODE]) ? 16 : 8; |
| 801 | 802 | |
| 802 | | if(state->m_ex_video_ff[ANALOG_256_MODE]) |
| 803 | if(m_ex_video_ff[ANALOG_256_MODE]) |
| 803 | 804 | { |
| 804 | 805 | for(xi=0;xi<8;xi++) |
| 805 | 806 | { |
| 806 | 807 | res_x = x + xi; |
| 807 | 808 | res_y = y; |
| 808 | 809 | |
| 809 | | if(!device->machine().first_screen()->visible_area().contains(res_x, res_y*2+0)) |
| 810 | if(!machine().first_screen()->visible_area().contains(res_x, res_y*2+0)) |
| 810 | 811 | return; |
| 811 | 812 | |
| 812 | | pen = state->m_ext_gvram[(address*8+xi)+(state->m_vram_disp*0x40000)]; |
| 813 | pen = m_ext_gvram[(address*8+xi)+(m_vram_disp*0x40000)]; |
| 813 | 814 | |
| 814 | 815 | bitmap.pix32(res_y*2+0, res_x) = palette[pen + 0x20]; |
| 815 | | if(device->machine().first_screen()->visible_area().contains(res_x, res_y*2+1)) |
| 816 | if(machine().first_screen()->visible_area().contains(res_x, res_y*2+1)) |
| 816 | 817 | bitmap.pix32(res_y*2+1, res_x) = palette[pen + 0x20]; |
| 817 | 818 | } |
| 818 | 819 | } |
| r29304 | r29305 | |
| 823 | 824 | res_x = x + xi; |
| 824 | 825 | res_y = y; |
| 825 | 826 | |
| 826 | | pen = ((state->m_video_ram_2[(address & 0x7fff) + (0x08000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 1 : 0; |
| 827 | | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x10000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 2 : 0; |
| 828 | | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x18000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 4 : 0; |
| 829 | | if(state->m_ex_video_ff[ANALOG_16_MODE]) |
| 830 | | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 8 : 0; |
| 827 | pen = ((m_video_ram_2[(address & 0x7fff) + (0x08000) + (m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 1 : 0; |
| 828 | pen|= ((m_video_ram_2[(address & 0x7fff) + (0x10000) + (m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 2 : 0; |
| 829 | pen|= ((m_video_ram_2[(address & 0x7fff) + (0x18000) + (m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 4 : 0; |
| 830 | if(m_ex_video_ff[ANALOG_16_MODE]) |
| 831 | pen|= ((m_video_ram_2[(address & 0x7fff) + (0) + (m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 8 : 0; |
| 831 | 832 | |
| 832 | 833 | if(interlace_on) |
| 833 | 834 | { |
| 834 | | if(device->machine().first_screen()->visible_area().contains(res_x, res_y*2+0)) |
| 835 | if(machine().first_screen()->visible_area().contains(res_x, res_y*2+0)) |
| 835 | 836 | bitmap.pix32(res_y*2+0, res_x) = palette[pen + colors16_mode]; |
| 836 | 837 | /* TODO: it looks like that PC-98xx can only display even lines ... */ |
| 837 | | if(device->machine().first_screen()->visible_area().contains(res_x, res_y*2+1)) |
| 838 | if(machine().first_screen()->visible_area().contains(res_x, res_y*2+1)) |
| 838 | 839 | bitmap.pix32(res_y*2+1, res_x) = palette[pen + colors16_mode]; |
| 839 | 840 | } |
| 840 | 841 | else |
| r29304 | r29305 | |
| 843 | 844 | } |
| 844 | 845 | } |
| 845 | 846 | |
| 846 | | static UPD7220_DRAW_TEXT_LINE( hgdc_draw_text ) |
| 847 | UPD7220_DRAW_TEXT_LINE_MEMBER( pc9801_state::hgdc_draw_text ) |
| 847 | 848 | { |
| 848 | | pc9801_state *state = device->machine().driver_data<pc9801_state>(); |
| 849 | | const rgb_t *palette = state->m_palette->palette()->entry_list_raw(); |
| 849 | const rgb_t *palette = m_palette->palette()->entry_list_raw(); |
| 850 | 850 | int xi,yi; |
| 851 | 851 | int x; |
| 852 | 852 | UINT8 char_size; |
| r29304 | r29305 | |
| 856 | 856 | UINT8 kanji_sel; |
| 857 | 857 | UINT8 x_step; |
| 858 | 858 | |
| 859 | | if(state->m_video_ff[DISPLAY_REG] == 0) //screen is off |
| 859 | if(m_video_ff[DISPLAY_REG] == 0) //screen is off |
| 860 | 860 | return; |
| 861 | 861 | |
| 862 | | // interlace_on = state->m_video_ff[INTERLACE_REG]; |
| 863 | | char_size = state->m_video_ff[FONTSEL_REG] ? 16 : 8; |
| 862 | // interlace_on = m_video_ff[INTERLACE_REG]; |
| 863 | char_size = m_video_ff[FONTSEL_REG] ? 16 : 8; |
| 864 | 864 | tile = 0; |
| 865 | 865 | |
| 866 | 866 | for(x=0;x<pitch;x+=x_step) |
| r29304 | r29305 | |
| 873 | 873 | UINT8 knj_tile; |
| 874 | 874 | UINT8 gfx_mode; |
| 875 | 875 | |
| 876 | | tile_addr = addr+(x*(state->m_video_ff[WIDTH40_REG]+1)); |
| 876 | tile_addr = addr+(x*(m_video_ff[WIDTH40_REG]+1)); |
| 877 | 877 | |
| 878 | 878 | kanji_sel = 0; |
| 879 | 879 | kanji_lr = 0; |
| 880 | 880 | |
| 881 | | tile = state->m_video_ram_1[(tile_addr*2) & 0x1fff] & 0xff; |
| 882 | | knj_tile = state->m_video_ram_1[(tile_addr*2+1) & 0x1fff] & 0xff; |
| 881 | tile = m_video_ram_1[(tile_addr*2) & 0x1fff] & 0xff; |
| 882 | knj_tile = m_video_ram_1[(tile_addr*2+1) & 0x1fff] & 0xff; |
| 883 | 883 | if(knj_tile) |
| 884 | 884 | { |
| 885 | 885 | /* Note: bit 7 doesn't really count, if a kanji is enabled then the successive tile is always the second part of it. |
| r29304 | r29305 | |
| 900 | 900 | else |
| 901 | 901 | x_step = 1; |
| 902 | 902 | |
| 903 | | attr = (state->m_video_ram_1[(tile_addr*2 & 0x1fff) | 0x2000] & 0xff); |
| 903 | attr = (m_video_ram_1[(tile_addr*2 & 0x1fff) | 0x2000] & 0xff); |
| 904 | 904 | |
| 905 | 905 | secret = (attr & 1) ^ 1; |
| 906 | 906 | blink = attr & 2; |
| 907 | 907 | reverse = attr & 4; |
| 908 | 908 | u_line = attr & 8; |
| 909 | | v_line = (state->m_video_ff[ATTRSEL_REG]) ? 0 : attr & 0x10; |
| 910 | | gfx_mode = (state->m_video_ff[ATTRSEL_REG]) ? attr & 0x10 : 0; |
| 909 | v_line = (m_video_ff[ATTRSEL_REG]) ? 0 : attr & 0x10; |
| 910 | gfx_mode = (m_video_ff[ATTRSEL_REG]) ? attr & 0x10 : 0; |
| 911 | 911 | color = (attr & 0xe0) >> 5; |
| 912 | 912 | |
| 913 | 913 | for(kanji_lr=0;kanji_lr<x_step;kanji_lr++) |
| r29304 | r29305 | |
| 918 | 918 | { |
| 919 | 919 | int res_x,res_y; |
| 920 | 920 | |
| 921 | | res_x = ((x+kanji_lr)*8+xi) * (state->m_video_ff[WIDTH40_REG]+1); |
| 922 | | res_y = y*lr+yi - (state->m_txt_scroll_reg[3] & 0xf); |
| 921 | res_x = ((x+kanji_lr)*8+xi) * (m_video_ff[WIDTH40_REG]+1); |
| 922 | res_y = y*lr+yi - (m_txt_scroll_reg[3] & 0xf); |
| 923 | 923 | |
| 924 | | if(!device->machine().first_screen()->visible_area().contains(res_x, res_y)) |
| 924 | if(!machine().first_screen()->visible_area().contains(res_x, res_y)) |
| 925 | 925 | continue; |
| 926 | 926 | |
| 927 | 927 | tile_data = 0; |
| r29304 | r29305 | |
| 952 | 952 | tile_data = ((tile >> gfx_bit) & 1) ? 0xff : 0x00; |
| 953 | 953 | } |
| 954 | 954 | else if(kanji_sel) |
| 955 | | tile_data = (state->m_kanji_rom[tile*0x20+yi*2+kanji_lr]); |
| 955 | tile_data = (m_kanji_rom[tile*0x20+yi*2+kanji_lr]); |
| 956 | 956 | else |
| 957 | | tile_data = (state->m_char_rom[tile*char_size+state->m_video_ff[FONTSEL_REG]*0x800+yi]); |
| 957 | tile_data = (m_char_rom[tile*char_size+m_video_ff[FONTSEL_REG]*0x800+yi]); |
| 958 | 958 | } |
| 959 | 959 | |
| 960 | 960 | if(reverse) { tile_data^=0xff; } |
| r29304 | r29305 | |
| 962 | 962 | if(v_line) { tile_data|=8; } |
| 963 | 963 | |
| 964 | 964 | /* TODO: proper blink rate for these two */ |
| 965 | | if(cursor_on && cursor_addr == tile_addr && device->machine().first_screen()->frame_number() & 0x10) |
| 965 | if(cursor_on && cursor_addr == tile_addr && machine().first_screen()->frame_number() & 0x10) |
| 966 | 966 | tile_data^=0xff; |
| 967 | 967 | |
| 968 | | if(blink && device->machine().first_screen()->frame_number() & 0x10) |
| 968 | if(blink && machine().first_screen()->frame_number() & 0x10) |
| 969 | 969 | tile_data^=0xff; |
| 970 | 970 | |
| 971 | 971 | if(yi >= char_size) |
| r29304 | r29305 | |
| 976 | 976 | if(pen != -1) |
| 977 | 977 | bitmap.pix32(res_y, res_x) = palette[pen]; |
| 978 | 978 | |
| 979 | | if(state->m_video_ff[WIDTH40_REG]) |
| 979 | if(m_video_ff[WIDTH40_REG]) |
| 980 | 980 | { |
| 981 | | if(!device->machine().first_screen()->visible_area().contains(res_x+1, res_y)) |
| 981 | if(!machine().first_screen()->visible_area().contains(res_x+1, res_y)) |
| 982 | 982 | continue; |
| 983 | 983 | |
| 984 | 984 | if(pen != -1) |
| r29304 | r29305 | |
| 990 | 990 | } |
| 991 | 991 | } |
| 992 | 992 | |
| 993 | | static UPD7220_INTERFACE( hgdc_1_intf ) |
| 994 | | { |
| 995 | | NULL, |
| 996 | | hgdc_draw_text, |
| 997 | | DEVCB_NULL, |
| 998 | | DEVCB_DEVICE_LINE_MEMBER("upd7220_btm", upd7220_device, ext_sync_w), |
| 999 | | DEVCB_NULL |
| 1000 | | }; |
| 1001 | 993 | |
| 1002 | | static UPD7220_INTERFACE( hgdc_2_intf ) |
| 1003 | | { |
| 1004 | | hgdc_display_pixels, |
| 1005 | | NULL, |
| 1006 | | DEVCB_NULL, |
| 1007 | | DEVCB_NULL, |
| 1008 | | DEVCB_NULL |
| 1009 | | }; |
| 1010 | | |
| 1011 | | |
| 1012 | 994 | #if 0 |
| 1013 | 995 | READ8_MEMBER(pc9801_state::pc9801_xx_r) |
| 1014 | 996 | { |
| r29304 | r29305 | |
| 3672 | 3654 | MCFG_SCREEN_SIZE(640, 480) |
| 3673 | 3655 | MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 200-1) |
| 3674 | 3656 | |
| 3675 | | MCFG_UPD7220_ADD("upd7220_chr", 5000000/2, hgdc_1_intf, upd7220_1_map) |
| 3676 | | MCFG_UPD7220_ADD("upd7220_btm", 5000000/2, hgdc_2_intf, upd7220_2_map) |
| 3657 | MCFG_DEVICE_ADD("upd7220_chr", UPD7220, 5000000/2) |
| 3658 | MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_1_map) |
| 3659 | MCFG_UPD7220_DRAW_TEXT_CALLBACK_OWNER(pc9801_state, hgdc_draw_text) |
| 3660 | MCFG_UPD7220_VSYNC_CALLBACK(DEVWRITELINE("upd7220_btm", upd7220_device, ext_sync_w)) |
| 3677 | 3661 | |
| 3662 | MCFG_DEVICE_ADD("upd7220_btm", UPD7220, 5000000/2) |
| 3663 | MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_2_map) |
| 3664 | MCFG_UPD7220_DISPLAY_PIXELS_CALLBACK_OWNER(pc9801_state, hgdc_display_pixels) |
| 3665 | |
| 3678 | 3666 | MCFG_PALETTE_ADD("palette", 16) |
| 3679 | 3667 | MCFG_PALETTE_INIT_OWNER(pc9801_state,pc9801) |
| 3680 | 3668 | MCFG_GFXDECODE_ADD("gfxdecode", "palette", pc9801) |
| r29304 | r29305 | |
| 3744 | 3732 | MCFG_SCREEN_SIZE(640, 480) |
| 3745 | 3733 | MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 200-1) |
| 3746 | 3734 | |
| 3747 | | MCFG_UPD7220_ADD("upd7220_chr", 5000000/2, hgdc_1_intf, upd7220_1_map) |
| 3748 | | MCFG_UPD7220_ADD("upd7220_btm", 5000000/2, hgdc_2_intf, upd7220_2_map) |
| 3735 | MCFG_DEVICE_ADD("upd7220_chr", UPD7220, 5000000/2) |
| 3736 | MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_1_map) |
| 3737 | MCFG_UPD7220_DRAW_TEXT_CALLBACK_OWNER(pc9801_state, hgdc_draw_text) |
| 3738 | MCFG_UPD7220_VSYNC_CALLBACK(DEVWRITELINE("upd7220_btm", upd7220_device, ext_sync_w)) |
| 3749 | 3739 | |
| 3740 | MCFG_DEVICE_ADD("upd7220_btm", UPD7220, 5000000/2) |
| 3741 | MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_2_map) |
| 3742 | MCFG_UPD7220_DISPLAY_PIXELS_CALLBACK_OWNER(pc9801_state, hgdc_display_pixels) |
| 3743 | |
| 3750 | 3744 | MCFG_PALETTE_ADD("palette", 16+16) |
| 3751 | 3745 | MCFG_PALETTE_INIT_OWNER(pc9801_state,pc9801) |
| 3752 | 3746 | MCFG_GFXDECODE_ADD("gfxdecode", "palette", pc9801) |
| r29304 | r29305 | |
| 3830 | 3824 | MCFG_SCREEN_SIZE(640, 480) |
| 3831 | 3825 | MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 200-1) |
| 3832 | 3826 | |
| 3833 | | MCFG_UPD7220_ADD("upd7220_chr", 5000000/2, hgdc_1_intf, upd7220_1_map) |
| 3834 | | MCFG_UPD7220_ADD("upd7220_btm", 5000000/2, hgdc_2_intf, upd7220_2_map) |
| 3827 | MCFG_DEVICE_ADD("upd7220_chr", UPD7220, 5000000/2) |
| 3828 | MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_1_map) |
| 3829 | MCFG_UPD7220_DRAW_TEXT_CALLBACK_OWNER(pc9801_state, hgdc_draw_text) |
| 3830 | MCFG_UPD7220_VSYNC_CALLBACK(DEVWRITELINE("upd7220_btm", upd7220_device, ext_sync_w)) |
| 3835 | 3831 | |
| 3832 | MCFG_DEVICE_ADD("upd7220_btm", UPD7220, 5000000/2) |
| 3833 | MCFG_DEVICE_ADDRESS_MAP(AS_0, upd7220_2_map) |
| 3834 | MCFG_UPD7220_DISPLAY_PIXELS_CALLBACK_OWNER(pc9801_state, hgdc_display_pixels) |
| 3835 | |
| 3836 | 3836 | MCFG_PALETTE_ADD("palette", 16+16+256) |
| 3837 | 3837 | MCFG_PALETTE_INIT_OWNER(pc9801_state,pc9801) |
| 3838 | 3838 | MCFG_GFXDECODE_ADD("gfxdecode", "palette", pc9801) |
shelves/new_menus/src/mess/machine/msx_slot.c
| r29304 | r29305 | |
| 347 | 347 | state->m_cart.scc.active = 0; |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | | static READ8_HANDLER (konami_scc_bank5) |
| 350 | READ8_MEMBER(msx_state::konami_scc_bank5) |
| 351 | 351 | { |
| 352 | | msx_state *drvstate = space.machine().driver_data<msx_state>(); |
| 353 | 352 | if (offset & 0x80) |
| 354 | 353 | { |
| 355 | 354 | if ((offset & 0xff) >= 0xe0) |
| 356 | 355 | { |
| 357 | | return drvstate->m_k051649->k051649_test_r(space, offset & 0xff); |
| 356 | return m_k051649->k051649_test_r(space, offset & 0xff); |
| 358 | 357 | } |
| 359 | 358 | return 0xff; |
| 360 | 359 | } |
| 361 | 360 | else |
| 362 | 361 | { |
| 363 | | return drvstate->m_k051649->k051649_waveform_r(space, offset & 0x7f); |
| 362 | return m_k051649->k051649_waveform_r(space, offset & 0x7f); |
| 364 | 363 | } |
| 365 | 364 | } |
| 366 | 365 | |
| r29304 | r29305 | |
| 381 | 380 | msx_cpu_setbank (machine, 6, state->m_mem + state->m_banks[3] * 0x2000); |
| 382 | 381 | if (state->m_cart.scc.active ) { |
| 383 | 382 | msx_state *drvstate = machine.driver_data<msx_state>(); |
| 384 | | drvstate->m_maincpu->space(AS_PROGRAM).install_legacy_read_handler(0x9800, 0x9fff, FUNC(konami_scc_bank5)); |
| 383 | drvstate->m_maincpu->space(AS_PROGRAM).install_read_handler(0x9800, 0x9fff, read8_delegate(FUNC(msx_state::konami_scc_bank5),drvstate)); |
| 385 | 384 | } else { |
| 386 | 385 | msx_state *drvstate = machine.driver_data<msx_state>(); |
| 387 | 386 | drvstate->m_maincpu->space(AS_PROGRAM).install_read_bank(0x9800, 0x9fff,"bank7"); |
| r29304 | r29305 | |
| 1234 | 1233 | drvstate->m_wd179x->reset(); |
| 1235 | 1234 | } |
| 1236 | 1235 | |
| 1237 | | static READ8_HANDLER (msx_diskrom_page1_r) |
| 1236 | READ8_MEMBER(msx_state::msx_diskrom_page1_r) |
| 1238 | 1237 | { |
| 1239 | | msx_state *state = space.machine().driver_data<msx_state>(); |
| 1240 | 1238 | switch (offset) |
| 1241 | 1239 | { |
| 1242 | | case 0: return state->m_wd179x->status_r (space, 0); |
| 1243 | | case 1: return state->m_wd179x->track_r (space, 0); |
| 1244 | | case 2: return state->m_wd179x->sector_r (space, 0); |
| 1245 | | case 3: return state->m_wd179x->data_r (space, 0); |
| 1246 | | case 7: return state->m_dsk_stat; |
| 1240 | case 0: return m_wd179x->status_r (space, 0); |
| 1241 | case 1: return m_wd179x->track_r (space, 0); |
| 1242 | case 2: return m_wd179x->sector_r (space, 0); |
| 1243 | case 3: return m_wd179x->data_r (space, 0); |
| 1244 | case 7: return m_dsk_stat; |
| 1247 | 1245 | default: |
| 1248 | | return state->m_state[1]->m_mem[offset + 0x3ff8]; |
| 1246 | return m_state[1]->m_mem[offset + 0x3ff8]; |
| 1249 | 1247 | } |
| 1250 | 1248 | } |
| 1251 | 1249 | |
| 1252 | | static READ8_HANDLER (msx_diskrom_page2_r) |
| 1250 | READ8_MEMBER(msx_state::msx_diskrom_page2_r) |
| 1253 | 1251 | { |
| 1254 | | msx_state *state = space.machine().driver_data<msx_state>(); |
| 1255 | 1252 | if (offset >= 0x7f8) |
| 1256 | 1253 | { |
| 1257 | 1254 | switch (offset) |
| 1258 | 1255 | { |
| 1259 | 1256 | case 0x7f8: |
| 1260 | | return state->m_wd179x->status_r (space, 0); |
| 1257 | return m_wd179x->status_r (space, 0); |
| 1261 | 1258 | case 0x7f9: |
| 1262 | | return state->m_wd179x->track_r (space, 0); |
| 1259 | return m_wd179x->track_r (space, 0); |
| 1263 | 1260 | case 0x7fa: |
| 1264 | | return state->m_wd179x->sector_r (space, 0); |
| 1261 | return m_wd179x->sector_r (space, 0); |
| 1265 | 1262 | case 0x7fb: |
| 1266 | | return state->m_wd179x->data_r (space, 0); |
| 1263 | return m_wd179x->data_r (space, 0); |
| 1267 | 1264 | case 0x7ff: |
| 1268 | | return state->m_dsk_stat; |
| 1265 | return m_dsk_stat; |
| 1269 | 1266 | default: |
| 1270 | | return state->m_state[2]->m_mem[offset + 0x3800]; |
| 1267 | return m_state[2]->m_mem[offset + 0x3800]; |
| 1271 | 1268 | } |
| 1272 | 1269 | } |
| 1273 | 1270 | else |
| r29304 | r29305 | |
| 1289 | 1286 | case 1: |
| 1290 | 1287 | msx_cpu_setbank (machine, 3, state->m_mem); |
| 1291 | 1288 | msx_cpu_setbank (machine, 4, state->m_mem + 0x2000); |
| 1292 | | space.install_legacy_read_handler(0x7ff8, 0x7fff, FUNC(msx_diskrom_page1_r)); |
| 1289 | space.install_read_handler(0x7ff8, 0x7fff, read8_delegate(FUNC(msx_state::msx_diskrom_page1_r),drvstate)); |
| 1293 | 1290 | break; |
| 1294 | 1291 | case 2: |
| 1295 | 1292 | msx_cpu_setbank (machine, 5, drvstate->m_empty); |
| 1296 | 1293 | msx_cpu_setbank (machine, 6, drvstate->m_empty); |
| 1297 | | space.install_legacy_read_handler(0xb800, 0xbfff, FUNC(msx_diskrom_page2_r)); |
| 1294 | space.install_read_handler(0xb800, 0xbfff, read8_delegate(FUNC(msx_state::msx_diskrom_page2_r),drvstate)); |
| 1298 | 1295 | break; |
| 1299 | 1296 | case 3: |
| 1300 | 1297 | msx_cpu_setbank (machine, 7, drvstate->m_empty); |
| r29304 | r29305 | |
| 1361 | 1358 | drvstate->m_wd179x->reset(); |
| 1362 | 1359 | } |
| 1363 | 1360 | |
| 1364 | | static READ8_HANDLER (msx_diskrom2_page1_r) |
| 1361 | READ8_MEMBER(msx_state::msx_diskrom2_page1_r) |
| 1365 | 1362 | { |
| 1366 | | msx_state *state = space.machine().driver_data<msx_state>(); |
| 1367 | 1363 | switch (offset) |
| 1368 | 1364 | { |
| 1369 | | case 0: return state->m_wd179x->status_r(space, 0); |
| 1370 | | case 1: return state->m_wd179x->track_r(space, 0); |
| 1371 | | case 2: return state->m_wd179x->sector_r(space, 0); |
| 1372 | | case 3: return state->m_wd179x->data_r(space, 0); |
| 1373 | | case 4: return state->m_dsk_stat; |
| 1365 | case 0: return m_wd179x->status_r(space, 0); |
| 1366 | case 1: return m_wd179x->track_r(space, 0); |
| 1367 | case 2: return m_wd179x->sector_r(space, 0); |
| 1368 | case 3: return m_wd179x->data_r(space, 0); |
| 1369 | case 4: return m_dsk_stat; |
| 1374 | 1370 | default: |
| 1375 | | return state->m_state[1]->m_mem[offset + 0x3ff8]; |
| 1371 | return m_state[1]->m_mem[offset + 0x3ff8]; |
| 1376 | 1372 | } |
| 1377 | 1373 | } |
| 1378 | 1374 | |
| 1379 | | static READ8_HANDLER (msx_diskrom2_page2_r) |
| 1375 | READ8_MEMBER(msx_state::msx_diskrom2_page2_r) |
| 1380 | 1376 | { |
| 1381 | | msx_state *state = space.machine().driver_data<msx_state>(); |
| 1382 | 1377 | if (offset >= 0x7b8) |
| 1383 | 1378 | { |
| 1384 | 1379 | switch (offset) |
| 1385 | 1380 | { |
| 1386 | 1381 | case 0x7b8: |
| 1387 | | return state->m_wd179x->status_r (space, 0); |
| 1382 | return m_wd179x->status_r (space, 0); |
| 1388 | 1383 | case 0x7b9: |
| 1389 | | return state->m_wd179x->track_r (space, 0); |
| 1384 | return m_wd179x->track_r (space, 0); |
| 1390 | 1385 | case 0x7ba: |
| 1391 | | return state->m_wd179x->sector_r (space, 0); |
| 1386 | return m_wd179x->sector_r (space, 0); |
| 1392 | 1387 | case 0x7bb: |
| 1393 | | return state->m_wd179x->data_r (space, 0); |
| 1388 | return m_wd179x->data_r (space, 0); |
| 1394 | 1389 | case 0x7bc: |
| 1395 | | return state->m_dsk_stat; |
| 1390 | return m_dsk_stat; |
| 1396 | 1391 | default: |
| 1397 | | return state->m_state[2]->m_mem[offset + 0x3800]; |
| 1392 | return m_state[2]->m_mem[offset + 0x3800]; |
| 1398 | 1393 | } |
| 1399 | 1394 | } |
| 1400 | 1395 | else |
| r29304 | r29305 | |
| 1416 | 1411 | case 1: |
| 1417 | 1412 | msx_cpu_setbank (machine, 3, state->m_mem); |
| 1418 | 1413 | msx_cpu_setbank (machine, 4, state->m_mem + 0x2000); |
| 1419 | | space.install_legacy_read_handler(0x7fb8, 0x7fbc, FUNC(msx_diskrom2_page1_r)); |
| 1414 | space.install_read_handler(0x7fb8, 0x7fbc, read8_delegate(FUNC(msx_state::msx_diskrom2_page1_r),drvstate)); |
| 1420 | 1415 | break; |
| 1421 | 1416 | case 2: |
| 1422 | 1417 | msx_cpu_setbank (machine, 5, drvstate->m_empty); |
| 1423 | 1418 | msx_cpu_setbank (machine, 6, drvstate->m_empty); |
| 1424 | | space.install_legacy_read_handler(0xb800, 0xbfbc, FUNC(msx_diskrom2_page2_r)); |
| 1419 | space.install_read_handler(0xb800, 0xbfbc, read8_delegate(FUNC(msx_state::msx_diskrom2_page2_r),drvstate)); |
| 1425 | 1420 | break; |
| 1426 | 1421 | case 3: |
| 1427 | 1422 | msx_cpu_setbank (machine, 7, drvstate->m_empty); |
| r29304 | r29305 | |
| 2181 | 2176 | state->m_cart.sccp.sccp_active = 0; |
| 2182 | 2177 | } |
| 2183 | 2178 | |
| 2184 | | static READ8_HANDLER (soundcartridge_scc) |
| 2179 | READ8_MEMBER(msx_state::soundcartridge_scc) |
| 2185 | 2180 | { |
| 2186 | | msx_state *state = space.machine().driver_data<msx_state>(); |
| 2187 | 2181 | int reg; |
| 2188 | 2182 | |
| 2189 | 2183 | |
| 2190 | 2184 | if (offset >= 0x7e0) |
| 2191 | 2185 | { |
| 2192 | | return state->m_state[2]->m_mem[ |
| 2193 | | state->m_state[2]->m_banks[2] * 0x2000 + 0x1800 + offset]; |
| 2186 | return m_state[2]->m_mem[ |
| 2187 | m_state[2]->m_banks[2] * 0x2000 + 0x1800 + offset]; |
| 2194 | 2188 | } |
| 2195 | 2189 | |
| 2196 | 2190 | reg = offset & 0xff; |
| 2197 | 2191 | |
| 2198 | 2192 | if (reg < 0x80) |
| 2199 | 2193 | { |
| 2200 | | return state->m_k051649->k051649_waveform_r (space, reg); |
| 2194 | return m_k051649->k051649_waveform_r (space, reg); |
| 2201 | 2195 | } |
| 2202 | 2196 | else if (reg < 0xa0) |
| 2203 | 2197 | { |
| r29304 | r29305 | |
| 2206 | 2200 | else if (reg < 0xc0) |
| 2207 | 2201 | { |
| 2208 | 2202 | /* read wave 5 */ |
| 2209 | | return state->m_k051649->k051649_waveform_r (space, 0x80 + (reg & 0x1f)); |
| 2203 | return m_k051649->k051649_waveform_r (space, 0x80 + (reg & 0x1f)); |
| 2210 | 2204 | } |
| 2211 | 2205 | else if (reg < 0xe0) |
| 2212 | 2206 | { |
| 2213 | | return state->m_k051649->k051649_test_r (space, reg); |
| 2207 | return m_k051649->k051649_test_r (space, reg); |
| 2214 | 2208 | } |
| 2215 | 2209 | |
| 2216 | 2210 | return 0xff; |
| 2217 | 2211 | } |
| 2218 | 2212 | |
| 2219 | | static READ8_HANDLER (soundcartridge_sccp) |
| 2213 | READ8_MEMBER(msx_state::soundcartridge_sccp) |
| 2220 | 2214 | { |
| 2221 | | msx_state *state = space.machine().driver_data<msx_state>(); |
| 2222 | 2215 | int reg; |
| 2223 | 2216 | |
| 2224 | 2217 | if (offset >= 0x7e0) |
| 2225 | 2218 | { |
| 2226 | | return state->m_state[2]->m_mem[ |
| 2227 | | state->m_state[2]->m_banks[3] * 0x2000 + 0x1800 + offset]; |
| 2219 | return m_state[2]->m_mem[ |
| 2220 | m_state[2]->m_banks[3] * 0x2000 + 0x1800 + offset]; |
| 2228 | 2221 | } |
| 2229 | 2222 | |
| 2230 | 2223 | reg = offset & 0xff; |
| 2231 | 2224 | |
| 2232 | 2225 | if (reg < 0xa0) |
| 2233 | 2226 | { |
| 2234 | | return state->m_k051649->k051649_waveform_r (space, reg); |
| 2227 | return m_k051649->k051649_waveform_r (space, reg); |
| 2235 | 2228 | } |
| 2236 | 2229 | else if (reg >= 0xc0 && reg < 0xe0) |
| 2237 | 2230 | { |
| 2238 | | return state->m_k051649->k051649_test_r (space, reg); |
| 2231 | return m_k051649->k051649_test_r (space, reg); |
| 2239 | 2232 | } |
| 2240 | 2233 | |
| 2241 | 2234 | return 0xff; |
| r29304 | r29305 | |
| 2259 | 2252 | msx_cpu_setbank (machine, 5, state->m_mem + state->m_banks[2] * 0x2000); |
| 2260 | 2253 | msx_cpu_setbank (machine, 6, state->m_mem + state->m_banks[3] * 0x2000); |
| 2261 | 2254 | if (state->m_cart.sccp.scc_active) { |
| 2262 | | space.install_legacy_read_handler(0x9800, 0x9fff, FUNC(soundcartridge_scc)); |
| 2255 | space.install_read_handler(0x9800, 0x9fff, read8_delegate(FUNC(msx_state::soundcartridge_scc),drvstate)); |
| 2263 | 2256 | } else { |
| 2264 | 2257 | space.install_read_bank(0x9800, 0x9fff, "bank7"); |
| 2265 | 2258 | } |
| 2266 | 2259 | if (state->m_cart.sccp.scc_active) { |
| 2267 | | space.install_legacy_read_handler(0xb800, 0xbfff, FUNC(soundcartridge_sccp)); |
| 2260 | space.install_read_handler(0xb800, 0xbfff, read8_delegate(FUNC(msx_state::soundcartridge_sccp),drvstate)); |
| 2268 | 2261 | } else { |
| 2269 | 2262 | space.install_read_bank(0xb800, 0xbfff, "bank9"); |
| 2270 | 2263 | } |
shelves/new_menus/src/mess/machine/swtpc09.c
| r29304 | r29305 | |
| 24 | 24 | #define LOG(x) do { if (VERBOSE) logerror x; } while (0) |
| 25 | 25 | |
| 26 | 26 | |
| 27 | | /* channel_data structure holds info about each 6844 DMA channel */ |
| 28 | | typedef struct m6844_channel_data |
| 29 | | { |
| 30 | | int active; |
| 31 | | int address; |
| 32 | | int counter; |
| 33 | | UINT8 control; |
| 34 | | int start_address; |
| 35 | | int start_counter; |
| 36 | | } m6844_channel_data; |
| 37 | | |
| 38 | | /* 6844 description */ |
| 39 | | static m6844_channel_data m6844_channel[4]; |
| 40 | | static UINT8 m6844_priority; |
| 41 | | static UINT8 m6844_interrupt; |
| 42 | | static UINT8 m6844_chain; |
| 43 | | |
| 44 | 27 | /******* MC6840 PTM on MPID Board *******/ |
| 45 | 28 | /* 6840 PTM interface */ |
| 46 | 29 | const ptm6840_interface swtpc09_6840_intf = |
| r29304 | r29305 | |
| 206 | 189 | |
| 207 | 190 | offset = (m_fdc_dma_address_reg & 0x0f)<<16; |
| 208 | 191 | |
| 209 | | if (m6844_channel[0].active == 1) //active dma transfer |
| 192 | if (m_m6844_channel[0].active == 1) //active dma transfer |
| 210 | 193 | { |
| 211 | | if (!(m6844_channel[0].control & 0x01)) // dma write to memory |
| 194 | if (!(m_m6844_channel[0].control & 0x01)) // dma write to memory |
| 212 | 195 | { |
| 213 | 196 | UINT8 data = m_fdc->data_r(space, 0); |
| 214 | 197 | |
| 215 | | LOG(("swtpc09_dma_write_mem %05X %02X\n", m6844_channel[0].address + offset, data)); |
| 216 | | RAM[m6844_channel[0].address + offset] = data; |
| 198 | LOG(("swtpc09_dma_write_mem %05X %02X\n", m_m6844_channel[0].address + offset, data)); |
| 199 | RAM[m_m6844_channel[0].address + offset] = data; |
| 217 | 200 | } |
| 218 | 201 | else |
| 219 | 202 | { |
| 220 | | UINT8 data = RAM[m6844_channel[0].address + offset]; |
| 203 | UINT8 data = RAM[m_m6844_channel[0].address + offset]; |
| 221 | 204 | |
| 222 | 205 | m_fdc->data_w(space, 0, data); |
| 223 | | //LOG(("swtpc09_dma_read_mem %04X %02X\n", m6844_channel[0].address, data)); |
| 206 | //LOG(("swtpc09_dma_read_mem %04X %02X\n", m_m6844_channel[0].address, data)); |
| 224 | 207 | } |
| 225 | 208 | |
| 226 | | m6844_channel[0].address++; |
| 227 | | m6844_channel[0].counter--; |
| 209 | m_m6844_channel[0].address++; |
| 210 | m_m6844_channel[0].counter--; |
| 228 | 211 | |
| 229 | | if (m6844_channel[0].counter == 0) // dma transfer has finished |
| 212 | if (m_m6844_channel[0].counter == 0) // dma transfer has finished |
| 230 | 213 | { |
| 231 | | m6844_channel[0].control |= 0x80; // set dend flag |
| 232 | | if (m6844_interrupt & 0x01) // interrupt for channel 0 is enabled? |
| 214 | m_m6844_channel[0].control |= 0x80; // set dend flag |
| 215 | if (m_m6844_interrupt & 0x01) // interrupt for channel 0 is enabled? |
| 233 | 216 | { |
| 234 | | m6844_interrupt |= 0x80; // set bit 7 to indicate active interrupt |
| 217 | m_m6844_interrupt |= 0x80; // set bit 7 to indicate active interrupt |
| 235 | 218 | swtpc09_irq_handler(DMAC_IRQ, ASSERT_LINE); |
| 236 | 219 | } |
| 237 | 220 | } |
| r29304 | r29305 | |
| 630 | 613 | { |
| 631 | 614 | if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 conroller this is the map |
| 632 | 615 | { |
| 633 | | mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); |
| 616 | mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); |
| 634 | 617 | mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); |
| 635 | 618 | mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); |
| 636 | 619 | mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); |
| r29304 | r29305 | |
| 640 | 623 | } |
| 641 | 624 | else if (m_system_type == FLEX_DC4_PIAIDE) // 2k ram for piaide on s09 board |
| 642 | 625 | { |
| 643 | | //mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); |
| 644 | | //mem.install_legacy_readwrite_handler(*fdc, logical_address+0x020, logical_address+0x023, 0, 0, FUNC(wd17xx_r), FUNC(wd17xx_w)); |
| 626 | //mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); |
| 627 | //mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); |
| 645 | 628 | //mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); |
| 646 | 629 | //mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); |
| 647 | 630 | mem.install_ram(logical_address+0x000, logical_address+0x7ff, &RAM[0xf000]); |
| r29304 | r29305 | |
| 649 | 632 | mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); |
| 650 | 633 | } |
| 651 | 634 | else // assume DMF3 controller |
| 652 | | { |
| 653 | | mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); |
| 635 | { |
| 636 | mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); |
| 654 | 637 | mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); |
| 655 | 638 | mem.install_readwrite_handler(logical_address+0x024, logical_address+0x024, read8_delegate(FUNC(swtpc09_state::dmf3_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_control_reg_w),this)); |
| 656 | 639 | mem.install_readwrite_handler(logical_address+0x025, logical_address+0x025, read8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_w),this)); |
| r29304 | r29305 | |
| 688 | 671 | |
| 689 | 672 | /* MC6844 DMA controller I/O */ |
| 690 | 673 | |
| 691 | | READ8_HANDLER( m6844_r ) |
| 674 | READ8_MEMBER( swtpc09_state::m6844_r ) |
| 692 | 675 | { |
| 693 | 676 | UINT8 result = 0; |
| 694 | | swtpc09_state *state = space.machine().driver_data<swtpc09_state>(); |
| 695 | 677 | |
| 696 | 678 | |
| 697 | 679 | /* switch off the offset we were given */ |
| r29304 | r29305 | |
| 702 | 684 | case 0x04: |
| 703 | 685 | case 0x08: |
| 704 | 686 | case 0x0c: |
| 705 | | result = m6844_channel[offset / 4].address >> 8; |
| 687 | result = m_m6844_channel[offset / 4].address >> 8; |
| 706 | 688 | break; |
| 707 | 689 | |
| 708 | 690 | /* lower byte of address */ |
| r29304 | r29305 | |
| 710 | 692 | case 0x05: |
| 711 | 693 | case 0x09: |
| 712 | 694 | case 0x0d: |
| 713 | | result = m6844_channel[offset / 4].address & 0xff; |
| 695 | result = m_m6844_channel[offset / 4].address & 0xff; |
| 714 | 696 | break; |
| 715 | 697 | |
| 716 | 698 | /* upper byte of counter */ |
| r29304 | r29305 | |
| 718 | 700 | case 0x06: |
| 719 | 701 | case 0x0a: |
| 720 | 702 | case 0x0e: |
| 721 | | result = m6844_channel[offset / 4].counter >> 8; |
| 703 | result = m_m6844_channel[offset / 4].counter >> 8; |
| 722 | 704 | break; |
| 723 | 705 | |
| 724 | 706 | /* lower byte of counter */ |
| r29304 | r29305 | |
| 726 | 708 | case 0x07: |
| 727 | 709 | case 0x0b: |
| 728 | 710 | case 0x0f: |
| 729 | | result = m6844_channel[offset / 4].counter & 0xff; |
| 711 | result = m_m6844_channel[offset / 4].counter & 0xff; |
| 730 | 712 | break; |
| 731 | 713 | |
| 732 | 714 | /* channel control */ |
| r29304 | r29305 | |
| 734 | 716 | case 0x11: |
| 735 | 717 | case 0x12: |
| 736 | 718 | case 0x13: |
| 737 | | result = m6844_channel[offset - 0x10].control; |
| 719 | result = m_m6844_channel[offset - 0x10].control; |
| 738 | 720 | |
| 739 | 721 | /* a read here clears the DMA end flag */ |
| 740 | | m6844_channel[offset - 0x10].control &= ~0x80; |
| 741 | | if (m6844_interrupt && 0x80) // if interrupt is active, then clear |
| 722 | m_m6844_channel[offset - 0x10].control &= ~0x80; |
| 723 | if (m_m6844_interrupt && 0x80) // if interrupt is active, then clear |
| 742 | 724 | { |
| 743 | | state->swtpc09_irq_handler(0x01, CLEAR_LINE); |
| 744 | | m6844_interrupt &= 0x7f; // clear interrupt indication bit 7 |
| 725 | swtpc09_irq_handler(0x01, CLEAR_LINE); |
| 726 | m_m6844_interrupt &= 0x7f; // clear interrupt indication bit 7 |
| 745 | 727 | LOG(("swtpc09_6844_r interrupt cleared \n")); |
| 746 | 728 | } |
| 747 | 729 | break; |
| 748 | 730 | |
| 749 | 731 | /* priority control */ |
| 750 | 732 | case 0x14: |
| 751 | | result = m6844_priority; |
| 733 | result = m_m6844_priority; |
| 752 | 734 | break; |
| 753 | 735 | |
| 754 | 736 | /* interrupt control */ |
| 755 | 737 | case 0x15: |
| 756 | | result = m6844_interrupt; |
| 738 | result = m_m6844_interrupt; |
| 757 | 739 | break; |
| 758 | 740 | |
| 759 | 741 | /* chaining control */ |
| 760 | 742 | case 0x16: |
| 761 | | result = m6844_chain; |
| 743 | result = m_m6844_chain; |
| 762 | 744 | break; |
| 763 | 745 | |
| 764 | 746 | /* 0x17-0x1f not used */ |
| r29304 | r29305 | |
| 766 | 748 | } |
| 767 | 749 | //LOG(("swtpc09_6844_r %02X %02X\n", offset, result & 0xff)); |
| 768 | 750 | |
| 769 | | if (state->m_system_type == UNIFLEX_DMF2 || state->m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 751 | if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 770 | 752 | { |
| 771 | 753 | return ~result & 0xff; |
| 772 | 754 | } |
| r29304 | r29305 | |
| 777 | 759 | } |
| 778 | 760 | |
| 779 | 761 | |
| 780 | | WRITE8_HANDLER( m6844_w ) |
| 762 | WRITE8_MEMBER( swtpc09_state::m6844_w ) |
| 781 | 763 | { |
| 782 | 764 | int i; |
| 783 | | swtpc09_state *state = space.machine().driver_data<swtpc09_state>(); |
| 784 | 765 | |
| 785 | | if (state->m_system_type == UNIFLEX_DMF2 || state->m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 766 | if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 786 | 767 | data = ~data & 0xff; |
| 787 | 768 | |
| 788 | 769 | LOG(("swtpc09_6844_w %02X %02X\n", offset, data)); |
| r29304 | r29305 | |
| 794 | 775 | case 0x04: |
| 795 | 776 | case 0x08: |
| 796 | 777 | case 0x0c: |
| 797 | | m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff) | (data << 8); |
| 778 | m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff) | (data << 8); |
| 798 | 779 | break; |
| 799 | 780 | |
| 800 | 781 | /* lower byte of address */ |
| r29304 | r29305 | |
| 802 | 783 | case 0x05: |
| 803 | 784 | case 0x09: |
| 804 | 785 | case 0x0d: |
| 805 | | m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff00) | (data & 0xff); |
| 786 | m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff00) | (data & 0xff); |
| 806 | 787 | break; |
| 807 | 788 | |
| 808 | 789 | /* upper byte of counter */ |
| r29304 | r29305 | |
| 810 | 791 | case 0x06: |
| 811 | 792 | case 0x0a: |
| 812 | 793 | case 0x0e: |
| 813 | | m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff) | (data << 8); |
| 794 | m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff) | (data << 8); |
| 814 | 795 | break; |
| 815 | 796 | |
| 816 | 797 | /* lower byte of counter */ |
| r29304 | r29305 | |
| 818 | 799 | case 0x07: |
| 819 | 800 | case 0x0b: |
| 820 | 801 | case 0x0f: |
| 821 | | m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff); |
| 802 | m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff); |
| 822 | 803 | break; |
| 823 | 804 | |
| 824 | 805 | /* channel control */ |
| r29304 | r29305 | |
| 826 | 807 | case 0x11: |
| 827 | 808 | case 0x12: |
| 828 | 809 | case 0x13: |
| 829 | | m6844_channel[offset - 0x10].control = (m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f); |
| 810 | m_m6844_channel[offset - 0x10].control = (m_m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f); |
| 830 | 811 | break; |
| 831 | 812 | |
| 832 | 813 | /* priority control */ |
| 833 | 814 | case 0x14: |
| 834 | | m6844_priority = data; |
| 815 | m_m6844_priority = data; |
| 835 | 816 | |
| 836 | 817 | /* update each channel */ |
| 837 | 818 | for (i = 0; i < 4; i++) |
| 838 | 819 | { |
| 839 | 820 | /* if we're going active... */ |
| 840 | | if (!m6844_channel[i].active && (data & (1 << i))) |
| 821 | if (!m_m6844_channel[i].active && (data & (1 << i))) |
| 841 | 822 | { |
| 842 | 823 | /* mark us active */ |
| 843 | | m6844_channel[i].active = 1; |
| 824 | m_m6844_channel[i].active = 1; |
| 844 | 825 | LOG(("swtpc09_dma_channel active %02X\n", i)); |
| 845 | 826 | |
| 846 | 827 | /* set the DMA busy bit and clear the DMA end bit */ |
| 847 | | m6844_channel[i].control |= 0x40; |
| 848 | | m6844_channel[i].control &= ~0x80; |
| 828 | m_m6844_channel[i].control |= 0x40; |
| 829 | m_m6844_channel[i].control &= ~0x80; |
| 849 | 830 | |
| 850 | 831 | /* set the starting address, counter, and time */ |
| 851 | | m6844_channel[i].start_address = m6844_channel[i].address; |
| 852 | | m6844_channel[i].start_counter = m6844_channel[i].counter; |
| 832 | m_m6844_channel[i].start_address = m_m6844_channel[i].address; |
| 833 | m_m6844_channel[i].start_counter = m_m6844_channel[i].counter; |
| 853 | 834 | |
| 854 | 835 | |
| 855 | 836 | /* generate and play the sample */ |
| r29304 | r29305 | |
| 857 | 838 | } |
| 858 | 839 | |
| 859 | 840 | /* if we're going inactive... */ |
| 860 | | else if (m6844_channel[i].active && !(data & (1 << i))) |
| 841 | else if (m_m6844_channel[i].active && !(data & (1 << i))) |
| 861 | 842 | { |
| 862 | 843 | /* mark us inactive */ |
| 863 | | m6844_channel[i].active = 0; |
| 844 | m_m6844_channel[i].active = 0; |
| 864 | 845 | } |
| 865 | 846 | } |
| 866 | 847 | break; |
| 867 | 848 | |
| 868 | 849 | /* interrupt control */ |
| 869 | 850 | case 0x15: |
| 870 | | m6844_interrupt = (m6844_interrupt & 0x80) | (data & 0x7f); |
| 871 | | LOG(("swtpc09_m6844_interrupt_w %02X\n", m6844_interrupt)); |
| 851 | m_m6844_interrupt = (m_m6844_interrupt & 0x80) | (data & 0x7f); |
| 852 | LOG(("swtpc09_m_m6844_interrupt_w %02X\n", m_m6844_interrupt)); |
| 872 | 853 | break; |
| 873 | 854 | |
| 874 | 855 | /* chaining control */ |
| 875 | 856 | case 0x16: |
| 876 | | m6844_chain = data; |
| 857 | m_m6844_chain = data; |
| 877 | 858 | break; |
| 878 | 859 | |
| 879 | 860 | /* 0x17-0x1f not used */ |
| r29304 | r29305 | |
| 895 | 876 | /* reset the 6844 */ |
| 896 | 877 | for (i = 0; i < 4; i++) |
| 897 | 878 | { |
| 898 | | m6844_channel[i].active = 0; |
| 899 | | m6844_channel[i].control = 0x00; |
| 879 | m_m6844_channel[i].active = 0; |
| 880 | m_m6844_channel[i].control = 0x00; |
| 900 | 881 | } |
| 901 | | m6844_priority = 0x00; |
| 902 | | m6844_interrupt = 0x00; |
| 903 | | m6844_chain = 0x00; |
| 882 | m_m6844_priority = 0x00; |
| 883 | m_m6844_interrupt = 0x00; |
| 884 | m_m6844_chain = 0x00; |
| 904 | 885 | |
| 905 | 886 | } |
| 906 | 887 | |
| r29304 | r29305 | |
| 917 | 898 | /* reset the 6844 */ |
| 918 | 899 | for (i = 0; i < 4; i++) |
| 919 | 900 | { |
| 920 | | m6844_channel[i].active = 0; |
| 921 | | m6844_channel[i].control = 0x00; |
| 901 | m_m6844_channel[i].active = 0; |
| 902 | m_m6844_channel[i].control = 0x00; |
| 922 | 903 | } |
| 923 | | m6844_priority = 0x00; |
| 924 | | m6844_interrupt = 0x00; |
| 925 | | m6844_chain = 0x00; |
| 904 | m_m6844_priority = 0x00; |
| 905 | m_m6844_interrupt = 0x00; |
| 906 | m_m6844_chain = 0x00; |
| 926 | 907 | |
| 927 | 908 | } |
| 928 | 909 | |
| r29304 | r29305 | |
| 939 | 920 | /* reset the 6844 */ |
| 940 | 921 | for (i = 0; i < 4; i++) |
| 941 | 922 | { |
| 942 | | m6844_channel[i].active = 0; |
| 943 | | m6844_channel[i].control = 0x00; |
| 923 | m_m6844_channel[i].active = 0; |
| 924 | m_m6844_channel[i].control = 0x00; |
| 944 | 925 | } |
| 945 | | m6844_priority = 0x00; |
| 946 | | m6844_interrupt = 0x00; |
| 947 | | m6844_chain = 0x00; |
| 926 | m_m6844_priority = 0x00; |
| 927 | m_m6844_interrupt = 0x00; |
| 928 | m_m6844_chain = 0x00; |
| 948 | 929 | |
| 949 | 930 | } |
| 950 | 931 | |
| r29304 | r29305 | |
| 963 | 944 | /* reset the 6844 */ |
| 964 | 945 | for (i = 0; i < 4; i++) |
| 965 | 946 | { |
| 966 | | m6844_channel[i].active = 0; |
| 967 | | m6844_channel[i].control = 0x00; |
| 947 | m_m6844_channel[i].active = 0; |
| 948 | m_m6844_channel[i].control = 0x00; |
| 968 | 949 | } |
| 969 | | m6844_priority = 0x00; |
| 970 | | m6844_interrupt = 0x00; |
| 971 | | m6844_chain = 0x00; |
| 950 | m_m6844_priority = 0x00; |
| 951 | m_m6844_interrupt = 0x00; |
| 952 | m_m6844_chain = 0x00; |
| 972 | 953 | |
| 973 | 954 | } |
shelves/new_menus/src/mame/video/snes.c
| r29304 | r29305 | |
| 81 | 81 | #define SNES_CLIP_ALWAYS 3 |
| 82 | 82 | |
| 83 | 83 | #if SNES_LAYER_DEBUG |
| 84 | | struct DEBUGOPTS |
| 85 | | { |
| 86 | | UINT8 bg_disabled[5]; |
| 87 | | UINT8 mode_disabled[8]; |
| 88 | | UINT8 draw_subscreen; |
| 89 | | UINT8 windows_disabled; |
| 90 | | UINT8 mosaic_disabled; |
| 91 | | UINT8 colormath_disabled; |
| 92 | | UINT8 sprite_reversed; |
| 93 | | UINT8 select_pri[5]; |
| 94 | | }; |
| 95 | | static struct DEBUGOPTS debug_options; |
| 96 | 84 | /* red green blue purple yellow cyan grey white */ |
| 97 | 85 | static const UINT16 dbg_mode_colours[8] = { 0x1f, 0x3e0, 0x7c00, 0x7c1f, 0x3ff, 0x7fe0, 0x4210, 0x7fff }; |
| 98 | 86 | #endif /* SNES_LAYER_DEBUG */ |
| r29304 | r29305 | |
| 197 | 185 | UINT8 clipmask = m_clipmasks[layer][ii]; |
| 198 | 186 | |
| 199 | 187 | #if SNES_LAYER_DEBUG |
| 200 | | if (debug_options.windows_disabled) |
| 188 | if (m_debug_options.windows_disabled) |
| 201 | 189 | clipmask = 0xff; |
| 202 | 190 | #endif /* SNES_LAYER_DEBUG */ |
| 203 | 191 | |
| r29304 | r29305 | |
| 232 | 220 | UINT8 clipmask = m_clipmasks[layer][ii >> 1]; |
| 233 | 221 | |
| 234 | 222 | #if SNES_LAYER_DEBUG |
| 235 | | if (debug_options.windows_disabled) |
| 223 | if (m_debug_options.windows_disabled) |
| 236 | 224 | clipmask = 0xff; |
| 237 | 225 | #endif /* SNES_LAYER_DEBUG */ |
| 238 | 226 | |
| r29304 | r29305 | |
| 266 | 254 | UINT8 clipmask = m_clipmasks[SNES_OAM][pos]; |
| 267 | 255 | |
| 268 | 256 | #if SNES_LAYER_DEBUG |
| 269 | | if (debug_options.windows_disabled) |
| 257 | if (m_debug_options.windows_disabled) |
| 270 | 258 | clipmask = 0xff; |
| 271 | 259 | #endif /* SNES_LAYER_DEBUG */ |
| 272 | 260 | |
| r29304 | r29305 | |
| 312 | 300 | UINT8 mosaic = m_layer[layer].mosaic_enabled; |
| 313 | 301 | |
| 314 | 302 | #if SNES_LAYER_DEBUG |
| 315 | | if (debug_options.mosaic_disabled) |
| 303 | if (m_debug_options.mosaic_disabled) |
| 316 | 304 | mosaic = 0; |
| 317 | 305 | #endif /* SNES_LAYER_DEBUG */ |
| 318 | 306 | |
| r29304 | r29305 | |
| 415 | 403 | UINT8 color_shift = 2 << color_depth; |
| 416 | 404 | |
| 417 | 405 | #if SNES_LAYER_DEBUG |
| 418 | | if (debug_options.bg_disabled[layer]) |
| 406 | if (m_debug_options.bg_disabled[layer]) |
| 419 | 407 | return; |
| 420 | 408 | #endif /* SNES_LAYER_DEBUG */ |
| 421 | 409 | |
| r29304 | r29305 | |
| 517 | 505 | |
| 518 | 506 | #if SNES_LAYER_DEBUG |
| 519 | 507 | /* if we want to draw only one of the priorities of this layer */ |
| 520 | | if (((debug_options.select_pri[layer] & 0x01) && (priority == priority_a)) || |
| 521 | | ((debug_options.select_pri[layer] & 0x02) && (priority == priority_b))) |
| 508 | if (((m_debug_options.select_pri[layer] & 0x01) && (priority == priority_a)) || |
| 509 | ((m_debug_options.select_pri[layer] & 0x02) && (priority == priority_b))) |
| 522 | 510 | { |
| 523 | 511 | if (!hires && tile_size) |
| 524 | 512 | ii += 16; |
| r29304 | r29305 | |
| 597 | 585 | int screen; |
| 598 | 586 | |
| 599 | 587 | #if SNES_LAYER_DEBUG |
| 600 | | if (debug_options.bg_disabled[layer]) |
| 588 | if (m_debug_options.bg_disabled[layer]) |
| 601 | 589 | return; |
| 602 | 590 | #endif /* SNES_LAYER_DEBUG */ |
| 603 | 591 | |
| r29304 | r29305 | |
| 659 | 647 | } |
| 660 | 648 | |
| 661 | 649 | #if SNES_LAYER_DEBUG |
| 662 | | if (debug_options.mosaic_disabled) |
| 650 | if (m_debug_options.mosaic_disabled) |
| 663 | 651 | { |
| 664 | 652 | mosaic_x = m_mosaic_table[0]; |
| 665 | 653 | mosaic_y = m_mosaic_table[0]; |
| r29304 | r29305 | |
| 712 | 700 | |
| 713 | 701 | #if SNES_LAYER_DEBUG |
| 714 | 702 | /* if we want to draw only one of the priorities of this layer */ |
| 715 | | if (((debug_options.select_pri[layer] & 0x01) && (priority == priority_a)) || |
| 716 | | ((debug_options.select_pri[layer] & 0x02) && (priority == priority_b))) |
| 703 | if (((m_debug_options.select_pri[layer] & 0x01) && (priority == priority_a)) || |
| 704 | ((m_debug_options.select_pri[layer] & 0x02) && (priority == priority_b))) |
| 717 | 705 | continue; |
| 718 | 706 | #endif /* SNES_LAYER_DEBUG */ |
| 719 | 707 | } |
| r29304 | r29305 | |
| 726 | 714 | UINT8 clipmask = m_clipmasks[layer][xpos]; |
| 727 | 715 | |
| 728 | 716 | #if SNES_LAYER_DEBUG |
| 729 | | if (debug_options.windows_disabled) |
| 717 | if (m_debug_options.windows_disabled) |
| 730 | 718 | clipmask = 0xff; |
| 731 | 719 | #endif /* SNES_LAYER_DEBUG */ |
| 732 | 720 | |
| r29304 | r29305 | |
| 784 | 772 | * test their priority with the one of the correct sprite - see update_objects. |
| 785 | 773 | *************************************************************************************************/ |
| 786 | 774 | |
| 787 | | struct OAM |
| 788 | | { |
| 789 | | UINT16 tile; |
| 790 | | INT16 x, y; |
| 791 | | UINT8 size, vflip, hflip, priority_bits, pal; |
| 792 | | int height, width; |
| 793 | | }; |
| 794 | 775 | |
| 795 | | static struct OAM oam_spritelist[SNES_SCR_WIDTH / 2]; |
| 796 | | |
| 797 | | static UINT8 oam_itemlist[32]; |
| 798 | | |
| 799 | | struct TILELIST { |
| 800 | | INT16 x; |
| 801 | | UINT16 priority, pal, tileaddr; |
| 802 | | int hflip; |
| 803 | | }; |
| 804 | | |
| 805 | | static struct TILELIST oam_tilelist[34]; |
| 806 | | |
| 807 | 776 | /********************************************* |
| 808 | 777 | * update_obsel() |
| 809 | 778 | * |
| r29304 | r29305 | |
| 843 | 812 | if (((ii + 1) % 4) == 0) |
| 844 | 813 | extra = oamram[oam_extra--]; |
| 845 | 814 | |
| 846 | | oam_spritelist[ii].vflip = (oamram[oam] & 0x80) >> 7; |
| 847 | | oam_spritelist[ii].hflip = (oamram[oam] & 0x40) >> 6; |
| 848 | | oam_spritelist[ii].priority_bits = (oamram[oam] & 0x30) >> 4; |
| 849 | | oam_spritelist[ii].pal = 128 + ((oamram[oam] & 0x0e) << 3); |
| 850 | | oam_spritelist[ii].tile = (oamram[oam--] & 0x1) << 8; |
| 851 | | oam_spritelist[ii].tile |= oamram[oam--]; |
| 852 | | oam_spritelist[ii].y = oamram[oam--] + 1; |
| 853 | | oam_spritelist[ii].x = oamram[oam--]; |
| 854 | | oam_spritelist[ii].size = (extra & 0x80) >> 7; |
| 815 | m_oam_spritelist[ii].vflip = (oamram[oam] & 0x80) >> 7; |
| 816 | m_oam_spritelist[ii].hflip = (oamram[oam] & 0x40) >> 6; |
| 817 | m_oam_spritelist[ii].priority_bits = (oamram[oam] & 0x30) >> 4; |
| 818 | m_oam_spritelist[ii].pal = 128 + ((oamram[oam] & 0x0e) << 3); |
| 819 | m_oam_spritelist[ii].tile = (oamram[oam--] & 0x1) << 8; |
| 820 | m_oam_spritelist[ii].tile |= oamram[oam--]; |
| 821 | m_oam_spritelist[ii].y = oamram[oam--] + 1; |
| 822 | m_oam_spritelist[ii].x = oamram[oam--]; |
| 823 | m_oam_spritelist[ii].size = (extra & 0x80) >> 7; |
| 855 | 824 | extra <<= 1; |
| 856 | | oam_spritelist[ii].x |= ((extra & 0x80) << 1); |
| 825 | m_oam_spritelist[ii].x |= ((extra & 0x80) << 1); |
| 857 | 826 | extra <<= 1; |
| 858 | 827 | |
| 859 | | oam_spritelist[ii].y *= m_obj_interlace; |
| 860 | | oam_spritelist[ii].y &= 0x1ff; |
| 828 | m_oam_spritelist[ii].y *= m_obj_interlace; |
| 829 | m_oam_spritelist[ii].y &= 0x1ff; |
| 861 | 830 | |
| 862 | | oam_spritelist[ii].x &= 0x1ff; |
| 831 | m_oam_spritelist[ii].x &= 0x1ff; |
| 863 | 832 | |
| 864 | 833 | /* Determine object size */ |
| 865 | 834 | switch (m_oam.size) |
| 866 | 835 | { |
| 867 | 836 | case 0: /* 8x8 or 16x16 */ |
| 868 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 2 : 1; |
| 869 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 2 : 1; |
| 837 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 2 : 1; |
| 838 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 2 : 1; |
| 870 | 839 | break; |
| 871 | 840 | case 1: /* 8x8 or 32x32 */ |
| 872 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 4 : 1; |
| 873 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 4 : 1; |
| 841 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 4 : 1; |
| 842 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 4 : 1; |
| 874 | 843 | break; |
| 875 | 844 | case 2: /* 8x8 or 64x64 */ |
| 876 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 8 : 1; |
| 877 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 8 : 1; |
| 845 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 8 : 1; |
| 846 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 8 : 1; |
| 878 | 847 | break; |
| 879 | 848 | case 3: /* 16x16 or 32x32 */ |
| 880 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 4 : 2; |
| 881 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 4 : 2; |
| 849 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 4 : 2; |
| 850 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 4 : 2; |
| 882 | 851 | break; |
| 883 | 852 | case 4: /* 16x16 or 64x64 */ |
| 884 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 8 : 2; |
| 885 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 8 : 2; |
| 853 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 8 : 2; |
| 854 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 8 : 2; |
| 886 | 855 | break; |
| 887 | 856 | case 5: /* 32x32 or 64x64 */ |
| 888 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 8 : 4; |
| 889 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 8 : 4; |
| 857 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 8 : 4; |
| 858 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 8 : 4; |
| 890 | 859 | break; |
| 891 | 860 | case 6: /* undocumented: 16x32 or 32x64 */ |
| 892 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 4 : 2; |
| 893 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 8 : 4; |
| 894 | | if (m_obj_interlace && !oam_spritelist[ii].size) |
| 895 | | oam_spritelist[ii].height = 2; |
| 861 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 4 : 2; |
| 862 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 8 : 4; |
| 863 | if (m_obj_interlace && !m_oam_spritelist[ii].size) |
| 864 | m_oam_spritelist[ii].height = 2; |
| 896 | 865 | break; |
| 897 | 866 | case 7: /* undocumented: 16x32 or 32x32 */ |
| 898 | | oam_spritelist[ii].width = oam_spritelist[ii].size ? 4 : 2; |
| 899 | | oam_spritelist[ii].height = oam_spritelist[ii].size ? 4 : 4; |
| 900 | | if (m_obj_interlace && !oam_spritelist[ii].size) |
| 901 | | oam_spritelist[ii].height = 2; |
| 867 | m_oam_spritelist[ii].width = m_oam_spritelist[ii].size ? 4 : 2; |
| 868 | m_oam_spritelist[ii].height = m_oam_spritelist[ii].size ? 4 : 4; |
| 869 | if (m_obj_interlace && !m_oam_spritelist[ii].size) |
| 870 | m_oam_spritelist[ii].height = 2; |
| 902 | 871 | break; |
| 903 | 872 | default: |
| 904 | 873 | /* we should never enter here... */ |
| r29304 | r29305 | |
| 919 | 888 | { |
| 920 | 889 | //if sprite is entirely offscreen and doesn't wrap around to the left side of the screen, |
| 921 | 890 | //then it is not counted. this *should* be 256, and not 255, even though dot 256 is offscreen. |
| 922 | | int spr_height = (oam_spritelist[sprite].height << 3); |
| 891 | int spr_height = (m_oam_spritelist[sprite].height << 3); |
| 923 | 892 | |
| 924 | | if (oam_spritelist[sprite].x > 256 && (oam_spritelist[sprite].x + (oam_spritelist[sprite].width << 3) - 1) < 512) |
| 893 | if (m_oam_spritelist[sprite].x > 256 && (m_oam_spritelist[sprite].x + (m_oam_spritelist[sprite].width << 3) - 1) < 512) |
| 925 | 894 | return 0; |
| 926 | 895 | |
| 927 | | if (curline >= oam_spritelist[sprite].y && curline < (oam_spritelist[sprite].y + spr_height)) |
| 896 | if (curline >= m_oam_spritelist[sprite].y && curline < (m_oam_spritelist[sprite].y + spr_height)) |
| 928 | 897 | return 1; |
| 929 | 898 | |
| 930 | | if ((oam_spritelist[sprite].y + spr_height) >= 256 && curline < ((oam_spritelist[sprite].y + spr_height) & 255)) |
| 899 | if ((m_oam_spritelist[sprite].y + spr_height) >= 256 && curline < ((m_oam_spritelist[sprite].y + spr_height) & 255)) |
| 931 | 900 | return 1; |
| 932 | 901 | |
| 933 | 902 | return 0; |
| r29304 | r29305 | |
| 962 | 931 | curline *= m_obj_interlace; |
| 963 | 932 | |
| 964 | 933 | /* reset the list of first 32 objects which intersect current scanline */ |
| 965 | | memset(oam_itemlist, 0xff, 32); |
| 934 | memset(m_oam_itemlist, 0xff, 32); |
| 966 | 935 | |
| 967 | 936 | /* populate the list of 32 objects */ |
| 968 | 937 | for (ii = 0; ii < 128; ii++) |
| r29304 | r29305 | |
| 975 | 944 | if (range_over++ >= 32) |
| 976 | 945 | break; |
| 977 | 946 | |
| 978 | | oam_itemlist[range_over - 1] = active_sprite; |
| 947 | m_oam_itemlist[range_over - 1] = active_sprite; |
| 979 | 948 | } |
| 980 | 949 | |
| 981 | 950 | /* reset the list of first 34 tiles to be drawn */ |
| 982 | 951 | for (ii = 0; ii < 34; ii++) |
| 983 | | oam_tilelist[ii].tileaddr = 0xffff; |
| 952 | m_oam_tilelist[ii].tileaddr = 0xffff; |
| 984 | 953 | |
| 985 | 954 | /* populate the list of 34 tiles */ |
| 986 | 955 | for (ii = 31; ii >= 0; ii--) |
| 987 | 956 | { |
| 988 | | if (oam_itemlist[ii] == 0xff) |
| 957 | if (m_oam_itemlist[ii] == 0xff) |
| 989 | 958 | continue; |
| 990 | 959 | |
| 991 | | active_sprite = oam_itemlist[ii]; |
| 960 | active_sprite = m_oam_itemlist[ii]; |
| 992 | 961 | |
| 993 | | tile = oam_spritelist[active_sprite].tile; |
| 994 | | x = oam_spritelist[active_sprite].x; |
| 995 | | y = oam_spritelist[active_sprite].y; |
| 996 | | height = oam_spritelist[active_sprite].height; |
| 997 | | width = oam_spritelist[active_sprite].width; |
| 998 | | vflip = oam_spritelist[active_sprite].vflip; |
| 999 | | hflip = oam_spritelist[active_sprite].hflip; |
| 1000 | | priority = oam_spritelist[active_sprite].priority_bits; |
| 1001 | | pal = oam_spritelist[active_sprite].pal; |
| 962 | tile = m_oam_spritelist[active_sprite].tile; |
| 963 | x = m_oam_spritelist[active_sprite].x; |
| 964 | y = m_oam_spritelist[active_sprite].y; |
| 965 | height = m_oam_spritelist[active_sprite].height; |
| 966 | width = m_oam_spritelist[active_sprite].width; |
| 967 | vflip = m_oam_spritelist[active_sprite].vflip; |
| 968 | hflip = m_oam_spritelist[active_sprite].hflip; |
| 969 | priority = m_oam_spritelist[active_sprite].priority_bits; |
| 970 | pal = m_oam_spritelist[active_sprite].pal; |
| 1002 | 971 | |
| 1003 | 972 | /* Adjust y, if past maximum position (for sprites which overlap between top & bottom) */ |
| 1004 | 973 | if (y >= (0x100 - 16) * m_interlace) |
| r29304 | r29305 | |
| 1030 | 999 | break; |
| 1031 | 1000 | |
| 1032 | 1001 | xs = (hflip) ? (width - 1 - jj) : jj; |
| 1033 | | oam_tilelist[time_over - 1].tileaddr = name_sel + tile + table_obj_offset[ys][xs] + line; |
| 1034 | | oam_tilelist[time_over - 1].hflip = hflip; |
| 1035 | | oam_tilelist[time_over - 1].x = xx; |
| 1036 | | oam_tilelist[time_over - 1].pal = pal; |
| 1037 | | oam_tilelist[time_over - 1].priority = priority; |
| 1002 | m_oam_tilelist[time_over - 1].tileaddr = name_sel + tile + table_obj_offset[ys][xs] + line; |
| 1003 | m_oam_tilelist[time_over - 1].hflip = hflip; |
| 1004 | m_oam_tilelist[time_over - 1].x = xx; |
| 1005 | m_oam_tilelist[time_over - 1].pal = pal; |
| 1006 | m_oam_tilelist[time_over - 1].priority = priority; |
| 1038 | 1007 | } |
| 1039 | 1008 | } |
| 1040 | 1009 | } |
| r29304 | r29305 | |
| 1061 | 1030 | int ii; |
| 1062 | 1031 | |
| 1063 | 1032 | #if SNES_LAYER_DEBUG |
| 1064 | | if (debug_options.bg_disabled[SNES_OAM]) |
| 1033 | if (m_debug_options.bg_disabled[SNES_OAM]) |
| 1065 | 1034 | return; |
| 1066 | 1035 | #endif /* SNES_LAYER_DEBUG */ |
| 1067 | 1036 | |
| r29304 | r29305 | |
| 1085 | 1054 | { |
| 1086 | 1055 | int tile = ii; |
| 1087 | 1056 | #if SNES_LAYER_DEBUG |
| 1088 | | if (debug_options.sprite_reversed) |
| 1057 | if (m_debug_options.sprite_reversed) |
| 1089 | 1058 | tile = 33 - ii; |
| 1090 | 1059 | #endif /* SNES_LAYER_DEBUG */ |
| 1091 | 1060 | |
| 1092 | | if (oam_tilelist[tile].tileaddr == 0xffff) |
| 1061 | if (m_oam_tilelist[tile].tileaddr == 0xffff) |
| 1093 | 1062 | continue; |
| 1094 | 1063 | |
| 1095 | | pri = priority[oam_tilelist[tile].priority]; |
| 1064 | pri = priority[m_oam_tilelist[tile].priority]; |
| 1096 | 1065 | |
| 1097 | 1066 | #if SNES_LAYER_DEBUG |
| 1098 | | if (debug_options.select_pri[SNES_OAM]) |
| 1067 | if (m_debug_options.select_pri[SNES_OAM]) |
| 1099 | 1068 | { |
| 1100 | | int oam_draw = debug_options.select_pri[SNES_OAM] - 1; |
| 1101 | | if (oam_draw != oam_tilelist[tile].priority) |
| 1069 | int oam_draw = m_debug_options.select_pri[SNES_OAM] - 1; |
| 1070 | if (oam_draw != m_oam_tilelist[tile].priority) |
| 1102 | 1071 | continue; |
| 1103 | 1072 | } |
| 1104 | 1073 | #endif /* SNES_LAYER_DEBUG */ |
| 1105 | 1074 | |
| 1106 | 1075 | /* OAM tiles have fixed planes (4), no direct color and no hires, but otherwise work the same as BG ones */ |
| 1107 | | draw_tile(4, SNES_OAM, charaddr + oam_tilelist[tile].tileaddr, oam_tilelist[tile].x, pri, oam_tilelist[tile].hflip, 0, oam_tilelist[tile].pal, 0); |
| 1076 | draw_tile(4, SNES_OAM, charaddr + m_oam_tilelist[tile].tileaddr, m_oam_tilelist[tile].x, pri, m_oam_tilelist[tile].hflip, 0, m_oam_tilelist[tile].pal, 0); |
| 1108 | 1077 | } |
| 1109 | 1078 | } |
| 1110 | 1079 | |
| r29304 | r29305 | |
| 1118 | 1087 | void snes_ppu_class::update_mode_0( UINT16 curline ) |
| 1119 | 1088 | { |
| 1120 | 1089 | #if SNES_LAYER_DEBUG |
| 1121 | | if (debug_options.mode_disabled[0]) |
| 1090 | if (m_debug_options.mode_disabled[0]) |
| 1122 | 1091 | return; |
| 1123 | 1092 | #endif /* SNES_LAYER_DEBUG */ |
| 1124 | 1093 | |
| r29304 | r29305 | |
| 1132 | 1101 | void snes_ppu_class::update_mode_1( UINT16 curline ) |
| 1133 | 1102 | { |
| 1134 | 1103 | #if SNES_LAYER_DEBUG |
| 1135 | | if (debug_options.mode_disabled[1]) |
| 1104 | if (m_debug_options.mode_disabled[1]) |
| 1136 | 1105 | return; |
| 1137 | 1106 | #endif /* SNES_LAYER_DEBUG */ |
| 1138 | 1107 | |
| r29304 | r29305 | |
| 1155 | 1124 | void snes_ppu_class::update_mode_2( UINT16 curline ) |
| 1156 | 1125 | { |
| 1157 | 1126 | #if SNES_LAYER_DEBUG |
| 1158 | | if (debug_options.mode_disabled[2]) |
| 1127 | if (m_debug_options.mode_disabled[2]) |
| 1159 | 1128 | return; |
| 1160 | 1129 | #endif /* SNES_LAYER_DEBUG */ |
| 1161 | 1130 | |
| r29304 | r29305 | |
| 1167 | 1136 | void snes_ppu_class::update_mode_3( UINT16 curline ) |
| 1168 | 1137 | { |
| 1169 | 1138 | #if SNES_LAYER_DEBUG |
| 1170 | | if (debug_options.mode_disabled[3]) |
| 1139 | if (m_debug_options.mode_disabled[3]) |
| 1171 | 1140 | return; |
| 1172 | 1141 | #endif /* SNES_LAYER_DEBUG */ |
| 1173 | 1142 | |
| r29304 | r29305 | |
| 1179 | 1148 | void snes_ppu_class::update_mode_4( UINT16 curline ) |
| 1180 | 1149 | { |
| 1181 | 1150 | #if SNES_LAYER_DEBUG |
| 1182 | | if (debug_options.mode_disabled[4]) |
| 1151 | if (m_debug_options.mode_disabled[4]) |
| 1183 | 1152 | return; |
| 1184 | 1153 | #endif /* SNES_LAYER_DEBUG */ |
| 1185 | 1154 | |
| r29304 | r29305 | |
| 1191 | 1160 | void snes_ppu_class::update_mode_5( UINT16 curline ) |
| 1192 | 1161 | { |
| 1193 | 1162 | #if SNES_LAYER_DEBUG |
| 1194 | | if (debug_options.mode_disabled[5]) |
| 1163 | if (m_debug_options.mode_disabled[5]) |
| 1195 | 1164 | return; |
| 1196 | 1165 | #endif /* SNES_LAYER_DEBUG */ |
| 1197 | 1166 | |
| r29304 | r29305 | |
| 1203 | 1172 | void snes_ppu_class::update_mode_6( UINT16 curline ) |
| 1204 | 1173 | { |
| 1205 | 1174 | #if SNES_LAYER_DEBUG |
| 1206 | | if (debug_options.mode_disabled[6]) |
| 1175 | if (m_debug_options.mode_disabled[6]) |
| 1207 | 1176 | return; |
| 1208 | 1177 | #endif /* SNES_LAYER_DEBUG */ |
| 1209 | 1178 | |
| r29304 | r29305 | |
| 1214 | 1183 | void snes_ppu_class::update_mode_7( UINT16 curline ) |
| 1215 | 1184 | { |
| 1216 | 1185 | #if SNES_LAYER_DEBUG |
| 1217 | | if (debug_options.mode_disabled[7]) |
| 1186 | if (m_debug_options.mode_disabled[7]) |
| 1218 | 1187 | return; |
| 1219 | 1188 | #endif /* SNES_LAYER_DEBUG */ |
| 1220 | 1189 | |
| r29304 | r29305 | |
| 1359 | 1328 | inline void snes_ppu_class::draw_blend( UINT16 offset, UINT16 *colour, UINT8 prevent_color_math, UINT8 black_pen_clip, int switch_screens ) |
| 1360 | 1329 | { |
| 1361 | 1330 | #if SNES_LAYER_DEBUG |
| 1362 | | if (debug_options.colormath_disabled) |
| 1331 | if (m_debug_options.colormath_disabled) |
| 1363 | 1332 | return; |
| 1364 | 1333 | #endif /* SNES_LAYER_DEBUG */ |
| 1365 | 1334 | |
| r29304 | r29305 | |
| 1386 | 1355 | |
| 1387 | 1356 | #if SNES_LAYER_DEBUG |
| 1388 | 1357 | /* Toggle drawing of SNES_SUBSCREEN or SNES_MAINSCREEN */ |
| 1389 | | if (debug_options.draw_subscreen) |
| 1358 | if (m_debug_options.draw_subscreen) |
| 1390 | 1359 | { |
| 1391 | 1360 | subscreen = switch_screens ? &m_scanlines[SNES_SUBSCREEN] : &m_scanlines[SNES_MAINSCREEN]; |
| 1392 | 1361 | } |
| r29304 | r29305 | |
| 1547 | 1516 | } |
| 1548 | 1517 | |
| 1549 | 1518 | /* Toggle drawing of SNES_SUBSCREEN or SNES_MAINSCREEN */ |
| 1550 | | if (debug_options.draw_subscreen) |
| 1519 | if (m_debug_options.draw_subscreen) |
| 1551 | 1520 | { |
| 1552 | 1521 | scanline1 = &m_scanlines[SNES_SUBSCREEN]; |
| 1553 | 1522 | scanline2 = &m_scanlines[SNES_MAINSCREEN]; |
| r29304 | r29305 | |
| 1643 | 1612 | g_profiler.stop(); |
| 1644 | 1613 | } |
| 1645 | 1614 | |
| 1646 | | void snes_ppu_class::ppu_start(screen_device &screen) |
| 1615 | void snes_ppu_class::ppu_start(screen_device &screen,snes_state *state) |
| 1647 | 1616 | { |
| 1648 | 1617 | m_screen = &screen; |
| 1649 | 1618 | running_machine &machine = screen.machine(); |
| 1650 | | |
| 1619 | m_state = state; |
| 1651 | 1620 | #if SNES_LAYER_DEBUG |
| 1652 | | memset(&debug_options, 0, sizeof(debug_options)); |
| 1621 | memset(&m_debug_options, 0, sizeof(m_debug_options)); |
| 1653 | 1622 | #endif |
| 1654 | 1623 | |
| 1655 | 1624 | m_vram = auto_alloc_array(machine, UINT8, SNES_VRAM_SIZE); |
| r29304 | r29305 | |
| 1938 | 1907 | if (h <= 4) |
| 1939 | 1908 | m_vram[offset] = data; |
| 1940 | 1909 | else if (h == 6) |
| 1941 | | m_vram[offset] = snes_open_bus_r(space, 0); |
| 1910 | m_vram[offset] = m_state->snes_open_bus_r(space, 0); |
| 1942 | 1911 | else |
| 1943 | 1912 | { |
| 1944 | 1913 | //printf("%d %d VRAM write, CHECK!\n",h,v); |
| r29304 | r29305 | |
| 2149 | 2118 | } |
| 2150 | 2119 | case SLHV: /* Software latch for H/V counter */ |
| 2151 | 2120 | latch_counters(space.machine()); |
| 2152 | | return snes_open_bus_r(space, 0); /* Return value is meaningless */ |
| 2121 | return m_state->snes_open_bus_r(space, 0); /* Return value is meaningless */ |
| 2153 | 2122 | case ROAMDATA: /* Read data from OAM (DR) */ |
| 2154 | 2123 | m_ppu1_open_bus = oam_read(space, m_oam.address); |
| 2155 | 2124 | PPU_REG(OAMDATA) = (PPU_REG(OAMDATA) + 1) % 2; |
| r29304 | r29305 | |
| 2244 | 2213 | } |
| 2245 | 2214 | |
| 2246 | 2215 | /* note: remaining registers (Namely TM in Super Kick Boxing) returns MDR open bus, not PPU Open Bus! */ |
| 2247 | | return snes_open_bus_r(space, 0); |
| 2216 | return m_state->snes_open_bus_r(space, 0); |
| 2248 | 2217 | } |
| 2249 | 2218 | |
| 2250 | 2219 | |
| r29304 | r29305 | |
| 2670 | 2639 | { |
| 2671 | 2640 | int i; |
| 2672 | 2641 | UINT8 toggles = machine.root_device().ioport("DEBUG1")->read_safe(0); |
| 2673 | | debug_options.select_pri[SNES_BG1] = (toggles & 0x03); |
| 2674 | | debug_options.select_pri[SNES_BG2] = (toggles & 0x0c) >> 2; |
| 2675 | | debug_options.select_pri[SNES_BG3] = (toggles & 0x30) >> 4; |
| 2676 | | debug_options.select_pri[SNES_BG4] = (toggles & 0xc0) >> 6; |
| 2642 | m_debug_options.select_pri[SNES_BG1] = (toggles & 0x03); |
| 2643 | m_debug_options.select_pri[SNES_BG2] = (toggles & 0x0c) >> 2; |
| 2644 | m_debug_options.select_pri[SNES_BG3] = (toggles & 0x30) >> 4; |
| 2645 | m_debug_options.select_pri[SNES_BG4] = (toggles & 0xc0) >> 6; |
| 2677 | 2646 | |
| 2678 | 2647 | toggles = machine.root_device().ioport("DEBUG2")->read_safe(0); |
| 2679 | 2648 | for (i = 0; i < 4; i++) |
| 2680 | | DEBUG_TOGGLE(i, debug_options.bg_disabled[i], ("Debug: Disabled BG%d.\n", i + 1), ("Debug: Enabled BG%d.\n", i + 1)) |
| 2681 | | DEBUG_TOGGLE(4, debug_options.bg_disabled[SNES_OAM], ("Debug: Disabled OAM.\n"), ("Debug: Enabled OAM.\n")) |
| 2682 | | DEBUG_TOGGLE(5, debug_options.draw_subscreen, ("Debug: Switched screens.\n"), ("Debug: Switched screens.\n")) |
| 2683 | | DEBUG_TOGGLE(6, debug_options.colormath_disabled, ("Debug: Disabled Color Math.\n"), ("Debug: Enabled Color Math.\n")) |
| 2684 | | DEBUG_TOGGLE(7, debug_options.windows_disabled, ("Debug: Disabled Window Masks.\n"), ("Debug: Enabled Window Masks.\n")) |
| 2649 | DEBUG_TOGGLE(i, m_debug_options.bg_disabled[i], ("Debug: Disabled BG%d.\n", i + 1), ("Debug: Enabled BG%d.\n", i + 1)) |
| 2650 | DEBUG_TOGGLE(4, m_debug_options.bg_disabled[SNES_OAM], ("Debug: Disabled OAM.\n"), ("Debug: Enabled OAM.\n")) |
| 2651 | DEBUG_TOGGLE(5, m_debug_options.draw_subscreen, ("Debug: Switched screens.\n"), ("Debug: Switched screens.\n")) |
| 2652 | DEBUG_TOGGLE(6, m_debug_options.colormath_disabled, ("Debug: Disabled Color Math.\n"), ("Debug: Enabled Color Math.\n")) |
| 2653 | DEBUG_TOGGLE(7, m_debug_options.windows_disabled, ("Debug: Disabled Window Masks.\n"), ("Debug: Enabled Window Masks.\n")) |
| 2685 | 2654 | |
| 2686 | 2655 | toggles = machine.root_device().ioport("DEBUG4")->read_safe(0); |
| 2687 | 2656 | for (i = 0; i < 8; i++) |
| 2688 | | DEBUG_TOGGLE(i, debug_options.mode_disabled[i], ("Debug: Disabled Mode %d drawing.\n", i), ("Debug: Enabled Mode %d drawing.\n", i)) |
| 2657 | DEBUG_TOGGLE(i, m_debug_options.mode_disabled[i], ("Debug: Disabled Mode %d drawing.\n", i), ("Debug: Enabled Mode %d drawing.\n", i)) |
| 2689 | 2658 | |
| 2690 | 2659 | toggles = machine.root_device().ioport("DEBUG3")->read_safe(0); |
| 2691 | | DEBUG_TOGGLE(2, debug_options.mosaic_disabled, ("Debug: Disabled Mosaic.\n"), ("Debug: Enabled Mosaic.\n")) |
| 2692 | | debug_options.sprite_reversed = BIT(toggles, 7); |
| 2693 | | debug_options.select_pri[SNES_OAM] = (toggles & 0x70) >> 4; |
| 2660 | DEBUG_TOGGLE(2, m_debug_options.mosaic_disabled, ("Debug: Disabled Mosaic.\n"), ("Debug: Enabled Mosaic.\n")) |
| 2661 | m_debug_options.sprite_reversed = BIT(toggles, 7); |
| 2662 | m_debug_options.select_pri[SNES_OAM] = (toggles & 0x70) >> 4; |
| 2694 | 2663 | |
| 2695 | 2664 | #ifdef MAME_DEBUG |
| 2696 | 2665 | /* Once per frame, log video properties */ |
| r29304 | r29305 | |
| 2698 | 2667 | { |
| 2699 | 2668 | static const char WINLOGIC[4] = { '|', '&', '^', '!' }; |
| 2700 | 2669 | |
| 2701 | | logerror("%s", debug_options.windows_disabled?" ":"W"); |
| 2670 | logerror("%s", m_debug_options.windows_disabled?" ":"W"); |
| 2702 | 2671 | logerror("%s1 %s%s%s%s%s%c%s%s%d%s %d %4X %4X", |
| 2703 | | debug_options.bg_disabled[0]?" ":"*", |
| 2672 | m_debug_options.bg_disabled[0]?" ":"*", |
| 2704 | 2673 | (PPU_REG(TM) & 0x1)?"M":" ", |
| 2705 | 2674 | (PPU_REG(TS) & 0x1)?"S":" ", |
| 2706 | 2675 | (PPU_REG(CGADSUB) & 0x1)?"B":" ", |
| r29304 | r29305 | |
| 2715 | 2684 | (PPU_REG(BG1SC) & 0xfc) << 9, |
| 2716 | 2685 | m_layer[SNES_BG1].charmap << 13); |
| 2717 | 2686 | logerror("%s2 %s%s%s%s%s%c%s%s%d%s %d %4X %4X", |
| 2718 | | debug_options.bg_disabled[1]?" ":"*", |
| 2687 | m_debug_options.bg_disabled[1]?" ":"*", |
| 2719 | 2688 | (PPU_REG(TM) & 0x2)?"M":" ", |
| 2720 | 2689 | (PPU_REG(TS) & 0x2)?"S":" ", |
| 2721 | 2690 | (PPU_REG(CGADSUB) & 0x2)?"B":" ", |
| r29304 | r29305 | |
| 2730 | 2699 | (PPU_REG(BG2SC) & 0xfc) << 9, |
| 2731 | 2700 | m_layer[SNES_BG2].charmap << 13); |
| 2732 | 2701 | logerror("%s3 %s%s%s%s%s%c%s%s%d%s%s%d %4X %4X", |
| 2733 | | debug_options.bg_disabled[2]?" ":"*", |
| 2702 | m_debug_options.bg_disabled[2]?" ":"*", |
| 2734 | 2703 | (PPU_REG(TM) & 0x4)?"M":" ", |
| 2735 | 2704 | (PPU_REG(TS) & 0x4)?"S":" ", |
| 2736 | 2705 | (PPU_REG(CGADSUB) & 0x4)?"B":" ", |
| r29304 | r29305 | |
| 2746 | 2715 | (PPU_REG(BG3SC) & 0xfc) << 9, |
| 2747 | 2716 | m_layer[SNES_BG3].charmap << 13); |
| 2748 | 2717 | logerror("%s4 %s%s%s%s%s%c%s%s%d%s %d %4X %4X", |
| 2749 | | debug_options.bg_disabled[3]?" ":"*", |
| 2718 | m_debug_options.bg_disabled[3]?" ":"*", |
| 2750 | 2719 | (PPU_REG(TM) & 0x8)?"M":" ", |
| 2751 | 2720 | (PPU_REG(TS) & 0x8)?"S":" ", |
| 2752 | 2721 | (PPU_REG(CGADSUB) & 0x8)?"B":" ", |
| r29304 | r29305 | |
| 2761 | 2730 | (PPU_REG(BG4SC) & 0xfc) << 9, |
| 2762 | 2731 | m_layer[SNES_BG4].charmap << 13 ); |
| 2763 | 2732 | logerror("%sO %s%s%s%s%s%c%s%s %4X", |
| 2764 | | debug_options.bg_disabled[4]?" ":"*", |
| 2733 | m_debug_options.bg_disabled[4]?" ":"*", |
| 2765 | 2734 | (PPU_REG(TM) & 0x10)?"M":" ", |
| 2766 | 2735 | (PPU_REG(TS) & 0x10)?"S":" ", |
| 2767 | 2736 | (PPU_REG(CGADSUB) & 0x10)?"B":" ", |
| r29304 | r29305 | |
| 2772 | 2741 | (PPU_REG(WOBJSEL) & 0x8)?((PPU_REG(WOBJSEL) & 0x4)?"o":"i"):" ", |
| 2773 | 2742 | m_layer[SNES_OAM].charmap << 13 ); |
| 2774 | 2743 | logerror("%sB %s %c%s%s", |
| 2775 | | debug_options.colormath_disabled?" ":"*", |
| 2744 | m_debug_options.colormath_disabled?" ":"*", |
| 2776 | 2745 | (PPU_REG(CGADSUB) & 0x20)?"B":" ", |
| 2777 | 2746 | WINLOGIC[(PPU_REG(WOBJLOG) & 0xc)>>2], |
| 2778 | 2747 | (PPU_REG(WOBJSEL) & 0x20)?((PPU_REG(WOBJSEL) & 0x10)?"o":"i"):" ", |
shelves/new_menus/src/mame/drivers/kopunch.c
| r29304 | r29305 | |
| 4 | 4 | |
| 5 | 5 | XTAL: ? |
| 6 | 6 | CPU: 8085 (proof: it uses SIM opcode) |
| 7 | Other: 4 x i8255 for all I/O |
| 7 | 8 | |
| 8 | 9 | TODO: |
| 9 | 10 | - discrete sound? |
| r29304 | r29305 | |
| 30 | 31 | |
| 31 | 32 | #include "emu.h" |
| 32 | 33 | #include "cpu/i8085/i8085.h" |
| 34 | #include "machine/i8255.h" |
| 33 | 35 | #include "includes/kopunch.h" |
| 34 | 36 | |
| 35 | 37 | |
| 36 | | INTERRUPT_GEN_MEMBER(kopunch_state::kopunch_interrupt) |
| 38 | /******************************************************** |
| 39 | |
| 40 | Interrupts |
| 41 | |
| 42 | ********************************************************/ |
| 43 | |
| 44 | INTERRUPT_GEN_MEMBER(kopunch_state::vblank_interrupt) |
| 37 | 45 | { |
| 38 | 46 | device.execute().set_input_line(I8085_RST75_LINE, ASSERT_LINE); |
| 39 | 47 | device.execute().set_input_line(I8085_RST75_LINE, CLEAR_LINE); |
| 40 | 48 | } |
| 41 | 49 | |
| 42 | | READ8_MEMBER(kopunch_state::kopunch_in_r) |
| 50 | INPUT_CHANGED_MEMBER(kopunch_state::left_coin_inserted) |
| 43 | 51 | { |
| 44 | | /* port 31 + low 3 bits of port 32 contain the punch strength */ |
| 45 | | if (offset == 0) |
| 46 | | return machine().rand(); |
| 47 | | else |
| 48 | | return (machine().rand() & 0x07) | ioport("SYSTEM")->read(); |
| 52 | // left coin insertion causes a rst6.5 (vector 0x34) |
| 53 | if (newval) |
| 54 | m_maincpu->set_input_line(I8085_RST65_LINE, HOLD_LINE); |
| 49 | 55 | } |
| 50 | 56 | |
| 51 | | WRITE8_MEMBER(kopunch_state::kopunch_lamp_w) |
| 57 | INPUT_CHANGED_MEMBER(kopunch_state::right_coin_inserted) |
| 52 | 58 | { |
| 53 | | set_led_status(machine(), 0, ~data & 0x80); |
| 59 | // right coin insertion causes a rst5.5 (vector 0x2c) |
| 60 | if (newval) |
| 61 | m_maincpu->set_input_line(I8085_RST55_LINE, HOLD_LINE); |
| 54 | 62 | } |
| 55 | 63 | |
| 56 | | WRITE8_MEMBER(kopunch_state::kopunch_coin_w) |
| 57 | | { |
| 58 | | coin_counter_w(machine(), 0, ~data & 0x80); |
| 59 | | coin_counter_w(machine(), 1, ~data & 0x40); |
| 60 | 64 | |
| 61 | | // if ((data & 0x3f) != 0x3e) |
| 62 | | // printf("port 34 = %02x ",data); |
| 63 | | } |
| 65 | /******************************************************** |
| 64 | 66 | |
| 67 | Memory Maps |
| 65 | 68 | |
| 69 | ********************************************************/ |
| 66 | 70 | |
| 67 | 71 | static ADDRESS_MAP_START( kopunch_map, AS_PROGRAM, 8, kopunch_state ) |
| 68 | 72 | AM_RANGE(0x0000, 0x1fff) AM_ROM |
| 69 | 73 | AM_RANGE(0x2000, 0x23ff) AM_RAM |
| 70 | | AM_RANGE(0x6000, 0x63ff) AM_RAM_WRITE(kopunch_fg_w) AM_SHARE("vram_fg") |
| 71 | | AM_RANGE(0x7000, 0x70ff) AM_RAM_WRITE(kopunch_bg_w) AM_SHARE("vram_bg") |
| 74 | AM_RANGE(0x6000, 0x63ff) AM_RAM_WRITE(vram_fg_w) AM_SHARE("vram_fg") |
| 75 | AM_RANGE(0x7000, 0x70ff) AM_RAM_WRITE(vram_bg_w) AM_SHARE("vram_bg") |
| 72 | 76 | AM_RANGE(0x7100, 0x73ff) AM_RAM // unused vram |
| 77 | AM_RANGE(0x7400, 0x7bff) AM_RAM // more unused vram? or accidental writes? |
| 73 | 78 | ADDRESS_MAP_END |
| 74 | 79 | |
| 75 | 80 | static ADDRESS_MAP_START( kopunch_io_map, AS_IO, 8, kopunch_state ) |
| 76 | | AM_RANGE(0x30, 0x30) AM_READ_PORT("P1") |
| 77 | | AM_RANGE(0x31, 0x32) AM_READ(kopunch_in_r) |
| 78 | | AM_RANGE(0x33, 0x33) AM_WRITENOP |
| 79 | | AM_RANGE(0x34, 0x34) AM_WRITE(kopunch_coin_w) |
| 80 | | AM_RANGE(0x35, 0x35) AM_WRITENOP |
| 81 | | AM_RANGE(0x36, 0x36) AM_WRITENOP |
| 82 | | AM_RANGE(0x37, 0x37) AM_WRITENOP |
| 83 | | AM_RANGE(0x38, 0x38) AM_WRITE(kopunch_lamp_w) |
| 84 | | AM_RANGE(0x39, 0x39) AM_WRITENOP |
| 85 | | AM_RANGE(0x3a, 0x3a) AM_READ_PORT("DSW") |
| 86 | | AM_RANGE(0x3b, 0x3b) AM_WRITENOP |
| 87 | | AM_RANGE(0x3c, 0x3c) AM_WRITE(kopunch_scroll_x_w) |
| 88 | | AM_RANGE(0x3d, 0x3d) AM_WRITE(kopunch_scroll_y_w) |
| 89 | | AM_RANGE(0x3e, 0x3e) AM_READ_PORT("P2") AM_WRITE(kopunch_gfxbank_w) |
| 90 | | AM_RANGE(0x3f, 0x3f) AM_WRITENOP |
| 81 | AM_RANGE(0x30, 0x33) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) |
| 82 | AM_RANGE(0x34, 0x37) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) |
| 83 | AM_RANGE(0x38, 0x3b) AM_DEVREADWRITE("ppi8255_2", i8255_device, read, write) |
| 84 | AM_RANGE(0x3c, 0x3f) AM_DEVREADWRITE("ppi8255_3", i8255_device, read, write) |
| 91 | 85 | ADDRESS_MAP_END |
| 92 | 86 | |
| 93 | | INPUT_CHANGED_MEMBER(kopunch_state::left_coin_inserted) |
| 87 | |
| 88 | |
| 89 | /******************************************************** |
| 90 | |
| 91 | PPI I/O |
| 92 | |
| 93 | ********************************************************/ |
| 94 | |
| 95 | READ8_MEMBER(kopunch_state::sensors1_r) |
| 94 | 96 | { |
| 95 | | // left coin insertion causes a rst6.5 (vector 0x34) |
| 96 | | if (newval) |
| 97 | | m_maincpu->set_input_line(I8085_RST65_LINE, HOLD_LINE); |
| 97 | // punch strength low bits |
| 98 | return machine().rand(); |
| 98 | 99 | } |
| 99 | 100 | |
| 100 | | INPUT_CHANGED_MEMBER(kopunch_state::right_coin_inserted) |
| 101 | READ8_MEMBER(kopunch_state::sensors2_r) |
| 101 | 102 | { |
| 102 | | // right coin insertion causes a rst5.5 (vector 0x2c) |
| 103 | | if (newval) |
| 104 | | m_maincpu->set_input_line(I8085_RST55_LINE, HOLD_LINE); |
| 103 | // d0-d2: punch strength high bits |
| 104 | // d3: coin 2 |
| 105 | // d4: unknown sensor |
| 106 | // d5: unknown sensor |
| 107 | // d6: unknown sensor |
| 108 | // d7: coin 1 |
| 109 | return (machine().rand() & 0x07) | ioport("SYSTEM")->read(); |
| 105 | 110 | } |
| 106 | 111 | |
| 112 | WRITE8_MEMBER(kopunch_state::lamp_w) |
| 113 | { |
| 114 | set_led_status(machine(), 0, ~data & 0x80); |
| 115 | } |
| 116 | |
| 117 | WRITE8_MEMBER(kopunch_state::coin_w) |
| 118 | { |
| 119 | coin_counter_w(machine(), 0, ~data & 0x80); |
| 120 | coin_counter_w(machine(), 1, ~data & 0x40); |
| 121 | |
| 122 | // if ((data & 0x3f) != 0x3e) |
| 123 | // printf("port 34 = %02x ",data); |
| 124 | } |
| 125 | |
| 126 | /*******************************************************/ |
| 127 | |
| 128 | static I8255A_INTERFACE( ppi8255_0_intf ) |
| 129 | { |
| 130 | // $30 - always $9b (PPI mode 0, ports A & B & C as input) |
| 131 | DEVCB_INPUT_PORT("P1"), |
| 132 | DEVCB_NULL, |
| 133 | DEVCB_DRIVER_MEMBER(kopunch_state, sensors1_r), |
| 134 | DEVCB_NULL, |
| 135 | DEVCB_DRIVER_MEMBER(kopunch_state, sensors2_r), |
| 136 | DEVCB_NULL |
| 137 | }; |
| 138 | |
| 139 | static I8255A_INTERFACE( ppi8255_1_intf ) |
| 140 | { |
| 141 | // $34 - always $80 (PPI mode 0, ports A & B & C as output) |
| 142 | DEVCB_NULL, |
| 143 | DEVCB_DRIVER_MEMBER(kopunch_state, coin_w), |
| 144 | DEVCB_NULL, |
| 145 | DEVCB_UNMAPPED, |
| 146 | DEVCB_NULL, |
| 147 | DEVCB_UNMAPPED |
| 148 | }; |
| 149 | |
| 150 | static I8255A_INTERFACE( ppi8255_2_intf ) |
| 151 | { |
| 152 | // $38 - always $89 (PPI mode 0, ports A & B as output, port C as input) |
| 153 | DEVCB_NULL, |
| 154 | DEVCB_DRIVER_MEMBER(kopunch_state, lamp_w), |
| 155 | DEVCB_NULL, |
| 156 | DEVCB_UNMAPPED, |
| 157 | DEVCB_INPUT_PORT("DSW"), |
| 158 | DEVCB_NULL |
| 159 | }; |
| 160 | |
| 161 | static I8255A_INTERFACE( ppi8255_3_intf ) |
| 162 | { |
| 163 | // $3c - always $88 (PPI mode 0, ports A & B & lower C as output, upper C as input) |
| 164 | DEVCB_NULL, |
| 165 | DEVCB_DRIVER_MEMBER(kopunch_state, scroll_x_w), |
| 166 | DEVCB_NULL, |
| 167 | DEVCB_DRIVER_MEMBER(kopunch_state, scroll_y_w), |
| 168 | DEVCB_INPUT_PORT("P2"), |
| 169 | DEVCB_DRIVER_MEMBER(kopunch_state, gfxbank_w) |
| 170 | }; |
| 171 | |
| 172 | |
| 173 | |
| 174 | /******************************************************** |
| 175 | |
| 176 | Inputs |
| 177 | |
| 178 | ********************************************************/ |
| 179 | |
| 107 | 180 | static INPUT_PORTS_START( kopunch ) |
| 108 | 181 | PORT_START("P1") |
| 109 | 182 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) |
| r29304 | r29305 | |
| 158 | 231 | INPUT_PORTS_END |
| 159 | 232 | |
| 160 | 233 | |
| 161 | | static const gfx_layout charlayout = |
| 234 | |
| 235 | /*******************************************************/ |
| 236 | |
| 237 | static const gfx_layout fg_layout = |
| 162 | 238 | { |
| 163 | 239 | 8,8, |
| 164 | 240 | RGN_FRAC(1,3), |
| r29304 | r29305 | |
| 169 | 245 | 8*8 |
| 170 | 246 | }; |
| 171 | 247 | |
| 172 | | static const gfx_layout charlayoutbig = |
| 248 | static const gfx_layout bg_layout = |
| 173 | 249 | { |
| 174 | 250 | 16,16, |
| 175 | 251 | RGN_FRAC(1,3), |
| r29304 | r29305 | |
| 181 | 257 | }; |
| 182 | 258 | |
| 183 | 259 | static GFXDECODE_START( kopunch ) |
| 184 | | GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 1 ) |
| 185 | | GFXDECODE_ENTRY( "gfx2", 0, charlayoutbig, 0, 1 ) |
| 260 | GFXDECODE_ENTRY( "gfx1", 0, fg_layout, 0, 1 ) |
| 261 | GFXDECODE_ENTRY( "gfx2", 0, bg_layout, 0, 1 ) |
| 186 | 262 | GFXDECODE_END |
| 187 | 263 | |
| 188 | 264 | |
| r29304 | r29305 | |
| 203 | 279 | MCFG_CPU_ADD("maincpu", I8085A, 4000000) // 4 MHz? |
| 204 | 280 | MCFG_CPU_PROGRAM_MAP(kopunch_map) |
| 205 | 281 | MCFG_CPU_IO_MAP(kopunch_io_map) |
| 206 | | MCFG_CPU_VBLANK_INT_DRIVER("screen", kopunch_state, kopunch_interrupt) |
| 282 | MCFG_CPU_VBLANK_INT_DRIVER("screen", kopunch_state, vblank_interrupt) |
| 207 | 283 | |
| 284 | MCFG_I8255A_ADD("ppi8255_0", ppi8255_0_intf) |
| 285 | MCFG_I8255A_ADD("ppi8255_1", ppi8255_1_intf) |
| 286 | MCFG_I8255A_ADD("ppi8255_2", ppi8255_2_intf) |
| 287 | MCFG_I8255A_ADD("ppi8255_3", ppi8255_3_intf) |
| 288 | |
| 208 | 289 | /* video hardware */ |
| 209 | 290 | MCFG_SCREEN_ADD("screen", RASTER) |
| 210 | 291 | MCFG_SCREEN_REFRESH_RATE(60) |
| 211 | 292 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) |
| 212 | 293 | MCFG_SCREEN_SIZE(32*8, 32*8) |
| 213 | | MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) |
| 294 | MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 28*8-1) |
| 214 | 295 | MCFG_SCREEN_UPDATE_DRIVER(kopunch_state, screen_update_kopunch) |
| 215 | 296 | MCFG_SCREEN_PALETTE("palette") |
| 216 | 297 | |
| r29304 | r29305 | |
| 219 | 300 | MCFG_PALETTE_INIT_OWNER(kopunch_state, kopunch) |
| 220 | 301 | |
| 221 | 302 | /* sound hardware */ |
| 303 | // ... |
| 222 | 304 | MACHINE_CONFIG_END |
| 223 | 305 | |
| 224 | 306 | |
| 225 | | /*************************************************************************** |
| 226 | 307 | |
| 308 | /******************************************************** |
| 309 | |
| 227 | 310 | Game driver(s) |
| 228 | 311 | |
| 229 | | ***************************************************************************/ |
| 312 | ********************************************************/ |
| 230 | 313 | |
| 231 | 314 | ROM_START( kopunch ) |
| 232 | 315 | ROM_REGION( 0x10000, "maincpu", 0 ) |
| r29304 | r29305 | |
| 252 | 335 | ROM_LOAD( "epr1100", 0x0040, 0x0020, CRC(bedb66b1) SHA1(8e78bb205d900075b761e1baa5f5813174ff28ba) ) /* unknown */ |
| 253 | 336 | ROM_END |
| 254 | 337 | |
| 338 | |
| 255 | 339 | GAME( 1981, kopunch, 0, kopunch, kopunch, driver_device, 0, ROT270, "Sega", "KO Punch", GAME_NO_SOUND | GAME_NOT_WORKING | GAME_MECHANICAL | GAME_SUPPORTS_SAVE ) |
shelves/new_menus/src/emu/rendlay.c
| r29304 | r29305 | |
| 666 | 666 | m_stateoffset = xml_get_attribute_int_with_subst(machine, compnode, "stateoffset", 0); |
| 667 | 667 | m_numsymbolsvisible = xml_get_attribute_int_with_subst(machine, compnode, "numsymbolsvisible", 3); |
| 668 | 668 | m_reelreversed = xml_get_attribute_int_with_subst(machine, compnode, "reelreversed", 0); |
| 669 | m_beltreel = xml_get_attribute_int_with_subst(machine, compnode, "beltreel", 0); |
| 670 | |
| 669 | 671 | } |
| 670 | 672 | |
| 671 | 673 | // led7seg nodes |
| r29304 | r29305 | |
| 981 | 983 | /* state is a normalized value between 0 and 65536 so that we don't need to worry about how many motor steps here or in the .lay, only the number of symbols */ |
| 982 | 984 | void layout_element::component::draw_reel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) |
| 983 | 985 | { |
| 986 | if (m_beltreel) |
| 987 | { |
| 988 | draw_beltreel(machine,dest,bounds,state); |
| 989 | } |
| 990 | else |
| 991 | { |
| 992 | const int max_state_used = 0x10000; |
| 993 | |
| 994 | // shift the reels a bit based on this param, allows fine tuning |
| 995 | int use_state = (state + m_stateoffset) % max_state_used; |
| 996 | |
| 997 | // compute premultiplied colors |
| 998 | UINT32 r = m_color.r * 255.0; |
| 999 | UINT32 g = m_color.g * 255.0; |
| 1000 | UINT32 b = m_color.b * 255.0; |
| 1001 | UINT32 a = m_color.a * 255.0; |
| 1002 | |
| 1003 | // get the width of the string |
| 1004 | render_font *font = machine.render().font_alloc("default"); |
| 1005 | float aspect = 1.0f; |
| 1006 | INT32 width; |
| 1007 | |
| 1008 | |
| 1009 | int curry = 0; |
| 1010 | int num_shown = m_numsymbolsvisible; |
| 1011 | |
| 1012 | int ourheight = bounds.height(); |
| 1013 | |
| 1014 | for (int fruit = 0;fruit<m_numstops;fruit++) |
| 1015 | { |
| 1016 | int basey; |
| 1017 | |
| 1018 | if (m_reelreversed==1) |
| 1019 | { |
| 1020 | basey = bounds.min_y + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry; |
| 1021 | } |
| 1022 | else |
| 1023 | { |
| 1024 | basey = bounds.min_y - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry; |
| 1025 | } |
| 1026 | |
| 1027 | // wrap around... |
| 1028 | if (basey < bounds.min_y) |
| 1029 | basey += ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops)); |
| 1030 | if (basey > bounds.max_y) |
| 1031 | basey -= ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops)); |
| 1032 | |
| 1033 | int endpos = basey+ourheight/num_shown; |
| 1034 | |
| 1035 | // only render the symbol / text if it's atually in view because the code is SLOW |
| 1036 | if ((endpos >= bounds.min_y) && (basey <= bounds.max_y)) |
| 1037 | { |
| 1038 | while (1) |
| 1039 | { |
| 1040 | width = font->string_width(ourheight/num_shown, aspect, m_stopnames[fruit]); |
| 1041 | if (width < bounds.width()) |
| 1042 | break; |
| 1043 | aspect *= 0.9f; |
| 1044 | } |
| 1045 | |
| 1046 | INT32 curx; |
| 1047 | curx = bounds.min_x + (bounds.width() - width) / 2; |
| 1048 | |
| 1049 | if (m_file[fruit]) |
| 1050 | if (!m_bitmap[fruit].valid()) |
| 1051 | load_reel_bitmap(fruit); |
| 1052 | |
| 1053 | if (m_file[fruit]) // render gfx |
| 1054 | { |
| 1055 | bitmap_argb32 tempbitmap2(dest.width(), ourheight/num_shown); |
| 1056 | |
| 1057 | if (m_bitmap[fruit].valid()) |
| 1058 | { |
| 1059 | render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], m_color); |
| 1060 | |
| 1061 | for (int y = 0; y < ourheight/num_shown; y++) |
| 1062 | { |
| 1063 | int effy = basey + y; |
| 1064 | |
| 1065 | if (effy >= bounds.min_y && effy <= bounds.max_y) |
| 1066 | { |
| 1067 | UINT32 *src = &tempbitmap2.pix32(y); |
| 1068 | UINT32 *d = &dest.pix32(effy); |
| 1069 | for (int x = 0; x < dest.width(); x++) |
| 1070 | { |
| 1071 | int effx = x; |
| 1072 | if (effx >= bounds.min_x && effx <= bounds.max_x) |
| 1073 | { |
| 1074 | UINT32 spix = rgb_t(src[x]).a(); |
| 1075 | if (spix != 0) |
| 1076 | { |
| 1077 | d[effx] = src[x]; |
| 1078 | } |
| 1079 | } |
| 1080 | } |
| 1081 | } |
| 1082 | |
| 1083 | } |
| 1084 | } |
| 1085 | } |
| 1086 | else // render text (fallback) |
| 1087 | { |
| 1088 | // allocate a temporary bitmap |
| 1089 | bitmap_argb32 tempbitmap(dest.width(), dest.height()); |
| 1090 | |
| 1091 | // loop over characters |
| 1092 | for (const char *s = m_stopnames[fruit]; *s != 0; s++) |
| 1093 | { |
| 1094 | // get the font bitmap |
| 1095 | rectangle chbounds; |
| 1096 | font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, *s, chbounds); |
| 1097 | |
| 1098 | // copy the data into the target |
| 1099 | for (int y = 0; y < chbounds.height(); y++) |
| 1100 | { |
| 1101 | int effy = basey + y; |
| 1102 | |
| 1103 | if (effy >= bounds.min_y && effy <= bounds.max_y) |
| 1104 | { |
| 1105 | UINT32 *src = &tempbitmap.pix32(y); |
| 1106 | UINT32 *d = &dest.pix32(effy); |
| 1107 | for (int x = 0; x < chbounds.width(); x++) |
| 1108 | { |
| 1109 | int effx = curx + x + chbounds.min_x; |
| 1110 | if (effx >= bounds.min_x && effx <= bounds.max_x) |
| 1111 | { |
| 1112 | UINT32 spix = rgb_t(src[x]).a(); |
| 1113 | if (spix != 0) |
| 1114 | { |
| 1115 | rgb_t dpix = d[effx]; |
| 1116 | UINT32 ta = (a * (spix + 1)) >> 8; |
| 1117 | UINT32 tr = (r * ta + dpix.r() * (0x100 - ta)) >> 8; |
| 1118 | UINT32 tg = (g * ta + dpix.g() * (0x100 - ta)) >> 8; |
| 1119 | UINT32 tb = (b * ta + dpix.b() * (0x100 - ta)) >> 8; |
| 1120 | d[effx] = rgb_t(tr, tg, tb); |
| 1121 | } |
| 1122 | } |
| 1123 | } |
| 1124 | } |
| 1125 | } |
| 1126 | |
| 1127 | // advance in the X direction |
| 1128 | curx += font->char_width(ourheight/num_shown, aspect, *s); |
| 1129 | |
| 1130 | } |
| 1131 | |
| 1132 | } |
| 1133 | } |
| 1134 | |
| 1135 | curry += ourheight/num_shown; |
| 1136 | } |
| 1137 | // free the temporary bitmap and font |
| 1138 | machine.render().font_free(font); |
| 1139 | } |
| 1140 | } |
| 1141 | |
| 1142 | |
| 1143 | void layout_element::component::draw_beltreel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) |
| 1144 | { |
| 984 | 1145 | const int max_state_used = 0x10000; |
| 985 | 1146 | |
| 986 | 1147 | // shift the reels a bit based on this param, allows fine tuning |
| r29304 | r29305 | |
| 996 | 1157 | render_font *font = machine.render().font_alloc("default"); |
| 997 | 1158 | float aspect = 1.0f; |
| 998 | 1159 | INT32 width; |
| 999 | | int curry = 0; |
| 1160 | int currx = 0; |
| 1000 | 1161 | int num_shown = m_numsymbolsvisible; |
| 1001 | 1162 | |
| 1002 | | int ourheight = bounds.height(); |
| 1163 | int ourwidth = bounds.width(); |
| 1003 | 1164 | |
| 1004 | 1165 | for (int fruit = 0;fruit<m_numstops;fruit++) |
| 1005 | 1166 | { |
| 1006 | | int basey; |
| 1007 | | |
| 1167 | int basex; |
| 1008 | 1168 | if (m_reelreversed==1) |
| 1009 | 1169 | { |
| 1010 | | basey = bounds.min_y + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry; |
| 1170 | basex = bounds.min_x + ((use_state)*(ourwidth/num_shown)/(max_state_used/m_numstops)) + currx; |
| 1011 | 1171 | } |
| 1012 | 1172 | else |
| 1013 | 1173 | { |
| 1014 | | basey = bounds.min_y - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry; |
| 1174 | basex = bounds.min_x - ((use_state)*(ourwidth/num_shown)/(max_state_used/m_numstops)) + currx; |
| 1015 | 1175 | } |
| 1016 | 1176 | |
| 1017 | 1177 | // wrap around... |
| 1018 | | if (basey < bounds.min_y) |
| 1019 | | basey += ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops)); |
| 1020 | | if (basey > bounds.max_y) |
| 1021 | | basey -= ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops)); |
| 1178 | if (basex < bounds.min_x) |
| 1179 | basex += ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops)); |
| 1180 | if (basex > bounds.max_x) |
| 1181 | basex -= ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops)); |
| 1022 | 1182 | |
| 1023 | | int endpos = basey+ourheight/num_shown; |
| 1183 | int endpos = basex+(ourwidth/num_shown); |
| 1024 | 1184 | |
| 1025 | 1185 | // only render the symbol / text if it's atually in view because the code is SLOW |
| 1026 | | if ((endpos >= bounds.min_y) && (basey <= bounds.max_y)) |
| 1186 | if ((endpos >= bounds.min_x) && (basex <= bounds.max_x)) |
| 1027 | 1187 | { |
| 1028 | 1188 | while (1) |
| 1029 | 1189 | { |
| 1030 | | width = font->string_width(ourheight/num_shown, aspect, m_stopnames[fruit]); |
| 1190 | width = font->string_width(dest.height(), aspect, m_stopnames[fruit]); |
| 1031 | 1191 | if (width < bounds.width()) |
| 1032 | 1192 | break; |
| 1033 | 1193 | aspect *= 0.9f; |
| 1034 | 1194 | } |
| 1035 | 1195 | |
| 1036 | 1196 | INT32 curx; |
| 1037 | | curx = bounds.min_x + (bounds.width() - width) / 2; |
| 1197 | curx = bounds.min_x; |
| 1038 | 1198 | |
| 1039 | 1199 | if (m_file[fruit]) |
| 1040 | 1200 | if (!m_bitmap[fruit].valid()) |
| r29304 | r29305 | |
| 1042 | 1202 | |
| 1043 | 1203 | if (m_file[fruit]) // render gfx |
| 1044 | 1204 | { |
| 1045 | | bitmap_argb32 tempbitmap2(dest.width(), ourheight/num_shown); |
| 1205 | bitmap_argb32 tempbitmap2(ourwidth/num_shown, dest.height()); |
| 1046 | 1206 | |
| 1047 | 1207 | if (m_bitmap[fruit].valid()) |
| 1048 | 1208 | { |
| 1049 | 1209 | render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], m_color); |
| 1050 | 1210 | |
| 1051 | | for (int y = 0; y < ourheight/num_shown; y++) |
| 1211 | for (int y = 0; y < dest.height(); y++) |
| 1052 | 1212 | { |
| 1053 | | int effy = basey + y; |
| 1213 | int effy = y; |
| 1054 | 1214 | |
| 1055 | 1215 | if (effy >= bounds.min_y && effy <= bounds.max_y) |
| 1056 | 1216 | { |
| 1057 | 1217 | UINT32 *src = &tempbitmap2.pix32(y); |
| 1058 | 1218 | UINT32 *d = &dest.pix32(effy); |
| 1059 | | for (int x = 0; x < dest.width(); x++) |
| 1219 | for (int x = 0; x < ourwidth/num_shown; x++) |
| 1060 | 1220 | { |
| 1061 | | int effx = x; |
| 1221 | int effx = basex + x; |
| 1062 | 1222 | if (effx >= bounds.min_x && effx <= bounds.max_x) |
| 1063 | 1223 | { |
| 1064 | 1224 | UINT32 spix = rgb_t(src[x]).a(); |
| r29304 | r29305 | |
| 1083 | 1243 | { |
| 1084 | 1244 | // get the font bitmap |
| 1085 | 1245 | rectangle chbounds; |
| 1086 | | font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, *s, chbounds); |
| 1246 | font->get_scaled_bitmap_and_bounds(tempbitmap, dest.height(), aspect, *s, chbounds); |
| 1087 | 1247 | |
| 1088 | 1248 | // copy the data into the target |
| 1089 | 1249 | for (int y = 0; y < chbounds.height(); y++) |
| 1090 | 1250 | { |
| 1091 | | int effy = basey + y; |
| 1251 | int effy = y; |
| 1092 | 1252 | |
| 1093 | 1253 | if (effy >= bounds.min_y && effy <= bounds.max_y) |
| 1094 | 1254 | { |
| r29304 | r29305 | |
| 1096 | 1256 | UINT32 *d = &dest.pix32(effy); |
| 1097 | 1257 | for (int x = 0; x < chbounds.width(); x++) |
| 1098 | 1258 | { |
| 1099 | | int effx = curx + x + chbounds.min_x; |
| 1259 | int effx = basex + curx + x; |
| 1100 | 1260 | if (effx >= bounds.min_x && effx <= bounds.max_x) |
| 1101 | 1261 | { |
| 1102 | | UINT32 spix = rgb_t(src[x]).a(); |
| 1262 | UINT32 spix = rgb_t(src[x]).a(); |
| 1103 | 1263 | if (spix != 0) |
| 1104 | 1264 | { |
| 1105 | 1265 | rgb_t dpix = d[effx]; |
| r29304 | r29305 | |
| 1115 | 1275 | } |
| 1116 | 1276 | |
| 1117 | 1277 | // advance in the X direction |
| 1118 | | curx += font->char_width(ourheight/num_shown, aspect, *s); |
| 1278 | curx += font->char_width(dest.height(), aspect, *s); |
| 1119 | 1279 | |
| 1120 | 1280 | } |
| 1121 | 1281 | |
| 1122 | 1282 | } |
| 1123 | 1283 | } |
| 1124 | 1284 | |
| 1125 | | curry += ourheight/num_shown; |
| 1285 | currx += ourwidth/num_shown; |
| 1126 | 1286 | } |
| 1127 | 1287 | |
| 1128 | 1288 | // free the temporary bitmap and font |
| r29304 | r29305 | |
| 1130 | 1290 | } |
| 1131 | 1291 | |
| 1132 | 1292 | |
| 1133 | | |
| 1134 | | |
| 1135 | 1293 | //------------------------------------------------- |
| 1136 | 1294 | // load_bitmap - load a PNG file with artwork for |
| 1137 | 1295 | // a component |
shelves/new_menus/src/emu/bus/isa/omti8621.c
| r29304 | r29305 | |
| 28 | 28 | #define LOG2(x) { if (verbose > 1) LOG(x)} |
| 29 | 29 | #define LOG3(x) { if (verbose > 2) LOG(x)} |
| 30 | 30 | |
| 31 | | #define DLOG(x) { logerror ("%s: ", cpu_context(disk->device)); logerror x; logerror ("\n"); } |
| 32 | | #define DLOG1(x) { if (verbose > 0) DLOG(x)} |
| 33 | | #define DLOG2(x) { if (verbose > 1) DLOG(x)} |
| 34 | | |
| 35 | 31 | #define OMTI_DISK_SECTOR_SIZE 1056 |
| 36 | 32 | |
| 37 | 33 | #define OMTI_DISK_TYPE_155_MB 0x607 // Micropolis 1355 (170 MB Dtype = 607) |
| r29304 | r29305 | |
| 71 | 67 | virtual const option_guide *create_option_guide() const { return NULL; } |
| 72 | 68 | |
| 73 | 69 | virtual bool call_create(int format_type, option_resolution *format_options); |
| 74 | | |
| 75 | | disk_data *token() { return &m_token; } |
| 76 | 70 | protected: |
| 77 | 71 | // device-level overrides |
| 78 | 72 | virtual void device_config_complete(); |
| 79 | 73 | virtual void device_start(); |
| 80 | 74 | virtual void device_reset(); |
| 75 | |
| 76 | void omti_disk_config(UINT16 disk_type); |
| 77 | public: |
| 78 | UINT16 m_type; |
| 79 | UINT16 m_cylinders; |
| 80 | UINT16 m_heads; |
| 81 | UINT16 m_sectors; |
| 82 | UINT32 m_sectorbytes; |
| 83 | UINT32 m_sector_count; |
| 81 | 84 | |
| 82 | | disk_data m_token; |
| 85 | device_image_interface *m_image; |
| 86 | |
| 87 | // configuration data |
| 88 | UINT8 m_config_data[10]; |
| 89 | |
| 90 | // ESDI defect list data |
| 91 | UINT8 m_esdi_defect_list[256]; |
| 83 | 92 | }; |
| 84 | 93 | |
| 85 | 94 | /* |
| r29304 | r29305 | |
| 279 | 288 | sector_buffer.resize(OMTI_DISK_SECTOR_SIZE*OMTI_MAX_BLOCK_COUNT); |
| 280 | 289 | |
| 281 | 290 | m_timer = timer_alloc(0, NULL); |
| 282 | | |
| 283 | | device_t *device0 = subdevice(OMTI_DISK0_TAG); |
| 284 | | our_disks[0] = (disk_data *) downcast<omti_disk_image_device *>(device0)->token(); |
| 285 | | |
| 286 | | device_t *device1 = subdevice(OMTI_DISK1_TAG); |
| 287 | | our_disks[1] = (disk_data *) downcast<omti_disk_image_device *>(device1)->token(); |
| 291 | |
| 292 | our_disks[0] = subdevice<omti_disk_image_device>(OMTI_DISK0_TAG); |
| 293 | our_disks[1] = subdevice<omti_disk_image_device>(OMTI_DISK1_TAG); |
| 288 | 294 | } |
| 289 | 295 | |
| 290 | 296 | /*------------------------------------------------- |
| r29304 | r29305 | |
| 320 | 326 | m_installed = true; |
| 321 | 327 | } |
| 322 | 328 | |
| 323 | | set_jumper(our_disks[0]->type); |
| 329 | set_jumper(our_disks[0]->m_type); |
| 324 | 330 | |
| 325 | 331 | // should go from reset to idle after 100 us |
| 326 | 332 | // state->omti_state = OMTI_STATE_RESET; |
| r29304 | r29305 | |
| 422 | 428 | LOG2(("set_configuration_data lun=%x", lun)); |
| 423 | 429 | |
| 424 | 430 | // initialize the configuration data |
| 425 | | disk_data *disk = our_disks[lun]; |
| 431 | omti_disk_image_device *disk = our_disks[lun]; |
| 426 | 432 | |
| 427 | | disk->config_data[0] = (disk->cylinders - 1) >> 8; // Number of Cylinders (MSB) |
| 428 | | disk->config_data[1] = (disk->cylinders - 1) & 0xff; // Number of Cylinders (LSB) (-1) |
| 429 | | disk->config_data[2] = disk->heads - 1; // Number of Heads (-1) |
| 430 | | disk->config_data[3] = disk->sectors - 1; // Number of Sectors (-1) |
| 431 | | disk->config_data[4] = 0x02; // Drive Configuration Word (MSB) |
| 432 | | disk->config_data[5] = 0x44; // Drive Configuration Word (LSB) |
| 433 | | disk->config_data[6] = 0x00; // ISG AFTER INDEX |
| 434 | | disk->config_data[7] = 0x00; // PLO SYN Field (ID) |
| 435 | | disk->config_data[8] = 0x00; // PLO SYN Field (DATA) |
| 436 | | disk->config_data[9] = 0x00; // ISG AFTER SECTOR |
| 433 | disk->m_config_data[0] = (disk->m_cylinders - 1) >> 8; // Number of Cylinders (MSB) |
| 434 | disk->m_config_data[1] = (disk->m_cylinders - 1) & 0xff; // Number of Cylinders (LSB) (-1) |
| 435 | disk->m_config_data[2] = disk->m_heads - 1; // Number of Heads (-1) |
| 436 | disk->m_config_data[3] = disk->m_sectors - 1; // Number of Sectors (-1) |
| 437 | disk->m_config_data[4] = 0x02; // Drive Configuration Word (MSB) |
| 438 | disk->m_config_data[5] = 0x44; // Drive Configuration Word (LSB) |
| 439 | disk->m_config_data[6] = 0x00; // ISG AFTER INDEX |
| 440 | disk->m_config_data[7] = 0x00; // PLO SYN Field (ID) |
| 441 | disk->m_config_data[8] = 0x00; // PLO SYN Field (DATA) |
| 442 | disk->m_config_data[9] = 0x00; // ISG AFTER SECTOR |
| 437 | 443 | } |
| 438 | 444 | |
| 439 | 445 | /*************************************************************************** |
| r29304 | r29305 | |
| 457 | 463 | UINT16 sector = cdb[2] & 0x3f; |
| 458 | 464 | UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3); |
| 459 | 465 | UINT8 block_count = cdb[4]; |
| 460 | | disk_data *disk = our_disks[lun]; |
| 466 | omti_disk_image_device *disk = our_disks[lun]; |
| 461 | 467 | |
| 462 | | UINT32 disk_track = cylinder * disk->heads + head; |
| 463 | | UINT32 disk_addr = (disk_track * disk->sectors) + sector; |
| 468 | UINT32 disk_track = cylinder * disk->m_heads + head; |
| 469 | UINT32 disk_addr = (disk_track * disk->m_sectors) + sector; |
| 464 | 470 | |
| 465 | 471 | if (block_count > OMTI_MAX_BLOCK_COUNT) { |
| 466 | 472 | LOG(("########### check_disk_address: unexpected block count %x", block_count)); |
| r29304 | r29305 | |
| 469 | 475 | |
| 470 | 476 | if (lun > OMTI_MAX_LUN) { |
| 471 | 477 | sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY; |
| 472 | | } else if (!disk->image->exists()) { |
| 478 | } else if (!disk->m_image->exists()) { |
| 473 | 479 | sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY; |
| 474 | 480 | } else if (sector >= OMTI_MAX_BLOCK_COUNT) { |
| 475 | 481 | sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID; |
| 476 | | } else if (head >= disk->heads) { |
| 482 | } else if (head >= disk->m_heads) { |
| 477 | 483 | sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID; |
| 478 | | } else if (cylinder >= disk->cylinders) { |
| 484 | } else if (cylinder >= disk->m_cylinders) { |
| 479 | 485 | sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID; |
| 480 | 486 | } else if ( disk_track == diskaddr_format_bad_track && disk_track != 0) { |
| 481 | 487 | sense_code = OMTI_SENSE_CODE_BAD_TRACK; |
| r29304 | r29305 | |
| 502 | 508 | UINT8 lun = get_lun(cdb); |
| 503 | 509 | UINT16 head = cdb[1] & 0x1f; |
| 504 | 510 | UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3); |
| 505 | | return cylinder * our_disks[lun]->heads + head; |
| 511 | return cylinder * our_disks[lun]->m_heads + head; |
| 506 | 512 | } |
| 507 | 513 | |
| 508 | 514 | /*************************************************************************** |
| r29304 | r29305 | |
| 512 | 518 | UINT32 omti8621_device::get_disk_address(const UINT8 * cdb) { |
| 513 | 519 | UINT8 lun = get_lun(cdb); |
| 514 | 520 | UINT16 sector = cdb[2] & 0x3f; |
| 515 | | return get_disk_track(cdb) * our_disks[lun]->sectors + sector; |
| 521 | return get_disk_track(cdb) * our_disks[lun]->m_sectors + sector; |
| 516 | 522 | } |
| 517 | 523 | |
| 518 | 524 | /*************************************************************************** |
| r29304 | r29305 | |
| 538 | 544 | void omti8621_device::read_sectors_from_disk(INT32 diskaddr, UINT8 count, UINT8 lun) |
| 539 | 545 | { |
| 540 | 546 | UINT8 *data_buffer = sector_buffer; |
| 541 | | device_image_interface *image = our_disks[lun]->image; |
| 547 | device_image_interface *image = our_disks[lun]->m_image; |
| 542 | 548 | |
| 543 | 549 | while (count-- > 0) { |
| 544 | 550 | LOG2(("read_sectors_from_disk lun=%d diskaddr=%x", lun, diskaddr)); |
| r29304 | r29305 | |
| 558 | 564 | void omti8621_device::write_sectors_to_disk(INT32 diskaddr, UINT8 count, UINT8 lun) |
| 559 | 565 | { |
| 560 | 566 | UINT8 *data_buffer = sector_buffer; |
| 561 | | device_image_interface *image = our_disks[lun]->image; |
| 567 | device_image_interface *image = our_disks[lun]->m_image; |
| 562 | 568 | |
| 563 | 569 | while (count-- > 0) { |
| 564 | 570 | LOG2(("write_sectors_to_disk lun=%d diskaddr=%x", lun, diskaddr)); |
| r29304 | r29305 | |
| 582 | 588 | |
| 583 | 589 | void omti8621_device::copy_sectors(INT32 dst_addr, INT32 src_addr, UINT8 count, UINT8 lun) |
| 584 | 590 | { |
| 585 | | device_image_interface *image = our_disks[lun]->image; |
| 591 | device_image_interface *image = our_disks[lun]->m_image; |
| 586 | 592 | |
| 587 | 593 | LOG2(("copy_sectors lun=%d src_addr=%x dst_addr=%x count=%x", lun, src_addr, dst_addr, count)); |
| 588 | 594 | |
| r29304 | r29305 | |
| 635 | 641 | |
| 636 | 642 | if (check_disk_address(cdb) ) { |
| 637 | 643 | if ((cdb[5] & 0x40) == 0) { |
| 638 | | memset(sector_buffer, 0x6C, OMTI_DISK_SECTOR_SIZE * our_disks[lun]->sectors); |
| 644 | memset(sector_buffer, 0x6C, OMTI_DISK_SECTOR_SIZE * our_disks[lun]->m_sectors); |
| 639 | 645 | } |
| 640 | | write_sectors_to_disk(disk_addr, our_disks[lun]->sectors, lun); |
| 646 | write_sectors_to_disk(disk_addr, our_disks[lun]->m_sectors, lun); |
| 641 | 647 | } |
| 642 | 648 | |
| 643 | 649 | } |
| r29304 | r29305 | |
| 648 | 654 | |
| 649 | 655 | void omti8621_device::set_esdi_defect_list(UINT8 lun, UINT8 head) |
| 650 | 656 | { |
| 651 | | disk_data *disk = our_disks[lun]; |
| 657 | omti_disk_image_device *disk = our_disks[lun]; |
| 652 | 658 | |
| 653 | | memset(disk->esdi_defect_list, 0, sizeof(disk->esdi_defect_list)); |
| 654 | | disk->esdi_defect_list[0] = 1; // month |
| 655 | | disk->esdi_defect_list[1] = 1; // day |
| 656 | | disk->esdi_defect_list[2] = 90; // year |
| 657 | | disk->esdi_defect_list[3] = head; |
| 658 | | memset(disk->esdi_defect_list+6, 0xff, 5); // end of defect list |
| 659 | memset(disk->m_esdi_defect_list, 0, sizeof(disk->m_esdi_defect_list)); |
| 660 | disk->m_esdi_defect_list[0] = 1; // month |
| 661 | disk->m_esdi_defect_list[1] = 1; // day |
| 662 | disk->m_esdi_defect_list[2] = 90; // year |
| 663 | disk->m_esdi_defect_list[3] = head; |
| 664 | memset(disk->m_esdi_defect_list+6, 0xff, 5); // end of defect list |
| 659 | 665 | } |
| 660 | 666 | |
| 661 | 667 | /*************************************************************************** |
| r29304 | r29305 | |
| 785 | 791 | void omti8621_device::do_command(const UINT8 cdb[], const UINT16 cdb_length) |
| 786 | 792 | { |
| 787 | 793 | UINT8 lun = get_lun(cdb); |
| 788 | | disk_data *disk = our_disks[lun]; |
| 794 | omti_disk_image_device *disk = our_disks[lun]; |
| 789 | 795 | int command_duration = 0; // ms |
| 790 | 796 | |
| 791 | 797 | log_command( cdb, cdb_length); |
| r29304 | r29305 | |
| 799 | 805 | set_interrupt(CLEAR_LINE); |
| 800 | 806 | } |
| 801 | 807 | |
| 802 | | if (!disk->image->exists()) { |
| 808 | if (!disk->m_image->exists()) { |
| 803 | 809 | command_status |= OMTI_COMMAND_STATUS_ERROR; // no such drive |
| 804 | 810 | } |
| 805 | 811 | |
| 806 | 812 | switch (cdb[0]) { |
| 807 | 813 | case OMTI_CMD_TEST_DRIVE_READY: // 0x00 |
| 808 | | if (!disk->image->exists()) |
| 814 | if (!disk->m_image->exists()) |
| 809 | 815 | { |
| 810 | 816 | set_sense_data(OMTI_SENSE_CODE_DRIVE_NOT_READY, cdb); |
| 811 | 817 | } |
| r29304 | r29305 | |
| 866 | 872 | |
| 867 | 873 | case OMTI_CMD_READ_ESDI_DEFECT_LIST: // 0x37 |
| 868 | 874 | set_esdi_defect_list(get_lun(cdb), cdb[1] & 0x1f); |
| 869 | | set_data_transfer(disk->esdi_defect_list, sizeof(disk->esdi_defect_list)); |
| 875 | set_data_transfer(disk->m_esdi_defect_list, sizeof(disk->m_esdi_defect_list)); |
| 870 | 876 | break; |
| 871 | 877 | |
| 872 | 878 | case OMTI_CMD_ASSIGN_ALTERNATE_TRACK: // 0x11 |
| r29304 | r29305 | |
| 917 | 923 | |
| 918 | 924 | case OMTI_CMD_READ_CONFIGURATION: // 0xEC |
| 919 | 925 | set_configuration_data(get_lun(cdb)); |
| 920 | | set_data_transfer(disk->config_data, sizeof(disk->config_data)); |
| 926 | set_data_transfer(disk->m_config_data, sizeof(disk->m_config_data)); |
| 921 | 927 | break; |
| 922 | 928 | |
| 923 | 929 | case OMTI_CMD_INVALID_COMMAND: // 0xFF |
| r29304 | r29305 | |
| 1196 | 1202 | |
| 1197 | 1203 | UINT32 omti8621_device::get_sector(INT32 diskaddr, UINT8 *data_buffer, UINT32 length, UINT8 lun) |
| 1198 | 1204 | { |
| 1199 | | disk_data *disk = our_disks[lun]; |
| 1205 | omti_disk_image_device *disk = our_disks[lun]; |
| 1200 | 1206 | |
| 1201 | | if (disk->image == NULL || !disk->image->exists()) |
| 1207 | if (disk->m_image == NULL || !disk->m_image->exists()) |
| 1202 | 1208 | { |
| 1203 | 1209 | return 0; |
| 1204 | 1210 | } |
| r29304 | r29305 | |
| 1209 | 1215 | // restrict length to size of 1 sector (i.e. 1024 Byte) |
| 1210 | 1216 | length = length < OMTI_DISK_SECTOR_SIZE ? length : OMTI_DISK_SECTOR_SIZE; |
| 1211 | 1217 | |
| 1212 | | disk->image->fseek(diskaddr * OMTI_DISK_SECTOR_SIZE, SEEK_SET); |
| 1213 | | disk->image->fread(data_buffer, length); |
| 1218 | disk->m_image->fseek(diskaddr * OMTI_DISK_SECTOR_SIZE, SEEK_SET); |
| 1219 | disk->m_image->fread(data_buffer, length); |
| 1214 | 1220 | |
| 1215 | 1221 | return length; |
| 1216 | 1222 | } |
| r29304 | r29305 | |
| 1282 | 1288 | |
| 1283 | 1289 | |
| 1284 | 1290 | /*************************************************************************** |
| 1285 | | get_safe_disk_token - makes sure that the passed in device is a OMTI disk |
| 1286 | | ***************************************************************************/ |
| 1287 | | |
| 1288 | | INLINE disk_data *get_safe_disk_token(device_t *device) { |
| 1289 | | assert(device != NULL); |
| 1290 | | assert(device->type() == OMTI_DISK); |
| 1291 | | return (disk_data *) downcast<omti_disk_image_device *>(device)->token(); |
| 1292 | | } |
| 1293 | | |
| 1294 | | /*************************************************************************** |
| 1295 | 1291 | omti_disk_config - configure disk parameters |
| 1296 | 1292 | ***************************************************************************/ |
| 1297 | 1293 | |
| 1298 | | static void omti_disk_config(disk_data *disk, UINT16 disk_type) |
| 1294 | void omti_disk_image_device::omti_disk_config(UINT16 disk_type) |
| 1299 | 1295 | { |
| 1300 | | DLOG1(("omti_disk_config: configuring disk with type %x", disk_type)); |
| 1296 | LOG1(("omti_disk_config: configuring disk with type %x", disk_type)); |
| 1301 | 1297 | |
| 1302 | 1298 | switch (disk_type) |
| 1303 | 1299 | { |
| 1304 | 1300 | case OMTI_DISK_TYPE_348_MB: // Maxtor 380 MB (348-MB FA formatted) |
| 1305 | | disk->cylinders = 1223; |
| 1306 | | disk->heads = 15; |
| 1307 | | disk->sectors = 18; |
| 1301 | m_cylinders = 1223; |
| 1302 | m_heads = 15; |
| 1303 | m_sectors = 18; |
| 1308 | 1304 | break; |
| 1309 | 1305 | |
| 1310 | 1306 | case OMTI_DISK_TYPE_155_MB: // Micropolis 170 MB (155-MB formatted) |
| 1311 | 1307 | default: |
| 1312 | | disk->cylinders = 1023; |
| 1313 | | disk->heads = 8; |
| 1314 | | disk->sectors = 18; |
| 1308 | m_cylinders = 1023; |
| 1309 | m_heads = 8; |
| 1310 | m_sectors = 18; |
| 1315 | 1311 | break; |
| 1316 | 1312 | } |
| 1317 | 1313 | |
| 1318 | | disk->type = disk_type; |
| 1319 | | disk->sectorbytes = OMTI_DISK_SECTOR_SIZE; |
| 1320 | | disk->sector_count = disk->cylinders * disk->heads * disk->sectors; |
| 1314 | m_type = disk_type; |
| 1315 | m_sectorbytes = OMTI_DISK_SECTOR_SIZE; |
| 1316 | m_sector_count = m_cylinders * m_heads * m_sectors; |
| 1321 | 1317 | } |
| 1322 | 1318 | |
| 1323 | 1319 | /*------------------------------------------------- |
| r29304 | r29305 | |
| 1326 | 1322 | |
| 1327 | 1323 | void omti_disk_image_device::device_start() |
| 1328 | 1324 | { |
| 1329 | | disk_data *disk = get_safe_disk_token(this); |
| 1325 | m_image = this; |
| 1330 | 1326 | |
| 1331 | | disk->device = this; |
| 1332 | | // note: we must have disk->device before we can log |
| 1333 | | |
| 1334 | | disk->image = this; |
| 1335 | | |
| 1336 | | if (disk->image->image_core_file() == NULL) |
| 1327 | if (m_image->image_core_file() == NULL) |
| 1337 | 1328 | { |
| 1338 | | DLOG1(("device_start_omti_disk: no disk")); |
| 1329 | LOG1(("device_start_omti_disk: no disk")); |
| 1339 | 1330 | } |
| 1340 | 1331 | else |
| 1341 | 1332 | { |
| 1342 | | DLOG1(("device_start_omti_disk: with disk image %s",disk->image->basename() )); |
| 1333 | LOG1(("device_start_omti_disk: with disk image %s",m_image->basename() )); |
| 1343 | 1334 | } |
| 1344 | 1335 | |
| 1345 | 1336 | // default disk type |
| 1346 | | omti_disk_config(disk, OMTI_DISK_TYPE_DEFAULT); |
| 1337 | omti_disk_config(OMTI_DISK_TYPE_DEFAULT); |
| 1347 | 1338 | } |
| 1348 | 1339 | |
| 1349 | 1340 | /*------------------------------------------------- |
| r29304 | r29305 | |
| 1351 | 1342 | -------------------------------------------------*/ |
| 1352 | 1343 | |
| 1353 | 1344 | void omti_disk_image_device::device_reset() |
| 1354 | | { |
| 1355 | | disk_data *disk = get_safe_disk_token(this); |
| 1356 | | DLOG1(("device_reset_omti_disk")); |
| 1345 | { |
| 1346 | LOG1(("device_reset_omti_disk")); |
| 1357 | 1347 | |
| 1358 | 1348 | if (exists() && fseek(0, SEEK_END) == 0) |
| 1359 | 1349 | { |
| 1360 | 1350 | UINT32 disk_size = (UINT32)(ftell() / OMTI_DISK_SECTOR_SIZE); |
| 1361 | 1351 | UINT16 disk_type = disk_size >= 300000 ? OMTI_DISK_TYPE_348_MB : OMTI_DISK_TYPE_155_MB; |
| 1362 | | if (disk_type != disk->type) { |
| 1363 | | DLOG1(("device_reset_omti_disk: disk size=%d blocks, disk type=%x", disk_size, disk_type )); |
| 1364 | | omti_disk_config(disk, disk_type); |
| 1352 | if (disk_type != m_type) { |
| 1353 | LOG1(("device_reset_omti_disk: disk size=%d blocks, disk type=%x", disk_size, disk_type )); |
| 1354 | omti_disk_config(disk_type); |
| 1365 | 1355 | } |
| 1366 | 1356 | } |
| 1367 | 1357 | } |
| r29304 | r29305 | |
| 1372 | 1362 | |
| 1373 | 1363 | bool omti_disk_image_device::call_create(int format_type, option_resolution *format_options) |
| 1374 | 1364 | { |
| 1375 | | disk_data *disk = get_safe_disk_token(this); |
| 1376 | | DLOG(("device_create_omti_disk: creating OMTI Disk with %d blocks", disk->sector_count)); |
| 1365 | LOG(("device_create_omti_disk: creating OMTI Disk with %d blocks", m_sector_count)); |
| 1377 | 1366 | |
| 1378 | 1367 | int x; |
| 1379 | 1368 | unsigned char sectordata[OMTI_DISK_SECTOR_SIZE]; // empty block data |
| 1380 | 1369 | |
| 1381 | 1370 | |
| 1382 | 1371 | memset(sectordata, 0x55, sizeof(sectordata)); |
| 1383 | | for (x = 0; x < disk->sector_count; x++) |
| 1372 | for (x = 0; x < m_sector_count; x++) |
| 1384 | 1373 | { |
| 1385 | 1374 | if (fwrite(sectordata, OMTI_DISK_SECTOR_SIZE) |
| 1386 | 1375 | < OMTI_DISK_SECTOR_SIZE) |
shelves/new_menus/src/emu/machine/smpc.c
| r29304 | r29305 | |
| 164 | 164 | * |
| 165 | 165 | *******************************************/ |
| 166 | 166 | |
| 167 | | static TIMER_CALLBACK( stv_bankswitch_state ) |
| 167 | TIMER_CALLBACK_MEMBER( saturn_state::stv_bankswitch_state ) |
| 168 | 168 | { |
| 169 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 170 | 169 | static const char *const banknames[] = { "game0", "game1", "game2", "game3" }; |
| 171 | 170 | UINT8* game_region; |
| 172 | 171 | |
| 173 | | if(state->m_prev_bankswitch != param) |
| 172 | if(m_prev_bankswitch != param) |
| 174 | 173 | { |
| 175 | | game_region = machine.root_device().memregion(banknames[param])->base(); |
| 174 | game_region = memregion(banknames[param])->base(); |
| 176 | 175 | |
| 177 | 176 | if (game_region) |
| 178 | | memcpy(machine.root_device().memregion("abus")->base(), game_region, 0x3000000); |
| 177 | memcpy(memregion("abus")->base(), game_region, 0x3000000); |
| 179 | 178 | else |
| 180 | | memset(machine.root_device().memregion("abus")->base(), 0x00, 0x3000000); |
| 179 | memset(memregion("abus")->base(), 0x00, 0x3000000); |
| 181 | 180 | |
| 182 | | state->m_prev_bankswitch = param; |
| 181 | m_prev_bankswitch = param; |
| 183 | 182 | } |
| 184 | 183 | } |
| 185 | 184 | |
| 186 | | static void stv_select_game(running_machine &machine, int gameno) |
| 185 | void saturn_state::stv_select_game(int gameno) |
| 187 | 186 | { |
| 188 | | machine.scheduler().timer_set(attotime::zero, FUNC(stv_bankswitch_state), gameno); |
| 187 | machine().scheduler().timer_set(attotime::zero, timer_expired_delegate(FUNC(saturn_state::stv_bankswitch_state),this), gameno); |
| 189 | 188 | } |
| 190 | 189 | |
| 191 | 190 | /******************************************** |
| r29304 | r29305 | |
| 194 | 193 | * |
| 195 | 194 | *******************************************/ |
| 196 | 195 | |
| 197 | | static void smpc_master_on(running_machine &machine) |
| 196 | void saturn_state::smpc_master_on() |
| 198 | 197 | { |
| 199 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 200 | | |
| 201 | | state->m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 198 | m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 202 | 199 | } |
| 203 | 200 | |
| 204 | | static TIMER_CALLBACK( smpc_slave_enable ) |
| 201 | TIMER_CALLBACK_MEMBER( saturn_state::smpc_slave_enable ) |
| 205 | 202 | { |
| 206 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 207 | | |
| 208 | | state->m_slave->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE); |
| 209 | | state->m_smpc.OREG[31] = param + 0x02; //read-back for last command issued |
| 210 | | state->m_smpc.SF = 0x00; //clear hand-shake flag |
| 211 | | state->m_smpc.slave_on = param; |
| 212 | | // printf("%d %d\n",machine.first_screen()->hpos(),machine.first_screen()->vpos()); |
| 203 | m_slave->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE); |
| 204 | m_smpc.OREG[31] = param + 0x02; //read-back for last command issued |
| 205 | m_smpc.SF = 0x00; //clear hand-shake flag |
| 206 | m_smpc.slave_on = param; |
| 207 | // printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); |
| 213 | 208 | } |
| 214 | 209 | |
| 215 | | static TIMER_CALLBACK( smpc_sound_enable ) |
| 210 | TIMER_CALLBACK_MEMBER( saturn_state::smpc_sound_enable ) |
| 216 | 211 | { |
| 217 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 218 | | |
| 219 | | state->m_audiocpu->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE); |
| 220 | | state->m_en_68k = param ^ 1; |
| 221 | | state->m_smpc.OREG[31] = param + 0x06; //read-back for last command issued |
| 222 | | state->m_smpc.SF = 0x00; //clear hand-shake flag |
| 212 | m_audiocpu->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE); |
| 213 | m_en_68k = param ^ 1; |
| 214 | m_smpc.OREG[31] = param + 0x06; //read-back for last command issued |
| 215 | m_smpc.SF = 0x00; //clear hand-shake flag |
| 223 | 216 | } |
| 224 | 217 | |
| 225 | | static TIMER_CALLBACK( smpc_cd_enable ) |
| 218 | TIMER_CALLBACK_MEMBER( saturn_state::smpc_cd_enable ) |
| 226 | 219 | { |
| 227 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 228 | | |
| 229 | | state->m_smpc.OREG[31] = param + 0x08; //read-back for last command issued |
| 230 | | state->m_smpc.SF = 0x08; //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high) |
| 220 | m_smpc.OREG[31] = param + 0x08; //read-back for last command issued |
| 221 | m_smpc.SF = 0x08; //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high) |
| 231 | 222 | } |
| 232 | 223 | |
| 233 | | static void smpc_system_reset(running_machine &machine) |
| 224 | void saturn_state::smpc_system_reset() |
| 234 | 225 | { |
| 235 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 236 | | |
| 237 | 226 | /*Only backup ram and SMPC ram are retained after that this command is issued.*/ |
| 238 | | memset(state->m_scu_regs ,0x00,0x000100); |
| 239 | | memset(state->m_scsp_regs,0x00,0x001000); |
| 240 | | memset(state->m_sound_ram,0x00,0x080000); |
| 241 | | memset(state->m_workram_h,0x00,0x100000); |
| 242 | | memset(state->m_workram_l,0x00,0x100000); |
| 243 | | memset(state->m_vdp2_regs,0x00,0x040000); |
| 244 | | memset(state->m_vdp2_vram,0x00,0x100000); |
| 245 | | memset(state->m_vdp2_cram,0x00,0x080000); |
| 246 | | memset(state->m_vdp1_vram,0x00,0x100000); |
| 227 | memset(m_scu_regs ,0x00,0x000100); |
| 228 | memset(m_scsp_regs,0x00,0x001000); |
| 229 | memset(m_sound_ram,0x00,0x080000); |
| 230 | memset(m_workram_h,0x00,0x100000); |
| 231 | memset(m_workram_l,0x00,0x100000); |
| 232 | memset(m_vdp2_regs,0x00,0x040000); |
| 233 | memset(m_vdp2_vram,0x00,0x100000); |
| 234 | memset(m_vdp2_cram,0x00,0x080000); |
| 235 | memset(m_vdp1_vram,0x00,0x100000); |
| 247 | 236 | //A-Bus |
| 248 | 237 | |
| 249 | | state->m_maincpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE); |
| 238 | m_maincpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE); |
| 250 | 239 | } |
| 251 | 240 | |
| 252 | | static TIMER_CALLBACK( smpc_change_clock ) |
| 241 | TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock ) |
| 253 | 242 | { |
| 254 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 255 | 243 | UINT32 xtal; |
| 256 | 244 | |
| 257 | | if(LOG_SMPC) printf ("Clock change execute at (%d %d)\n",machine.first_screen()->hpos(),machine.first_screen()->vpos()); |
| 245 | if(LOG_SMPC) printf ("Clock change execute at (%d %d)\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); |
| 258 | 246 | |
| 259 | 247 | xtal = param ? MASTER_CLOCK_320 : MASTER_CLOCK_352; |
| 260 | 248 | |
| 261 | | machine.device("maincpu")->set_unscaled_clock(xtal/2); |
| 262 | | machine.device("slave")->set_unscaled_clock(xtal/2); |
| 249 | machine().device("maincpu")->set_unscaled_clock(xtal/2); |
| 250 | machine().device("slave")->set_unscaled_clock(xtal/2); |
| 263 | 251 | |
| 264 | | state->m_vdp2.dotsel = param ^ 1; |
| 265 | | state->stv_vdp2_dynamic_res_change(); |
| 252 | m_vdp2.dotsel = param ^ 1; |
| 253 | stv_vdp2_dynamic_res_change(); |
| 266 | 254 | |
| 267 | | state->m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 268 | | if(!state->m_NMI_reset) |
| 269 | | state->m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 270 | | state->m_slave->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 271 | | state->m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 272 | | state->m_audiocpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 255 | m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 256 | if(!m_NMI_reset) |
| 257 | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 258 | m_slave->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 259 | m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 260 | m_audiocpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 273 | 261 | |
| 274 | 262 | /* put issued command in OREG31 */ |
| 275 | | state->m_smpc.OREG[31] = 0x0e + param; |
| 263 | m_smpc.OREG[31] = 0x0e + param; |
| 276 | 264 | /* clear hand-shake flag */ |
| 277 | | state->m_smpc.SF = 0x00; |
| 265 | m_smpc.SF = 0x00; |
| 278 | 266 | |
| 279 | 267 | /* TODO: VDP1 / VDP2 / SCU / SCSP default power ON values? */ |
| 280 | 268 | } |
| 281 | 269 | |
| 282 | | static TIMER_CALLBACK( stv_intback_peripheral ) |
| 270 | TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral ) |
| 283 | 271 | { |
| 284 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 285 | | |
| 286 | | if (state->m_smpc.intback_stage == 2) |
| 272 | if (m_smpc.intback_stage == 2) |
| 287 | 273 | { |
| 288 | | state->m_smpc.SR = (0x80 | state->m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback |
| 289 | | state->m_smpc.intback_stage = 0; |
| 274 | m_smpc.SR = (0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback |
| 275 | m_smpc.intback_stage = 0; |
| 290 | 276 | } |
| 291 | 277 | else |
| 292 | 278 | { |
| 293 | | state->m_smpc.SR = (0xc0 | state->m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback |
| 294 | | state->m_smpc.intback_stage ++; |
| 279 | m_smpc.SR = (0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback |
| 280 | m_smpc.intback_stage ++; |
| 295 | 281 | } |
| 296 | 282 | |
| 297 | | if(!(state->m_scu.ism & IRQ_SMPC)) |
| 298 | | state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 283 | if(!(m_scu.ism & IRQ_SMPC)) |
| 284 | m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 299 | 285 | else |
| 300 | | state->m_scu.ist |= (IRQ_SMPC); |
| 286 | m_scu.ist |= (IRQ_SMPC); |
| 301 | 287 | |
| 302 | | state->m_smpc.OREG[31] = 0x10; /* callback for last command issued */ |
| 303 | | state->m_smpc.SF = 0x00; /* clear hand-shake flag */ |
| 288 | m_smpc.OREG[31] = 0x10; /* callback for last command issued */ |
| 289 | m_smpc.SF = 0x00; /* clear hand-shake flag */ |
| 304 | 290 | } |
| 305 | 291 | |
| 306 | 292 | |
| 307 | | static TIMER_CALLBACK( stv_smpc_intback ) |
| 293 | TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback ) |
| 308 | 294 | { |
| 309 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 310 | 295 | int i; |
| 311 | 296 | |
| 312 | | // printf("%02x %02x %02x\n",state->m_smpc.intback_buf[0],state->m_smpc.intback_buf[1],state->m_smpc.intback_buf[2]); |
| 297 | // printf("%02x %02x %02x\n",m_smpc.intback_buf[0],m_smpc.intback_buf[1],m_smpc.intback_buf[2]); |
| 313 | 298 | |
| 314 | | if(state->m_smpc.intback_buf[0] != 0) |
| 299 | if(m_smpc.intback_buf[0] != 0) |
| 315 | 300 | { |
| 316 | | state->m_smpc.OREG[0] = (0x80) | ((state->m_NMI_reset & 1) << 6); |
| 301 | m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6); |
| 317 | 302 | |
| 318 | 303 | for(i=0;i<7;i++) |
| 319 | | state->m_smpc.OREG[1+i] = state->m_smpc.rtc_data[i]; |
| 304 | m_smpc.OREG[1+i] = m_smpc.rtc_data[i]; |
| 320 | 305 | |
| 321 | | state->m_smpc.OREG[8]=0x00; // CTG0 / CTG1? |
| 306 | m_smpc.OREG[8]=0x00; // CTG0 / CTG1? |
| 322 | 307 | |
| 323 | | state->m_smpc.OREG[9]=0x00; // TODO: system region on Saturn |
| 308 | m_smpc.OREG[9]=0x00; // TODO: system region on Saturn |
| 324 | 309 | |
| 325 | | state->m_smpc.OREG[10]= 0 << 7 | |
| 326 | | state->m_vdp2.dotsel << 6 | |
| 310 | m_smpc.OREG[10]= 0 << 7 | |
| 311 | m_vdp2.dotsel << 6 | |
| 327 | 312 | 1 << 5 | |
| 328 | 313 | 1 << 4 | |
| 329 | 314 | 0 << 3 | //MSHNMI |
| 330 | 315 | 1 << 2 | |
| 331 | 316 | 0 << 1 | //SYSRES |
| 332 | 317 | 0 << 0; //SOUNDRES |
| 333 | | state->m_smpc.OREG[11]= 0 << 6; //CDRES |
| 318 | m_smpc.OREG[11]= 0 << 6; //CDRES |
| 334 | 319 | |
| 335 | 320 | for(i=0;i<4;i++) |
| 336 | | state->m_smpc.OREG[12+i]=state->m_smpc.SMEM[i]; |
| 321 | m_smpc.OREG[12+i]=m_smpc.SMEM[i]; |
| 337 | 322 | |
| 338 | 323 | for(i=0;i<15;i++) |
| 339 | | state->m_smpc.OREG[16+i]=0xff; // undefined |
| 324 | m_smpc.OREG[16+i]=0xff; // undefined |
| 340 | 325 | |
| 341 | | state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 342 | | state->m_smpc.SR = 0x40 | state->m_smpc.intback_stage << 5; |
| 343 | | state->m_smpc.pmode = state->m_smpc.intback_buf[0]>>4; |
| 326 | m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 327 | m_smpc.SR = 0x40 | m_smpc.intback_stage << 5; |
| 328 | m_smpc.pmode = m_smpc.intback_buf[0]>>4; |
| 344 | 329 | |
| 345 | 330 | // /*This is for RTC,cartridge code and similar stuff...*/ |
| 346 | 331 | //if(LOG_SMPC) printf ("Interrupt: System Manager (SMPC) at scanline %04x, Vector 0x47 Level 0x08\n",scanline); |
| 347 | | if(!(state->m_scu.ism & IRQ_SMPC)) |
| 348 | | state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 332 | if(!(m_scu.ism & IRQ_SMPC)) |
| 333 | m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 349 | 334 | else |
| 350 | | state->m_scu.ist |= (IRQ_SMPC); |
| 335 | m_scu.ist |= (IRQ_SMPC); |
| 351 | 336 | |
| 352 | 337 | /* put issued command in OREG31 */ |
| 353 | | state->m_smpc.OREG[31] = 0x10; // TODO: doc says 0? |
| 338 | m_smpc.OREG[31] = 0x10; // TODO: doc says 0? |
| 354 | 339 | /* clear hand-shake flag */ |
| 355 | | state->m_smpc.SF = 0x00; |
| 340 | m_smpc.SF = 0x00; |
| 356 | 341 | } |
| 357 | | else if(state->m_smpc.intback_buf[1] & 8) |
| 342 | else if(m_smpc.intback_buf[1] & 8) |
| 358 | 343 | { |
| 359 | | state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 360 | | state->m_smpc.SR = 0x40; |
| 361 | | state->m_smpc.OREG[31] = 0x10; |
| 362 | | machine.scheduler().timer_set(attotime::from_usec(0), FUNC(stv_intback_peripheral),0); |
| 344 | m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 345 | m_smpc.SR = 0x40; |
| 346 | m_smpc.OREG[31] = 0x10; |
| 347 | machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0); |
| 363 | 348 | } |
| 364 | 349 | else |
| 365 | 350 | { |
| 366 | 351 | /* Shienryu calls this, it would be plainly illegal on Saturn, I'll just return the command and clear the hs flag for now. */ |
| 367 | | state->m_smpc.OREG[31] = 0x10; |
| 368 | | state->m_smpc.SF = 0x00; |
| 352 | m_smpc.OREG[31] = 0x10; |
| 353 | m_smpc.SF = 0x00; |
| 369 | 354 | } |
| 370 | 355 | } |
| 371 | 356 | |
| r29304 | r29305 | |
| 383 | 368 | 0x34 keyboard |
| 384 | 369 | */ |
| 385 | 370 | |
| 386 | | static void smpc_digital_pad(running_machine &machine, UINT8 pad_num, UINT8 offset) |
| 371 | void saturn_state::smpc_digital_pad(UINT8 pad_num, UINT8 offset) |
| 387 | 372 | { |
| 388 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 389 | 373 | static const char *const padnames[] = { "JOY1", "JOY2" }; |
| 390 | 374 | UINT16 pad_data; |
| 391 | 375 | |
| 392 | | pad_data = machine.root_device().ioport(padnames[pad_num])->read(); |
| 393 | | state->m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 394 | | state->m_smpc.OREG[1+pad_num*offset] = 0x02; |
| 395 | | state->m_smpc.OREG[2+pad_num*offset] = pad_data>>8; |
| 396 | | state->m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff; |
| 376 | pad_data = ioport(padnames[pad_num])->read(); |
| 377 | m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 378 | m_smpc.OREG[1+pad_num*offset] = 0x02; |
| 379 | m_smpc.OREG[2+pad_num*offset] = pad_data>>8; |
| 380 | m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff; |
| 397 | 381 | } |
| 398 | 382 | |
| 399 | | static void smpc_analog_pad(running_machine &machine, UINT8 pad_num, UINT8 offset, UINT8 id) |
| 383 | void saturn_state::smpc_analog_pad( UINT8 pad_num, UINT8 offset, UINT8 id) |
| 400 | 384 | { |
| 401 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 402 | 385 | static const char *const padnames[] = { "AN_JOY1", "AN_JOY2" }; |
| 403 | 386 | static const char *const annames[2][3] = { { "AN_X1", "AN_Y1", "AN_Z1" }, |
| 404 | 387 | { "AN_X2", "AN_Y2", "AN_Z2" }}; |
| 405 | 388 | UINT16 pad_data; |
| 406 | 389 | |
| 407 | | pad_data = machine.root_device().ioport(padnames[pad_num])->read(); |
| 408 | | state->m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 409 | | state->m_smpc.OREG[1+pad_num*offset] = id; |
| 410 | | state->m_smpc.OREG[2+pad_num*offset] = pad_data>>8; |
| 411 | | state->m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff; |
| 412 | | state->m_smpc.OREG[4+pad_num*offset] = machine.root_device().ioport(annames[pad_num][0])->read(); |
| 390 | pad_data = ioport(padnames[pad_num])->read(); |
| 391 | m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 392 | m_smpc.OREG[1+pad_num*offset] = id; |
| 393 | m_smpc.OREG[2+pad_num*offset] = pad_data>>8; |
| 394 | m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff; |
| 395 | m_smpc.OREG[4+pad_num*offset] = ioport(annames[pad_num][0])->read(); |
| 413 | 396 | if(id == 0x15) |
| 414 | 397 | { |
| 415 | | state->m_smpc.OREG[5+pad_num*offset] = machine.root_device().ioport(annames[pad_num][1])->read(); |
| 416 | | state->m_smpc.OREG[6+pad_num*offset] = machine.root_device().ioport(annames[pad_num][2])->read(); |
| 398 | m_smpc.OREG[5+pad_num*offset] = ioport(annames[pad_num][1])->read(); |
| 399 | m_smpc.OREG[6+pad_num*offset] = ioport(annames[pad_num][2])->read(); |
| 417 | 400 | } |
| 418 | 401 | } |
| 419 | 402 | |
| 420 | | static void smpc_keyboard(running_machine &machine, UINT8 pad_num, UINT8 offset) |
| 403 | void saturn_state::smpc_keyboard(UINT8 pad_num, UINT8 offset) |
| 421 | 404 | { |
| 422 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 423 | 405 | UINT16 game_key; |
| 424 | 406 | |
| 425 | 407 | game_key = 0xffff; |
| 426 | 408 | |
| 427 | | game_key ^= ((state->ioport("KEYS_1")->read() & 0x80) << 8); // right |
| 428 | | game_key ^= ((state->ioport("KEYS_1")->read() & 0x40) << 8); // left |
| 429 | | game_key ^= ((state->ioport("KEYS_1")->read() & 0x20) << 8); // down |
| 430 | | game_key ^= ((state->ioport("KEYS_1")->read() & 0x10) << 8); // up |
| 431 | | game_key ^= ((state->ioport("KEYF")->read() & 0x80) << 4); // ESC -> START |
| 432 | | game_key ^= ((state->ioport("KEY3")->read() & 0x04) << 8); // Z / A trigger |
| 433 | | game_key ^= ((state->ioport("KEY4")->read() & 0x02) << 8); // C / C trigger |
| 434 | | game_key ^= ((state->ioport("KEY6")->read() & 0x04) << 6); // X / B trigger |
| 435 | | game_key ^= ((state->ioport("KEY2")->read() & 0x20) << 2); // Q / R trigger |
| 436 | | game_key ^= ((state->ioport("KEY3")->read() & 0x10) << 2); // A / X trigger |
| 437 | | game_key ^= ((state->ioport("KEY3")->read() & 0x08) << 2); // S / Y trigger |
| 438 | | game_key ^= ((state->ioport("KEY4")->read() & 0x08) << 1); // D / Z trigger |
| 439 | | game_key ^= ((state->ioport("KEY4")->read() & 0x10) >> 1); // E / L trigger |
| 409 | game_key ^= ((ioport("KEYS_1")->read() & 0x80) << 8); // right |
| 410 | game_key ^= ((ioport("KEYS_1")->read() & 0x40) << 8); // left |
| 411 | game_key ^= ((ioport("KEYS_1")->read() & 0x20) << 8); // down |
| 412 | game_key ^= ((ioport("KEYS_1")->read() & 0x10) << 8); // up |
| 413 | game_key ^= ((ioport("KEYF")->read() & 0x80) << 4); // ESC -> START |
| 414 | game_key ^= ((ioport("KEY3")->read() & 0x04) << 8); // Z / A trigger |
| 415 | game_key ^= ((ioport("KEY4")->read() & 0x02) << 8); // C / C trigger |
| 416 | game_key ^= ((ioport("KEY6")->read() & 0x04) << 6); // X / B trigger |
| 417 | game_key ^= ((ioport("KEY2")->read() & 0x20) << 2); // Q / R trigger |
| 418 | game_key ^= ((ioport("KEY3")->read() & 0x10) << 2); // A / X trigger |
| 419 | game_key ^= ((ioport("KEY3")->read() & 0x08) << 2); // S / Y trigger |
| 420 | game_key ^= ((ioport("KEY4")->read() & 0x08) << 1); // D / Z trigger |
| 421 | game_key ^= ((ioport("KEY4")->read() & 0x10) >> 1); // E / L trigger |
| 440 | 422 | |
| 441 | | state->m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 442 | | state->m_smpc.OREG[1+pad_num*offset] = 0x34; |
| 443 | | state->m_smpc.OREG[2+pad_num*offset] = game_key>>8; // game buttons, TODO |
| 444 | | state->m_smpc.OREG[3+pad_num*offset] = game_key & 0xff; |
| 423 | m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 424 | m_smpc.OREG[1+pad_num*offset] = 0x34; |
| 425 | m_smpc.OREG[2+pad_num*offset] = game_key>>8; // game buttons, TODO |
| 426 | m_smpc.OREG[3+pad_num*offset] = game_key & 0xff; |
| 445 | 427 | /* |
| 446 | 428 | x--- ---- 0 |
| 447 | 429 | -x-- ---- caps lock |
| r29304 | r29305 | |
| 452 | 434 | ---- --x- 1 |
| 453 | 435 | ---- ---x Break key |
| 454 | 436 | */ |
| 455 | | state->m_smpc.OREG[4+pad_num*offset] = state->m_keyb.status | 6; |
| 456 | | state->m_smpc.OREG[5+pad_num*offset] = state->m_keyb.data; |
| 437 | m_smpc.OREG[4+pad_num*offset] = m_keyb.status | 6; |
| 438 | m_smpc.OREG[5+pad_num*offset] = m_keyb.data; |
| 457 | 439 | } |
| 458 | 440 | |
| 459 | | static void smpc_mouse(running_machine &machine, UINT8 pad_num, UINT8 offset, UINT8 id) |
| 441 | void saturn_state::smpc_mouse(UINT8 pad_num, UINT8 offset, UINT8 id) |
| 460 | 442 | { |
| 461 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 462 | 443 | static const char *const mousenames[2][3] = { { "MOUSEB1", "MOUSEX1", "MOUSEY1" }, |
| 463 | 444 | { "MOUSEB2", "MOUSEX2", "MOUSEY2" }}; |
| 464 | 445 | UINT8 mouse_ctrl; |
| 465 | 446 | INT16 mouse_x, mouse_y; |
| 466 | 447 | |
| 467 | | mouse_ctrl = machine.root_device().ioport(mousenames[pad_num][0])->read(); |
| 468 | | mouse_x = machine.root_device().ioport(mousenames[pad_num][1])->read(); |
| 469 | | mouse_y = machine.root_device().ioport(mousenames[pad_num][2])->read(); |
| 448 | mouse_ctrl = ioport(mousenames[pad_num][0])->read(); |
| 449 | mouse_x = ioport(mousenames[pad_num][1])->read(); |
| 450 | mouse_y = ioport(mousenames[pad_num][2])->read(); |
| 470 | 451 | |
| 471 | 452 | if(mouse_x < 0) |
| 472 | 453 | mouse_ctrl |= 0x10; |
| r29304 | r29305 | |
| 480 | 461 | if((mouse_y & 0xff00) != 0xff00 && (mouse_y & 0xff00) != 0x0000) |
| 481 | 462 | mouse_ctrl |= 0x80; |
| 482 | 463 | |
| 483 | | state->m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 484 | | state->m_smpc.OREG[1+pad_num*offset] = id; // 0x23 / 0xe3 |
| 485 | | state->m_smpc.OREG[2+pad_num*offset] = mouse_ctrl; |
| 486 | | state->m_smpc.OREG[3+pad_num*offset] = mouse_x & 0xff; |
| 487 | | state->m_smpc.OREG[4+pad_num*offset] = mouse_y & 0xff; |
| 464 | m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 465 | m_smpc.OREG[1+pad_num*offset] = id; // 0x23 / 0xe3 |
| 466 | m_smpc.OREG[2+pad_num*offset] = mouse_ctrl; |
| 467 | m_smpc.OREG[3+pad_num*offset] = mouse_x & 0xff; |
| 468 | m_smpc.OREG[4+pad_num*offset] = mouse_y & 0xff; |
| 488 | 469 | } |
| 489 | 470 | |
| 490 | 471 | /* TODO: is there ANY game on which the MD pad works? */ |
| 491 | | static void smpc_md_pad(running_machine &machine, UINT8 pad_num, UINT8 offset, UINT8 id) |
| 472 | void saturn_state::smpc_md_pad(UINT8 pad_num, UINT8 offset, UINT8 id) |
| 492 | 473 | { |
| 493 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 494 | 474 | static const char *const padnames[] = { "MD_JOY1", "MD_JOY2" }; |
| 495 | 475 | UINT16 pad_data; |
| 496 | 476 | |
| 497 | | pad_data = machine.root_device().ioport(padnames[pad_num])->read(); |
| 498 | | state->m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 499 | | state->m_smpc.OREG[1+pad_num*offset] = id; |
| 500 | | state->m_smpc.OREG[2+pad_num*offset] = pad_data>>8; |
| 477 | pad_data = ioport(padnames[pad_num])->read(); |
| 478 | m_smpc.OREG[0+pad_num*offset] = 0xf1; |
| 479 | m_smpc.OREG[1+pad_num*offset] = id; |
| 480 | m_smpc.OREG[2+pad_num*offset] = pad_data>>8; |
| 501 | 481 | if(id == 0xe2) // MD 6 Button PAD |
| 502 | | state->m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff; |
| 482 | m_smpc.OREG[3+pad_num*offset] = pad_data & 0xff; |
| 503 | 483 | } |
| 504 | 484 | |
| 505 | | static void smpc_unconnected(running_machine &machine, UINT8 pad_num, UINT8 offset) |
| 485 | void saturn_state::smpc_unconnected(UINT8 pad_num, UINT8 offset) |
| 506 | 486 | { |
| 507 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 508 | | |
| 509 | | state->m_smpc.OREG[0+pad_num*offset] = 0xf0; |
| 487 | m_smpc.OREG[0+pad_num*offset] = 0xf0; |
| 510 | 488 | } |
| 511 | 489 | |
| 512 | | static TIMER_CALLBACK( intback_peripheral ) |
| 490 | TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral ) |
| 513 | 491 | { |
| 514 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 515 | 492 | int pad_num; |
| 516 | 493 | static const UINT8 peri_id[10] = { 0x02, 0x13, 0x15, 0x23, 0x23, 0x34, 0xe1, 0xe2, 0xe3, 0xff }; |
| 517 | 494 | UINT8 read_id[2]; |
| r29304 | r29305 | |
| 519 | 496 | |
| 520 | 497 | // if (LOG_SMPC) logerror("SMPC: providing PAD data for intback, pad %d\n", intback_stage-2); |
| 521 | 498 | |
| 522 | | read_id[0] = (machine.root_device().ioport("INPUT_TYPE")->read()) & 0x0f; |
| 523 | | read_id[1] = (machine.root_device().ioport("INPUT_TYPE")->read()) >> 4; |
| 499 | read_id[0] = (ioport("INPUT_TYPE")->read()) & 0x0f; |
| 500 | read_id[1] = (ioport("INPUT_TYPE")->read()) >> 4; |
| 524 | 501 | |
| 525 | 502 | /* doesn't work? */ |
| 526 | | //pad_num = state->m_smpc.intback_stage - 1; |
| 503 | //pad_num = m_smpc.intback_stage - 1; |
| 527 | 504 | |
| 528 | | if(LOG_PAD_CMD) printf("%d %d %d\n",state->m_smpc.intback_stage - 1,machine.first_screen()->vpos(),(int)machine.first_screen()->frame_number()); |
| 505 | if(LOG_PAD_CMD) printf("%d %d %d\n",m_smpc.intback_stage - 1,machine().first_screen()->vpos(),(int)machine().first_screen()->frame_number()); |
| 529 | 506 | |
| 530 | 507 | offset = 0; |
| 531 | 508 | |
| r29304 | r29305 | |
| 533 | 510 | { |
| 534 | 511 | switch(read_id[pad_num]) |
| 535 | 512 | { |
| 536 | | case 0: smpc_digital_pad(machine,pad_num,offset); break; |
| 537 | | case 1: smpc_analog_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Steering Wheel */ |
| 538 | | case 2: smpc_analog_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Analog Pad */ |
| 539 | | case 4: smpc_mouse(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Pointing Device */ |
| 540 | | case 5: smpc_keyboard(machine,pad_num,offset); break; |
| 541 | | case 6: smpc_md_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 3B PAD */ |
| 542 | | case 7: smpc_md_pad(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 6B PAD */ |
| 543 | | case 8: smpc_mouse(machine,pad_num,offset,peri_id[read_id[pad_num]]); break; /* Saturn Mouse */ |
| 544 | | case 9: smpc_unconnected(machine,pad_num,offset); break; |
| 513 | case 0: smpc_digital_pad(pad_num,offset); break; |
| 514 | case 1: smpc_analog_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Steering Wheel */ |
| 515 | case 2: smpc_analog_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Analog Pad */ |
| 516 | case 4: smpc_mouse(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Pointing Device */ |
| 517 | case 5: smpc_keyboard(pad_num,offset); break; |
| 518 | case 6: smpc_md_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 3B PAD */ |
| 519 | case 7: smpc_md_pad(pad_num,offset,peri_id[read_id[pad_num]]); break; /* MD 6B PAD */ |
| 520 | case 8: smpc_mouse(pad_num,offset,peri_id[read_id[pad_num]]); break; /* Saturn Mouse */ |
| 521 | case 9: smpc_unconnected(pad_num,offset); break; |
| 545 | 522 | } |
| 546 | 523 | |
| 547 | 524 | offset += (peri_id[read_id[pad_num]] & 0xf) + 2; /* offset for port 2 */ |
| 548 | 525 | } |
| 549 | 526 | |
| 550 | | if (state->m_smpc.intback_stage == 2) |
| 527 | if (m_smpc.intback_stage == 2) |
| 551 | 528 | { |
| 552 | | state->m_smpc.SR = (0x80 | state->m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback |
| 553 | | state->m_smpc.intback_stage = 0; |
| 529 | m_smpc.SR = (0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback |
| 530 | m_smpc.intback_stage = 0; |
| 554 | 531 | } |
| 555 | 532 | else |
| 556 | 533 | { |
| 557 | | state->m_smpc.SR = (0xc0 | state->m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback |
| 558 | | state->m_smpc.intback_stage ++; |
| 534 | m_smpc.SR = (0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback |
| 535 | m_smpc.intback_stage ++; |
| 559 | 536 | } |
| 560 | 537 | |
| 561 | | if(!(state->m_scu.ism & IRQ_SMPC)) |
| 562 | | state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 538 | if(!(m_scu.ism & IRQ_SMPC)) |
| 539 | m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 563 | 540 | else |
| 564 | | state->m_scu.ist |= (IRQ_SMPC); |
| 541 | m_scu.ist |= (IRQ_SMPC); |
| 565 | 542 | |
| 566 | | state->m_smpc.OREG[31] = 0x10; /* callback for last command issued */ |
| 567 | | state->m_smpc.SF = 0x00; /* clear hand-shake flag */ |
| 543 | m_smpc.OREG[31] = 0x10; /* callback for last command issued */ |
| 544 | m_smpc.SF = 0x00; /* clear hand-shake flag */ |
| 568 | 545 | } |
| 569 | 546 | |
| 570 | | static TIMER_CALLBACK( saturn_smpc_intback ) |
| 547 | TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback ) |
| 571 | 548 | { |
| 572 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 573 | | |
| 574 | | if(state->m_smpc.intback_buf[0] != 0) |
| 549 | if(m_smpc.intback_buf[0] != 0) |
| 575 | 550 | { |
| 576 | 551 | { |
| 577 | 552 | int i; |
| 578 | 553 | |
| 579 | | state->m_smpc.OREG[0] = (0x80) | ((state->m_NMI_reset & 1) << 6); // bit 7: SETTIME (RTC isn't setted up properly) |
| 554 | m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6); // bit 7: SETTIME (RTC isn't setted up properly) |
| 580 | 555 | |
| 581 | 556 | for(i=0;i<7;i++) |
| 582 | | state->m_smpc.OREG[1+i] = state->m_smpc.rtc_data[i]; |
| 557 | m_smpc.OREG[1+i] = m_smpc.rtc_data[i]; |
| 583 | 558 | |
| 584 | | state->m_smpc.OREG[8]=0x00; //Cartridge code? |
| 559 | m_smpc.OREG[8]=0x00; //Cartridge code? |
| 585 | 560 | |
| 586 | | state->m_smpc.OREG[9] = state->m_saturn_region; |
| 561 | m_smpc.OREG[9] = m_saturn_region; |
| 587 | 562 | |
| 588 | | state->m_smpc.OREG[10]= 0 << 7 | |
| 589 | | state->m_vdp2.dotsel << 6 | |
| 563 | m_smpc.OREG[10]= 0 << 7 | |
| 564 | m_vdp2.dotsel << 6 | |
| 590 | 565 | 1 << 5 | |
| 591 | 566 | 1 << 4 | |
| 592 | 567 | 0 << 3 | //MSHNMI |
| 593 | 568 | 1 << 2 | |
| 594 | 569 | 0 << 1 | //SYSRES |
| 595 | 570 | 0 << 0; //SOUNDRES |
| 596 | | state->m_smpc.OREG[11]= 0 << 6; //CDRES |
| 571 | m_smpc.OREG[11]= 0 << 6; //CDRES |
| 597 | 572 | |
| 598 | 573 | for(i=0;i<4;i++) |
| 599 | | state->m_smpc.OREG[12+i]=state->m_smpc.SMEM[i]; |
| 574 | m_smpc.OREG[12+i]=m_smpc.SMEM[i]; |
| 600 | 575 | |
| 601 | 576 | for(i=0;i<15;i++) |
| 602 | | state->m_smpc.OREG[16+i]=0xff; // undefined |
| 577 | m_smpc.OREG[16+i]=0xff; // undefined |
| 603 | 578 | } |
| 604 | 579 | |
| 605 | | state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 606 | | state->m_smpc.SR = 0x40 | state->m_smpc.intback_stage << 5; |
| 607 | | state->m_smpc.pmode = state->m_smpc.intback_buf[0]>>4; |
| 580 | m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 581 | m_smpc.SR = 0x40 | m_smpc.intback_stage << 5; |
| 582 | m_smpc.pmode = m_smpc.intback_buf[0]>>4; |
| 608 | 583 | |
| 609 | | if(!(state->m_scu.ism & IRQ_SMPC)) |
| 610 | | state->m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 584 | if(!(m_scu.ism & IRQ_SMPC)) |
| 585 | m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47); |
| 611 | 586 | else |
| 612 | | state->m_scu.ist |= (IRQ_SMPC); |
| 587 | m_scu.ist |= (IRQ_SMPC); |
| 613 | 588 | |
| 614 | 589 | /* put issued command in OREG31 */ |
| 615 | | state->m_smpc.OREG[31] = 0x10; |
| 590 | m_smpc.OREG[31] = 0x10; |
| 616 | 591 | /* clear hand-shake flag */ |
| 617 | | state->m_smpc.SF = 0x00; |
| 592 | m_smpc.SF = 0x00; |
| 618 | 593 | } |
| 619 | | else if(state->m_smpc.intback_buf[1] & 8) |
| 594 | else if(m_smpc.intback_buf[1] & 8) |
| 620 | 595 | { |
| 621 | | state->m_smpc.intback_stage = (state->m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 622 | | state->m_smpc.SR = 0x40; |
| 623 | | state->m_smpc.OREG[31] = 0x10; |
| 624 | | machine.scheduler().timer_set(attotime::from_usec(0), FUNC(intback_peripheral),0); |
| 596 | m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral |
| 597 | m_smpc.SR = 0x40; |
| 598 | m_smpc.OREG[31] = 0x10; |
| 599 | machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0); |
| 625 | 600 | } |
| 626 | 601 | else |
| 627 | 602 | { |
| 628 | | printf("SMPC intback bogus behaviour called %02x %02x\n",state->m_smpc.IREG[0],state->m_smpc.IREG[1]); |
| 603 | printf("SMPC intback bogus behaviour called %02x %02x\n",m_smpc.IREG[0],m_smpc.IREG[1]); |
| 629 | 604 | } |
| 630 | 605 | |
| 631 | 606 | } |
| 632 | 607 | |
| 633 | | static void smpc_rtc_write(running_machine &machine) |
| 608 | void saturn_state::smpc_rtc_write() |
| 634 | 609 | { |
| 635 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 636 | 610 | int i; |
| 637 | 611 | |
| 638 | 612 | for(i=0;i<7;i++) |
| 639 | | state->m_smpc.rtc_data[i] = state->m_smpc.IREG[i]; |
| 613 | m_smpc.rtc_data[i] = m_smpc.IREG[i]; |
| 640 | 614 | } |
| 641 | 615 | |
| 642 | | static void smpc_memory_setting(running_machine &machine) |
| 616 | void saturn_state::smpc_memory_setting() |
| 643 | 617 | { |
| 644 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 645 | 618 | int i; |
| 646 | 619 | |
| 647 | 620 | for(i=0;i<4;i++) |
| 648 | | state->m_smpc.SMEM[i] = state->m_smpc.IREG[i]; |
| 621 | m_smpc.SMEM[i] = m_smpc.IREG[i]; |
| 649 | 622 | } |
| 650 | 623 | |
| 651 | | static void smpc_nmi_req(running_machine &machine) |
| 624 | void saturn_state::smpc_nmi_req() |
| 652 | 625 | { |
| 653 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 654 | | |
| 655 | 626 | /*NMI is unconditionally requested */ |
| 656 | | state->m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 627 | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 657 | 628 | } |
| 658 | 629 | |
| 659 | | static TIMER_CALLBACK( smpc_nmi_set ) |
| 630 | TIMER_CALLBACK_MEMBER( saturn_state::smpc_nmi_set ) |
| 660 | 631 | { |
| 661 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 632 | // printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); |
| 662 | 633 | |
| 663 | | // printf("%d %d\n",machine.first_screen()->hpos(),machine.first_screen()->vpos()); |
| 664 | | state->m_NMI_reset = param; |
| 634 | m_NMI_reset = param; |
| 665 | 635 | /* put issued command in OREG31 */ |
| 666 | | state->m_smpc.OREG[31] = 0x19 + param; |
| 636 | m_smpc.OREG[31] = 0x19 + param; |
| 667 | 637 | /* clear hand-shake flag */ |
| 668 | | state->m_smpc.SF = 0x00; |
| 638 | m_smpc.SF = 0x00; |
| 669 | 639 | |
| 670 | | //state->m_smpc.OREG[0] = (0x80) | ((state->m_NMI_reset & 1) << 6); |
| 640 | //m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6); |
| 671 | 641 | } |
| 672 | 642 | |
| 673 | 643 | |
| r29304 | r29305 | |
| 682 | 652 | * |
| 683 | 653 | *******************************************/ |
| 684 | 654 | |
| 685 | | static void smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv) |
| 655 | void saturn_state::smpc_comreg_exec(address_space &space, UINT8 data, UINT8 is_stv) |
| 686 | 656 | { |
| 687 | | saturn_state *state = space.machine().driver_data<saturn_state>(); |
| 688 | | |
| 689 | 657 | switch (data) |
| 690 | 658 | { |
| 691 | 659 | case 0x00: |
| 692 | 660 | if(LOG_SMPC) printf ("SMPC: Master ON\n"); |
| 693 | | smpc_master_on(space.machine()); |
| 661 | smpc_master_on(); |
| 694 | 662 | break; |
| 695 | 663 | //case 0x01: Master OFF? |
| 696 | 664 | case 0x02: |
| 697 | 665 | case 0x03: |
| 698 | | if(LOG_SMPC) printf ("SMPC: Slave %s %d %d\n",(data & 1) ? "off" : "on",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos()); |
| 699 | | space.machine().scheduler().timer_set(attotime::from_usec(15), FUNC(smpc_slave_enable),data & 1); |
| 666 | if(LOG_SMPC) printf ("SMPC: Slave %s %d %d\n",(data & 1) ? "off" : "on",machine().first_screen()->hpos(),machine().first_screen()->vpos()); |
| 667 | machine().scheduler().timer_set(attotime::from_usec(15), timer_expired_delegate(FUNC(saturn_state::smpc_slave_enable),this),data & 1); |
| 700 | 668 | break; |
| 701 | 669 | case 0x06: |
| 702 | 670 | case 0x07: |
| 703 | 671 | if(LOG_SMPC) printf ("SMPC: Sound %s\n",(data & 1) ? "off" : "on"); |
| 704 | 672 | |
| 705 | 673 | if(!is_stv) |
| 706 | | space.machine().scheduler().timer_set(attotime::from_usec(15), FUNC(smpc_sound_enable),data & 1); |
| 674 | machine().scheduler().timer_set(attotime::from_usec(15), timer_expired_delegate(FUNC(saturn_state::smpc_sound_enable),this),data & 1); |
| 707 | 675 | break; |
| 708 | 676 | /*CD (SH-1) ON/OFF */ |
| 709 | 677 | case 0x08: |
| 710 | 678 | case 0x09: |
| 711 | 679 | printf ("SMPC: CD %s\n",(data & 1) ? "off" : "on"); |
| 712 | | space.machine().scheduler().timer_set(attotime::from_usec(20), FUNC(smpc_cd_enable),data & 1); |
| 680 | machine().scheduler().timer_set(attotime::from_usec(20), timer_expired_delegate(FUNC(saturn_state::smpc_cd_enable),this),data & 1); |
| 713 | 681 | break; |
| 714 | 682 | case 0x0d: |
| 715 | 683 | if(LOG_SMPC) printf ("SMPC: System Reset\n"); |
| 716 | | smpc_system_reset(space.machine()); |
| 684 | smpc_system_reset(); |
| 717 | 685 | break; |
| 718 | 686 | case 0x0e: |
| 719 | 687 | case 0x0f: |
| 720 | | if(LOG_SMPC) printf ("SMPC: Change Clock to %s (%d %d)\n",data & 1 ? "320" : "352",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos()); |
| 688 | if(LOG_SMPC) printf ("SMPC: Change Clock to %s (%d %d)\n",data & 1 ? "320" : "352",machine().first_screen()->hpos(),machine().first_screen()->vpos()); |
| 721 | 689 | |
| 722 | 690 | /* on ST-V timing of this is pretty fussy, you get 2 credits at start-up otherwise |
| 723 | 691 | My current theory is that SMPC first stops all CPUs until it executes the whole snippet for this, |
| r29304 | r29305 | |
| 725 | 693 | can do an usable mid-frame clock switching anyway. |
| 726 | 694 | */ |
| 727 | 695 | |
| 728 | | state->m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 729 | | state->m_slave->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 730 | | state->m_audiocpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 696 | m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 697 | m_slave->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 698 | m_audiocpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 731 | 699 | |
| 732 | | space.machine().scheduler().timer_set(space.machine().first_screen()->time_until_pos(state->get_vblank_start_position()*state->get_ystep_count(), 0), FUNC(smpc_change_clock),data & 1); |
| 700 | machine().scheduler().timer_set(machine().first_screen()->time_until_pos(get_vblank_start_position()*get_ystep_count(), 0), timer_expired_delegate(FUNC(saturn_state::smpc_change_clock),this),data & 1); |
| 733 | 701 | break; |
| 734 | 702 | /*"Interrupt Back"*/ |
| 735 | 703 | case 0x10: |
| 736 | 704 | if(0) |
| 737 | 705 | { |
| 738 | | saturn_state *state = space.machine().driver_data<saturn_state>(); |
| 739 | | printf ("SMPC: Status Acquire %02x %02x %02x %d\n",state->m_smpc.IREG[0],state->m_smpc.IREG[1],state->m_smpc.IREG[2],space.machine().first_screen()->vpos()); |
| 706 | printf ("SMPC: Status Acquire %02x %02x %02x %d\n",m_smpc.IREG[0],m_smpc.IREG[1],m_smpc.IREG[2],machine().first_screen()->vpos()); |
| 740 | 707 | } |
| 741 | 708 | |
| 742 | 709 | int timing; |
| 743 | 710 | |
| 744 | 711 | timing = 8; |
| 745 | 712 | |
| 746 | | if(state->m_smpc.IREG[0] != 0) // non-peripheral data |
| 713 | if(m_smpc.IREG[0] != 0) // non-peripheral data |
| 747 | 714 | timing += 8; |
| 748 | 715 | |
| 749 | 716 | /* TODO: At vblank-out actually ... */ |
| 750 | | if(state->m_smpc.IREG[1] & 8) // peripheral data |
| 717 | if(m_smpc.IREG[1] & 8) // peripheral data |
| 751 | 718 | timing += 700; |
| 752 | 719 | |
| 753 | 720 | /* TODO: check if IREG[2] is setted to 0xf0 */ |
| r29304 | r29305 | |
| 755 | 722 | int i; |
| 756 | 723 | |
| 757 | 724 | for(i=0;i<3;i++) |
| 758 | | state->m_smpc.intback_buf[i] = state->m_smpc.IREG[i]; |
| 725 | m_smpc.intback_buf[i] = m_smpc.IREG[i]; |
| 759 | 726 | } |
| 760 | 727 | |
| 761 | 728 | if(is_stv) |
| 762 | 729 | { |
| 763 | | space.machine().scheduler().timer_set(attotime::from_usec(timing), FUNC(stv_smpc_intback),0); //TODO: variable time |
| 730 | machine().scheduler().timer_set(attotime::from_usec(timing), timer_expired_delegate(FUNC(saturn_state::stv_smpc_intback),this),0); //TODO: variable time |
| 764 | 731 | } |
| 765 | 732 | else |
| 766 | 733 | { |
| 767 | | if(LOG_PAD_CMD) printf("INTBACK %02x %02x %d %d\n",state->m_smpc.IREG[0],state->m_smpc.IREG[1],space.machine().first_screen()->vpos(),(int)space.machine().first_screen()->frame_number()); |
| 768 | | space.machine().scheduler().timer_set(attotime::from_usec(timing), FUNC(saturn_smpc_intback),0); //TODO: is variable time correct? |
| 734 | if(LOG_PAD_CMD) printf("INTBACK %02x %02x %d %d\n",m_smpc.IREG[0],m_smpc.IREG[1],machine().first_screen()->vpos(),(int)machine().first_screen()->frame_number()); |
| 735 | machine().scheduler().timer_set(attotime::from_usec(timing), timer_expired_delegate(FUNC(saturn_state::saturn_smpc_intback),this),0); //TODO: is variable time correct? |
| 769 | 736 | } |
| 770 | 737 | break; |
| 771 | 738 | /* RTC write*/ |
| 772 | 739 | case 0x16: |
| 773 | 740 | if(LOG_SMPC) printf("SMPC: RTC write\n"); |
| 774 | | smpc_rtc_write(space.machine()); |
| 741 | smpc_rtc_write(); |
| 775 | 742 | break; |
| 776 | 743 | /* SMPC memory setting*/ |
| 777 | 744 | case 0x17: |
| 778 | 745 | if(LOG_SMPC) printf ("SMPC: memory setting\n"); |
| 779 | | smpc_memory_setting(space.machine()); |
| 746 | smpc_memory_setting(); |
| 780 | 747 | break; |
| 781 | 748 | case 0x18: |
| 782 | 749 | if(LOG_SMPC) printf ("SMPC: NMI request\n"); |
| 783 | | smpc_nmi_req(space.machine()); |
| 750 | smpc_nmi_req(); |
| 784 | 751 | break; |
| 785 | 752 | case 0x19: |
| 786 | 753 | case 0x1a: |
| 787 | 754 | /* TODO: timing */ |
| 788 | | if(LOG_SMPC) printf ("SMPC: NMI %sable %d %d\n",data & 1 ? "Dis" : "En",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos()); |
| 789 | | space.machine().scheduler().timer_set(attotime::from_usec(100), FUNC(smpc_nmi_set),data & 1); |
| 755 | if(LOG_SMPC) printf ("SMPC: NMI %sable %d %d\n",data & 1 ? "Dis" : "En",machine().first_screen()->hpos(),machine().first_screen()->vpos()); |
| 756 | machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_nmi_set),this),data & 1); |
| 790 | 757 | break; |
| 791 | 758 | default: |
| 792 | 759 | printf ("cpu '%s' (PC=%08X) SMPC: undocumented Command %02x\n", space.device().tag(), space.device().safe_pc(), data); |
| r29304 | r29305 | |
| 799 | 766 | * |
| 800 | 767 | *******************************************/ |
| 801 | 768 | |
| 802 | | READ8_HANDLER( stv_SMPC_r ) |
| 769 | READ8_MEMBER( saturn_state::stv_SMPC_r ) |
| 803 | 770 | { |
| 804 | | saturn_state *state = space.machine().driver_data<saturn_state>(); |
| 805 | 771 | int return_data = 0; |
| 806 | 772 | |
| 807 | 773 | if(!(offset & 1)) |
| 808 | 774 | return 0; |
| 809 | 775 | |
| 810 | 776 | if(offset >= 0x21 && offset <= 0x5f) |
| 811 | | return_data = state->m_smpc.OREG[(offset-0x21) >> 1]; |
| 777 | return_data = m_smpc.OREG[(offset-0x21) >> 1]; |
| 812 | 778 | |
| 813 | 779 | if (offset == 0x61) // TODO: SR |
| 814 | | return_data = state->m_smpc.SR; |
| 780 | return_data = m_smpc.SR; |
| 815 | 781 | |
| 816 | 782 | if (offset == 0x63) |
| 817 | | return_data = state->m_smpc.SF; |
| 783 | return_data = m_smpc.SF; |
| 818 | 784 | |
| 819 | 785 | if (offset == 0x75)//PDR1 read |
| 820 | | return_data = state->ioport("DSW1")->read(); |
| 786 | return_data = ioport("DSW1")->read(); |
| 821 | 787 | |
| 822 | 788 | if (offset == 0x77)//PDR2 read |
| 823 | | return_data = (0xfe | state->m_eeprom->do_read()); |
| 789 | return_data = (0xfe | m_eeprom->do_read()); |
| 824 | 790 | |
| 825 | 791 | return return_data; |
| 826 | 792 | } |
| 827 | 793 | |
| 828 | | WRITE8_HANDLER( stv_SMPC_w ) |
| 794 | WRITE8_MEMBER( saturn_state::stv_SMPC_w ) |
| 829 | 795 | { |
| 830 | | saturn_state *state = space.machine().driver_data<saturn_state>(); |
| 831 | | |
| 832 | 796 | if (!(offset & 1)) // avoid writing to even bytes |
| 833 | 797 | return; |
| 834 | 798 | |
| 835 | 799 | // if(LOG_SMPC) printf ("8-bit SMPC Write to Offset %02x with Data %02x\n", offset, data); |
| 836 | 800 | |
| 837 | 801 | if(offset >= 1 && offset <= 0xd) |
| 838 | | state->m_smpc.IREG[offset >> 1] = data; |
| 802 | m_smpc.IREG[offset >> 1] = data; |
| 839 | 803 | |
| 840 | 804 | if(offset == 1) //IREG0, check if a BREAK / CONTINUE request for INTBACK command |
| 841 | 805 | { |
| 842 | | if(state->m_smpc.intback_stage) |
| 806 | if(m_smpc.intback_stage) |
| 843 | 807 | { |
| 844 | 808 | if(data & 0x40) |
| 845 | 809 | { |
| 846 | 810 | if(LOG_PAD_CMD) printf("SMPC: BREAK request\n"); |
| 847 | | state->m_smpc.SR &= 0x0f; |
| 848 | | state->m_smpc.intback_stage = 0; |
| 811 | m_smpc.SR &= 0x0f; |
| 812 | m_smpc.intback_stage = 0; |
| 849 | 813 | } |
| 850 | 814 | else if(data & 0x80) |
| 851 | 815 | { |
| 852 | 816 | if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n"); |
| 853 | | space.machine().scheduler().timer_set(attotime::from_usec(700), FUNC(stv_intback_peripheral),0); /* TODO: is timing correct? */ |
| 854 | | state->m_smpc.OREG[31] = 0x10; |
| 855 | | state->m_smpc.SF = 0x01; //TODO: set hand-shake flag? |
| 817 | machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0); /* TODO: is timing correct? */ |
| 818 | m_smpc.OREG[31] = 0x10; |
| 819 | m_smpc.SF = 0x01; //TODO: set hand-shake flag? |
| 856 | 820 | } |
| 857 | 821 | } |
| 858 | 822 | } |
| r29304 | r29305 | |
| 864 | 828 | // we've processed the command, clear status flag |
| 865 | 829 | if(data != 0x10 && data != 0x02 && data != 0x03 && data != 0x08 && data != 0x09 && data != 0xe && data != 0xf && data != 0x19 && data != 0x1a) |
| 866 | 830 | { |
| 867 | | state->m_smpc.OREG[31] = data; //read-back command |
| 868 | | state->m_smpc.SF = 0x00; |
| 831 | m_smpc.OREG[31] = data; //read-back command |
| 832 | m_smpc.SF = 0x00; |
| 869 | 833 | } |
| 870 | 834 | /*TODO:emulate the timing of each command...*/ |
| 871 | 835 | } |
| 872 | 836 | |
| 873 | 837 | if(offset == 0x63) |
| 874 | | state->m_smpc.SF = data & 1; |
| 838 | m_smpc.SF = data & 1; |
| 875 | 839 | |
| 876 | 840 | if(offset == 0x75) |
| 877 | 841 | { |
| r29304 | r29305 | |
| 882 | 846 | ---- -x-- EEPROM CS line |
| 883 | 847 | ---- --xx A-Bus bank bits |
| 884 | 848 | */ |
| 885 | | state->m_eeprom->clk_write((data & 0x08) ? ASSERT_LINE : CLEAR_LINE); |
| 886 | | state->m_eeprom->di_write((data >> 4) & 1); |
| 887 | | state->m_eeprom->cs_write((data & 0x04) ? ASSERT_LINE : CLEAR_LINE); |
| 888 | | state->m_stv_multi_bank = data & 3; |
| 849 | m_eeprom->clk_write((data & 0x08) ? ASSERT_LINE : CLEAR_LINE); |
| 850 | m_eeprom->di_write((data >> 4) & 1); |
| 851 | m_eeprom->cs_write((data & 0x04) ? ASSERT_LINE : CLEAR_LINE); |
| 852 | m_stv_multi_bank = data & 3; |
| 889 | 853 | |
| 890 | | stv_select_game(space.machine(), state->m_stv_multi_bank); |
| 854 | stv_select_game(m_stv_multi_bank); |
| 891 | 855 | |
| 892 | | state->m_smpc.PDR1 = (data & 0x60); |
| 856 | m_smpc.PDR1 = (data & 0x60); |
| 893 | 857 | } |
| 894 | 858 | |
| 895 | 859 | if(offset == 0x77) |
| r29304 | r29305 | |
| 898 | 862 | -xx- ---- PDR2 |
| 899 | 863 | ---x ---- Enable Sound System (ACTIVE LOW) |
| 900 | 864 | */ |
| 901 | | //popmessage("PDR2 = %02x",state->m_smpc_ram[0x77]); |
| 865 | //popmessage("PDR2 = %02x",m_smpc_ram[0x77]); |
| 902 | 866 | |
| 903 | 867 | if(LOG_SMPC) printf("SMPC: M68k %s\n",(data & 0x10) ? "off" : "on"); |
| 904 | | //space.machine().scheduler().timer_set(attotime::from_usec(100), FUNC(smpc_sound_enable),(state->m_smpc_ram[0x77] & 0x10) >> 4); |
| 905 | | state->m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? ASSERT_LINE : CLEAR_LINE); |
| 906 | | state->m_en_68k = ((data & 0x10) >> 4) ^ 1; |
| 868 | //machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_sound_enable),this),(m_smpc_ram[0x77] & 0x10) >> 4); |
| 869 | m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? ASSERT_LINE : CLEAR_LINE); |
| 870 | m_en_68k = ((data & 0x10) >> 4) ^ 1; |
| 907 | 871 | |
| 908 | 872 | //if(LOG_SMPC) printf("SMPC: ram [0x77] = %02x\n",data); |
| 909 | | state->m_smpc.PDR2 = (data & 0x60); |
| 873 | m_smpc.PDR2 = (data & 0x60); |
| 910 | 874 | } |
| 911 | 875 | |
| 912 | 876 | if(offset == 0x7d) |
| r29304 | r29305 | |
| 915 | 879 | ---- --x- IOSEL2 direct (1) / control mode (0) port select |
| 916 | 880 | ---- ---x IOSEL1 direct (1) / control mode (0) port select |
| 917 | 881 | */ |
| 918 | | state->m_smpc.IOSEL1 = (data & 1) >> 0; |
| 919 | | state->m_smpc.IOSEL2 = (data & 2) >> 1; |
| 882 | m_smpc.IOSEL1 = (data & 1) >> 0; |
| 883 | m_smpc.IOSEL2 = (data & 2) >> 1; |
| 920 | 884 | } |
| 921 | 885 | |
| 922 | 886 | if(offset == 0x7f) |
| 923 | 887 | { |
| 924 | 888 | //enable PAD irq & VDP2 external latch for port 1/2 |
| 925 | | state->m_smpc.EXLE1 = (data & 1) >> 0; |
| 926 | | state->m_smpc.EXLE2 = (data & 2) >> 1; |
| 889 | m_smpc.EXLE1 = (data & 1) >> 0; |
| 890 | m_smpc.EXLE2 = (data & 2) >> 1; |
| 927 | 891 | } |
| 928 | 892 | } |
| 929 | 893 | |
| r29304 | r29305 | |
| 1001 | 965 | |
| 1002 | 966 | if (offset == 0x63) |
| 1003 | 967 | { |
| 1004 | | //printf("SF %d %d\n",space.machine().first_screen()->hpos(),space.machine().first_screen()->vpos()); |
| 968 | //printf("SF %d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); |
| 1005 | 969 | return_data = m_smpc.SF; |
| 1006 | 970 | } |
| 1007 | 971 | |
| r29304 | r29305 | |
| 1060 | 1024 | else if(data & 0x80) |
| 1061 | 1025 | { |
| 1062 | 1026 | if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n"); |
| 1063 | | machine().scheduler().timer_set(attotime::from_usec(700), FUNC(intback_peripheral),0); /* TODO: is timing correct? */ |
| 1027 | machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0); /* TODO: is timing correct? */ |
| 1064 | 1028 | m_smpc.OREG[31] = 0x10; |
| 1065 | 1029 | m_smpc.SF = 0x01; //TODO: set hand-shake flag? |
| 1066 | 1030 | } |
shelves/new_menus/src/emu/cpu/g65816/g65816.c
| r29304 | r29305 | |
| 584 | 584 | 8 CPU cycles for division at first, since using 16 produces bugs (see e.g. |
| 585 | 585 | Triforce pieces in Zelda 3 intro) */ |
| 586 | 586 | |
| 587 | | static WRITE8_HANDLER( wrmpya_w ) |
| 587 | WRITE8_MEMBER( _5a22_device::wrmpya_w ) |
| 588 | 588 | { |
| 589 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 589 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 590 | 590 | |
| 591 | 591 | cpustate->wrmpya = data; |
| 592 | 592 | } |
| 593 | 593 | |
| 594 | | static WRITE8_HANDLER( wrmpyb_w ) |
| 594 | WRITE8_MEMBER( _5a22_device::wrmpyb_w ) |
| 595 | 595 | { |
| 596 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 596 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 597 | 597 | |
| 598 | 598 | cpustate->wrmpyb = data; |
| 599 | 599 | cpustate->rdmpy = cpustate->wrmpya * cpustate->wrmpyb; |
| 600 | 600 | /* TODO: cpustate->rddiv == 0? */ |
| 601 | 601 | } |
| 602 | 602 | |
| 603 | | static WRITE8_HANDLER( wrdivl_w ) |
| 603 | WRITE8_MEMBER( _5a22_device::wrdivl_w ) |
| 604 | 604 | { |
| 605 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 605 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 606 | 606 | |
| 607 | 607 | cpustate->wrdiv = (data) | (cpustate->wrdiv & 0xff00); |
| 608 | 608 | } |
| 609 | 609 | |
| 610 | | static WRITE8_HANDLER( wrdivh_w ) |
| 610 | WRITE8_MEMBER( _5a22_device::wrdivh_w ) |
| 611 | 611 | { |
| 612 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 612 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 613 | 613 | |
| 614 | 614 | cpustate->wrdiv = (data << 8) | (cpustate->wrdiv & 0xff); |
| 615 | 615 | } |
| 616 | 616 | |
| 617 | | static WRITE8_HANDLER( wrdvdd_w ) |
| 617 | WRITE8_MEMBER( _5a22_device::wrdvdd_w ) |
| 618 | 618 | { |
| 619 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 619 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 620 | 620 | UINT16 quotient, remainder; |
| 621 | 621 | |
| 622 | 622 | cpustate->dvdd = data; |
| r29304 | r29305 | |
| 628 | 628 | cpustate->rdmpy = remainder; |
| 629 | 629 | } |
| 630 | 630 | |
| 631 | | static WRITE8_HANDLER( memsel_w ) |
| 631 | WRITE8_MEMBER( _5a22_device::memsel_w ) |
| 632 | 632 | { |
| 633 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 633 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 634 | 634 | cpustate->fastROM = data & 1; |
| 635 | 635 | } |
| 636 | 636 | |
| 637 | | static READ8_HANDLER( rddivl_r ) |
| 637 | READ8_MEMBER( _5a22_device::rddivl_r ) |
| 638 | 638 | { |
| 639 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 639 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 640 | 640 | return cpustate->rddiv & 0xff; |
| 641 | 641 | } |
| 642 | 642 | |
| 643 | | static READ8_HANDLER( rddivh_r ) |
| 643 | READ8_MEMBER( _5a22_device::rddivh_r ) |
| 644 | 644 | { |
| 645 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 645 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 646 | 646 | return cpustate->rddiv >> 8; |
| 647 | 647 | } |
| 648 | 648 | |
| 649 | | static READ8_HANDLER( rdmpyl_r ) |
| 649 | READ8_MEMBER( _5a22_device::rdmpyl_r ) |
| 650 | 650 | { |
| 651 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 651 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 652 | 652 | return cpustate->rdmpy & 0xff; |
| 653 | 653 | } |
| 654 | 654 | |
| 655 | | static READ8_HANDLER( rdmpyh_r ) |
| 655 | READ8_MEMBER( _5a22_device::rdmpyh_r ) |
| 656 | 656 | { |
| 657 | | g65816i_cpu_struct *cpustate = get_safe_token(&space.device()); |
| 657 | g65816i_cpu_struct *cpustate = get_safe_token(this); |
| 658 | 658 | return cpustate->rdmpy >> 8; |
| 659 | 659 | } |
| 660 | 660 | |
| 661 | 661 | |
| 662 | | static ADDRESS_MAP_START(_5a22_map, AS_PROGRAM, 8, legacy_cpu_device) |
| 663 | | AM_RANGE(0x4202, 0x4202) AM_MIRROR(0xbf0000) AM_WRITE_LEGACY(wrmpya_w) |
| 664 | | AM_RANGE(0x4203, 0x4203) AM_MIRROR(0xbf0000) AM_WRITE_LEGACY(wrmpyb_w) |
| 665 | | AM_RANGE(0x4204, 0x4204) AM_MIRROR(0xbf0000) AM_WRITE_LEGACY(wrdivl_w) |
| 666 | | AM_RANGE(0x4205, 0x4205) AM_MIRROR(0xbf0000) AM_WRITE_LEGACY(wrdivh_w) |
| 667 | | AM_RANGE(0x4206, 0x4206) AM_MIRROR(0xbf0000) AM_WRITE_LEGACY(wrdvdd_w) |
| 662 | static ADDRESS_MAP_START(_5a22_map, AS_PROGRAM, 8, _5a22_device) |
| 663 | AM_RANGE(0x4202, 0x4202) AM_MIRROR(0xbf0000) AM_WRITE(wrmpya_w) |
| 664 | AM_RANGE(0x4203, 0x4203) AM_MIRROR(0xbf0000) AM_WRITE(wrmpyb_w) |
| 665 | AM_RANGE(0x4204, 0x4204) AM_MIRROR(0xbf0000) AM_WRITE(wrdivl_w) |
| 666 | AM_RANGE(0x4205, 0x4205) AM_MIRROR(0xbf0000) AM_WRITE(wrdivh_w) |
| 667 | AM_RANGE(0x4206, 0x4206) AM_MIRROR(0xbf0000) AM_WRITE(wrdvdd_w) |
| 668 | 668 | |
| 669 | | AM_RANGE(0x420d, 0x420d) AM_MIRROR(0xbf0000) AM_WRITE_LEGACY(memsel_w) |
| 669 | AM_RANGE(0x420d, 0x420d) AM_MIRROR(0xbf0000) AM_WRITE(memsel_w) |
| 670 | 670 | |
| 671 | | AM_RANGE(0x4214, 0x4214) AM_MIRROR(0xbf0000) AM_READ_LEGACY(rddivl_r) |
| 672 | | AM_RANGE(0x4215, 0x4215) AM_MIRROR(0xbf0000) AM_READ_LEGACY(rddivh_r) |
| 673 | | AM_RANGE(0x4216, 0x4216) AM_MIRROR(0xbf0000) AM_READ_LEGACY(rdmpyl_r) |
| 674 | | AM_RANGE(0x4217, 0x4217) AM_MIRROR(0xbf0000) AM_READ_LEGACY(rdmpyh_r) |
| 671 | AM_RANGE(0x4214, 0x4214) AM_MIRROR(0xbf0000) AM_READ(rddivl_r) |
| 672 | AM_RANGE(0x4215, 0x4215) AM_MIRROR(0xbf0000) AM_READ(rddivh_r) |
| 673 | AM_RANGE(0x4216, 0x4216) AM_MIRROR(0xbf0000) AM_READ(rdmpyl_r) |
| 674 | AM_RANGE(0x4217, 0x4217) AM_MIRROR(0xbf0000) AM_READ(rdmpyh_r) |
| 675 | 675 | |
| 676 | 676 | ADDRESS_MAP_END |
| 677 | 677 | |
| 678 | | void set_5a22_map(legacy_cpu_device &cpu) |
| 678 | void _5a22_device::set_5a22_map() |
| 679 | 679 | { |
| 680 | | cpu.space(AS_PROGRAM).install_legacy_write_handler(0x4202, 0x4202, 0, 0xbf0000, FUNC(wrmpya_w)); |
| 681 | | cpu.space(AS_PROGRAM).install_legacy_write_handler(0x4203, 0x4203, 0, 0xbf0000, FUNC(wrmpyb_w)); |
| 682 | | cpu.space(AS_PROGRAM).install_legacy_write_handler(0x4204, 0x4204, 0, 0xbf0000, FUNC(wrdivl_w)); |
| 683 | | cpu.space(AS_PROGRAM).install_legacy_write_handler(0x4205, 0x4205, 0, 0xbf0000, FUNC(wrdivh_w)); |
| 684 | | cpu.space(AS_PROGRAM).install_legacy_write_handler(0x4206, 0x4206, 0, 0xbf0000, FUNC(wrdvdd_w)); |
| 680 | space(AS_PROGRAM).install_write_handler(0x4202, 0x4202, 0, 0xbf0000, write8_delegate(FUNC(_5a22_device::wrmpya_w),this)); |
| 681 | space(AS_PROGRAM).install_write_handler(0x4203, 0x4203, 0, 0xbf0000, write8_delegate(FUNC(_5a22_device::wrmpyb_w),this)); |
| 682 | space(AS_PROGRAM).install_write_handler(0x4204, 0x4204, 0, 0xbf0000, write8_delegate(FUNC(_5a22_device::wrdivl_w),this)); |
| 683 | space(AS_PROGRAM).install_write_handler(0x4205, 0x4205, 0, 0xbf0000, write8_delegate(FUNC(_5a22_device::wrdivh_w),this)); |
| 684 | space(AS_PROGRAM).install_write_handler(0x4206, 0x4206, 0, 0xbf0000, write8_delegate(FUNC(_5a22_device::wrdvdd_w),this)); |
| 685 | 685 | |
| 686 | | cpu.space(AS_PROGRAM).install_legacy_write_handler(0x420d, 0x420d, 0, 0xbf0000, FUNC(memsel_w)); |
| 686 | space(AS_PROGRAM).install_write_handler(0x420d, 0x420d, 0, 0xbf0000, write8_delegate(FUNC(_5a22_device::memsel_w),this)); |
| 687 | 687 | |
| 688 | | cpu.space(AS_PROGRAM).install_legacy_read_handler(0x4214, 0x4214, 0, 0xbf0000, FUNC(rddivl_r)); |
| 689 | | cpu.space(AS_PROGRAM).install_legacy_read_handler(0x4215, 0x4215, 0, 0xbf0000, FUNC(rddivh_r)); |
| 690 | | cpu.space(AS_PROGRAM).install_legacy_read_handler(0x4216, 0x4216, 0, 0xbf0000, FUNC(rdmpyl_r)); |
| 691 | | cpu.space(AS_PROGRAM).install_legacy_read_handler(0x4217, 0x4217, 0, 0xbf0000, FUNC(rdmpyh_r)); |
| 688 | space(AS_PROGRAM).install_read_handler(0x4214, 0x4214, 0, 0xbf0000, read8_delegate(FUNC(_5a22_device::rddivl_r),this)); |
| 689 | space(AS_PROGRAM).install_read_handler(0x4215, 0x4215, 0, 0xbf0000, read8_delegate(FUNC(_5a22_device::rddivh_r),this)); |
| 690 | space(AS_PROGRAM).install_read_handler(0x4216, 0x4216, 0, 0xbf0000, read8_delegate(FUNC(_5a22_device::rdmpyl_r),this)); |
| 691 | space(AS_PROGRAM).install_read_handler(0x4217, 0x4217, 0, 0xbf0000, read8_delegate(FUNC(_5a22_device::rdmpyh_r),this)); |
| 692 | 692 | } |
| 693 | 693 | |
| 694 | 694 | CPU_SET_INFO( _5a22 ) |
shelves/new_menus/src/emu/cpu/h8/h83008.c
| r0 | r29305 | |
| 1 | #include "emu.h" |
| 2 | #include "h83008.h" |
| 3 | #include "h8_adc.h" |
| 4 | |
| 5 | const device_type H83008 = &device_creator<h83008_device>; |
| 6 | |
| 7 | h83008_device::h83008_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 8 | h8h_device(mconfig, H83008, "H8/3008", tag, owner, clock, "h83008", __FILE__, address_map_delegate(FUNC(h83008_device::map), this)), |
| 9 | intc(*this, "intc"), |
| 10 | adc(*this, "adc"), |
| 11 | port4(*this, "port4"), |
| 12 | port6(*this, "port6"), |
| 13 | port7(*this, "port7"), |
| 14 | port8(*this, "port8"), |
| 15 | port9(*this, "port9"), |
| 16 | porta(*this, "porta"), |
| 17 | portb(*this, "portb"), |
| 18 | timer16(*this, "timer16"), |
| 19 | timer16_0(*this, "timer16:0"), |
| 20 | timer16_1(*this, "timer16:1"), |
| 21 | timer16_2(*this, "timer16:2"), |
| 22 | sci0(*this, "sci0"), |
| 23 | sci1(*this, "sci1") |
| 24 | { |
| 25 | } |
| 26 | |
| 27 | static MACHINE_CONFIG_FRAGMENT(h83008) |
| 28 | MCFG_H8H_INTC_ADD("intc") |
| 29 | MCFG_H8_ADC_3006_ADD("adc", "intc", 23) |
| 30 | MCFG_H8_PORT_ADD("port4", h8_device::PORT_4, 0x00, 0x00) |
| 31 | MCFG_H8_PORT_ADD("port6", h8_device::PORT_6, 0x80, 0x80) |
| 32 | MCFG_H8_PORT_ADD("port7", h8_device::PORT_7, 0xff, 0x00) |
| 33 | MCFG_H8_PORT_ADD("port8", h8_device::PORT_8, 0xf0, 0xe0) |
| 34 | MCFG_H8_PORT_ADD("port9", h8_device::PORT_9, 0xc0, 0xc0) |
| 35 | MCFG_H8_PORT_ADD("porta", h8_device::PORT_A, 0x80, 0x00) |
| 36 | MCFG_H8_PORT_ADD("portb", h8_device::PORT_B, 0x00, 0x00) |
| 37 | MCFG_H8_TIMER16_ADD("timer16", 3, 0xf8) |
| 38 | MCFG_H8H_TIMER16_CHANNEL_ADD("timer16:0", 2, 2, "intc", 24) |
| 39 | MCFG_H8H_TIMER16_CHANNEL_ADD("timer16:1", 2, 2, "intc", 28) |
| 40 | MCFG_H8H_TIMER16_CHANNEL_ADD("timer16:2", 2, 2, "intc", 32) |
| 41 | MCFG_H8_SCI_ADD("sci0", "intc", 52, 53, 54, 55) |
| 42 | MCFG_H8_SCI_ADD("sci1", "intc", 56, 57, 58, 59) |
| 43 | MACHINE_CONFIG_END |
| 44 | |
| 45 | DEVICE_ADDRESS_MAP_START(map, 16, h83008_device) |
| 46 | AM_RANGE(0xfee002, 0xfee003) AM_DEVWRITE8( "port4", h8_port_device, ddr_w, 0x00ff) |
| 47 | AM_RANGE(0xfee004, 0xfee005) AM_DEVWRITE8( "port6", h8_port_device, ddr_w, 0x00ff) |
| 48 | AM_RANGE(0xfee006, 0xfee007) AM_DEVWRITE8( "port8", h8_port_device, ddr_w, 0x00ff) |
| 49 | AM_RANGE(0xfee008, 0xfee009) AM_DEVWRITE8( "port9", h8_port_device, ddr_w, 0xff00) |
| 50 | AM_RANGE(0xfee008, 0xfee009) AM_DEVWRITE8( "porta", h8_port_device, ddr_w, 0x00ff) |
| 51 | AM_RANGE(0xfee00a, 0xfee00b) AM_DEVWRITE8( "portb", h8_port_device, ddr_w, 0xff00) |
| 52 | |
| 53 | AM_RANGE(0xfee012, 0xfee013) AM_READWRITE8( syscr_r, syscr_w, 0xff00) |
| 54 | AM_RANGE(0xfee014, 0xfee015) AM_DEVREADWRITE8("intc", h8h_intc_device, iscr_r, iscr_w, 0xff00) |
| 55 | AM_RANGE(0xfee014, 0xfee015) AM_DEVREADWRITE8("intc", h8h_intc_device, ier_r, ier_w, 0x00ff) |
| 56 | AM_RANGE(0xfee016, 0xfee017) AM_DEVREADWRITE8("intc", h8h_intc_device, isr_r, isr_w, 0xff00) |
| 57 | AM_RANGE(0xfee018, 0xfee019) AM_DEVREADWRITE8("intc", h8h_intc_device, icr_r, icr_w, 0xffff) |
| 58 | |
| 59 | AM_RANGE(0xfee03e, 0xfee03f) AM_DEVREADWRITE8("port4", h8_port_device, pcr_r, pcr_w, 0xff00) |
| 60 | |
| 61 | AM_RANGE(0xffef20, 0xffff1f) AM_RAM |
| 62 | |
| 63 | AM_RANGE(0xffff60, 0xffff61) AM_DEVREADWRITE8("timer16", h8_timer16_device, tstr_r, tstr_w, 0xff00) |
| 64 | AM_RANGE(0xffff60, 0xffff61) AM_DEVREADWRITE8("timer16", h8_timer16_device, tsyr_r, tsyr_w, 0x00ff) |
| 65 | AM_RANGE(0xffff62, 0xffff63) AM_DEVREADWRITE8("timer16", h8_timer16_device, tmdr_r, tmdr_w, 0xff00) |
| 66 | AM_RANGE(0xffff62, 0xffff63) AM_DEVWRITE8( "timer16", h8_timer16_device, tolr_w, 0x00ff) |
| 67 | AM_RANGE(0xffff64, 0xffff65) AM_DEVREADWRITE8("timer16", h8_timer16_device, tisr_r, tisr_w, 0xffff) |
| 68 | AM_RANGE(0xffff66, 0xffff67) AM_DEVREADWRITE8("timer16", h8_timer16_device, tisrc_r, tisrc_w, 0xff00) |
| 69 | AM_RANGE(0xffff68, 0xffff69) AM_DEVREADWRITE8("timer16:0", h8_timer16_channel_device, tcr_r, tcr_w, 0xff00) |
| 70 | AM_RANGE(0xffff68, 0xffff69) AM_DEVREADWRITE8("timer16:0", h8_timer16_channel_device, tior_r, tior_w, 0x00ff) |
| 71 | AM_RANGE(0xffff6a, 0xffff6b) AM_DEVREADWRITE( "timer16:0", h8_timer16_channel_device, tcnt_r, tcnt_w ) |
| 72 | AM_RANGE(0xffff6c, 0xffff6f) AM_DEVREADWRITE( "timer16:0", h8_timer16_channel_device, tgr_r, tgr_w ) |
| 73 | AM_RANGE(0xffff70, 0xffff71) AM_DEVREADWRITE8("timer16:1", h8_timer16_channel_device, tcr_r, tcr_w, 0xff00) |
| 74 | AM_RANGE(0xffff70, 0xffff71) AM_DEVREADWRITE8("timer16:1", h8_timer16_channel_device, tior_r, tior_w, 0x00ff) |
| 75 | AM_RANGE(0xffff72, 0xffff73) AM_DEVREADWRITE( "timer16:1", h8_timer16_channel_device, tcnt_r, tcnt_w ) |
| 76 | AM_RANGE(0xffff74, 0xffff77) AM_DEVREADWRITE( "timer16:1", h8_timer16_channel_device, tgr_r, tgr_w ) |
| 77 | AM_RANGE(0xffff78, 0xffff79) AM_DEVREADWRITE8("timer16:2", h8_timer16_channel_device, tcr_r, tcr_w, 0xff00) |
| 78 | AM_RANGE(0xffff78, 0xffff79) AM_DEVREADWRITE8("timer16:2", h8_timer16_channel_device, tior_r, tior_w, 0x00ff) |
| 79 | AM_RANGE(0xffff7a, 0xffff7b) AM_DEVREADWRITE( "timer16:2", h8_timer16_channel_device, tcnt_r, tcnt_w ) |
| 80 | AM_RANGE(0xffff7c, 0xffff7f) AM_DEVREADWRITE( "timer16:2", h8_timer16_channel_device, tgr_r, tgr_w ) |
| 81 | |
| 82 | AM_RANGE(0xffffb0, 0xffffb1) AM_DEVREADWRITE8("sci0", h8_sci_device, smr_r, smr_w, 0xff00) |
| 83 | AM_RANGE(0xffffb0, 0xffffb1) AM_DEVREADWRITE8("sci0", h8_sci_device, brr_r, brr_w, 0x00ff) |
| 84 | AM_RANGE(0xffffb2, 0xffffb3) AM_DEVREADWRITE8("sci0", h8_sci_device, scr_r, scr_w, 0xff00) |
| 85 | AM_RANGE(0xffffb2, 0xffffb3) AM_DEVREADWRITE8("sci0", h8_sci_device, tdr_r, tdr_w, 0x00ff) |
| 86 | AM_RANGE(0xffffb4, 0xffffb5) AM_DEVREADWRITE8("sci0", h8_sci_device, ssr_r, ssr_w, 0xff00) |
| 87 | AM_RANGE(0xffffb4, 0xffffb5) AM_DEVREAD8( "sci0", h8_sci_device, rdr_r, 0x00ff) |
| 88 | AM_RANGE(0xffffb6, 0xffffb7) AM_DEVREADWRITE8("sci0", h8_sci_device, scmr_r, scmr_w, 0xff00) |
| 89 | AM_RANGE(0xffffb8, 0xffffb9) AM_DEVREADWRITE8("sci1", h8_sci_device, smr_r, smr_w, 0xff00) |
| 90 | AM_RANGE(0xffffb8, 0xffffb9) AM_DEVREADWRITE8("sci1", h8_sci_device, brr_r, brr_w, 0x00ff) |
| 91 | AM_RANGE(0xffffba, 0xffffbb) AM_DEVREADWRITE8("sci1", h8_sci_device, scr_r, scr_w, 0xff00) |
| 92 | AM_RANGE(0xffffba, 0xffffbb) AM_DEVREADWRITE8("sci1", h8_sci_device, tdr_r, tdr_w, 0x00ff) |
| 93 | AM_RANGE(0xffffbc, 0xffffbd) AM_DEVREADWRITE8("sci1", h8_sci_device, ssr_r, ssr_w, 0xff00) |
| 94 | AM_RANGE(0xffffbc, 0xffffbd) AM_DEVREAD8( "sci1", h8_sci_device, rdr_r, 0x00ff) |
| 95 | AM_RANGE(0xffffbe, 0xffffbf) AM_DEVREADWRITE8("sci1", h8_sci_device, scmr_r, scmr_w, 0xff00) |
| 96 | AM_RANGE(0xffffd2, 0xffffd3) AM_DEVREADWRITE8("port4", h8_port_device, port_r, dr_w, 0x00ff) |
| 97 | AM_RANGE(0xffffd4, 0xffffd5) AM_DEVREADWRITE8("port6", h8_port_device, port_r, dr_w, 0x00ff) |
| 98 | AM_RANGE(0xffffd6, 0xffffd7) AM_DEVREADWRITE8("port7", h8_port_device, port_r, dr_w, 0xff00) |
| 99 | AM_RANGE(0xffffd6, 0xffffd7) AM_DEVREADWRITE8("port8", h8_port_device, port_r, dr_w, 0x00ff) |
| 100 | AM_RANGE(0xffffd8, 0xffffd9) AM_DEVREADWRITE8("port9", h8_port_device, port_r, dr_w, 0xff00) |
| 101 | AM_RANGE(0xffffd8, 0xffffd9) AM_DEVREADWRITE8("porta", h8_port_device, port_r, dr_w, 0x00ff) |
| 102 | AM_RANGE(0xffffda, 0xffffdb) AM_DEVREADWRITE8("portb", h8_port_device, port_r, dr_w, 0xff00) |
| 103 | |
| 104 | AM_RANGE(0xffffe0, 0xffffe7) AM_DEVREAD8( "adc", h8_adc_device, addr8_r, 0xffff) |
| 105 | AM_RANGE(0xffffe8, 0xffffe9) AM_DEVREADWRITE8("adc", h8_adc_device, adcsr_r, adcsr_w, 0xff00) |
| 106 | AM_RANGE(0xffffe8, 0xffffe9) AM_DEVREADWRITE8("adc", h8_adc_device, adcr_r, adcr_w, 0x00ff) |
| 107 | ADDRESS_MAP_END |
| 108 | |
| 109 | machine_config_constructor h83008_device::device_mconfig_additions() const |
| 110 | { |
| 111 | return MACHINE_CONFIG_NAME(h83008); |
| 112 | } |
| 113 | |
| 114 | void h83008_device::execute_set_input(int inputnum, int state) |
| 115 | { |
| 116 | intc->set_input(inputnum, state); |
| 117 | } |
| 118 | |
| 119 | int h83008_device::trapa_setup() |
| 120 | { |
| 121 | if(syscr & 0x08) |
| 122 | CCR |= F_I; |
| 123 | else |
| 124 | CCR |= F_I|F_UI; |
| 125 | return 8; |
| 126 | } |
| 127 | |
| 128 | void h83008_device::irq_setup() |
| 129 | { |
| 130 | if(syscr & 0x08) |
| 131 | CCR |= F_I; |
| 132 | else |
| 133 | CCR |= F_I|F_UI; |
| 134 | } |
| 135 | |
| 136 | void h83008_device::update_irq_filter() |
| 137 | { |
| 138 | switch(syscr & 0x08) { |
| 139 | case 0x00: |
| 140 | if((CCR & (F_I|F_UI)) == (F_I|F_UI)) |
| 141 | intc->set_filter(2, -1); |
| 142 | else if(CCR & F_I) |
| 143 | intc->set_filter(1, -1); |
| 144 | else |
| 145 | intc->set_filter(0, -1); |
| 146 | break; |
| 147 | case 0x08: |
| 148 | if(CCR & F_I) |
| 149 | intc->set_filter(2, -1); |
| 150 | else |
| 151 | intc->set_filter(0, -1); |
| 152 | break; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | void h83008_device::interrupt_taken() |
| 157 | { |
| 158 | standard_irq_callback(intc->interrupt_taken(taken_irq_vector)); |
| 159 | } |
| 160 | |
| 161 | void h83008_device::internal_update(UINT64 current_time) |
| 162 | { |
| 163 | UINT64 event_time = 0; |
| 164 | |
| 165 | add_event(event_time, adc->internal_update(current_time)); |
| 166 | add_event(event_time, sci0->internal_update(current_time)); |
| 167 | add_event(event_time, sci1->internal_update(current_time)); |
| 168 | add_event(event_time, timer16_0->internal_update(current_time)); |
| 169 | add_event(event_time, timer16_1->internal_update(current_time)); |
| 170 | add_event(event_time, timer16_2->internal_update(current_time)); |
| 171 | |
| 172 | recompute_bcount(event_time); |
| 173 | } |
| 174 | |
| 175 | void h83008_device::device_start() |
| 176 | { |
| 177 | h8h_device::device_start(); |
| 178 | } |
| 179 | |
| 180 | void h83008_device::device_reset() |
| 181 | { |
| 182 | h8h_device::device_reset(); |
| 183 | syscr = 0x09; |
| 184 | } |
| 185 | |
| 186 | |
| 187 | READ8_MEMBER(h83008_device::syscr_r) |
| 188 | { |
| 189 | return syscr; |
| 190 | } |
| 191 | |
| 192 | WRITE8_MEMBER(h83008_device::syscr_w) |
| 193 | { |
| 194 | syscr = data; |
| 195 | update_irq_filter(); |
| 196 | logerror("%s: syscr = %02x\n", tag(), data); |
| 197 | } |
shelves/new_menus/src/emu/video/i8275x.c
| r29304 | r29305 | |
| 25 | 25 | // MACROS / CONSTANTS |
| 26 | 26 | //************************************************************************** |
| 27 | 27 | |
| 28 | #define LOG 0 |
| 29 | |
| 30 | |
| 28 | 31 | const int DMA_BURST_SPACING[] = { 0, 7, 15, 23, 31, 39, 47, 55 }; |
| 29 | 32 | |
| 33 | |
| 30 | 34 | #define DOUBLE_SPACED_ROWS \ |
| 31 | 35 | BIT(m_param[REG_SCN1], 7) |
| 32 | 36 | |
| r29304 | r29305 | |
| 66 | 70 | |
| 67 | 71 | |
| 68 | 72 | //************************************************************************** |
| 69 | | // somethign |
| 73 | // DEVICE DEFINITIONS |
| 70 | 74 | //************************************************************************** |
| 71 | 75 | |
| 72 | 76 | // device type definition |
| 73 | 77 | const device_type I8275x = &device_creator<i8275x_device>; |
| 74 | 78 | |
| 75 | 79 | |
| 80 | |
| 76 | 81 | //************************************************************************** |
| 77 | 82 | // LIVE DEVICE |
| 78 | 83 | //************************************************************************** |
| r29304 | r29305 | |
| 81 | 86 | // i8275x_device - constructor |
| 82 | 87 | //------------------------------------------------- |
| 83 | 88 | |
| 84 | | i8275x_device::i8275x_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 85 | | : device_t(mconfig, I8275x, "I8275", tag, owner, clock, "i8275x", __FILE__), |
| 86 | | device_video_interface(mconfig, *this), |
| 87 | | m_write_irq(*this), |
| 88 | | m_write_drq(*this), |
| 89 | | m_write_hrtc(*this), |
| 90 | | m_write_vrtc(*this), |
| 91 | | m_display_pixels(NULL), |
| 92 | | m_status(0), |
| 93 | | m_param_idx(0), |
| 94 | | m_param_end(0), |
| 95 | | m_buffer_idx(0), |
| 96 | | m_fifo_next(false), |
| 97 | | m_buffer_dma(0), |
| 98 | | m_lpen(0), |
| 99 | | m_hlgt(0), |
| 100 | | m_vsp(0), |
| 101 | | m_gpa(0), |
| 102 | | m_rvv(0), |
| 103 | | m_lten(0), |
| 104 | | m_scanline(0), |
| 105 | | m_du(false), |
| 106 | | m_cursor_blink(0), |
| 107 | | m_char_blink(0) |
| 89 | i8275x_device::i8275x_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 90 | device_t(mconfig, I8275x, "I8275", tag, owner, clock, "i8275x", __FILE__), |
| 91 | device_video_interface(mconfig, *this), |
| 92 | m_write_irq(*this), |
| 93 | m_write_drq(*this), |
| 94 | m_write_hrtc(*this), |
| 95 | m_write_vrtc(*this), |
| 96 | m_display_cb(NULL), |
| 97 | m_status(0), |
| 98 | m_param_idx(0), |
| 99 | m_param_end(0), |
| 100 | m_buffer_idx(0), |
| 101 | m_fifo_next(false), |
| 102 | m_buffer_dma(0), |
| 103 | m_lpen(0), |
| 104 | m_hlgt(0), |
| 105 | m_vsp(0), |
| 106 | m_gpa(0), |
| 107 | m_rvv(0), |
| 108 | m_lten(0), |
| 109 | m_scanline(0), |
| 110 | m_du(false), |
| 111 | m_cursor_blink(0), |
| 112 | m_char_blink(0) |
| 108 | 113 | { |
| 109 | 114 | } |
| 110 | 115 | |
| r29304 | r29305 | |
| 173 | 178 | switch (id) |
| 174 | 179 | { |
| 175 | 180 | case TIMER_HRTC_ON: |
| 176 | | //logerror("I8275 '%s' y %u x %u HRTC 1\n", tag(), y, x); |
| 181 | //if (LOG) logerror("I8275 '%s' y %u x %u HRTC 1\n", tag(), y, x); |
| 177 | 182 | m_write_hrtc(1); |
| 178 | 183 | break; |
| 179 | 184 | |
| 180 | 185 | case TIMER_DRQ_ON: |
| 181 | | //logerror("I8275 '%s' y %u x %u DRQ 1\n", tag(), y, x); |
| 186 | //if (LOG) logerror("I8275 '%s' y %u x %u DRQ 1\n", tag(), y, x); |
| 182 | 187 | m_write_drq(1); |
| 183 | 188 | m_drq_off_timer->adjust(clocks_to_attotime(DMA_BURST_COUNT)); |
| 184 | 189 | break; |
| r29304 | r29305 | |
| 188 | 193 | { |
| 189 | 194 | m_status |= ST_DU; |
| 190 | 195 | m_du = true; |
| 191 | | //logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x); |
| 196 | //if (LOG) logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x); |
| 192 | 197 | m_write_drq(0); |
| 193 | 198 | } |
| 194 | 199 | else if (m_buffer_idx == CHARACTERS_PER_ROW) |
| 195 | 200 | { |
| 196 | | //logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x); |
| 201 | //if (LOG) logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x); |
| 197 | 202 | m_write_drq(0); |
| 198 | 203 | } |
| 199 | 204 | else if (DMA_BURST_SPACE > 0) |
| 200 | 205 | { |
| 201 | | //logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x); |
| 206 | //if (LOG) logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x); |
| 202 | 207 | m_write_drq(0); |
| 203 | 208 | m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE)); |
| 204 | 209 | } |
| r29304 | r29305 | |
| 207 | 212 | case TIMER_SCANLINE: |
| 208 | 213 | if (!(m_status & ST_VE)) break; |
| 209 | 214 | |
| 210 | | //logerror("I8275 '%s' y %u x %u HRTC 0\n", tag(), y, x); |
| 215 | //if (LOG) logerror("I8275 '%s' y %u x %u HRTC 0\n", tag(), y, x); |
| 211 | 216 | m_write_hrtc(0); |
| 212 | 217 | |
| 213 | 218 | if (m_scanline == 0) |
| 214 | 219 | { |
| 215 | | //logerror("I8275 '%s' y %u x %u VRTC 0\n", tag(), y, x); |
| 220 | //if (LOG) logerror("I8275 '%s' y %u x %u VRTC 0\n", tag(), y, x); |
| 216 | 221 | m_write_vrtc(0); |
| 217 | 222 | } |
| 218 | 223 | else if (m_scanline == m_irq_scanline) |
| 219 | 224 | { |
| 220 | 225 | if (m_status & ST_IE) |
| 221 | 226 | { |
| 222 | | //logerror("I8275 '%s' y %u x %u IRQ 1\n", tag(), y, x); |
| 227 | //if (LOG) logerror("I8275 '%s' y %u x %u IRQ 1\n", tag(), y, x); |
| 223 | 228 | m_status |= ST_IR; |
| 224 | 229 | m_write_irq(ASSERT_LINE); |
| 225 | 230 | } |
| 226 | 231 | } |
| 227 | 232 | else if (m_scanline == m_vrtc_scanline) |
| 228 | 233 | { |
| 229 | | //logerror("I8275 '%s' y %u x %u VRTC 1\n", tag(), y, x); |
| 234 | //if (LOG) logerror("I8275 '%s' y %u x %u VRTC 1\n", tag(), y, x); |
| 230 | 235 | m_write_vrtc(1); |
| 231 | 236 | |
| 232 | 237 | // reset field attributes |
| r29304 | r29305 | |
| 329 | 334 | lc = (lc - 1) & 0x0f; |
| 330 | 335 | } |
| 331 | 336 | |
| 332 | | if (m_display_pixels) |
| 333 | | m_display_pixels(this, m_bitmap, |
| 337 | if (m_display_cb) |
| 338 | m_display_cb(this, m_bitmap, |
| 334 | 339 | sx * m_hpixels_per_column, // x position on screen of starting point |
| 335 | 340 | m_scanline, // y position on screen |
| 336 | 341 | lc, // current line of char |
| r29304 | r29305 | |
| 366 | 371 | |
| 367 | 372 | if (m_status & ST_IR) |
| 368 | 373 | { |
| 369 | | //logerror("I8275 '%s' IRQ 0\n", tag()); |
| 374 | //if (LOG) logerror("I8275 '%s' IRQ 0\n", tag()); |
| 370 | 375 | m_write_irq(CLEAR_LINE); |
| 371 | 376 | } |
| 372 | 377 | |
| r29304 | r29305 | |
| 395 | 400 | { |
| 396 | 401 | if (offset & 0x01) |
| 397 | 402 | { |
| 398 | | logerror("I8275 '%s' Command %02x\n", tag(), data); |
| 403 | if (LOG) logerror("I8275 '%s' Command %02x\n", tag(), data); |
| 399 | 404 | |
| 400 | 405 | switch (data >> 5) |
| 401 | 406 | { |
| 402 | 407 | case CMD_RESET: |
| 403 | | logerror("I8275 '%s' Reset\n", tag()); |
| 408 | if (LOG) logerror("I8275 '%s' Reset\n", tag()); |
| 404 | 409 | |
| 405 | 410 | m_status &= ~ST_IE; |
| 406 | | logerror("I8275 '%s' IRQ 0\n", tag()); |
| 411 | if (LOG) logerror("I8275 '%s' IRQ 0\n", tag()); |
| 407 | 412 | m_write_irq(CLEAR_LINE); |
| 408 | 413 | |
| 409 | 414 | m_param_idx = REG_SCN1; |
| r29304 | r29305 | |
| 413 | 418 | case CMD_START_DISPLAY: |
| 414 | 419 | { |
| 415 | 420 | m_param[REG_DMA] = data; |
| 416 | | logerror("I8275 '%s' Start Display %u %u\n", tag(), DMA_BURST_COUNT, DMA_BURST_SPACE); |
| 421 | if (LOG) logerror("I8275 '%s' Start Display %u %u\n", tag(), DMA_BURST_COUNT, DMA_BURST_SPACE); |
| 417 | 422 | m_status |= (ST_IE | ST_VE); |
| 418 | 423 | } |
| 419 | 424 | break; |
| 420 | 425 | |
| 421 | 426 | case CMD_STOP_DISPLAY: |
| 422 | | logerror("I8275 '%s' Stop Display\n", tag()); |
| 427 | if (LOG) logerror("I8275 '%s' Stop Display\n", tag()); |
| 423 | 428 | m_status &= ~ST_VE; |
| 424 | 429 | break; |
| 425 | 430 | |
| 426 | 431 | case CMD_READ_LIGHT_PEN: |
| 427 | | logerror("I8275 '%s' Read Light Pen\n", tag()); |
| 432 | if (LOG) logerror("I8275 '%s' Read Light Pen\n", tag()); |
| 428 | 433 | m_param_idx = REG_LPEN_COL; |
| 429 | 434 | m_param_end = REG_LPEN_ROW; |
| 430 | 435 | break; |
| 431 | 436 | |
| 432 | 437 | case CMD_LOAD_CURSOR: |
| 433 | | logerror("I8275 '%s' Load Cursor\n", tag()); |
| 438 | if (LOG) logerror("I8275 '%s' Load Cursor\n", tag()); |
| 434 | 439 | m_param_idx = REG_CUR_COL; |
| 435 | 440 | m_param_end = REG_CUR_ROW; |
| 436 | 441 | break; |
| 437 | 442 | |
| 438 | 443 | case CMD_ENABLE_INTERRUPT: |
| 439 | | logerror("I8275 '%s' Enable Interrupt\n", tag()); |
| 444 | if (LOG) logerror("I8275 '%s' Enable Interrupt\n", tag()); |
| 440 | 445 | m_status |= ST_IE; |
| 441 | 446 | break; |
| 442 | 447 | |
| 443 | 448 | case CMD_DISABLE_INTERRUPT: |
| 444 | | logerror("I8275 '%s' Disable Interrupt\n", tag()); |
| 449 | if (LOG) logerror("I8275 '%s' Disable Interrupt\n", tag()); |
| 445 | 450 | m_status &= ~ST_IE; |
| 446 | 451 | break; |
| 447 | 452 | |
| 448 | 453 | case CMD_PRESET_COUNTERS: |
| 449 | | logerror("I8275 '%s' Preset Counters\n", tag()); |
| 454 | if (LOG) logerror("I8275 '%s' Preset Counters\n", tag()); |
| 450 | 455 | m_scanline = 0; |
| 451 | 456 | break; |
| 452 | 457 | } |
| 453 | 458 | } |
| 454 | 459 | else |
| 455 | 460 | { |
| 456 | | logerror("I8275 '%s' Parameter %02x\n", tag(), data); |
| 461 | if (LOG) logerror("I8275 '%s' Parameter %02x\n", tag(), data); |
| 457 | 462 | |
| 458 | 463 | m_param[m_param_idx] = data; |
| 459 | 464 | |
| r29304 | r29305 | |
| 473 | 478 | |
| 474 | 479 | WRITE8_MEMBER( i8275x_device::dack_w ) |
| 475 | 480 | { |
| 476 | | //logerror("DACK write %02x %u\n", data, m_buffer_idx); |
| 481 | //if (LOG) logerror("DACK write %02x %u\n", data, m_buffer_idx); |
| 477 | 482 | |
| 478 | 483 | if (m_fifo_next) |
| 479 | 484 | { |
| r29304 | r29305 | |
| 553 | 558 | int max_visible_x = (CHARACTERS_PER_ROW * m_hpixels_per_column) - 1; |
| 554 | 559 | int max_visible_y = (CHARACTER_ROWS_PER_FRAME * SCANLINES_PER_ROW) - 1; |
| 555 | 560 | |
| 556 | | logerror("width %u height %u max_x %u max_y %u refresh %f\n", horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); |
| 561 | if (LOG) logerror("width %u height %u max_x %u max_y %u refresh %f\n", horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); |
| 557 | 562 | |
| 558 | 563 | rectangle visarea; |
| 559 | 564 | visarea.set(0, max_visible_x, 0, max_visible_y); |
shelves/new_menus/src/emu/devcb.h
| r29304 | r29305 | |
| 34 | 34 | write_line_device_func: (device, data) |
| 35 | 35 | read8_device_func: (device, offset) |
| 36 | 36 | write8_device_func: (device, offset, data) |
| 37 | | read8_space_func: (space, offset) |
| 38 | | write8_space_func: (space, offset, data) |
| 39 | 37 | read16_device_func: (device, offset) |
| 40 | 38 | write16_device_func: (device, offset, data) |
| 41 | | read16_space_func: (space, offset) |
| 42 | | write16_space_func: (space, offset, data) |
| 43 | 39 | read32_device_func: (device, offset) |
| 44 | 40 | write32_device_func: (device, offset, data) |
| 45 | | read32_space_func: (space, offset) |
| 46 | | write32_space_func: (space, offset, data) |
| 47 | 41 | read64_device_func: (device, offset) |
| 48 | 42 | write64_device_func: (device, offset, data) |
| 49 | | read64_space_func: (space, offset) |
| 50 | | write64_space_func: (space, offset, data) |
| 51 | 43 | |
| 52 | 44 | ***************************************************************************/ |
| 53 | 45 | |
| r29304 | r29305 | |
| 165 | 157 | #define DEVCB_NULL { DEVCB_TYPE_NULL } |
| 166 | 158 | |
| 167 | 159 | // line or read/write handlers for the driver device |
| 168 | | #define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } |
| 169 | | #define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } |
| 170 | | #define DEVCB_DRIVER_MEMBER16(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub16<cls, &cls::memb>, NULL } |
| 171 | | #define DEVCB_DRIVER_MEMBER32(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub32<cls, &cls::memb>, NULL } |
| 172 | | //#define DEVCB_DRIVER_MEMBER64(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub64<cls, &cls::memb>, NULL } |
| 160 | #define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL } |
| 161 | #define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb> } |
| 162 | #define DEVCB_DRIVER_MEMBER16(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub16<cls, &cls::memb> } |
| 163 | #define DEVCB_DRIVER_MEMBER32(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub32<cls, &cls::memb> } |
| 164 | //#define DEVCB_DRIVER_MEMBER64(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub64<cls, &cls::memb> } |
| 173 | 165 | |
| 174 | 166 | // line or read/write handlers for another device |
| 175 | | #define DEVCB_DEVICE_LINE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } |
| 176 | | #define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } |
| 177 | | #define DEVCB_DEVICE_MEMBER16(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub16<cls, &cls::memb>, NULL } |
| 178 | | #define DEVCB_DEVICE_MEMBER32(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub32<cls, &cls::memb>, NULL } |
| 179 | | //#define DEVCB_DEVICE_MEMBER64(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub64<cls, &cls::memb>, NULL } |
| 167 | #define DEVCB_DEVICE_LINE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL } |
| 168 | #define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb> } |
| 169 | #define DEVCB_DEVICE_MEMBER16(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub16<cls, &cls::memb> } |
| 170 | #define DEVCB_DEVICE_MEMBER32(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub32<cls, &cls::memb> } |
| 171 | //#define DEVCB_DEVICE_MEMBER64(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub64<cls, &cls::memb> } |
| 180 | 172 | |
| 181 | 173 | // constant values |
| 182 | | #define DEVCB_CONSTANT(value) { DEVCB_TYPE_CONSTANT, value, NULL, NULL, NULL, NULL } |
| 174 | #define DEVCB_CONSTANT(value) { DEVCB_TYPE_CONSTANT, value, NULL, NULL, NULL } |
| 183 | 175 | #define DEVCB_LINE_GND DEVCB_CONSTANT(0) |
| 184 | 176 | #define DEVCB_LINE_VCC DEVCB_CONSTANT(1) |
| 185 | 177 | |
| 186 | | #define DEVCB_UNMAPPED { DEVCB_TYPE_UNMAP, 0, NULL, NULL, NULL, NULL } |
| 178 | #define DEVCB_UNMAPPED { DEVCB_TYPE_UNMAP, 0, NULL, NULL, NULL } |
| 187 | 179 | |
| 188 | 180 | // read handlers for an I/O port by tag |
| 189 | | #define DEVCB_INPUT_PORT(tag) { DEVCB_TYPE_IOPORT, 0, (tag), NULL, NULL, NULL, NULL } |
| 181 | #define DEVCB_INPUT_PORT(tag) { DEVCB_TYPE_IOPORT, 0, (tag), NULL, NULL, NULL } |
| 190 | 182 | |
| 191 | 183 | // write handlers for a CPU input line |
| 192 | | #define DEVCB_CPU_INPUT_LINE(tag,line) { DEVCB_TYPE_INPUT_LINE, (line), (tag), NULL, NULL, NULL, NULL } |
| 184 | #define DEVCB_CPU_INPUT_LINE(tag,line) { DEVCB_TYPE_INPUT_LINE, (line), (tag), NULL, NULL, NULL } |
| 193 | 185 | |
| 194 | 186 | |
| 195 | 187 | |
| r29304 | r29305 | |
| 218 | 210 | UINT8 * null_indicator; |
| 219 | 211 | read_line_device_func read_line; |
| 220 | 212 | read8_device_func read8_device; |
| 221 | | read8_space_func read8_space; |
| 222 | 213 | read16_device_func read16_device; |
| 223 | | read16_space_func read16_space; |
| 224 | 214 | read32_device_func read32_device; |
| 225 | | read32_space_func read32_space; |
| 226 | 215 | read64_device_func read64_device; |
| 227 | | read64_space_func read64_space; |
| 228 | 216 | }; |
| 229 | 217 | |
| 230 | 218 | union devcb_resolved_write_helpers |
| r29304 | r29305 | |
| 232 | 220 | UINT8 * null_indicator; |
| 233 | 221 | write_line_device_func write_line; |
| 234 | 222 | write8_device_func write8_device; |
| 235 | | write8_space_func write8_space; |
| 236 | 223 | write16_device_func write16_device; |
| 237 | | write16_space_func write16_space; |
| 238 | 224 | write32_device_func write32_device; |
| 239 | | write32_space_func write32_space; |
| 240 | 225 | write64_device_func write64_device; |
| 241 | | write64_space_func write64_space; |
| 242 | 226 | int input_line; |
| 243 | 227 | }; |
| 244 | 228 | |
| r29304 | r29305 | |
| 254 | 238 | const char * name; // name of the target function |
| 255 | 239 | read_line_device_func readline; // read line function |
| 256 | 240 | read8_device_func readdevice; // read device function |
| 257 | | read8_space_func readspace; // read space function |
| 258 | 241 | }; |
| 259 | 242 | |
| 260 | 243 | |
| r29304 | r29305 | |
| 304 | 287 | const char * name; // name of the target function |
| 305 | 288 | write_line_device_func writeline; // write line function |
| 306 | 289 | write8_device_func writedevice; // write device function |
| 307 | | write8_space_func writespace; // write space function |
| 308 | 290 | }; |
| 309 | 291 | |
| 310 | 292 | |
| r29304 | r29305 | |
| 355 | 337 | const char * name; // name of the target function |
| 356 | 338 | read_line_device_func readline; // read line function |
| 357 | 339 | read8_device_func readdevice; // read device function |
| 358 | | read8_space_func readspace; // read space function |
| 359 | 340 | }; |
| 360 | 341 | |
| 361 | 342 | |
| r29304 | r29305 | |
| 386 | 367 | private: |
| 387 | 368 | // internal helpers |
| 388 | 369 | UINT8 from_port(offs_t offset, UINT8 mem_mask); |
| 389 | | UINT8 from_read8space(offs_t offset, UINT8 mem_mask); |
| 390 | 370 | UINT8 from_read8device(offs_t offset, UINT8 mem_mask); |
| 391 | 371 | UINT8 from_readline(offs_t offset, UINT8 mem_mask); |
| 392 | 372 | UINT8 from_constant(offs_t offset, UINT8 mem_mask); |
| r29304 | r29305 | |
| 410 | 390 | const char * name; // name of the target function |
| 411 | 391 | write_line_device_func writeline; // write line function |
| 412 | 392 | write8_device_func writedevice; // write device function |
| 413 | | write8_space_func writespace; // write space function |
| 414 | 393 | }; |
| 415 | 394 | |
| 416 | 395 | |
| r29304 | r29305 | |
| 442 | 421 | // internal helpers |
| 443 | 422 | void to_null(offs_t offset, UINT8 data, UINT8 mem_mask); |
| 444 | 423 | void to_port(offs_t offset, UINT8 data, UINT8 mem_mask); |
| 445 | | void to_write8space(offs_t offset, UINT8 data, UINT8 mem_mask); |
| 446 | 424 | void to_write8device(offs_t offset, UINT8 data, UINT8 mem_mask); |
| 447 | 425 | void to_writeline(offs_t offset, UINT8 data, UINT8 mem_mask); |
| 448 | 426 | void to_input(offs_t offset, UINT8 data, UINT8 mem_mask); |
| r29304 | r29305 | |
| 466 | 444 | const char * name; // name of the target function |
| 467 | 445 | read_line_device_func readline; // read line function |
| 468 | 446 | read16_device_func readdevice; // read device function |
| 469 | | read16_space_func readspace; // read space function |
| 470 | 447 | }; |
| 471 | 448 | |
| 472 | 449 | |
| r29304 | r29305 | |
| 520 | 497 | const char * name; // name of the target function |
| 521 | 498 | write_line_device_func writeline; // write line function |
| 522 | 499 | write16_device_func writedevice; // write device function |
| 523 | | write16_space_func writespace; // write space function |
| 524 | 500 | }; |
| 525 | 501 | |
| 526 | 502 | |
| r29304 | r29305 | |
| 574 | 550 | const char * name; // name of the target function |
| 575 | 551 | read_line_device_func readline; // read line function |
| 576 | 552 | read32_device_func readdevice; // read device function |
| 577 | | read32_space_func readspace; // read space function |
| 578 | 553 | }; |
| 579 | 554 | |
| 580 | 555 | |
| r29304 | r29305 | |
| 628 | 603 | const char * name; // name of the target function |
| 629 | 604 | write_line_device_func writeline; // write line function |
| 630 | 605 | write32_device_func writedevice; // write device function |
| 631 | | write32_space_func writespace; // write space function |
| 632 | 606 | }; |
| 633 | 607 | |
| 634 | 608 | |
| r29304 | r29305 | |
| 682 | 656 | const char * name; // name of the target function |
| 683 | 657 | read_line_device_func readline; // read line function |
| 684 | 658 | read64_device_func readdevice; // read device function |
| 685 | | read64_space_func readspace; // read space function |
| 686 | 659 | }; |
| 687 | 660 | |
| 688 | 661 | |
| r29304 | r29305 | |
| 736 | 709 | const char * name; // name of the target function |
| 737 | 710 | write_line_device_func writeline; // write line function |
| 738 | 711 | write64_device_func writedevice; // write device function |
| 739 | | write64_space_func writespace; // write space function |
| 740 | 712 | }; |
| 741 | 713 | |
| 742 | 714 | |