This commit is contained in:
Irmen de Jong 2021-01-05 04:46:25 +01:00
parent dde6919446
commit 4309a0dc68

View File

@ -25,7 +25,7 @@ textparse {
str input_line = "?" * 40 str input_line = "?" * 40
uword[3] word_addrs uword[3] word_addrs
uword program_counter = $1000 uword program_counter = $4000
sub user_input() { sub user_input() {
repeat { repeat {
@ -134,6 +134,10 @@ textparse {
txt.print("?invalid operand\n") txt.print("?invalid operand\n")
} else { } else {
ubyte num_operand_bytes = operand_size[addr_mode-1] ubyte num_operand_bytes = operand_size[addr_mode-1]
if not parse_operand_value(operand_ptr, addr_mode) {
txt.print("?invalid operand")
return
}
; txt.print("(debug:) addr.mode: ") ; txt.print("(debug:) addr.mode: ")
; txt.print_ub(addr_mode) ; txt.print_ub(addr_mode)
; txt.chrout('\n') ; txt.chrout('\n')
@ -141,8 +145,11 @@ textparse {
txt.print_uwhex(program_counter, 1) txt.print_uwhex(program_counter, 1)
txt.print(" ") txt.print(" ")
emit(opcode) emit(opcode)
repeat num_operand_bytes { if num_operand_bytes==1 {
emit($00) ; TODO determine correct bytes emit(lsb(cx16.r0))
} else if num_operand_bytes == 2 {
emit(lsb(cx16.r0))
emit(msb(cx16.r0))
} }
repeat 2-num_operand_bytes { repeat 2-num_operand_bytes {
txt.print(" ") txt.print(" ")
@ -190,6 +197,85 @@ textparse {
} }
} }
sub dummy(uword operand_ptr) -> uword {
uword a1=rndw()
uword a6=a1+operand_ptr
return a6
}
sub parse_operand_value(uword operand_ptr, ubyte addr_mode) -> ubyte {
; -- returns true/false success status, the value is in cx16.r0 if succesful
; TODO number parsing error detection
; TODO optimize this (coalesce various parsing options)
; TODO fix number parsing by ending the number with \0 after the last digit
when addr_mode {
instructions.am_Imp, instructions.am_Acc -> {
; nop / asl a (no operands)
return true
}
instructions.am_Imm -> {
; lda #$12
cx16.r0 = parse_number(operand_ptr+1)
debug_print_value(operand_ptr+1)
return true
}
instructions.am_Zp, instructions.am_Zpr -> {
; lda $02 / brr0 $12,label
cx16.r0 = parse_number(operand_ptr)
debug_print_value(operand_ptr)
return true
}
instructions.am_ZpX, instructions.am_ZpY -> {
; lda $02,x / lda $02,y
cx16.r0 = parse_number(operand_ptr)
debug_print_value(operand_ptr)
return true
}
instructions.am_Rel -> {
cx16.r0 = parse_number(operand_ptr)
; TODO calcualate relative offset to current programcounter
debug_print_value(operand_ptr)
return true
}
instructions.am_Abs -> {
; jmp $1234
cx16.r0 = parse_number(operand_ptr)
debug_print_value(operand_ptr)
return true
}
instructions.am_AbsX, instructions.am_AbsY -> {
; sta $3000,x / sta $3000,y
cx16.r0 = parse_number(operand_ptr)
debug_print_value(operand_ptr)
return true
}
instructions.am_Ind -> {
; jmp ($fffc)
cx16.r0 = parse_number(operand_ptr+1)
debug_print_value(operand_ptr+1)
return true
}
instructions.am_IzX, instructions.am_IzY, instructions.am_Izp, instructions.am_IaX -> {
; lda ($02,x) / lda ($02),y / lda ($02) / jmp ($a000,x)
cx16.r0 = parse_number(operand_ptr+1)
debug_print_value(operand_ptr+1)
return true
}
}
return false
sub debug_print_value(uword optr) {
txt.print("(debug:) operand=")
txt.print(optr)
txt.print(" -> value: ")
txt.print_uwhex(cx16.r0, true)
txt.chrout('\n')
}
}
sub parse_number(uword strptr) -> uword { sub parse_number(uword strptr) -> uword {
; TODO move to conv module and optimize ; TODO move to conv module and optimize
if @(strptr)=='$' if @(strptr)=='$'
@ -239,8 +325,8 @@ textparse {
input_line[char_idx] = 0 input_line[char_idx] = 0
} }
sub debug_print_words() { sub debug_print_words() { ; TODO remove
txt.print("(debug:) words: ") ; TODO remove txt.print("(debug:) words: ")
uword word_ptr uword word_ptr
for word_ptr in word_addrs { for word_ptr in word_addrs {
txt.chrout('[') txt.chrout('[')
@ -328,66 +414,67 @@ benchmark {
} }
instructions { instructions {
const ubyte am_Invalid = 0
const ubyte am_Imp = 1
const ubyte am_Acc = 2
const ubyte am_Imm = 3
const ubyte am_Zp = 4
const ubyte am_ZpX = 5
const ubyte am_ZpY = 6
const ubyte am_Rel = 7
const ubyte am_Abs = 8
const ubyte am_AbsX = 9
const ubyte am_AbsY = 10
const ubyte am_Ind = 11
const ubyte am_IzX = 12
const ubyte am_IzY = 13
const ubyte am_Zpr = 14
const ubyte am_Izp = 15
const ubyte am_IaX = 16
sub determine_addrmode(uword operand_ptr) -> ubyte { sub determine_addrmode(uword operand_ptr) -> ubyte {
; Imp = 1,
; Acc = 2,
; Imm = 3,
; Zp = 4,
; ZpX = 5,
; ZpY = 6,
; Rel = 7,
; Abs = 8,
; AbsX = 9,
; AbsY = 10,
; Ind = 11,
; IzX = 12,
; IzY = 13,
; Zpr = 14,
; Izp = 15,
; IaX = 16
if not operand_ptr if not operand_ptr
return 1 ; implied return am_Imp
when @(operand_ptr) { when @(operand_ptr) {
0 -> return 1 ; implied 0 -> return am_Imp
'a' -> { 'a' -> {
if @(operand_ptr+1) == 0 if @(operand_ptr+1) == 0
return 2 ; accumulator return am_Acc
; some expression TODO ; some expression TODO
return 0 return am_Invalid
} }
'#' -> { '#' -> {
if @(operand_ptr+1) if @(operand_ptr+1)
return 3 ; immediate return am_Imm
return 0 return am_Invalid
} }
'(' -> { '(' -> {
; some indirect TODO ; some indirect TODO
if @(operand_ptr+1) if @(operand_ptr+1)
return 13 return am_Ind
return 0 return am_Invalid
} }
'$' -> { '$' -> {
; hex address TODO ; hex address TODO
if @(operand_ptr+1) if @(operand_ptr+1)
return 8 return am_Abs
return 0 return am_Invalid
} }
'%' -> { '%' -> {
; bin address TODO ; bin address TODO
if @(operand_ptr+1) if @(operand_ptr+1)
return 8 return am_Abs
return 0 return am_Invalid
} }
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> {
; absolute or indexed address TODO ; absolute or indexed address TODO
return 8 return am_Abs
} }
else -> return 0 ; unknown
} }
return 0 ; unknown return am_Invalid
} }
asmsub match(uword mnemonic_ptr @AY) -> uword @AY { asmsub match(uword mnemonic_ptr @AY) -> uword @AY {