; ======================================================================
; XANDRIAN LABS  /  CS617 CHAPTER 09
; ======================================================================
; Program    : MathROM - Special Tests
; Source     : mathrom_special_tests.s
; Revision   : r029
; Target     : Casio PB-2000C / HD61700
; Role       : Check five type-specific native services.
; Interface  : PI, CNVR, B2BCD, CMP, RND12; 17 test cases.
; Maintainer : Xandrian Labs
; ----------------------------------------------------------------------
; This suite reuses DY_ scratch while the numeric sweep is idle.
; Its output distinguishes exact, unexpected and CHECK results.
; ======================================================================

; ----------------------------------------------------------------------
; IMPLEMENTATION NOTES
; ----------------------------------------------------------------------
; SP_ registers reuse the DY_ ledger; do not run suites together.

SP_IDX: EQU DY_FUNC
SP_STATS: EQU DY_STATUS
SP_PASS: EQU DY_COUNT
SP_FAIL: EQU DY_COUNT+1
SP_CHECK: EQU DY_COUNT+2
SP_RAW: EQU DY_LAST9

; ----------------------------------------------------------------------
; SPECIAL TEST DISPATCH
; ----------------------------------------------------------------------
SP_ENTER:
        PST UA,&H14
        CAL VT23_CLEAR
        PRE IX,MR_VROW
        LD $0,1
        ST $0,(IX+$SX)
        LDW $4,SP_TITLE
        LD $9,1
        LD $13,34
        CAL MR_PUT_ROM
        PRE IX,MR_VROW
        LD $0,2
        ST $0,(IX+$SX)
        LDW $4,SP_SUBTITLE
        LD $9,1
        LD $13,64
        CAL MR_PUT_ROM
        PRE IX,MR_VROW
        LD $0,4
        ST $0,(IX+$SX)
        LDW $4,SP_HEAD
        LD $9,1
        LD $13,61
        CAL MR_PUT_ROM
        PRE IX,SP_IDX
        LD $0,0
        ST $0,(IX+$SX)
        PRE IX,SP_PASS
        STI $0,(IX+$SX)
        STI $0,(IX+$SX)
        ST $0,(IX+$SX)
SP_LOOP:
        CAL SP_DISPATCH
        PRE IX,SP_IDX
        LD $0,(IX+$SX)
        AD $0,$SY
        ST $0,(IX+$SX)
        SBC $0,17
        JP C,SP_LOOP
        CAL SP_FOOTER
        CAL VT23_VIEW
        SBC $0,2
        JP Z,LAB_WARM
        JP MR_HOME

; ----------------------------------------------------------------------
; TYPE-SPECIFIC TEST CASES
; ----------------------------------------------------------------------
SP_DISPATCH:
        PST UA,&H14
        PRE IX,SP_IDX
        LD $0,(IX+$SX)
        SBC $0,0
        JP Z,SP_CASE0
        SBC $0,1
        JP Z,SP_CASE1
        SBC $0,2
        JP Z,SP_CASE2
        SBC $0,3
        JP Z,SP_CASE3
        SBC $0,4
        JP Z,SP_CASE4
        SBC $0,5
        JP Z,SP_CASE5
        SBC $0,6
        JP Z,SP_CASE6
        SBC $0,7
        JP Z,SP_CASE7
        SBC $0,8
        JP Z,SP_CASE8
        SBC $0,9
        JP Z,SP_CASE9
        SBC $0,10
        JP Z,SP_CASE10
        SBC $0,11
        JP Z,SP_CASE11
        SBC $0,12
        JP Z,SP_CASE12
        SBC $0,13
        JP Z,SP_CASE13
        SBC $0,14
        JP Z,SP_CASE14
        SBC $0,15
        JP Z,SP_CASE15
        JP SP_CASE16

SP_CASE0:
        CAL SP_ZERO_REG
        CAL MATH_PI
        JP SP_CAPTURE
SP_CASE1:
        LDW $15, 1
        CAL MATH_CNVR
        JP SP_CAPTURE
SP_CASE2:
        LDW $15, 123
        CAL MATH_CNVR
        JP SP_CAPTURE
SP_CASE3:
        LDW $15, 32767
        CAL MATH_CNVR
        JP SP_CAPTURE
SP_CASE4:
        LDW $15, &HFFFF
        CAL MATH_CNVR
        JP SP_CAPTURE
SP_CASE5:
        CAL SP_ZERO_REG
        LDW $3,1
        CAL MATH_B2BCD
        JP SP_CAPTURE
SP_CASE6:
        CAL SP_ZERO_REG
        LDW $3,9
        CAL MATH_B2BCD
        JP SP_CAPTURE
SP_CASE7:
        CAL SP_ZERO_REG
        LDW $3,10
        CAL MATH_B2BCD
        JP SP_CAPTURE
SP_CASE8:
        CAL SP_ZERO_REG
        LDW $3,99
        CAL MATH_B2BCD
        JP SP_CAPTURE
SP_CASE9:
        CAL SP_ZERO_REG
        LDW $3,123
        CAL MATH_B2BCD
        JP SP_CAPTURE
SP_CASE10:
        LDW $15,2
        CAL MATH_CNVR
        CAL MR_XSAVEA
        LDW $15,3
        CAL MATH_CNVR
        CAL MR_XSAVE_B
        CAL MR_XLOAD_B
        CAL MATH_CMP
        JP C,SP_FLAG_C
        JP Z,SP_FLAG_Z
        LD $10,0
        JP SP_FLAG_PACK
SP_CASE11:
        LDW $15,3
        CAL MATH_CNVR
        CAL MR_XSAVEA
        LDW $15,2
        CAL MATH_CNVR
        CAL MR_XSAVE_B
        CAL MR_XLOAD_B
        CAL MATH_CMP
        JP C,SP_FLAG_C
        JP Z,SP_FLAG_Z
        LD $10,0
        JP SP_FLAG_PACK
SP_CASE12:
        LDW $15,2
        CAL MATH_CNVR
        CAL MR_XSAVEA
        LDW $15,2
        CAL MATH_CNVR
        CAL MR_XSAVE_B
        CAL MR_XLOAD_B
        CAL MATH_CMP
        JP C,SP_FLAG_C
        JP Z,SP_FLAG_Z
        LD $10,0
        JP SP_FLAG_PACK
SP_CASE13:
        LDW $15,7
        CAL MATH_CNVR
        CAL MATH_RND12
        JP SP_CAPTURE
SP_CASE14:
        LDW $22,SP_INPUT14
        CAL SP_LOAD_B9
        CAL MATH_RND12
        JP SP_CAPTURE
SP_CASE15:
        LDW $22,SP_INPUT15
        CAL SP_LOAD_B9
        CAL MATH_RND12
        JP SP_CAPTURE
SP_CASE16:
        LDW $22,SP_INPUT16
        CAL SP_LOAD_B9
        CAL MATH_RND12
        JP SP_CAPTURE

; Snapshot C/Z with *only conditional branches* immediately after CMP.
; Encoded witness: 1 C=1/Z=0 (LT), 2 Z=1 (EQ), 0 C=0/Z=0 (GT).
SP_FLAG_C:
        JP Z,SP_FLAG_Z
        LD $10,1
        JP SP_FLAG_PACK
SP_FLAG_Z:
        LD $10,2
SP_FLAG_PACK:
        LD $11,0
        LD $12,0
        LD $13,0
        LD $14,0
        LD $15,0
        LD $16,0
        LD $17,0
        LD $18,0
        JP SP_CAPTURE

SP_ZERO_REG:
        LD $10,0
        LD $11,0
        LD $12,0
        LD $13,0
        LD $14,0
        LD $15,0
        LD $16,0
        LD $17,0
        LD $18,0
        RTN

; $22 points at a nine-byte literal B9 in ROM; only $10..$18 output changed.
SP_LOAD_B9:
        PRE IZ,$22
        LDM $10,(IZ+$SX),8
        LDW $24,$22
        LDW $20,8
        ADW $24,$20
        PRE IZ,$24
        LD $18,(IZ+$SX)
        RTN

SP_CAPTURE:
        LDW $8,SP_RAW
        CAL MR_SAVE9
        CAL SP_JUDGE
        CAL SP_ROW
        RTN

; Compute pointer to expected 9-byte record for the current case.
SP_EXP_PTR:
        LDW $4,SP_EXPECT
        PRE IX,SP_IDX
        LD $20,(IX+$SX)
SP_OFF9:
        AN $20,$20
        RTN Z
        LDW $0,9
        ADW $4,$0
        SB $20,$SY
        JP SP_OFF9

SP_JUDGE:
        PST UA,&H14
        CAL SP_EXP_PTR
        PRE IX,SP_IDX
        LD $0,(IX+$SX)
        SBC $0,5
        JP C,SP_COMPARE9
        SBC $0,10
        JP C,SP_COMPARE3
        SBC $0,13
        JP C,SP_COMPARE1
        JP SP_COMPARE9
SP_COMPARE3:
        LDW $0,4
        ADW $4,$0
        LDW $2,SP_RAW+4
        LD $20,3
        JP SP_COMPARE
SP_COMPARE1:
        LDW $2,SP_RAW
        LD $20,1
        JP SP_COMPARE
SP_COMPARE9:
        LDW $2,SP_RAW
        LD $20,9
SP_COMPARE:
        PRE IZ,$4
        PRE IX,$2
        LD $21,1
SP_COMP_LOOP:
        LDI $16,(IZ+$SX)
        LDI $17,(IX+$SX)
        SBC $16,$17
        JP Z,SP_MATCH_BYTE
        LD $21,3
SP_MATCH_BYTE:
        SB $20,$SY
        JP NZ,SP_COMP_LOOP
; Three positive CNVR integer anchors have definite integer oracles.
; Remaining mismatches are CHECK: BCD layout, sign, PI, flags and rounding
; are evidence-driven hypotheses until independently qualified.
        SBC $21,3
        JP NZ,SP_SAVE_STAT
        PRE IX,SP_IDX
        LD $0,(IX+$SX)
        SBC $0,1
        JP C,SP_SAVE_STAT
        SBC $0,4
        JP NC,SP_SAVE_STAT
        LD $21,2
SP_SAVE_STAT:
        PRE IX,SP_IDX
        LD $0,(IX+$SX)
        LDW $4,SP_STATS
        LDW $2,0
        LD $2,$0
        ADW $4,$2
        PRE IX,$4
        ST $21,(IX+$SX)
        SBC $21,1
        JP Z,SP_INC_PASS
        SBC $21,2
        JP Z,SP_INC_FAIL
        PRE IX,SP_CHECK
        JP SP_INC_STAT
SP_INC_PASS:
        PRE IX,SP_PASS
        JP SP_INC_STAT
SP_INC_FAIL:
        PRE IX,SP_FAIL
SP_INC_STAT:
        LD $0,(IX+$SX)
        AD $0,$SY
        ST $0,(IX+$SX)
        RTN

SP_ROW:
        PRE IX,SP_IDX
        LD $0,(IX+$SX)
        AD $0,5
        LD $8,$0
        PRE IX,MR_VROW
        ST $0,(IX+$SX)
        LDW $14,SP_LABELS
        PRE IX,SP_IDX
        LD $20,(IX+$SX)
SP_LABEL_ADV:
        AN $20,$20
        JP Z,SP_LABEL_DONE
        LDW $0,10
        ADW $14,$0
        SB $20,$SY
        JP SP_LABEL_ADV
SP_LABEL_DONE:
        LDW $10,SP_RAW
        CAL MR_RAW_ROW
        PRE IX,SP_IDX
        LD $0,(IX+$SX)
        LDW $4,SP_STATS
        LDW $2,0
        LD $2,$0
        ADW $4,$2
        PRE IX,$4
        LD $0,(IX+$SX)
        SBC $0,1
        JP Z,SP_TXT_PASS
        SBC $0,2
        JP Z,SP_TXT_FAIL
        LDW $4,SP_CHECK_TXT
        JP SP_TXT_WRITE
SP_TXT_PASS:
        LDW $4,SP_PASS_TXT
        JP SP_TXT_WRITE
SP_TXT_FAIL:
        LDW $4,SP_FAIL_TXT
SP_TXT_WRITE:
        LD $9,34
        LD $13,5
        CAL MR_PUT_ROM
        RTN

SP_FOOTER:
        PRE IX,MR_VROW
        LD $0,23
        ST $0,(IX+$SX)
        LDW $4,SP_FOOT
        LD $9,1
        LD $13,50
        CAL MR_PUT_ROM
        PRE IX,SP_PASS
        LD $0,(IX+$SX)
        CAL DY_TO_2DIG
        LDW $4,DY_NTXT
        LD $9,6
        LD $13,2
        CAL MR_PUT_RAM
        PRE IX,SP_FAIL
        LD $0,(IX+$SX)
        CAL DY_TO_2DIG
        LDW $4,DY_NTXT
        LD $9,15
        LD $13,2
        CAL MR_PUT_RAM
        PRE IX,SP_CHECK
        LD $0,(IX+$SX)
        CAL DY_TO_2DIG
        LDW $4,DY_NTXT
        LD $9,26
        LD $13,2
        CAL MR_PUT_RAM
        PRE IX,MR_VROW
        LD $0,24
        ST $0,(IX+$SX)
        LDW $4,SP_NOTE
        LD $9,1
        LD $13,67
        CAL MR_PUT_ROM
        RTN

SP_TITLE: DB "MATHROM / SPECIALIST F2 TEST PILOT"
SP_SUBTITLE: DB "17 DIRECT CASES / 5 SERVICES / NO DYADIC AGGREGATES               "
SP_HEAD: DB "CASE       RAW 10..18         VERDICT   (CMP BYTE=FLAG)           "
SP_PASS_TXT: DB "PASS "
SP_FAIL_TXT: DB "FAIL "
SP_CHECK_TXT: DB "CHECK"
SP_FOOT: DB "PASS:__  FAIL:__  CHECK:__  TOTAL=17              "
SP_NOTE: DB "EXPANDED B9 / BCD / CMP FLAGS. CHECK=PROVISIONAL. EMULATOR PENDING."
SP_LABELS:
SP_LBL0: DB "pi()      "
SP_LBL1: DB "cnvr(1)   "
SP_LBL2: DB "cnvr(123) "
SP_LBL3: DB "cnvr(max) "
SP_LBL4: DB "cnvr(-1)  "
SP_LBL5: DB "bcd(1)    "
SP_LBL6: DB "bcd(9)    "
SP_LBL7: DB "bcd(10)   "
SP_LBL8: DB "bcd(99)   "
SP_LBL9: DB "bcd(123)  "
SP_LBL10: DB "cmp(2,3)  "
SP_LBL11: DB "cmp(3,2)  "
SP_LBL12: DB "cmp(2,2)  "
SP_LBL13: DB "rnd12(7)  "
SP_LBL14: DB "rnd(down) "
SP_LBL15: DB "rnd(up)   "
SP_LBL16: DB "rnd carry "
SP_EXPECT:
SP_EXP0: DB &H90,&H35,&H65,&H92,&H15,&H14,&H03,&H00,&H01
SP_EXP1: DB &H00,&H00,&H00,&H00,&H00,&H00,&H01,&H00,&H01
SP_EXP2: DB &H00,&H00,&H00,&H00,&H00,&H23,&H01,&H02,&H01
SP_EXP3: DB &H00,&H00,&H00,&H00,&H67,&H27,&H03,&H04,&H01
SP_EXP4: DB &H00,&H00,&H00,&H00,&H00,&H00,&H01,&H00,&H06
SP_EXP5: DB &H00,&H00,&H00,&H00,&H01,&H00,&H00,&H00,&H00
SP_EXP6: DB &H00,&H00,&H00,&H00,&H09,&H00,&H00,&H00,&H00
SP_EXP7: DB &H00,&H00,&H00,&H00,&H10,&H00,&H00,&H00,&H00
SP_EXP8: DB &H00,&H00,&H00,&H00,&H99,&H00,&H00,&H00,&H00
SP_EXP9: DB &H00,&H00,&H00,&H00,&H23,&H01,&H00,&H00,&H00
SP_EXP10: DB &H01,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
SP_EXP11: DB &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
SP_EXP12: DB &H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
SP_EXP13: DB &H00,&H00,&H00,&H00,&H00,&H00,&H07,&H00,&H01
SP_EXP14: DB &H20,&H01,&H89,&H67,&H45,&H23,&H01,&H00,&H01
SP_EXP15: DB &H30,&H01,&H89,&H67,&H45,&H23,&H01,&H00,&H01
SP_EXP16: DB &H00,&H00,&H00,&H00,&H00,&H00,&H02,&H00,&H01
SP_INPUT14: DB &H23,&H01,&H89,&H67,&H45,&H23,&H01,&H00,&H01
SP_INPUT15: DB &H26,&H01,&H89,&H67,&H45,&H23,&H01,&H00,&H01
SP_INPUT16: DB &H96,&H99,&H99,&H99,&H99,&H99,&H01,&H00,&H01
