REGION_FREE = 1 .include "shell.inc" .include "crc_fast.s" zp_byte in_p zp_byte in_a zp_byte in_x zp_byte in_y zp_byte in_s .macro entry opcode,name,crc_0,crc_1,crc_2,crc_3 jsr reset_crc lda #opcode sta opcode_byte - testcase_entry + testcase_instance jsr run_testcase ; testcase_0 OPERANDS + 4,{testcase opcode} lda checksum cmp #crc_0 jne fail lda checksum+1 cmp #crc_1 jne fail lda checksum+2 cmp #crc_2 jne fail lda checksum+3 cmp #crc_3 jne fail .endmacro testcase_entry: lda in_p pha lda in_a ldx in_x ldy in_y plp opcode_byte: .byte 0 .if OPERANDS > 0 ; .out .sprintf(" 1: %s", .string(op_1)) .byte 0 .endif .if OPERANDS > 1 ; .out .sprintf(" 2: %s", .string(op_2)) .byte 0 .endif php pha txa pha tya pha ; Stack: pla jsr update_crc_fast pla jsr update_crc_fast pla jsr update_crc_fast pla jsr update_crc_fast rts testcase_entry_size = * - testcase_entry ; .macro testcase opcode, reg_p, reg_a, reg_x, reg_y, op_1, op_2 ; jsr crc_calc ; .out .sprintf("OP: %s", .string(opcode)) ; .out .sprintf(" S: %s", .string(reg_p)) ; .out .sprintf(" A: %s", .string(reg_a)) ; .out .sprintf(" X: %s", .string(reg_x)) ; .out .sprintf(" Y: %s", .string(reg_y)) ; .endmacro ; .macro testcase_6 opcode, ops ; testcase opcode, ops ; ; .mid(0, 1, ops), .mid(1, 1, ops), .mid(2, 1, ops), .mid(3, 1, ops), .mid(4, 1, ops), .mid(5, 1, ops) ; .endmacro ; .macro testcase_0 count,ins ; .if count > 0 ; testcase_0 count - 1, {ins,0} ; testcase_0 count - 1, {ins,1} ; testcase_0 count - 1, {ins,2} ; testcase_0 count - 1, {ins,$40} ; testcase_0 count - 1, {ins,$7F} ; testcase_0 count - 1, {ins,$80} ; testcase_0 count - 1, {ins,$81} ; testcase_0 count - 1, {ins,$FF} ; ; .byte 0,1,2,$40,$7F,$80,$81,$FF ; .else ; ins ; .endif ; .endmacro .pushseg .segment "BSS" testcase_instance: .res testcase_entry_size .popseg testcase_init: ldx #0 @loop: lda testcase_entry,x sta testcase_instance,x inx cpx #testcase_entry_size bmi @loop rts ; values: ; .byte 0,1,2,$40,$7F,$80,$81,$FF ; values_size = * - values ; .byte 0,1,2,$40,$7F,$80,$81,$FF .macro increment pos, next, done lda pos cmp #0 bne @a_1 lda #1 sta pos jmp done @a_1: cmp #1 bne @a_2 lda #2 sta pos jmp done @a_2: cmp #2 bne @a_40 lda #40 sta pos jmp done @a_40: cmp #$40 bne @a_7F lda #$7F sta pos jmp done @a_7F: cmp #$7F bne @a_80 lda #$80 sta pos jmp done @a_80: cmp #$80 bne @a_81 lda #$81 sta pos jmp done @a_81: cmp #$81 bne @a_FF lda #$FF sta pos jmp done @a_FF: cmp #$FF lda #0 sta pos jmp next .endmacro run_testcase: increment in_a, increment_x, done increment_x: increment in_x, increment_y, done increment_y: increment in_y, increment_p, done increment_p: increment in_p, ret, done done: jsr testcase_instance jmp run_testcase ret: rts ; Defines instruction to test ; Values set_paxyso sets registers to. Set ; before calling test_values, which can then ; overwrite them if desired. ; Temporary space for check_paxyso zp_byte out_a zp_byte out_x zp_byte out_s ; Values to cycle through for registers ; ; Sets bytes on stack around in_s ; .macro set_stack ; ldx in_s ; inx ; inx ; ldy #6 ; : txa ; asl ; eor #$A5 ; sta $100,x ; dex ; dey ; bne :- ; .endmacro ; ; Checksums bytes on stack around in_s ; .macro check_stack ; ldx in_s ; inx ; inx ; ldy #6 ; : lda $100,x ; dex ; jsr update_crc ; dey ; bne :- ; .endmacro ; ; Sets P, A, X, Y, S, and operand ; .macro set_paxyso ; ldx in_s ; txs ; lda values,y ; sta operand ; lda in_p ; pha ; lda in_a ; ldx in_x ; ldy in_y ; plp ; .endmacro ; ; Checksums P, A, X, Y, S, and operand ; .macro check_paxyso ; php ; sta out_a ; pla ; stx out_x ; tsx ; stx out_s ; ldx saved_s ; txs ; cld ; jsr update_crc_fast ; lda out_a ; jsr update_crc_fast ; lda out_x ; jsr update_crc_fast ; tya ; jsr update_crc_fast ; lda out_s ; jsr update_crc_fast ; lda operand ; jsr update_crc_fast ; .endmacro