Previous Thread
Next Thread
Print Thread
#118596 02/09/21 06:14 PM
Joined: Apr 2012
Posts: 300
Pernod Offline OP
Senior Member
OP Offline
Senior Member
Joined: Apr 2012
Posts: 300
I'm looking at the rare Acorn A680 (ARM2) which starts with:
Code
0000000: E49FF000 LDR     R15, [R15], #$0 ; [$8]
0000004: EA0003CA B       $f34
0000008: 03400010 CMPEQ   R0, #$10
000000C: 268EE513 STRCS   R14, [R14, R3 LSL R10]
0000010: E49FF000 LDR     R15, [R15], #$0 ; [$18]
0000014: EA002EFD B       $bc10
0000018: 03800028 ORREQ   R0, R0, #$28
000001C: EA0007EE B       $1fdc
0000020: 00000000 ANDEQ   R0, R0, R0
0000024: 00000000 ANDEQ   R0, R0, R0
0000028: E49F0000 LDR     R0, [R15], #$0 ; [$30]
000002C: E090F00F ADDS    R15, R0, R15
0000030: 00000000 ANDEQ   R0, R0, R0
0000034: E49F2000 LDR     R2, [R15], #$0 ; [$3c]
0000038: E090F00F ADDS    R15, R0, R15
000003C: 03800000 ORREQ   R0, R0, #$0
0000040: E0903000 ADDS    R3, R0, R0
0000044: E4921000 LDR     R1, [R2], #$0
0000048: E0933001 ADDS    R3, R3, R1
000004C: E49F1000 LDR     R1, [R15], #$0 ; [$54]
0000050: E090F00F ADDS    R15, R0, R15
0000054: 00000004 ANDEQ   R0, R0, R4
0000058: E0922001 ADDS    R2, R2, R1
000005C: E49F1000 LDR     R1, [R15], #$0 ; [$64]
0000060: E090F00F ADDS    R15, R0, R15
0000064: FC7FE014 Undefined
0000068: E0911002 ADDS    R1, R1, R2
000006C: 349FF000 LDRCC   R15, [R15], #$0 ; [$74]
0000070: E090F00F ADDS    R15, R0, R15
0000074: 03800044 ORREQ   R0, R0, #$44
0000078: E49F1000 LDR     R1, [R15], #$0 ; [$80]
000007C: E090F00F ADDS    R15, R0, R15
The whole ROM can be found at https://stardot.org.uk/forums/viewtopic.php?p=187052#p187052

The first instruction is causing a jump to 0x3400010, but there is no code there. The region 0x3400000 - 0x34000FF is read-only and triggers a LED to display a diagnostic indicator 0-F, so a read from 0x3400010 would display 1, and reading 0x3400090 would display 9, etc.

According to Sarah Walker (Arculator, PCEm, etc.)
Quote
ldr pc, [pc], #0 is specifically described in several places as risky - "Do not use a PC relative load or store with base writeback as the effects may vary in future processors:"
I have a vague feeling that it might do something odd like cause a read from 3400010 but then immediately writeback the old PC
section 9.4 of the ARM2 datasheet does seem to back this up - it looks like it will read from the generated address (PC+8 in this case), perform a single read from the address read from [PC+8] (3400010 in this case), then flush the pipeline and continue instruction fetch from the generated address (PC+8)
Pretty certain Arculator won't handle this properly
so this looks like one pipeline flush (due to R15 being loaded with 3400010) being interrupted by another (due to base register writeback)
a pretty nasty corner case!

Anyone any further thoughts on this, and fancies fixing it?


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Pernod #118600 02/09/21 09:10 PM
Joined: Mar 2001
Posts: 16,716
Likes: 11
R
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,716
Likes: 11
We fixed a *lot* of those corner cases in the ARM7 core because GBA games were (ab)using them. It's possible this particular fix just wasn't backported to the 26-bit ARM core.

Pernod #118607 02/10/21 06:03 AM
Joined: May 2009
Posts: 1,923
Likes: 3
J
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,923
Likes: 3
Such a corner case isn't handled in the ARM7 core, either, because thus far, nothing has been encountered which is crazy enough to do a PC-relative PC load on such a relatively recent vintage of ARM. Particularly because such behavior is either implementation-defined or unpredictable entirely (I forget the wording used), as it depends on the manufacturer. Also, the ARM7 core is terrible and needs to be nuked from orbit.

It's a reasonable - though risky - thing to try to do on ARM2, though, since at the time there was still only one company making ARM2 chips. The behavior would be quirky, but well-defined.

The ARM2 core entirely lacks any concept of a pipeline, let alone a pipeline to flush, and implementing one would be an exercise in frustration. The best, albeit kludgy, way of fixing it would be:

- At the top of arm_cpu_device::HandleMemSingle, right where rd is assigned (under the "Do the transfer" comment), do something like:

Code
bool pipeline_override = (rd == rn && rd == eR15);
const uint32_t old_pc = R15;

- In the case of a word load to R15 (the (insn & INSN_SDT_L) case, and the not-(insn & INSN_SDT_B) case), replace the code there with this:

Code
			const uint32_t value = cpu_read32(rnv);
			if (rd == eR15)
			{
				R15 = (value & ADDRESS_MASK) | (R15 & PSR_MASK) | (R15 & IRQ_MASK) | (R15 & MODE_MASK);

				/*
				The docs are explicit in that the bottom bits should be masked off
				when writing to R15 in this way, however World Cup Volleyball 95 has
				an example of an unaligned jump (bottom bits = 2) where execution
				should definitely continue from the rounded up address.

				In other cases, 4 is subracted from R15 here to account for pipelining.
				*/
				if (m_copro_type == copro_type::VL86C020 || (cpu_read32(rnv)&3)==0)
					R15 -= 4;

				m_icount -= S_CYCLE + N_CYCLE;

				/* If necessary, read a bunk value from the target address to simulate pipeline behavior for a PC-relative PC load */
				if (pipeline_override)
					cpu_read32(value);
			}
			else
			{
				SetRegister(rd, value);
			}

- Look for the words "Writeback is applied in pipeline". Replace the "SetRegister(rn,GetRegister(rd));" part with:

Code
				if (pipeline_override)
					SetRegister(rn,old_pc);
				else
					SetRegister(rn,GetRegister(rd));

All respect to Sarah Walker, I'm not sure I agree with her assessment that execution would resume from the generated address (PC+8) as opposed to simply continuing on from the next instruction in line (PC+4), as the intent seems to be for the unconditional branch to be taken immediately after the load, not for execution to resume at the non-instruction represented by the 34xxxxx address.

Just Desserts #118609 02/10/21 10:12 AM
Joined: Apr 2012
Posts: 300
Pernod Offline OP
Senior Member
OP Offline
Senior Member
Joined: Apr 2012
Posts: 300
Originally Posted by Just Desserts
All respect to Sarah Walker, I'm not sure I agree with her assessment that execution would resume from the generated address (PC+8) as opposed to simply continuing on from the next instruction in line (PC+4), as the intent seems to be for the unconditional branch to be taken immediately after the load, not for execution to resume at the non-instruction represented by the 34xxxxx address.
Thanks JD, I'll take a look at implementing your suggestion.

My quote from Sarah was her initial take on the issue, and has since suggested the ROM may actually be mirrored in low ROM at 0x34xxxxx. I've tested with the mirrored ROM and though it gets a little further it then wants to branch to 0x4000000 but the ROM has now been paged out due to previous access with A25 high. So this suggests the initial assessment may be correct.

The ROM is performing diagnostics, indicating progress to a hexadecimal display on the board which I'm logging, so is proving to be a nice test case.


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Pernod #118610 02/10/21 10:23 AM
Joined: Jun 2001
Posts: 445
O
Senior Member
Offline
Senior Member
O
Joined: Jun 2001
Posts: 445
There are three branches in there, to f34, bc10 and 1fdc. Given the target code, which makes sense for startup?

OG.

Pernod #118611 02/10/21 10:31 AM
Joined: Jun 2001
Posts: 445
O
Senior Member
Offline
Senior Member
O
Joined: Jun 2001
Posts: 445
Well, I just looked, and I'm with JD on that one. The f34 code looks like something sane for initializations, while the asm at bc10 and 1fdc expect R0 to contain a useful value. So the write to r15 just being ignored and the execution continuing normally to the next instruction at +4 (to f34) look like the correct path.

Last edited by Olivier Galibert; 02/10/21 10:31 AM.
Pernod #118613 02/10/21 10:50 AM
Joined: May 2009
Posts: 1,923
Likes: 3
J
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,923
Likes: 3
It also just plain doesn't make sense for the ROM to be mirrored at 0x34xxxxx.

If it's as you say, Pernod, that reads from the first 256 bytes of that area will cause A7..A4 to be latched into a 7-segment hex decoder, then executing out of that range as well would result in the diagnostic digit flickering all over the place. With that generation of ARM, as far as I know there's no practical differentiation between an instruction fetch and a data fetch. Even if there were, it wouldn't make sense to implement the extra logic to latch only data fetches within that range, for something as simple as a diagnostic readout.

I would even go so far as to say that I wouldn't be shocked if reads above that range also result in A7..A4 being latched and displayed. Enforcing an entire range of 12 bits being all zeroes would require either an extremely wide NAND gate or multiple cascaded NAND gates, which again adds complexity to what would otherwise be a simple diagnostic readout. It's more likely that just the relevant upper bits of the address are decoded, and the value of A7..A4 gets latched across the entire 0x034xxxYx range, possibly even from 0x034xxxYx to 0x037xxxYx, depending on whether the chip select for the diagnostic latch is enabled based on just A26..A22 or A26 all the way down to A20.

Just Desserts #118614 02/10/21 12:12 PM
Joined: Apr 2012
Posts: 300
Pernod Offline OP
Senior Member
OP Offline
Senior Member
Joined: Apr 2012
Posts: 300
Originally Posted by Just Desserts
It also just plain doesn't make sense for the ROM to be mirrored at 0x34xxxxx.
I agree.
Originally Posted by Just Desserts
It's more likely that just the relevant upper bits of the address are decoded, and the value of A7..A4 gets latched across the entire 0x034xxxYx range, possibly even from 0x034xxxYx to 0x037xxxYx, depending on whether the chip select for the diagnostic latch is enabled based on just A26..A22 or A26 all the way down to A20.
A read from 0x3420000 will blank the hex display so definitely more decoding implemented. This is all documented in the TRM Part 1 available at http://chrisacorns.computinghistory.org.uk/RISCiXComputers.html


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Pernod #118616 02/10/21 06:30 PM
Joined: Apr 2012
Posts: 300
Pernod Offline OP
Senior Member
OP Offline
Senior Member
Joined: Apr 2012
Posts: 300
The ROM is definitely also at 0x34xxxxx:
Originally Posted by Sarah Walker
This code is written with the assumption that the CPU is mostly broken, hence it initially only uses LDR and ADD instructions, and very few registers
Hence why it's quite odd
That's also why it's setting the LED display by briefly jumping into a mirrored section of ROM
I'm ploughing on with Sarah's guidance:
Originally Posted by Sarah Walker
ok, so current test is a combination of CPU mode switching and shifting/rotation
test is failing in (I think) FIQ mode
R13_fiq was loaded with 1 at 0x4cc, this is the first operation on it which is ROR #1, which should result in 0x80000000
R1 was loaded with 0 at 0x544, C flag was set via TEQP at 0x540, so the RRX at 0x54c should result in R1 also being 0x80000000
At a guess, either a) MAME is failing to set C at the TEQP at 0x540, or b) MAME has an issue with register bank switching on mode change
Where R13_fiq is supposed to be loaded with 1 it's actually setting R13, so this is the current line of investigation.


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Pernod #118617 02/10/21 06:32 PM
Joined: May 2009
Posts: 1,923
Likes: 3
J
Very Senior Member
Offline
Very Senior Member
J
Joined: May 2009
Posts: 1,923
Likes: 3
Well good luck, then. I won't bother trying to help in the future. I'm not even part of the MAME team anymore, and this sort of thing is why. Don't waste anyone's time making a thread if you're just going to ignore what everyone says in favor of someone who you trust more. Lock this thread.


Link Copied to Clipboard
Who's Online Now
3 members (Golden Child, R. Belmont, Fake Shemp), 35 guests, and 2 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,921
Posts117,204
Members4,989
Most Online890
Jan 17th, 2020
Forum Host
These forums are hosted by www.retrogamesformac.com
Forum hosted by www.retrogamesformac.com