From ea086fe33f6ca4ea5485711eb55ae2f2c7b73b94 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 31 Mar 2012 19:14:31 +1100 Subject: [PATCH] Update to v087r12 release. byuu says: Enough to get through the BIOS and into cartridge ROM. I am a bit annoyed that I was basically told that the GBA PPU wasn't that bad. Sprites are a clusterfuck, easily worse than Mode7, docs don't even begin to explain them in enough detail. This is going to be fun. --- bsnes/base/base.hpp | 2 +- bsnes/gba/cpu/cpu.cpp | 197 ++++++++++++++++++--- bsnes/gba/cpu/registers.cpp | 28 ++- bsnes/gba/cpu/registers.hpp | 26 ++- bsnes/gba/memory/memory.cpp | 22 +-- bsnes/gba/ppu/bg.cpp | 2 + bsnes/gba/ppu/mmio.cpp | 57 ++++++ bsnes/gba/ppu/obj.cpp | 25 +++ bsnes/gba/ppu/ppu.cpp | 22 +-- bsnes/gba/ppu/ppu.hpp | 9 +- bsnes/gba/ppu/registers.cpp | 36 ++++ bsnes/gba/ppu/registers.hpp | 24 +++ bsnes/gba/ppu/window.cpp | 2 + bsnes/processor/arm/arm.cpp | 12 ++ bsnes/processor/arm/arm.hpp | 2 + bsnes/processor/arm/disassembler.cpp | 41 +++-- bsnes/processor/arm/instructions-arm.cpp | 81 ++++++--- bsnes/processor/arm/instructions-arm.hpp | 1 + bsnes/processor/arm/instructions-thumb.cpp | 49 ++--- bsnes/processor/arm/registers.cpp | 4 +- bsnes/snes/chip/armdsp/memory.cpp | 25 +-- 21 files changed, 528 insertions(+), 139 deletions(-) create mode 100755 bsnes/gba/ppu/bg.cpp create mode 100755 bsnes/gba/ppu/mmio.cpp create mode 100755 bsnes/gba/ppu/obj.cpp create mode 100755 bsnes/gba/ppu/registers.cpp create mode 100755 bsnes/gba/ppu/registers.hpp create mode 100755 bsnes/gba/ppu/window.cpp diff --git a/bsnes/base/base.hpp b/bsnes/base/base.hpp index 30ff4f74..a6ce8b05 100755 --- a/bsnes/base/base.hpp +++ b/bsnes/base/base.hpp @@ -1,7 +1,7 @@ #ifndef BASE_HPP #define BASE_HPP -static const char Version[] = "087.11"; +static const char Version[] = "087.12"; #include #include diff --git a/bsnes/gba/cpu/cpu.cpp b/bsnes/gba/cpu/cpu.cpp index f9447b66..c1ab471b 100755 --- a/bsnes/gba/cpu/cpu.cpp +++ b/bsnes/gba/cpu/cpu.cpp @@ -18,6 +18,15 @@ void CPU::enter() { } processor.irqline = regs.ime && regs.irq_flag; + + if(regs.mode == Registers::Mode::Halt) { + if((regs.irq_enable & regs.irq_flag) == 0) { + step(1); + continue; + } + regs.mode = Registers::Mode::Normal; + } + exec(); } } @@ -47,35 +56,75 @@ void CPU::power() { for(unsigned n = 0; n < iwram.size; n++) iwram.data[n] = 0; for(unsigned n = 0; n < ewram.size; n++) ewram.data[n] = 0; + regs.dma[0].source = regs.dma[1].source = regs.dma[2].source = regs.dma[3].source = 0; + regs.dma[0].target = regs.dma[1].target = regs.dma[2].target = regs.dma[3].target = 0; + regs.dma[0].length = regs.dma[1].length = regs.dma[2].length = regs.dma[3].length = 0; + regs.dma[0].control = regs.dma[1].control = regs.dma[2].control = regs.dma[3].control = 0; + regs.ime = 0; regs.irq_enable = 0; regs.irq_flag = 0; + regs.postboot = 0; + regs.mode = Registers::Mode::Normal; - bus.mmio[0x130] = this; - bus.mmio[0x200] = this; - bus.mmio[0x202] = this; - bus.mmio[0x208] = this; + for(unsigned n = 0x0b0; n <= 0x0df; n++) bus.mmio[n] = this; + + bus.mmio[0x130] = bus.mmio[0x131] = this; + bus.mmio[0x200] = bus.mmio[0x201] = this; + bus.mmio[0x202] = bus.mmio[0x203] = this; + bus.mmio[0x208] = bus.mmio[0x209] = this; + bus.mmio[0x300] = bus.mmio[0x301] = this; } uint32 CPU::read(uint32 addr, uint32 size) { - uint32 result = 0; + if(size == Word) { + addr &= ~3; + uint32 word = 0; + word |= read(addr + 0, Byte) << 0; + word |= read(addr + 1, Byte) << 8; + word |= read(addr + 2, Byte) << 16; + word |= read(addr + 3, Byte) << 24; + return word; + } - switch(addr & 0x0ffffffc) { + if(size == Half) { + addr &= ~3; + uint32 half = 0; + half |= read(addr + 0, Byte) << 0; + half |= read(addr + 0, Byte) << 8; + return half; + } - case 0x04000130: //KEYINPUT - for(unsigned n = 0; n < 10; n++) result |= (interface->inputPoll(n) == false) << n; + uint8 result = 0; + + switch(addr & 0x0fffffff) { + + //KEYINPUT + case 0x04000130: + for(unsigned n = 0; n < 8; n++) result |= (interface->inputPoll(n) == false) << n; if((result & 0xc0) == 0xc0) result &= ~0xc0; //up+down cannot be pressed simultaneously if((result & 0x30) == 0x30) result &= ~0x30; //left+right cannot be pressed simultaneously return result; + case 0x40000131: + result |= (interface->inputPoll(8) == false) << 0; + result |= (interface->inputPoll(9) == false) << 1; + return result; - case 0x04000200: //IE - return regs.irq_enable; + //IE + case 0x04000200: return regs.irq_enable >> 0; + case 0x04000201: return regs.irq_enable >> 8; - case 0x04000202: //IF - return regs.irq_flag; + //IF + case 0x04000202: return regs.irq_flag >> 0; + case 0x04000203: return regs.irq_flag >> 8; - case 0x04000208: //IME - return regs.ime; + //IME + case 0x04000208: return regs.ime; + case 0x04000209: return 0u; + + //POSTFLG + HALTCNT + case 0x04000300: return regs.postboot; + case 0x04000301: return 0u; } @@ -83,19 +132,121 @@ uint32 CPU::read(uint32 addr, uint32 size) { } void CPU::write(uint32 addr, uint32 size, uint32 word) { - switch(addr & 0x0ffffffc) { - - case 0x04000200: //IE - regs.irq_enable = word; + if(size == Word) { + addr &= ~3; + write(addr + 0, Byte, word >> 0); + write(addr + 1, Byte, word >> 8); + write(addr + 2, Byte, word >> 16); + write(addr + 3, Byte, word >> 24); return; + } - case 0x04000202: //IF - regs.irq_flag = regs.irq_flag & ~word; + if(size == Half) { + addr &= ~1; + write(addr + 0, Byte, word >> 0); + write(addr + 1, Byte, word >> 8); return; + } - case 0x04000208: //IME - regs.ime = word & 1; - return; + uint8 byte = word; + + switch(addr & 0x0fffffff) { + + //DMA0SAD + case 0x040000b0: regs.dma[0].source = (regs.dma[0].source & 0xffffff00) | (byte << 0); return; + case 0x040000b1: regs.dma[0].source = (regs.dma[0].source & 0xffff00ff) | (byte << 8); return; + case 0x040000b2: regs.dma[0].source = (regs.dma[0].source & 0xff00ffff) | (byte << 16); return; + case 0x040000b3: regs.dma[0].source = (regs.dma[0].source & 0x00ffffff) | (byte << 24); return; + + //DMA0DAD + case 0x040000b4: regs.dma[0].target = (regs.dma[0].target & 0xffffff00) | (byte << 0); return; + case 0x040000b5: regs.dma[0].target = (regs.dma[0].target & 0xffff00ff) | (byte << 8); return; + case 0x040000b6: regs.dma[0].target = (regs.dma[0].target & 0xff00ffff) | (byte << 16); return; + case 0x040000b7: regs.dma[0].target = (regs.dma[0].target & 0x00ffffff) | (byte << 24); return; + + //DMA0CNT_L + case 0x040000b8: regs.dma[0].length = (regs.dma[0].length & 0xff00) | (byte << 0); return; + case 0x040000b9: regs.dma[0].length = (regs.dma[0].length & 0x00ff) | (byte << 8); return; + + //DMA0CNT_H + case 0x040000ba: regs.dma[0].control = (regs.dma[0].control & 0xff00) | (byte << 0); return; + case 0x040000bb: regs.dma[0].control = (regs.dma[0].control & 0x00ff) | (byte << 8); return; + + //DMA1SAD + case 0x040000bc: regs.dma[1].source = (regs.dma[1].source & 0xffffff00) | (byte << 0); return; + case 0x040000bd: regs.dma[1].source = (regs.dma[1].source & 0xffff00ff) | (byte << 8); return; + case 0x040000be: regs.dma[1].source = (regs.dma[1].source & 0xff00ffff) | (byte << 16); return; + case 0x040000bf: regs.dma[1].source = (regs.dma[1].source & 0x00ffffff) | (byte << 24); return; + + //DMA1DAD + case 0x040000c0: regs.dma[1].target = (regs.dma[1].target & 0xffffff00) | (byte << 0); return; + case 0x040000c1: regs.dma[1].target = (regs.dma[1].target & 0xffff00ff) | (byte << 8); return; + case 0x040000c2: regs.dma[1].target = (regs.dma[1].target & 0xff00ffff) | (byte << 16); return; + case 0x040000c3: regs.dma[1].target = (regs.dma[1].target & 0x00ffffff) | (byte << 24); return; + + //DMA1CNT_L + case 0x040000c4: regs.dma[1].length = (regs.dma[1].length & 0xff00) | (byte << 0); return; + case 0x040000c5: regs.dma[1].length = (regs.dma[1].length & 0x00ff) | (byte << 8); return; + + //DMA1CNT_H + case 0x040000c6: regs.dma[1].control = (regs.dma[1].control & 0xff00) | (byte << 0); return; + case 0x040000c7: regs.dma[1].control = (regs.dma[1].control & 0x00ff) | (byte << 8); return; + + //DMA2SAD + case 0x040000c8: regs.dma[2].source = (regs.dma[2].source & 0xffffff00) | (byte << 0); return; + case 0x040000c9: regs.dma[2].source = (regs.dma[2].source & 0xffff00ff) | (byte << 8); return; + case 0x040000ca: regs.dma[2].source = (regs.dma[2].source & 0xff00ffff) | (byte << 16); return; + case 0x040000cb: regs.dma[2].source = (regs.dma[2].source & 0x00ffffff) | (byte << 24); return; + + //DMA2DAD + case 0x040000cc: regs.dma[2].target = (regs.dma[2].target & 0xffffff00) | (byte << 0); return; + case 0x040000cd: regs.dma[2].target = (regs.dma[2].target & 0xffff00ff) | (byte << 8); return; + case 0x040000ce: regs.dma[2].target = (regs.dma[2].target & 0xff00ffff) | (byte << 16); return; + case 0x040000cf: regs.dma[2].target = (regs.dma[2].target & 0x00ffffff) | (byte << 24); return; + + //DMA2CNT_L + case 0x040000d0: regs.dma[2].length = (regs.dma[2].length & 0xff00) | (byte << 0); return; + case 0x040000d1: regs.dma[2].length = (regs.dma[2].length & 0x00ff) | (byte << 8); return; + + //DMA2CNT_H + case 0x040000d2: regs.dma[2].control = (regs.dma[2].control & 0xff00) | (byte << 0); return; + case 0x040000d3: regs.dma[2].control = (regs.dma[2].control & 0x00ff) | (byte << 8); return; + + //DMA3SAD + case 0x040000d4: regs.dma[3].source = (regs.dma[3].source & 0xffffff00) | (byte << 0); return; + case 0x040000d5: regs.dma[3].source = (regs.dma[3].source & 0xffff00ff) | (byte << 8); return; + case 0x040000d6: regs.dma[3].source = (regs.dma[3].source & 0xff00ffff) | (byte << 16); return; + case 0x040000d7: regs.dma[3].source = (regs.dma[3].source & 0x00ffffff) | (byte << 24); return; + + //DMA3DAD + case 0x040000d8: regs.dma[3].target = (regs.dma[3].target & 0xffffff00) | (byte << 0); return; + case 0x040000d9: regs.dma[3].target = (regs.dma[3].target & 0xffff00ff) | (byte << 8); return; + case 0x040000da: regs.dma[3].target = (regs.dma[3].target & 0xff00ffff) | (byte << 16); return; + case 0x040000db: regs.dma[3].target = (regs.dma[3].target & 0x00ffffff) | (byte << 24); return; + + //DMA3CNT_L + case 0x040000dc: regs.dma[3].length = (regs.dma[3].length & 0xff00) | (byte << 0); return; + case 0x040000dd: regs.dma[3].length = (regs.dma[3].length & 0x00ff) | (byte << 8); return; + + //DMA3CNT_H + case 0x040000de: regs.dma[3].control = (regs.dma[3].control & 0xff00) | (byte << 0); return; + case 0x040000df: regs.dma[3].control = (regs.dma[3].control & 0x00ff) | (byte << 8); return; + + //IE + case 0x04000200: regs.irq_enable = (regs.irq_enable & 0xff00) | (byte << 0); return; + case 0x04000201: regs.irq_enable = (regs.irq_enable & 0x00ff) | (byte << 8); return; + + //IF + case 0x04000202: regs.irq_flag = regs.irq_flag & ~(byte << 0); return; + case 0x04000203: regs.irq_flag = regs.irq_flag & ~(byte << 8); return; + + //IME + case 0x04000208: regs.ime = byte & 1; return; + case 0x04000209: return; + + //POSTFLG + HALTCNT + case 0x04000300: regs.postboot = byte & 1; return; + case 0x04000301: regs.mode = byte & 0x80 ? Registers::Mode::Stop : Registers::Mode::Halt; return; } } diff --git a/bsnes/gba/cpu/registers.cpp b/bsnes/gba/cpu/registers.cpp index 03e80866..70081ab9 100755 --- a/bsnes/gba/cpu/registers.cpp +++ b/bsnes/gba/cpu/registers.cpp @@ -1,3 +1,28 @@ +CPU::Registers::DMA::Control::operator uint16() const { + return ( + (targetmode << 5) + || (sourcemode << 7) + || (repeat << 9) + || (size << 10) + || (drq << 11) + || (timing << 12) + || (irq << 14) + || (enable << 15) + ); +} + +uint16 CPU::Registers::DMA::Control::operator=(uint16 source) { + targetmode = source >> 5; + sourcemode = source >> 7; + repeat = source >> 9; + size = source >> 10; + drq = source >> 11; + timing = source >> 12; + irq = source >> 14; + enable = source >> 15; + return operator uint16(); +} + CPU::Registers::Interrupt::operator uint16() const { return ( (vblank << 0) @@ -17,7 +42,7 @@ CPU::Registers::Interrupt::operator uint16() const { ); } -CPU::Registers::Interrupt& CPU::Registers::Interrupt::operator=(uint16 source) { +uint16 CPU::Registers::Interrupt::operator=(uint16 source) { vblank = source & (1 << 0); hblank = source & (1 << 1); vcoincidence = source & (1 << 2); @@ -32,4 +57,5 @@ CPU::Registers::Interrupt& CPU::Registers::Interrupt::operator=(uint16 source) { dma3 = source & (1 << 11); keypad = source & (1 << 12); cartridge = source & (1 << 13); + return operator uint16(); } diff --git a/bsnes/gba/cpu/registers.hpp b/bsnes/gba/cpu/registers.hpp index 9666355e..b9de3b16 100755 --- a/bsnes/gba/cpu/registers.hpp +++ b/bsnes/gba/cpu/registers.hpp @@ -1,6 +1,26 @@ struct Registers { bool ime; + struct DMA { + uint32 source; + uint32 target; + uint16 length; + struct Control { + uint2 targetmode; + uint2 sourcemode; + uint1 repeat; + uint1 size; + uint1 drq; + uint2 timing; + uint1 irq; + uint1 enable; + + operator uint16() const; + uint16 operator=(uint16 source); + DMA& operator=(const DMA&) = delete; + } control; + } dma[4]; + struct Interrupt { bool vblank; bool hblank; @@ -18,6 +38,10 @@ struct Registers { bool cartridge; operator uint16() const; - Interrupt& operator=(uint16 source); + uint16 operator=(uint16 source); + Interrupt& operator=(const Interrupt&) = delete; } irq_enable, irq_flag; + + bool postboot; + enum class Mode : unsigned { Normal, Halt, Stop } mode; } regs; diff --git a/bsnes/gba/memory/memory.cpp b/bsnes/gba/memory/memory.cpp index 9aba9b2c..6cb11567 100755 --- a/bsnes/gba/memory/memory.cpp +++ b/bsnes/gba/memory/memory.cpp @@ -12,27 +12,11 @@ struct UnmappedMemory : Memory { static UnmappedMemory unmappedMemory; uint32 StaticMemory::read(uint32 addr, uint32 size) { - uint32 word = 0; - switch(size) { - case Word: - addr &= ~3; - word |= data[addr + 0] << 0; - word |= data[addr + 1] << 8; - word |= data[addr + 2] << 16; - word |= data[addr + 3] << 24; - break; - case Half: - addr &= ~1; - word |= data[addr + 0] << 0; - word |= data[addr + 1] << 8; - break; - case Byte: - word |= data[addr + 0] << 0; - break; + case Word: addr &= ~3; return (data[addr + 0] << 0) | (data[addr + 1] << 8) | (data[addr + 2] << 16) | (data[addr + 3] << 24); + case Half: addr &= ~1; return (data[addr + 0] << 0) | (data[addr + 1] << 8); + case Byte: return (data[addr + 0] << 0); } - - return word; } void StaticMemory::write(uint32 addr, uint32 size, uint32 word) { diff --git a/bsnes/gba/ppu/bg.cpp b/bsnes/gba/ppu/bg.cpp new file mode 100755 index 00000000..982cc80e --- /dev/null +++ b/bsnes/gba/ppu/bg.cpp @@ -0,0 +1,2 @@ +void PPU::render_bg() { +} diff --git a/bsnes/gba/ppu/mmio.cpp b/bsnes/gba/ppu/mmio.cpp new file mode 100755 index 00000000..74338f92 --- /dev/null +++ b/bsnes/gba/ppu/mmio.cpp @@ -0,0 +1,57 @@ +uint32 PPU::read(uint32 addr, uint32 size) { + if(size == Word) { + addr &= ~3; + uint32 word = 0; + word |= read(addr + 0, Byte) << 0; + word |= read(addr + 1, Byte) << 8; + word |= read(addr + 2, Byte) << 16; + word |= read(addr + 3, Byte) << 24; + return word; + } + + if(size == Half) { + addr &= ~3; + uint32 half = 0; + half |= read(addr + 0, Byte) << 0; + half |= read(addr + 0, Byte) << 8; + return half; + } + + switch(addr & 0x0fffffff) { + + //VCOUNT + case 0x04000006: return regs.scanline >> 0; + case 0x04000007: return regs.scanline >> 8; + + } + + return 0u; +} + +void PPU::write(uint32 addr, uint32 size, uint32 word) { + if(size == Word) { + addr &= ~3; + write(addr + 0, Byte, word >> 0); + write(addr + 1, Byte, word >> 8); + write(addr + 2, Byte, word >> 16); + write(addr + 3, Byte, word >> 24); + return; + } + + if(size == Half) { + addr &= ~1; + write(addr + 0, Byte, word >> 0); + write(addr + 1, Byte, word >> 8); + return; + } + + uint8 byte = word; + + switch(addr & 0x0fffffff) { + + //DISPCNT + case 0x04000000: regs.control = (regs.control & 0xff00) | (byte << 0); return; + case 0x04000001: regs.control = (regs.control & 0x00ff) | (byte << 8); return; + + } +} diff --git a/bsnes/gba/ppu/obj.cpp b/bsnes/gba/ppu/obj.cpp new file mode 100755 index 00000000..868b0ba7 --- /dev/null +++ b/bsnes/gba/ppu/obj.cpp @@ -0,0 +1,25 @@ +//BG modes 0,1,2 = 0x10000-0x17fff +//BG modes 3,4,5 = 0x14000-0x17fff + +//OAM = 1024 bytes (128 entries x 64-bits) + +// 0- 7 = y +// 8 = scale +// 9 = scaleflag (0 = single-fold, 1 = double-angle) +//10-11 = mode (0 = normal, 1 = semi-transparent, 2 = obj window, 3 = prohibited) +// 12 = mosaic +// 13 = colormode (0 = 16 colors x 16 palettes, 1 = 256 colors x 1 palette) +//14-15 = shape (0 = square, 1 = horizontal, 2 = vertical, 3 = prohibited) + +//00-08 = x +//09-11 = rotation/scaling parameter +// 12 = hflip +// 13 = vflip +//14-15 = size + +//00-09 = character +//10-11 = priority +//12-15 = palette (16-color mode) + +void PPU::render_obj() { +} diff --git a/bsnes/gba/ppu/ppu.cpp b/bsnes/gba/ppu/ppu.cpp index 500b2fce..52288ee2 100755 --- a/bsnes/gba/ppu/ppu.cpp +++ b/bsnes/gba/ppu/ppu.cpp @@ -12,6 +12,11 @@ namespace GBA { +#include "registers.cpp" +#include "mmio.cpp" +#include "bg.cpp" +#include "obj.cpp" +#include "window.cpp" PPU ppu; void PPU::Enter() { ppu.enter(); } @@ -35,9 +40,10 @@ void PPU::power() { for(unsigned n = 0; n < oam.size; n++) oam.data[n] = 0; for(unsigned n = 0; n < pram.size; n++) pram.data[n] = 0; + regs.control = 0; regs.scanline = 0; - bus.mmio[0x006] = this; + for(unsigned n = 0x000; n <= 0x055; n++) bus.mmio[n] = this; } void PPU::scanline() { @@ -55,6 +61,8 @@ void PPU::scanline() { } if(regs.scanline >= 160) return; + render_bg(); + render_obj(); } void PPU::frame() { @@ -77,18 +85,6 @@ void PPU::frame() { scheduler.exit(Scheduler::ExitReason::FrameEvent); } -uint32 PPU::read(uint32 addr, uint32 size) { - if(addr == 0x04000006) { - //VCOUNT - return regs.scanline; - } - - return 0u; -} - -void PPU::write(uint32 addr, uint32 size, uint32 word) { -} - PPU::PPU() { vram.data = new uint8[vram.size = 96 * 1024]; oam.data = new uint8[oam.size = 1024]; diff --git a/bsnes/gba/ppu/ppu.hpp b/bsnes/gba/ppu/ppu.hpp index c9f3e70f..b1ff840c 100755 --- a/bsnes/gba/ppu/ppu.hpp +++ b/bsnes/gba/ppu/ppu.hpp @@ -2,10 +2,7 @@ struct PPU : Thread, Memory { StaticMemory vram; StaticMemory oam; StaticMemory pram; - - struct Registers { - unsigned scanline; - } regs; + #include "registers.hpp" static void Enter(); void enter(); @@ -18,6 +15,10 @@ struct PPU : Thread, Memory { uint32 read(uint32 addr, uint32 size); void write(uint32 addr, uint32 size, uint32 word); + void render_bg(); + void render_obj(); + void render_window(); + PPU(); }; diff --git a/bsnes/gba/ppu/registers.cpp b/bsnes/gba/ppu/registers.cpp new file mode 100755 index 00000000..7dff719b --- /dev/null +++ b/bsnes/gba/ppu/registers.cpp @@ -0,0 +1,36 @@ +PPU::Registers::Control::operator uint16() const { + return ( + (bgmode << 0) + || (cgbmode << 3) + || (frame << 4) + || (hblank << 5) + || (objmap << 6) + || (forceblank << 7) + || (displaybg0 << 8) + || (displaybg1 << 9) + || (displaybg2 << 10) + || (displaybg3 << 11) + || (displayobj << 12) + || (displaybgwindow0 << 13) + || (displaybgwindow1 << 14) + || (displayobjwindow << 15) + ); +} + +uint16 PPU::Registers::Control::operator=(uint16 source) { + bgmode = source & 0x0007; + cgbmode = source & 0x0008; + frame = source & 0x0010; + hblank = source & 0x0020; + objmap = source & 0x0040; + forceblank = source & 0x0080; + displaybg0 = source & 0x0100; + displaybg1 = source & 0x0200; + displaybg2 = source & 0x0400; + displaybg3 = source & 0x0800; + displayobj = source & 0x1000; + displaybgwindow0 = source & 0x2000; + displaybgwindow1 = source & 0x4000; + displayobjwindow = source & 0x8000; + return operator uint16(); +} diff --git a/bsnes/gba/ppu/registers.hpp b/bsnes/gba/ppu/registers.hpp new file mode 100755 index 00000000..6297da3f --- /dev/null +++ b/bsnes/gba/ppu/registers.hpp @@ -0,0 +1,24 @@ +struct Registers { + struct Control { + uint3 bgmode; + bool cgbmode; + bool frame; + bool hblank; + bool objmap; + bool forceblank; + bool displaybg0; + bool displaybg1; + bool displaybg2; + bool displaybg3; + bool displayobj; + bool displaybgwindow0; + bool displaybgwindow1; + bool displayobjwindow; + + operator uint16() const; + uint16 operator=(uint16 source); + Control& operator=(const Control&) = delete; + } control; + + uint16 scanline; +} regs; diff --git a/bsnes/gba/ppu/window.cpp b/bsnes/gba/ppu/window.cpp new file mode 100755 index 00000000..f97ae99c --- /dev/null +++ b/bsnes/gba/ppu/window.cpp @@ -0,0 +1,2 @@ +void PPU::render_window() { +} diff --git a/bsnes/processor/arm/arm.cpp b/bsnes/processor/arm/arm.cpp index 74ababe5..49844bcd 100755 --- a/bsnes/processor/arm/arm.cpp +++ b/bsnes/processor/arm/arm.cpp @@ -32,6 +32,18 @@ void ARM::exec() { cpsr().t ? thumb_step() : arm_step(); } +uint32 ARM::read(uint32 addr, uint32 size) { + uint32 word = bus_read(addr, size); +//uint32 rotate = (addr & 3) << 3; +//word = (word >> rotate) | (word << (32 - rotate)); +//word = word & (~0u >> (32 - size)); + return word; +} + +void ARM::write(uint32 addr, uint32 size, uint32 word) { + return bus_write(addr, size, word); +} + void ARM::vector(uint32 addr, Processor::Mode mode) { auto psr = cpsr(); processor.setMode(mode); diff --git a/bsnes/processor/arm/arm.hpp b/bsnes/processor/arm/arm.hpp index 98f69b7a..0b2e0e42 100755 --- a/bsnes/processor/arm/arm.hpp +++ b/bsnes/processor/arm/arm.hpp @@ -17,6 +17,8 @@ struct ARM { void power(); void exec(); + uint32 read(uint32 addr, uint32 size); + void write(uint32 addr, uint32 size, uint32 word); void vector(uint32 addr, Processor::Mode mode); bool condition(uint4 condition); diff --git a/bsnes/processor/arm/disassembler.cpp b/bsnes/processor/arm/disassembler.cpp index 9d827686..eaf9a368 100755 --- a/bsnes/processor/arm/disassembler.cpp +++ b/bsnes/processor/arm/disassembler.cpp @@ -32,7 +32,7 @@ string ARM::disassemble_arm_instruction(uint32 pc) { string output{hex<8>(pc), " "}; - uint32 instruction = bus_read(pc, Word); + uint32 instruction = read(pc & ~3, Word); output.append(hex<8>(instruction), " "); //multiply() @@ -45,7 +45,7 @@ string ARM::disassemble_arm_instruction(uint32 pc) { uint4 rd = instruction >> 16; uint4 rn = instruction >> 12; uint4 rs = instruction >> 8; - uint4 rm = instruction >> 0; + uint4 rm = instruction; output.append(accumulate ? "mla" : "mul", conditions[condition], save ? "s " : " "); output.append(registers[rd], ",", registers[rm], ",", registers[rs]); @@ -54,6 +54,25 @@ string ARM::disassemble_arm_instruction(uint32 pc) { return output; } + //multiply_long() + //(u,s)mull{condition}{s} rdlo,rdhi,rm,rs + //(u,s)mlal{condition}{s} rdlo,rdhi,rm,rs + if((instruction & 0x0f8000f0) == 0x00800090) { + uint4 condition = instruction >> 28; + uint1 signextend = instruction >> 22; + uint1 accumulate = instruction >> 21; + uint1 save = instruction >> 20; + uint4 rdhi = instruction >> 16; + uint4 rdlo = instruction >> 12; + uint4 rs = instruction >> 8; + uint4 rm = instruction; + + output.append(signextend ? "s" : "u", accumulate ? "mlal" : "mull", conditions[condition], save ? "s " : " "); + output.append(registers[rdlo], ",", registers[rdhi], ",", registers[rm], ",", registers[rs]); + + return output; + } + //memory_swap() //swp{condition}{b} rd,rm,[rn] if((instruction & 0x0fb000f0) == 0x01000090) { @@ -115,7 +134,7 @@ string ARM::disassemble_arm_instruction(uint32 pc) { if(pre == 1) output.append("]"); if(pre == 0 || writeback == 1) output.append("!"); - if(rn == 15) output.append(" =0x", hex<4>(bus_read(pc + 8 + (up ? +immediate : -immediate), Half))); + if(rn == 15) output.append(" =0x", hex<4>(read(pc + 8 + (up ? +immediate : -immediate), Half))); return output; } @@ -165,8 +184,8 @@ string ARM::disassemble_arm_instruction(uint32 pc) { if(pre == 1) output.append("]"); if(pre == 0 || writeback == 1) output.append("!"); - if(rn == 15 && half == 1) output.append(" =0x", hex<4>(bus_read(pc + 8 + (up ? +immediate : -immediate), Half))); - if(rn == 15 && half == 0) output.append(" =0x", hex<2>(bus_read(pc + 8 + (up ? +immediate : -immediate), Byte))); + if(rn == 15 && half == 1) output.append(" =0x", hex<4>(read(pc + 8 + (up ? +immediate : -immediate), Half))); + if(rn == 15 && half == 0) output.append(" =0x", hex<2>(read(pc + 8 + (up ? +immediate : -immediate), Byte))); return output; } @@ -340,7 +359,7 @@ string ARM::disassemble_arm_instruction(uint32 pc) { if(pre == 1) output.append("]"); if(pre == 0 || writeback == 1) output.append("!"); - if(rn == 15) output.append(" =0x", hex<8>(bus_read(pc + 8 + (up ? +immediate : -immediate), byte ? Byte : Word))); + if(rn == 15) output.append(" =0x", hex<8>(read(pc + 8 + (up ? +immediate : -immediate), byte ? Byte : Word))); return output; } @@ -438,7 +457,7 @@ string ARM::disassemble_thumb_instruction(uint32 pc) { string output{hex<8>(pc), " "}; - uint16 instruction = bus_read(pc, Half); + uint16 instruction = read(pc & ~1, Half); output.append(hex<4>(instruction), " "); //adjust_register() @@ -552,7 +571,7 @@ string ARM::disassemble_thumb_instruction(uint32 pc) { unsigned rm = ((pc + 4) & ~3) + displacement * 4; output.append("ldr ", registers[rd], ",[pc,#0x", hex<3>(rm), "]"); - output.append(" =0x", hex<8>(bus_read(rm, Word))); + output.append(" =0x", hex<8>(read(rm, Word))); return output; } @@ -721,7 +740,7 @@ string ARM::disassemble_thumb_instruction(uint32 pc) { //bl address if((instruction & 0xf800) == 0xf000) { uint11 offsethi = instruction; - instruction = bus_read(pc + 2, Half); + instruction = read((pc & ~1) + 2, Half); uint11 offsetlo = instruction; int22 displacement = (offsethi << 11) | (offsetlo << 0); @@ -747,12 +766,14 @@ string ARM::disassemble_registers() { output.append( "r0:", hex<8>(r( 0)), " r1:", hex<8>(r( 1)), " r2:", hex<8>(r( 2)), " r3:", hex<8>(r( 3)), " "); output.append( "r4:", hex<8>(r( 4)), " r5:", hex<8>(r( 5)), " r6:", hex<8>(r( 6)), " r7:", hex<8>(r( 7)), " "); output.append("cpsr:", cpsr().n ? "N" : "n", cpsr().z ? "Z" : "z", cpsr().c ? "C" : "c", cpsr().v ? "V" : "v"); + output.append("/", cpsr().i ? "I" : "i", cpsr().f ? "F" : "f", cpsr().t ? "T" : "t"); output.append("/", hex<2>(cpsr().m), "\n"); output.append( "r8:", hex<8>(r( 8)), " r9:", hex<8>(r( 9)), " r10:", hex<8>(r(10)), " r11:", hex<8>(r(11)), " "); output.append("r12:", hex<8>(r(12)), " sp:", hex<8>(r(13)), " lr:", hex<8>(r(14)), " pc:", hex<8>(r(15)), " "); output.append("spsr:"); - if(mode() == Processor::Mode::USR || mode() == Processor::Mode::SYS) { output.append("----/--"); return output; } + if(mode() == Processor::Mode::USR || mode() == Processor::Mode::SYS) { output.append("----/---/--"); return output; } output.append( spsr().n ? "N" : "n", spsr().z ? "Z" : "z", spsr().c ? "C" : "c", spsr().v ? "V" : "v"); + output.append("/", spsr().i ? "I" : "i", spsr().f ? "F" : "f", spsr().t ? "T" : "t"); output.append("/", hex<2>(spsr().m)); return output; } diff --git a/bsnes/processor/arm/instructions-arm.cpp b/bsnes/processor/arm/instructions-arm.cpp index bd5c3a1d..ed0e3b3e 100755 --- a/bsnes/processor/arm/instructions-arm.cpp +++ b/bsnes/processor/arm/instructions-arm.cpp @@ -3,9 +3,10 @@ void ARM::arm_step() { if(pipeline.reload) { pipeline.reload = false; + r(15).data &= ~3; pipeline.fetch.address = r(15); - pipeline.fetch.instruction = bus_read(r(15), Word); + pipeline.fetch.instruction = read(r(15), Word); pipeline_step(); step(2); @@ -18,6 +19,7 @@ void ARM::arm_step() { if(trace) { print(disassemble_registers(), "\n"); print(disassemble_arm_instruction(pipeline.execute.address), "\n"); + usleep(100000); } if(condition(instruction() >> 28) == false) return; @@ -29,6 +31,7 @@ void ARM::arm_step() { decode("???? 0001 0010 ++++ ++++ ++++ 0001 ????", branch_exchange_register); decode("???? 0000 00?? ???? ???? ???? 1001 ????", multiply); + decode("???? 0000 1??? ???? ???? ???? 1001 ????", multiply_long); decode("???? 0001 0?00 ++++ ???? ---- 0000 ----", move_to_register_from_status); decode("???? 0001 0?00 ???? ???? ---- 1001 ????", memory_swap); decode("???? 0001 0?10 ???? ++++ ---- 0000 ????", move_to_status_from_register); @@ -122,19 +125,57 @@ void ARM::arm_move_to_status(uint32 rm) { //d = rd //n = rn //s = rs -//n = rm +//m = rm void ARM::arm_op_multiply() { uint1 accumulate = instruction() >> 21; + uint1 save = instruction() >> 20; uint4 d = instruction() >> 16; uint4 n = instruction() >> 12; uint4 s = instruction() >> 8; - uint4 m = instruction() >> 0; + uint4 m = instruction(); r(d) = accumulate ? r(n) : 0u; step(1); r(d) = mul(r(d), r(m), r(s)); } +//(u,s)mull{condition}{s} rdlo,rdhi,rm,rs +//(u,s)mlal{condition}{s} rdlo,rdhi,rm,rs +//cccc 0000 1sas hhhh llll ssss 1001 mmmm +//c = condition +//s = sign-extend +//a = accumulate +//s = save flags +//h = rdhi +//l = rdlo +//s = rs +//m = rm +void ARM::arm_op_multiply_long() { + uint1 signextend = instruction() >> 22; + uint1 accumulate = instruction() >> 21; + uint1 save = instruction() >> 20; + uint4 dhi = instruction() >> 16; + uint4 dlo = instruction() >> 12; + uint4 s = instruction() >> 8; + uint4 m = instruction(); + + uint64 rm = signextend ? r(m) : (int32)r(m); + uint64 rs = signextend ? r(s) : (int32)r(s); + + uint64 rd = rm * rs; + if(accumulate) rd += ((uint64)r(dhi) << 32) + ((uint64)r(dlo) << 0); + + r(dhi) = rd >> 32; + r(dlo) = rd >> 0; + + if(save) { + cpsr().n = r(dhi) >> 31; + cpsr().z = r(dhi) == 0 && r(dlo) == 0; + cpsr().c = 0; + cpsr().v = 0; + } +} + //swp{condition}{b} rd,rm,[rn] //cccc 0001 0b00 nnnn dddd ---- 1001 mmmm //c = condition @@ -148,8 +189,8 @@ void ARM::arm_op_memory_swap() { uint4 d = instruction() >> 12; uint4 m = instruction(); - uint32 word = bus_read(r(n), byte ? Byte : Word); - bus_write(r(n), byte ? Byte : Word, r(m)); + uint32 word = read(r(n), byte ? Byte : Word); + write(r(n), byte ? Byte : Word, r(m)); r(d) = word; } @@ -177,8 +218,8 @@ void ARM::arm_op_move_half_register() { uint32 rm = r(m); if(pre == 1) rn = up ? rn + rm : rn - rm; - if(load == 1) r(d) = bus_read(rn, Half); - if(load == 0) bus_write(rn, Half, r(d)); + if(load == 1) r(d) = read(rn, Half); + if(load == 0) write(rn, Half, r(d)); if(pre == 0) rn = up ? rn + rm : rn - rm; if(pre == 0 || writeback == 1) r(n) = rn; @@ -210,8 +251,8 @@ void ARM::arm_op_move_half_immediate() { uint8 immediate = (ih << 4) + (il << 0); if(pre == 1) rn = up ? rn + immediate : rn - immediate; - if(load == 1) r(d) = bus_read(rn, Half); - if(load == 0) bus_write(rn, Half, r(d)); + if(load == 1) r(d) = read(rn, Half); + if(load == 0) write(rn, Half, r(d)); if(pre == 0) rn = up ? rn + immediate : rn - immediate; if(pre == 0 || writeback == 1) r(n) = rn; @@ -241,7 +282,7 @@ void ARM::arm_op_load_register() { uint32 rm = r(m); if(pre == 1) rn = up ? rn + rm : rn - rm; - uint32 word = bus_read(rn, half ? Half : Byte); + uint32 word = read(rn, half ? Half : Byte); r(d) = half ? (int16)word : (int8)word; if(pre == 0) rn = up ? rn + rm : rn - rm; @@ -274,7 +315,7 @@ void ARM::arm_op_load_immediate() { uint8 immediate = (ih << 4) + (il << 0); if(pre == 1) rn = up ? rn + immediate : rn - immediate; - uint32 word = bus_read(rn, half ? Half : Byte); + uint32 word = read(rn, half ? Half : Byte); r(d) = half ? (int16)word : (int8)word; if(pre == 0) rn = up ? rn + immediate : rn - immediate; @@ -445,11 +486,8 @@ void ARM::arm_op_move_immediate_offset() { auto &rd = r(d); if(pre == 1) rn = up ? rn + rm : rn - rm; - if(load) { - rd = bus_read(rn, byte ? Byte : Word); - } else { - bus_write(rn, byte ? Byte : Word, rd); - } + if(load == 1) rd = read(rn, byte ? Byte : Word); + if(load == 0) write(rn, byte ? Byte : Word, rd); if(pre == 0) rn = up ? rn + rm : rn - rm; if(pre == 0 || writeback == 1) r(n) = rn; @@ -493,11 +531,8 @@ void ARM::arm_op_move_register_offset() { if(mode == 3) rm = rs ? ror(rm, rs) : rrx(rm); if(pre == 1) rn = up ? rn + rm : rn - rm; - if(load) { - rd = bus_read(rn, byte ? Byte : Word); - } else { - bus_write(rn, byte ? Byte : Word, rd); - } + if(load == 1) rd = read(rn, byte ? Byte : Word); + if(load == 0) write(rn, byte ? Byte : Word, rd); if(pre == 0) rn = up ? rn + rm : rn - rm; if(pre == 0 || writeback == 1) r(n) = rn; @@ -537,8 +572,8 @@ void ARM::arm_op_move_multiple() { for(unsigned n = 0; n < 16; n++) { if(list & (1 << n)) { - if(load) r(n) = bus_read(rn, Word); - else bus_write(rn, Word, r(n)); + if(load == 1) r(n) = read(rn, Word); + if(load == 0) write(rn, Word, r(n)); rn += 4; } } diff --git a/bsnes/processor/arm/instructions-arm.hpp b/bsnes/processor/arm/instructions-arm.hpp index efd9a8b1..b7a9870c 100755 --- a/bsnes/processor/arm/instructions-arm.hpp +++ b/bsnes/processor/arm/instructions-arm.hpp @@ -4,6 +4,7 @@ void arm_opcode(uint32 rm); void arm_move_to_status(uint32 rm); void arm_op_multiply(); +void arm_op_multiply_long(); void arm_op_memory_swap(); void arm_op_move_half_register(); void arm_op_move_half_immediate(); diff --git a/bsnes/processor/arm/instructions-thumb.cpp b/bsnes/processor/arm/instructions-thumb.cpp index 5327cc3e..b713c4d7 100755 --- a/bsnes/processor/arm/instructions-thumb.cpp +++ b/bsnes/processor/arm/instructions-thumb.cpp @@ -3,9 +3,10 @@ void ARM::thumb_step() { if(pipeline.reload) { pipeline.reload = false; + r(15).data &= ~1; pipeline.fetch.address = r(15); - pipeline.fetch.instruction = bus_read(r(15), Half); + pipeline.fetch.instruction = read(r(15), Half); pipeline_step(); step(1); @@ -198,7 +199,7 @@ void ARM::thumb_op_load_literal() { uint8 displacement = instruction(); unsigned rm = (r(15) & ~3) + displacement * 4; - r(d) = bus_read(rm, Word); + r(d) = read(rm, Word); } //(ld(r,s),str){b,h} rd,[rn,rm] @@ -214,14 +215,14 @@ void ARM::thumb_op_move_register_offset() { uint3 d = instruction() >> 0; switch(opcode) { - case 0: bus_write(r(n) + r(m), Word, r(d)); break; //STR - case 1: bus_write(r(n) + r(m), Half, r(d)); break; //STRH - case 2: bus_write(r(n) + r(m), Byte, r(d)); break; //STRB - case 3: r(d) = (int8)bus_read(r(n) + r(m), Byte); break; //LDSB - case 4: r(d) = bus_read(r(n) + r(m), Word); break; //LDR - case 5: r(d) = bus_read(r(n) + r(m), Half); break; //LDRH - case 6: r(d) = bus_read(r(n) + r(m), Byte); break; //LDRB - case 7: r(d) = (int16)bus_read(r(n) + r(m), Half); break; //LDSH + case 0: write(r(n) + r(m), Word, r(d)); break; //STR + case 1: write(r(n) + r(m), Half, r(d)); break; //STRH + case 2: write(r(n) + r(m), Byte, r(d)); break; //STRB + case 3: r(d) = (int8)read(r(n) + r(m), Byte); break; //LDSB + case 4: r(d) = read(r(n) + r(m), Word); break; //LDR + case 5: r(d) = read(r(n) + r(m), Half); break; //LDRH + case 6: r(d) = read(r(n) + r(m), Byte); break; //LDRB + case 7: r(d) = (int16)read(r(n) + r(m), Half); break; //LDSH } } @@ -237,8 +238,8 @@ void ARM::thumb_op_move_word_immediate() { uint3 n = instruction() >> 3; uint3 d = instruction() >> 0; - if(load == 1) r(d) = bus_read(r(n) + offset * 4, Word); - if(load == 0) bus_write(r(n) + offset * 4, Word, r(d)); + if(load == 1) r(d) = read(r(n) + offset * 4, Word); + if(load == 0) write(r(n) + offset * 4, Word, r(d)); } //(ldr,str)b rd,[rn,#offset] @@ -253,8 +254,8 @@ void ARM::thumb_op_move_byte_immediate() { uint3 n = instruction() >> 3; uint3 d = instruction() >> 0; - if(load == 1) r(d) = bus_read(r(n) + offset, Byte); - if(load == 0) bus_write(r(n) + offset, Byte, r(d)); + if(load == 1) r(d) = read(r(n) + offset, Byte); + if(load == 0) write(r(n) + offset, Byte, r(d)); } //(ldr,str)h rd,[rn,#offset] @@ -269,8 +270,8 @@ void ARM::thumb_op_move_half_immediate() { uint3 n = instruction() >> 3; uint3 d = instruction() >> 0; - if(load == 1) r(d) = bus_read(r(n) + offset * 2, Half); - if(load == 0) bus_write(r(n) + offset * 2, Half, r(d)); + if(load == 1) r(d) = read(r(n) + offset * 2, Half); + if(load == 0) write(r(n) + offset * 2, Half, r(d)); } //(ldr,str) rd,[sp,#immediate] @@ -283,8 +284,8 @@ void ARM::thumb_op_move_stack() { uint3 d = instruction() >> 8; uint8 immediate = instruction(); - if(opcode == 0) bus_write(r(13) + immediate * 4, Word, r(d)); - if(opcode == 1) r(d) = bus_read(r(13) + immediate * 4, Word); + if(opcode == 0) write(r(13) + immediate * 4, Word, r(d)); + if(opcode == 1) r(d) = read(r(13) + immediate * 4, Word); } //add rd,{pc,sp},#immediate @@ -330,16 +331,16 @@ void ARM::thumb_op_stack_multiple() { for(unsigned l = 0; l < 8; l++) { if(list & (1 << l)) { - if(load == 1) r(l) = bus_read(sp, Word); //POP - if(load == 0) bus_write(sp, Word, r(l)); //PUSH + if(load == 1) r(l) = read(sp, Word); //POP + if(load == 0) write(sp, Word, r(l)); //PUSH sp += 4; } } if(branch) { //note: ARMv5+ POP sets cpsr().t - if(load == 1) r(15) = bus_read(sp, Word); //POP - if(load == 0) bus_write(sp, Word, r(14)); //PUSH + if(load == 1) r(15) = read(sp, Word); //POP + if(load == 0) write(sp, Word, r(14)); //PUSH sp += 4; } @@ -359,8 +360,8 @@ void ARM::thumb_op_move_multiple() { for(unsigned l = 0; l < 8; l++) { if(list & (1 << l)) { - if(load == 1) r(l) = bus_read(r(n), Word); //LDMIA - if(load == 0) bus_write(r(n), Word, r(l)); //STMIA + if(load == 1) r(l) = read(r(n), Word); //LDMIA + if(load == 0) write(r(n), Word, r(l)); //STMIA r(n) += 4; } } diff --git a/bsnes/processor/arm/registers.cpp b/bsnes/processor/arm/registers.cpp index e39baff0..183a77ef 100755 --- a/bsnes/processor/arm/registers.cpp +++ b/bsnes/processor/arm/registers.cpp @@ -67,11 +67,11 @@ void ARM::pipeline_step() { if(cpsr().t == 0) { r(15).data += 4; pipeline.fetch.address = r(15); - pipeline.fetch.instruction = bus_read(r(15), Word); + pipeline.fetch.instruction = read(r(15), Word); } else { r(15).data += 2; pipeline.fetch.address = r(15); - pipeline.fetch.instruction = bus_read(r(15), Half); + pipeline.fetch.instruction = read(r(15), Half); } } diff --git a/bsnes/snes/chip/armdsp/memory.cpp b/bsnes/snes/chip/armdsp/memory.cpp index d64c0568..f1e5ce11 100755 --- a/bsnes/snes/chip/armdsp/memory.cpp +++ b/bsnes/snes/chip/armdsp/memory.cpp @@ -1,30 +1,19 @@ #ifdef ARMDSP_CPP uint32 ArmDSP::bus_read(uint32 addr, uint32 size) { - static auto adjust = [&](uint32 word, uint32 addr, uint32 size) { - unsigned rotate = (addr & 3) << 3; - word = (word >> rotate) | (word << (32 - rotate)); - return word & (~0u >> (32 - size)); - }; - static auto memory = [&](const uint8 *memory, uint32 addr, uint32 size) { memory += addr & ~3; - uint32 word = 0; - word |= *memory++ << 0; - word |= *memory++ << 8; - word |= *memory++ << 16; - word |= *memory++ << 24; - return adjust(word, addr, size); + return (memory[0] << 0) | (memory[1] << 8) | (memory[2] << 16) | (memory[3] << 24); }; switch(addr & 0xe0000000) { case 0x00000000: return memory(programROM, addr & 0x1ffff, size); - case 0x20000000: return adjust(pipeline.fetch.instruction, addr, size); + case 0x20000000: return pipeline.fetch.instruction; case 0x40000000: break; - case 0x60000000: return adjust(0x40404001, addr, size); - case 0x80000000: return adjust(pipeline.fetch.instruction, addr, size); + case 0x60000000: return 0x40404001; + case 0x80000000: return pipeline.fetch.instruction; case 0xa0000000: return memory(dataROM, addr & 0x7fff, size); - case 0xc0000000: return adjust(pipeline.fetch.instruction, addr, size); + case 0xc0000000: return pipeline.fetch.instruction; case 0xe0000000: return memory(programRAM, addr & 0x3fff, size); } @@ -33,12 +22,12 @@ uint32 ArmDSP::bus_read(uint32 addr, uint32 size) { if(addr == 0x40000010) { if(bridge.cputoarm.ready) { bridge.cputoarm.ready = false; - return adjust(bridge.cputoarm.data, addr, size); + return bridge.cputoarm.data; } } if(addr == 0x40000020) { - return adjust(bridge.status(), addr, size); + return bridge.status(); } return 0u;