diff options
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/Makefile | 8 | ||||
-rw-r--r-- | cpu/ROM_count_seconds.rom (renamed from cpu/prog_rom0.rom) | 0 | ||||
-rw-r--r-- | cpu/alu.ml | 148 | ||||
-rw-r--r-- | cpu/cpu.ml | 41 | ||||
-rw-r--r-- | cpu/netlist_gen.ml | 70 | ||||
-rw-r--r-- | cpu/netlist_gen.mli | 2 | ||||
-rw-r--r-- | cpu/netlist_printer.ml | 82 | ||||
-rw-r--r-- | cpu/os.asm | 242 |
8 files changed, 487 insertions, 106 deletions
diff --git a/cpu/Makefile b/cpu/Makefile index 898b007..7e92314 100644 --- a/cpu/Makefile +++ b/cpu/Makefile @@ -6,9 +6,13 @@ AUXILLARY=alu.ml SCHED=../sched/sched SIM=../csim/csim MON=../monitor/mon +ASM=../asm/asm -all: _build/cpu_opt.dumb - $(MON) $(SIM) -rom ROM0 prog_rom0.rom $< +all: _build/cpu_opt.dumb os.rom + $(MON) $(SIM) -rom ROM0 os.rom $< + +os.rom: os.asm + $(ASM) $< > $@ %.sim: _build/%.dumb $(SIM) -n 12 $< diff --git a/cpu/prog_rom0.rom b/cpu/ROM_count_seconds.rom index 7330dac..7330dac 100644 --- a/cpu/prog_rom0.rom +++ b/cpu/ROM_count_seconds.rom @@ -53,20 +53,114 @@ let nadder n a b = let a, b = nadder_with_carry n a b (const "0") in b ^. a +let neg n a = nadder n (not a) (one n) + let rec nsubber n a b = - zeroes n (* TODO *) + let r, c = nadder_with_carry n a (not b) (const "1") in + c ^. r + + + + +(* Some operations on Redundant Binary Representation + Each binary digit is encoded on 2 bits + + A n-digits number in RBR is written + [a_0, a'_0, a_1, a'_1, ..., a_(n-1), a'_(n-1)] + +*) + +(* [a] and [b] are encoded on 2n bits + [c_in] and [c_out] on 2 bits *) + +let rec rbr_nadder_with_carry n a b c_in = + + if n = 0 then (zeroes 0), c_in else + + let fa1s, fa1r = fulladder (a ** 1) (b ** 0) (b ** 1) in + let fa2s, fa2r = fulladder (c_in ** 1) (a ** 0) fa1s in + + let rec_s, rec_c = + rbr_nadder_with_carry (n - 1) + (a % (2, 2*n - 1)) + (b % (2, 2*n - 1)) + (fa1r ++ fa2r) + + in (c_in ** 0) ++ fa2s ++ rec_s, rec_c + + +let rbr_nadder n a b = + let s, c = rbr_nadder_with_carry n a b (zeroes 2) in + c ^. s + + +let bin_of_rbr n a c = + + (* Split even and odd bits *) + let rec split_bits n a = + if n = 0 then (zeroes 0, zeroes 0) + else + let even, odd = split_bits (n-1) (a % (2, 2*n - 1)) in + (a ** 0) ++ even, (a ** 1) ++ odd + + in + let a_even, a_odd = split_bits n a in + + nadder n a_even a_odd + + + +(* TODO : move to utils module *) +let rec range a b = if a > b then [] else a :: (range (a+1) b) + +(* Sépare en deux listes de même taille une liste de taille paire *) +let rec split_list = function + | [] -> [], [] + | [_] -> assert false + | x::y::tl -> let a, b = split_list tl in x::a, y::b + +let nmulu n a b start_signal = + let next_busy, set_next_busy = loop 1 in + let busy = start_signal ^| (reg 1 next_busy) in + + (* 'mule' est intialisé à b au début de la multiplication, + puis à chaque cycle est shifté de 1 bit vers la droite (donc perd le bit de poid faible) *) + let mule, set_mule = loop n in + let mule = set_mule (mux start_signal (((reg n mule) % (1, n-1)) ++ const "0") b) in + (* 'adde' est initialisé à a étendu sur 32 bits au début de la multiplication, + puis à chaque cycle est shifté de 1 bit vers la gauche (donc multiplié par 2) *) + let adde, set_adde = loop (2*n) in + let adde = set_adde (mux start_signal (const "0" ++ ((reg (2*n) adde) % (0, 2*n-2))) (a ++ (zeroes n))) in + + (* 'res' est un accumulateur qui contient le résultat que l'on calcule, + il est initialisé à 0 au début de la multiplication, et à chaque cycle + si mule[0] est non nul, on lui rajoute adde (c'est correct) *) + let res, set_res = loop (2*n) in + let t_res = mux start_signal (reg (2*n) res) (zeroes (2*n)) in + let res = set_res (mux (mule ** 0) t_res (nadder (2*n) adde t_res)) in + let work_remains = nonnull (n - 1) (mule % (1, n-1)) in + + let finished = + set_next_busy (busy ^& work_remains) ^. + (not work_remains) ^& busy in + + res % (0, n-1), res % (n, 2*n-1), finished + + + +let rec ndivu n a b start_signal = + zeroes (n-3) ++ const "110", zeroes (n-3) ++ const "110", start_signal + (* TODO : unsigned division, returns quotient and remainder *) -let rec nmul n a b = - zeroes n, zeroes n (* TODO : retuns lo and hi part of 32-bit answer *) +let rec nmul n a b start_signal = + zeroes (n-3) ++ const "101", zeroes (n-3) ++ const "101", start_signal + (* TODO : signed multiplication ; returns low part and high part *) -let rec ndiv n a b = - zeroes n, zeroes n (* TODO : returns quotient and remainder *) -let rec nmulu n a b = - zeroes n, zeroes n (* TODO : same as nmul but unsigned *) +let rec ndiv n a b start_signal = + zeroes (n - 3) ++ const "011", zeroes (n - 3) ++ const "011", start_signal + (* TODO : signed division *) -let rec ndivu n a b = - zeroes n, zeroes n (* TODO : save as ndiv but unsigned *) (* Shifts *) @@ -123,26 +217,31 @@ let alu_comparer n f0 f a b = let lte = mux (f ** 1) lte_signed lte_unsigned in mux f0 eq_ne lte -let alu_arith f1 f a b = +let alu_arith f0 f a b start_signal = (* See table for ALU below *) let add = nadder 16 a b in let sub = nsubber 16 a b in - let mul, mul2 = nmul 16 a b in - let div, div2 = ndiv 16 a b in - let mulu, mulu2 = nmulu 16 a b in - let divu, divu2 = ndivu 16 a b in + let mul, mul2, mul_end_signal = nmul 16 a b start_signal in + let div, div2, div_end_signal = ndiv 16 a b start_signal in + let mulu, mulu2, mulu_end_signal = nmulu 16 a b start_signal in + let divu, divu2, divu_end_signal = ndivu 16 a b start_signal in let q00 = mux (f ** 0) add sub in let q01 = mux (f ** 0) mul div in let q03 = mux (f ** 0) mulu divu in let q10 = mux (f ** 1) q00 q01 in let q11 = mux (f ** 1) q00 q03 in - let q = mux f1 q10 q11 in + let q = mux f0 q10 q11 in let r01 = mux (f ** 0) mul2 div2 in let r03 = mux (f ** 0) mulu2 divu2 in let r10 = mux (f ** 1) (zeroes 16) r01 in let r11 = mux (f ** 1) (zeroes 16) r03 in - let r = mux f1 r10 r11 in - q, r + let r = mux f0 r10 r11 in + let s01 = mux (f ** 0) mul_end_signal div_end_signal in + let s03 = mux (f ** 0) mulu_end_signal divu_end_signal in + let s10 = mux (f ** 1) start_signal s01 in + let s11 = mux (f ** 1) start_signal s03 in + let end_signal = mux f0 s10 s11 in + q, r, end_signal let alu_logic f a b = (* See table for ALU below *) @@ -155,9 +254,9 @@ let alu_shifts f a b = let q1 = mux (f ** 0) (op_lsr 16 a b) (op_asr 16 a b) in mux (f ** 1) (op_lsl 16 a b) q1 -let alu f1 f0 f a b = +let alu f1 f0 f a b start_signal = (* - f0 f1 f action + f1 f0 f action -- -- - ------ 0 0 0 add 0 0 1 sub @@ -176,12 +275,13 @@ let alu f1 f0 f a b = 1 1 2 lsr 1 1 3 asr *) - let arith, arith_r = alu_arith f1 f a b in + let arith, arith_r, arith_end_signal = alu_arith f0 f a b start_signal in let logic = alu_logic f a b in let shifts = alu_shifts f a b in - let q0 = mux f1 logic shifts in - let s = mux f0 arith q0 in - let r = mux f0 arith_r (zeroes 16) in - s, r + let q0 = mux f0 logic shifts in + let s = mux f1 arith q0 in + let r = mux f1 arith_r (zeroes 16) in + let end_signal = mux f1 arith_end_signal start_signal in + s, r, end_signal @@ -6,6 +6,8 @@ let ser_in_busy, save_ser_in_busy = loop 1 let dbg_ra, save_dbg_ra = loop 16 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 cpu_ram ra we wa d = (* Ram chip has word size = 8 bits and address size = 16 bits @@ -54,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)) ^. @@ -61,6 +64,8 @@ let cpu_ram ra we wa d = save_dbg_ra ra ^. save_dbg_read_data read_data ^. + save_dbg_wa wa ^. + save_dbg_write_data d ^. read_data @@ -149,18 +154,18 @@ let rl, rh, i, ex, exf, pc = (* instruction : add/sub/mul/div/unsigned/or/and/xor/nor/lsl/lsr/asr *) let instr_alu = eq_c 3 (i_i % (2, 4)) 0b000 in - let f0 = i_i ** 0 in let f1 = i_i ** 1 in + let f0 = i_i ** 0 in let double_instr_alu = instr_alu ^& (not f1) ^& (i_f ** 1) ^& (ne_n 3 i_r (const "101")) in - let instr_alu = exec ^& instr_alu in - let instr_alu_2 = reg 1 (exec ^& double_instr_alu) in - let alu_d1, alu_d2 = alu f1 f0 i_f v_ra v_rb in - let wr = mux instr_alu wr i_r in - let rwd = mux instr_alu rwd alu_d1 in - let wr = mux instr_alu_2 wr (const "101") in - let rwd = mux instr_alu_2 rwd alu_d2 in - let exec_finished = mux double_instr_alu exec_finished instr_alu_2 in + let alu_d1, alu_d2, instr_alu_finished = alu f1 f0 i_f v_ra v_rb (exec ^& instr_alu) in + let instr_alu_store_2 = reg 1 (instr_alu_finished ^& double_instr_alu) in + let wr = mux instr_alu_finished wr i_r in + let rwd = mux instr_alu_finished rwd alu_d1 in + let wr = mux instr_alu_store_2 wr (const "101") in + let rwd = mux instr_alu_store_2 rwd alu_d2 in + let exec_finished = mux instr_alu exec_finished + (mux double_instr_alu instr_alu_finished instr_alu_store_2) in (* instruction : se/sne/slt/slte/sleu/sleu *) @@ -183,6 +188,7 @@ let rl, rh, i, ex, exf, pc = let instr_j = exec ^& eq_c 5 i_i 0b01000 in let next_pc = mux instr_j next_pc (nadder 16 pc (sign_extend 11 16 i_jd)) in (* instruction : jal *) + let link_pc = next_pc in let instr_jal = exec ^& eq_c 5 i_i 0b01001 in let next_pc = mux instr_jal next_pc (nadder 16 pc (sign_extend 11 16 i_jd)) in let instr_jalxx = instr_jal in @@ -196,7 +202,7 @@ let rl, rh, i, ex, exf, pc = let next_pc = mux cond_jxxr next_pc v_r in (* prologue for jal/jalr *) let wr = mux instr_jalxx wr (const "011") in - let rwd = mux instr_jalxx rwd next_pc in + let rwd = mux instr_jalxx rwd link_pc in (* instruction : lra *) let instr_lra = exec ^& eq_c 5 i_i 0b01100 in @@ -272,6 +278,11 @@ let rl, rh, i, ex, exf, pc = ( (* lil *) i_id ++ (mux instr_lixz (v_r % (8, 15)) (zeroes 8))) ( (* liu *) (mux instr_lixz (v_r % (0, 7)) (zeroes 8)) ++ i_id)) in + (* instruction : lie *) + let instr_lie = eq_c 5 i_i 0b11100 in + let wr = mux instr_lie wr i_r in + let rwd= mux instr_lie rwd (sign_extend 8 16 i_id) in + save_cpu_regs wr rwd ^. save_ram_read (cpu_ram ra we wa d) ^. save_next_read exec_finished ^. @@ -287,11 +298,13 @@ let p = [ "read_ilow", 1, rl; "read_ihi", 1, rh; - "exec_instr", 1, ex; - "exec_finished", 1, exf; - "instruction", 16, i; + "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; @@ -305,5 +318,5 @@ let p = "ser_in_busy", 1, ser_in_busy; ] -let () = Netlist_gen.print stdout p +let () = Netlist_printer.print_program stdout p diff --git a/cpu/netlist_gen.ml b/cpu/netlist_gen.ml index 016c595..956de91 100644 --- a/cpu/netlist_gen.ml +++ b/cpu/netlist_gen.ml @@ -59,7 +59,12 @@ let ( ++ ) v1 v2 = let x1, p = v1 p in let x2, p = v2 p in let sz1, sz2 = get_size p x1, get_size p x2 in - (Avar i), add p i (Econcat (x1, x2)) (sz1 + sz2) + if sz1 = 0 then + (x2), p + else if sz2 = 0 then + (x1), p + else + (Avar i), add p i (Econcat (x1, x2)) (sz1 + sz2) let ( ^| ) v1 v2 = let i = id "" in @@ -198,66 +203,3 @@ let program entries outputs = p_outputs = List.rev outputs } -(* Netlist printer *) - -let init_string n f = - let s = String.make n 'a' in - for i = 0 to n - 1 do - s.[i] <- f i - done; - s - -(* value to string *) -let vts bits = - init_string (Array.length bits) (fun i -> - if bits.(i) then '1' else '0') - -(* argument to string *) -let ats = function - | Avar id -> id - | Aconst n -> vts n - -let s_op = function - | Or -> "OR" - | Xor -> "XOR" - | And -> "AND" - | Nand -> "NAND" - -let print oc p = - let print_eq oc (s,e) = - let s_e = - match e with - | Earg a -> ats a - | Ereg s -> "REG " ^ s - | Enot a -> "NOT " ^ (ats a) - | Ebinop (b,a1,a2) -> (s_op b) ^ " " ^ (ats a1) ^ " " ^ (ats a2) - | Emux (a1,a2,a3) -> - "MUX " ^ (ats a1) ^ " " ^ (ats a2) ^ " " ^ (ats a3) - | Erom (n1,n2,a3) -> - "ROM " ^ (string_of_int n1) ^ " " ^ (string_of_int n2) ^ - " " ^ (ats a3) - | Eram (n1,n2,a3,a4,a5,a6) -> - "RAM " ^ (string_of_int n1) ^ " " ^ (string_of_int n2) ^ - " " ^ (ats a3) ^ " " ^ (ats a4) ^ " " ^ (ats a5) ^ - " " ^ (ats a6) - | Econcat (a1,a2) -> "CONCAT " ^ (ats a1) ^ " " ^ (ats a2) - | Eslice (n1,n2,a3) -> "SLICE " ^ (string_of_int n1) ^ " " ^ - (string_of_int n2) ^ " " ^ (ats a3) - | Eselect (n,a) -> "SELECT " ^ (string_of_int n) ^ " " ^ (ats a) in - Printf.fprintf oc "%s = %s\n" s s_e in - Printf.fprintf oc "INPUT "; - if p.p_inputs <> [] then - (Printf.fprintf oc "%s" (List.hd p.p_inputs); List.iter - (Printf.fprintf oc ", %s") (List.tl p.p_inputs)); - Printf.fprintf oc "\nOUTPUT "; - if p.p_outputs <> [] then - (Printf.fprintf oc "%s" (List.hd p.p_outputs); List.iter - (Printf.fprintf oc ", %s") (List.tl p.p_outputs)); - Printf.fprintf oc "\nVAR "; - let stts s t = if t = 1 then s else s ^ " : " ^ (string_of_int t) in - Pervasives.ignore (Env.fold (fun s t b -> - if b then Printf.fprintf oc "%s" (stts s t) - else Printf.fprintf oc ", %s" (stts s t); - false) p.p_vars true); - Printf.fprintf oc "\nIN\n"; - List.iter (print_eq oc) p.p_eqs diff --git a/cpu/netlist_gen.mli b/cpu/netlist_gen.mli index 67d4774..24cd6f1 100644 --- a/cpu/netlist_gen.mli +++ b/cpu/netlist_gen.mli @@ -1,7 +1,5 @@ type t -val print : out_channel -> Netlist_ast.program -> unit - val get : Netlist_ast.ident -> t val loop : int -> (t * (t -> t)) diff --git a/cpu/netlist_printer.ml b/cpu/netlist_printer.ml new file mode 100644 index 0000000..2c80d70 --- /dev/null +++ b/cpu/netlist_printer.ml @@ -0,0 +1,82 @@ +open Netlist_ast +open Format + +let rec print_env print lp sep rp ff env = + let first = ref true in + fprintf ff "%s" lp; + Env.iter + (fun x ty -> + if !first then + (first := false; fprintf ff "%a" print (x, ty)) + else + fprintf ff "%s%a" sep print (x, ty)) env; + fprintf ff "%s" rp + +let rec print_list print lp sep rp ff = function + | [] -> () + | x :: l -> + fprintf ff "%s%a" lp print x; + List.iter (fprintf ff "%s %a" sep print) l; + fprintf ff "%s" rp + +let print_ty ff n = + fprintf ff " : %d" n + +let print_bool ff b = + if b then + fprintf ff "1" + else + fprintf ff "0" + +let print_value ff a = + Array.iter (print_bool ff) a + +let print_arg ff arg = match arg with + | Aconst v -> print_value ff v + | Avar id -> fprintf ff "%s" id + +let print_op ff op = match op with + | And -> fprintf ff "AND" + | Nand -> fprintf ff "NAND" + | Or -> fprintf ff "OR" + | Xor -> fprintf ff "XOR" + +let print_exp ff e = match e with + | Earg a -> print_arg ff a + | Ereg x -> fprintf ff "REG %s" x + | Enot x -> fprintf ff "NOT %a" print_arg x + | Ebinop(op, x, y) -> fprintf ff "%a %a %a" print_op op print_arg x print_arg y + | Emux (c, x, y) -> fprintf ff "MUX %a %a %a " print_arg c print_arg x print_arg y + | Erom (addr, word, ra) -> fprintf ff "ROM %d %d %a" addr word print_arg ra + | Eram (addr, word, ra, we, wa, data) -> + fprintf ff "RAM %d %d %a %a %a %a" addr word + print_arg ra print_arg we + print_arg wa print_arg data + | Eselect (idx, x) -> fprintf ff "SELECT %d %a" idx print_arg x + | Econcat (x, y) -> fprintf ff "CONCAT %a %a" print_arg x print_arg y + | Eslice (min, max, x) -> fprintf ff "SLICE %d %d %a" min max print_arg x + +let print_eq ff (x, e) = + fprintf ff "%s = %a@." x print_exp e + +let print_var ff (x, ty) = + fprintf ff "@[%s%a@]" x print_ty ty + +let print_vars ff env = + fprintf ff "@[<v 2>VAR@,%a@]@.IN@," + (print_env print_var "" ", " "") env + +let print_idents ff ids = + let print_ident ff s = fprintf ff "%s" s in + print_list print_ident """,""" ff ids + +let print_program oc p = + let ff = formatter_of_out_channel oc in + fprintf ff "INPUT %a@." print_idents p.p_inputs; + fprintf ff "OUTPUT %a@." print_idents p.p_outputs; + print_vars ff p.p_vars; + List.iter (print_eq ff) p.p_eqs; + (* flush *) + fprintf ff "@." + + diff --git a/cpu/os.asm b/cpu/os.asm new file mode 100644 index 0000000..6c5d162 --- /dev/null +++ b/cpu/os.asm @@ -0,0 +1,242 @@ +# 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 + jal run_unit_tests + + 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) + add D D B + push D + + jz B main_loop + li A msgtick + jal ser_out_msg + 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: + lb B 0(A) + jz B ser_out_msg_ret + sb B 0(C) + incri A 1 + j 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 + jz A check_input +check_input_ret: + jr RA + +# PROCEDURE: run_unit_tests +# ROLE: check that CPU features work correctly ; displays message to serial output +# ARGUMENTS: none +run_unit_tests: + push RA + + li A testbegin + jal ser_out_msg + + li A test0 + jal ser_out_msg + jal unit_test_0 + li A testfail + jz B t0fail + li A testok +t0fail: + jal ser_out_msg + + li A test1 + jal ser_out_msg + jal unit_test_1 + li A testfail + jz B t1fail + li A testok +t1fail: + jal ser_out_msg + + li A test2 + jal ser_out_msg + jal unit_test_2 + li A testfail + jz B t2fail + li A testok +t2fail: + jal ser_out_msg + + li A test3 + jal ser_out_msg + jal unit_test_3 + li A testfail + jz B t2fail + li A testok +t3fail: + jal ser_out_msg + + pop RA + jr RA + +unit_test_0: # Addition / substraction + li B 1 + + li C 12 + li D 44 + add C C D + sei A C 56 + and B B A + + li C 7 + sub C Z C + li D 7 + add C C D + se A C Z + and B B A + + li C 32767 + li D 32767 + add C C D + li D 2 + sub D Z D + se A C D + and B B A + + jr RA + +unit_test_1: # Unsigned multiplication + li B 1 + + li C 12 + li D 44 + mulu C C D + move D E + sei A C 528 + and B B A + se A D Z + and B B A + + li C 744 + li D 1244 + mulu C C D + move D E + sei A C 8032 + and B B A + sei A D 14 + and B B A + + jr RA + +unit_test_2: + li B 1 + jr RA +unit_test_3: + li B 1 + jr RA + + + +# READ-ONLY PROGRAM DATA +msghello: + ascii "Hello, world!\n" +msgtick: + ascii " ..." +prompt: + ascii "\n$ " +endl: + ascii "\n" +error: + ascii "Sorry but I'm to stupid to understand that.\n" + +testbegin: + ascii "Runing CPU unit tests...\n" +testok: + ascii "OK\n" +testfail: + ascii "FAIL\n" +test0: + ascii "Addition/substraction: " +test1: + ascii "Unsigned multiplication: " +test2: + ascii "Unsigned division: " +test3: + ascii "Signed division/multiplication: " + + + +.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 + + + + + |