aboutsummaryrefslogtreecommitdiff
path: root/assembler
diff options
context:
space:
mode:
Diffstat (limited to 'assembler')
-rw-r--r--assembler/assemble.s116
-rw-r--r--assembler/get_char.s21
-rw-r--r--assembler/notes35
-rw-r--r--assembler/string.s16
4 files changed, 127 insertions, 61 deletions
diff --git a/assembler/assemble.s b/assembler/assemble.s
index 96940ea..bf31edf 100644
--- a/assembler/assemble.s
+++ b/assembler/assemble.s
@@ -1,77 +1,71 @@
-1yyyxxxx Imm yyy = shift amount xxxx = bit-width
-00000001 Brackets
-0011yyyy Reg yyyy = shift amount
-0100yyyy Reg
-
-MOVS 0x 00 00 88 38
-ADDS 0x 00 00 88 38
-SUBS 0x 00 00 88 38
-CMP 0x 00 00 33 30
-ANDS 0x 00 00 33 30
-ORRS 0x 00 00 33 30
-TST 0x 00 00 33 30
-LSLS 0x 00 E5 33 30
-LSRS 0x 00 E5 33 30
-RORS 0x 00 00 33 30
-LDR 0x E5 33 01 30
-LDRB 0x 36 33 01 30
-STR 0x E5 33 01 30
-STRB 0x 36 33 01 30
-B<c> 0x 00 00 00 88
-B 0x 00 00 00 8B
-BX 0x 00 00 00 43
-
-// R2 holds the whole word
-// R0 holds just the byte
-// R1 holds either 3 or 4
-more:
- MOVS R0, 0xFF
- ANDS R0, R2
- MOVS R1, 0x80
- TST R0, R1
- BNE handle_imm // if IMM
- MOVS R1, 0xF0
- ANDS R1, R0
- BEQ handle_brackets // if BRACKETS
+assemble:
+ BL receive_op
+ LDR R5, =0x20002000 // opcode table
+ LDR R1, =0x20001000 // opcode buffer base addr
+loop:
+ LDR R0, [R5, 0] // load the string addr
+ BL string_compare
+ BEQ match
+ ADDS R5, 8 // next row of table
+ LDR R0, =0x20002080 // opcode table end
+ CMP R5, R0
+ BLO loop // Keep going if lower than end
+ B redo_line // redo line if opcode was not found
+match:
+ LDR R6, [R5, 4] // load the parse instructions
+main_loop:
+ MOVS R0, 0xFF // lsb mask
+ ANDS R0, R6 // store in R0
+ MOVS R1, 0x80 // bit 7 mask
+ TST R0, R1 // compare (AND) to R0 byte
+ BNE handle_imm // if IMM (== 1)
+ LSRS R0, 4 // R0 hold 3 or 4 (or 0)
+ BEQ handle_brackets // if BRACKETS (== 0)
handle_reg:
- LSRS R1, 4
- MOVS R3, 0x0F
- ANDS R0, R3
- // R1 = 3 or 4
- // R0 = shift amount
- BL register
+ BL register // result is put in R4
+ MOVS R0, 0x0F // lower nibble mask
+ ANDS R0, R6 // store shift amount in R0
+ LSLS R4, R0 // shift the result by the shift amount
+ ORRS R5, R4 // OR the register code into the word under construction
B done_stuff
-
handle_imm:
- BL octal
- B done_stuff
-
-handle_brackets:
- // expect bracket
- // echo bracket
- LSRS R2, 0x8
- BEQ next_instr
- Back
- ...
-
+ MOVS R1, 0x0F // lower nibble mask
+ ANDS R0, R1 // store immediate width in R0
+ BL octal // result is put in R4
+ MOVS R0, 0x7F // least significant 7 bits mask
+ ANDS R0, R6 // store ls 7 bits in R0
+ LSRS R0, 4 // shift right to get shift amount
+ LSLS R4, R0 // shift the result by the shift amount
done_stuff:
- LSRS R2, 0x4
- BEQ done
- MOVS R0, 0
+ LSRS R6, 0x8 // get next parse instruction
+ BEQ done // if it's zero there are no more things to parse
+ MOVS R0, 0 // copy the end_char into R0
ORRS R0, R9
BL uart_send // echo the comma (or bracket)
-expect:
+10:
BL get_char
MOVS R1, ' // space char
CMP R0, R1
- BNE expect // keep trying if not space
+ BNE 10b // keep trying if not space
BL uart_send // echo the space
- B more
+ B main_loop
+handle_brackets:
+ BL get_char // char in R0
+ MOVS R1, '[ // open bracket
+ CMP R0, R1
+ BNE handle_brackets // keep trying if not bracket
+ BL uart_send // echo bracket
+ MOVS R8, 1 // 1 means we are now in brackets
+ LSRS R6, 0x8 // get next parse instruction
+ BNE main_loop
done:
TST R8, R8 // R8 == whether we are in bracket or not
BEQ no_brackets
- MOVS R0, ']
+ MOVS R0, '] // echo bracket
BL uart_send
no_bracket:
- // echo carriage return + newline
+ MOVS R0, '\r // send carriage return
+ BL uart_send
+ MOVS R0, '\n // send newline
+ BL uart_send
B next_instr
diff --git a/assembler/get_char.s b/assembler/get_char.s
new file mode 100644
index 0000000..f1f43e7
--- /dev/null
+++ b/assembler/get_char.s
@@ -0,0 +1,21 @@
+// R9: end_char
+get_char:
+ PUSH {LR}
+ BL uart_recv
+ MOVS R1, 025 // ^U (NAK)
+ CMP R0, R1
+ BEQ redo_line
+ MOVS R1, 004 // ^D (EOT)
+ CMP R0, R1
+ BEQ done_for_real
+ CMP R0, R9
+ POP {PC}
+
+get_line:
+ BL get_char
+ ...
+ B get_line
+
+redo_line:
+ ...
+ B get_line
diff --git a/assembler/notes b/assembler/notes
new file mode 100644
index 0000000..6206eff
--- /dev/null
+++ b/assembler/notes
@@ -0,0 +1,35 @@
+Clobber
+R0: arg1, uart result
+R1: arg2
+R2:
+R3: shift_amount
+-------------
+Save
+R4: octal result, register result
+R5: word under construction
+R6: parse instructions
+R8:
+R9: end_char
+
+1yyyxxxx Imm yyy = shift amount xxxx = bit-width
+00000001 Brackets
+0011yyyy Reg yyyy = shift amount
+0100yyyy Reg
+
+MOVS 0x 00 00 88 38
+ADDS 0x 00 00 88 38
+SUBS 0x 00 00 88 38
+CMP 0x 00 00 33 30
+ANDS 0x 00 00 33 30
+ORRS 0x 00 00 33 30
+TST 0x 00 00 33 30
+LSLS 0x 00 E5 33 30
+LSRS 0x 00 E5 33 30
+RORS 0x 00 00 33 30
+LDR 0x E5 33 01 30
+LDRB 0x 36 33 01 30
+STR 0x E5 33 01 30
+STRB 0x 36 33 01 30
+B<c> 0x 00 00 00 88
+B 0x 00 00 00 8B
+BX 0x 00 00 00 43
diff --git a/assembler/string.s b/assembler/string.s
new file mode 100644
index 0000000..0ed7ca3
--- /dev/null
+++ b/assembler/string.s
@@ -0,0 +1,16 @@
+// R0 : string1 address
+// R1 : string2 address
+// Result in R0
+string_compare:
+ MOVS R4, 0
+loop:
+ LDRB R2, [R0, R4]
+ LDRB R3, [R1, R4]
+ CMP R2, R3
+ BNE done
+ CMP R2, 0
+ BEQ done
+ ADDS R4, 1
+ B loop
+done:
+ BX LR