module ZXUtils::Benchmark::Macros
ZXUtils::Benchmark
macros.¶ ↑
Public Instance Methods
calculate_benchmark_tstates(counter, tsframe, frames, idle, adjustment)
click to toggle source
Returns the benchmark result.
Calculates: (frames*(tsframe - 102) + tsframe - (idle*512 + signed adjustment)) / counter - 82 Limit: Tested routine should not take longer than 65453 T-states
# File lib/zxutils/benchmark.rb, line 88 def calculate_benchmark_tstates(counter, tsframe, frames, idle, adjustment) with_saved :exx, hl, :exx, ret: true, isolate: true do # a|hl = tsframe-102 ld hl, [tsframe.bytes[0]] ld a, [tsframe.bytes[2]] ld c, a ld de, -102 add24_16(c, hl, de, signed:true) # a|hl = tsframe-102 # a|hl|de = frames*(tsframe-102) ld bc, [frames] push af # a: res.hi24 (tsframe-102).hi24 push bc mul16_32(bc, tt:bc) # hl|hl'=res.lo * frames pop de # de: frames pop af # a: res.hi24 push hl # res2.hi: (res.lo * frames).hi (4) 300898 exx push hl # res2.lo: (res.lo * frames).lo (38754) exx ld b, a # b: res.hi24 mul8_24(d, e, b, t:c, tt:de, clrahl:true) # a|hl = res.hi24*frames pop de # res2.lo pop bc # res2.hi add hl, bc adc 0 # res3: a|hl|de = frames*(tsframe-102) overflw report_error_unless Z, 'B Integer out of range' exx # 0|hl'|de' = frames*(tsframe-102) # c|hl = idle*512 ld hl, [idle] # hl: idle, a: 0 ld c, h # idle*512 (<< 9) c=h|h=l|l=0 ld h, l ld l, a sla h rl c # c|hl: idle*512 # a|hl = idle*512 + signed adjustment ld de, [adjustment] add24_16(c, hl, de, signed:true) # a|hl = idle*512 + adjustment # a|hl = tsframe - (idle*512 + adjustment) ld c, a ex de, hl # c|de: idle*512 + adjustment ld hl, [tsframe.bytes[0]] ld a, [tsframe.bytes[2]] # a|hl: tsframe ora a # CF=0 sbc hl, de # a|hl: tsframe-(idle*512 + adjustment) sbc c # hl|de = frames*(tsframe-102) + tsframe - (idle*512 + adjustment) push hl #........hl'|de' + a|hl exx # hl|de: frames*(tsframe-102) pop bc # a|bc: tsframe-(idle*512 + adjustment) ex de, hl add hl, bc ex de, hl # de: de + bc ld b, 0 ld c, a # bc: 0|a adc hl, bc # hl|de: frames*(tsframe-92-22) + tsframe-(idle*512 + adjustment) jr C, overflw.err # +hl+|+hl' = round((frames*(tsframe-102) + tsframe - (idle*512 + adjustment)) / counter) push de exx pop hl ld de, [counter] push de srl d rr e # counter/2 add hl, de # hl' = hl' + counter/2 exx ld de, 0 adc hl, de # +hl+|+hl' = +hl+|+hl' + counter/2 jr C, overflw.err pop de # counter divmod32_16 check0:overflw.err # +hl+|+hl' = +hl+|+hl'+ / +de+ ld a, l ora h jp NZ, overflw.err exx # +bc+ = round((frames*(tsframe-102) + tsframe - (idle*512 + adjustment)) / counter) - 82 ld bc, 82 sbc hl, bc ld16 bc, hl end end
estimate_tstates_per_interrupt(stack_end, interrup_vec, forward, tsframe, idle)
click to toggle source
Estimates the number of T-States between interrupts.
# File lib/zxutils/benchmark.rb, line 171 def estimate_tstates_per_interrupt(stack_end, interrup_vec, forward, tsframe, idle) isolate do di ld [restore_sp+1], sp ld sp, stack_end ld hl, inthandler ld [forward+1], hl ld a, interrup_vec>>8 ld i, a im2 ld hl, finale ei halt # 19 (accepting interrupt) + 10 (forward) + 14 (inthandler) ld [forward+1], hl # 16 ld hl, forever # 10 ld bc, 0 # 10 #=79 forever inc c # 4 126.times { nop } # 126*4 jp (hl) # 4 #=512 finale ld [idle], bc # idle*512 + (pc==forever ? 0 : (pc - finale)*4) + 79 pop de # de: pc xor a sbc hl, de # hl: forever - pc (pc >= forever) jr Z, no_adjust # hl: 0 ex de, hl # hl: pc ld de, finale xor a sbc hl, de # pc - finale add hl, hl # (pc - finale)*4 add hl, hl # hl: (pc - finale)*4 no_adjust ld a, 79 adda_to h,l # hl: (pc - finale)*4 + 79 ex de, hl # de: (pc - finale)*4 + 79 ld h, c # idle*512 (<< 9) b=0|h=c|l=0 ld l, b sla h rl b # b|hl: idle*512 # idle*512 + (pc - finale)*4 + 79 add24_16(b, hl, de, signed:true) ld [tsframe.bytes[0]], hl ld [tsframe.bytes[2]], a # return (pc - finale)*4 + 79 ld16 bc, de restore_sp ld sp, 0 restore_rom_interrupt_handler ret inthandler ei # 4 ret # 10 end end