src/mame/drivers/megadriv.c
| r9406 | r9407 | |
| 343 | 343 | /* SegaCD! */ |
| 344 | 344 | static cpu_device *_segacd_68k_cpu; |
| 345 | 345 | static emu_timer *segacd_gfx_conversion_timer; |
| 346 | static emu_timer *segacd_dmna_ret_timer; |
| 346 | 347 | static emu_timer *segacd_irq3_timer; |
| 347 | 348 | static int segacd_wordram_mapped = 0; |
| 348 | 349 | static TIMER_CALLBACK( segacd_irq3_timer_callback ); |
| r9406 | r9407 | |
| 3919 | 3920 | // so probably don't change instantly... |
| 3920 | 3921 | // |
| 3921 | 3922 | |
| 3923 | int segacd_dmna = 0; |
| 3924 | int segacd_ret = 0; |
| 3925 | |
| 3926 | static TIMER_CALLBACK( segacd_dmna_ret_timer_callback ) |
| 3927 | { |
| 3928 | |
| 3929 | // this is the initial state, and the state after changing modes? |
| 3930 | if ((segacd_dmna==0) && (segacd_ret ==0)) |
| 3931 | { |
| 3932 | //printf("aaa %d %d\n", segacd_dmna, segacd_ret); |
| 3933 | segacd_dmna = 0; |
| 3934 | segacd_ret = 1; |
| 3935 | //printf("bbb %d %d\n", segacd_dmna, segacd_ret); |
| 3936 | } |
| 3937 | else if ((segacd_dmna==1) && (segacd_ret == 1)) |
| 3938 | { |
| 3939 | //printf("aaa %d %d\n", segacd_dmna, segacd_ret); |
| 3940 | segacd_dmna = 1; |
| 3941 | segacd_ret = 0; |
| 3942 | //printf("bbb %d %d\n", segacd_dmna, segacd_ret); |
| 3943 | } |
| 3944 | else if ((segacd_dmna==1) && (segacd_ret == 0)) |
| 3945 | { |
| 3946 | //printf("aaa %d %d\n", segacd_dmna, segacd_ret); |
| 3947 | segacd_dmna = 0; |
| 3948 | segacd_ret = 1; |
| 3949 | //printf("bbb %d %d\n", segacd_dmna, segacd_ret); |
| 3950 | } |
| 3951 | else |
| 3952 | { |
| 3953 | printf("huh? %d %d\n", segacd_dmna, segacd_ret); |
| 3954 | } |
| 3955 | } |
| 3956 | |
| 3957 | |
| 3922 | 3958 | static UINT8 segacd_ram_writeprotect_bits; |
| 3923 | 3959 | static int segacd_ram_mode; |
| 3960 | static int segacd_ram_mode_old; |
| 3924 | 3961 | |
| 3925 | | static int segacd_maincpu_has_ram_access = 0; |
| 3962 | //static int segacd_maincpu_has_ram_access = 0; |
| 3926 | 3963 | static int segacd_4meg_prgbank = 0; // which bank the MainCPU can see of the SubCPU PrgRAM |
| 3927 | 3964 | static int segacd_memory_priority_mode = 0; |
| 3928 | 3965 | static int segacd_stampsize; |
| r9406 | r9407 | |
| 3933 | 3970 | return (segacd_ram_writeprotect_bits << 8) | |
| 3934 | 3971 | (segacd_4meg_prgbank << 6) | |
| 3935 | 3972 | (segacd_ram_mode << 2) | |
| 3936 | | ((segacd_maincpu_has_ram_access^1) << 1) | |
| 3937 | | ((segacd_maincpu_has_ram_access) << 0); |
| 3973 | ((segacd_dmna) << 1) | |
| 3974 | ((segacd_ret) << 0); |
| 3938 | 3975 | } |
| 3939 | 3976 | |
| 3940 | 3977 | |
| 3941 | 3978 | /* I'm still not 100% clear how this works, the sources I have are a bit vague, |
| 3942 | 3979 | it might still be incorrect in both modes |
| 3980 | |
| 3981 | for a simple way to swap blocks of ram between cpus this is stupidly convoluted |
| 3982 | |
| 3943 | 3983 | */ |
| 3944 | 3984 | |
| 3945 | 3985 | // DMNA = Decleration Mainram No Access (bit 0) |
| r9406 | r9407 | |
| 3983 | 4023 | //printf("dmna set (swap requested)\n"); // give ram to sub? |
| 3984 | 4024 | |
| 3985 | 4025 | // this should take some time? |
| 3986 | | segacd_maincpu_has_ram_access = 0; |
| 4026 | |
| 4027 | //segacd_ret = 1; |
| 4028 | |
| 4029 | //printf("main cpu dmna set dmna: %d ret: %d\n", segacd_dmna, segacd_ret); |
| 4030 | if (segacd_ram_mode==0) |
| 4031 | { |
| 4032 | if (!timer_enabled(segacd_dmna_ret_timer)) |
| 4033 | { |
| 4034 | if (!segacd_dmna) |
| 4035 | { |
| 4036 | //printf("main dmna\n"); |
| 4037 | segacd_dmna = 1; |
| 4038 | timer_adjust_oneshot(segacd_dmna_ret_timer, ATTOTIME_IN_USEC(100), 0); |
| 4039 | } |
| 4040 | } |
| 4041 | } |
| 4042 | else |
| 4043 | { |
| 4044 | printf("dmna bit in mode 1\n"); |
| 4045 | } |
| 3987 | 4046 | } |
| 3988 | 4047 | |
| 3989 | 4048 | |
| r9406 | r9407 | |
| 4018 | 4077 | /*(segacd_4meg_prgbank << 6) | */ |
| 4019 | 4078 | (segacd_memory_priority_mode << 3) | |
| 4020 | 4079 | (segacd_ram_mode << 2) | |
| 4021 | | ((segacd_maincpu_has_ram_access^1) << 1) | |
| 4022 | | ((segacd_maincpu_has_ram_access) << 0); |
| 4080 | ((segacd_dmna) << 1) | |
| 4081 | ((segacd_ret) << 0); |
| 4023 | 4082 | } |
| 4024 | 4083 | |
| 4025 | 4084 | static WRITE16_HANDLER( segacd_sub_memory_mode_w ) |
| r9406 | r9407 | |
| 4031 | 4090 | if (data&0x0001) |
| 4032 | 4091 | { |
| 4033 | 4092 | //printf("ret bit set\n"); |
| 4034 | | segacd_maincpu_has_ram_access = 1; |
| 4093 | //segacd_dmna = 0; |
| 4094 | |
| 4095 | |
| 4096 | //printf("sub cpu ret set dmna: %d ret: %d\n", segacd_dmna, segacd_ret); |
| 4097 | |
| 4098 | if (segacd_ram_mode==0) |
| 4099 | { |
| 4100 | if (!timer_enabled(segacd_dmna_ret_timer)) |
| 4101 | { |
| 4102 | if (segacd_dmna) |
| 4103 | { |
| 4104 | // printf("sub ret\n"); |
| 4105 | // segacd_ret = 1; |
| 4106 | // segacd_dmna = 0; |
| 4107 | timer_adjust_oneshot(segacd_dmna_ret_timer, ATTOTIME_IN_USEC(100), 0); |
| 4108 | } |
| 4109 | } |
| 4110 | } |
| 4111 | else |
| 4112 | { |
| 4113 | // in mode 1 this changes the word ram 1 to main cpu and word ram 0 to sub cpu? |
| 4114 | // but should be proceeded by a dmna request? is this only valid if dmna has been |
| 4115 | // set to 1 by the main CPU first? |
| 4116 | printf("ret bit in mode 1\n"); |
| 4117 | segacd_ret = 1; |
| 4118 | } |
| 4035 | 4119 | } |
| 4120 | else |
| 4121 | { |
| 4122 | // in mode 1 this changes the word ram 0 to main cpu and word ram 1 to sub cpu? |
| 4123 | // but should be proceeded by a dmna request? is this only valid if dmna has been |
| 4124 | // set to 1 by the main CPU first? |
| 4125 | if (segacd_ram_mode==1) |
| 4126 | { |
| 4127 | segacd_ret = 0; |
| 4128 | } |
| 4129 | } |
| 4036 | 4130 | |
| 4037 | 4131 | |
| 4038 | 4132 | //if (data&0x0002) printf("dmna set (swap requested) (invalid, can't be set from sub68k?\n"); |
| r9406 | r9407 | |
| 4040 | 4134 | //if (data&0x0004) |
| 4041 | 4135 | { |
| 4042 | 4136 | segacd_ram_mode = (data&0x0004)>>2; |
| 4043 | | //printf("mode set %d\n", segacd_ram_mode); |
| 4137 | if (segacd_ram_mode!=segacd_ram_mode_old) |
| 4138 | { |
| 4139 | printf("mode set %d\n", segacd_ram_mode); |
| 4140 | segacd_ram_mode_old = segacd_ram_mode; |
| 4141 | |
| 4142 | if (segacd_ram_mode==0) |
| 4143 | { |
| 4144 | // reset it flags etc.? |
| 4145 | segacd_ret = 0; |
| 4146 | segacd_dmna = 0; |
| 4147 | timer_adjust_oneshot(segacd_dmna_ret_timer, ATTOTIME_IN_USEC(100), 0); |
| 4148 | } |
| 4149 | else |
| 4150 | { |
| 4151 | segacd_ret = 0; |
| 4152 | segacd_dmna = 0; |
| 4153 | |
| 4154 | |
| 4155 | } |
| 4156 | } |
| 4044 | 4157 | } |
| 4045 | 4158 | |
| 4046 | 4159 | //if (data&0x0018) |
| r9406 | r9407 | |
| 4300 | 4413 | if (segacd_ram_mode==0) |
| 4301 | 4414 | { |
| 4302 | 4415 | // is this correct? |
| 4303 | | if (segacd_maincpu_has_ram_access) |
| 4416 | if (!segacd_dmna) |
| 4304 | 4417 | { |
| 4305 | 4418 | //printf("segacd_main_dataram_part1_r in mode 0 %08x %04x\n", offset*2, segacd_dataram[offset]); |
| 4306 | 4419 | |
| 4307 | 4420 | return segacd_dataram[offset]; |
| 4308 | 4421 | |
| 4309 | 4422 | } |
| 4423 | /* |
| 4310 | 4424 | else |
| 4311 | 4425 | { |
| 4312 | 4426 | printf("Illegal: segacd_main_dataram_part1_r in mode 0 without permission\n"); |
| 4313 | 4427 | return 0xffff; |
| 4314 | 4428 | } |
| 4429 | */ |
| 4315 | 4430 | } |
| 4316 | 4431 | else if (segacd_ram_mode==1) |
| 4317 | 4432 | { |
| r9406 | r9407 | |
| 4337 | 4452 | if (segacd_ram_mode==0) |
| 4338 | 4453 | { |
| 4339 | 4454 | // is this correct? |
| 4340 | | if (segacd_maincpu_has_ram_access) |
| 4455 | if (!segacd_dmna) |
| 4341 | 4456 | { |
| 4342 | 4457 | COMBINE_DATA(&segacd_dataram[offset]); |
| 4343 | 4458 | segacd_mark_tiles_dirty(space->machine, offset); |
| 4344 | 4459 | } |
| 4460 | /* |
| 4345 | 4461 | else |
| 4346 | 4462 | { |
| 4347 | 4463 | printf("Illegal: segacd_main_dataram_part1_w in mode 0 without permission\n"); |
| 4348 | 4464 | } |
| 4465 | */ |
| 4349 | 4466 | } |
| 4350 | 4467 | else if (segacd_ram_mode==1) |
| 4351 | 4468 | { |
| r9406 | r9407 | |
| 4902 | 5019 | segacd_gfx_conversion_timer = timer_alloc(machine, segacd_gfx_conversion_timer_callback, 0); |
| 4903 | 5020 | timer_adjust_oneshot(segacd_gfx_conversion_timer, attotime_never, 0); |
| 4904 | 5021 | |
| 5022 | segacd_dmna_ret_timer = timer_alloc(machine, segacd_dmna_ret_timer_callback, 0); |
| 5023 | timer_adjust_oneshot(segacd_gfx_conversion_timer, attotime_never, 0); |
| 5024 | |
| 5025 | |
| 4905 | 5026 | segacd_irq3_timer = timer_alloc(machine, segacd_irq3_timer_callback, 0); |
| 4906 | 5027 | timer_adjust_oneshot(segacd_irq3_timer, attotime_never, 0); |
| 4907 | 5028 | |
| r9406 | r9407 | |
| 4975 | 5096 | } |
| 4976 | 5097 | } |
| 4977 | 5098 | #endif |
| 5099 | |
| 5100 | segacd_dmna = 0; |
| 5101 | segacd_ret = 0; |
| 5102 | |
| 5103 | segacd_ram_mode = 0; |
| 5104 | segacd_ram_mode_old = 0; |
| 5105 | |
| 5106 | timer_adjust_oneshot(segacd_dmna_ret_timer, attotime_zero, 0); |
| 4978 | 5107 | } |
| 4979 | 5108 | |
| 4980 | 5109 | |
| r9406 | r9407 | |
| 5027 | 5156 | if (segacd_ram_mode==0) |
| 5028 | 5157 | { |
| 5029 | 5158 | // is this correct? |
| 5030 | | if (!segacd_maincpu_has_ram_access) |
| 5159 | if (segacd_dmna) |
| 5031 | 5160 | return segacd_dataram[offset]; |
| 5032 | 5161 | else |
| 5033 | 5162 | { |
| r9406 | r9407 | |
| 5049 | 5178 | if (segacd_ram_mode==0) |
| 5050 | 5179 | { |
| 5051 | 5180 | // is this correct? |
| 5052 | | if (!segacd_maincpu_has_ram_access) |
| 5181 | if (segacd_dmna) |
| 5053 | 5182 | { |
| 5054 | 5183 | COMBINE_DATA(&segacd_dataram[offset]); |
| 5055 | 5184 | segacd_mark_tiles_dirty(space->machine, offset); |
| r9406 | r9407 | |
| 5450 | 5579 | segacd_conversion_active = 1; |
| 5451 | 5580 | |
| 5452 | 5581 | // todo: proper time calculation |
| 5453 | | timer_adjust_oneshot(segacd_gfx_conversion_timer, ATTOTIME_IN_HZ(1000), 0); |
| 5582 | timer_adjust_oneshot(segacd_gfx_conversion_timer, ATTOTIME_IN_HZ(500), 0); |
| 5454 | 5583 | |
| 5455 | 5584 | |
| 5456 | 5585 | int line; |