aboutsummaryrefslogtreecommitdiff
path: root/assembler/assemble.s
diff options
context:
space:
mode:
authorJacques Comeaux <jacquesrcomeaux@protonmail.com>2024-05-29 08:15:09 -0500
committerJacques Comeaux <jacquesrcomeaux@protonmail.com>2024-05-29 08:15:09 -0500
commit86b72b11d6abcc602a93aa480f27644cc0b34373 (patch)
tree5c1c7875e9ae3cc72248d5e7dab9af083de98d6d /assembler/assemble.s
parente8bc3587cce27b25ba07469964828a327471e5ed (diff)
Use absolute branches for subroutine calls
Diffstat (limited to 'assembler/assemble.s')
-rw-r--r--assembler/assemble.s156
1 files changed, 71 insertions, 85 deletions
diff --git a/assembler/assemble.s b/assembler/assemble.s
index 6ef1436..04bfb6c 100644
--- a/assembler/assemble.s
+++ b/assembler/assemble.s
@@ -6,92 +6,78 @@
.global assemble
// TODO:
+// - make subroutine addresses explicit
// - test each instruction
// - decide on additional push or pops
-// - redo_line is problematic
+// - add GO to get_char
// - PP and PL are broken (end char)
-assemble:
- PUSH {LR}
- MOVS R6, 0
- MOVS R0, '
- MOV R8, R0
- BL opcode
- MOV R0, R8
- BL uart_send
- MOVS R7, R4
-main_loop:
- LSRS R0, R7, 8 // just peek
- BNE skip // if more stuff then skip
- MOVS R0, '\r
- MOV R8, R0 //set end char to carriage return
-skip:
- UXTB R0, R7 // store lsb in R0
- LSRS R1, R0, 4 // upper nibble
- CMP R1, 0xC // if 0xxxxxxx or 10xxxxxx
- BLO handle_opcode
- CMP R1, 0xE // if 110xyyyy
- BLO handle_imm
-handle_reg: // if 111xyyyy
- MOVS R1, (1<<4) // bit 4 mask
- ANDS R0, R1 // get bit 4
- ADDS R0, 3 // add 3 to it (now 3 or 4)
- BL register // result is put in R4
- MOVS R0, 0x0F // lower nibble mask
- ANDS R0, R7 // store shift amount in R0
- LSLS R4, R0 // shift the result by the shift amount
- ORRS R6, R4 // OR the register code into the word under construction
- B done_stuff
-handle_opcode:
- MOVS R2, 9 // shift amount for 7-bit opcode
- MOVS R1, (1<<7) // bit 7 mask
- TST R0, R1 // check bit 7
- BEQ fin // if zero done
- BICS R0, R1 // clear bit 7
- MOVS R2, 11 // shift amount for 5-bit opcode high
- MOVS R1, (1<<5) // bit 5 mask
- TST R0, R1 // check bit 5
- BEQ fin // if zero done
- BICS R0, R1 // clear bit 5
- MOVS R2, 6 // shift amount for 5-bit opcode low
-fin:
- LSLS R0, R2
- ORRS R6, R0
- B here
-handle_imm:
- MOVS R1, 0x0F // lower nibble mask
- ANDS R0, R1 // store immediate width in R0
- BL octal // result is put in R4
- LSLS R0, R7, 27
- LSRS R0, 31
- MOVS R2, 6
- MULS R0, R2 // R0 has shift amount (0 or 6)
- LSLS R4, R0 // shift the result by the shift amount
- ORRS R6, R4 // OR the immediate into the word under construction
-done_stuff:
- MOV R0, R8 // copy the end_char into R0
- BL uart_send // echo the space (or carriage return)
-here:
- LSRS R7, 0x8 // get next parse instruction
- BNE main_loop // if it's nonzero there are more things to parse
-done:
- MOVS R0, '\n // send newline
- BL uart_send
- POP {PC}
-
-.type get_char, %function
-.global get_char
-
-// R8: end_char
-get_char:
- PUSH {LR}
- BL uart_recv
- CMP R0, 025 // ^U (NAK)
- BEQ redo_line
- // CMP R0, 004 // ^D (EOT)
- // BEQ done_for_real
- CMP R0, R8
- POP {PC}
-redo_line:
- POP {R0}
- B done
+assemble: PUSH {LR}
+ LDR R0, =uart_send
+ LDR R1, =get_char
+ ADDS R0, 1
+ ADDS R1, 1
+ MOV R9, R0
+ MOV R10, R1
+ MOVS R6, 0
+ MOVS R0, '
+ MOV R8, R0
+ LDR R1, =opcode
+ ADDS R1, 1
+ BLX R1
+ MOV R0, R8
+ BLX R9
+ MOVS R7, R4
+main_loop: LSRS R0, R7, 8 // just peek
+ BNE skip // if more stuff then skip
+ MOVS R0, '\r
+ MOV R8, R0 //set end char to carriage return
+skip: UXTB R0, R7 // store lsb in R0
+ LSRS R1, R0, 4 // upper nibble
+ CMP R1, 0xC // if 0xxxxxxx or 10xxxxxx
+ BLO handle_op
+ CMP R1, 0xE // if 110xyyyy
+ BLO handle_imm
+handle_reg: MOVS R1, (1<<4) // bit 4 mask // if 111xyyyy
+ ANDS R0, R1 // get bit 4
+ ADDS R0, 3 // add 3 to it (now 3 or 4)
+ LDR R1, =register
+ ADDS R1, 1
+ BLX R1
+ MOVS R0, 0x0F // lower nibble mask
+ ANDS R0, R7 // store shift amount in R0
+ LSLS R4, R0 // shift the result by the shift amount
+ ORRS R6, R4 // OR the register code into the word under construction
+ B done_stuff
+handle_op: MOVS R2, 9 // shift amount for 7-bit opcode
+ MOVS R1, (1<<7) // bit 7 mask
+ TST R0, R1 // check bit 7
+ BEQ fin // if zero done
+ BICS R0, R1 // clear bit 7
+ MOVS R2, 11 // shift amount for 5-bit opcode high
+ MOVS R1, (1<<5) // bit 5 mask
+ TST R0, R1 // check bit 5
+ BEQ fin // if zero done
+ BICS R0, R1 // clear bit 5
+ MOVS R2, 6 // shift amount for 5-bit opcode low
+fin: LSLS R0, R2
+ ORRS R6, R0
+ B here
+handle_imm: MOVS R1, 0x0F // lower nibble mask
+ ANDS R0, R1 // store immediate width in R0
+ LDR R1, =octal
+ ADDS R1, 1
+ BLX R1 // result is put in R4
+ LSLS R0, R7, 27
+ LSRS R0, 31
+ MOVS R2, 6
+ MULS R0, R2 // R0 has shift amount (0 or 6)
+ LSLS R4, R0 // shift the result by the shift amount
+ ORRS R6, R4 // OR the immediate into the word under construction
+done_stuff: MOV R0, R8 // copy the end_char into R0
+ BLX R9 // echo the space (or carriage return)
+here: LSRS R7, 0x8 // get next parse instruction
+ BNE main_loop // if it's nonzero there are more things to parse
+done: MOVS R0, '\n // send newline
+ BLX R9
+ POP {PC}