Simplify I/O byte writes

Can easily be mapped to 16 bit writes.
This commit is contained in:
David Guillen Fandos 2023-04-21 21:44:34 +02:00
parent 2d28451f6c
commit a53399af58

View file

@ -719,402 +719,12 @@ static cpu_alert_type trigger_dma(u32 dma_number, u32 value)
}
#define access_register8_high(address) \
value = (value << 8) | (address8(io_registers, address)) \
#define access_register8_low(address) \
value = ((address8(io_registers, address + 1)) << 8) | value \
#define access_register16_high(address) \
value = (value << 16) | (readaddress16(io_registers, address)) \
#define access_register16_low(address) \
value = ((readaddress16(io_registers, address + 2)) << 16) | value \
cpu_alert_type function_cc write_io_register8(u32 address, u32 value)
{
value &= 0xff;
switch(address)
{
case 0x00:
{
u32 dispcnt = read_ioreg(REG_DISPCNT);
if((value & 0x07) != (dispcnt & 0x07))
reg[OAM_UPDATED] = 1;
address8(io_registers, 0x00) = value;
break;
}
// DISPSTAT (lower byte)
case 0x04:
address8(io_registers, 0x04) =
(address8(io_registers, 0x04) & 0x07) | (value & ~0x07);
break;
// VCOUNT
case 0x06:
case 0x07:
break;
// BG2 reference X
case 0x28:
access_register8_low(0x28);
access_register16_low(0x28);
affine_reference_x[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x28) = eswap32(value);
break;
case 0x29:
access_register8_high(0x28);
access_register16_low(0x28);
affine_reference_x[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x28) = eswap32(value);
break;
case 0x2A:
access_register8_low(0x2A);
access_register16_high(0x28);
affine_reference_x[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x28) = eswap32(value);
break;
case 0x2B:
access_register8_high(0x2A);
access_register16_high(0x28);
affine_reference_x[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x28) = eswap32(value);
break;
// BG2 reference Y
case 0x2C:
access_register8_low(0x2C);
access_register16_low(0x2C);
affine_reference_y[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x2C) = eswap32(value);
break;
case 0x2D:
access_register8_high(0x2C);
access_register16_low(0x2C);
affine_reference_y[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x2C) = eswap32(value);
break;
case 0x2E:
access_register8_low(0x2E);
access_register16_high(0x2C);
affine_reference_y[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x2C) = eswap32(value);
break;
case 0x2F:
access_register8_high(0x2E);
access_register16_high(0x2C);
affine_reference_y[0] = (s32)(value << 4) >> 4;
address32(io_registers, 0x2C) = eswap32(value);
break;
// BG3 reference X
case 0x38:
access_register8_low(0x38);
access_register16_low(0x38);
affine_reference_x[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x38) = eswap32(value);
break;
case 0x39:
access_register8_high(0x38);
access_register16_low(0x38);
affine_reference_x[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x38) = eswap32(value);
break;
case 0x3A:
access_register8_low(0x3A);
access_register16_high(0x38);
affine_reference_x[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x38) = eswap32(value);
break;
case 0x3B:
access_register8_high(0x3A);
access_register16_high(0x38);
affine_reference_x[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x38) = eswap32(value);
break;
// BG3 reference Y
case 0x3C:
access_register8_low(0x3C);
access_register16_low(0x3C);
affine_reference_y[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x3C) = eswap32(value);
break;
case 0x3D:
access_register8_high(0x3C);
access_register16_low(0x3C);
affine_reference_y[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x3C) = eswap32(value);
break;
case 0x3E:
access_register8_low(0x3E);
access_register16_high(0x3C);
affine_reference_y[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x3C) = eswap32(value);
break;
case 0x3F:
access_register8_high(0x3E);
access_register16_high(0x3C);
affine_reference_y[1] = (s32)(value << 4) >> 4;
address32(io_registers, 0x3C) = eswap32(value);
break;
// Sound 1 control sweep
case 0x60:
gbc_sound_tone_control_sweep();
break;
// Sound 1 control duty/length/envelope
case 0x62:
access_register8_low(0x62);
gbc_sound_tone_control_low(0, REG_SOUND1CNT_H);
break;
case 0x63:
access_register8_high(0x62);
gbc_sound_tone_control_low(0, REG_SOUND1CNT_H);
break;
// Sound 1 control frequency
case 0x64:
access_register8_low(0x64);
gbc_sound_tone_control_high(0, REG_SOUND1CNT_X);
break;
case 0x65:
access_register8_high(0x64);
gbc_sound_tone_control_high(0, REG_SOUND1CNT_X);
break;
// Sound 2 control duty/length/envelope
case 0x68:
access_register8_low(0x68);
gbc_sound_tone_control_low(1, REG_SOUND2CNT_L);
break;
case 0x69:
access_register8_high(0x68);
gbc_sound_tone_control_low(1, REG_SOUND2CNT_L);
break;
// Sound 2 control frequency
case 0x6C:
access_register8_low(0x6C);
gbc_sound_tone_control_high(1, REG_SOUND2CNT_H);
break;
case 0x6D:
access_register8_high(0x6C);
gbc_sound_tone_control_high(1, REG_SOUND2CNT_H);
break;
// Sound 3 control wave
case 0x70:
access_register8_low(0x70);
gbc_sound_wave_control();
break;
case 0x71:
access_register8_high(0x70);
gbc_sound_wave_control();
break;
// Sound 3 control length/volume
case 0x72:
access_register8_low(0x72);
gbc_sound_tone_control_low_wave();
break;
case 0x73:
access_register8_high(0x72);
gbc_sound_tone_control_low_wave();
break;
// Sound 3 control frequency
case 0x74:
access_register8_low(0x74);
gbc_sound_tone_control_high_wave();
break;
case 0x75:
access_register8_high(0x74);
gbc_sound_tone_control_high_wave();
break;
// Sound 4 control length/envelope
case 0x78:
access_register8_low(0x78);
gbc_sound_tone_control_low(3, REG_SOUND4CNT_L);
break;
case 0x79:
access_register8_high(0x78);
gbc_sound_tone_control_low(3, REG_SOUND4CNT_L);
break;
// Sound 4 control frequency
case 0x7C:
access_register8_low(0x7C);
gbc_sound_noise_control();
break;
case 0x7D:
access_register8_high(0x7C);
gbc_sound_noise_control();
break;
// Sound control L
case 0x80:
access_register8_low(0x80);
gbc_trigger_sound(value);
break;
case 0x81:
access_register8_high(0x80);
gbc_trigger_sound(value);
break;
// Sound control H
case 0x82:
access_register8_low(0x82);
trigger_sound();
break;
case 0x83:
access_register8_high(0x82);
trigger_sound();
break;
// Sound control X
case 0x84:
sound_control_x(value);
break;
// Sound wave RAM
case 0x90 ... 0x9F:
gbc_sound_wave_update = 1;
address8(io_registers, address) = value;
break;
// DMA control (trigger byte)
case 0xBB:
access_register8_low(0xBA);
return trigger_dma(0, value);
case 0xC7:
access_register8_low(0xC6);
return trigger_dma(1, value);
case 0xD3:
access_register8_low(0xD2);
return trigger_dma(2, value);
case 0xDF:
access_register8_low(0xDE);
return trigger_dma(3, value);
// Timer counts
case 0x100:
access_register8_low(0x100);
count_timer(0);
break;
case 0x101:
access_register8_high(0x100);
count_timer(0);
break;
case 0x104:
access_register8_low(0x104);
count_timer(1);
break;
case 0x105:
access_register8_high(0x104);
count_timer(1);
break;
case 0x108:
access_register8_low(0x108);
count_timer(2);
break;
case 0x109:
access_register8_high(0x108);
count_timer(2);
break;
case 0x10C:
access_register8_low(0x10C);
count_timer(3);
break;
case 0x10D:
access_register8_high(0x10C);
count_timer(3);
break;
// Timer control (trigger byte)
case 0x103:
access_register8_low(0x102);
trigger_timer(0, value);
break;
case 0x107:
access_register8_low(0x106);
trigger_timer(1, value);
break;
case 0x10B:
access_register8_low(0x10A);
trigger_timer(2, value);
break;
case 0x10F:
access_register8_low(0x10E);
trigger_timer(3, value);
break;
// IF
case 0x202:
address8(io_registers, 0x202) &= ~value;
break;
case 0x203:
address8(io_registers, 0x203) &= ~value;
break;
// Halt
case 0x301:
if((value & 0x01) == 0)
reg[CPU_HALT_STATE] = CPU_HALT;
else
reg[CPU_HALT_STATE] = CPU_STOP;
return CPU_ALERT_HALT;
default:
address8(io_registers, address) = value;
break;
}
return CPU_ALERT_NONE;
}
cpu_alert_type function_cc write_io_register16(u32 address, u32 value)
{
@ -1338,15 +948,6 @@ cpu_alert_type function_cc write_io_register16(u32 address, u32 value)
write_ioreg(REG_IME, value);
return check_interrupt();
// Halt
case 0x300:
if(((value >> 8) & 0x01) == 0)
reg[CPU_HALT_STATE] = CPU_HALT;
else
reg[CPU_HALT_STATE] = CPU_STOP;
return CPU_ALERT_HALT;
default:
address16(io_registers, address) = eswap16(value);
break;
@ -1355,6 +956,24 @@ cpu_alert_type function_cc write_io_register16(u32 address, u32 value)
return CPU_ALERT_NONE;
}
cpu_alert_type function_cc write_io_register8(u32 address, u32 value)
{
if (address == 0x301) {
if (value & 1)
reg[CPU_HALT_STATE] = CPU_STOP;
else
reg[CPU_HALT_STATE] = CPU_HALT;
return CPU_ALERT_HALT;
}
// Partial 16 bit write, treat like a regular merge-write
if (address & 1)
value = (value << 8) | (read_ioreg((address >> 1) & 0x1FF) & 0x00ff);
else
value = (value & 0xff) | (read_ioreg((address >> 1) & 0x1FF) & 0xff00);
return write_io_register16(address & 0x3FE, value);
}
cpu_alert_type function_cc write_io_register32(u32 address, u32 value)
{
// Handle sound FIFO data write