1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-01-28 07:02:55 +08:00

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: ;**************************************************************************************