Skip to content

Commit

Permalink
Added sound support, small fix related do DMA IRQs, implement Open Bu…
Browse files Browse the repository at this point in the history
…s reads
  • Loading branch information
gdkchan committed Jan 17, 2017
1 parent 42373de commit 790ac57
Show file tree
Hide file tree
Showing 14 changed files with 872 additions and 143 deletions.
13 changes: 7 additions & 6 deletions arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static void arm_bank_to_regs(int8_t mode) {
arm_r.r[14] = arm_r.r14_fiq;
break;

case ARM_IRQ:
case ARM_IRQ:
arm_r.r[13] = arm_r.r13_irq;
arm_r.r[14] = arm_r.r14_irq;
break;
Expand Down Expand Up @@ -100,7 +100,7 @@ static void arm_regs_to_bank(int8_t mode) {
arm_r.r14_fiq = arm_r.r[14];
break;

case ARM_IRQ:
case ARM_IRQ:
arm_r.r13_irq = arm_r.r[13];
arm_r.r14_irq = arm_r.r[14];
break;
Expand Down Expand Up @@ -1365,7 +1365,7 @@ static void arm_memio_stm(arm_memio_t op) {

if (first) {
arm_r.r[op.rn] += op.disp;

first = false;
}

Expand Down Expand Up @@ -3167,7 +3167,8 @@ static void arm_step() {

void arm_exec(uint32_t target_cycles) {
if (int_halt) {
tick_timers(target_cycles);
timers_clock(target_cycles);

return;
}

Expand All @@ -3182,9 +3183,9 @@ void arm_exec(uint32_t target_cycles) {
else
arm_step();

if (tmr_enb) tick_timers(arm_cycles - cycles);

if (int_halt) arm_cycles = target_cycles;

if (tmr_enb) timers_clock(arm_cycles - cycles);
}

arm_cycles -= target_cycles;
Expand Down
67 changes: 38 additions & 29 deletions arm_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,40 +135,49 @@ static uint8_t arm_read_(uint32_t address) {
return 0;
}

static uint8_t arm_readb(uint32_t address) {
return arm_read_(address);
#define IS_OPEN_BUS(a) (((a) >> 28) || ((a) >= 0x00004000 && (a) < 0x02000000))

uint8_t arm_readb(uint32_t address) {
if (IS_OPEN_BUS(address))
return arm_read_(arm_r.r[15]);
else
return arm_read_(address);
}

static uint32_t arm_readh(uint32_t address) {
if (address < 0x4000 && arm_r.r[15] >= 0x4000) {
return bios_op;
} else {
uint32_t a = address & ~1;
uint8_t s = address & 1;
uint32_t arm_readh(uint32_t address) {
if (address < 0x4000 && arm_r.r[15] >= 0x4000)
return bios_op & 0xffff;

uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8;
if (IS_OPEN_BUS(address))
return arm_pipe[1] & 0xffff;

return ROR(value, s << 3);
}
uint32_t a = address & ~1;
uint8_t s = address & 1;

uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8;

return ROR(value, s << 3);
}

static uint32_t arm_read(uint32_t address) {
if (address < 0x4000 && arm_r.r[15] >= 0x4000) {
uint32_t arm_read(uint32_t address) {
if (address < 0x4000 && arm_r.r[15] >= 0x4000)
return bios_op;
} else {
uint32_t a = address & ~3;
uint8_t s = address & 3;

uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8 |
arm_read_(a | 2) << 16 |
arm_read_(a | 3) << 24;
if (IS_OPEN_BUS(address))
return arm_pipe[1];

return ROR(value, s << 3);
}
uint32_t a = address & ~3;
uint8_t s = address & 3;

uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8 |
arm_read_(a | 2) << 16 |
arm_read_(a | 3) << 24;

return ROR(value, s << 3);
}

uint8_t arm_readb_n(uint32_t address) {
Expand Down Expand Up @@ -299,14 +308,14 @@ static void arm_write_(uint32_t address, uint8_t value) {
eeprom_write = true;
//TODO
break;

case 0xe:
case 0xf:
flash_write(address, value); break;
}
}

static void arm_writeb(uint32_t address, uint8_t value) {
void arm_writeb(uint32_t address, uint8_t value) {
uint8_t ah = address >> 24;

if (ah == 7) return; //OAM doesn't supposrt 8 bits writes
Expand All @@ -319,14 +328,14 @@ static void arm_writeb(uint32_t address, uint8_t value) {
}
}

static void arm_writeh(uint32_t address, uint16_t value) {
void arm_writeh(uint32_t address, uint16_t value) {
uint32_t a = address & ~1;

arm_write_(a | 0, (uint8_t)(value >> 0));
arm_write_(a | 1, (uint8_t)(value >> 8));
}

static void arm_write(uint32_t address, uint32_t value) {
void arm_write(uint32_t address, uint32_t value) {
uint32_t a = address & ~3;

arm_write_(a | 0, (uint8_t)(value >> 0));
Expand Down
6 changes: 6 additions & 0 deletions arm_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ typedef enum {

void arm_access_bus(uint32_t address, uint8_t size, access_type_e at);

uint8_t arm_readb(uint32_t address);
uint32_t arm_readh(uint32_t address);
uint32_t arm_read(uint32_t address);
uint8_t arm_readb_n(uint32_t address);
uint32_t arm_readh_n(uint32_t address);
uint32_t arm_read_n(uint32_t address);
uint8_t arm_readb_s(uint32_t address);
uint32_t arm_readh_s(uint32_t address);
uint32_t arm_read_s(uint32_t address);

void arm_writeb(uint32_t address, uint8_t value);
void arm_writeh(uint32_t address, uint16_t value);
void arm_write(uint32_t address, uint32_t value);
void arm_writeb_n(uint32_t address, uint8_t value);
void arm_writeh_n(uint32_t address, uint16_t value);
void arm_write_n(uint32_t address, uint32_t value);
Expand Down
47 changes: 31 additions & 16 deletions dma.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include <stdio.h>

#include "arm.h"
#include "arm_mem.h"

#include "dma.h"
#include "io.h"
#include "sound.h"

//TODO: Timing - DMA should take some amount of cycles

void dma_transfer(dma_timing_e timing) {
uint8_t ch;
Expand Down Expand Up @@ -35,29 +36,18 @@ void dma_transfer(dma_timing_e timing) {
case 1: src_inc = -unit_size; break;
}

if (timing == SPECIAL) {
dma_count[ch] = 4;
dst_inc = 0;
}

if (dma_src_addr[ch] & dma_dst_addr[ch] & 0x08000000)
arm_cycles += 4;
else
arm_cycles += 2;

while (dma_count[ch]--) {
if (dma_ch[ch].ctrl.w & DMA_32)
arm_write_s(dma_dst_addr[ch], arm_read_s(dma_src_addr[ch]));
arm_write(dma_dst_addr[ch], arm_read(dma_src_addr[ch]));
else
arm_writeh_s(dma_dst_addr[ch], arm_readh_s(dma_src_addr[ch]));
arm_writeh(dma_dst_addr[ch], arm_readh(dma_src_addr[ch]));

dma_dst_addr[ch] += dst_inc;
dma_src_addr[ch] += src_inc;
}

if (dma_ch[ch].ctrl.w & DMA_IRQ) {
if (dma_ch[ch].ctrl.w & DMA_IRQ)
trigger_irq(DMA0_FLAG << ch);
}

if (dma_ch[ch].ctrl.w & DMA_REP) {
dma_count[ch] = dma_ch[ch].count.w;
Expand All @@ -71,4 +61,29 @@ void dma_transfer(dma_timing_e timing) {

dma_ch[ch].ctrl.w &= ~DMA_ENB;
}
}

void dma_transfer_fifo(uint8_t ch) {
if (!(dma_ch[ch].ctrl.w & DMA_ENB) ||
((dma_ch[ch].ctrl.w >> 12) & 3) != SPECIAL)
return;

uint8_t i;

for (i = 0; i < 4; i++) {
arm_write(dma_dst_addr[ch], arm_read(dma_src_addr[ch]));

if (ch == 1)
fifo_a_copy();
else
fifo_b_copy();

switch ((dma_ch[ch].ctrl.w >> 7) & 3) {
case 0: dma_src_addr[ch] += 4; break;
case 1: dma_src_addr[ch] -= 4; break;
}
}

if (dma_ch[ch].ctrl.w & DMA_IRQ)
trigger_irq(DMA0_FLAG << ch);
}
3 changes: 2 additions & 1 deletion dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ uint32_t dma_dst_addr[4];

uint32_t dma_count[4];

void dma_transfer(dma_timing_e timing);
void dma_transfer(dma_timing_e timing);
void dma_transfer_fifo(uint8_t ch);
Loading

0 comments on commit 790ac57

Please sign in to comment.