SplitLint reports valid assembly that has a shorter direct expression: zero loads that could be RSTA or RSTB, Q moved through the stack where MVQA would do, self-cancelling push and pop pairs, assignments overwritten before use, unreachable fallthrough, one-byte pointer moves that could be INCD or DECD, a branch to the label directly below it, a SETD reloading an address the pointer already holds, and branches whose carry is known. Its model is deliberately local and conservative: every label and every directive forgets all known state, so a claim only ever lives inside a straight-line region. It knows the calling convention - CALL forgets DP3 and keeps the rest, RCAL and SWI forget everything - and it shares assembly.o with the assembler, so an added opcode cannot leave it holding a private copy of the instruction table. 260 warnings across the corpus, of which three were wrong in the way that matters: branchTest.asm and interruptFlagTest.asm exist to check that a branch whose carry is known behaves correctly, so a diagnostic saying the outcome is known is exactly right and exactly unwanted. A line whose comment says "splitlint: <reason>" is now not reported on. THE REASON IS REQUIRED and a bare marker is refused, because a suppression nobody explained outlives whatever made it necessary. Suppressed warnings are not counted, so --fatal-warnings does not fail on one, and the number of them is printed at the end so the claim is visible rather than silent. Tests/lint.sh checked a TOTAL: twenty three warnings expected, twenty three found. That number stays right while the thing behind it goes wrong - a rule that stopped firing while another fired twice would pass, and so would a rule reporting at the wrong line. It now checks which warning came out and at which line, that nothing else came out, and that the four lines meant to stay quiet did. Confirmed by breaking one rule's message and watching it name that rule: the old assertion passed the same sabotage, because the warning still fired and the count never moved. Written with the user while I was away; my part is the suppression mechanism, the harness rewrite, and the three marks in the test programs.
46 lines
1.1 KiB
NASM
46 lines
1.1 KiB
NASM
; Tests SIF and CIF, the Interrupt Flag.
|
|
;
|
|
; Nothing reads the Interrupt Flag yet, so what this proves is that the two
|
|
; instructions decode, execute, and leave everything else exactly as they found
|
|
; it. The Carry Flag is the part worth checking, because it lives in the same
|
|
; Status register and a careless mask would take it out.
|
|
;
|
|
; Correct output is:
|
|
; OKC
|
|
|
|
#Program
|
|
|
|
start:
|
|
; Load two registers, run the new instructions across them, and prove that
|
|
; nothing moved.
|
|
INIA 0d79 ; 'O'
|
|
INIB 0d75 ; 'K'
|
|
SIF
|
|
CIF
|
|
SIF
|
|
OUTA 0x00 ; Still 'O'.
|
|
OUTB 0x00 ; Still 'K'.
|
|
|
|
; Now set the Carry Flag, and work the Interrupt Flag around it.
|
|
CCF
|
|
INIA 0xFF
|
|
INIB 0x01
|
|
ADD ; Q = 0, and the Carry Flag is set.
|
|
SIF
|
|
CIF
|
|
BRC carryHeld ; splitlint: whether carry survived SIF and CIF is what is being tested
|
|
|
|
; Falling through here means one flag trampled the other.
|
|
INIA 0d88 ; 'X'
|
|
OUTA 0x00
|
|
INIA 0x0A
|
|
OUTA 0x00
|
|
HALT
|
|
|
|
carryHeld:
|
|
INIA 0d67 ; 'C'
|
|
OUTA 0x00
|
|
INIA 0x0A
|
|
OUTA 0x00
|
|
HALT
|