2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_opcode(uint32 rm) {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint4 opcode = instruction() >> 21;
|
|
|
|
uint1 save = instruction() >> 20;
|
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
|
|
|
|
|
|
|
switch(opcode) {
|
2012-03-29 11:58:10 +00:00
|
|
|
case 0: r(d) = bit(rn & rm); break; //AND
|
|
|
|
case 1: r(d) = bit(rn ^ rm); break; //EOR
|
|
|
|
case 2: r(d) = sub(rn, rm, 1); break; //SUB
|
|
|
|
case 3: r(d) = sub(rm, rn, 1); break; //RSB
|
|
|
|
case 4: r(d) = add(rn, rm, 0); break; //ADD
|
|
|
|
case 5: r(d) = add(rn, rm, cpsr().c); break; //ADC
|
|
|
|
case 6: r(d) = sub(rn, rm, cpsr().c); break; //SBC
|
|
|
|
case 7: r(d) = sub(rm, rn, cpsr().c); break; //RSC
|
|
|
|
case 8: bit(rn & rm); break; //TST
|
|
|
|
case 9: bit(rn ^ rm); break; //TEQ
|
|
|
|
case 10: sub(rn, rm, 1); break; //CMP
|
|
|
|
case 11: add(rn, rm, 0); break; //CMN
|
|
|
|
case 12: r(d) = bit(rn | rm); break; //ORR
|
|
|
|
case 13: r(d) = bit(rm); break; //MOV
|
|
|
|
case 14: r(d) = bit(rn & ~rm); break; //BIC
|
|
|
|
case 15: r(d) = bit(~rm); break; //MVN
|
|
|
|
}
|
|
|
|
|
2015-06-27 02:38:08 +00:00
|
|
|
if(exceptionMode() && d == 15 && save) {
|
2012-03-29 11:58:10 +00:00
|
|
|
cpsr() = spsr();
|
|
|
|
processor.setMode((Processor::Mode)cpsr().m);
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_move_to_status(uint32 rm) {
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
uint1 source = instruction() >> 22;
|
|
|
|
uint4 field = instruction() >> 16;
|
|
|
|
|
|
|
|
if(source == 1) {
|
|
|
|
if(mode() == Processor::Mode::USR) return;
|
|
|
|
if(mode() == Processor::Mode::SYS) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
PSR &psr = source ? spsr() : cpsr();
|
|
|
|
|
|
|
|
if(field & 1) {
|
2015-06-27 02:38:08 +00:00
|
|
|
if(source == 1 || privilegedMode()) {
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
psr.i = rm & 0x00000080;
|
|
|
|
psr.f = rm & 0x00000040;
|
|
|
|
psr.t = rm & 0x00000020;
|
|
|
|
psr.m = rm & 0x0000001f;
|
|
|
|
if(source == 0) processor.setMode((Processor::Mode)psr.m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(field & 8) {
|
|
|
|
psr.n = rm & 0x80000000;
|
|
|
|
psr.z = rm & 0x40000000;
|
|
|
|
psr.c = rm & 0x20000000;
|
|
|
|
psr.v = rm & 0x10000000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:08:16 +00:00
|
|
|
//mul{condition}{s} rd,rm,rs
|
|
|
|
//mla{condition}{s} rd,rm,rs,rn
|
|
|
|
//cccc 0000 00as dddd nnnn ssss 1001 mmmm
|
|
|
|
//c = condition
|
|
|
|
//a = accumulate
|
|
|
|
//s = save flags
|
|
|
|
//d = rd
|
|
|
|
//n = rn
|
|
|
|
//s = rs
|
2012-03-31 08:14:31 +00:00
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_multiply() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 accumulate = instruction() >> 21;
|
2012-03-31 08:14:31 +00:00
|
|
|
uint1 save = instruction() >> 20;
|
2012-03-21 11:08:16 +00:00
|
|
|
uint4 d = instruction() >> 16;
|
|
|
|
uint4 n = instruction() >> 12;
|
|
|
|
uint4 s = instruction() >> 8;
|
2012-03-31 08:14:31 +00:00
|
|
|
uint4 m = instruction();
|
2012-03-21 11:08:16 +00:00
|
|
|
|
2012-04-01 01:41:15 +00:00
|
|
|
r(d) = mul(accumulate ? r(n) : 0u, r(m), r(s));
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
|
2012-03-31 08:14:31 +00:00
|
|
|
//(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
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_multiply_long() {
|
2012-03-31 08:14:31 +00:00
|
|
|
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();
|
|
|
|
|
2012-03-31 08:17:36 +00:00
|
|
|
uint64 rm = r(m);
|
|
|
|
uint64 rs = r(s);
|
|
|
|
if(signextend) {
|
|
|
|
rm = (int32)rm;
|
|
|
|
rs = (int32)rs;
|
|
|
|
}
|
2012-03-31 08:14:31 +00:00
|
|
|
|
|
|
|
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;
|
2012-04-01 01:41:15 +00:00
|
|
|
//cpsr().c = 0; //(undefined)
|
|
|
|
//cpsr().v = 0; //(undefined)
|
2012-03-31 08:14:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
//swp{condition}{b} rd,rm,[rn]
|
|
|
|
//cccc 0001 0b00 nnnn dddd ---- 1001 mmmm
|
|
|
|
//c = condition
|
|
|
|
//b = byte (0 = word)
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_memory_swap() {
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
uint1 byte = instruction() >> 22;
|
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
uint4 m = instruction();
|
|
|
|
|
2015-07-01 10:58:42 +00:00
|
|
|
uint32 word = load((byte ? Byte : Word) | Nonsequential, r(n));
|
|
|
|
store((byte ? Byte : Word) | Nonsequential, r(n), r(m));
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
r(d) = word;
|
|
|
|
}
|
|
|
|
|
2012-03-27 11:02:57 +00:00
|
|
|
//(ldr,str){condition}h rd,[rn,rm]{!}
|
|
|
|
//(ldr,str){condition}h rd,[rn],rm
|
|
|
|
//cccc 000p u0wl nnnn dddd ---- 1011 mmmm
|
|
|
|
//c = condition
|
|
|
|
//p = pre (0 = post)
|
|
|
|
//u = up
|
|
|
|
//w = writeback
|
|
|
|
//l = load (0 = save)
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_half_register() {
|
2012-03-27 11:02:57 +00:00
|
|
|
uint1 pre = instruction() >> 24;
|
|
|
|
uint1 up = instruction() >> 23;
|
|
|
|
uint1 writeback = instruction() >> 21;
|
2012-04-15 06:49:56 +00:00
|
|
|
uint1 l = instruction() >> 20;
|
2012-03-27 11:02:57 +00:00
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
uint4 m = instruction();
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
|
|
|
uint32 rm = r(m);
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
uint32 rd = r(d);
|
2012-03-27 11:02:57 +00:00
|
|
|
|
|
|
|
if(pre == 1) rn = up ? rn + rm : rn - rm;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
if(l == 1) rd = load(Half | Nonsequential, rn);
|
|
|
|
if(l == 0) store(Half | Nonsequential, rn, rd);
|
2012-03-27 11:02:57 +00:00
|
|
|
if(pre == 0) rn = up ? rn + rm : rn - rm;
|
|
|
|
|
|
|
|
if(pre == 0 || writeback == 1) r(n) = rn;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
if(l == 1) r(d) = rd;
|
2012-03-27 11:02:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//(ldr,str){condition}h rd,[rn{,+/-offset}]{!}
|
|
|
|
//(ldr,str){condition}h rd,[rn]{,+/-offset}
|
|
|
|
//cccc 000p u1wl nnnn dddd iiii 1011 iiii
|
|
|
|
//c = condition
|
|
|
|
//p = pre (0 = post)
|
|
|
|
//u = up
|
|
|
|
//w = writeback
|
|
|
|
//l = load (0 = save)
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//i = immediate hi
|
|
|
|
//i = immediate lo
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_half_immediate() {
|
2012-03-27 11:02:57 +00:00
|
|
|
uint1 pre = instruction() >> 24;
|
|
|
|
uint1 up = instruction() >> 23;
|
|
|
|
uint1 writeback = instruction() >> 21;
|
2012-04-15 06:49:56 +00:00
|
|
|
uint1 l = instruction() >> 20;
|
2012-03-27 11:02:57 +00:00
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
uint4 ih = instruction() >> 8;
|
|
|
|
uint4 il = instruction();
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
uint32 rd = r(d);
|
2012-03-27 11:02:57 +00:00
|
|
|
uint8 immediate = (ih << 4) + (il << 0);
|
|
|
|
|
|
|
|
if(pre == 1) rn = up ? rn + immediate : rn - immediate;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
if(l == 1) rd = load(Half | Nonsequential, rn);
|
|
|
|
if(l == 0) store(Half | Nonsequential, rn, rd);
|
2012-03-27 11:02:57 +00:00
|
|
|
if(pre == 0) rn = up ? rn + immediate : rn - immediate;
|
|
|
|
|
|
|
|
if(pre == 0 || writeback == 1) r(n) = rn;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
if(l == 1) r(d) = rd;
|
2012-03-27 11:02:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//ldr{condition}s(h,b) rd,[rn,rm]{!}
|
|
|
|
//ldr{condition}s(h,b) rd,[rn],rm
|
|
|
|
//cccc 000p u0w1 nnnn dddd ---- 11h1 mmmm
|
|
|
|
//c = condition
|
|
|
|
//p = pre (0 = post)
|
|
|
|
//u = up
|
|
|
|
//w = writeback
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//h = half (0 = byte)
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_load_register() {
|
2012-03-27 11:02:57 +00:00
|
|
|
uint1 pre = instruction() >> 24;
|
|
|
|
uint1 up = instruction() >> 23;
|
|
|
|
uint1 writeback = instruction() >> 21;
|
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
uint1 half = instruction() >> 5;
|
|
|
|
uint4 m = instruction();
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
|
|
|
uint32 rm = r(m);
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
uint32 rd = r(d);
|
2012-03-27 11:02:57 +00:00
|
|
|
|
|
|
|
if(pre == 1) rn = up ? rn + rm : rn - rm;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
rd = load((half ? Half : Byte) | Nonsequential | Signed, rn);
|
2012-03-29 11:58:10 +00:00
|
|
|
if(pre == 0) rn = up ? rn + rm : rn - rm;
|
2012-03-27 11:02:57 +00:00
|
|
|
|
|
|
|
if(pre == 0 || writeback == 1) r(n) = rn;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
r(d) = rd;
|
2012-03-27 11:02:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//ldr{condition}s(h,b) rd,[rn{,+/-offset}]{!}
|
|
|
|
//ldr{condition}s(h,b) rd,[rn]{,+/-offset}
|
|
|
|
//cccc 000p u1w1 nnnn dddd iiii 11h1 iiii
|
|
|
|
//c = condition
|
|
|
|
//p = pre (0 = post)
|
|
|
|
//u = up
|
|
|
|
//w = writeback
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//i = immediate hi
|
|
|
|
//h = half (0 = byte)
|
|
|
|
//i = immediate lo
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_load_immediate() {
|
2012-03-27 11:02:57 +00:00
|
|
|
uint1 pre = instruction() >> 24;
|
|
|
|
uint1 up = instruction() >> 23;
|
|
|
|
uint1 writeback = instruction() >> 21;
|
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
uint4 ih = instruction() >> 8;
|
|
|
|
uint1 half = instruction() >> 5;
|
|
|
|
uint4 il = instruction();
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
uint32 rd = r(d);
|
2012-03-27 11:02:57 +00:00
|
|
|
uint8 immediate = (ih << 4) + (il << 0);
|
|
|
|
|
|
|
|
if(pre == 1) rn = up ? rn + immediate : rn - immediate;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
rd = load((half ? Half : Byte) | Nonsequential | Signed, rn);
|
2012-03-27 11:02:57 +00:00
|
|
|
if(pre == 0) rn = up ? rn + immediate : rn - immediate;
|
|
|
|
|
|
|
|
if(pre == 0 || writeback == 1) r(n) = rn;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
r(d) = rd;
|
2012-03-27 11:02:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//mrs{condition} rd,(c,s)psr
|
|
|
|
//cccc 0001 0r00 ++++ dddd ---- 0000 ----
|
|
|
|
//c = condition
|
|
|
|
//r = SPSR (0 = CPSR)
|
|
|
|
//d = rd
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_to_register_from_status() {
|
2012-03-27 11:02:57 +00:00
|
|
|
uint1 source = instruction() >> 22;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
|
|
|
|
if(source) {
|
|
|
|
if(mode() == Processor::Mode::USR) return;
|
|
|
|
if(mode() == Processor::Mode::SYS) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
r(d) = source ? spsr() : cpsr();
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:08:16 +00:00
|
|
|
//msr{condition} (c,s)psr:{fields},rm
|
|
|
|
//cccc 0001 0r10 ffff ++++ ---- 0000 mmmm
|
|
|
|
//c = condition
|
|
|
|
//r = SPSR (0 = CPSR)
|
|
|
|
//f = field mask
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_to_status_from_register() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint4 m = instruction();
|
|
|
|
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
arm_move_to_status(r(m));
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//bx{condition} rm
|
|
|
|
//cccc 0001 0010 ++++ ++++ ++++ 0001 mmmm
|
|
|
|
//c = condition
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_branch_exchange_register() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint4 m = instruction();
|
|
|
|
|
|
|
|
cpsr().t = r(m) & 1;
|
2012-03-26 10:13:02 +00:00
|
|
|
r(15) = r(m);
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
//msr{condition} (c,s)psr:{fields},#immediate
|
|
|
|
//cccc 0011 0r10 ffff ++++ rrrr iiii iiii
|
|
|
|
//c = condition
|
|
|
|
//r = SPSR (0 = CPSR)
|
|
|
|
//f = field mask
|
|
|
|
//r = rotate
|
|
|
|
//i = immediate
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_to_status_from_immediate() {
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
uint4 rotate = instruction() >> 8;
|
|
|
|
uint8 immediate = instruction();
|
|
|
|
|
|
|
|
uint32 rm = immediate;
|
2012-03-29 11:58:10 +00:00
|
|
|
if(rotate) rm = ror(rm, 2 * rotate);
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
|
|
|
|
arm_move_to_status(rm);
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:08:16 +00:00
|
|
|
//{opcode}{condition}{s} rd,rm {shift} #immediate
|
|
|
|
//{opcode}{condition} rn,rm {shift} #immediate
|
|
|
|
//{opcode}{condition}{s} rd,rn,rm {shift} #immediate
|
|
|
|
//cccc 000o ooos nnnn dddd llll lss0 mmmm
|
|
|
|
//c = condition
|
|
|
|
//o = opcode
|
|
|
|
//s = save flags
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//l = shift immediate
|
|
|
|
//s = shift
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_data_immediate_shift() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 save = instruction() >> 20;
|
|
|
|
uint5 shift = instruction() >> 7;
|
|
|
|
uint2 mode = instruction() >> 5;
|
|
|
|
uint4 m = instruction();
|
|
|
|
|
|
|
|
uint32 rs = shift;
|
|
|
|
uint32 rm = r(m);
|
2012-03-31 08:17:36 +00:00
|
|
|
carryout() = cpsr().c;
|
2012-03-21 11:08:16 +00:00
|
|
|
|
2012-03-29 11:58:10 +00:00
|
|
|
if(mode == 0) rm = lsl(rm, rs);
|
2016-02-16 09:27:55 +00:00
|
|
|
if(mode == 1) rm = lsr(rm, rs ? rs : (uint32)32);
|
|
|
|
if(mode == 2) rm = asr(rm, rs ? rs : (uint32)32);
|
2012-03-29 11:58:10 +00:00
|
|
|
if(mode == 3) rm = rs ? ror(rm, rs) : rrx(rm);
|
2012-03-21 11:08:16 +00:00
|
|
|
|
|
|
|
arm_opcode(rm);
|
|
|
|
}
|
|
|
|
|
|
|
|
//{opcode}{condition}{s} rd,rm {shift} rs
|
|
|
|
//{opcode}{condition} rn,rm {shift} rs
|
|
|
|
//{opcode}{condition}{s} rd,rn,rm {shift} rs
|
|
|
|
//cccc 000o ooos nnnn dddd ssss 0ss1 mmmm
|
|
|
|
//c = condition
|
|
|
|
//o = opcode
|
|
|
|
//s = save flags
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//s = rs
|
|
|
|
//s = shift
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_data_register_shift() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 save = instruction() >> 20;
|
|
|
|
uint4 s = instruction() >> 8;
|
|
|
|
uint2 mode = instruction() >> 5;
|
|
|
|
uint4 m = instruction();
|
|
|
|
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
uint8 rs = r(s) + (s == 15 ? 4 : 0);
|
|
|
|
uint32 rm = r(m) + (m == 15 ? 4 : 0);
|
2012-03-31 08:17:36 +00:00
|
|
|
carryout() = cpsr().c;
|
2012-03-21 11:08:16 +00:00
|
|
|
|
2016-02-16 09:27:55 +00:00
|
|
|
if(mode == 0 ) rm = lsl(rm, rs < 33 ? rs : (uint8)33);
|
|
|
|
if(mode == 1 ) rm = lsr(rm, rs < 33 ? rs : (uint8)33);
|
|
|
|
if(mode == 2 ) rm = asr(rm, rs < 32 ? rs : (uint8)32);
|
2012-03-29 11:58:10 +00:00
|
|
|
if(mode == 3 && rs) rm = ror(rm, rs & 31 == 0 ? 32 : rs & 31);
|
2012-03-21 11:08:16 +00:00
|
|
|
|
|
|
|
arm_opcode(rm);
|
|
|
|
}
|
|
|
|
|
|
|
|
//{opcode}{condition}{s} rd,#immediate
|
|
|
|
//{opcode}{condition} rn,#immediate
|
|
|
|
//{opcode}{condition}{s} rd,rn,#immediate
|
|
|
|
//cccc 001o ooos nnnn dddd ssss iiii iiii
|
|
|
|
//c = condition
|
|
|
|
//o = opcode
|
|
|
|
//s = save flags
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//s = shift immediate
|
|
|
|
//i = immediate
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_data_immediate() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 save = instruction() >> 20;
|
|
|
|
uint4 shift = instruction() >> 8;
|
|
|
|
uint8 immediate = instruction();
|
|
|
|
|
2012-03-31 08:17:36 +00:00
|
|
|
uint32 rm = immediate;
|
|
|
|
|
|
|
|
carryout() = cpsr().c;
|
|
|
|
if(shift) rm = ror(immediate, 2 * shift);
|
2012-03-21 11:08:16 +00:00
|
|
|
|
|
|
|
arm_opcode(rm);
|
|
|
|
}
|
|
|
|
|
|
|
|
//(ldr,str){condition}{b} rd,[rn{,+/-offset}]{!}
|
|
|
|
//(ldr,str){condition}{b} rd,[rn]{,+/-offset}
|
|
|
|
//cccc 010p ubwl nnnn dddd iiii iiii iiii
|
|
|
|
//c = condition
|
|
|
|
//p = pre (0 = post-indexed addressing)
|
|
|
|
//u = up (add/sub offset to base)
|
|
|
|
//b = byte (1 = word)
|
|
|
|
//w = writeback
|
|
|
|
//l = load (0 = save)
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//i = immediate
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_immediate_offset() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 pre = instruction() >> 24;
|
|
|
|
uint1 up = instruction() >> 23;
|
|
|
|
uint1 byte = instruction() >> 22;
|
|
|
|
uint1 writeback = instruction() >> 21;
|
2012-04-15 06:49:56 +00:00
|
|
|
uint1 l = instruction() >> 20;
|
2012-03-21 11:08:16 +00:00
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
uint12 rm = instruction();
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
uint32 rd = r(d);
|
2012-03-21 11:08:16 +00:00
|
|
|
|
|
|
|
if(pre == 1) rn = up ? rn + rm : rn - rm;
|
2015-07-01 10:58:42 +00:00
|
|
|
if(l == 1) rd = load((byte ? Byte : Word) | Nonsequential, rn);
|
|
|
|
if(l == 0) store((byte ? Byte : Word) | Nonsequential, rn, rd);
|
2012-03-21 11:08:16 +00:00
|
|
|
if(pre == 0) rn = up ? rn + rm : rn - rm;
|
|
|
|
|
|
|
|
if(pre == 0 || writeback == 1) r(n) = rn;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
if(l == 1) r(d) = rd;
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
|
2012-03-27 11:02:57 +00:00
|
|
|
//(ldr,str){condition}{b} rd,[rn,rm {mode} #immediate]{!}
|
2012-03-21 11:08:16 +00:00
|
|
|
//(ldr,str){condition}{b} rd,[rn],rm {mode} #immediate
|
|
|
|
//cccc 011p ubwl nnnn dddd llll lss0 mmmm
|
|
|
|
//c = condition
|
|
|
|
//p = pre (0 = post-indexed addressing)
|
|
|
|
//u = up
|
|
|
|
//b = byte (1 = word)
|
|
|
|
//w = writeback
|
|
|
|
//l = load (0 = save)
|
|
|
|
//n = rn
|
|
|
|
//d = rd
|
|
|
|
//l = shift immediate
|
|
|
|
//s = shift mode
|
|
|
|
//m = rm
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_register_offset() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 pre = instruction() >> 24;
|
|
|
|
uint1 up = instruction() >> 23;
|
|
|
|
uint1 byte = instruction() >> 22;
|
|
|
|
uint1 writeback = instruction() >> 21;
|
2012-04-15 06:49:56 +00:00
|
|
|
uint1 l = instruction() >> 20;
|
2012-03-21 11:08:16 +00:00
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint4 d = instruction() >> 12;
|
|
|
|
uint5 immediate = instruction() >> 7;
|
|
|
|
uint2 mode = instruction() >> 5;
|
|
|
|
uint4 m = instruction();
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
uint32 rd = r(d);
|
2012-03-21 11:08:16 +00:00
|
|
|
uint32 rs = immediate;
|
|
|
|
uint32 rm = r(m);
|
|
|
|
bool c = cpsr().c;
|
|
|
|
|
2012-03-29 11:58:10 +00:00
|
|
|
if(mode == 0) rm = lsl(rm, rs);
|
2016-02-16 09:27:55 +00:00
|
|
|
if(mode == 1) rm = lsr(rm, rs ? rs : (uint32)32);
|
|
|
|
if(mode == 2) rm = asr(rm, rs ? rs : (uint32)32);
|
2012-03-29 11:58:10 +00:00
|
|
|
if(mode == 3) rm = rs ? ror(rm, rs) : rrx(rm);
|
2012-03-21 11:08:16 +00:00
|
|
|
|
|
|
|
if(pre == 1) rn = up ? rn + rm : rn - rm;
|
2015-07-01 10:58:42 +00:00
|
|
|
if(l == 1) rd = load((byte ? Byte : Word) | Nonsequential, rn);
|
|
|
|
if(l == 0) store((byte ? Byte : Word) | Nonsequential, rn, rd);
|
2012-03-21 11:08:16 +00:00
|
|
|
if(pre == 0) rn = up ? rn + rm : rn - rm;
|
|
|
|
|
|
|
|
if(pre == 0 || writeback == 1) r(n) = rn;
|
Update to v095r03 release and icarus 20151107.
byuu says:
Note: you will need the new icarus (and please use the "no manifest"
system) to run GBA games with this WIP.
Changelog:
- fixed caching of r(d) to pass armwrestler tests [Jonas Quinn]
- DMA to/from GBA BIOS should fail [Cydrak]
- fixed sign-extend and rotate on ldrs instructions [Cydrak]
- fixed 8-bit SRAM reading/writing [byuu]
- refactored GBA/cartridge
- cartridge/rom,ram.type is now cartridge/mrom,sram,eeprom,flash
- things won't crash horribly if you specify a RAM size larger than
the largest legal size in the manifest
- specialized MROM / SRAM classes replace all the shared read/write
functions that didn't work right anyway
- there's a new ruby/video.glx2 driver, which is not enabled by default
- use this if you are running Linux/BSD, but don't have OpenGL 3.2 yet
- I'm not going to support OpenGL2 on Windows/OS X, because these OSes
don't ship ancient video card drivers
- probably more. What am I, clairvoyant? :P
For endrift's tests, this gets us to 1348/1552 memory and 1016/1260
timing. Overall, this puts us back in second place. Only no$ is ahead
on memory, but bgba is even more ahead on timing.
2015-11-08 09:09:18 +00:00
|
|
|
if(l == 1) r(d) = rd;
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//(ldm,stm){condition}{mode} rn{!},{r...}
|
|
|
|
//cccc 100p uswl nnnn llll llll llll llll
|
|
|
|
//c = condition
|
|
|
|
//p = pre (0 = post-indexed addressing)
|
|
|
|
//u = up (add/sub offset to base)
|
|
|
|
//s = spsr copy -or- usr register copy
|
|
|
|
//w = writeback
|
|
|
|
//l = load (0 = save)
|
|
|
|
//n = rn
|
|
|
|
//l = register list
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_move_multiple() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 pre = instruction() >> 24;
|
|
|
|
uint1 up = instruction() >> 23;
|
|
|
|
uint1 s = instruction() >> 22;
|
|
|
|
uint1 writeback = instruction() >> 21;
|
2012-04-15 06:49:56 +00:00
|
|
|
uint1 l = instruction() >> 20;
|
2012-03-21 11:08:16 +00:00
|
|
|
uint4 n = instruction() >> 16;
|
|
|
|
uint16 list = instruction();
|
|
|
|
|
|
|
|
uint32 rn = r(n);
|
|
|
|
if(pre == 0 && up == 1) rn = rn + 0; //IA
|
|
|
|
if(pre == 1 && up == 1) rn = rn + 4; //IB
|
|
|
|
if(pre == 1 && up == 0) rn = rn - bit::count(list) * 4 + 0; //DB
|
|
|
|
if(pre == 0 && up == 0) rn = rn - bit::count(list) * 4 + 4; //DA
|
|
|
|
|
2015-08-02 06:23:13 +00:00
|
|
|
if(writeback && l == 1) {
|
|
|
|
if(up == 1) r(n) = r(n) + bit::count(list) * 4; //IA, IB
|
|
|
|
if(up == 0) r(n) = r(n) - bit::count(list) * 4; //DA, DB
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:08:16 +00:00
|
|
|
Processor::Mode pmode = mode();
|
|
|
|
bool usr = false;
|
2012-04-15 06:49:56 +00:00
|
|
|
if(s && l == 1 && (list & 0x8000) == 0) usr = true;
|
|
|
|
if(s && l == 0) usr = true;
|
2012-03-21 11:08:16 +00:00
|
|
|
if(usr) processor.setMode(Processor::Mode::USR);
|
|
|
|
|
2015-07-01 10:58:42 +00:00
|
|
|
unsigned sequential = Nonsequential;
|
2012-04-15 06:49:56 +00:00
|
|
|
for(unsigned m = 0; m < 16; m++) {
|
2015-06-25 09:52:32 +00:00
|
|
|
if(list & 1 << m) {
|
2015-07-01 10:58:42 +00:00
|
|
|
if(l == 1) r(m) = read(Word | sequential, rn);
|
|
|
|
if(l == 0) write(Word | sequential, rn, r(m));
|
2012-03-21 11:08:16 +00:00
|
|
|
rn += 4;
|
2015-07-01 10:58:42 +00:00
|
|
|
sequential = Sequential;
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(usr) processor.setMode(pmode);
|
|
|
|
|
2012-04-15 06:49:56 +00:00
|
|
|
if(l == 1) {
|
|
|
|
idle();
|
|
|
|
if(s && (list & 0x8000)) {
|
|
|
|
if(mode() != Processor::Mode::USR && mode() != Processor::Mode::SYS) {
|
|
|
|
cpsr() = spsr();
|
|
|
|
processor.setMode((Processor::Mode)cpsr().m);
|
|
|
|
}
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
2015-06-27 02:38:08 +00:00
|
|
|
} else {
|
2015-07-01 10:58:42 +00:00
|
|
|
pipeline.nonsequential = true;
|
2012-03-21 11:08:16 +00:00
|
|
|
}
|
|
|
|
|
2015-08-02 06:23:13 +00:00
|
|
|
if(writeback && l == 0) {
|
2012-03-21 11:08:16 +00:00
|
|
|
if(up == 1) r(n) = r(n) + bit::count(list) * 4; //IA, IB
|
|
|
|
if(up == 0) r(n) = r(n) - bit::count(list) * 4; //DA, DB
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//b{l}{condition} address
|
|
|
|
//cccc 101l dddd dddd dddd dddd dddd dddd
|
|
|
|
//c = condition
|
|
|
|
//l = link
|
|
|
|
//d = displacement (24-bit signed)
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_branch() {
|
2012-03-21 11:08:16 +00:00
|
|
|
uint1 link = instruction() >> 24;
|
|
|
|
int24 displacement = instruction();
|
|
|
|
|
|
|
|
if(link) r(14) = r(15) - 4;
|
|
|
|
r(15) += displacement * 4;
|
|
|
|
}
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
|
|
|
|
//swi #immediate
|
|
|
|
//cccc 1111 iiii iiii iiii iiii iiii iiii
|
|
|
|
//c = condition
|
|
|
|
//i = immediate
|
2015-06-24 13:21:24 +00:00
|
|
|
auto ARM::arm_op_software_interrupt() {
|
Update to v087r08 release.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
2012-03-24 07:52:36 +00:00
|
|
|
uint24 immediate = instruction();
|
|
|
|
|
|
|
|
vector(0x00000008, Processor::Mode::SVC);
|
|
|
|
}
|