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