uclock.psm
来自「PacoBlaze is a from-scratch synthesizabl」· PSM 代码 · 共 1,009 行 · 第 1/4 页
PSM
1,009 行
store int_counter_lsb, us_time_stamp_lsb ;counter. Interrupts are disabled to ensure that both bytes relate
store int_counter_msb, us_time_stamp_msb ;to the same count value.
interrupt enable
fetch s4, us_time_stamp_lsb ;read the new 'us' time stamp in [s5,s4]
fetch s5, us_time_stamp_msb ;
sub s4, s2 ;calculate 'us' time difference [s5,s4] = [s5,s4] - [s3,s2]
subcy s5, s3 ; (This works correctly even if counter has rolled over)
fetch s2, us_time_lsb ;read current 'us' time into [s3,s2]
fetch s3, us_time_msb
add s2, s4 ;add on the elapsed 'us' value [s3,s2] = [s3,s2] + [s5,s4]
addcy s3, s5
;determine how many 1000us (1ms) units there are (if any) in current 'us' time
load s0, $00 ;reset 'ms' counter
test_1000us: sub s2, count_1000_lsb ;subtract 1000 from [s3,s2]
subcy s3, count_1000_msb
jump c, store_us_time ;Carry indicates [s3,s2] was less than 1000us
add s0, $01 ;increment 'ms' elapsed because [s3,s2] was more or equal to 1000us
jump test_1000us ;repeat to see if more than 1ms has elapsed
store_us_time: add s2, count_1000_lsb ;add 1000 to restore 'us' value
addcy s3, count_1000_msb
store s2, us_time_lsb ;store the current value of 'us'
store s3, us_time_msb
;s0 holds the number of 'ms' elapsed since last update (if any).
fetch s2, ms_time_lsb ;read current 'ms' time into [s3,s2]
fetch s3, ms_time_msb
add s2, s0 ;add on the elapsed 'ms' value [s3,s2] = [s3,s2] + s0
addcy s3, $00
;determine if there are now more than 1000ms to form 1 second.
load s0, $00 ;reset 'second' counter
sub s2, count_1000_lsb ;subtract 1000 from [s3,s2]
subcy s3, count_1000_msb
jump c, restore_ms_time ;Carry indicates [s3,s2] was less than 1000ms
add s0, $01 ;increment 'second' elapsed because [s3,s2] was more or equal to 1000ms
jump store_ms_time ;new value of 'ms' is remainder of subtraction
restore_ms_time: add s2, count_1000_lsb ;add 1000 to restore 'ms' value
addcy s3, count_1000_msb
store_ms_time: store s2, ms_time_lsb ;store the current value of 'ms'
store s3, ms_time_msb
;s0 currently determines if one second needs to be added to the hh:mm:ss clock time
fetch s1, real_time_seconds ;read seconds
add s1, s0 ;add one second if required by s0
compare s1, seconds_in_a_minute ;test for 1 minute
jump z, inc_minutes
store s1, real_time_seconds ;store updated seconds
jump time_update_complete
inc_minutes: load s1, $00 ;seconds become zero
store s1, real_time_seconds
fetch s1, real_time_minutes ;read minutes
add s1, $01 ;increment minutes
compare s1, minutes_in_an_hour ;test for 1 hour
jump z, inc_hours
store s1, real_time_minutes ;store updated minutes
jump time_update_complete
inc_hours: load s1, $00 ;minutes become zero
store s1, real_time_minutes
fetch s1, real_time_hours ;read hours
add s1, $01 ;increment hours
compare s1, hours_in_a_day ;test for 24 hours
jump z, reset_hours
store s1, real_time_hours ;store updated hours
jump time_update_complete
reset_hours: load s1, $00 ;hours become zero
store s1, real_time_hours
;
;With the time updated, there is then a test for time=alarm time
;
time_update_complete: fetch s0, real_time_hours
fetch s1, alarm_time_hours ;compare hours
compare s0, s1
jump nz, finish_update
fetch s0, real_time_minutes ;compare minutes
fetch s1, alarm_time_minutes
compare s0, s1
jump nz, finish_update
fetch s0, real_time_seconds ;compare seconds
fetch s1, alarm_time_seconds
compare s0, s1
jump nz, finish_update
fetch s0, alarm_status ;test if alarm is turned on
test s0, alarm_armed
jump z, finish_update ;alarm was off
or s0, alarm_active ;activate alarm
store s0, alarm_status
call alarm_drive
finish_update: fetch s0, time_preserve0 ;restore the register contents
fetch s1, time_preserve1
fetch s2, time_preserve2
fetch s3, time_preserve3
fetch s4, time_preserve4
fetch s5, time_preserve5
return
;
;Convert character to upper case
;
;The character supplied in register s0.
;If the character is in the range 'a' to 'z', it is converted
;to the equivalent upper case character in the range 'A' to 'Z'.
;All other characters remain unchanged.
;
;Registers used s0.
;
upper_case: compare s0, $61 ;eliminate character codes below 'a' (61 hex)
return c
compare s0, $7B ;eliminate character codes above 'z' (7A hex)
return nc
and s0, $DF ;mask bit5 to convert to upper case
return
;
;
;Convert character '0' to '9' to numerical value in range 0 to 9
;
;The character supplied in register s0. If the character is in the
;range '0' to '9', it is converted to the equivalent decimal value.
;Characters not in the range '0' to '9' are signified by the return
;with the CARRY flag set.
;
;Registers used s0.
;
_1char_to_value: add s0, $C6 ;reject character codes above '9' (39 hex)
return c ;carry flag is set
sub s0, $F6 ;reject character codes below '0' (30 hex)
return ;carry is set if value not in range
;
;
;Determine the numerical value of a two character decimal string held in
;scratch pad memory such the result is in the range 0 to 99 (00 to 63 hex).
;
;The string must be stored as in two consecutive memory locations and the
;location of the first (tens) character supplied in the s1 register.
;The result is provided in register s2. Strings not using characters in the
;range '0' to '9' are signified by the return with the CARRY flag set.
;
;Registers used s0, s1 and s2.
;
_2char_to_value: fetch s0, s1 ;read 'tens' character
call _1char_to_value ;convert to numerical value
return c ;bad character - CARRY set
load s2, s0
sl0 s2 ;multiply 'tens' value by 10 (0A hex)
sl0 s2
add s2, s0
sl0 s2
add s1, $01 ;read 'units' character
fetch s0, s1
call _1char_to_value ;convert to numerical value
return c ;bad character - CARRY set
add s2, s0 ;add units to result and clear CARRY flag
return
;
;
;Interrupt service routine (ISR)
;
;The interrupt is used to increment a 16-bit counter formed with two registers
;called [int_counter_msb,int_counter_lsb]. This provides a count of the number
;of micro-seconds elapsed. The counter is 'free running' in that it will count
;up to 65,535 and then roll over to zero. The count value is then used in other
;parts of the program as required and where it is less time critical.
;
;The ISR only uses the specified counter registers
;
address $3FC
ISR: add int_counter_lsb, $01 ;add 1us to 16-bit counter
addcy int_counter_msb, $00
returni enable
;
;Interrupt vector
;
address $3FF
jump ISR
;
;
;Useful constants
;
;
;ASCII table
;
constant character_a, $61
constant character_b, $62
constant character_c, $63
constant character_d, $64
constant character_e, $65
constant character_f, $66
constant character_g, $67
constant character_h, $68
constant character_i, $69
constant character_j, $6A
constant character_k, $6B
constant character_l, $6C
constant character_m, $6D
constant character_n, $6E
constant character_o, $6F
constant character_p, $70
constant character_q, $71
constant character_r, $72
constant character_s, $73
constant character_t, $74
constant character_u, $75
constant character_v, $76
constant character_w, $77
constant character_x, $78
constant character_y, $79
constant character_z, $7A
constant character_A, $41
constant character_B, $42
constant character_C, $43
constant character_D, $44
constant character_E, $45
constant character_F, $46
constant character_G, $47
constant character_H, $48
constant character_I, $49
constant character_J, $4A
constant character_K, $4B
constant character_L, $4C
constant character_M, $4D
constant character_N, $4E
constant character_O, $4F
constant character_P, $50
constant character_Q, $51
constant character_R, $52
constant character_S, $53
constant character_T, $54
constant character_U, $55
constant character_V, $56
constant character_W, $57
constant character_X, $58
constant character_Y, $59
constant character_Z, $5A
constant character_0, $30
constant character_1, $31
constant character_2, $32
constant character_3, $33
constant character_4, $34
constant character_5, $35
constant character_6, $36
constant character_7, $37
constant character_8, $38
constant character_9, $39
constant character_colon, $3A
constant character_semi_colon, $3B
constant character_less_than, $3C
constant character_greater_than, $3E
constant character_equals, $3D
constant character_space, $20
constant character_CR, $0D ;carriage return
constant character_question, $3F ;'?'
constant character_dollar, $24
constant character_BS, $08 ;Back Space command character
;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?