aboutsummaryrefslogtreecommitdiff
path: root/assembler/octal.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/octal.s
parente8bc3587cce27b25ba07469964828a327471e5ed (diff)
Use absolute branches for subroutine calls
Diffstat (limited to 'assembler/octal.s')
-rw-r--r--assembler/octal.s116
1 files changed, 48 insertions, 68 deletions
diff --git a/assembler/octal.s b/assembler/octal.s
index 18abebd..62e2b1e 100644
--- a/assembler/octal.s
+++ b/assembler/octal.s
@@ -5,71 +5,51 @@
.type octal, %function
.global octal
-octal:
- PUSH {LR}
- MOVS R5, R0
-
- // Handle bit-width = 0
- BNE 30f
-10:
- BL get_char
- CMP R0, '0
- BNE 10b
- BL uart_send
- MOVS R4, 0
-20:
- BL get_char
- BNE 20b
- POP {PC}
-30:
-
- // R4 will become '1 or '3 or '7
- MOVS R0, 3
- CMP R5, 3
- BHS 40f
- MOVS R0, R5
-40:
- MOVS R4, 1
- LSLS R4, R0
- ADDS R4, ('0 - 1)
-
- // Get first char
-50:
- BL get_char
- CMP R0, '0
- BLO 50b
- CMP R0, R4
- BHI 50b
- BL uart_send
- SUBS R0, '0
- MOVS R4, R0
-
- // Subtract 1, 2, or 3 from bit-width
- MOVS R1, 0
-60:
- ADDS R1, 1
- LSRS R0, 1
- BNE 60b
- SUBS R5, R1
-
- // Loop for remaining chars
-70:
- CMP R5, 3
- BLO 80f
- BL get_char
- BEQ 90f
- CMP R0, '0
- BLO 70b
- CMP R0, '7
- BHI 70b
- BL uart_send
- SUBS R0, '0
- LSLS R4, 3
- ADDS R4, R0
- SUBS R5, 3
- B 70b
-80:
- BL get_char
- BNE 80b
-90:
- POP {PC}
+octal: PUSH {LR} // 0c0000 0xB500 ; SAVE LINK REGISTER
+ MOVS R5, R0 // 0x0002 0x0005 ; SAVE BIT WIDTH
+ BNE 30f // 0x0004 0xD1 ; SKIP IF BIT WIDTH != 0
+10: BLX R10 // 0x0006 0x ; GET CHAR
+ CMP R0, '0 // 0x000A 0x2830 ; COMPARE TO '0 CHAR
+ BNE 10b // 0x000C 0xD1 ; GET ANOTHER CHAR IF NOT '0
+ BLX R9 // 0x000E 0x ; OTHERWISE ECHO '0 CHAR
+ MOVS R4, 0 // 0x0012 0x2400 ; SET RESULT TO 0
+20: BLX R10 // 0x0014 0x ; GET CHAR
+ BNE 20b // 0x0018 0xD1 ; LOOP IF NOT END CHAR
+ POP {PC} // 0x001A 0xBD00 ; RETURN IF END CHAR
+30: MOVS R0, 3 // 0x001C 0x2003 ; DEFAULT TO 3
+ CMP R5, 3 // 0x001E 0x2D03 ; CHECK BIT WIDTH
+ BHS 40f // 0x0020 0xD2 ; IF BIT WIDTH >= 3 KEEP R0 == 3
+ MOVS R0, R5 // 0x0022 0x0028 ; IF BIT WIDTH < 3 COPY TO R0
+40: MOVS R4, 1 // 0x0024 0x2401 ; 2^0
+ LSLS R4, R0 // 0x0026 0x4084 ; 2^(MAX(BIT WIDTH, 3))
+ ADDS R4, ('0 - 1) // 0x0028 0x342F ; '1 OR '3 or '7
+50: BLX R10 // 0x002A 0x ; GET FIRST CHAR
+ CMP R0, '0 // 0x002E 0x2830 ; COMPARE WITH '0
+ BLO 50b // 0x0030 0xD3 ; RETRY IF BELOW OCTAL RANGE
+ CMP R0, R4 // 0x0032 0x42A0 ; COMPARE WITH END CHAR
+ BHI 50b // 0x0034 0xD8 ; RETRY IF ABOVE RANGE
+ BLX R9 // 0x0036 0x ; ECHO IF IN RANGE
+ SUBS R0, '0 // 0x003A 0x3830 ; GET VALUE FROM CHAR
+ MOVS R4, R0 // 0x003C 0x0004 ; STORE VALUE IN RESULT
+ MOVS R1, 0 // 0x003E 0x2100 ; BIT WIDTH FOR FIRST CHAR
+60: ADDS R1, 1 // 0x0040 0x3101 ; INCREMENT FIRST CHAR WIDTH
+ LSRS R0, 1 // 0x0042 0x0840 ; SHIFT RIGHT ONE BIT
+ BNE 60b // 0x0044 0x ; IF NONZERO STAY IN LOOP
+ SUBS R5, R1 // 0x0046 0x1A6D ; SUBTRACT FIRST CHAR WIDTH FROM TOTAL
+70: CMP R5, 3 // 0x0048 0x2D03 ; COMPARE BIT WIDTH TO 3
+ BLO 80f // 0x004A 0xD3 ; EXIT LOOP IF LESS THAN 3
+ BLX R10 // 0x004C 0x ; GET ANOTHER CHAR
+ BEQ 90f // 0x0050 0xD0 ; IF END CHAR EXIT LOOP
+ CMP R0, '0 // 0x0052 0x2830 ; BOTTOM OF OCTAL RANGE
+ BLO 70b // 0x0054 0xD3 ; RETRY IF BELOW
+ CMP R0, '7 // 0x0056 0x2837 ; TOP OF OCTAL RANGE
+ BHI 70b // 0x0058 0xD8 ; RETRY IF ABOVE
+ BLX R9 // 0x005A 0x ; ECHO IF IN RANGE
+ SUBS R0, '0 // 0x005E 0x3830 ; GET VALUE FROM CHAR
+ LSLS R4, 3 // 0x0060 0x00E4 ; SHIFT OLD VALUE BY ONE DIGIT
+ ADDS R4, R0 // 0x0062 0x1824 ; ACCUMULATE INTO VALUE
+ SUBS R5, 3 // 0x0064 0x3D03 ; DECREMENT BIT WIDTH BY 3
+ B 70b // 0x0066 0xD0 ; LOOP FOR ANOTHER DIGIT
+80: BLX R10 // 0x0068 0x ; GET A CHAR
+ BNE 80b // 0x006C 0xD1 ; LOOP UNTIL END CHAR
+90: POP {PC} // 0x006E 0xBD00 ; RETURN