Simplify I/O byte writes
Can easily be mapped to 16 bit writes.
This commit is contained in:
parent
2d28451f6c
commit
a53399af58
1 changed files with 18 additions and 399 deletions
417
gba_memory.c
417
gba_memory.c
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue