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 + -
显示快捷键?