; CSCI 6461 Comprehensive Instruction Test Suite
; ------------------------------------------------
; This source contains every instruction defined by the August 2024 ISA.
;
; Entry points (decimal / octal):
;   Start       6 / 000006   Core integer self-test
;   IOTest    206 / 000316   Manual console I/O test
;   TrapTest  210 / 000322   Manual TRAP test
;   FPTest    225 / 000341   Phase IV floating/vector test
;
; Core test result:
;   memory location 277 decimal (000425 octal) = 1 on PASS
;   a failed comparison halts at 192 decimal (000300 octal),
;   or at the end of the block in which the failure occurred.
;
; Notes:
; - The I/O test waits for a keyboard character and echoes it.
; - The TRAP and floating/vector sections require the later simulator phases.
; - Numbers in source operands are decimal, as required by the assembler spec.

; ---------------- Reserved memory ----------------
LOC 0
Data TrapTable          ; location 0: address of TRAP vector table
Data FaultHandler       ; location 1: machine-fault handler address
Data 0                  ; location 2: saved PC for TRAP
Data 0                  ; location 3: unused
Data 0                  ; location 4: saved PC for machine fault
Data 0                  ; location 5: unused

; ---------------- Bootstrap ----------------
LOC 6
Start: LDX 2,20         ; X2 = address of Core1 (64)
       JMA 2,0          ; begin core test

; ---------------- Low-memory pointer table ----------------
LOC 19
STXScratchPtr: Data ScratchX ; pointer used by indirect STX
LOC 20
Core1Ptr:      Data Core1
Core2Ptr:      Data Core2
Core3Ptr:      Data Core3
LogicPtr:      Data LogicBlock
IOPtr:         Data IOBlock
FPPtr:         Data FPBlock
DataPtr:       Data TestData
FPDataPtr:     Data FPData
TrapTablePtr:  Data TrapTable
TrapHandlerPtr: Data TrapHandler
FaultHandlerPtr: Data FaultHandler
SubroutinePtr: Data Subroutine

; ============================================================
; CORE BLOCK 1: load/store/address and memory arithmetic
; Base X2 = 64. X1 = test data base. X3 = Core3 base for fail halt.
; ============================================================
LOC 64
Core1: LDX 1,26         ; LDX: X1 = TestData (256)
       LDX 3,22         ; X3 = Core3 base (128)

       LDR 0,1,9        ; LDR: R0 = 10
       LDR 1,1,9        ; R1 = 10
       TRR 0,1
       JCC 3,2,7        ; equal -> address 71
       JMA 3,31         ; fail -> 159

       STR 0,1,20       ; STR: save 10 in scratch
       LDR 1,1,0        ; clear R1 with zero
       LDR 1,1,20       ; reload scratch
       TRR 0,1
       JCC 3,2,13       ; equal -> address 77
       JMA 3,31

       LDA 2,1,5        ; LDA: R2 = 256 + 5 = 261
       LDR 3,1,17       ; expected 261
       TRR 2,3
       JCC 3,2,18       ; equal -> address 82
       JMA 3,31

       LDR 0,1,4        ; R0 = 5
       AMR 0,1,6        ; AMR: 5 + 7 = 12
       LDR 1,1,11       ; expected 12
       TRR 0,1
       JCC 3,2,24       ; equal -> address 88
       JMA 3,31

       SMR 0,1,6        ; SMR: 12 - 7 = 5
       LDR 1,1,4        ; expected 5
       TRR 0,1
       JCC 3,2,29       ; equal -> address 93
       JMA 3,31

       LDX 2,21         ; X2 = Core2 (96)
       JMA 2,0
       HLT              ; block-local failure stop

; ============================================================
; CORE BLOCK 2: immediate and transfer instructions
; ============================================================
LOC 96
Core2: LDR 0,1,4        ; R0 = 5
       AIR 0,3          ; AIR: R0 = 8
       LDR 1,1,7        ; expected 8
       TRR 0,1
       JCC 3,2,6        ; equal -> 102
       JMA 3,31

       SIR 0,3          ; SIR: R0 = 5
       LDR 1,1,4
       TRR 0,1
       JCC 3,2,11       ; equal -> 107
       JMA 3,31

       LDR 0,1,0        ; R0 = 0
       JZ 0,2,14        ; JZ taken -> 110
       JMA 3,31

       LDR 0,1,1        ; R0 = 1
       JNE 0,2,17       ; JNE taken -> 113
       JMA 3,31

       JMA 2,19         ; JMA -> 115
       JMA 3,31         ; must be skipped

       LDR 0,1,2        ; R0 = 2
       SOB 0,2,20       ; loops at 116 until R0 becomes 0
       LDR 1,1,0
       TRR 0,1
       JCC 3,2,25       ; equal -> 121
       JMA 3,31

       LDR 0,1,12       ; R0 = -1
       JGE 0,2,28       ; must NOT branch to failure at 124
       JMA 2,29         ; continue at 125
       JMA 3,31         ; failure if JGE incorrectly branches

       LDX 2,22         ; X2 = Core3 (128)
       JMA 2,0
       HLT

; ============================================================
; CORE BLOCK 3: subroutine, multiply, and divide
; ============================================================
LOC 128
Core3: LDX 3,31         ; X3 = Subroutine (152)
       JSR 3,0          ; JSR; RFS returns to address 130
       LDX 3,23         ; X3 = LogicBlock (160), fail target = 191
       LDR 1,1,18       ; expected RFS return code 17
       TRR 0,1
       JCC 3,2,7        ; equal -> 135
       JMA 3,31

       LDR 0,1,3        ; R0 = 3
       LDR 2,1,4        ; R2 = 5
       MLT 0,2          ; MLT: R0:R1 = 15
       LDR 2,1,0        ; expected high word 0
       TRR 0,2
       JCC 3,2,14       ; equal -> 142
       JMA 3,31
       LDR 2,1,10       ; expected low word 15
       TRR 1,2
       JCC 3,2,18       ; equal -> 146
       JMA 3,31

       LDR 0,1,10       ; dividend = 15
       LDR 2,1,8        ; divisor = 4
       DVD 0,2          ; DVD: quotient R0=3, remainder R1=3
       LDR 2,1,3
       TRR 0,2
       JCC 3,2,26       ; equal -> 154

Subroutine: RFS 17      ; RFS: R0=17; PC <- R3
       HLT              ; safety stop if entered sequentially

       TRR 1,2          ; verify remainder = 3
       JCC 3,2,29       ; equal -> 157
       JMA 3,31
       LDX 2,23         ; X2 = LogicBlock (160)
       JMA 2,0
       HLT              ; failure at 159

; ============================================================
; LOGIC BLOCK: register logic and shift/rotate
; ============================================================
LOC 160
LogicBlock: LDX 3,24    ; X3 = IOBlock (192); failure target = 192
       LDR 0,1,11       ; 12
       LDR 1,1,9        ; 10
       AND 0,1          ; AND: 12 & 10 = 8
       LDR 2,1,7
       TRR 0,2
       JCC 3,2,8        ; equal -> 168
       JMA 3,0

       LDR 0,1,11       ; 12
       LDR 1,1,3        ; 3
       ORR 0,1          ; ORR: 12 | 3 = 15
       LDR 2,1,10
       TRR 0,2
       JCC 3,2,15       ; equal -> 175
       JMA 3,0

       LDR 0,1,0        ; 0
       NOT 0            ; NOT: R0 = 0xFFFF (-1)
       LDR 1,1,12
       TRR 0,1
       JCC 3,2,21       ; equal -> 181
       JMA 3,0

       LDR 0,1,3        ; 3
       SRC 0,2,1,1      ; SRC: logical left shift 2 -> 12
       LDR 1,1,11
       TRR 0,1
       JCC 3,2,27       ; equal -> 187
       JMA 3,0

       LDR 0,1,1        ; 1
       RRC 0,1,0,1      ; RRC: logical rotate right -> 0x8000
       LDR 1,1,16
       TRR 0,1
       JCC 3,3,1        ; equal -> 193; otherwise fall into fail HLT

; ============================================================
; I/O BLOCK: final core memory tests and optional I/O/TRAP tests
; ============================================================
LOC 192
IOBlock: HLT            ; common core failure stop (000300 octal)
       LDX 2,24         ; X2 = IOBlock (192)
       LDX 3,25         ; X3 = FPBlock (224); failure target = 224

       STX 1,19,1       ; STX: indirect store X1 (256) into ScratchX
       LDR 0,1,20
       LDR 1,1,19       ; expected 256
       TRR 0,1
       JCC 3,2,9        ; equal -> 201
       JMA 3,0

       LDR 0,1,24,1     ; indirect LDR: pointer at 280 -> value at 278
       LDR 1,1,22       ; expected 42
       TRR 0,1
       JCC 3,2,21       ; equal -> CorePass at 213
       JMA 3,0

IOTest: CHK 0,0         ; CHK keyboard status into R0
        IN 1,0          ; IN one keyboard character into R1
        OUT 1,1         ; OUT character to console printer
        HLT

TrapTest: TRAP 0        ; TRAP using vector table at location 0
          HLT           ; safety stop if simulator returns here
          HLT

CorePass: LDR 0,1,1     ; R0 = 1
          STR 0,1,21    ; memory[277] = 1 means core PASS
          HLT

; ============================================================
; PHASE IV BLOCK: floating point and vector operations
; Run separately by setting PC to 225 decimal (000341 octal).
; ============================================================
LOC 224
FPBlock: HLT            ; floating/vector failure stop
FPTest:  LDX 1,27       ; X1 = FPData (320)
         LDFR 0,1,0     ; LDFR: load floating zero into FR0
         FADD 0,1,2     ; FADD zero
         FSUB 0,1,2     ; FSUB zero
         STFR 0,1,4     ; STFR result to scratch
         LDR 0,1,4
         LDR 1,1,0
         TRR 0,1
         JCC 3,2,11     ; equal -> 235
         JMA 2,0

         LDR 0,1,0      ; F selector = 0
         CNVRT 0,1,2    ; CNVRT floating zero to fixed zero
         TRR 0,1
         JCC 3,2,16     ; equal -> 240
         JMA 2,0

         LDFR 0,1,6     ; FR0 = vector length 1
         VADD 0,1,8     ; vector[330] = 5 + 3 = 8
         LDR 0,1,10
         LDR 1,1,14
         TRR 0,1
         JCC 3,2,23     ; equal -> 247
         JMA 2,0

         VSUB 0,1,8     ; vector[330] = 8 - 3 = 5
         LDR 0,1,10
         LDR 1,1,15
         TRR 0,1
         JCC 3,2,29     ; equal -> 253
         JMA 2,0

         LDR 0,1,1
         STR 0,1,16     ; FPData+16 = 1 means phase IV PASS
         HLT

; ---------------- Core test data ----------------
LOC 256
TestData:
D0:       Data 0
D1:       Data 1
D2:       Data 2
D3:       Data 3
D5:       Data 5
D6:       Data 6
D7:       Data 7
D8:       Data 8
D4:       Data 4
D10:      Data 10
D15:      Data 15
D12:      Data 12
DNEG1:    Data -1
D240:     Data 240
DZERO14:  Data 0
DZERO15:  Data 0
D32768:   Data 32768
D261:     Data 261
D17:      Data 17
D256:     Data 256
ScratchX: Data 0
CoreResult: Data 0       ; address 277 decimal; set to 1 on core PASS
D42:      Data 42
Scratch2: Data 0
Ptr42:    Data D42       ; address 280 contains pointer 278
          Data 0
          Data 0
          Data 0
          Data 0
          Data 0
          Data 0
          Data 0

; ---------------- Floating/vector test data ----------------
LOC 320
FPData:
FPZeroA:   Data 0
FPZeroB:   Data 0
FPZeroC:   Data 0
FPZeroD:   Data 0
FPScratch0: Data 0
FPScratch1: Data 0
VectorLen: Data 1
           Data 0
VectorPtrs: Data VectorA
            Data VectorB
VectorA:    Data 5
VectorB:    Data 3
            Data 0
            Data 0
Expected8:  Data 8
Expected5:  Data 5
FPResult:   Data 0       ; set to 1 on phase IV PASS

; ---------------- TRAP and fault support ----------------
LOC 400
TrapTable:
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler
Data TrapHandler

LOC 416
TrapHandler: HLT        ; successful TRAP 0 should arrive here

LOC 432
FaultHandler: HLT       ; machine faults should arrive here
