1; Verifies timing of branch instructions 2; 3; Runs branch instruction in loop that counts iterations 4; until APU length counter expires. Moves the loop around 5; in memory to trigger page cross/no cross cases. 6 7.include "shell.inc" 8 9zp_byte opcode 10zp_byte flags 11zp_byte time_ptr 12bss_res times,8 13 14main: 15 set_test 0 16 for_loop test_opcode,$10,$F0,$20 17 jmp tests_done 18 19log_time: 20 ldx time_ptr 21 sta times,x 22 inc time_ptr 23 rts 24 25test_opcode: 26 sta opcode 27 28 ; Not taken 29 ldx #$FF 30 and #$20 31 beq :+ 32 inx 33: stx flags 34 setb time_ptr,0 35 jsr test_addrs 36 37 ; Taken 38 lda flags 39 eor #$FF 40 sta flags 41 jsr test_addrs 42 43 ; Verify times 44 ldx #8 - 1 45: lda times,x 46 cmp @correct_times,x 47 bne @error 48 dex 49 bpl :- 50 51 rts 52 53@correct_times: 54 .byte 2,2,2,2,3,3,4,4 55 56@error: lda opcode 57 jsr print_a 58 jsr play_byte 59 ldy #0 60: lda times,y 61 jsr print_dec 62 jsr print_space 63 iny 64 cpy #8 65 bne :- 66 jsr print_newline 67 set_test 1 68 rts 69 70; Tests instruction with page cross/no cross cases 71test_addrs: 72 setw addr,$6EA 73 jsr test_forward 74 75 setw addr,$700 76 jsr test_reverse 77 78 setw addr,$6EB 79 jsr test_forward 80 81 setw addr,$6FF 82 jsr test_reverse 83 84 rts 85 86; Times code at addr 87time_code: 88 pha 89 90 ; Synchronize with APU length counter 91 setb SNDMODE,$40 92 setb SNDCHN,$01 93 setb $4000,$10 94 setb $4001,$7F 95 setb $4002,$FF 96 setb $4003,$18 97 lda #$01 98: and SNDCHN 99 bne :- 100 101 ; Setup length counter 102 setb $4003,$18 103 104 delay 29830-7120 105 106 ; Run instruction 107 setb temp,0 108 pla 109 jmp (addr) 110 111raw_to_cycles: ; entry i is lowest value that qualifies for i cycles 112 .byte 250, 241, 233, 226, 219, 213, 206, 201, 195, 190, 0 113 114; Jumps here when instruction has been timed 115instr_done: 116 ; Convert iteration count to cycle count 117 lda temp 118 ldy #-1 119: iny 120 cmp raw_to_cycles,y 121 blt :- 122 123 ; Convert 10+ to 0 124 cpy #10 125 blt :+ 126 ldy #0 127: 128 tya 129 jsr log_time 130 131 rts 132 133.macro test_dir 134 ; Copy code 135 ldy #40 136: lda @code,y 137 sta (addr),y 138 dey 139 bpl :- 140 141 ; Patch branch opcode 142 ldy #@branch - @code 143 lda opcode 144 sta (addr),y 145 146 ; Calculate address of @loop 147 lda addr 148 clc 149 adc #@loop - @code 150 sta addr 151 lda addr+1 152 adc #0 153 sta addr+1 154 155 jmp time_code 156@code: 157.endmacro 158 159.macro instr_loop 160 inc temp 161 lda SNDCHN 162 and #$01 163 beq *+5 164 jmp (addr) 165 jmp instr_done 166.endmacro 167 168test_reverse: 169 test_dir 170: instr_loop 171@loop: lda flags 172 pha 173 plp 174@branch: 175 bmi :- 176 instr_loop 177 178test_forward: 179 test_dir 180@loop: lda flags 181 pha 182 plp 183@branch: 184 bmi :+ 185 instr_loop 186: instr_loop 187