void divide_mapper() {
// if CONMEM is set, connect EEPROM (read only if JP2 is closed) and selected RAM bank (read/write)
if (DIVIDE_CONMEM(divide_int_port)) { // map eeprom+ram
if ((divide_memstate != 1) || divide_bank_changed) {
memcpy(PRNM(proc).mem, divide_eeprom, 0x2000);
memcpy(PRNM(proc).mem + 0x2000, divide_ram[DIVIDE_BANK(divide_int_port)], 0x2000);
}
divide_memstate = 1;
divide_bank_changed = 0;
return;
}
// if CONMEM isn't set and MAPRAM is set and:
// 1) if we reached "connecting" entry point, connect RAM #3 bank (read only) and selected RAM bank (if it is 3 it is too read only, else it is writable)
// 2) if we reached "disconnecting" entry point, connect original ZX Speccy ROM
if (DIVIDE_MAPRAM(divide_int_port)) {
// check for mb02 layout
if (!divide_jp2 && (DIVIDE_BANK(divide_int_port) > 1 || divide_memstate == 3)) {
if ((divide_memstate != 3) || divide_bank_changed) {
memcpy(PRNM(proc).mem, divide_ram[DIVIDE_MB02_BANK(divide_int_port)*2], 0x2000);
memcpy(PRNM(proc).mem + 0x2000, divide_ram[DIVIDE_MB02_BANK(divide_int_port)*2+1], 0x2000);
}
divide_memstate = 3;
divide_bank_changed = 0;
return;
}
if (divide_automap) { // map ram3+ram
if ((divide_memstate != 2) || divide_bank_changed) {
memcpy(PRNM(proc).mem, divide_ram[3], 0x2000);
memcpy(PRNM(proc).mem + 0x2000, divide_ram[DIVIDE_BANK(divide_int_port)], 0x2000);
}
divide_memstate = 2;
divide_bank_changed = 0;
} else { // map original_rom
if (divide_memstate) {
memcpy(PRNM(proc).mem, orig_rom, 0x4000);
}
divide_memstate = 0;
divide_bank_changed = 0;
}
return;
}
// if JP2 is closed and:
// 1) if we reached "connecting" entry point, connect EEPROM (read only) and selected RAM bank (read/write)
// 2) if we reached "disconnecting" entry point, connect original ZX Speccy ROM
if (divide_jp2) {
if (divide_automap) { // map eeprom+ram
if ((divide_memstate != 1) || divide_bank_changed) {
memcpy(PRNM(proc).mem, divide_eeprom, 0x2000);
memcpy(PRNM(proc).mem + 0x2000, divide_ram[DIVIDE_BANK(divide_int_port)], 0x2000);
}
divide_memstate = 1;
divide_bank_changed = 0;
} else { // map original_rom
if (divide_memstate) {
memcpy(PRNM(proc).mem, orig_rom, 0x4000);
}
divide_memstate = 0;
divide_bank_changed = 0;
}
return;
}
// else connect original ZX Speccy ROM
if (divide_memstate) { // map original_rom
memcpy(PRNM(proc).mem, orig_rom, 0x4000);
}
divide_memstate = 0;
divide_bank_changed = 0;
}
void divide_put_mem(int addr, byte *ptr, byte val) {
switch (divide_memstate) {
case 0:
// original ZX Speccy ROM - no update memory
break;
case 1:
// EEPROM + selected RAM bank
if (addr<0x2000) {
// is EEPROM writable?
if (divide_jp2) break;
*ptr=val;
// we have to make this change in divide memory too (not really mapped, only copied)
divide_eeprom[addr]=val;
divide_image_changed=1;
break;
}
*ptr=val;
// we have to make this change in divide memory too (not really mapped, only copied)
divide_ram[DIVIDE_BANK(divide_int_port)][addr-0x2000]=val;
break;
case 2:
// RAM #3 bank + selected RAM bank
// if it is 0k-8k page, write is disabled
// if it is 8k-16k page, write is disabled if is selected RAM #3 bank
if (addr<0x2000 || DIVIDE_BANK(divide_int_port)==3) break;
*ptr=val;
// we have to make this change in divide memory too (not really mapped, only copied)
divide_ram[DIVIDE_BANK(divide_int_port)][addr-0x2000]=val;
break;
case 3:
if (!divide_mb02_write_enable) break;
*ptr=val;
if (addr<0x2000)
divide_ram[DIVIDE_MB02_BANK(divide_int_port)*2][addr]=val;
else
divide_ram[DIVIDE_MB02_BANK(divide_int_port)*2+1][addr-0x2000]=val;
break;
default:
// printf("unknown divide state %d\n", divide_memstate);
;
}
}
[свернуть]