diff options
author | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2024-05-29 08:15:09 -0500 |
---|---|---|
committer | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2024-05-29 08:15:09 -0500 |
commit | 86b72b11d6abcc602a93aa480f27644cc0b34373 (patch) | |
tree | 5c1c7875e9ae3cc72248d5e7dab9af083de98d6d /assembler/assemble.s | |
parent | e8bc3587cce27b25ba07469964828a327471e5ed (diff) |
Use absolute branches for subroutine calls
Diffstat (limited to 'assembler/assemble.s')
-rw-r--r-- | assembler/assemble.s | 156 |
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} |