mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 20:33:39 +00:00
168 lines
4.6 KiB
Lua
168 lines
4.6 KiB
Lua
%target cx16
|
|
%import test_stack
|
|
%import textio
|
|
%zeropage basicsafe
|
|
%option no_sysinit
|
|
|
|
|
|
main {
|
|
|
|
sub start() {
|
|
txt.print("\nassembler benchmark - tree match routine\n")
|
|
|
|
benchmark.benchmark()
|
|
|
|
test_stack.test()
|
|
}
|
|
|
|
}
|
|
|
|
benchmark {
|
|
sub benchmark() {
|
|
str[20] mnemonics = ["lda", "ldx", "ldy", "jsr", "bcs", "rts", "lda", "ora", "and", "eor", "wai", "nop", "wai", "nop", "wai", "nop", "wai", "nop", "wai", "nop"]
|
|
ubyte[20] modes = [3, 4, 8, 8, 7, 1, 12, 13, 5, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
|
uword valid = 0
|
|
|
|
const uword iterations = 40000 / len(mnemonics)
|
|
const uword amount = iterations * len(mnemonics)
|
|
|
|
txt.print("matching ")
|
|
txt.print_uw(amount)
|
|
txt.print(" mnemonics")
|
|
|
|
c64.SETTIM(0,0,0)
|
|
|
|
uword total = 0
|
|
repeat iterations {
|
|
if lsb(total)==0
|
|
txt.chrout('.')
|
|
ubyte idx
|
|
for idx in 0 to len(mnemonics)-1 {
|
|
uword instr_info = instructions.match(mnemonics[idx])
|
|
ubyte opcode = instructions.opcode(instr_info, modes[idx])
|
|
if_cs
|
|
valid++
|
|
total++
|
|
}
|
|
}
|
|
|
|
uword current_time = c64.RDTIM16()
|
|
txt.print("\nvalid: ")
|
|
txt.print_uw(valid)
|
|
txt.print("\ninvalid: ")
|
|
txt.print_uw(amount-valid)
|
|
txt.print("\ntotal: ")
|
|
txt.print_uw(total)
|
|
txt.print("\n\nseconds:")
|
|
uword secs = current_time / 60
|
|
current_time = (current_time - secs*60)*1000/60
|
|
txt.print_uw(secs)
|
|
txt.chrout('.')
|
|
if current_time<10
|
|
txt.chrout('0')
|
|
if current_time<100
|
|
txt.chrout('0')
|
|
txt.print_uw(current_time)
|
|
txt.nl()
|
|
}
|
|
}
|
|
|
|
instructions {
|
|
asmsub match(uword mnemonic_ptr @AY) -> uword @AY {
|
|
; -- input: mnemonic_ptr in AY, output: pointer to instruction info structure or $0000 in AY
|
|
%asm {{
|
|
phx
|
|
sta P8ZP_SCRATCH_W1
|
|
sty P8ZP_SCRATCH_W1+1
|
|
ldy #0
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
pha
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
pha
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
pha
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
sta cx16.r4 ; fourth letter in R4 (only exists for the few 4-letter mnemonics)
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
sta cx16.r5 ; fifth letter in R5 (should always be zero or whitespace for a valid mnemonic)
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
jsr get_opcode_info
|
|
plx
|
|
rts
|
|
}}
|
|
}
|
|
|
|
asmsub opcode(uword instr_info_ptr @AY, ubyte addr_mode @X) clobbers(X) -> ubyte @A, ubyte @Pc {
|
|
; -- input: instruction info struct ptr @AY, desired addr_mode @X
|
|
; output: opcode @A, valid @carrybit
|
|
%asm {{
|
|
cpy #0
|
|
beq _not_found
|
|
sta P8ZP_SCRATCH_W2
|
|
sty P8ZP_SCRATCH_W2+1
|
|
stx cx16.r15
|
|
|
|
; debug result address
|
|
;sec
|
|
;jsr txt.print_uwhex
|
|
;lda #13
|
|
;jsr c64.CHROUT
|
|
|
|
ldy #0
|
|
lda (P8ZP_SCRATCH_W2),y
|
|
beq _multi_addrmodes
|
|
iny
|
|
lda (P8ZP_SCRATCH_W2),y
|
|
cmp cx16.r15 ; check single possible addr.mode
|
|
bne _not_found
|
|
iny
|
|
lda (P8ZP_SCRATCH_W2),y ; get opcode
|
|
sec
|
|
rts
|
|
|
|
_not_found lda #0
|
|
clc
|
|
rts
|
|
|
|
_multi_addrmodes
|
|
ldy cx16.r15
|
|
lda (P8ZP_SCRATCH_W2),y ; check opcode for addr.mode
|
|
bne _valid
|
|
; opcode $00 usually means 'invalid' but for "brk" it is actually valid so check for "brk"
|
|
ldy #0
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
cmp #'b'
|
|
bne _not_found
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
cmp #'r'
|
|
bne _not_found
|
|
iny
|
|
lda (P8ZP_SCRATCH_W1),y
|
|
and #$7f ; lowercase
|
|
cmp #'k'
|
|
bne _not_found
|
|
lda #0
|
|
_valid sec
|
|
rts
|
|
}}
|
|
}
|
|
|
|
%asminclude "opcodes.asm", ""
|
|
}
|