mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-28 07:02:55 +08:00
2552 lines
105 KiB
Plaintext
2552 lines
105 KiB
Plaintext
/* Symbol Table */
|
|
// CRC_send_loop = LABEL: 128
|
|
// ISR = LABEL: 997
|
|
// ISR_preserve_s0 = CONSTANT: 0
|
|
// LCD_DB4 = CONSTANT: 16
|
|
// LCD_DB5 = CONSTANT: 32
|
|
// LCD_DB6 = CONSTANT: 64
|
|
// LCD_DB7 = CONSTANT: 128
|
|
// LCD_E = CONSTANT: 1
|
|
// LCD_RS = CONSTANT: 4
|
|
// LCD_RW = CONSTANT: 2
|
|
// LCD_clear = LABEL: 825
|
|
// LCD_cursor = LABEL: 830
|
|
// LCD_drive = CONSTANT: 8
|
|
// LCD_input_port = CONSTANT: 3
|
|
// LCD_output_port = CONSTANT: 32
|
|
// LCD_pulse_E = LABEL: 741
|
|
// LCD_read_DB4 = CONSTANT: 16
|
|
// LCD_read_DB5 = CONSTANT: 32
|
|
// LCD_read_DB6 = CONSTANT: 64
|
|
// LCD_read_DB7 = CONSTANT: 128
|
|
// LCD_read_data8 = LABEL: 783
|
|
// LCD_read_spare0 = CONSTANT: 1
|
|
// LCD_read_spare1 = CONSTANT: 2
|
|
// LCD_read_spare2 = CONSTANT: 4
|
|
// LCD_read_spare3 = CONSTANT: 8
|
|
// LCD_reset = LABEL: 808
|
|
// LCD_write_data = LABEL: 766
|
|
// LCD_write_inst4 = LABEL: 747
|
|
// LCD_write_inst8 = LABEL: 751
|
|
// Menu = LABEL: 60
|
|
// SF_addr_hi_port = CONSTANT: 131
|
|
// SF_addr_lo_port = CONSTANT: 129
|
|
// SF_addr_mi_port = CONSTANT: 130
|
|
// SF_byte_read = LABEL: 257
|
|
// SF_byte_write = LABEL: 267
|
|
// SF_ce = CONSTANT: 2
|
|
// SF_control_port = CONSTANT: 64
|
|
// SF_data_in_port = CONSTANT: 2
|
|
// SF_data_out_port = CONSTANT: 128
|
|
// SF_erase_block = LABEL: 228
|
|
// SF_init = LABEL: 225
|
|
// SF_read = CONSTANT: 1
|
|
// SF_single_byte_write = LABEL: 236
|
|
// SF_we = CONSTANT: 4
|
|
// UART_data = REGISTER: 15
|
|
// UART_read_port = CONSTANT: 1
|
|
// UART_write = LABEL: 295
|
|
// UART_write_port = CONSTANT: 8
|
|
// auth_byte_loop = LABEL: 180
|
|
// auth_check2 = LABEL: 156
|
|
// auth_check3 = LABEL: 160
|
|
// auth_check4 = LABEL: 164
|
|
// auth_failure = LABEL: 54
|
|
// auth_line_loop = LABEL: 177
|
|
// auth_passed = LABEL: 51
|
|
// auth_read_delay = LABEL: 171
|
|
// auth_read_loop = LABEL: 151
|
|
// auth_write_check2 = LABEL: 200
|
|
// auth_write_check3 = LABEL: 206
|
|
// auth_write_check4 = LABEL: 212
|
|
// auth_write_loop = LABEL: 193
|
|
// authentication_CRC0 = CONSTANT: 26
|
|
// authentication_CRC1 = CONSTANT: 27
|
|
// authentication_control_port = CONSTANT: 16
|
|
// authentication_status = CONSTANT: 28
|
|
// authorise_command = LABEL: 79
|
|
// character_0 = CONSTANT: 48
|
|
// character_1 = CONSTANT: 49
|
|
// character_2 = CONSTANT: 50
|
|
// character_3 = CONSTANT: 51
|
|
// character_4 = CONSTANT: 52
|
|
// character_5 = CONSTANT: 53
|
|
// character_6 = CONSTANT: 54
|
|
// character_7 = CONSTANT: 55
|
|
// character_8 = CONSTANT: 56
|
|
// character_9 = CONSTANT: 57
|
|
// character_A = CONSTANT: 65
|
|
// character_B = CONSTANT: 66
|
|
// character_BS = CONSTANT: 8
|
|
// character_C = CONSTANT: 67
|
|
// character_CR = CONSTANT: 13
|
|
// character_D = CONSTANT: 68
|
|
// character_E = CONSTANT: 69
|
|
// character_F = CONSTANT: 70
|
|
// character_G = CONSTANT: 71
|
|
// character_H = CONSTANT: 72
|
|
// character_I = CONSTANT: 73
|
|
// character_J = CONSTANT: 74
|
|
// character_K = CONSTANT: 75
|
|
// character_L = CONSTANT: 76
|
|
// character_M = CONSTANT: 77
|
|
// character_N = CONSTANT: 78
|
|
// character_O = CONSTANT: 79
|
|
// character_P = CONSTANT: 80
|
|
// character_Q = CONSTANT: 81
|
|
// character_R = CONSTANT: 82
|
|
// character_S = CONSTANT: 83
|
|
// character_T = CONSTANT: 84
|
|
// character_U = CONSTANT: 85
|
|
// character_V = CONSTANT: 86
|
|
// character_W = CONSTANT: 87
|
|
// character_X = CONSTANT: 88
|
|
// character_Y = CONSTANT: 89
|
|
// character_Z = CONSTANT: 90
|
|
// character_a = CONSTANT: 97
|
|
// character_b = CONSTANT: 98
|
|
// character_c = CONSTANT: 99
|
|
// character_colon = CONSTANT: 58
|
|
// character_comma = CONSTANT: 44
|
|
// character_d = CONSTANT: 100
|
|
// character_divide = CONSTANT: 47
|
|
// character_dollar = CONSTANT: 36
|
|
// character_e = CONSTANT: 101
|
|
// character_equals = CONSTANT: 61
|
|
// character_exclaim = CONSTANT: 33
|
|
// character_f = CONSTANT: 102
|
|
// character_fullstop = CONSTANT: 46
|
|
// character_g = CONSTANT: 103
|
|
// character_greater_than = CONSTANT: 62
|
|
// character_h = CONSTANT: 104
|
|
// character_i = CONSTANT: 105
|
|
// character_j = CONSTANT: 106
|
|
// character_k = CONSTANT: 107
|
|
// character_l = CONSTANT: 108
|
|
// character_less_than = CONSTANT: 60
|
|
// character_m = CONSTANT: 109
|
|
// character_minus = CONSTANT: 45
|
|
// character_n = CONSTANT: 110
|
|
// character_o = CONSTANT: 111
|
|
// character_p = CONSTANT: 112
|
|
// character_plus = CONSTANT: 43
|
|
// character_q = CONSTANT: 113
|
|
// character_question = CONSTANT: 63
|
|
// character_r = CONSTANT: 114
|
|
// character_s = CONSTANT: 115
|
|
// character_semi_colon = CONSTANT: 59
|
|
// character_space = CONSTANT: 32
|
|
// character_t = CONSTANT: 116
|
|
// character_u = CONSTANT: 117
|
|
// character_v = CONSTANT: 118
|
|
// character_w = CONSTANT: 119
|
|
// character_x = CONSTANT: 120
|
|
// character_y = CONSTANT: 121
|
|
// character_z = CONSTANT: 122
|
|
// cold_start = LABEL: 0
|
|
// compute_CRC16 = LABEL: 134
|
|
// compute_seeded_CRC = LABEL: 127
|
|
// computed_CRC0 = CONSTANT: 24
|
|
// computed_CRC1 = CONSTANT: 25
|
|
// crc16_loop = LABEL: 135
|
|
// crc16_shift = LABEL: 141
|
|
// delay_1ms = LABEL: 849
|
|
// delay_1s = LABEL: 859
|
|
// delay_1us = LABEL: 840
|
|
// delay_1us_constant = CONSTANT: 11
|
|
// delay_20ms = LABEL: 854
|
|
// delay_40us = LABEL: 844
|
|
// delay_Ns = LABEL: 864
|
|
// disable_app_hardware = LABEL: 86
|
|
// disp_Authentication = LABEL: 937
|
|
// disp_FLASH_Serial_No = LABEL: 904
|
|
// disp_Failed = LABEL: 982
|
|
// disp_Passed = LABEL: 968
|
|
// disp_PicoBlaze = LABEL: 868
|
|
// disp_SN_loop = LABEL: 119
|
|
// disp_Security = LABEL: 887
|
|
// disp_hex_byte = LABEL: 333
|
|
// disp_serial_number = LABEL: 112
|
|
// end_ISR = LABEL: 1016
|
|
// end_disp_SN = LABEL: 125
|
|
// end_read_SN = LABEL: 255
|
|
// end_send_SN = LABEL: 110
|
|
// erase_authentication = LABEL: 222
|
|
// erase_command = LABEL: 75
|
|
// hex_byte_to_ASCII = LABEL: 303
|
|
// hex_to_ASCII = LABEL: 315
|
|
// link_FIFO_write_port = CONSTANT: 4
|
|
// next_auth_read = LABEL: 168
|
|
// number_char = LABEL: 318
|
|
// pass_token = LABEL: 1010
|
|
// random_value_port = CONSTANT: 4
|
|
// read_SF_serial_number = LABEL: 242
|
|
// read_SN_loop = LABEL: 248
|
|
// read_authentication = LABEL: 148
|
|
// read_character = LABEL: 289
|
|
// read_command = LABEL: 70
|
|
// read_from_UART = LABEL: 285
|
|
// rx_data_present = CONSTANT: 4
|
|
// rx_full = CONSTANT: 16
|
|
// rx_half_full = CONSTANT: 8
|
|
// s0 = REGISTER: 0
|
|
// s1 = REGISTER: 1
|
|
// s2 = REGISTER: 2
|
|
// s3 = REGISTER: 3
|
|
// s4 = REGISTER: 4
|
|
// s5 = REGISTER: 5
|
|
// s6 = REGISTER: 6
|
|
// s7 = REGISTER: 7
|
|
// s8 = REGISTER: 8
|
|
// s9 = REGISTER: 9
|
|
// sA = REGISTER: 10
|
|
// sB = REGISTER: 11
|
|
// sC = REGISTER: 12
|
|
// sD = REGISTER: 13
|
|
// sE = REGISTER: 14
|
|
// sF = REGISTER: 15
|
|
// security_disable_interrupts = CONSTANT: 1
|
|
// security_disable_outputs = CONSTANT: 2
|
|
// send_Auth = LABEL: 527
|
|
// send_Authentication = LABEL: 562
|
|
// send_Authoris = LABEL: 536
|
|
// send_Authorisation = LABEL: 546
|
|
// send_Authorise = LABEL: 558
|
|
// send_CR = LABEL: 340
|
|
// send_CRC = LABEL: 585
|
|
// send_Computed_CRC = LABEL: 594
|
|
// send_Copyright = LABEL: 436
|
|
// send_Erase = LABEL: 611
|
|
// send_Erase_in_progress = LABEL: 623
|
|
// send_FAILED = LABEL: 655
|
|
// send_FLASH = LABEL: 487
|
|
// send_FLASH_CRC = LABEL: 584
|
|
// send_FLASH_Serial_Number = LABEL: 498
|
|
// send_Menu = LABEL: 700
|
|
// send_OK = LABEL: 649
|
|
// send_PASSED = LABEL: 669
|
|
// send_SN_loop = LABEL: 103
|
|
// send_Writing = LABEL: 682
|
|
// send_auth_page = LABEL: 174
|
|
// send_dash = LABEL: 351
|
|
// send_equals = LABEL: 346
|
|
// send_hex_3bytes = LABEL: 326
|
|
// send_hex_byte = LABEL: 320
|
|
// send_serial_number = LABEL: 101
|
|
// send_space = LABEL: 343
|
|
// send_to_UART = LABEL: 291
|
|
// send_welcome = LABEL: 356
|
|
// serial_number0 = CONSTANT: 16
|
|
// serial_number1 = CONSTANT: 17
|
|
// serial_number2 = CONSTANT: 18
|
|
// serial_number3 = CONSTANT: 19
|
|
// serial_number4 = CONSTANT: 20
|
|
// serial_number5 = CONSTANT: 21
|
|
// serial_number6 = CONSTANT: 22
|
|
// serial_number7 = CONSTANT: 23
|
|
// set_SF_read_array_mode = LABEL: 277
|
|
// set_line2 = LABEL: 836
|
|
// spare1 = CONSTANT: 32
|
|
// spare2 = CONSTANT: 64
|
|
// status_port = CONSTANT: 0
|
|
// strataflash_sts = CONSTANT: 128
|
|
// tx_full = CONSTANT: 2
|
|
// tx_half_full = CONSTANT: 1
|
|
// upper_case = LABEL: 297
|
|
// wait_1ms = LABEL: 850
|
|
// wait_1s = LABEL: 860
|
|
// wait_1us = LABEL: 841
|
|
// wait_20ms = LABEL: 855
|
|
// wait_40us = LABEL: 845
|
|
// wait_SF_ready = LABEL: 280
|
|
// warm_start = LABEL: 8
|
|
// write_auth = LABEL: 218
|
|
// write_authentication = LABEL: 190
|
|
|
|
/* Program Code */
|
|
// #1: ; KCPSM3 Program - Security control and design authentication.
|
|
// #2: ;
|
|
// #3: ; This program is provided for use with the reference design
|
|
// #4: ; 'low_cost_design_authentication_for_spartan_3e.vhd' implemented on the Spartan-3E Starter
|
|
// #5: ; Kit. The program provides design authentication control over the 'real' application as well
|
|
// #6: ; as providing features to enable evaluation of the design authentication method.
|
|
// #7: ;
|
|
// #8: ; Ken Chapman - Xilinx Ltd
|
|
// #9: ;
|
|
// #10: ; Version v1.00 - 1st November 2006
|
|
// #11: ;
|
|
// #12: ; This code communicates with the StrataFLASH memory to implement a design authentication
|
|
// #13: ; algorithm which then enables the main application design in various ways. To facilitate
|
|
// #14: ; evaluation of design authentication this design also interacts with the LCD display
|
|
// #15: ; and PC (via UART based RS232 link) to indicate authentication status and allow control
|
|
// #16: ; over the authentication validity of the design. Therefore this program includes:-
|
|
// #17: ;
|
|
// #18: ; 1) Code required to check authorisation which would be included in a production design.
|
|
// #19: ; 2) Code required to program the authentication value into FLASH memory which would
|
|
// #20: ; typically only be implemented in a special design used at a secure programming
|
|
// #21: ; facility as part of the production programming procedure.
|
|
// #22: ; 3) Code to allow you to see what is happening at all stages which is code that should
|
|
// #23: ; never be included in a real production design as it reveals secrets that should remain
|
|
// #24: ; hidden in order to make the task of breaking the security as difficult as possible.
|
|
// #25: ;
|
|
// #26: ; IMPORTANT - Feel free to use this code as a reference for your own security scheme but
|
|
// #27: ; never use this code unmodified.
|
|
// #28: ;
|
|
// #29: ;
|
|
// #30: ;**************************************************************************************
|
|
// #31: ; NOTICE:
|
|
// #32: ;
|
|
// #33: ; Copyright Xilinx, Inc. 2006. This code may be contain portions patented by other
|
|
// #34: ; third parties. By providing this core as one possible implementation of a standard,
|
|
// #35: ; Xilinx is making no representation that the provided implementation of this standard
|
|
// #36: ; is free from any claims of infringement by any third party. Xilinx expressly
|
|
// #37: ; disclaims any warranty with respect to the adequacy of the implementation, including
|
|
// #38: ; but not limited to any warranty or representation that the implementation is free
|
|
// #39: ; from claims of any third party. Furthermore, Xilinx is providing this core as a
|
|
// #40: ; courtesy to you and suggests that you contact all third parties to obtain the
|
|
// #41: ; necessary rights to use this implementation.
|
|
// #42: ;
|
|
// #43: ;
|
|
// #44: ;**************************************************************************************
|
|
// #45: ; Port definitions
|
|
// #46: ;**************************************************************************************
|
|
// #47: ;
|
|
// #48: ;
|
|
// #49: ; UART ports
|
|
// #50: ;
|
|
// #51: ; Connection to PC to allow display of progress information and to operate simple
|
|
// #52: ; menu of commands.
|
|
// #53: ;
|
|
// #54: CONSTANT(status_port,0) ;UART and memory status
|
|
// #55: CONSTANT(tx_half_full,1) ; Transmitter half full - bit0
|
|
// #56: CONSTANT(tx_full,2) ; FIFO tx_full - bit1
|
|
// #57: CONSTANT(rx_data_present,4) ; Receiver data present - bit2
|
|
// #58: CONSTANT(rx_half_full,8) ; FIFO half full - bit3
|
|
// #59: CONSTANT(rx_full,16) ; rx_full - bit4
|
|
// #60: CONSTANT(spare1,32) ; spare '0' - bit5
|
|
// #61: CONSTANT(spare2,64) ; spare '0' - bit6
|
|
// #62: CONSTANT(strataflash_sts,128) ; StrataFLASH STS - bit7
|
|
// #63: ;
|
|
// #64: CONSTANT(UART_read_port,1) ;UART Rx data input
|
|
// #65: ;
|
|
// #66: CONSTANT(UART_write_port,8) ;UART Tx data output
|
|
// #67: ;
|
|
// #68: ;
|
|
// #69: ; LCD Display
|
|
// #70: ;
|
|
// #71: ;The master enable signal is not used by the LCD display itself
|
|
// #72: ;but is used to prevent any contention with the StrataFLASH memory that
|
|
// #73: ;is connected to the same data pins. In this design the StrataFLASH memory is
|
|
// #74: ;used in 8-bit mode so not contention should exist but this master enable
|
|
// #75: ;facilty is then available for anyone wanting to modify the design for use
|
|
// #76: ;with a 16-bit interface.
|
|
// #77: ;
|
|
// #78: CONSTANT(LCD_output_port,32) ;LCD character module output data and control
|
|
// #79: CONSTANT(LCD_E,1) ; active High Enable E - bit0
|
|
// #80: CONSTANT(LCD_RW,2) ; Read=1 Write=0 RW - bit1
|
|
// #81: CONSTANT(LCD_RS,4) ; Instruction=0 Data=1 RS - bit2
|
|
// #82: CONSTANT(LCD_drive,8) ; Master enable (active High) - bit3
|
|
// #83: CONSTANT(LCD_DB4,16) ; 4-bit Data DB4 - bit4
|
|
// #84: CONSTANT(LCD_DB5,32) ; interface Data DB5 - bit5
|
|
// #85: CONSTANT(LCD_DB6,64) ; Data DB6 - bit6
|
|
// #86: CONSTANT(LCD_DB7,128) ; Data DB7 - bit7
|
|
// #87: ;
|
|
// #88: ;
|
|
// #89: CONSTANT(LCD_input_port,3) ;LCD character module input data
|
|
// #90: CONSTANT(LCD_read_spare0,1) ; Spare bits - bit0
|
|
// #91: CONSTANT(LCD_read_spare1,2) ; are zero - bit1
|
|
// #92: CONSTANT(LCD_read_spare2,4) ; - bit2
|
|
// #93: CONSTANT(LCD_read_spare3,8) ; - bit3
|
|
// #94: CONSTANT(LCD_read_DB4,16) ; 4-bit Data DB4 - bit4
|
|
// #95: CONSTANT(LCD_read_DB5,32) ; interface Data DB5 - bit5
|
|
// #96: CONSTANT(LCD_read_DB6,64) ; Data DB6 - bit6
|
|
// #97: CONSTANT(LCD_read_DB7,128) ; Data DB7 - bit7
|
|
// #98: ;
|
|
// #99: ;
|
|
// #100: ;
|
|
// #101: ; StrataFLASH memory ports
|
|
// #102: ;
|
|
// #103: ; The FLASH memory is used to hold the authentication value as well as provide the
|
|
// #104: ; unique serial number from which the authentication algorithm computes the value.
|
|
// #105: ; In practice, the FLASH will also hold the configuration image for the Spartan device.
|
|
// #106: ;
|
|
// #107: ;
|
|
// #108: CONSTANT(SF_data_in_port,2) ;Read data from StrataFLASH device
|
|
// #109: ;
|
|
// #110: CONSTANT(SF_data_out_port,128) ;Data to write into StrataFLASH device
|
|
// #111: ;
|
|
// #112: CONSTANT(SF_addr_hi_port,131) ;StrataFLASH address[21:16] (6 LSB's)
|
|
// #113: CONSTANT(SF_addr_mi_port,130) ;StrataFLASH address[15:8]
|
|
// #114: CONSTANT(SF_addr_lo_port,129) ;StrataFLASH address[7:0]
|
|
// #115: ;
|
|
// #116: CONSTANT(SF_control_port,64) ;StrataFLASH control
|
|
// #117: CONSTANT(SF_read,1) ; active High read - bit0
|
|
// #118: CONSTANT(SF_ce,2) ; active Low device enable - bit1
|
|
// #119: CONSTANT(SF_we,4) ; active Low write - bit2
|
|
// #120: ;
|
|
// #121: ;
|
|
// #122: ; Design Authentication enable/disable signals.
|
|
// #123: ;
|
|
// #124: ; Hardware controls over the 'real' application.
|
|
// #125: ;
|
|
// #126: CONSTANT(authentication_control_port,16) ;Design disable control port
|
|
// #127: CONSTANT(security_disable_interrupts,1) ; active High disable of interrupt generation - bit0
|
|
// #128: CONSTANT(security_disable_outputs,2) ; active High disable of output pins - bit1
|
|
// #129: ;
|
|
// #130: ; Pseudo Random number generator
|
|
// #131: ;
|
|
// #132: CONSTANT(random_value_port,4) ;read LFSR counter value
|
|
// #133: ;
|
|
// #134: ;
|
|
// #135: ; Link FIFO buffer
|
|
// #136: ;
|
|
// #137: ; Provides a connection to the 'real' application such that 'soft tokens' in the
|
|
// #138: ; form of short messages to be passed to the 'real' application to enable or disable
|
|
// #139: ; it depending on the authentication status.
|
|
// #140: ;
|
|
// #141: CONSTANT(link_FIFO_write_port,4) ;write data to FIFO
|
|
// #142: ;
|
|
// #143: ;
|
|
// #144: ;**************************************************************************************
|
|
// #145: ; Special Register usage
|
|
// #146: ;**************************************************************************************
|
|
// #147: ;
|
|
// #148: NAMEREG(sF,UART_data) ;used to pass data to and from the UART
|
|
// #149: ;
|
|
// #150: ;
|
|
// #151: ;
|
|
// #152: ;**************************************************************************************
|
|
// #153: ;Scratch Pad Memory Locations
|
|
// #154: ;**************************************************************************************
|
|
// #155: ;
|
|
// #156: CONSTANT(ISR_preserve_s0,0) ;preserve register contents during Interrupt Service Routine
|
|
// #157: ;
|
|
// #158: ;
|
|
// #159: CONSTANT(serial_number0,16) ;64-bit serial number of StrataFlash
|
|
// #160: CONSTANT(serial_number1,17) ;LS-Byte first
|
|
// #161: CONSTANT(serial_number2,18)
|
|
// #162: CONSTANT(serial_number3,19)
|
|
// #163: CONSTANT(serial_number4,20)
|
|
// #164: CONSTANT(serial_number5,21)
|
|
// #165: CONSTANT(serial_number6,22)
|
|
// #166: CONSTANT(serial_number7,23)
|
|
// #167: ;
|
|
// #168: ;
|
|
// #169: CONSTANT(computed_CRC0,24) ;computed 16-bit CRC based on the
|
|
// #170: CONSTANT(computed_CRC1,25) ; StrataFlash unique serial number (LS-Byte first)
|
|
// #171: ;
|
|
// #172: ;
|
|
// #173: CONSTANT(authentication_CRC0,26) ;16-bit CRC value read from authentication
|
|
// #174: CONSTANT(authentication_CRC1,27) ; area of StrataFLASH memory (LS-Byte first)
|
|
// #175: ;
|
|
// #176: ;
|
|
// #177: CONSTANT(authentication_status,28) ;Status of design authentication
|
|
// #178: ;
|
|
// #179: ;
|
|
// #180: ;**************************************************************************************
|
|
// #181: ;Useful data constants
|
|
// #182: ;**************************************************************************************
|
|
// #183: ;
|
|
// #184: ;
|
|
// #185: ;
|
|
// #186: ;Constant to define a software delay of 1us. This must be adjusted to reflect the
|
|
// #187: ;clock applied to KCPSM3. Every instruction executes in 2 clock cycles making the
|
|
// #188: ;calculation highly predictable. The '6' in the following equation even allows for
|
|
// #189: ;'CALL delay_1us' instruction in the initiating code.
|
|
// #190: ;
|
|
// #191: ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
|
|
// #192: ;
|
|
// #193: ;Example: For a 50MHz clock the constant value is (10-6)/4 = 11 (0B Hex).
|
|
// #194: ;For clock rates below 10MHz the value of 1 must be used and the operation will
|
|
// #195: ;become lower than intended.
|
|
// #196: ;
|
|
// #197: CONSTANT(delay_1us_constant,11)
|
|
// #198: ;
|
|
// #199: ;
|
|
// #200: ;
|
|
// #201: ;
|
|
// #202: ;ASCII table
|
|
// #203: ;
|
|
// #204: CONSTANT(character_a,97)
|
|
// #205: CONSTANT(character_b,98)
|
|
// #206: CONSTANT(character_c,99)
|
|
// #207: CONSTANT(character_d,100)
|
|
// #208: CONSTANT(character_e,101)
|
|
// #209: CONSTANT(character_f,102)
|
|
// #210: CONSTANT(character_g,103)
|
|
// #211: CONSTANT(character_h,104)
|
|
// #212: CONSTANT(character_i,105)
|
|
// #213: CONSTANT(character_j,106)
|
|
// #214: CONSTANT(character_k,107)
|
|
// #215: CONSTANT(character_l,108)
|
|
// #216: CONSTANT(character_m,109)
|
|
// #217: CONSTANT(character_n,110)
|
|
// #218: CONSTANT(character_o,111)
|
|
// #219: CONSTANT(character_p,112)
|
|
// #220: CONSTANT(character_q,113)
|
|
// #221: CONSTANT(character_r,114)
|
|
// #222: CONSTANT(character_s,115)
|
|
// #223: CONSTANT(character_t,116)
|
|
// #224: CONSTANT(character_u,117)
|
|
// #225: CONSTANT(character_v,118)
|
|
// #226: CONSTANT(character_w,119)
|
|
// #227: CONSTANT(character_x,120)
|
|
// #228: CONSTANT(character_y,121)
|
|
// #229: CONSTANT(character_z,122)
|
|
// #230: CONSTANT(character_A,65)
|
|
// #231: CONSTANT(character_B,66)
|
|
// #232: CONSTANT(character_C,67)
|
|
// #233: CONSTANT(character_D,68)
|
|
// #234: CONSTANT(character_E,69)
|
|
// #235: CONSTANT(character_F,70)
|
|
// #236: CONSTANT(character_G,71)
|
|
// #237: CONSTANT(character_H,72)
|
|
// #238: CONSTANT(character_I,73)
|
|
// #239: CONSTANT(character_J,74)
|
|
// #240: CONSTANT(character_K,75)
|
|
// #241: CONSTANT(character_L,76)
|
|
// #242: CONSTANT(character_M,77)
|
|
// #243: CONSTANT(character_N,78)
|
|
// #244: CONSTANT(character_O,79)
|
|
// #245: CONSTANT(character_P,80)
|
|
// #246: CONSTANT(character_Q,81)
|
|
// #247: CONSTANT(character_R,82)
|
|
// #248: CONSTANT(character_S,83)
|
|
// #249: CONSTANT(character_T,84)
|
|
// #250: CONSTANT(character_U,85)
|
|
// #251: CONSTANT(character_V,86)
|
|
// #252: CONSTANT(character_W,87)
|
|
// #253: CONSTANT(character_X,88)
|
|
// #254: CONSTANT(character_Y,89)
|
|
// #255: CONSTANT(character_Z,90)
|
|
// #256: CONSTANT(character_0,48)
|
|
// #257: CONSTANT(character_1,49)
|
|
// #258: CONSTANT(character_2,50)
|
|
// #259: CONSTANT(character_3,51)
|
|
// #260: CONSTANT(character_4,52)
|
|
// #261: CONSTANT(character_5,53)
|
|
// #262: CONSTANT(character_6,54)
|
|
// #263: CONSTANT(character_7,55)
|
|
// #264: CONSTANT(character_8,56)
|
|
// #265: CONSTANT(character_9,57)
|
|
// #266: CONSTANT(character_colon,58)
|
|
// #267: CONSTANT(character_fullstop,46)
|
|
// #268: CONSTANT(character_semi_colon,59)
|
|
// #269: CONSTANT(character_minus,45)
|
|
// #270: CONSTANT(character_divide,47) ;'/'
|
|
// #271: CONSTANT(character_plus,43)
|
|
// #272: CONSTANT(character_comma,44)
|
|
// #273: CONSTANT(character_less_than,60)
|
|
// #274: CONSTANT(character_greater_than,62)
|
|
// #275: CONSTANT(character_equals,61)
|
|
// #276: CONSTANT(character_space,32)
|
|
// #277: CONSTANT(character_CR,13) ;carriage return
|
|
// #278: CONSTANT(character_question,63) ;'?'
|
|
// #279: CONSTANT(character_dollar,36)
|
|
// #280: CONSTANT(character_exclaim,33) ;'!'
|
|
// #281: CONSTANT(character_BS,8) ;Back Space command character
|
|
// #282: ;
|
|
// #283: ;
|
|
// #284: ;
|
|
// #285: ;
|
|
// #286: ;
|
|
// #287: ;**************************************************************************************
|
|
// #288: ;Initialise the system
|
|
// #289: ;**************************************************************************************
|
|
// #290: ;
|
|
// @000 #291: [cold_start]
|
|
300e1 // @000 #291: CALL(SF_init) ;initialise StrataFLASH controls
|
|
00000 // @001 #292: LOAD(s0,0) ;Start with application enabled in hardware
|
|
2c010 // @002 #293: OUTPUT(s0,authentication_control_port)
|
|
00050 // @003 #294: LOAD(s0,character_P) ;start with design enabled by software (see ISR)
|
|
2e01c // @004 #295: STORE(s0,authentication_status)
|
|
3035b // @005 #296: CALL(delay_1s) ;delay to allow system to settle
|
|
30328 // @006 #297: CALL(LCD_reset) ;Initialise the LCD
|
|
// #298: ;
|
|
3c001 // @007 #299: ENABLE(INTERRUPT) ;interrupts to provide software enable to application
|
|
// #300: ;
|
|
// #301: ;**************************************************************************************
|
|
// #302: ; Main program
|
|
// #303: ;**************************************************************************************
|
|
// #304: ;
|
|
// #305: ; The main program follows a logical sequence of events describing the power on and
|
|
// #306: ; authentication process of a design. This process will is either successfully authorises
|
|
// #307: ; the 'real' application to operate or fail to authenticate and disable the 'real'
|
|
// #308: ; application in a similar way to a production design. The only difference that it keeps
|
|
// #309: ; you informed about what it is doing on both the LCD display and PC terminal via the UART.
|
|
// #310: ; A real production design should keep all details hidden.
|
|
// #311: ;
|
|
// #312: ; Following the authentication check and control over the 'real' application a simple menu
|
|
// #313: ; is provided on the PC terminal to allow you to read, write and erase the authentication
|
|
// #314: ; area of the StrataFLASH memory and therefore evaluate the design authentication security
|
|
// #315: ; of this reference design.
|
|
// #316: ;
|
|
// #317: ;
|
|
// #318: ;
|
|
// #319: ; Write welcome message to LCD display
|
|
// #320: ;
|
|
// @008 #321: [warm_start]
|
|
00512 // @008 #321: LOAD(s5,18) ;Line 1 position 2
|
|
3033e // @009 #322: CALL(LCD_cursor)
|
|
30364 // @00a #323: CALL(disp_PicoBlaze) ;Display 'PicoBlaze'
|
|
00525 // @00b #324: LOAD(s5,37) ;Line 2 position 5
|
|
3033e // @00c #325: CALL(LCD_cursor)
|
|
30377 // @00d #326: CALL(disp_Security) ;Display 'Security'
|
|
// #327: ;
|
|
// #328: ; Write welcome message to PC via UART
|
|
// #329: ;
|
|
30164 // @00e #330: CALL(send_welcome)
|
|
// #331: ;
|
|
// #332: ;
|
|
// #333: ; Display 'Copyright Ken Chapman 2006' via the UART.
|
|
// #334: ;
|
|
// #335: ; This message is significant because it demonstrates that the design now has a 'watermark'.
|
|
// #336: ; The ASCII codes for this string are part of the PicoBlaze program stored in a Block
|
|
// #337: ; Memory and therefore are also part of the configuration bit stream. If someone tries to
|
|
// #338: ; change or delete this copyright message the hardware design will detect the change to the
|
|
// #339: ; Block memory contents and also inhibit the design.
|
|
// #340: ;
|
|
301b4 // @00f #341: CALL(send_Copyright)
|
|
// #342: ;
|
|
// #343: ;
|
|
// #344: ;
|
|
// #345: ; Delay of 10 seconds before performing any security checks.
|
|
// #346: ;
|
|
// #347: ; This allows the design to work for a short time which could be important for
|
|
// #348: ; production testing.
|
|
// #349: ;
|
|
// #350: ; Having a significant time delay (days or weeks) before security checks means that someone
|
|
// #351: ; attempting to clone the product may not be aware that there is any form of design security
|
|
// #352: ; at all until products are in the field are failing. A time delay also impedes the ability to
|
|
// #353: ; attempt to break the security and confirm if an attempt is or is not successful.
|
|
// #354: ;
|
|
0050a // @010 #355: LOAD(s5,10) ;delay of 10 seconds.
|
|
30360 // @011 #356: CALL(delay_Ns)
|
|
// #357: ;
|
|
// #358: ;
|
|
// #359: ;
|
|
// #360: ; Read serial number of the StrataFLASH memory.
|
|
// #361: ; The whole principle of low cost design security is based on this unique number. Clearly this
|
|
// #362: ; number is not a secret, but what we then go on to do with it should normally be kept secret.
|
|
// #363: ;
|
|
300f2 // @012 #364: CALL(read_SF_serial_number) ;read serial number from FLASH memory
|
|
30065 // @013 #365: CALL(send_serial_number) ;send value to UART for display on PC
|
|
30070 // @014 #366: CALL(disp_serial_number) ;display serial number on LCD display.
|
|
30154 // @015 #367: CALL(send_CR)
|
|
// #368: ;
|
|
// #369: ;
|
|
// #370: ;
|
|
0050a // @016 #371: LOAD(s5,10) ;delay of 10 seconds to read messages.
|
|
30360 // @017 #372: CALL(delay_Ns)
|
|
// #373: ;
|
|
// #374: ;
|
|
// #375: ;
|
|
// #376: ; Compute the 16-bit CRC for the serial number as an authentication value for the design.
|
|
// #377: ; The CRC value is formed in register pair [sE,sD]. To complicate the authentication value
|
|
// #378: ; the initial contents of the registers are seeded with a 'secret' number.
|
|
// #379: ; Hint 1 - The CRC computation could be implemented in hardware where it is less visible.
|
|
// #380: ; Hint 2 - There are more secure algorithms such as SHA-1 which could be used to generate
|
|
// #381: ; authentication values that are extremely difficult to decode.
|
|
// #382: ;
|
|
// #383: ;
|
|
00e15 // @018 #384: LOAD(sE,21) ;seed CRC register with an initial value provided by my daughter when asked :-)
|
|
00d8e // @019 #385: LOAD(sD,142)
|
|
3007f // @01a #386: CALL(compute_seeded_CRC) ;compute CRC for serial number and configuration memory
|
|
// #387: ;
|
|
// #388: ; Store CRC value in scratch pad memory and display computed CRC value on the PC via UART.
|
|
// #389: ;
|
|
2ed18 // @01b #390: STORE(sD,computed_CRC0) ;store CRC value
|
|
2ee19 // @01c #391: STORE(sE,computed_CRC1)
|
|
30252 // @01d #392: CALL(send_Computed_CRC) ;display computed CRC value on PC via UART
|
|
010e0 // @01e #393: LOAD(s0,sE)
|
|
30140 // @01f #394: CALL(send_hex_byte)
|
|
010d0 // @020 #395: LOAD(s0,sD)
|
|
30140 // @021 #396: CALL(send_hex_byte)
|
|
30154 // @022 #397: CALL(send_CR)
|
|
// #398: ;
|
|
// #399: ;
|
|
// #400: ;
|
|
// #401: ; Read the authenticated CRC value stored in StrataFLASH memory.
|
|
// #402: ; 16-bit value is hidden in 256 bytes of random numbers to make it more difficult
|
|
// #403: ; for an attacker to identify.
|
|
// #404: ; Read value is stored in scratch pad memory and displayed on the PC via UART.
|
|
// #405: ;
|
|
30094 // @023 #406: CALL(read_authentication) ;read StrataFLASH memory into [sB,sA]
|
|
2ea1a // @024 #407: STORE(sA,authentication_CRC0) ;store CRC value
|
|
2eb1b // @025 #408: STORE(sB,authentication_CRC1)
|
|
30248 // @026 #409: CALL(send_FLASH_CRC) ;display CRC value from FLASH on PC via UART
|
|
010b0 // @027 #410: LOAD(s0,sB)
|
|
30140 // @028 #411: CALL(send_hex_byte)
|
|
010a0 // @029 #412: LOAD(s0,sA)
|
|
30140 // @02a #413: CALL(send_hex_byte)
|
|
30154 // @02b #414: CALL(send_CR)
|
|
// #415: ;
|
|
// #416: ;
|
|
// #417: ; Compare the computed CRC value with the authentication value stored in StrataFLASH
|
|
// #418: ; and determine if the design is authenticated. Then decide course of action.
|
|
// #419: ;
|
|
30339 // @02c #420: CALL(LCD_clear) ;clear LCD display
|
|
303a9 // @02d #421: CALL(disp_Authentication) ;prepare LCD display for result of authentication
|
|
30232 // @02e #422: CALL(send_Authentication) ;prepare PC display for result of authentication
|
|
// #423: ;
|
|
15ad0 // @02f #424: COMPARE(sA,sD) ;Perform comparison of CRC values
|
|
35436 // @030 #425: JUMP(NZ,auth_failure)
|
|
15be0 // @031 #426: COMPARE(sB,sE)
|
|
35436 // @032 #427: JUMP(NZ,auth_failure)
|
|
// #428: ;
|
|
// #429: ;
|
|
// #430: ; Authentication Successful Process
|
|
// #431: ;
|
|
// #432: ; In this mode the design continues to operate and for evaluation
|
|
// #433: ; purposes this design transfers control to the simple menu immediately.
|
|
// #434: ;
|
|
// @033 #435: [auth_passed]
|
|
303c8 // @033 #435: CALL(disp_Passed) ;display successful authentication on LCD display
|
|
3029d // @034 #436: CALL(send_PASSED) ;display successful authentication on PC via UART
|
|
3403c // @035 #437: JUMP(Menu)
|
|
// #438: ;
|
|
// #439: ; Authentication Failure Process
|
|
// #440: ;
|
|
// #441: ; When the authentication fails two hardware based disable methods are demonstrated. Then
|
|
// #442: ; the failed status is remembered for future software token messages to demonstrate software
|
|
// #443: ; based disabling of the 'real' application. Finally the simple menu of options is presented
|
|
// #444: ; to allow evaluation to continue.
|
|
// #445: ;
|
|
// #446: ;
|
|
// @036 #447: [auth_failure]
|
|
303d6 // @036 #447: CALL(disp_Failed) ;display failure to authenticate on LCD display
|
|
3028f // @037 #448: CALL(send_FAILED) ;display failure to authenticate on PC via UART
|
|
30154 // @038 #449: CALL(send_CR)
|
|
30056 // @039 #450: CALL(disable_app_hardware) ;sequence hardware disable signals
|
|
00046 // @03a #451: LOAD(s0,character_F) ;change authentication status to 'F' for failed.
|
|
2e01c // @03b #452: STORE(s0,authentication_status) ; so that application software disable is demonstrated
|
|
// #453: ;
|
|
// #454: ;
|
|
// #455: ;
|
|
// #456: ; Menu of options for authentication processing
|
|
// #457: ;
|
|
// @03c #458: [Menu]
|
|
302bc // @03c #458: CALL(send_Menu) ;display menu and prompt
|
|
3011d // @03d #459: CALL(read_from_UART) ;read character from PC
|
|
30129 // @03e #460: CALL(upper_case) ;convert to upper case
|
|
14f52 // @03f #461: COMPARE(UART_data,character_R)
|
|
35046 // @040 #462: JUMP(Z,read_command)
|
|
14f45 // @041 #463: COMPARE(UART_data,character_E)
|
|
3504b // @042 #464: JUMP(Z,erase_command)
|
|
14f41 // @043 #465: COMPARE(UART_data,character_A)
|
|
3504f // @044 #466: JUMP(Z,authorise_command)
|
|
3403c // @045 #467: JUMP(Menu) ;repeat menu for invalid selection
|
|
// #468: ;
|
|
// #469: ;
|
|
// #470: ;
|
|
// @046 #471: [read_command]
|
|
30154 // @046 #471: CALL(send_CR)
|
|
300ae // @047 #472: CALL(send_auth_page)
|
|
30154 // @048 #473: CALL(send_CR)
|
|
30154 // @049 #474: CALL(send_CR)
|
|
3403c // @04a #475: JUMP(Menu)
|
|
// #476: ;
|
|
// #477: ;
|
|
// #478: ;
|
|
// @04b #479: [erase_command]
|
|
3026f // @04b #479: CALL(send_Erase_in_progress)
|
|
300de // @04c #480: CALL(erase_authentication)
|
|
30289 // @04d #481: CALL(send_OK)
|
|
3403c // @04e #482: JUMP(Menu)
|
|
// #483: ;
|
|
// #484: ;
|
|
// #485: ;
|
|
// @04f #486: [authorise_command]
|
|
302aa // @04f #486: CALL(send_Writing) ;Send 'Writing Authorisation' message
|
|
30154 // @050 #487: CALL(send_CR)
|
|
06d18 // @051 #488: FETCH(sD,computed_CRC0) ;fetch computed CRC value
|
|
06e19 // @052 #489: FETCH(sE,computed_CRC1)
|
|
300be // @053 #490: CALL(write_authentication) ;write computed CRC to FLASH with random data
|
|
30289 // @054 #491: CALL(send_OK)
|
|
3403c // @055 #492: JUMP(Menu)
|
|
// #493: ;
|
|
// #494: ;
|
|
// #495: ;**************************************************************************************
|
|
// #496: ; Drive failure signals to the application.
|
|
// #497: ;**************************************************************************************
|
|
// #498: ;
|
|
// #499: ; When the design fails to authorise, these controls cause the application to behave in
|
|
// #500: ; a strange way!
|
|
// #501: ;
|
|
// #502: ;
|
|
// #503: ; Disable interrupts to application PicoBlaze to stop PWM generation completely for 5 seconds
|
|
// #504: ;
|
|
// @056 #505: [disable_app_hardware]
|
|
00001 // @056 #505: LOAD(s0,security_disable_interrupts)
|
|
2c010 // @057 #506: OUTPUT(s0,authentication_control_port)
|
|
00505 // @058 #507: LOAD(s5,5)
|
|
30360 // @059 #508: CALL(delay_Ns)
|
|
// #509: ;
|
|
// #510: ; Enable application for 5 seconds
|
|
// #511: ;
|
|
00000 // @05a #512: LOAD(s0,0)
|
|
2c010 // @05b #513: OUTPUT(s0,authentication_control_port)
|
|
00505 // @05c #514: LOAD(s5,5)
|
|
30360 // @05d #515: CALL(delay_Ns)
|
|
// #516: ;
|
|
// #517: ; Disable and/or scramble outputs connected to application PicoBlaze for 5 seconds
|
|
// #518: ;
|
|
00002 // @05e #519: LOAD(s0,security_disable_outputs)
|
|
2c010 // @05f #520: OUTPUT(s0,authentication_control_port)
|
|
00505 // @060 #521: LOAD(s5,5)
|
|
30360 // @061 #522: CALL(delay_Ns)
|
|
// #523: ;
|
|
// #524: ;
|
|
// #525: ; Enable application in hardware so that software disable function can then be
|
|
// #526: ; demonstrated until the design is reconfigured and authentication test repeated.
|
|
// #527: ;
|
|
00000 // @062 #528: LOAD(s0,0)
|
|
2c010 // @063 #529: OUTPUT(s0,authentication_control_port)
|
|
2a000 // @064 #530: RETURN
|
|
// #531: ;
|
|
// #532: ;
|
|
// #533: ;
|
|
// #534: ;**************************************************************************************
|
|
// #535: ; Send the 64-bit serial number stored in scratch pad memory to the UART
|
|
// #536: ;**************************************************************************************
|
|
// #537: ;
|
|
// #538: ; The serial number should previously have been copied into the 8 ascending scratch pad
|
|
// #539: ; memory locations called 'serial_number0' through to 'serial_number7'.
|
|
// #540: ;
|
|
// #541: ; The serial number is displayed MS-Byte first.
|
|
// #542: ;
|
|
// #543: ; Registers used s0,s1,s2,s3
|
|
// #544: ;
|
|
// @065 #545: [send_serial_number]
|
|
301f2 // @065 #545: CALL(send_FLASH_Serial_Number) ;display text message
|
|
00317 // @066 #546: LOAD(s3,serial_number7) ;pointer to scratch pad memory
|
|
// @067 #547: [send_SN_loop]
|
|
07030 // @067 #547: FETCH(s0,s3) ;read serial number byte
|
|
30140 // @068 #548: CALL(send_hex_byte) ;display byte
|
|
30157 // @069 #549: CALL(send_space) ;display byte
|
|
14310 // @06a #550: COMPARE(s3,serial_number0) ;check for 8 bytes sent to UART
|
|
3506e // @06b #551: JUMP(Z,end_send_SN)
|
|
1c301 // @06c #552: SUB(s3,1) ;increment memory pointer
|
|
34067 // @06d #553: JUMP(send_SN_loop)
|
|
// #554: ;
|
|
// @06e #555: [end_send_SN]
|
|
30154 // @06e #555: CALL(send_CR)
|
|
2a000 // @06f #556: RETURN
|
|
// #557: ;
|
|
// #558: ;
|
|
// #559: ;
|
|
// #560: ;**************************************************************************************
|
|
// #561: ; Display the 64-bit serial number stored in scratch pad memory on the LCD display
|
|
// #562: ;**************************************************************************************
|
|
// #563: ;
|
|
// #564: ; The serial number should previously have been copied into the 8 ascending scratch pad
|
|
// #565: ; memory locations called 'serial_number0' through to 'serial_number7'.
|
|
// #566: ;
|
|
// #567: ; The serial number is displayed MS-Byte first.
|
|
// #568: ;
|
|
// #569: ; Registers used s0,s1,s2,s3,s4,s5,s6
|
|
// #570: ;
|
|
// @070 #571: [disp_serial_number]
|
|
30339 // @070 #571: CALL(LCD_clear) ;clear LCD display
|
|
00510 // @071 #572: LOAD(s5,16) ;Line 1 position 0
|
|
3033e // @072 #573: CALL(LCD_cursor)
|
|
30388 // @073 #574: CALL(disp_FLASH_Serial_No) ;display text message
|
|
00520 // @074 #575: LOAD(s5,32) ;Line 2 position 0
|
|
3033e // @075 #576: CALL(LCD_cursor)
|
|
00617 // @076 #577: LOAD(s6,serial_number7) ;pointer to scratch pad memory
|
|
// @077 #578: [disp_SN_loop]
|
|
07060 // @077 #578: FETCH(s0,s6) ;read serial number byte
|
|
3014d // @078 #579: CALL(disp_hex_byte) ;display byte
|
|
14610 // @079 #580: COMPARE(s6,serial_number0) ;check for 8 bytes sent to UART
|
|
3507d // @07a #581: JUMP(Z,end_disp_SN)
|
|
1c601 // @07b #582: SUB(s6,1) ;increment memory pointer
|
|
34077 // @07c #583: JUMP(disp_SN_loop)
|
|
// #584: ;
|
|
// @07d #585: [end_disp_SN]
|
|
30154 // @07d #585: CALL(send_CR)
|
|
2a000 // @07e #586: RETURN
|
|
// #587: ;
|
|
// #588: ;
|
|
// #589: ;**************************************************************************************
|
|
// #590: ; Compute a 16-bit CRC value for the StrataFLASH 64-bit serial number.
|
|
// #591: ;**************************************************************************************
|
|
// #592: ;
|
|
// #593: ; This routing performs a 16-bit CRC calculation for the 64-bit unique serial number
|
|
// #594: ; of the StrataFLASH memory which forms the authentication value for the design.
|
|
// #595: ;
|
|
// #596: ; The 16-bit CRC value returned in register pair [sE,sD] will be reflective of the unique
|
|
// #597: ; serial number. This will be used as the authentication value for the design which is
|
|
// #598: ; stored at known locations in the FLASH memory.
|
|
// #599: ;
|
|
// #600: ; A direct copy of the FLASH contents will not authorise a design to operate because the
|
|
// #601: ; authentication value will not match the CRC value generated from the different serial number.
|
|
// #602: ;
|
|
// #603: ; To complicate the CRC value generation the CRC register can be seeded with a value rather
|
|
// #604: ; than starting with a clear register.
|
|
// #605: ;
|
|
// #606: ;
|
|
// #607: ; Registers used s0,s1,s2,s3
|
|
// #608: ;
|
|
// @07f #609: [compute_seeded_CRC]
|
|
00410 // @07f #609: LOAD(s4,serial_number0) ;pointer to scratch pad memory holding serial number
|
|
// @080 #610: [CRC_send_loop]
|
|
07340 // @080 #610: FETCH(s3,s4) ;read serial number byte
|
|
30086 // @081 #611: CALL(compute_CRC16) ;compute CRC for value in 's3'
|
|
14417 // @082 #612: COMPARE(s4,serial_number7) ;check for 8 bytes processed
|
|
2b000 // @083 #613: RETURN(Z)
|
|
18401 // @084 #614: ADD(s4,1) ;increment memory pointer
|
|
34080 // @085 #615: JUMP(CRC_send_loop)
|
|
// #616: ;
|
|
// #617: ;
|
|
// #618: ;**************************************************************************************
|
|
// #619: ; Compute 16-bit CRC using the polynomial X16 + X15 + X2 + 1.
|
|
// #620: ;**************************************************************************************
|
|
// #621: ;
|
|
// #622: ;
|
|
// #623: ; This routine computes a 16-bit CRC in the register pair [sE,sD] and these
|
|
// #624: ; registers must not be disturbed between calls of this routine.
|
|
// #625: ;
|
|
// #626: ; This routine has been written such that the CRC can be computed one
|
|
// #627: ; byte at a time. The byte to be processed should be provided in register 's3'
|
|
// #628: ; and the contents of this register are preserved.
|
|
// #629: ;
|
|
// #630: ; Before starting a CRC computation either clear or pre-load (seed) the register pair
|
|
// #631: ; [sE,sD] and do not disturb the value of the register pair between calling this routine.
|
|
// #632: ;
|
|
// #633: ; Registers used s0,s1,s3,sD,sE
|
|
// #634: ; s3 is preserved.
|
|
// #635: ; sD and sE should not be disturbed between calls if CRC value is required.
|
|
// #636: ;
|
|
// #637: ;
|
|
// #638: ;
|
|
// @086 #639: [compute_CRC16]
|
|
00108 // @086 #639: LOAD(s1,8) ;8-bits to shift
|
|
// @087 #640: [crc16_loop]
|
|
010d0 // @087 #640: LOAD(s0,sD) ;copy current CRC value
|
|
0f030 // @088 #641: XOR(s0,s3) ;Need to know LSB XOR next input bit
|
|
12001 // @089 #642: TEST(s0,1) ;test result of XOR in LSB
|
|
35c8d // @08a #643: JUMP(NC,crc16_shift)
|
|
0ed02 // @08b #644: XOR(sD,2) ;compliment bit 1 of CRC
|
|
0ee40 // @08c #645: XOR(sE,64) ;compliment bit 14 of CRC
|
|
// @08d #646: [crc16_shift]
|
|
2000e // @08d #646: SR0(s0) ;Carry gets LSB XOR next input bit
|
|
20e08 // @08e #647: SRA(sE) ;shift Carry into MSB to form new CRC value
|
|
20d08 // @08f #648: SRA(sD)
|
|
2030c // @090 #649: RR(s3) ;shift input value
|
|
1c101 // @091 #650: SUB(s1,1) ;count bits
|
|
35487 // @092 #651: JUMP(NZ,crc16_loop) ;next bit
|
|
2a000 // @093 #652: RETURN
|
|
// #653: ;
|
|
// #654: ;
|
|
// #655: ;**************************************************************************************
|
|
// #656: ; Read 256 bytes of StrataFLASH memory including the authentication value.
|
|
// #657: ;**************************************************************************************
|
|
// #658: ;
|
|
// #659: ; This routine reads the authentication value from the StrataFLASH memory. In this
|
|
// #660: ; design the authentication value is only 2 bytes which once read will be returned
|
|
// #661: ; in the register pair [sB,sA].
|
|
// #662: ;
|
|
// #663: ; To make the authentication value more difficult to identify, it is hidden in 256 bytes
|
|
// #664: ; of pseudo random values which will also appear different in each FLASH device inspected.
|
|
// #665: ; This routine deliberately reads all 256 bytes that are stored and abstracts the required
|
|
// #666: ; 2 bytes of information from them otherwise it would be easy to observe which addresses
|
|
// #667: ; of the block were being accessed.
|
|
// #668: ;
|
|
// #669: ; Another way that an attacker may deduce which address locations are important would be to
|
|
// #670: ; observe the time between read accesses and note when there is any difference. In this case
|
|
// #671: ; the attacker is attempting to detect when PicoBlaze takes slightly longer to execute the
|
|
// #672: ; instructions which store the important bytes in scratch pad memory. So to avoid this
|
|
// #673: ; detection this routine inserts an additional random delay between reads to mask any code
|
|
// #674: ; execution differences.
|
|
// #675: ;
|
|
// #676: ; The 256 bytes are stored at addresses 060000 to 0600FF hex (the first block above the
|
|
// #677: ; XC3S500E configuration image which occupies 000000 to 04547F hex). The 2 bytes forming the
|
|
// #678: ; actual authentication value are stored as 4-bit nibbles in 4 different locations in this range.
|
|
// #679: ;
|
|
// #680: ;
|
|
// #681: ; High Order Nibble Low Order Nibble
|
|
// #682: ; (NNNNxxxx) (xxxxNNNN)
|
|
// #683: ;
|
|
// #684: ; LS-Byte in 'sA' Addr=060010 Addr=06007F
|
|
// #685: ; MS-Byte in 'sB' Addr=060025 Addr=0600FA
|
|
// #686: ;
|
|
// #687: ;
|
|
// @094 #688: [read_authentication]
|
|
00906 // @094 #688: LOAD(s9,6) ;start address in FLASH
|
|
00800 // @095 #689: LOAD(s8,0)
|
|
00700 // @096 #690: LOAD(s7,0)
|
|
// @097 #691: [auth_read_loop]
|
|
30101 // @097 #691: CALL(SF_byte_read) ;read byte from FLASH into s0
|
|
14710 // @098 #692: COMPARE(s7,16) ;check for bytes/nibbles that contain real information
|
|
3549c // @099 #693: JUMP(NZ,auth_check2)
|
|
01a00 // @09a #694: LOAD(sA,s0) ;isolate upper order nibble for LS-Byte
|
|
0aaf0 // @09b #695: AND(sA,F0)
|
|
// @09c #696: [auth_check2]
|
|
14725 // @09c #696: COMPARE(s7,37)
|
|
354a0 // @09d #697: JUMP(NZ,auth_check3)
|
|
01b00 // @09e #698: LOAD(sB,s0) ;isolate upper order nibble for MS-Byte
|
|
0abf0 // @09f #699: AND(sB,F0)
|
|
// @0a0 #700: [auth_check3]
|
|
1477f // @0a0 #700: COMPARE(s7,127)
|
|
354a4 // @0a1 #701: JUMP(NZ,auth_check4)
|
|
0a00f // @0a2 #702: AND(s0,15) ;isolate lower order nibble for LS-Byte
|
|
0da00 // @0a3 #703: OR(sA,s0) ; and merge with upper order nibble
|
|
// @0a4 #704: [auth_check4]
|
|
147fa // @0a4 #704: COMPARE(s7,FA)
|
|
354a8 // @0a5 #705: JUMP(NZ,next_auth_read)
|
|
0a00f // @0a6 #706: AND(s0,15) ;isolate lower order nibble for MS-Byte
|
|
0db00 // @0a7 #707: OR(sB,s0) ; and merge with upper order nibble
|
|
// @0a8 #708: [next_auth_read]
|
|
18701 // @0a8 #708: ADD(s7,1) ;increment address
|
|
2b000 // @0a9 #709: RETURN(Z) ;complete after 256 reads
|
|
04004 // @0aa #710: INPUT(s0,random_value_port) ;random delay between reads
|
|
// @0ab #711: [auth_read_delay]
|
|
1c001 // @0ab #711: SUB(s0,1)
|
|
354ab // @0ac #712: JUMP(NZ,auth_read_delay)
|
|
34097 // @0ad #713: JUMP(auth_read_loop)
|
|
// #714: ;
|
|
// #715: ;
|
|
// #716: ;**************************************************************************************
|
|
// #717: ; Read 256 bytes (page) of StrataFLASH memory containing the authentication value.
|
|
// #718: ;**************************************************************************************
|
|
// #719: ;
|
|
// #720: ; This routine reads the StrataFLASH memory and displays the contents on the PC display
|
|
// #721: ; via the UART. The display will be 256 bytes from address range 060000 to 0600FF displayed
|
|
// #722: ; as 16 lines of 16 bytes with each line commencing with the address of the first byte.
|
|
// #723: ;
|
|
// @0ae #724: [send_auth_page]
|
|
00906 // @0ae #724: LOAD(s9,6) ;start address in FLASH
|
|
00800 // @0af #725: LOAD(s8,0)
|
|
00700 // @0b0 #726: LOAD(s7,0)
|
|
// @0b1 #727: [auth_line_loop]
|
|
30154 // @0b1 #727: CALL(send_CR)
|
|
30146 // @0b2 #728: CALL(send_hex_3bytes) ;display address
|
|
30157 // @0b3 #729: CALL(send_space)
|
|
// @0b4 #730: [auth_byte_loop]
|
|
30157 // @0b4 #730: CALL(send_space)
|
|
30101 // @0b5 #731: CALL(SF_byte_read) ;read byte into s0
|
|
30140 // @0b6 #732: CALL(send_hex_byte) ;display byte
|
|
18701 // @0b7 #733: ADD(s7,1) ;increment FLASH address
|
|
1270f // @0b8 #734: TEST(s7,15) ;test for 16 byte boundary
|
|
354b4 // @0b9 #735: JUMP(NZ,auth_byte_loop)
|
|
127ff // @0ba #736: TEST(s7,FF) ;test for roll over of 256 bytes
|
|
354b1 // @0bb #737: JUMP(NZ,auth_line_loop)
|
|
30154 // @0bc #738: CALL(send_CR)
|
|
2a000 // @0bd #739: RETURN
|
|
// #740: ;
|
|
// #741: ;
|
|
// #742: ;
|
|
// #743: ;
|
|
// #744: ;**************************************************************************************
|
|
// #745: ; Write 256 bytes of StrataFLASH memory including the authentication value.
|
|
// #746: ;**************************************************************************************
|
|
// #747: ;
|
|
// #748: ; This routine writes the authentication value to the StrataFLASH memory. This routine
|
|
// #749: ; would normally be part of a production programming mechanism and not part of the
|
|
// #750: ; final design which only reads and confirms authentication. This routine does not
|
|
// #751: ; require and special measures to confuse an attacker if it is only used in a secure
|
|
// #752: ; production environment.
|
|
// #753: ;
|
|
// #754: ; The 2 bytes forming the actual authentication value are stored as 4-bit nibbles in
|
|
// #755: ; 4 different locations in the address range 600000 to 6000FF hex (256 bytes) with
|
|
// #756: ; all remaining locations filled with pseudo random values.
|
|
// #757: ;
|
|
// #758: ; The authentication value to be stored in StrataFLASH memory should be provided in
|
|
// #759: ; the register pair [sE,sD] and will be stored in the following locations.
|
|
// #760: ;
|
|
// #761: ; High Order Nibble Low Order Nibble
|
|
// #762: ; (NNNNxxxx) (xxxxNNNN)
|
|
// #763: ;
|
|
// #764: ; LS-Byte in 'sD' Addr=060010 Addr=06007F
|
|
// #765: ; MS-Byte in 'sE' Addr=060025 Addr=0600FA
|
|
// #766: ;
|
|
// #767: ;
|
|
// @0be #768: [write_authentication]
|
|
00906 // @0be #768: LOAD(s9,6) ;start address in FLASH
|
|
00800 // @0bf #769: LOAD(s8,0)
|
|
00700 // @0c0 #770: LOAD(s7,0)
|
|
// @0c1 #771: [auth_write_loop]
|
|
04004 // @0c1 #771: INPUT(s0,random_value_port) ;Obtain random value
|
|
14710 // @0c2 #772: COMPARE(s7,16) ;check for bytes/nibbles that need to be real information
|
|
354c8 // @0c3 #773: JUMP(NZ,auth_write_check2)
|
|
011d0 // @0c4 #774: LOAD(s1,sD) ;merge upper order nibble for LS-Byte with random
|
|
0a1f0 // @0c5 #775: AND(s1,F0)
|
|
0a00f // @0c6 #776: AND(s0,15)
|
|
0d010 // @0c7 #777: OR(s0,s1)
|
|
// @0c8 #778: [auth_write_check2]
|
|
14725 // @0c8 #778: COMPARE(s7,37)
|
|
354ce // @0c9 #779: JUMP(NZ,auth_write_check3)
|
|
011e0 // @0ca #780: LOAD(s1,sE) ;merge upper order nibble for MS-Byte with random
|
|
0a1f0 // @0cb #781: AND(s1,F0)
|
|
0a00f // @0cc #782: AND(s0,15)
|
|
0d010 // @0cd #783: OR(s0,s1)
|
|
// @0ce #784: [auth_write_check3]
|
|
1477f // @0ce #784: COMPARE(s7,127)
|
|
354d4 // @0cf #785: JUMP(NZ,auth_write_check4)
|
|
011d0 // @0d0 #786: LOAD(s1,sD) ;merge lower order nibble for LS-Byte with random
|
|
0a10f // @0d1 #787: AND(s1,15)
|
|
0a0f0 // @0d2 #788: AND(s0,F0)
|
|
0d010 // @0d3 #789: OR(s0,s1)
|
|
// @0d4 #790: [auth_write_check4]
|
|
147fa // @0d4 #790: COMPARE(s7,FA)
|
|
354da // @0d5 #791: JUMP(NZ,write_auth)
|
|
011e0 // @0d6 #792: LOAD(s1,sE) ;merge lower order nibble for MS-Byte with random
|
|
0a10f // @0d7 #793: AND(s1,15)
|
|
0a0f0 // @0d8 #794: AND(s0,F0)
|
|
0d010 // @0d9 #795: OR(s0,s1)
|
|
// @0da #796: [write_auth]
|
|
300ec // @0da #796: CALL(SF_single_byte_write) ;write byte to FLASH
|
|
18701 // @0db #797: ADD(s7,1) ;increment address
|
|
2b000 // @0dc #798: RETURN(Z) ;complete after 256 writes
|
|
340c1 // @0dd #799: JUMP(auth_write_loop)
|
|
// #800: ;
|
|
// #801: ;
|
|
// #802: ;**************************************************************************************
|
|
// #803: ; Erase authentication value from StrataFLASH memory.
|
|
// #804: ;**************************************************************************************
|
|
// #805: ;
|
|
// #806: ; Erase block 3 of the StrataFLASH memory which covers the address range 060000 to 07FFFF.
|
|
// #807: ; This erases the area containing the authentication value and random values which helps
|
|
// #808: ; to hide it.
|
|
// #809: ;
|
|
// @0de #810: [erase_authentication]
|
|
00906 // @0de #810: LOAD(s9,6) ;set address to 06xxxx hex which defines block 3 (060000 to 07FFFF)
|
|
300e4 // @0df #811: CALL(SF_erase_block)
|
|
2a000 // @0e0 #812: RETURN
|
|
// #813: ;
|
|
// #814: ;
|
|
// #815: ;**************************************************************************************
|
|
// #816: ; Initialise the StrataFlash Memory control signals.
|
|
// #817: ;**************************************************************************************
|
|
// #818: ;
|
|
// #819: ; SF_read = 0 - Output enable off
|
|
// #820: ; SF_ce = 1 - Deselect StrataFLASH memory
|
|
// #821: ; SF_we = 1 - Write enable off
|
|
// #822: ;
|
|
// #823: ; Register used s0
|
|
// #824: ;
|
|
// @0e1 #825: [SF_init]
|
|
00006 // @0e1 #825: LOAD(s0,6)
|
|
2c040 // @0e2 #826: OUTPUT(s0,SF_control_port)
|
|
2a000 // @0e3 #827: RETURN
|
|
// #828: ;
|
|
// #829: ;
|
|
// #830: ;
|
|
// #831: ;**************************************************************************************
|
|
// #832: ; StrataFLASH Block Erase
|
|
// #833: ;**************************************************************************************
|
|
// #834: ;
|
|
// #835: ; This routine will erase one 128k-byte block of the StrataFLASH memory.
|
|
// #836: ; The block to be erased is specified by the contents of register 's9'.
|
|
// #837: ;
|
|
// #838: ; s9=06 erases Block 3 (address range 060000 to 07FFFF)
|
|
// #839: ;
|
|
// #840: ;
|
|
// #841: ; To erase a block the 24-bit address must be set and then the block erase command
|
|
// #842: ; (20 hex) written to the memory followed by the write confirm command (D0 hex).
|
|
// #843: ;
|
|
// #844: ; The act of erasing a block may take up to 1 second to complete. This routine
|
|
// #845: ; waits for the memory to be ready before restoring the normal read array mode and
|
|
// #846: ; returning.
|
|
// #847: ;
|
|
// #848: ; Registers used s0,s1,s7,s8,s9
|
|
// #849: ;
|
|
// @0e4 #850: [SF_erase_block]
|
|
00800 // @0e4 #850: LOAD(s8,0) ;define lower address of block = xx0000
|
|
00700 // @0e5 #851: LOAD(s7,0)
|
|
00120 // @0e6 #852: LOAD(s1,32) ;block erase command
|
|
3010b // @0e7 #853: CALL(SF_byte_write)
|
|
001d0 // @0e8 #854: LOAD(s1,D0) ;write confirm command
|
|
3010b // @0e9 #855: CALL(SF_byte_write)
|
|
30118 // @0ea #856: CALL(wait_SF_ready) ;wait for erase to complete
|
|
2a000 // @0eb #857: RETURN
|
|
// #858: ;
|
|
// #859: ;
|
|
// #860: ;**************************************************************************************
|
|
// #861: ; Write a single byte to StrataFlash Memory
|
|
// #862: ;**************************************************************************************
|
|
// #863: ;
|
|
// #864: ; To write a single byte to StrataFLASH memory the address must be set and the
|
|
// #865: ; single-word/byte program command (40 hex) sent to the memory. Then the data byte can
|
|
// #866: ; be written to the memory using the same address.
|
|
// #867: ;
|
|
// #868: ; The 24-bit address should be supplied in register set [s9,s8,s7].
|
|
// #869: ; Register s0 should contain the byte data to be written to the memory.
|
|
// #870: ;
|
|
// #871: ; The act of writing the memory array may take up to 175us to complete. This routine
|
|
// #872: ; waits for the memory to be ready before restoring the normal read array mode and
|
|
// #873: ; returning.
|
|
// #874: ;
|
|
// #875: ; Registers used s0,s1,s7,s8,s9 (s7,s8,s9 not changed)
|
|
// #876: ;
|
|
// #877: ; Registers used s0,s1,s7,s8,s9
|
|
// #878: ;
|
|
// @0ec #879: [SF_single_byte_write]
|
|
00140 // @0ec #879: LOAD(s1,64) ;command for single byte program
|
|
3010b // @0ed #880: CALL(SF_byte_write)
|
|
01100 // @0ee #881: LOAD(s1,s0) ;write data to be programmed
|
|
3010b // @0ef #882: CALL(SF_byte_write)
|
|
30118 // @0f0 #883: CALL(wait_SF_ready) ;wait for program to complete
|
|
2a000 // @0f1 #884: RETURN
|
|
// #885: ;
|
|
// #886: ;
|
|
// #887: ;
|
|
// #888: ;**************************************************************************************
|
|
// #889: ; Read the unique 64-bit serial number of the StrataFLASH FLASH memory
|
|
// #890: ;**************************************************************************************
|
|
// #891: ;
|
|
// #892: ; To read the device information the Read device information command (90)
|
|
// #893: ; must be written to the memory. The information is read back from address 000102
|
|
// #894: ; to 000109 (note these are byte access addresses).
|
|
// #895: ;
|
|
// #896: ; The serial number is copied to 8 ascending scratch pad memory locations called
|
|
// #897: ; 'serial_number0' through to 'serial_number7' for future use.
|
|
// #898: ;
|
|
// #899: ; After reading the device information the read array command is written to the
|
|
// #900: ; device to put it back to normal read mode.
|
|
// #901: ;
|
|
// #902: ; Registers used s0,s1,s2,s7,s8,s9
|
|
// #903: ;
|
|
// @0f2 #904: [read_SF_serial_number]
|
|
00900 // @0f2 #904: LOAD(s9,0) ;StrataFLASH address to read serial number = 000102
|
|
00801 // @0f3 #905: LOAD(s8,1)
|
|
00702 // @0f4 #906: LOAD(s7,2)
|
|
00210 // @0f5 #907: LOAD(s2,serial_number0) ;pointer to scratch pad memory
|
|
00190 // @0f6 #908: LOAD(s1,144) ;command to read device information
|
|
3010b // @0f7 #909: CALL(SF_byte_write)
|
|
// @0f8 #910: [read_SN_loop]
|
|
30101 // @0f8 #910: CALL(SF_byte_read) ;read serial number value
|
|
2f020 // @0f9 #911: STORE(s0,s2)
|
|
14217 // @0fa #912: COMPARE(s2,serial_number7) ;check for 8 bytes copied
|
|
350ff // @0fb #913: JUMP(Z,end_read_SN)
|
|
18701 // @0fc #914: ADD(s7,1) ;increment StrataFLASH address
|
|
18201 // @0fd #915: ADD(s2,1) ;increment memory pointer
|
|
340f8 // @0fe #916: JUMP(read_SN_loop)
|
|
// #917: ;
|
|
// @0ff #918: [end_read_SN]
|
|
30115 // @0ff #918: CALL(set_SF_read_array_mode) ;restore normal read array mode
|
|
2a000 // @100 #919: RETURN
|
|
// #920: ;
|
|
// #921: ;
|
|
// #922: ;
|
|
// #923: ;**************************************************************************************
|
|
// #924: ; Read a byte from StrataFlash Memory
|
|
// #925: ;**************************************************************************************
|
|
// #926: ;
|
|
// #927: ; The 24-bit address should be supplied in register set [s9,s8,s7].
|
|
// #928: ; Register s0 will return the byte data retrieved from the memory.
|
|
// #929: ;
|
|
// #930: ; To read a byte, the address needs to be set up on the address lines
|
|
// #931: ; and the controls set as follows
|
|
// #932: ; SF_read = 1 - disable Spartan data outputs and enable StrataFlash outputs (OE=0)
|
|
// #933: ; SF_ce = 0 - enable StrataFLASH memory
|
|
// #934: ; SF_we = 1 - Write enable off
|
|
// #935: ;
|
|
// #936: ; The access time of the memory is 75ns. This is equivalent to 3.75 clock cycles at
|
|
// #937: ; 50MHz. Since each KCPSM3 instruction takes 2 clock cycles to execute, two instructions
|
|
// #938: ; provides adequate delay for the memory to be accessed.
|
|
// #939: ;
|
|
// #940: ; Registers used s0,s1,s7,s8,s9
|
|
// #941: ;
|
|
// @101 #942: [SF_byte_read]
|
|
2c983 // @101 #942: OUTPUT(s9,SF_addr_hi_port) ;set 24-bit address
|
|
2c882 // @102 #943: OUTPUT(s8,SF_addr_mi_port)
|
|
2c781 // @103 #944: OUTPUT(s7,SF_addr_lo_port)
|
|
00105 // @104 #945: LOAD(s1,5) ;set controls
|
|
2c140 // @105 #946: OUTPUT(s1,SF_control_port)
|
|
00106 // @106 #947: LOAD(s1,6) ;>75ns delay
|
|
00106 // @107 #948: LOAD(s1,6) ;but do something useful!
|
|
04002 // @108 #949: INPUT(s0,SF_data_in_port) ;read data byte
|
|
2c140 // @109 #950: OUTPUT(s1,SF_control_port) ;clear controls
|
|
2a000 // @10a #951: RETURN
|
|
// #952: ;
|
|
// #953: ;
|
|
// #954: ;**************************************************************************************
|
|
// #955: ; Write data or command byte to StrataFlash Memory
|
|
// #956: ;**************************************************************************************
|
|
// #957: ;
|
|
// #958: ; The 24-bit address should be supplied in register set [s9,s8,s7].
|
|
// #959: ; Register s1 should contain the byte to be written to the memory.
|
|
// #960: ;
|
|
// #961: ; To write a byte, the address needs to be set up on the address lines
|
|
// #962: ; and the controls set as follows
|
|
// #963: ; SF_read = 0 - enable Spartan data outputs and disable StrataFlash outputs (OE=1)
|
|
// #964: ; SF_ce = 0 - enable StrataFLASH memory
|
|
// #965: ; SF_we = 0 - Write enable on
|
|
// #966: ;
|
|
// #967: ; The setup time of the memory is 60ns. This is equivalent to 3 clock cycles at
|
|
// #968: ; 50MHz. Since each KCPSM3 instruction takes 2 clock cycles to execute, two instructions
|
|
// #969: ; provides adequate delay for the memory.
|
|
// #970: ;
|
|
// #971: ; Registers used s1,s7,s8,s9
|
|
// #972: ;
|
|
// @10b #973: [SF_byte_write]
|
|
2c983 // @10b #973: OUTPUT(s9,SF_addr_hi_port) ;set 24-bit address
|
|
2c882 // @10c #974: OUTPUT(s8,SF_addr_mi_port)
|
|
2c781 // @10d #975: OUTPUT(s7,SF_addr_lo_port)
|
|
2c180 // @10e #976: OUTPUT(s1,SF_data_out_port) ;set data byte to be written
|
|
00100 // @10f #977: LOAD(s1,0) ;set controls
|
|
2c140 // @110 #978: OUTPUT(s1,SF_control_port)
|
|
00106 // @111 #979: LOAD(s1,6) ;>60ns delay
|
|
00106 // @112 #980: LOAD(s1,6) ;but do something useful!
|
|
2c140 // @113 #981: OUTPUT(s1,SF_control_port) ;clear controls
|
|
2a000 // @114 #982: RETURN
|
|
// #983: ;
|
|
// #984: ;
|
|
// #985: ;**************************************************************************************
|
|
// #986: ; Set 'Read Array' mode on StrataFLASH
|
|
// #987: ;**************************************************************************************
|
|
// #988: ;
|
|
// #989: ; The read array mode is the default mode of the memory and allows the contents
|
|
// #990: ; of the memory to be read based on the supplied address.
|
|
// #991: ;
|
|
// #992: ; Read array is the default mode of the device, but it must also be placed back
|
|
// #993: ; into this mode after programming, erasing or reading the status register.
|
|
// #994: ;
|
|
// #995: ; The read array command (FF hex) is written to the Strata flash memory.
|
|
// #996: ;
|
|
// #997: ; Registers used s1,s7,s8,s9
|
|
// #998: ;
|
|
// @115 #999: [set_SF_read_array_mode]
|
|
001ff // @115 #999: LOAD(s1,FF) ;command to read array
|
|
3010b // @116 #1000: CALL(SF_byte_write)
|
|
2a000 // @117 #1001: RETURN
|
|
// #1002: ;
|
|
// #1003: ;
|
|
// #1004: ;**************************************************************************************
|
|
// #1005: ; Wait for StrataFLASH to be ready
|
|
// #1006: ;**************************************************************************************
|
|
// #1007: ;
|
|
// #1008: ; This routine will typically be used after instigating a program or erase
|
|
// #1009: ; command. It continuously reads the StrataFLASH status register and tests the
|
|
// #1010: ; information provided by bit7 which indicates if the memory is busy(0) or ready(1).
|
|
// #1011: ; The routine waits for the ready condition before sending a read array command
|
|
// #1012: ; which puts the memory back to normal read mode.
|
|
// #1013: ;
|
|
// #1014: ;
|
|
// #1015: ; Registers used s0,s1,s7,s8,s9 (s7,s8,s9 not changed)
|
|
// #1016: ;
|
|
// #1017: ;
|
|
// @118 #1018: [wait_SF_ready]
|
|
30101 // @118 #1018: CALL(SF_byte_read) ;read status register into s0
|
|
12080 // @119 #1019: TEST(s0,128) ;test ready/busy flag
|
|
35118 // @11a #1020: JUMP(Z,wait_SF_ready)
|
|
30115 // @11b #1021: CALL(set_SF_read_array_mode) ;restore normal read array mode
|
|
2a000 // @11c #1022: RETURN
|
|
// #1023: ;
|
|
// #1024: ;
|
|
// #1025: ;
|
|
// #1026: ;
|
|
// #1027: ;**************************************************************************************
|
|
// #1028: ; UART communication routines
|
|
// #1029: ;**************************************************************************************
|
|
// #1030: ;
|
|
// #1031: ; Read one character from the UART
|
|
// #1032: ;
|
|
// #1033: ; Character read will be returned in a register called 'UART_data'.
|
|
// #1034: ;
|
|
// #1035: ; The routine first tests the receiver FIFO buffer to see if data is present.
|
|
// #1036: ; If the FIFO is empty, the routine waits until there is a character to read.
|
|
// #1037: ; As this could take any amount of time the wait loop could include a call to a
|
|
// #1038: ; subroutine which performs a useful function.
|
|
// #1039: ;
|
|
// #1040: ;
|
|
// #1041: ; Registers used s0 and UART_data
|
|
// #1042: ;
|
|
// @11d #1043: [read_from_UART]
|
|
04000 // @11d #1043: INPUT(s0,status_port) ;test Rx_FIFO buffer
|
|
12004 // @11e #1044: TEST(s0,rx_data_present) ;wait if empty
|
|
35521 // @11f #1045: JUMP(NZ,read_character)
|
|
3411d // @120 #1046: JUMP(read_from_UART)
|
|
// @121 #1047: [read_character]
|
|
04f01 // @121 #1047: INPUT(UART_data,UART_read_port) ;read from FIFO
|
|
2a000 // @122 #1048: RETURN
|
|
// #1049: ;
|
|
// #1050: ;
|
|
// #1051: ;
|
|
// #1052: ; Transmit one character to the UART
|
|
// #1053: ;
|
|
// #1054: ; Character supplied in register called 'UART_data'.
|
|
// #1055: ;
|
|
// #1056: ; The routine first tests the transmit FIFO buffer to see if it is full.
|
|
// #1057: ; If the FIFO is full, then the routine waits until it there is space.
|
|
// #1058: ;
|
|
// #1059: ; Registers used s0
|
|
// #1060: ;
|
|
// @123 #1061: [send_to_UART]
|
|
04000 // @123 #1061: INPUT(s0,status_port) ;test Tx_FIFO buffer
|
|
12002 // @124 #1062: TEST(s0,tx_full) ;wait if full
|
|
35127 // @125 #1063: JUMP(Z,UART_write)
|
|
34123 // @126 #1064: JUMP(send_to_UART)
|
|
// @127 #1065: [UART_write]
|
|
2cf08 // @127 #1065: OUTPUT(UART_data,UART_write_port)
|
|
2a000 // @128 #1066: RETURN
|
|
// #1067: ;
|
|
// #1068: ;
|
|
// #1069: ;
|
|
// #1070: ;**************************************************************************************
|
|
// #1071: ;Useful ASCII conversion and handling routines
|
|
// #1072: ;**************************************************************************************
|
|
// #1073: ;
|
|
// #1074: ;
|
|
// #1075: ;
|
|
// #1076: ;Convert character to upper case
|
|
// #1077: ;
|
|
// #1078: ;The character supplied in register UART_data.
|
|
// #1079: ;If the character is in the range 'a' to 'z', it is converted
|
|
// #1080: ;to the equivalent upper case character in the range 'A' to 'Z'.
|
|
// #1081: ;All other characters remain unchanged.
|
|
// #1082: ;
|
|
// #1083: ;Registers used s0.
|
|
// #1084: ;
|
|
// @129 #1085: [upper_case]
|
|
14f61 // @129 #1085: COMPARE(UART_data,97) ;eliminate character codes below 'a' (61 hex)
|
|
2b800 // @12a #1086: RETURN(C)
|
|
14f7b // @12b #1087: COMPARE(UART_data,123) ;eliminate character codes above 'z' (7A hex)
|
|
2bc00 // @12c #1088: RETURN(NC)
|
|
0afdf // @12d #1089: AND(UART_data,DF) ;mask bit5 to convert to upper case
|
|
2a000 // @12e #1090: RETURN
|
|
// #1091: ;
|
|
// #1092: ;
|
|
// #1093: ;Convert hexadecimal value provided in register s0 into ASCII characters
|
|
// #1094: ;
|
|
// #1095: ;The value provided must can be any value in the range 00 to FF and will be converted into
|
|
// #1096: ;two ASCII characters.
|
|
// #1097: ; The upper nibble will be represented by an ASCII character returned in register s2.
|
|
// #1098: ; The lower nibble will be represented by an ASCII character returned in register s1.
|
|
// #1099: ;
|
|
// #1100: ;The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex
|
|
// #1101: ;added to the actual decimal value. The ASCII representations of 'A' to 'F' are 41 to 46
|
|
// #1102: ;hexadecimal requiring a further addition of 07 to the 30 already added.
|
|
// #1103: ;
|
|
// #1104: ;Registers used s0, s1 and s2.
|
|
// #1105: ;
|
|
// @12f #1106: [hex_byte_to_ASCII]
|
|
01100 // @12f #1106: LOAD(s1,s0) ;remember value supplied
|
|
2000e // @130 #1107: SR0(s0) ;isolate upper nibble
|
|
2000e // @131 #1108: SR0(s0)
|
|
2000e // @132 #1109: SR0(s0)
|
|
2000e // @133 #1110: SR0(s0)
|
|
3013b // @134 #1111: CALL(hex_to_ASCII) ;convert
|
|
01200 // @135 #1112: LOAD(s2,s0) ;upper nibble value in s2
|
|
01010 // @136 #1113: LOAD(s0,s1) ;restore complete value
|
|
0a00f // @137 #1114: AND(s0,15) ;isolate lower nibble
|
|
3013b // @138 #1115: CALL(hex_to_ASCII) ;convert
|
|
01100 // @139 #1116: LOAD(s1,s0) ;lower nibble value in s1
|
|
2a000 // @13a #1117: RETURN
|
|
// #1118: ;
|
|
// #1119: ;Convert hexadecimal value provided in register s0 into ASCII character
|
|
// #1120: ;
|
|
// #1121: ;Register used s0
|
|
// #1122: ;
|
|
// @13b #1123: [hex_to_ASCII]
|
|
1c00a // @13b #1123: SUB(s0,10) ;test if value is in range 0 to 9
|
|
3593e // @13c #1124: JUMP(C,number_char)
|
|
18007 // @13d #1125: ADD(s0,7) ;ASCII char A to F in range 41 to 46
|
|
// @13e #1126: [number_char]
|
|
1803a // @13e #1126: ADD(s0,58) ;ASCII char 0 to 9 in range 30 to 40
|
|
2a000 // @13f #1127: RETURN
|
|
// #1128: ;
|
|
// #1129: ;
|
|
// #1130: ;Send the two character HEX value of the register contents 's0' to the UART
|
|
// #1131: ;
|
|
// #1132: ;Registers used s0, s1, s2
|
|
// #1133: ;
|
|
// @140 #1134: [send_hex_byte]
|
|
3012f // @140 #1134: CALL(hex_byte_to_ASCII)
|
|
01f20 // @141 #1135: LOAD(UART_data,s2)
|
|
30123 // @142 #1136: CALL(send_to_UART)
|
|
01f10 // @143 #1137: LOAD(UART_data,s1)
|
|
30123 // @144 #1138: CALL(send_to_UART)
|
|
2a000 // @145 #1139: RETURN
|
|
// #1140: ;
|
|
// #1141: ;
|
|
// #1142: ;Send the six character HEX value of the register contents [s9,s8,s7] to the UART
|
|
// #1143: ;
|
|
// #1144: ;Registers used s0, s1, s2
|
|
// #1145: ;
|
|
// @146 #1146: [send_hex_3bytes]
|
|
01090 // @146 #1146: LOAD(s0,s9)
|
|
30140 // @147 #1147: CALL(send_hex_byte)
|
|
01080 // @148 #1148: LOAD(s0,s8)
|
|
30140 // @149 #1149: CALL(send_hex_byte)
|
|
01070 // @14a #1150: LOAD(s0,s7)
|
|
30140 // @14b #1151: CALL(send_hex_byte)
|
|
2a000 // @14c #1152: RETURN
|
|
// #1153: ;
|
|
// #1154: ;
|
|
// #1155: ;Display the two character HEX value of the register contents 's0' on the LCD display
|
|
// #1156: ;
|
|
// #1157: ;Registers used s0,s1,s2,s3,s4,s5
|
|
// #1158: ;
|
|
// @14d #1159: [disp_hex_byte]
|
|
3012f // @14d #1159: CALL(hex_byte_to_ASCII)
|
|
01310 // @14e #1160: LOAD(s3,s1) ;remember least significant digit
|
|
01520 // @14f #1161: LOAD(s5,s2)
|
|
302fe // @150 #1162: CALL(LCD_write_data) ;display most significant digit
|
|
01530 // @151 #1163: LOAD(s5,s3)
|
|
302fe // @152 #1164: CALL(LCD_write_data) ;display least significant digit
|
|
2a000 // @153 #1165: RETURN
|
|
// #1166: ;
|
|
// #1167: ;
|
|
// #1168: ;
|
|
// #1169: ;**************************************************************************************
|
|
// #1170: ; UART Text messages
|
|
// #1171: ;**************************************************************************************
|
|
// #1172: ;
|
|
// #1173: ;
|
|
// #1174: ;Send Carriage Return to the UART
|
|
// #1175: ;
|
|
// @154 #1176: [send_CR]
|
|
00f0d // @154 #1176: LOAD(UART_data,character_CR)
|
|
30123 // @155 #1177: CALL(send_to_UART)
|
|
2a000 // @156 #1178: RETURN
|
|
// #1179: ;
|
|
// #1180: ;Send a space to the UART
|
|
// #1181: ;
|
|
// @157 #1182: [send_space]
|
|
00f20 // @157 #1182: LOAD(UART_data,character_space)
|
|
30123 // @158 #1183: CALL(send_to_UART)
|
|
2a000 // @159 #1184: RETURN
|
|
// #1185: ;
|
|
// #1186: ;
|
|
// #1187: ;Send an equals sign to the UART with a space each side
|
|
// #1188: ;
|
|
// @15a #1189: [send_equals]
|
|
30157 // @15a #1189: CALL(send_space)
|
|
00f3d // @15b #1190: LOAD(UART_data,character_equals)
|
|
30123 // @15c #1191: CALL(send_to_UART)
|
|
30157 // @15d #1192: CALL(send_space)
|
|
2a000 // @15e #1193: RETURN
|
|
// #1194: ;
|
|
// #1195: ;
|
|
// #1196: ;
|
|
// #1197: ;Send an minus sign (dash) to the UART with a space each side
|
|
// #1198: ;
|
|
// @15f #1199: [send_dash]
|
|
30157 // @15f #1199: CALL(send_space)
|
|
00f2d // @160 #1200: LOAD(UART_data,character_minus)
|
|
30123 // @161 #1201: CALL(send_to_UART)
|
|
30157 // @162 #1202: CALL(send_space)
|
|
2a000 // @163 #1203: RETURN
|
|
// #1204: ;
|
|
// #1205: ;
|
|
// #1206: ;Send 'PicoBlaze Low Cost Design Security v1.00' string to the UART
|
|
// #1207: ;
|
|
// @164 #1208: [send_welcome]
|
|
30154 // @164 #1208: CALL(send_CR)
|
|
30154 // @165 #1209: CALL(send_CR)
|
|
00f50 // @166 #1210: LOAD(UART_data,character_P)
|
|
30123 // @167 #1211: CALL(send_to_UART)
|
|
00f69 // @168 #1212: LOAD(UART_data,character_i)
|
|
30123 // @169 #1213: CALL(send_to_UART)
|
|
00f63 // @16a #1214: LOAD(UART_data,character_c)
|
|
30123 // @16b #1215: CALL(send_to_UART)
|
|
00f6f // @16c #1216: LOAD(UART_data,character_o)
|
|
30123 // @16d #1217: CALL(send_to_UART)
|
|
00f42 // @16e #1218: LOAD(UART_data,character_B)
|
|
30123 // @16f #1219: CALL(send_to_UART)
|
|
00f6c // @170 #1220: LOAD(UART_data,character_l)
|
|
30123 // @171 #1221: CALL(send_to_UART)
|
|
00f61 // @172 #1222: LOAD(UART_data,character_a)
|
|
30123 // @173 #1223: CALL(send_to_UART)
|
|
00f7a // @174 #1224: LOAD(UART_data,character_z)
|
|
30123 // @175 #1225: CALL(send_to_UART)
|
|
00f65 // @176 #1226: LOAD(UART_data,character_e)
|
|
30123 // @177 #1227: CALL(send_to_UART)
|
|
30157 // @178 #1228: CALL(send_space)
|
|
00f4c // @179 #1229: LOAD(UART_data,character_L)
|
|
30123 // @17a #1230: CALL(send_to_UART)
|
|
00f6f // @17b #1231: LOAD(UART_data,character_o)
|
|
30123 // @17c #1232: CALL(send_to_UART)
|
|
00f77 // @17d #1233: LOAD(UART_data,character_w)
|
|
30123 // @17e #1234: CALL(send_to_UART)
|
|
30157 // @17f #1235: CALL(send_space)
|
|
00f43 // @180 #1236: LOAD(UART_data,character_C)
|
|
30123 // @181 #1237: CALL(send_to_UART)
|
|
00f6f // @182 #1238: LOAD(UART_data,character_o)
|
|
30123 // @183 #1239: CALL(send_to_UART)
|
|
00f73 // @184 #1240: LOAD(UART_data,character_s)
|
|
30123 // @185 #1241: CALL(send_to_UART)
|
|
00f74 // @186 #1242: LOAD(UART_data,character_t)
|
|
30123 // @187 #1243: CALL(send_to_UART)
|
|
30157 // @188 #1244: CALL(send_space)
|
|
00f44 // @189 #1245: LOAD(UART_data,character_D)
|
|
30123 // @18a #1246: CALL(send_to_UART)
|
|
00f65 // @18b #1247: LOAD(UART_data,character_e)
|
|
30123 // @18c #1248: CALL(send_to_UART)
|
|
00f73 // @18d #1249: LOAD(UART_data,character_s)
|
|
30123 // @18e #1250: CALL(send_to_UART)
|
|
00f69 // @18f #1251: LOAD(UART_data,character_i)
|
|
30123 // @190 #1252: CALL(send_to_UART)
|
|
00f67 // @191 #1253: LOAD(UART_data,character_g)
|
|
30123 // @192 #1254: CALL(send_to_UART)
|
|
00f6e // @193 #1255: LOAD(UART_data,character_n)
|
|
30123 // @194 #1256: CALL(send_to_UART)
|
|
30157 // @195 #1257: CALL(send_space)
|
|
00f53 // @196 #1258: LOAD(UART_data,character_S)
|
|
30123 // @197 #1259: CALL(send_to_UART)
|
|
00f65 // @198 #1260: LOAD(UART_data,character_e)
|
|
30123 // @199 #1261: CALL(send_to_UART)
|
|
00f63 // @19a #1262: LOAD(UART_data,character_c)
|
|
30123 // @19b #1263: CALL(send_to_UART)
|
|
00f75 // @19c #1264: LOAD(UART_data,character_u)
|
|
30123 // @19d #1265: CALL(send_to_UART)
|
|
00f72 // @19e #1266: LOAD(UART_data,character_r)
|
|
30123 // @19f #1267: CALL(send_to_UART)
|
|
00f69 // @1a0 #1268: LOAD(UART_data,character_i)
|
|
30123 // @1a1 #1269: CALL(send_to_UART)
|
|
00f74 // @1a2 #1270: LOAD(UART_data,character_t)
|
|
30123 // @1a3 #1271: CALL(send_to_UART)
|
|
00f79 // @1a4 #1272: LOAD(UART_data,character_y)
|
|
30123 // @1a5 #1273: CALL(send_to_UART)
|
|
30157 // @1a6 #1274: CALL(send_space)
|
|
00f76 // @1a7 #1275: LOAD(UART_data,character_v)
|
|
30123 // @1a8 #1276: CALL(send_to_UART)
|
|
00f31 // @1a9 #1277: LOAD(UART_data,character_1)
|
|
30123 // @1aa #1278: CALL(send_to_UART)
|
|
00f2e // @1ab #1279: LOAD(UART_data,character_fullstop)
|
|
30123 // @1ac #1280: CALL(send_to_UART)
|
|
00f30 // @1ad #1281: LOAD(UART_data,character_0)
|
|
30123 // @1ae #1282: CALL(send_to_UART)
|
|
00f30 // @1af #1283: LOAD(UART_data,character_0)
|
|
30123 // @1b0 #1284: CALL(send_to_UART)
|
|
30154 // @1b1 #1285: CALL(send_CR)
|
|
30154 // @1b2 #1286: CALL(send_CR)
|
|
2a000 // @1b3 #1287: RETURN
|
|
// #1288: ;
|
|
// #1289: ;
|
|
// #1290: ;
|
|
// #1291: ;Send 'Copyright Ken Chapman 2006' string to the UART
|
|
// #1292: ;
|
|
// #1293: ;This message is significant because it demonstrates that the design
|
|
// #1294: ;now has a 'watermark'. The ASCII codes for this string will be
|
|
// #1295: ;stored in the design configuration bit stream somewhere as well as
|
|
// #1296: ;being played out by the UART. If someone tries to change or delete
|
|
// #1297: ;this message the contents of the BRAM will change and the hardware
|
|
// #1298: ;check of the BRAM contents will fail to match the expected value and
|
|
// #1299: ;the design will again be disabled.
|
|
// #1300: ;
|
|
// @1b4 #1301: [send_Copyright]
|
|
00f43 // @1b4 #1301: LOAD(UART_data,character_C)
|
|
30123 // @1b5 #1302: CALL(send_to_UART)
|
|
00f6f // @1b6 #1303: LOAD(UART_data,character_o)
|
|
30123 // @1b7 #1304: CALL(send_to_UART)
|
|
00f70 // @1b8 #1305: LOAD(UART_data,character_p)
|
|
30123 // @1b9 #1306: CALL(send_to_UART)
|
|
00f79 // @1ba #1307: LOAD(UART_data,character_y)
|
|
30123 // @1bb #1308: CALL(send_to_UART)
|
|
00f72 // @1bc #1309: LOAD(UART_data,character_r)
|
|
30123 // @1bd #1310: CALL(send_to_UART)
|
|
00f69 // @1be #1311: LOAD(UART_data,character_i)
|
|
30123 // @1bf #1312: CALL(send_to_UART)
|
|
00f67 // @1c0 #1313: LOAD(UART_data,character_g)
|
|
30123 // @1c1 #1314: CALL(send_to_UART)
|
|
00f68 // @1c2 #1315: LOAD(UART_data,character_h)
|
|
30123 // @1c3 #1316: CALL(send_to_UART)
|
|
00f74 // @1c4 #1317: LOAD(UART_data,character_t)
|
|
30123 // @1c5 #1318: CALL(send_to_UART)
|
|
30157 // @1c6 #1319: CALL(send_space)
|
|
00f4b // @1c7 #1320: LOAD(UART_data,character_K)
|
|
30123 // @1c8 #1321: CALL(send_to_UART)
|
|
00f65 // @1c9 #1322: LOAD(UART_data,character_e)
|
|
30123 // @1ca #1323: CALL(send_to_UART)
|
|
00f6e // @1cb #1324: LOAD(UART_data,character_n)
|
|
30123 // @1cc #1325: CALL(send_to_UART)
|
|
30157 // @1cd #1326: CALL(send_space)
|
|
00f43 // @1ce #1327: LOAD(UART_data,character_C)
|
|
30123 // @1cf #1328: CALL(send_to_UART)
|
|
00f68 // @1d0 #1329: LOAD(UART_data,character_h)
|
|
30123 // @1d1 #1330: CALL(send_to_UART)
|
|
00f61 // @1d2 #1331: LOAD(UART_data,character_a)
|
|
30123 // @1d3 #1332: CALL(send_to_UART)
|
|
00f70 // @1d4 #1333: LOAD(UART_data,character_p)
|
|
30123 // @1d5 #1334: CALL(send_to_UART)
|
|
00f6d // @1d6 #1335: LOAD(UART_data,character_m)
|
|
30123 // @1d7 #1336: CALL(send_to_UART)
|
|
00f61 // @1d8 #1337: LOAD(UART_data,character_a)
|
|
30123 // @1d9 #1338: CALL(send_to_UART)
|
|
00f6e // @1da #1339: LOAD(UART_data,character_n)
|
|
30123 // @1db #1340: CALL(send_to_UART)
|
|
30157 // @1dc #1341: CALL(send_space)
|
|
00f32 // @1dd #1342: LOAD(UART_data,character_2)
|
|
30123 // @1de #1343: CALL(send_to_UART)
|
|
00f30 // @1df #1344: LOAD(UART_data,character_0)
|
|
30123 // @1e0 #1345: CALL(send_to_UART)
|
|
30123 // @1e1 #1346: CALL(send_to_UART)
|
|
00f36 // @1e2 #1347: LOAD(UART_data,character_6)
|
|
30123 // @1e3 #1348: CALL(send_to_UART)
|
|
30154 // @1e4 #1349: CALL(send_CR)
|
|
30154 // @1e5 #1350: CALL(send_CR)
|
|
2a000 // @1e6 #1351: RETURN
|
|
// #1352: ;
|
|
// #1353: ;
|
|
// #1354: ;
|
|
// #1355: ;Send 'FLASH ' string to the UART
|
|
// #1356: ;
|
|
// @1e7 #1357: [send_FLASH]
|
|
00f46 // @1e7 #1357: LOAD(UART_data,character_F)
|
|
30123 // @1e8 #1358: CALL(send_to_UART)
|
|
00f4c // @1e9 #1359: LOAD(UART_data,character_L)
|
|
30123 // @1ea #1360: CALL(send_to_UART)
|
|
00f41 // @1eb #1361: LOAD(UART_data,character_A)
|
|
30123 // @1ec #1362: CALL(send_to_UART)
|
|
00f53 // @1ed #1363: LOAD(UART_data,character_S)
|
|
30123 // @1ee #1364: CALL(send_to_UART)
|
|
00f48 // @1ef #1365: LOAD(UART_data,character_H)
|
|
30123 // @1f0 #1366: CALL(send_to_UART)
|
|
2a000 // @1f1 #1367: RETURN
|
|
// #1368: ;
|
|
// #1369: ;
|
|
// #1370: ;
|
|
// #1371: ;Send 'FLASH Serial Number = ' string to the UART
|
|
// #1372: ;
|
|
// @1f2 #1373: [send_FLASH_Serial_Number]
|
|
301e7 // @1f2 #1373: CALL(send_FLASH)
|
|
30157 // @1f3 #1374: CALL(send_space)
|
|
00f53 // @1f4 #1375: LOAD(UART_data,character_S)
|
|
30123 // @1f5 #1376: CALL(send_to_UART)
|
|
00f65 // @1f6 #1377: LOAD(UART_data,character_e)
|
|
30123 // @1f7 #1378: CALL(send_to_UART)
|
|
00f72 // @1f8 #1379: LOAD(UART_data,character_r)
|
|
30123 // @1f9 #1380: CALL(send_to_UART)
|
|
00f69 // @1fa #1381: LOAD(UART_data,character_i)
|
|
30123 // @1fb #1382: CALL(send_to_UART)
|
|
00f61 // @1fc #1383: LOAD(UART_data,character_a)
|
|
30123 // @1fd #1384: CALL(send_to_UART)
|
|
00f6c // @1fe #1385: LOAD(UART_data,character_l)
|
|
30123 // @1ff #1386: CALL(send_to_UART)
|
|
30157 // @200 #1387: CALL(send_space)
|
|
00f4e // @201 #1388: LOAD(UART_data,character_N)
|
|
30123 // @202 #1389: CALL(send_to_UART)
|
|
00f75 // @203 #1390: LOAD(UART_data,character_u)
|
|
30123 // @204 #1391: CALL(send_to_UART)
|
|
00f6d // @205 #1392: LOAD(UART_data,character_m)
|
|
30123 // @206 #1393: CALL(send_to_UART)
|
|
00f62 // @207 #1394: LOAD(UART_data,character_b)
|
|
30123 // @208 #1395: CALL(send_to_UART)
|
|
00f65 // @209 #1396: LOAD(UART_data,character_e)
|
|
30123 // @20a #1397: CALL(send_to_UART)
|
|
00f72 // @20b #1398: LOAD(UART_data,character_r)
|
|
30123 // @20c #1399: CALL(send_to_UART)
|
|
3015a // @20d #1400: CALL(send_equals)
|
|
2a000 // @20e #1401: RETURN
|
|
// #1402: ;
|
|
// #1403: ;
|
|
// #1404: ;Send 'Auth' string to the UART
|
|
// #1405: ;
|
|
// @20f #1406: [send_Auth]
|
|
00f41 // @20f #1406: LOAD(UART_data,character_A)
|
|
30123 // @210 #1407: CALL(send_to_UART)
|
|
00f75 // @211 #1408: LOAD(UART_data,character_u)
|
|
30123 // @212 #1409: CALL(send_to_UART)
|
|
00f74 // @213 #1410: LOAD(UART_data,character_t)
|
|
30123 // @214 #1411: CALL(send_to_UART)
|
|
00f68 // @215 #1412: LOAD(UART_data,character_h)
|
|
30123 // @216 #1413: CALL(send_to_UART)
|
|
2a000 // @217 #1414: RETURN
|
|
// #1415: ;
|
|
// #1416: ;Send 'Authoris' to the UART
|
|
// #1417: ;
|
|
// @218 #1418: [send_Authoris]
|
|
3020f // @218 #1418: CALL(send_Auth)
|
|
00f6f // @219 #1419: LOAD(UART_data,character_o)
|
|
30123 // @21a #1420: CALL(send_to_UART)
|
|
00f72 // @21b #1421: LOAD(UART_data,character_r)
|
|
30123 // @21c #1422: CALL(send_to_UART)
|
|
00f69 // @21d #1423: LOAD(UART_data,character_i)
|
|
30123 // @21e #1424: CALL(send_to_UART)
|
|
00f73 // @21f #1425: LOAD(UART_data,character_s)
|
|
30123 // @220 #1426: CALL(send_to_UART)
|
|
2a000 // @221 #1427: RETURN
|
|
// #1428: ;
|
|
// #1429: ;Send 'Authorisation' to the UART
|
|
// #1430: ;
|
|
// @222 #1431: [send_Authorisation]
|
|
30218 // @222 #1431: CALL(send_Authoris)
|
|
00f61 // @223 #1432: LOAD(UART_data,character_a)
|
|
30123 // @224 #1433: CALL(send_to_UART)
|
|
00f74 // @225 #1434: LOAD(UART_data,character_t)
|
|
30123 // @226 #1435: CALL(send_to_UART)
|
|
00f69 // @227 #1436: LOAD(UART_data,character_i)
|
|
30123 // @228 #1437: CALL(send_to_UART)
|
|
00f6f // @229 #1438: LOAD(UART_data,character_o)
|
|
30123 // @22a #1439: CALL(send_to_UART)
|
|
00f6e // @22b #1440: LOAD(UART_data,character_n)
|
|
30123 // @22c #1441: CALL(send_to_UART)
|
|
2a000 // @22d #1442: RETURN
|
|
// #1443: ;
|
|
// #1444: ;Send 'Authorise' to the UART
|
|
// #1445: ;
|
|
// @22e #1446: [send_Authorise]
|
|
30218 // @22e #1446: CALL(send_Authoris)
|
|
00f65 // @22f #1447: LOAD(UART_data,character_e)
|
|
30123 // @230 #1448: CALL(send_to_UART)
|
|
2a000 // @231 #1449: RETURN
|
|
// #1450: ;
|
|
// #1451: ;Send 'Authentication' string to the UART
|
|
// #1452: ;
|
|
// @232 #1453: [send_Authentication]
|
|
3020f // @232 #1453: CALL(send_Auth)
|
|
00f65 // @233 #1454: LOAD(UART_data,character_e)
|
|
30123 // @234 #1455: CALL(send_to_UART)
|
|
00f6e // @235 #1456: LOAD(UART_data,character_n)
|
|
30123 // @236 #1457: CALL(send_to_UART)
|
|
00f74 // @237 #1458: LOAD(UART_data,character_t)
|
|
30123 // @238 #1459: CALL(send_to_UART)
|
|
00f69 // @239 #1460: LOAD(UART_data,character_i)
|
|
30123 // @23a #1461: CALL(send_to_UART)
|
|
00f63 // @23b #1462: LOAD(UART_data,character_c)
|
|
30123 // @23c #1463: CALL(send_to_UART)
|
|
00f61 // @23d #1464: LOAD(UART_data,character_a)
|
|
30123 // @23e #1465: CALL(send_to_UART)
|
|
00f74 // @23f #1466: LOAD(UART_data,character_t)
|
|
30123 // @240 #1467: CALL(send_to_UART)
|
|
00f69 // @241 #1468: LOAD(UART_data,character_i)
|
|
30123 // @242 #1469: CALL(send_to_UART)
|
|
00f6f // @243 #1470: LOAD(UART_data,character_o)
|
|
30123 // @244 #1471: CALL(send_to_UART)
|
|
00f6e // @245 #1472: LOAD(UART_data,character_n)
|
|
30123 // @246 #1473: CALL(send_to_UART)
|
|
2a000 // @247 #1474: RETURN
|
|
// #1475: ;
|
|
// #1476: ;
|
|
// #1477: ;Send 'FLASH CRC = ' string to the UART
|
|
// #1478: ;
|
|
// @248 #1479: [send_FLASH_CRC]
|
|
301e7 // @248 #1479: CALL(send_FLASH)
|
|
// #1480: ;
|
|
// #1481: ;
|
|
// #1482: ;Send ' CRC = ' string to the UART
|
|
// #1483: ;
|
|
// @249 #1484: [send_CRC]
|
|
30157 // @249 #1484: CALL(send_space)
|
|
00f43 // @24a #1485: LOAD(UART_data,character_C)
|
|
30123 // @24b #1486: CALL(send_to_UART)
|
|
00f52 // @24c #1487: LOAD(UART_data,character_R)
|
|
30123 // @24d #1488: CALL(send_to_UART)
|
|
00f43 // @24e #1489: LOAD(UART_data,character_C)
|
|
30123 // @24f #1490: CALL(send_to_UART)
|
|
3015a // @250 #1491: CALL(send_equals)
|
|
2a000 // @251 #1492: RETURN
|
|
// #1493: ;
|
|
// #1494: ;
|
|
// #1495: ;
|
|
// #1496: ;Send 'Computed CRC = ' string to the UART
|
|
// #1497: ;
|
|
// @252 #1498: [send_Computed_CRC]
|
|
00f43 // @252 #1498: LOAD(UART_data,character_C)
|
|
30123 // @253 #1499: CALL(send_to_UART)
|
|
00f6f // @254 #1500: LOAD(UART_data,character_o)
|
|
30123 // @255 #1501: CALL(send_to_UART)
|
|
00f6d // @256 #1502: LOAD(UART_data,character_m)
|
|
30123 // @257 #1503: CALL(send_to_UART)
|
|
00f70 // @258 #1504: LOAD(UART_data,character_p)
|
|
30123 // @259 #1505: CALL(send_to_UART)
|
|
00f75 // @25a #1506: LOAD(UART_data,character_u)
|
|
30123 // @25b #1507: CALL(send_to_UART)
|
|
00f74 // @25c #1508: LOAD(UART_data,character_t)
|
|
30123 // @25d #1509: CALL(send_to_UART)
|
|
00f65 // @25e #1510: LOAD(UART_data,character_e)
|
|
30123 // @25f #1511: CALL(send_to_UART)
|
|
00f64 // @260 #1512: LOAD(UART_data,character_d)
|
|
30123 // @261 #1513: CALL(send_to_UART)
|
|
34249 // @262 #1514: JUMP(send_CRC)
|
|
// #1515: ;
|
|
// #1516: ;
|
|
// #1517: ;Send 'Erase ' string to the UART
|
|
// #1518: ;
|
|
// @263 #1519: [send_Erase]
|
|
00f45 // @263 #1519: LOAD(UART_data,character_E)
|
|
30123 // @264 #1520: CALL(send_to_UART)
|
|
00f72 // @265 #1521: LOAD(UART_data,character_r)
|
|
30123 // @266 #1522: CALL(send_to_UART)
|
|
00f61 // @267 #1523: LOAD(UART_data,character_a)
|
|
30123 // @268 #1524: CALL(send_to_UART)
|
|
00f73 // @269 #1525: LOAD(UART_data,character_s)
|
|
30123 // @26a #1526: CALL(send_to_UART)
|
|
00f65 // @26b #1527: LOAD(UART_data,character_e)
|
|
30123 // @26c #1528: CALL(send_to_UART)
|
|
30157 // @26d #1529: CALL(send_space)
|
|
2a000 // @26e #1530: RETURN
|
|
// #1531: ;
|
|
// #1532: ;
|
|
// #1533: ;Send 'Erase Authorisation in progress' string to the UART
|
|
// #1534: ;
|
|
// @26f #1535: [send_Erase_in_progress]
|
|
30154 // @26f #1535: CALL(send_CR)
|
|
30263 // @270 #1536: CALL(send_Erase)
|
|
30222 // @271 #1537: CALL(send_Authorisation)
|
|
30157 // @272 #1538: CALL(send_space)
|
|
00f69 // @273 #1539: LOAD(UART_data,character_i)
|
|
30123 // @274 #1540: CALL(send_to_UART)
|
|
00f6e // @275 #1541: LOAD(UART_data,character_n)
|
|
30123 // @276 #1542: CALL(send_to_UART)
|
|
30157 // @277 #1543: CALL(send_space)
|
|
00f50 // @278 #1544: LOAD(UART_data,character_P)
|
|
30123 // @279 #1545: CALL(send_to_UART)
|
|
00f72 // @27a #1546: LOAD(UART_data,character_r)
|
|
30123 // @27b #1547: CALL(send_to_UART)
|
|
00f6f // @27c #1548: LOAD(UART_data,character_o)
|
|
30123 // @27d #1549: CALL(send_to_UART)
|
|
00f67 // @27e #1550: LOAD(UART_data,character_g)
|
|
30123 // @27f #1551: CALL(send_to_UART)
|
|
00f72 // @280 #1552: LOAD(UART_data,character_r)
|
|
30123 // @281 #1553: CALL(send_to_UART)
|
|
00f65 // @282 #1554: LOAD(UART_data,character_e)
|
|
30123 // @283 #1555: CALL(send_to_UART)
|
|
00f73 // @284 #1556: LOAD(UART_data,character_s)
|
|
30123 // @285 #1557: CALL(send_to_UART)
|
|
30123 // @286 #1558: CALL(send_to_UART)
|
|
30154 // @287 #1559: CALL(send_CR)
|
|
2a000 // @288 #1560: RETURN
|
|
// #1561: ;
|
|
// #1562: ;
|
|
// #1563: ;Send 'OK' to the UART
|
|
// #1564: ;
|
|
// @289 #1565: [send_OK]
|
|
00f4f // @289 #1565: LOAD(UART_data,character_O)
|
|
30123 // @28a #1566: CALL(send_to_UART)
|
|
00f4b // @28b #1567: LOAD(UART_data,character_K)
|
|
30123 // @28c #1568: CALL(send_to_UART)
|
|
30154 // @28d #1569: CALL(send_CR)
|
|
2a000 // @28e #1570: RETURN
|
|
// #1571: ;
|
|
// #1572: ;
|
|
// #1573: ;Send ' FAILED' to the UART
|
|
// #1574: ;
|
|
// @28f #1575: [send_FAILED]
|
|
30157 // @28f #1575: CALL(send_space)
|
|
00f46 // @290 #1576: LOAD(UART_data,character_F)
|
|
30123 // @291 #1577: CALL(send_to_UART)
|
|
00f41 // @292 #1578: LOAD(UART_data,character_A)
|
|
30123 // @293 #1579: CALL(send_to_UART)
|
|
00f49 // @294 #1580: LOAD(UART_data,character_I)
|
|
30123 // @295 #1581: CALL(send_to_UART)
|
|
00f4c // @296 #1582: LOAD(UART_data,character_L)
|
|
30123 // @297 #1583: CALL(send_to_UART)
|
|
00f45 // @298 #1584: LOAD(UART_data,character_E)
|
|
30123 // @299 #1585: CALL(send_to_UART)
|
|
00f44 // @29a #1586: LOAD(UART_data,character_D)
|
|
30123 // @29b #1587: CALL(send_to_UART)
|
|
2a000 // @29c #1588: RETURN
|
|
// #1589: ;
|
|
// #1590: ;
|
|
// #1591: ;Send ' PASSED' to the UART
|
|
// #1592: ;
|
|
// @29d #1593: [send_PASSED]
|
|
30157 // @29d #1593: CALL(send_space)
|
|
00f50 // @29e #1594: LOAD(UART_data,character_P)
|
|
30123 // @29f #1595: CALL(send_to_UART)
|
|
00f41 // @2a0 #1596: LOAD(UART_data,character_A)
|
|
30123 // @2a1 #1597: CALL(send_to_UART)
|
|
00f53 // @2a2 #1598: LOAD(UART_data,character_S)
|
|
30123 // @2a3 #1599: CALL(send_to_UART)
|
|
30123 // @2a4 #1600: CALL(send_to_UART)
|
|
00f45 // @2a5 #1601: LOAD(UART_data,character_E)
|
|
30123 // @2a6 #1602: CALL(send_to_UART)
|
|
00f44 // @2a7 #1603: LOAD(UART_data,character_D)
|
|
30123 // @2a8 #1604: CALL(send_to_UART)
|
|
2a000 // @2a9 #1605: RETURN
|
|
// #1606: ;
|
|
// #1607: ;
|
|
// #1608: ;
|
|
// #1609: ;Send 'Writing Authorisation' to the UART
|
|
// #1610: ;
|
|
// @2aa #1611: [send_Writing]
|
|
30154 // @2aa #1611: CALL(send_CR)
|
|
00f57 // @2ab #1612: LOAD(UART_data,character_W)
|
|
30123 // @2ac #1613: CALL(send_to_UART)
|
|
00f72 // @2ad #1614: LOAD(UART_data,character_r)
|
|
30123 // @2ae #1615: CALL(send_to_UART)
|
|
00f69 // @2af #1616: LOAD(UART_data,character_i)
|
|
30123 // @2b0 #1617: CALL(send_to_UART)
|
|
00f74 // @2b1 #1618: LOAD(UART_data,character_t)
|
|
30123 // @2b2 #1619: CALL(send_to_UART)
|
|
00f69 // @2b3 #1620: LOAD(UART_data,character_i)
|
|
30123 // @2b4 #1621: CALL(send_to_UART)
|
|
00f6e // @2b5 #1622: LOAD(UART_data,character_n)
|
|
30123 // @2b6 #1623: CALL(send_to_UART)
|
|
00f67 // @2b7 #1624: LOAD(UART_data,character_g)
|
|
30123 // @2b8 #1625: CALL(send_to_UART)
|
|
30157 // @2b9 #1626: CALL(send_space)
|
|
30222 // @2ba #1627: CALL(send_Authorisation)
|
|
2a000 // @2bb #1628: RETURN
|
|
// #1629: ;
|
|
// #1630: ;Send simple menu of options to the UART
|
|
// #1631: ;
|
|
// #1632: ;
|
|
// @2bc #1633: [send_Menu]
|
|
30154 // @2bc #1633: CALL(send_CR)
|
|
30154 // @2bd #1634: CALL(send_CR)
|
|
00f4d // @2be #1635: LOAD(UART_data,character_M)
|
|
30123 // @2bf #1636: CALL(send_to_UART)
|
|
00f65 // @2c0 #1637: LOAD(UART_data,character_e)
|
|
30123 // @2c1 #1638: CALL(send_to_UART)
|
|
00f6e // @2c2 #1639: LOAD(UART_data,character_n)
|
|
30123 // @2c3 #1640: CALL(send_to_UART)
|
|
00f75 // @2c4 #1641: LOAD(UART_data,character_u)
|
|
30123 // @2c5 #1642: CALL(send_to_UART)
|
|
30154 // @2c6 #1643: CALL(send_CR)
|
|
30154 // @2c7 #1644: CALL(send_CR)
|
|
00f52 // @2c8 #1645: LOAD(UART_data,character_R)
|
|
30123 // @2c9 #1646: CALL(send_to_UART)
|
|
3015f // @2ca #1647: CALL(send_dash)
|
|
00f52 // @2cb #1648: LOAD(UART_data,character_R)
|
|
30123 // @2cc #1649: CALL(send_to_UART)
|
|
00f65 // @2cd #1650: LOAD(UART_data,character_e)
|
|
30123 // @2ce #1651: CALL(send_to_UART)
|
|
00f61 // @2cf #1652: LOAD(UART_data,character_a)
|
|
30123 // @2d0 #1653: CALL(send_to_UART)
|
|
00f64 // @2d1 #1654: LOAD(UART_data,character_d)
|
|
30123 // @2d2 #1655: CALL(send_to_UART)
|
|
30157 // @2d3 #1656: CALL(send_space)
|
|
30222 // @2d4 #1657: CALL(send_Authorisation)
|
|
30154 // @2d5 #1658: CALL(send_CR)
|
|
00f45 // @2d6 #1659: LOAD(UART_data,character_E)
|
|
30123 // @2d7 #1660: CALL(send_to_UART)
|
|
3015f // @2d8 #1661: CALL(send_dash)
|
|
30263 // @2d9 #1662: CALL(send_Erase)
|
|
30222 // @2da #1663: CALL(send_Authorisation)
|
|
30154 // @2db #1664: CALL(send_CR)
|
|
00f41 // @2dc #1665: LOAD(UART_data,character_A)
|
|
30123 // @2dd #1666: CALL(send_to_UART)
|
|
3015f // @2de #1667: CALL(send_dash)
|
|
3022e // @2df #1668: CALL(send_Authorise)
|
|
30154 // @2e0 #1669: CALL(send_CR)
|
|
30154 // @2e1 #1670: CALL(send_CR)
|
|
00f3e // @2e2 #1671: LOAD(UART_data,character_greater_than) ;prompt for input
|
|
30123 // @2e3 #1672: CALL(send_to_UART)
|
|
2a000 // @2e4 #1673: RETURN
|
|
// #1674: ;
|
|
// #1675: ;**************************************************************************************
|
|
// #1676: ;LCD Character Module Routines
|
|
// #1677: ;**************************************************************************************
|
|
// #1678: ;
|
|
// #1679: ;LCD module is a 16 character by 2 line display but all displays are very similar
|
|
// #1680: ;The 4-wire data interface will be used (DB4 to DB7).
|
|
// #1681: ;
|
|
// #1682: ;The LCD modules are relatively slow and software delay loops are used to slow down
|
|
// #1683: ;KCPSM3 adequately for the LCD to communicate. The delay routines are provided in
|
|
// #1684: ;a different section (see above in this case).
|
|
// #1685: ;
|
|
// #1686: ;
|
|
// #1687: ;Pulse LCD enable signal 'E' high for greater than 230ns (1us is used).
|
|
// #1688: ;
|
|
// #1689: ;Register s4 should define the current state of the LCD output port.
|
|
// #1690: ;
|
|
// #1691: ;Registers used s0, s4
|
|
// #1692: ;
|
|
// @2e5 #1693: [LCD_pulse_E]
|
|
0e401 // @2e5 #1693: XOR(s4,LCD_E) ;E=1
|
|
2c420 // @2e6 #1694: OUTPUT(s4,LCD_output_port)
|
|
30348 // @2e7 #1695: CALL(delay_1us)
|
|
0e401 // @2e8 #1696: XOR(s4,LCD_E) ;E=0
|
|
2c420 // @2e9 #1697: OUTPUT(s4,LCD_output_port)
|
|
2a000 // @2ea #1698: RETURN
|
|
// #1699: ;
|
|
// #1700: ;Write 4-bit instruction to LCD display.
|
|
// #1701: ;
|
|
// #1702: ;The 4-bit instruction should be provided in the upper 4-bits of register s4.
|
|
// #1703: ;Note that this routine does not release the master enable but as it is only
|
|
// #1704: ;used during initialisation and as part of the 8-bit instruction write it
|
|
// #1705: ;should be acceptable.
|
|
// #1706: ;
|
|
// #1707: ;Registers used s4
|
|
// #1708: ;
|
|
// @2eb #1709: [LCD_write_inst4]
|
|
0a4f8 // @2eb #1709: AND(s4,F8) ;Enable=1 RS=0 Instruction, RW=0 Write, E=0
|
|
2c420 // @2ec #1710: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
302e5 // @2ed #1711: CALL(LCD_pulse_E)
|
|
2a000 // @2ee #1712: RETURN
|
|
// #1713: ;
|
|
// #1714: ;
|
|
// #1715: ;Write 8-bit instruction to LCD display.
|
|
// #1716: ;
|
|
// #1717: ;The 8-bit instruction should be provided in register s5.
|
|
// #1718: ;Instructions are written using the following sequence
|
|
// #1719: ; Upper nibble
|
|
// #1720: ; wait >1us
|
|
// #1721: ; Lower nibble
|
|
// #1722: ; wait >40us
|
|
// #1723: ;
|
|
// #1724: ;Registers used s0, s1, s4, s5
|
|
// #1725: ;
|
|
// @2ef #1726: [LCD_write_inst8]
|
|
01450 // @2ef #1726: LOAD(s4,s5)
|
|
0a4f0 // @2f0 #1727: AND(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
0c408 // @2f1 #1728: OR(s4,LCD_drive) ;Enable=1
|
|
302eb // @2f2 #1729: CALL(LCD_write_inst4) ;write upper nibble
|
|
30348 // @2f3 #1730: CALL(delay_1us) ;wait >1us
|
|
01450 // @2f4 #1731: LOAD(s4,s5) ;select lower nibble with
|
|
20407 // @2f5 #1732: SL1(s4) ;Enable=1
|
|
20406 // @2f6 #1733: SL0(s4) ;RS=0 Instruction
|
|
20406 // @2f7 #1734: SL0(s4) ;RW=0 Write
|
|
20406 // @2f8 #1735: SL0(s4) ;E=0
|
|
302eb // @2f9 #1736: CALL(LCD_write_inst4) ;write lower nibble
|
|
3034c // @2fa #1737: CALL(delay_40us) ;wait >40us
|
|
004f0 // @2fb #1738: LOAD(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
2c420 // @2fc #1739: OUTPUT(s4,LCD_output_port) ;Release master enable
|
|
2a000 // @2fd #1740: RETURN
|
|
// #1741: ;
|
|
// #1742: ;
|
|
// #1743: ;
|
|
// #1744: ;Write 8-bit data to LCD display.
|
|
// #1745: ;
|
|
// #1746: ;The 8-bit data should be provided in register s5.
|
|
// #1747: ;Data bytes are written using the following sequence
|
|
// #1748: ; Upper nibble
|
|
// #1749: ; wait >1us
|
|
// #1750: ; Lower nibble
|
|
// #1751: ; wait >40us
|
|
// #1752: ;
|
|
// #1753: ;Registers used s0, s1, s4, s5
|
|
// #1754: ;
|
|
// @2fe #1755: [LCD_write_data]
|
|
01450 // @2fe #1755: LOAD(s4,s5)
|
|
0a4f0 // @2ff #1756: AND(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
0c40c // @300 #1757: OR(s4,12) ;Enable=1 RS=1 Data, RW=0 Write, E=0
|
|
2c420 // @301 #1758: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
302e5 // @302 #1759: CALL(LCD_pulse_E) ;write upper nibble
|
|
30348 // @303 #1760: CALL(delay_1us) ;wait >1us
|
|
01450 // @304 #1761: LOAD(s4,s5) ;select lower nibble with
|
|
20407 // @305 #1762: SL1(s4) ;Enable=1
|
|
20407 // @306 #1763: SL1(s4) ;RS=1 Data
|
|
20406 // @307 #1764: SL0(s4) ;RW=0 Write
|
|
20406 // @308 #1765: SL0(s4) ;E=0
|
|
2c420 // @309 #1766: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
302e5 // @30a #1767: CALL(LCD_pulse_E) ;write lower nibble
|
|
3034c // @30b #1768: CALL(delay_40us) ;wait >40us
|
|
004f0 // @30c #1769: LOAD(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
2c420 // @30d #1770: OUTPUT(s4,LCD_output_port) ;Release master enable
|
|
2a000 // @30e #1771: RETURN
|
|
// #1772: ;
|
|
// #1773: ;
|
|
// #1774: ;
|
|
// #1775: ;
|
|
// #1776: ;Read 8-bit data from LCD display.
|
|
// #1777: ;
|
|
// #1778: ;The 8-bit data will be read from the current LCD memory address
|
|
// #1779: ;and will be returned in register s5.
|
|
// #1780: ;It is advisable to set the LCD address (cursor position) before
|
|
// #1781: ;using the data read for the first time otherwise the display may
|
|
// #1782: ;generate invalid data on the first read.
|
|
// #1783: ;
|
|
// #1784: ;Data bytes are read using the following sequence
|
|
// #1785: ; Upper nibble
|
|
// #1786: ; wait >1us
|
|
// #1787: ; Lower nibble
|
|
// #1788: ; wait >40us
|
|
// #1789: ;
|
|
// #1790: ;Registers used s0, s1, s4, s5
|
|
// #1791: ;
|
|
// @30f #1792: [LCD_read_data8]
|
|
0040e // @30f #1792: LOAD(s4,14) ;Enable=1 RS=1 Data, RW=1 Read, E=0
|
|
2c420 // @310 #1793: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
0e401 // @311 #1794: XOR(s4,LCD_E) ;E=1
|
|
2c420 // @312 #1795: OUTPUT(s4,LCD_output_port)
|
|
30348 // @313 #1796: CALL(delay_1us) ;wait >260ns to access data
|
|
04503 // @314 #1797: INPUT(s5,LCD_input_port) ;read upper nibble
|
|
0e401 // @315 #1798: XOR(s4,LCD_E) ;E=0
|
|
2c420 // @316 #1799: OUTPUT(s4,LCD_output_port)
|
|
30348 // @317 #1800: CALL(delay_1us) ;wait >1us
|
|
0e401 // @318 #1801: XOR(s4,LCD_E) ;E=1
|
|
2c420 // @319 #1802: OUTPUT(s4,LCD_output_port)
|
|
30348 // @31a #1803: CALL(delay_1us) ;wait >260ns to access data
|
|
04003 // @31b #1804: INPUT(s0,LCD_input_port) ;read lower nibble
|
|
0e401 // @31c #1805: XOR(s4,LCD_E) ;E=0
|
|
2c420 // @31d #1806: OUTPUT(s4,LCD_output_port)
|
|
0a5f0 // @31e #1807: AND(s5,F0) ;merge upper and lower nibbles
|
|
2000e // @31f #1808: SR0(s0)
|
|
2000e // @320 #1809: SR0(s0)
|
|
2000e // @321 #1810: SR0(s0)
|
|
2000e // @322 #1811: SR0(s0)
|
|
0d500 // @323 #1812: OR(s5,s0)
|
|
00404 // @324 #1813: LOAD(s4,4) ;Enable=0 RS=1 Data, RW=0 Write, E=0
|
|
2c420 // @325 #1814: OUTPUT(s4,LCD_output_port) ;Stop reading 5V device and release master enable
|
|
3034c // @326 #1815: CALL(delay_40us) ;wait >40us
|
|
2a000 // @327 #1816: RETURN
|
|
// #1817: ;
|
|
// #1818: ;
|
|
// #1819: ;Reset and initialise display to communicate using 4-bit data mode
|
|
// #1820: ;Includes routine to clear the display.
|
|
// #1821: ;
|
|
// #1822: ;Requires the 4-bit instructions 3,3,3,2 to be sent with suitable delays
|
|
// #1823: ;following by the 8-bit instructions to set up the display.
|
|
// #1824: ;
|
|
// #1825: ; 28 = '001' Function set, '0' 4-bit mode, '1' 2-line, '0' 5x7 dot matrix, 'xx'
|
|
// #1826: ; 06 = '000001' Entry mode, '1' increment, '0' no display shift
|
|
// #1827: ; 0C = '00001' Display control, '1' display on, '0' cursor off, '0' cursor blink off
|
|
// #1828: ; 01 = '00000001' Display clear
|
|
// #1829: ;
|
|
// #1830: ;Registers used s0, s1, s2, s3, s4
|
|
// #1831: ;
|
|
// @328 #1832: [LCD_reset]
|
|
30356 // @328 #1832: CALL(delay_20ms) ;wait more that 15ms for display to be ready
|
|
00430 // @329 #1833: LOAD(s4,48)
|
|
302eb // @32a #1834: CALL(LCD_write_inst4) ;send '3'
|
|
30356 // @32b #1835: CALL(delay_20ms) ;wait >4.1ms
|
|
302eb // @32c #1836: CALL(LCD_write_inst4) ;send '3'
|
|
30351 // @32d #1837: CALL(delay_1ms) ;wait >100us
|
|
302eb // @32e #1838: CALL(LCD_write_inst4) ;send '3'
|
|
3034c // @32f #1839: CALL(delay_40us) ;wait >40us
|
|
00420 // @330 #1840: LOAD(s4,32)
|
|
302eb // @331 #1841: CALL(LCD_write_inst4) ;send '2'
|
|
3034c // @332 #1842: CALL(delay_40us) ;wait >40us
|
|
00528 // @333 #1843: LOAD(s5,40) ;Function set
|
|
302ef // @334 #1844: CALL(LCD_write_inst8)
|
|
00506 // @335 #1845: LOAD(s5,6) ;Entry mode
|
|
302ef // @336 #1846: CALL(LCD_write_inst8)
|
|
0050c // @337 #1847: LOAD(s5,12) ;Display control
|
|
302ef // @338 #1848: CALL(LCD_write_inst8)
|
|
// @339 #1849: [LCD_clear]
|
|
00501 // @339 #1849: LOAD(s5,1) ;Display clear
|
|
302ef // @33a #1850: CALL(LCD_write_inst8)
|
|
30351 // @33b #1851: CALL(delay_1ms) ;wait >1.64ms for display to clear
|
|
30351 // @33c #1852: CALL(delay_1ms)
|
|
2a000 // @33d #1853: RETURN
|
|
// #1854: ;
|
|
// #1855: ;Position the cursor ready for characters to be written.
|
|
// #1856: ;The display is formed of 2 lines of 16 characters and each
|
|
// #1857: ;position has a corresponding address as indicated below.
|
|
// #1858: ;
|
|
// #1859: ; Character position
|
|
// #1860: ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
|
// #1861: ;
|
|
// #1862: ; Line 1 - 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
|
|
// #1863: ; Line 2 - C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
|
|
// #1864: ;
|
|
// #1865: ;This routine will set the cursor position using the value provided
|
|
// #1866: ;in register s5. The upper nibble will define the line and the lower
|
|
// #1867: ;nibble the character position on the line.
|
|
// #1868: ; Example s5 = 2B will position the cursor on line 2 position 11
|
|
// #1869: ;
|
|
// #1870: ;Registers used s0, s1, s2, s3, s4
|
|
// #1871: ;
|
|
// @33e #1872: [LCD_cursor]
|
|
12510 // @33e #1872: TEST(s5,16) ;test for line 1
|
|
35344 // @33f #1873: JUMP(Z,set_line2)
|
|
0a50f // @340 #1874: AND(s5,15) ;make address in range 80 to 8F for line 1
|
|
0c580 // @341 #1875: OR(s5,128)
|
|
302ef // @342 #1876: CALL(LCD_write_inst8) ;instruction write to set cursor
|
|
2a000 // @343 #1877: RETURN
|
|
// @344 #1878: [set_line2]
|
|
0a50f // @344 #1878: AND(s5,15) ;make address in range C0 to CF for line 2
|
|
0c5c0 // @345 #1879: OR(s5,C0)
|
|
302ef // @346 #1880: CALL(LCD_write_inst8) ;instruction write to set cursor
|
|
2a000 // @347 #1881: RETURN
|
|
// #1882: ;
|
|
// #1883: ;**************************************************************************************
|
|
// #1884: ;Software delay routines
|
|
// #1885: ;**************************************************************************************
|
|
// #1886: ;
|
|
// #1887: ;
|
|
// #1888: ;
|
|
// #1889: ;Delay of 1us.
|
|
// #1890: ;
|
|
// #1891: ;Constant value defines reflects the clock applied to KCPSM3. Every instruction
|
|
// #1892: ;executes in 2 clock cycles making the calculation highly predictable. The '6' in
|
|
// #1893: ;the following equation even allows for 'CALL delay_1us' instruction in the initiating code.
|
|
// #1894: ;
|
|
// #1895: ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
|
|
// #1896: ;
|
|
// #1897: ;Registers used s0
|
|
// #1898: ;
|
|
// @348 #1899: [delay_1us]
|
|
0000b // @348 #1899: LOAD(s0,delay_1us_constant)
|
|
// @349 #1900: [wait_1us]
|
|
1c001 // @349 #1900: SUB(s0,1)
|
|
35749 // @34a #1901: JUMP(NZ,wait_1us)
|
|
2a000 // @34b #1902: RETURN
|
|
// #1903: ;
|
|
// #1904: ;Delay of 40us.
|
|
// #1905: ;
|
|
// #1906: ;Registers used s0, s1
|
|
// #1907: ;
|
|
// @34c #1908: [delay_40us]
|
|
00128 // @34c #1908: LOAD(s1,40) ;40 x 1us = 40us
|
|
// @34d #1909: [wait_40us]
|
|
30348 // @34d #1909: CALL(delay_1us)
|
|
1c101 // @34e #1910: SUB(s1,1)
|
|
3574d // @34f #1911: JUMP(NZ,wait_40us)
|
|
2a000 // @350 #1912: RETURN
|
|
// #1913: ;
|
|
// #1914: ;
|
|
// #1915: ;Delay of 1ms.
|
|
// #1916: ;
|
|
// #1917: ;Registers used s0, s1, s2
|
|
// #1918: ;
|
|
// @351 #1919: [delay_1ms]
|
|
00219 // @351 #1919: LOAD(s2,25) ;25 x 40us = 1ms
|
|
// @352 #1920: [wait_1ms]
|
|
3034c // @352 #1920: CALL(delay_40us)
|
|
1c201 // @353 #1921: SUB(s2,1)
|
|
35752 // @354 #1922: JUMP(NZ,wait_1ms)
|
|
2a000 // @355 #1923: RETURN
|
|
// #1924: ;
|
|
// #1925: ;Delay of 20ms.
|
|
// #1926: ;
|
|
// #1927: ;Delay of 20ms used during initialisation.
|
|
// #1928: ;
|
|
// #1929: ;Registers used s0, s1, s2, s3
|
|
// #1930: ;
|
|
// @356 #1931: [delay_20ms]
|
|
00314 // @356 #1931: LOAD(s3,20) ;20 x 1ms = 20ms
|
|
// @357 #1932: [wait_20ms]
|
|
30351 // @357 #1932: CALL(delay_1ms)
|
|
1c301 // @358 #1933: SUB(s3,1)
|
|
35757 // @359 #1934: JUMP(NZ,wait_20ms)
|
|
2a000 // @35a #1935: RETURN
|
|
// #1936: ;
|
|
// #1937: ;Delay of approximately 1 second.
|
|
// #1938: ;
|
|
// #1939: ;Registers used s0, s1, s2, s3, s4
|
|
// #1940: ;
|
|
// @35b #1941: [delay_1s]
|
|
00432 // @35b #1941: LOAD(s4,50) ;50 x 20ms = 1000ms
|
|
// @35c #1942: [wait_1s]
|
|
30356 // @35c #1942: CALL(delay_20ms)
|
|
1c401 // @35d #1943: SUB(s4,1)
|
|
3575c // @35e #1944: JUMP(NZ,wait_1s)
|
|
2a000 // @35f #1945: RETURN
|
|
// #1946: ;
|
|
// #1947: ;
|
|
// #1948: ;Delay of approximately N seconds where 'N' is provided in register s5.
|
|
// #1949: ;
|
|
// #1950: ;Registers used s0, s1, s2, s3, s4, s5
|
|
// #1951: ;
|
|
// @360 #1952: [delay_Ns]
|
|
3035b // @360 #1952: CALL(delay_1s)
|
|
1c501 // @361 #1953: SUB(s5,1)
|
|
35760 // @362 #1954: JUMP(NZ,delay_Ns)
|
|
2a000 // @363 #1955: RETURN
|
|
// #1956: ;
|
|
// #1957: ;
|
|
// #1958: ;
|
|
// #1959: ;**************************************************************************************
|
|
// #1960: ;LCD text messages
|
|
// #1961: ;**************************************************************************************
|
|
// #1962: ;
|
|
// #1963: ;
|
|
// #1964: ;
|
|
// #1965: ;Display 'PicoBlaze' on LCD at current cursor position
|
|
// #1966: ;
|
|
// #1967: ;
|
|
// @364 #1968: [disp_PicoBlaze]
|
|
00550 // @364 #1968: LOAD(s5,character_P)
|
|
302fe // @365 #1969: CALL(LCD_write_data)
|
|
00569 // @366 #1970: LOAD(s5,character_i)
|
|
302fe // @367 #1971: CALL(LCD_write_data)
|
|
00563 // @368 #1972: LOAD(s5,character_c)
|
|
302fe // @369 #1973: CALL(LCD_write_data)
|
|
0056f // @36a #1974: LOAD(s5,character_o)
|
|
302fe // @36b #1975: CALL(LCD_write_data)
|
|
00542 // @36c #1976: LOAD(s5,character_B)
|
|
302fe // @36d #1977: CALL(LCD_write_data)
|
|
0056c // @36e #1978: LOAD(s5,character_l)
|
|
302fe // @36f #1979: CALL(LCD_write_data)
|
|
00561 // @370 #1980: LOAD(s5,character_a)
|
|
302fe // @371 #1981: CALL(LCD_write_data)
|
|
0057a // @372 #1982: LOAD(s5,character_z)
|
|
302fe // @373 #1983: CALL(LCD_write_data)
|
|
00565 // @374 #1984: LOAD(s5,character_e)
|
|
302fe // @375 #1985: CALL(LCD_write_data)
|
|
2a000 // @376 #1986: RETURN
|
|
// #1987: ;
|
|
// #1988: ;
|
|
// #1989: ;Display 'Security' on LCD at current cursor position
|
|
// #1990: ;
|
|
// #1991: ;
|
|
// @377 #1992: [disp_Security]
|
|
00553 // @377 #1992: LOAD(s5,character_S)
|
|
302fe // @378 #1993: CALL(LCD_write_data)
|
|
00565 // @379 #1994: LOAD(s5,character_e)
|
|
302fe // @37a #1995: CALL(LCD_write_data)
|
|
00563 // @37b #1996: LOAD(s5,character_c)
|
|
302fe // @37c #1997: CALL(LCD_write_data)
|
|
00575 // @37d #1998: LOAD(s5,character_u)
|
|
302fe // @37e #1999: CALL(LCD_write_data)
|
|
00572 // @37f #2000: LOAD(s5,character_r)
|
|
302fe // @380 #2001: CALL(LCD_write_data)
|
|
00569 // @381 #2002: LOAD(s5,character_i)
|
|
302fe // @382 #2003: CALL(LCD_write_data)
|
|
00574 // @383 #2004: LOAD(s5,character_t)
|
|
302fe // @384 #2005: CALL(LCD_write_data)
|
|
00579 // @385 #2006: LOAD(s5,character_y)
|
|
302fe // @386 #2007: CALL(LCD_write_data)
|
|
2a000 // @387 #2008: RETURN
|
|
// #2009: ;
|
|
// #2010: ;
|
|
// #2011: ;Display 'FLASH Serial No.' on LCD at current cursor position
|
|
// #2012: ;
|
|
// #2013: ;
|
|
// @388 #2014: [disp_FLASH_Serial_No]
|
|
00546 // @388 #2014: LOAD(s5,character_F)
|
|
302fe // @389 #2015: CALL(LCD_write_data)
|
|
0054c // @38a #2016: LOAD(s5,character_L)
|
|
302fe // @38b #2017: CALL(LCD_write_data)
|
|
00541 // @38c #2018: LOAD(s5,character_A)
|
|
302fe // @38d #2019: CALL(LCD_write_data)
|
|
00553 // @38e #2020: LOAD(s5,character_S)
|
|
302fe // @38f #2021: CALL(LCD_write_data)
|
|
00548 // @390 #2022: LOAD(s5,character_H)
|
|
302fe // @391 #2023: CALL(LCD_write_data)
|
|
00520 // @392 #2024: LOAD(s5,character_space)
|
|
302fe // @393 #2025: CALL(LCD_write_data)
|
|
00553 // @394 #2026: LOAD(s5,character_S)
|
|
302fe // @395 #2027: CALL(LCD_write_data)
|
|
00565 // @396 #2028: LOAD(s5,character_e)
|
|
302fe // @397 #2029: CALL(LCD_write_data)
|
|
00572 // @398 #2030: LOAD(s5,character_r)
|
|
302fe // @399 #2031: CALL(LCD_write_data)
|
|
00569 // @39a #2032: LOAD(s5,character_i)
|
|
302fe // @39b #2033: CALL(LCD_write_data)
|
|
00561 // @39c #2034: LOAD(s5,character_a)
|
|
302fe // @39d #2035: CALL(LCD_write_data)
|
|
0056c // @39e #2036: LOAD(s5,character_l)
|
|
302fe // @39f #2037: CALL(LCD_write_data)
|
|
00520 // @3a0 #2038: LOAD(s5,character_space)
|
|
302fe // @3a1 #2039: CALL(LCD_write_data)
|
|
0054e // @3a2 #2040: LOAD(s5,character_N)
|
|
302fe // @3a3 #2041: CALL(LCD_write_data)
|
|
0056f // @3a4 #2042: LOAD(s5,character_o)
|
|
302fe // @3a5 #2043: CALL(LCD_write_data)
|
|
0052e // @3a6 #2044: LOAD(s5,character_fullstop)
|
|
302fe // @3a7 #2045: CALL(LCD_write_data)
|
|
2a000 // @3a8 #2046: RETURN
|
|
// #2047: ;
|
|
// #2048: ;
|
|
// #2049: ;
|
|
// #2050: ;Display 'Authentication' on top line of the LCD
|
|
// #2051: ;
|
|
// #2052: ;
|
|
// @3a9 #2053: [disp_Authentication]
|
|
00511 // @3a9 #2053: LOAD(s5,17) ;Line 1 position 1
|
|
3033e // @3aa #2054: CALL(LCD_cursor)
|
|
00541 // @3ab #2055: LOAD(s5,character_A)
|
|
302fe // @3ac #2056: CALL(LCD_write_data)
|
|
00575 // @3ad #2057: LOAD(s5,character_u)
|
|
302fe // @3ae #2058: CALL(LCD_write_data)
|
|
00574 // @3af #2059: LOAD(s5,character_t)
|
|
302fe // @3b0 #2060: CALL(LCD_write_data)
|
|
00568 // @3b1 #2061: LOAD(s5,character_h)
|
|
302fe // @3b2 #2062: CALL(LCD_write_data)
|
|
00565 // @3b3 #2063: LOAD(s5,character_e)
|
|
302fe // @3b4 #2064: CALL(LCD_write_data)
|
|
0056e // @3b5 #2065: LOAD(s5,character_n)
|
|
302fe // @3b6 #2066: CALL(LCD_write_data)
|
|
00574 // @3b7 #2067: LOAD(s5,character_t)
|
|
302fe // @3b8 #2068: CALL(LCD_write_data)
|
|
00569 // @3b9 #2069: LOAD(s5,character_i)
|
|
302fe // @3ba #2070: CALL(LCD_write_data)
|
|
00563 // @3bb #2071: LOAD(s5,character_c)
|
|
302fe // @3bc #2072: CALL(LCD_write_data)
|
|
00561 // @3bd #2073: LOAD(s5,character_a)
|
|
302fe // @3be #2074: CALL(LCD_write_data)
|
|
00574 // @3bf #2075: LOAD(s5,character_t)
|
|
302fe // @3c0 #2076: CALL(LCD_write_data)
|
|
00569 // @3c1 #2077: LOAD(s5,character_i)
|
|
302fe // @3c2 #2078: CALL(LCD_write_data)
|
|
0056f // @3c3 #2079: LOAD(s5,character_o)
|
|
302fe // @3c4 #2080: CALL(LCD_write_data)
|
|
0056e // @3c5 #2081: LOAD(s5,character_n)
|
|
302fe // @3c6 #2082: CALL(LCD_write_data)
|
|
2a000 // @3c7 #2083: RETURN
|
|
// #2084: ;
|
|
// #2085: ;
|
|
// #2086: ;
|
|
// #2087: ;
|
|
// #2088: ;Display 'Passed' on lower line of the LCD
|
|
// #2089: ;
|
|
// #2090: ;
|
|
// @3c8 #2091: [disp_Passed]
|
|
00525 // @3c8 #2091: LOAD(s5,37) ;Line 2 position 5
|
|
3033e // @3c9 #2092: CALL(LCD_cursor)
|
|
00550 // @3ca #2093: LOAD(s5,character_P)
|
|
302fe // @3cb #2094: CALL(LCD_write_data)
|
|
00561 // @3cc #2095: LOAD(s5,character_a)
|
|
302fe // @3cd #2096: CALL(LCD_write_data)
|
|
00573 // @3ce #2097: LOAD(s5,character_s)
|
|
302fe // @3cf #2098: CALL(LCD_write_data)
|
|
302fe // @3d0 #2099: CALL(LCD_write_data)
|
|
00565 // @3d1 #2100: LOAD(s5,character_e)
|
|
302fe // @3d2 #2101: CALL(LCD_write_data)
|
|
00564 // @3d3 #2102: LOAD(s5,character_d)
|
|
302fe // @3d4 #2103: CALL(LCD_write_data)
|
|
2a000 // @3d5 #2104: RETURN
|
|
// #2105: ;
|
|
// #2106: ;
|
|
// #2107: ;
|
|
// #2108: ;
|
|
// #2109: ;
|
|
// #2110: ;Display 'Failed' on lower line of the LCD
|
|
// #2111: ;
|
|
// #2112: ;
|
|
// @3d6 #2113: [disp_Failed]
|
|
00525 // @3d6 #2113: LOAD(s5,37) ;Line 2 position 5
|
|
3033e // @3d7 #2114: CALL(LCD_cursor)
|
|
00546 // @3d8 #2115: LOAD(s5,character_F)
|
|
302fe // @3d9 #2116: CALL(LCD_write_data)
|
|
00561 // @3da #2117: LOAD(s5,character_a)
|
|
302fe // @3db #2118: CALL(LCD_write_data)
|
|
00569 // @3dc #2119: LOAD(s5,character_i)
|
|
302fe // @3dd #2120: CALL(LCD_write_data)
|
|
0056c // @3de #2121: LOAD(s5,character_l)
|
|
302fe // @3df #2122: CALL(LCD_write_data)
|
|
00565 // @3e0 #2123: LOAD(s5,character_e)
|
|
302fe // @3e1 #2124: CALL(LCD_write_data)
|
|
00564 // @3e2 #2125: LOAD(s5,character_d)
|
|
302fe // @3e3 #2126: CALL(LCD_write_data)
|
|
2a000 // @3e4 #2127: RETURN
|
|
// #2128: ;
|
|
// #2129: ;
|
|
// #2130: ;**************************************************************************************
|
|
// #2131: ; Interrupt Service Routine (ISR)
|
|
// #2132: ;**************************************************************************************
|
|
// #2133: ;
|
|
// #2134: ; Interrupts occur when the application processor is requesting a design authorisation
|
|
// #2135: ; message. Therefore an interrupt results in a message being sent to the Link FIFO
|
|
// #2136: ; depending on the authentication status.
|
|
// #2137: ;
|
|
// @3e5 #2138: [ISR]
|
|
2e000 // @3e5 #2138: STORE(s0,ISR_preserve_s0) ;save register contents
|
|
// #2139: ;
|
|
0601c // @3e6 #2140: FETCH(s0,authentication_status) ;read authentication status
|
|
14050 // @3e7 #2141: COMPARE(s0,character_P) ;test for pass 'P' or fail 'F'
|
|
353f2 // @3e8 #2142: JUMP(Z,pass_token)
|
|
// #2143: ;
|
|
00046 // @3e9 #2144: LOAD(s0,character_F) ;send FAIL to link FIFO
|
|
2c004 // @3ea #2145: OUTPUT(s0,link_FIFO_write_port)
|
|
00041 // @3eb #2146: LOAD(s0,character_A)
|
|
2c004 // @3ec #2147: OUTPUT(s0,link_FIFO_write_port)
|
|
00049 // @3ed #2148: LOAD(s0,character_I)
|
|
2c004 // @3ee #2149: OUTPUT(s0,link_FIFO_write_port)
|
|
0004c // @3ef #2150: LOAD(s0,character_L)
|
|
2c004 // @3f0 #2151: OUTPUT(s0,link_FIFO_write_port)
|
|
343f8 // @3f1 #2152: JUMP(end_ISR)
|
|
// #2153: ;
|
|
// @3f2 #2154: [pass_token]
|
|
2c004 // @3f2 #2154: OUTPUT(s0,link_FIFO_write_port) ;send PASS to link FIFO
|
|
00041 // @3f3 #2155: LOAD(s0,character_A)
|
|
2c004 // @3f4 #2156: OUTPUT(s0,link_FIFO_write_port)
|
|
00053 // @3f5 #2157: LOAD(s0,character_S)
|
|
2c004 // @3f6 #2158: OUTPUT(s0,link_FIFO_write_port)
|
|
2c004 // @3f7 #2159: OUTPUT(s0,link_FIFO_write_port)
|
|
// #2160: ;
|
|
// @3f8 #2161: [end_ISR]
|
|
06000 // @3f8 #2161: FETCH(s0,ISR_preserve_s0) ;restore register contents
|
|
38001 // @3f9 #2162: RETURNI(ENABLE)
|
|
// #2163: ;
|
|
// #2164: ;
|
|
// #2165: ;**************************************************************************************
|
|
// #2166: ; Interrupt Vector
|
|
// #2167: ;**************************************************************************************
|
|
// #2168: ;
|
|
@3ff // #2169: ADDRESS(1023)
|
|
343e5 // @3ff #2170: JUMP(ISR)
|
|
// #2171: ;
|
|
// #2172: ;
|
|
// #2173: ;**************************************************************************************
|
|
// #2174: ; End of Program
|
|
// #2175: ;**************************************************************************************
|