summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/asmlex.mll4
-rw-r--r--asm/assembler.ml8
-rw-r--r--cpu/cpu.ml1
-rw-r--r--cpu/os.asm103
4 files changed, 108 insertions, 8 deletions
diff --git a/asm/asmlex.mll b/asm/asmlex.mll
index 7be493e..7459966 100644
--- a/asm/asmlex.mll
+++ b/asm/asmlex.mll
@@ -94,6 +94,10 @@ rule token = parse
with Not_found -> ID id }
| "0x" (((hexdigit)+) as n)
{ INT (read_16 n) }
+ | "'\\n'" { INT (Char.code '\n') }
+ | "'\\t'" { INT (Char.code '\t') }
+ | "'\\r'" { INT (Char.code '\r') }
+ | "'" (_ as c) "'" { INT (Char.code c) }
| (digit)+ as n { INT (int_of_string n) }
| "0b" (['0' '1']+ as n) { INT (read_2 n) }
| ['A'-'Z']+ as name { try REG (List.assoc name regs) with Not_found -> raise (Asm_error ("no reg " ^ name))}
diff --git a/asm/assembler.ml b/asm/assembler.ml
index 66999fb..8c8ff97 100644
--- a/asm/assembler.ml
+++ b/asm/assembler.ml
@@ -2,6 +2,8 @@ open Asm
open Printf
open Lexing
+exception No_such_label of string
+
let init_string n f =
let res = String.make n 'a' in
for i = 0 to n - 1 do res.[i] <- f i done; res
@@ -83,13 +85,13 @@ let print_program p =
let pc = ref 0 in
let value = function
| Imm i -> i
- | Lab l -> fst (Imap.find l p.lbls) in
+ | Lab l -> try fst (Imap.find l p.lbls) with Not_found -> raise (No_such_label l) in
let value2 = function
| Imm i -> i
- | Lab l -> fst (Imap.find l p.lbls) - !pc in
+ | Lab l -> try fst (Imap.find l p.lbls) - !pc with Not_found -> raise (No_such_label l) in
let value3 = function
| Imm i -> i
- | Lab l -> (byte 16 (fst (Imap.find l p.lbls))) lsr 8 in
+ | Lab l -> try (byte 16 (fst (Imap.find l p.lbls))) lsr 8 with Not_found -> raise (No_such_label l) in
let get_reps = function
| R (o,r1,r2,r3) -> r (code o) r1 r2 r3,
sprintf "%s %s %s %s" (List.assoc o rev_keywords) (rts r1) (rts r2) (rts r3)
diff --git a/cpu/cpu.ml b/cpu/cpu.ml
index 1d1eea8..3f9dd74 100644
--- a/cpu/cpu.ml
+++ b/cpu/cpu.ml
@@ -56,6 +56,7 @@ let cpu_ram ra we wa d =
let iser = nonnull 8 ser_in in
let ser = mux iser ser ser_in in
let ser_busy = nonnull 8 ser in
+ let ser_busy = mux read_ser ser_busy (const "0") in
let read_data =
save_ser_in_busy ser_busy ^.
save_next_ser (mux read_ser ser (zeroes 8)) ^.
diff --git a/cpu/os.asm b/cpu/os.asm
index 5d58ff7..4a7449a 100644
--- a/cpu/os.asm
+++ b/cpu/os.asm
@@ -1,15 +1,58 @@
+# CONVENTION:
+# return value for functions : in register A
+# arguments for functions : registers A, B, C, D
+# all registers are caller-saved, except SP which is preserved by function calls
+
.text
-init:
+ li A msghello
+ jal ser_out_msg
+
+ push Z
+main_loop:
+ # Process serial input
+ jal check_input
+ jz A end_process_input
+ jal run_cmd
+end_process_input:
+
+ # Process clock ticking
+ pop D
li B _clock
lw B 0(B)
- jz B init
add D D B
push D
+
+ jz B main_loop
li A msgtick
jal ser_out_msg
- pop D
- j init
+ j main_loop
+
+# PROCEDURE: run_cmd
+# ROLE: execute and clear command stored in cmdline
+# ARGUMENTS: none
+run_cmd:
+ push RA
+
+ li A prompt
+ jal ser_out_msg
+ li A cmdline
+ jal ser_out_msg
+ li A endl
+ jal ser_out_msg
+
+ li A error
+ jal ser_out_msg
+ li A cmdline_used
+ sw Z 0(A)
+
+ pop RA
+ jr RA
+
+
+# PROCEDURE: ser_out_msg
+# ROLE: write null-terminated string to serial output
+# ARGUMENTS: address of string in register A
ser_out_msg:
li C _output
ser_out_msg_loop:
@@ -21,5 +64,55 @@ ser_out_msg_loop:
ser_out_msg_ret:
jr RA
+# PROCEDURE: check_input
+# ROLE: check if an input byte is available. if it is, and is different from '\n' (10), add it to cmdline
+# ARGUMENTS: none
+# RETURN VALUE: 1 if read byte was '\n', 0 otherwise
+# WARNING: no buffer overflow check.
+check_input:
+ li A _input
+ lb A 0(A)
+ jz A check_input_ret
+ move B A
+ sei A A '\n'
+ jz A add_b_to_string
+ move B Z
+add_b_to_string:
+ push A
+ li A cmdline
+ li D cmdline_used
+ lw C 0(D)
+ add A A C
+ sb B 0(A)
+ incri C 1
+ sw C 0(D)
+ pop A
+check_input_ret:
+ jr RA
+
+
+# READ-ONLY PROGRAM DATA
+msghello:
+ ascii "Hello, world!\n"
msgtick:
- ascii "Tick!"
+ ascii " ..."
+prompt:
+ ascii "\n$ "
+endl:
+ ascii "\n"
+error:
+ ascii "Sorry but I'm to stupid to understand that.\n"
+
+
+.data
+# Space where command-line is buffered from serial input
+cmdline:
+ byte 256
+# Number of bytes used in the command-line buffer
+cmdline_used:
+ word 1
+
+
+
+
+