84 lines
5.3 KiB
Markdown
84 lines
5.3 KiB
Markdown
# Addresses that moved, and what that means for the older reports
|
|
|
|
The probe-hardening pass needed room inside the `$E6F2-$E732` block, which had only three spare
|
|
bytes, so six internal helpers were relocated. Nothing the game, the ABI or the frozen regions name
|
|
by address moved - `checkAbi.py` still passes - and every one of these is reached only by a `JSR` or
|
|
`JMP` from code that changed in the same pass.
|
|
|
|
| routine | was | now |
|
|
|---|---|---|
|
|
| `aciaSetCommandIdle` | `$E72A` | `$E408` |
|
|
| `baudEntryTable` | `$E6FD` | `$E706` |
|
|
| `queueAndKickTx` | `$E712` | `$E71B` |
|
|
| `silenceCia2` | `$E71E` | `$E727` |
|
|
| `countLinkError` | `$E403` | `$E73F` |
|
|
| `aciaPageLatch` | (new) | `$E5BF` |
|
|
|
|
`queueByteForTransmit` `$E73C` kept its address and became a tail `JMP` into `queueAndKickTx`.
|
|
|
|
## The adopt-mode and re-entrancy-guard pass (2026-08-22)
|
|
|
|
The NMI re-entrancy guard and the probe that reads the user's own line settings before overwriting
|
|
them needed 50-odd bytes inside `$E644-$E732`, a block that had six spare bytes in it. Three
|
|
routines left the block, one routine was deleted, one was folded into another, and the table grew an
|
|
eighth entry. Again, nothing the game, the ABI or the frozen regions name by address moved, and
|
|
`checkAbi.py` still passes.
|
|
|
|
| routine | was | now |
|
|
|---|---|---|
|
|
| `aciaResumeReceiver` | `$E658` | `$E5B1` |
|
|
| `silenceCia2` | `$E727` | `$E56F` |
|
|
| `dropDtrLine` | `$E574` | `$E408` |
|
|
| `aciaSetPage` | `$E663` | `$E6FA` |
|
|
| `aciaProbe` | `$E6F2` | `$E655`, renamed `aciaProbeAdopted` - it reads the control register before it writes one |
|
|
| `baudEntryTable` | `$E706` | `$E710`, and 23 bytes wide: eight entries, not seven (the last entry's spare byte is not needed) |
|
|
| `queueAndKickTx` | `$E71B` | `$E727` |
|
|
| the NMI handler's chain exit | `$E679` | `$E67B` |
|
|
| `aciaDetectDone` | `$E654` (as `setBitPeriodFull`) | `$E654`, unchanged, and now the shared 'nothing to do' RTS of the transmit path as well |
|
|
|
|
Deleted outright: `aciaSetCommandIdle` `$E408` (the re-entrancy guard makes its second half provably
|
|
unnecessary at the one site that called it, so the NMI's disarm is a plain `aciaSetCommand` again),
|
|
`clearUartState` `$E5B6` (its whole inline block was the single byte `txCharActive`, which
|
|
`clearTxCharActive` `$E04F` already clears in the same three bytes at the one call site), `setBitPeriod`
|
|
`$E657` and the shared transmit-path RTS `L_E662` (its callers now branch to `aciaDetectDone` `$E654`,
|
|
which is the same instruction). `aciaRxByte` `$E5BD` became `nmiHandlerState`, the guard's own byte:
|
|
the receive half tests the error bits before it takes the character out of the data register, so it no
|
|
longer needs anywhere to park it.
|
|
|
|
`dropDtrLine` moving is the only one of these that is visible outside the driver's own block: the
|
|
`JSR` operand at `$E38E` inside `hangUpModem` had to follow it, which is why `checkAbi.py` now lists
|
|
`$E38E-$E38F` as changed.
|
|
The dead `ignoreLinkError` stub that used to sit at `$E408-$E40E` was deleted to make the space; it
|
|
was provably unreachable, and both halves of the error-vector pair at `$E3C7`/`$E3C9` were repointed
|
|
at `countLinkError` so that even the never-selected configuration lands on a real hook.
|
|
|
|
## Why the older reports were not rewritten
|
|
|
|
`realtimeReport.md`, `strapReport.md`, `rate1200Report.md`, `highRateReport.md`, `hotkeyReport.md`,
|
|
`testReport.md` and `spec_uart.md` cite several of the old addresses - `$E403` most often, because
|
|
`countLinkError` is where the error tracepoint was set in every measurement.
|
|
|
|
Those documents are records of what was observed on the build that existed when the measurement was
|
|
taken. Editing the addresses inside them would make them describe a run that never happened, so they
|
|
have been left alone. Read an address in a test report as "the address that routine had at the time
|
|
of that run", and use the table above to map it onto the current source.
|
|
|
|
`README.md` is the exception: it documents the driver as it stands now, and it was updated.
|
|
`wedgeDiagnosis.md` is a second exception in the other direction: it is a record of measurements made
|
|
against the build that still had the fault, so its addresses are the ones that build had.
|
|
|
|
## Conclusions that were overturned
|
|
|
|
The same rule applies to a report's *conclusions*, and for the same reason. Where a later measurement
|
|
has overturned one, the older file keeps its numbers and gains a note at the top pointing at the newer
|
|
result - the way this file points at moved addresses. Three exist so far:
|
|
|
|
| File | What was overturned | By |
|
|
|---|---|---|
|
|
| `highRateReport.md` | "Must not be selected: 38400", and 9600/19200 as degraded modes | `wedgeDiagnosis.md` found the cause; `portCompatReport.md` sections 3-4 measured the guarded build |
|
|
| `hardenReport.md` | the 38400 retirement (its hot-key code blanked) | the same, plus `testAdopt.py`: C= + 8 selects 38400 again |
|
|
| `strapReport.md` | the two probe weaknesses in its section 8 | `hardenReport.md` (two patterns, and the page latched once per cold start) and `portCompatReport.md` section 9.1 (the `$DF00` fallback now reads that page before writing it) |
|
|
|
|
`spec_uart.md` carries a note of the same kind on its hazards checklist: hazard 2's character-time
|
|
arithmetic is three times out, and hazard 8's "same 8N1 framing" now describes only the data bits,
|
|
since the driver adopts the port's own stop bits and clock source.
|