summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpu/cpu.ml54
-rw-r--r--cpu/os.asm169
2 files changed, 187 insertions, 36 deletions
diff --git a/cpu/cpu.ml b/cpu/cpu.ml
index dbea33b..74e25c3 100644
--- a/cpu/cpu.ml
+++ b/cpu/cpu.ml
@@ -9,6 +9,8 @@ let dbg_read_data, save_dbg_read_data = loop 8
let dbg_wa, save_dbg_wa = loop 16
let dbg_write_data, save_dbg_write_data = loop 8
+let d7_out = Array.to_list (Array.init 8 (fun i -> let v, sl = loop 8 in ("d7_"^(string_of_int i), v, sl, i)))
+
let cpu_ram ra we wa d =
(* Ram chip has word size = 8 bits and address size = 16 bits
0x0000 to 0x3FFF is ROM0
@@ -65,6 +67,12 @@ let cpu_ram ra we wa d =
save_next_ser (mux read_ser ser (zeroes 8)) ^.
mux read_ser read_data ser in
+ let read_data = List.fold_left
+ (fun rd (_, prevd7digit, setd7digit, i) ->
+ let save_that_digit = we ^& (eq_c 16 wa (0x4200 + i)) in
+ setd7digit (mux save_that_digit (reg 8 prevd7digit) d) ^. rd)
+ read_data d7_out in
+
save_dbg_ra ra ^.
save_dbg_read_data read_data ^.
save_dbg_wa wa ^.
@@ -298,28 +306,30 @@ let p =
"tick", 1;
"ser_in", 8;
]
- [
- "read_ilow", 1, rl;
- "read_ihi", 1, rh;
- "ex_instr", 1, ex;
- "ex_finish", 1, exf;
- "i", 16, i;
- "ra", 16, dbg_ra;
- "read_data", 8, dbg_read_data;
- "wa", 16, dbg_wa;
- "write_data", 8, dbg_write_data;
- "pc", 16, pc;
- "r0_Z", 16, r0;
- "r1_A", 16, r1;
- "r2_B", 16, r2;
- "r3_C", 16, r3;
- "r4_D", 16, r4;
- "r5_E", 16, r5;
- "r6_F", 16, r6;
- "r7_G", 16, r7;
- "ser_out", 8, ser_out;
- "ser_in_busy", 1, ser_in_busy;
- ]
+ (
+ [
+ "read_ilow", 1, rl;
+ "read_ihi", 1, rh;
+ "ex_instr", 1, ex;
+ "ex_finish", 1, exf;
+ "i", 16, i;
+ "ra", 16, dbg_ra;
+ "read_data", 8, dbg_read_data;
+ "wa", 16, dbg_wa;
+ "write_data", 8, dbg_write_data;
+ "pc", 16, pc;
+ "r0_Z", 16, r0;
+ "r1_A", 16, r1;
+ "r2_B", 16, r2;
+ "r3_C", 16, r3;
+ "r4_D", 16, r4;
+ "r5_E", 16, r5;
+ "r6_F", 16, r6;
+ "r7_G", 16, r7;
+ "ser_out", 8, ser_out;
+ "ser_in_busy", 1, ser_in_busy;
+ ] @ List.map (fun (name, out, _, _) -> (name, 8, out)) d7_out
+ )
let () = Netlist_printer.print_program stdout p
diff --git a/cpu/os.asm b/cpu/os.asm
index 9a3d7a6..3fbf757 100644
--- a/cpu/os.asm
+++ b/cpu/os.asm
@@ -37,13 +37,14 @@ _end_process_input:
jz A _main_loop
jal incr_clock
- jal disp_time
+ jal disp_clock_d7
j _main_loop
# PROCEDURE: incr_clock
# ROLE: take into account seconds increment
# ARGUMENTS: number of seconds to add, in register A
incr_clock:
+ push RA
jz A _incr_clock_ret
lb B var_sec
@@ -71,11 +72,8 @@ incr_clock:
lb B var_day
add B B A
- lb C var_month
- li D days_in_month
- add D D C
- lb C 0(D)
- divu A B C
+ jal get_dom
+ divu A B A
move B E
sb B var_day
jz A _incr_clock_ret
@@ -94,12 +92,65 @@ incr_clock:
_incr_clock_ret:
+ pop RA
jr RA
-# PROCEDURE: disp_clock
-# ROLE: display current time
+# PROCEDURE: get_dom
+# ROLE: how many days in current month ?
+# RETURN VALUE: the result, in register A.
+# PRESERVES REGISTERS: B
+get_dom:
+ lb C var_month
+ li D days_in_month
+ add D D C
+ lb A 0(D)
+
+ jr RA
+
+# PROCEDURE: disp_clock_d7
+# ROLE: display current time (H M S) to D7 display
# ARGUMENTS: none
-disp_time:
+disp_clock_d7:
+ li D 10
+
+ lb A var_sec
+ divu A A D
+ move B E
+ push B
+ push A
+ push D
+
+ lb A var_min
+ divu A A D
+ move B E
+ push B
+ push A
+ push D
+
+ lb A var_hour
+ divu A A D
+ move B E
+ push B
+ push A
+
+ li D d7_digits
+ li C 8
+ li B 0x4200
+_disp_d7_loop:
+ pop A
+ add A A D
+ lb A 0(A)
+ sb A 0(B)
+ incri B 1
+ incri C -1
+ jnz C _disp_d7_loop
+
+ jr RA
+
+# PROCEDURE: disp_clock_ser
+# ROLE: display current time to serial output
+# ARGUMENTS: none
+disp_clock_ser:
push RA
lw A var_year
@@ -147,6 +198,7 @@ disp_time:
# PROCEDURE: run_cmd
# ROLE: execute and clear command stored in cmdline
# ARGUMENTS: none
+# COMMAND FORMAT:[hmsYMD][0-9]+
run_cmd:
push RA
@@ -156,12 +208,94 @@ run_cmd:
jal ser_out_str
li A endl
jal ser_out_str
+
+ li A cmdline
+ incri A 1
+ li C 0
+_decode_digit_loop:
+ lb B 0(A)
+ jz B _decode_digit_end
+ li D 10
+ mulu C C D
+ li D '0'
+ sub B B D
+ add C C B
+ incri A 1
+ j _decode_digit_loop
+_decode_digit_end:
- li A error
+ li A cmdline
+ lb A 0(A)
+
+ sei B A 's'
+ jz B _test_min
+ li D 60
+ sleu D D C
+ jnz D _error_too_big
+ sb C var_sec
+ j _return_run_cmd
+
+_test_min:
+ sei B A 'm'
+ jz B _test_hour
+ li D 60
+ sleu D D C
+ jnz D _error_too_big
+ sb C var_min
+ j _return_run_cmd
+
+_test_hour:
+ sei B A 'h'
+ jz B _test_day
+ li D 24
+ sleu D D C
+ jnz D _error_too_big
+ sb C var_hour
+ j _return_run_cmd
+
+_test_day:
+ sei B A 'D'
+ jz B _test_month
+ move B C
+ incri B -1
+ jal get_dom
+ sleu D A B
+ jnz D _error_too_big
+ sb B var_day
+ j _return_run_cmd
+
+_test_month:
+ sei B A 'M'
+ jz B _test_year
+ li D 12
+ sleu D D C
+ jnz D _error_too_big
+ incri C -1
+ sb C var_month
+ j _return_run_cmd
+
+_test_year:
+ sei B A 'Y'
+ jz B _test_anything_else
+ sb C var_year
+ j _return_run_cmd
+
+_test_anything_else:
+ jz A _return_run_cmd
+ j _error_no_such_var
+
+_error_too_big:
+ li A error_too_big
jal ser_out_str
+ j _return_run_cmd
- li A cmdline_used
- sw Z 0(A)
+_error_no_such_var:
+ li A error_no_such_var
+ jal ser_out_str
+
+_return_run_cmd:
+ sw Z cmdline_used
+ jal disp_clock_ser
pop RA
jr RA
@@ -380,8 +514,10 @@ prompt:
ascii "\n$ "
endl:
ascii "\n"
-error:
- ascii "Sorry but I'm to stupid to understand that.\n"
+error_too_big:
+ ascii "That number is too big!\n"
+error_no_such_var:
+ ascii "No such variable...\n"
# For unit-tests
@@ -408,6 +544,11 @@ test3:
days_in_month:
byte 31 28 31 30 31 30 31 31 30 31 30 31
+d7_digits:
+ byte 0b1110111 0b0100100 0b1011101 0b1101101 0b0101110
+ byte 0b1101011 0b1111011 0b0100101 0b1111111 0b1101111
+ byte 0
+
.data
# Space where command-line is buffered from serial input (256 bytes)