mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 19:29:50 +00:00
assem
This commit is contained in:
parent
dde6919446
commit
4309a0dc68
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user