Minor DMA cleanup

This commit is contained in:
David Guillen Fandos 2021-08-21 18:10:12 +02:00
parent 86b365f065
commit a3377c2ac1
5 changed files with 35 additions and 17 deletions

View file

@ -143,6 +143,9 @@ typedef u32 fixed8_24;
#define read_ioreg(regnum) (eswap16(io_registers[(regnum)])) #define read_ioreg(regnum) (eswap16(io_registers[(regnum)]))
#define write_ioreg(regnum, val) io_registers[(regnum)] = eswap16(val) #define write_ioreg(regnum, val) io_registers[(regnum)] = eswap16(val)
#define read_dmareg(regnum, dmachan) (eswap16(io_registers[(regnum) + (dmachan) * 6]))
#define write_dmareg(regnum, dmachan, val) io_registers[(regnum) + (dmachan) * 6] = eswap16(val)
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>

View file

@ -666,13 +666,14 @@ static cpu_alert_type trigger_dma(u32 dma_number, u32 value)
if(dma[dma_number].start_type == DMA_INACTIVE) if(dma[dma_number].start_type == DMA_INACTIVE)
{ {
dma_start_type start_type = (dma_start_type)((value >> 12) & 0x03); dma_start_type start_type = (dma_start_type)((value >> 12) & 0x03);
u32 dest_address = readaddress32(io_registers, (dma_number * 12) + 0xB4) & u32 src_address = 0xFFFFFFF & (read_dmareg(REG_DMA0SAD, dma_number) |
0xFFFFFFF; (read_dmareg(REG_DMA0SAD + 1, dma_number) << 16));
u32 dst_address = 0xFFFFFFF & (read_dmareg(REG_DMA0DAD, dma_number) |
(read_dmareg(REG_DMA0DAD + 1, dma_number) << 16));
dma[dma_number].dma_channel = dma_number; dma[dma_number].dma_channel = dma_number;
dma[dma_number].source_address = dma[dma_number].source_address = src_address;
readaddress32(io_registers, (dma_number * 12) + 0xB0) & 0xFFFFFFF; dma[dma_number].dest_address = dst_address;
dma[dma_number].dest_address = dest_address;
dma[dma_number].source_direction = (dma_increment_type)((value >> 7) & 3); dma[dma_number].source_direction = (dma_increment_type)((value >> 7) & 3);
dma[dma_number].repeat_type = (dma_repeat_type)((value >> 9) & 0x01); dma[dma_number].repeat_type = (dma_repeat_type)((value >> 9) & 0x01);
dma[dma_number].start_type = start_type; dma[dma_number].start_type = start_type;
@ -685,16 +686,16 @@ static cpu_alert_type trigger_dma(u32 dma_number, u32 value)
dma[dma_number].length_type = DMA_32BIT; dma[dma_number].length_type = DMA_32BIT;
dma[dma_number].length = 4; dma[dma_number].length = 4;
dma[dma_number].dest_direction = DMA_FIXED; dma[dma_number].dest_direction = DMA_FIXED;
if(dest_address == 0x40000A4) if(dst_address == 0x40000A4)
dma[dma_number].direct_sound_channel = DMA_DIRECT_SOUND_B; dma[dma_number].direct_sound_channel = DMA_DIRECT_SOUND_B;
else else
dma[dma_number].direct_sound_channel = DMA_DIRECT_SOUND_A; dma[dma_number].direct_sound_channel = DMA_DIRECT_SOUND_A;
} }
else else
{ {
u32 length = read_ioreg(REG_DMA0CNT_L + (dma_number * 6)); u32 length = read_dmareg(REG_DMA0CNT_L, dma_number);
if((dma_number == 3) && ((dest_address >> 24) == 0x0D) && if((dma_number == 3) && ((dst_address >> 24) == 0x0D) &&
((length & 0x1F) == 17)) ((length & 0x1F) == 17))
eeprom_size = EEPROM_8_KBYTE; eeprom_size = EEPROM_8_KBYTE;
@ -714,16 +715,16 @@ static cpu_alert_type trigger_dma(u32 dma_number, u32 value)
dma[dma_number].dest_direction = (dma_increment_type)((value >> 5) & 3); dma[dma_number].dest_direction = (dma_increment_type)((value >> 5) & 3);
} }
write_ioreg(REG_DMA0CNT_H + (dma_number * 6), value); write_dmareg(REG_DMA0CNT_H, dma_number, value);
if(start_type == DMA_START_IMMEDIATELY) if(start_type == DMA_START_IMMEDIATELY)
return dma_transfer(dma + dma_number); return dma_transfer(&dma[dma_number]);
} }
} }
else else
{ {
dma[dma_number].start_type = DMA_INACTIVE; dma[dma_number].start_type = DMA_INACTIVE;
dma[dma_number].direct_sound_channel = DMA_NO_DIRECT_SOUND; dma[dma_number].direct_sound_channel = DMA_NO_DIRECT_SOUND;
write_ioreg(REG_DMA0CNT_H + (dma_number * 6), value); write_dmareg(REG_DMA0CNT_H, dma_number, value);
} }
return CPU_ALERT_NONE; return CPU_ALERT_NONE;
@ -2916,9 +2917,9 @@ cpu_alert_type dma_transfer(dma_transfer_type *dma)
if((dma->repeat_type == DMA_NO_REPEAT) || if((dma->repeat_type == DMA_NO_REPEAT) ||
(dma->start_type == DMA_START_IMMEDIATELY)) (dma->start_type == DMA_START_IMMEDIATELY))
{ {
u32 cntrl = read_dmareg(REG_DMA0CNT_H, dma->dma_channel);
write_dmareg(REG_DMA0CNT_H, dma->dma_channel, cntrl & (~0x8000));
dma->start_type = DMA_INACTIVE; dma->start_type = DMA_INACTIVE;
address16(io_registers, (dma->dma_channel * 12) + 0xBA) =
readaddress16(io_registers, (dma->dma_channel * 12) + 0xBA) & (~0x8000);
} }
if(dma->irq) if(dma->irq)

View file

@ -136,10 +136,24 @@ typedef enum
REG_SOUNDCNT_L = 0x40, REG_SOUNDCNT_L = 0x40,
REG_SOUNDCNT_H = 0x41, REG_SOUNDCNT_H = 0x41,
REG_SOUNDCNT_X = 0x42, REG_SOUNDCNT_X = 0x42,
// DMA control
REG_DMA0SAD = 0x58, REG_DMA0SAD = 0x58,
REG_DMA0DAD = 0x5A, REG_DMA0DAD = 0x5A,
REG_DMA0CNT_L = 0x5C, REG_DMA0CNT_L = 0x5C,
REG_DMA0CNT_H = 0x5D, REG_DMA0CNT_H = 0x5D,
REG_DMA1SAD = 0x5E,
REG_DMA1DAD = 0x60,
REG_DMA1CNT_L = 0x62,
REG_DMA1CNT_H = 0x63,
REG_DMA2SAD = 0x64,
REG_DMA2DAD = 0x66,
REG_DMA2CNT_L = 0x68,
REG_DMA2CNT_H = 0x69,
REG_DMA3SAD = 0x6A,
REG_DMA3DAD = 0x6C,
REG_DMA3CNT_L = 0x6E,
REG_DMA3CNT_H = 0x6F,
// Timers
REG_TM0D = 0x80, REG_TM0D = 0x80,
REG_TM0CNT = 0x81, REG_TM0CNT = 0x81,
REG_TM1D = 0x82, REG_TM1D = 0x82,

4
main.c
View file

@ -156,7 +156,7 @@ u32 update_gba(void)
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
{ {
if(dma[i].start_type == DMA_START_HBLANK) if(dma[i].start_type == DMA_START_HBLANK)
dma_transfer(dma + i); dma_transfer(&dma[i]);
} }
} }
@ -187,7 +187,7 @@ u32 update_gba(void)
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
{ {
if(dma[i].start_type == DMA_START_VBLANK) if(dma[i].start_type == DMA_START_VBLANK)
dma_transfer(dma + i); dma_transfer(&dma[i]);
} }
} }
else else

View file

@ -165,10 +165,10 @@ void sound_timer(fixed8_24 frequency_step, u32 channel)
if(((ds->fifo_top - ds->fifo_base) % 32) <= 16) if(((ds->fifo_top - ds->fifo_base) % 32) <= 16)
{ {
if(dma[1].direct_sound_channel == channel) if(dma[1].direct_sound_channel == channel)
dma_transfer(dma + 1); dma_transfer(&dma[1]);
if(dma[2].direct_sound_channel == channel) if(dma[2].direct_sound_channel == channel)
dma_transfer(dma + 2); dma_transfer(&dma[2]);
} }
} }