aboutsummaryrefslogtreecommitdiff
path: root/newasm
diff options
context:
space:
mode:
authorJacques Comeaux <jacquesrcomeaux@protonmail.com>2024-08-21 00:21:54 -0500
committerJacques Comeaux <jacquesrcomeaux@protonmail.com>2024-08-21 00:21:54 -0500
commited6f1106322f8ca4a6e26d08365bb9558ffa9d09 (patch)
tree0258d4a7b0429c82b4f7af8d63106ea93e7150de /newasm
parentd23ab4295a865580f6cb7bb4526978bac388b5ac (diff)
Start new assembler
Diffstat (limited to 'newasm')
-rw-r--r--newasm/Makefile39
-rw-r--r--newasm/data.s15
-rw-r--r--newasm/input.s84
-rw-r--r--newasm/main.s34
-rw-r--r--newasm/pico_bin.ld13
-rw-r--r--newasm/slowcat.c11
-rw-r--r--newasm/string.s32
-rw-r--r--newasm/uart.s44
8 files changed, 272 insertions, 0 deletions
diff --git a/newasm/Makefile b/newasm/Makefile
new file mode 100644
index 0000000..3302630
--- /dev/null
+++ b/newasm/Makefile
@@ -0,0 +1,39 @@
+PICO = /dev/disk/by-label/RPI-RP2
+DEVICE = /dev/ttyUSB0
+
+.PHONY: build
+build: parse.he
+
+parse.he: parse.bin
+ od -An -tx2 -v parse.bin | sed "s/^ //" | tr " " "\n" | tr [:lower:] [:upper:] | sed "s/^/0x/" > parse.he
+
+parse.bin: parse.elf
+ arm-none-eabi-objcopy -O binary parse.elf parse.bin
+
+objects = main.o uart.o data.o string.o input.o
+
+parse.elf: pico_bin.ld $(objects)
+ arm-none-eabi-ld -T pico_bin.ld -o parse.elf $(objects)
+
+$(objects): %.o: %.s
+ arm-none-eabi-as -o $@ $<
+
+.PHONY: clean
+clean:
+ rm -f parse.elf parse.bin parse.he slowcat $(objects)
+
+.PHONY: dump
+dump: parse.bin
+ @od -Ax -tx2 -v parse.bin
+
+.PHONY: serial
+serial: $(DEVICE) parse.he slowcat
+ cat parse.he | tr "\n" "\r" | ./slowcat | picocom -b 115200 -q $(DEVICE)
+ @echo
+ echo -n "G" | picocom -b 115200 -q $(DEVICE)
+ @echo
+
+$(DEVICE):
+ @echo Serial device not found
+ @echo Connect USB cable from USB-UART bridge
+ @false
diff --git a/newasm/data.s b/newasm/data.s
new file mode 100644
index 0000000..69d03ac
--- /dev/null
+++ b/newasm/data.s
@@ -0,0 +1,15 @@
+.syntax unified
+.cpu cortex-m0plus
+.thumb
+
+.global crlf, word, hword, byte, align, asciz, SP, LR, PC
+
+crlf: .asciz "\r\n"
+word: .asciz "word"
+hword: .asciz "hword"
+byte: .asciz "byte"
+align: .asciz "align"
+asciz: .asciz "asciz"
+SP: .asciz "SP"
+LR: .asciz "LR"
+PC: .asciz "PC"
diff --git a/newasm/input.s b/newasm/input.s
new file mode 100644
index 0000000..d9c8c73
--- /dev/null
+++ b/newasm/input.s
@@ -0,0 +1,84 @@
+.syntax unified
+.cpu cortex-m0plus
+.thumb
+
+.type getline, %function
+.global getline
+
+getline:
+ PUSH {R4, R5, LR} // save registers
+ MOVS R4, R0 // put strbuf in R4
+next: BL uart_recv // get a char
+ CMP R0, 0x03 // end of text (^C)
+ BEQ cancel // don't submit, start on next line
+ CMP R0, 0x04 // end of transmission (^D)
+ BEQ done // begin of line done, in a line submit the line
+ CMP R0, 0x7F // delete (backspace)
+ BEQ back // in a line go back a space, begin of line do nothing
+ CMP R0, 0x0D // carriage return (Enter)
+ BEQ submit // submit the line
+ CMP R0, 0x15 // NAK (^U)
+ BEQ retry // restart the line
+ // CMP R0, 0x1B // Escape (ESC)
+ // BEQ address // enter a new address to edit at
+ CMP R0, 0x20 // start of printable range
+ BLO next
+ CMP R0, 0x7E // end of printable range
+ BHI next
+good: BL uart_send // echo the printable char
+ STRB R0, [R4, R5] // write the printable char
+ ADDS R5, 1 // increment strbuf offset
+ B next // get another char
+cancel: MOVS R5, 0 // reset offset
+ STRB R5, [R4, R5] // write empty string
+ LDR R0, =crlf // newline
+ BL putstr
+ MOVS R0, 1 // error code 1 (line canceled)
+ POP {R4, R5, PC} // return
+done: TST R5, R5 // check if offset is zero
+ BNE submit // if not zero submit line
+ STRB R5, [R4, R5] // clear input buffer
+ LDR R0, =crlf // newline
+ BL putstr
+ MOVS R0, 2 // error code 2 (end of input)
+ POP {R4, R5, PC} // return
+back: TST R5, R5 // check if offset is zero
+ BEQ next // if so get another char
+ SUBS R5, 1 // push back offset
+ MOVS R0, 0 // null byte
+ STRB R0, [R4, R5] // delete character
+ MOVS R0, 0x08 // backspace
+ BL uart_send // move cursor back
+ MOVS R0, ' // space
+ BL uart_send // overwrite
+ MOVS R0, 0x08 // backspace
+ BL uart_send // move cursor back again
+ B next // get another char
+submit: MOVS R0, 0 // null byte
+ STRB R0, [R4, R5] // terminate string
+ MOVS R0, 0x0D // carriage return
+ BL uart_send
+ MOVS R0, 0x0A // line feed
+ BL uart_send
+ MOVS R0, 0 // return code 0 (success)
+ POP {R4, R5, PC}
+retry: MOVS R0, 0x08 // backspace
+ MOVS R1, ' // space
+ MOVS R2, R5 // repeat once per character
+ MOVS R5, 0 // reset offset
+ TST R2, R2 // check if already zero
+1: BEQ 2f // while not zero
+ STRB R0, [R4, R5] // write backspace
+ ADDS R5, 1
+ STRB R1, [R4, R5] // write space
+ ADDS R5, 1
+ STRB R0, [R4, R5] // write backspace
+ ADDS R5, 1
+ SUBS R2, 1 // decrement amount
+ B 1b // repeat
+2: STRB R2, [R4, R5] // terminate string
+ MOVS R0, R4 // copy strbuf address
+ BL putstr // print backspace sequence
+ MOVS R5, 0 // null byte and reset offset
+ STRB R5, [R4] // write empty string
+ B next // get new chars
diff --git a/newasm/main.s b/newasm/main.s
new file mode 100644
index 0000000..7f3c038
--- /dev/null
+++ b/newasm/main.s
@@ -0,0 +1,34 @@
+.syntax unified
+.cpu cortex-m0plus
+.thumb
+
+.type main, %function
+.global main, strbuf
+
+main: LDR R6, =0x20002000
+ BL uart_recv
+loop: BL prompt
+ LDR R0, strbuf
+ BL getline
+ LDR R0, strbuf
+ BL putstr
+ LDR R0, =crlf
+ BL putstr
+ B loop
+ BL uart_recv
+ LDR R0, =0x20000001
+ BX R0
+
+ .align 4
+strbuf: .word 0x20001F00
+
+prompt: PUSH {LR}
+ MOVS R0, R6
+ BL send_hex
+ MOVS R0, '
+ BL uart_send
+ LDR R0, [R6]
+ BL send_hex
+ MOVS R0, '
+ BL uart_send
+ POP {PC}
diff --git a/newasm/pico_bin.ld b/newasm/pico_bin.ld
new file mode 100644
index 0000000..258ba57
--- /dev/null
+++ b/newasm/pico_bin.ld
@@ -0,0 +1,13 @@
+ENTRY(main)
+
+MEMORY {
+ FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2M
+ SRAM(rwx) : ORIGIN = 0x20001000, LENGTH = 264K
+}
+
+SECTIONS {
+ .text : {
+ *(.text);
+ . = ALIGN(4);
+ } > SRAM
+}
diff --git a/newasm/slowcat.c b/newasm/slowcat.c
new file mode 100644
index 0000000..e33f92a
--- /dev/null
+++ b/newasm/slowcat.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <stdint.h>
+
+int main() {
+ uint8_t byte;
+ while (read(STDIN_FILENO, &byte, 1)) {
+ write(STDOUT_FILENO, &byte, 1);
+ usleep(5000);
+ }
+ return 0;
+}
diff --git a/newasm/string.s b/newasm/string.s
new file mode 100644
index 0000000..c1dad1c
--- /dev/null
+++ b/newasm/string.s
@@ -0,0 +1,32 @@
+.syntax unified
+.cpu cortex-m0plus
+.thumb
+
+.type putstr, %function
+.type cmpstr, %function
+
+.global putstr, cmpstr
+
+putstr: LDR R3, =0x40034000
+ MOVS R2, 0x20
+1: LDR R1, [R3, 0x18]
+ TST R1, R2
+ BNE 1b
+ LDRB R1, [R0]
+ TST R1, R1
+ BEQ 2f
+ STRB R1, [R3]
+ ADDS R0, 1
+ B 1b
+2: BX LR
+
+cmpstr: MOVS R4, 0
+1: LDRB R2, [R0, R4]
+ LDRB R3, [R1, R4]
+ CMP R2, R3
+ BNE 2f
+ CMP R2, 0
+ BEQ 2f
+ ADDS R4, 1
+ B 1b
+2: BX LR
diff --git a/newasm/uart.s b/newasm/uart.s
new file mode 100644
index 0000000..c4abb8a
--- /dev/null
+++ b/newasm/uart.s
@@ -0,0 +1,44 @@
+.syntax unified
+.cpu cortex-m0plus
+.thumb
+
+.type uart_send, %function
+.type uart_recv, %function
+.type send_hex, %function
+
+.global uart_send
+.global uart_recv
+.global send_hex
+
+uart_send: LDR R1, =0x40034000
+ MOVS R3, 0x20
+1: LDR R2, [R1, 0x18]
+ TST R2, R3
+ BNE 1b
+ STRB R0, [R1]
+ BX LR
+
+uart_recv: LDR R1, =0x40034000
+ MOVS R3, 0x10
+1: LDR R2, [R1, 0x18]
+ TST R2, R3
+ BNE 1b
+ LDRB R0, [R1]
+ BX LR
+
+send_hex: PUSH {R4, R5, LR}
+ MOVS R4, R0
+ MOVS R5, 8
+0: MOVS R0, 0x1C
+ RORS R4, R0
+ MOVS R0, 0x0F
+ ANDS R0, R4
+ CMP R0, 0x9
+ BHI 1f
+ ADDS R0, 0x30
+ B 2f
+1: ADDS R0, 0x37
+2: BL uart_send
+ SUBS R5, 1
+ BNE 0b
+ POP {R4, R5, PC}