From adb1aa800d0071a1bccf122c2d48e9fa278f19a0 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Tue, 14 Jan 2014 15:17:34 +0100 Subject: Implement basic clock. --- cpu/os.asm | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 201 insertions(+), 30 deletions(-) diff --git a/cpu/os.asm b/cpu/os.asm index 72598c6..9a3d7a6 100644 --- a/cpu/os.asm +++ b/cpu/os.asm @@ -12,9 +12,18 @@ jal run_unit_tests li A msghello - jal ser_out_msg + jal ser_out_str + + li A 1994 + li B var_year + sw A 0(B) + li A 2 + li B var_month + sb A 0(B) + li A 26 + li B var_day + sb A 0(B) - push Z _main_loop: # Process serial input jal check_input @@ -23,17 +32,118 @@ _main_loop: _end_process_input: # Process clock ticking - pop D li B _clock - lw B 0(B) - add D D B - push D + lw A 0(B) + jz A _main_loop - jz B _main_loop - li A msgtick - jal ser_out_msg + jal incr_clock + jal disp_time j _main_loop +# PROCEDURE: incr_clock +# ROLE: take into account seconds increment +# ARGUMENTS: number of seconds to add, in register A +incr_clock: + jz A _incr_clock_ret + + lb B var_sec + add B B A + li C 60 + divu A B C + move B E + sb B var_sec + jz A _incr_clock_ret + + lb B var_min + add B B A + divu A B C + move B E + sb B var_min + jz A _incr_clock_ret + + lb B var_hour + add B B A + li C 24 + divu A B C + move B E + sb B var_hour + jz A _incr_clock_ret + + 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 + move B E + sb B var_day + jz A _incr_clock_ret + + lb B var_month + add B B A + li C 12 + divu A B C + move B E + sb B var_month + jz A _incr_clock_ret + + lw B var_year + add B B A + sw B var_year + + +_incr_clock_ret: + jr RA + +# PROCEDURE: disp_clock +# ROLE: display current time +# ARGUMENTS: none +disp_time: + push RA + + lw A var_year + jal ser_out_int_dec + li A '-' + li E _output + sb A 0(E) + + lb A var_month + incri A 1 + jal ser_out_int_dec_two_digit + li A '-' + li E _output + sb A 0(E) + + lb A var_day + incri A 1 + jal ser_out_int_dec_two_digit + li A ' ' + li E _output + sb A 0(E) + + lb A var_hour + jal ser_out_int_dec_two_digit + li A ':' + li E _output + sb A 0(E) + + lb A var_min + jal ser_out_int_dec_two_digit + li A ':' + li E _output + sb A 0(E) + + lb A var_sec + jal ser_out_int_dec_two_digit + li A '\n' + li E _output + sb A 0(E) + + pop RA + jr RA + + # PROCEDURE: run_cmd # ROLE: execute and clear command stored in cmdline # ARGUMENTS: none @@ -41,14 +151,14 @@ run_cmd: push RA li A prompt - jal ser_out_msg + jal ser_out_str li A cmdline - jal ser_out_msg + jal ser_out_str li A endl - jal ser_out_msg + jal ser_out_str li A error - jal ser_out_msg + jal ser_out_str li A cmdline_used sw Z 0(A) @@ -57,18 +167,63 @@ run_cmd: jr RA -# PROCEDURE: ser_out_msg +# PROCEDURE: ser_out_int_dec +# ROLE: write a decimal integer to serial output +# ARGUMENTS: integer to write in register A +ser_out_int_dec: + jz A _display_zero + push Z + li B 10 +_divide_int_by_ten: + jz A _show_dec + divu A A B + move C E + addi C C '0' + push C + j _divide_int_by_ten +_show_dec: + li C _output + pop A + jz A _return_out_dec + sb A 0(C) + j _show_dec +_return_out_dec: + jr RA +_display_zero: + li C _output + li D '0' + sb D 0(C) + jr RA + +# PROCEDURE: ser_out_two_digit +# ROLE: write only the two lower digits of a decimal integer to serial output +# ARGUMENTS: integer to write in register A +ser_out_int_dec_two_digit: + li B 10 + divu A A B + move C E + divu A A B + move D E + li B _output + addi D D '0' + addi C C '0' + sw D 0(B) + sw C 0(B) + jr RA + + +# PROCEDURE: ser_out_str # ROLE: write null-terminated string to serial output # ARGUMENTS: address of string in register A -ser_out_msg: +ser_out_str: li C _output -_ser_out_msg_loop: +_ser_out_str_loop: lb B 0(A) - jz B _ser_out_msg_ret + jz B _ser_out_str_ret sb B 0(C) incri A 1 - j _ser_out_msg_loop -_ser_out_msg_ret: + j _ser_out_str_loop +_ser_out_str_ret: jr RA # PROCEDURE: check_input @@ -105,7 +260,7 @@ run_unit_tests: push RA li A testbegin - jal ser_out_msg + jal ser_out_str move B Z @@ -120,14 +275,14 @@ _unit_test_begin: li A teststr add A A B lw A 0(A) - jal ser_out_msg + jal ser_out_str pop D jalr D li A testfail jz B _unit_test_failed li A testok _unit_test_failed: - jal ser_out_msg + jal ser_out_str pop B addi B B 2 @@ -198,14 +353,14 @@ unit_test_2: # Unsigned division sei A D 1 and B B A - #li C 61 - #li D 5 - #divu C C D - #move D E - #sei A C 12 - #and B B A - #sei A D 1 - #and B B A + li C 54200 + li D 4203 + divu C C D + move D E + sei A C 12 + and B B A + sei A D 3764 + and B B A jr RA unit_test_3: # Signed multiplication/division @@ -228,6 +383,7 @@ endl: error: ascii "Sorry but I'm to stupid to understand that.\n" + # For unit-tests testlist: word unit_test_0 unit_test_1 unit_test_2 unit_test_3 0 @@ -249,6 +405,9 @@ test3: ascii "Signed multiplication/division. " +days_in_month: + byte 31 28 31 30 31 30 31 31 30 31 30 31 + .data # Space where command-line is buffered from serial input (256 bytes) @@ -258,6 +417,18 @@ cmdline: cmdline_used: word 1 +var_sec: + byte 1 +var_min: + byte 1 +var_hour: + byte 1 +var_day: + byte 1 +var_month: + byte 1 +var_year: + word 1 -- cgit v1.2.3