forked from opencode.energia.arti.ee/vt1200
dis34: print long relative JR as jr and surface B-file SP as b15
The 16-bit-displacement jump (low byte 0x00, two words) is JRcc, not the three-word JAcc (low byte 0x80). Printing it as ja made linear disassembly report the wrong control flow and made every such branch grow by a word when reassembled. Register 15 is the stack pointer in either file: 0x0F is A15 and 0x1F is B15. The disassembler printed both as sp, hiding B-file stack-pointer code. Print b15 when the R bit selects the B file. Validated with the 1987 TI GSPA/GSPLNK/GSPROM round trip: the 32 KB region at bit 3F208000 still reassembles byte-for-byte (md5 43adb6669571041985f3e26fd9ff7cb9), as do the 4 KB and 16 KB spans and the 0x8000/3F240000 region. The converter no longer needs its ja->jr or sp->b15 rewrites (5 fixups -> 3); a whole-ROM diff contains only those two output categories. The ROM is unchanged (b46a3e442ccb86134d2356bd70d22fd2).
This commit is contained in:
1 parent
8bc8d90ea6
commit
af7d3565a5
9 files changed
+512
-10
No files matched your search
@@ -42,7 +42,10 @@ Examples:
|
||||
|
||||
- **A-file**: a0-a14, accessed when register bit 4 = 0
|
||||
- **B-file**: b0-b14, accessed when register bit 4 = 1
|
||||
- **sp**: register 15 in either file (stack pointer)
|
||||
- **sp**: register 15 in either file (stack pointer), encoded as `0x0F`
|
||||
(A15, printed `sp`) or `0x1F` (B15, printed `b15`). Both are the same
|
||||
physical stack pointer, but the encoding names a different file; a
|
||||
disassembler must not collapse them.
|
||||
- Register encoding: 5-bit field, bit 4 = file select, bits 3:0 = register number
|
||||
|
||||
### Instruction Word Format
|
||||
@@ -299,9 +302,13 @@ Condition code in bits 11:8 of the instruction word:
|
||||
| 15 | nn | Not negative |
|
||||
|
||||
Jump forms:
|
||||
- **JR cc** (relative): `0xC000 | (cc<<8) | 0x00` + 16-bit displacement
|
||||
- **JR cc** (short): `0xC000 | (cc<<8) | disp8` (8-bit signed displacement)
|
||||
- **JA cc** (absolute): `0xC000 | (cc<<8) | 0x80` + 32-bit address
|
||||
- **JR cc** (relative, 2 words): `0xC000 | (cc<<8) | 0x00` + 16-bit displacement
|
||||
- **JR cc** (short, 2 words): `0xC000 | (cc<<8) | disp8` (8-bit signed displacement)
|
||||
- **JA cc** (absolute, 3 words): `0xC000 | (cc<<8) | 0x80` + 32-bit address
|
||||
|
||||
Only low byte `0x80` is the absolute form. Low byte `0x00` carries a 16-bit
|
||||
*displacement* and is still `JRcc`; the word count must not be used to invent
|
||||
an absolute mnemonic for it.
|
||||
|
||||
Displacement formula:
|
||||
- 16-bit: `target = pc + 32 + (disp << 4)`
|
||||
@@ -337,10 +344,11 @@ Using the wrong decode gives K±1 errors. In `dis34.c`:
|
||||
|
||||
### Round-Trip Design Decisions
|
||||
|
||||
1. **`jacc` for 16-bit displacement JR** -- dis34 outputs `jacc` (not `jrcc`)
|
||||
for the 16-bit displacement form of conditional jumps. This ensures as34
|
||||
emits the same 4-byte encoding. The 8-bit short form uses `jrcc`. The
|
||||
32-bit absolute form uses `jacc`.
|
||||
1. **`jrcc` for both relative forms** -- the 8-bit and 16-bit displacement
|
||||
forms are both `JRcc` (2 words); only the 3-word `0x80` form is `JAcc`.
|
||||
(Until 2026-10-18 the 16-bit form was printed as `jacc`, which made a
|
||||
linear disassembly's control flow wrong and forced the round-trip
|
||||
converter to rewrite it back to `jrcc`.)
|
||||
|
||||
2. **Branch-only labels** -- Only branch/call targets (jr, ja, callr, calla,
|
||||
dsj, dsjeq, dsjne, dsjs) get labels. MOVI and other data-reference
|
||||
|
||||
Binary file not shown.
@@ -70,7 +70,12 @@ regname (int reg, int file)
|
||||
char *p = s[idx++ & 7];
|
||||
if (reg == 15)
|
||||
{
|
||||
strcpy (p, "sp");
|
||||
/* Register 15 is the stack pointer in *either* file: the R bit
|
||||
(bit 4 of the register field) selects A15 or B15. Printing both
|
||||
as "sp" hides which file the instruction actually names. GSPA
|
||||
spells the B-file one "b15"; it rejects "a15", and bare "sp" is
|
||||
the A-file register. */
|
||||
strcpy (p, file ? "b15" : "sp");
|
||||
return p;
|
||||
}
|
||||
snprintf (p, 8, "%c%d", file ? 'b' : 'a', reg);
|
||||
@@ -2163,9 +2168,11 @@ main (int argc, char **argv)
|
||||
}
|
||||
else if (lo8 == 0x00)
|
||||
{
|
||||
/* 16-bit displacement form: still JRcc (2 words), not
|
||||
the 3-word absolute JAcc (lo8 == 0x80). */
|
||||
int16_t disp = (int16_t) r16 ();
|
||||
uint32_t target = pc + 32 + ((int32_t) disp << 4);
|
||||
printf ("ja%s %s", condnames[cc], fmt_target (target));
|
||||
printf ("jr%s %s", condnames[cc], fmt_target (target));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user