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

1917 lines
80 KiB
Plaintext
Raw Permalink Normal View History

/* Symbol Table */
// ASCII_byte_to_hex = LABEL: 372
// ASCII_letter = LABEL: 395
// ASCII_to_hex = LABEL: 385
// ISR = LABEL: 1013
// ISR_preserve_s0 = CONSTANT: 0
// MCS_address = LABEL: 103
// SF_STS = CONSTANT: 128
// SF_addr_hi_port = CONSTANT: 128
// SF_addr_lo_port = CONSTANT: 32
// SF_addr_mi_port = CONSTANT: 64
// SF_buffer_write = LABEL: 119
// SF_byte_read = LABEL: 224
// SF_byte_write = LABEL: 234
// SF_ce = CONSTANT: 2
// SF_control_port = CONSTANT: 8
// SF_data_in_port = CONSTANT: 2
// SF_data_out_port = CONSTANT: 16
// SF_erase_block = LABEL: 65
// SF_information = LABEL: 194
// SF_init = LABEL: 39
// SF_read = CONSTANT: 1
// SF_single_byte_write = LABEL: 157
// SF_status = LABEL: 213
// SF_we = CONSTANT: 4
// UART_data = REGISTER: 15
// UART_read_port = CONSTANT: 1
// UART_write = LABEL: 309
// UART_write_port = CONSTANT: 4
// abort_erase = LABEL: 63
// block_erase_command = LABEL: 44
// blocks_erase = LABEL: 45
// blocks_erase_loop = LABEL: 56
// 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_LF = CONSTANT: 10
// 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_XOFF = CONSTANT: 19
// character_XON = CONSTANT: 17
// character_Y = CONSTANT: 89
// character_Z = CONSTANT: 90
// character_a = CONSTANT: 97
// character_b = CONSTANT: 98
// character_c = CONSTANT: 99
// character_close = CONSTANT: 41
// 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_open = CONSTANT: 40
// 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
// data_start = CONSTANT: 47
// decimal_to_ASCII = LABEL: 311
// delay_1ms = LABEL: 272
// delay_1s = LABEL: 282
// delay_1us = LABEL: 263
// delay_1us_constant = CONSTANT: 11
// delay_20ms = LABEL: 277
// delay_40us = LABEL: 267
// erase_command = LABEL: 42
// get_data = LABEL: 150
// hex_byte_to_ASCII = LABEL: 342
// hex_to_ASCII = LABEL: 354
// isr_send_character = LABEL: 1020
// isr_send_xon = LABEL: 1019
// line_start = CONSTANT: 43
// new_low_address = LABEL: 114
// number_char = LABEL: 357
// obtain_8bits = LABEL: 397
// onechar_to_value = LABEL: 324
// program_MCS = LABEL: 76
// program_command = LABEL: 71
// prompt = LABEL: 7
// read_MCS_byte = LABEL: 91
// read_MCS_line = LABEL: 87
// read_XON = LABEL: 301
// read_character = LABEL: 292
// read_command = LABEL: 163
// read_from_UART = LABEL: 287
// read_upper_case = LABEL: 34
// rx_data_present = CONSTANT: 8
// rx_full = CONSTANT: 32
// rx_half_full = CONSTANT: 16
// 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
// send_Abort = LABEL: 753
// send_CR = LABEL: 403
// send_Confirm = LABEL: 724
// send_Erase = LABEL: 544
// send_Erase_in_progress = LABEL: 521
// send_ID = LABEL: 710
// send_MCS_file = LABEL: 503
// send_Menu = LABEL: 563
// send_OK = LABEL: 556
// send_SF_byte = LABEL: 182
// send_SF_line = LABEL: 178
// send_SF_page = LABEL: 177
// send_Waiting_MCS_file = LABEL: 482
// send_address = LABEL: 766
// send_byte = LABEL: 715
// send_counter_timer = LABEL: 256
// send_data = LABEL: 782
// send_equals = LABEL: 779
// send_hex_3bytes = LABEL: 365
// send_hex_byte = LABEL: 359
// send_space = LABEL: 406
// send_to_UART = LABEL: 305
// send_welcome = LABEL: 409
// set_SF_read_array_mode = LABEL: 244
// spare1 = CONSTANT: 64
// status_port = CONSTANT: 0
// test_for_ten = LABEL: 312
// twochar_to_value = LABEL: 328
// tx_data_present = CONSTANT: 1
// tx_full = CONSTANT: 4
// tx_half_full = CONSTANT: 2
// upper_case = LABEL: 318
// wait_1ms = LABEL: 273
// wait_1s = LABEL: 283
// wait_1us = LABEL: 264
// wait_20ms = LABEL: 278
// wait_40us = LABEL: 268
// wait_MCS_line_Start = LABEL: 88
// wait_Rx_character = LABEL: 288
// wait_SF_loop = LABEL: 249
// wait_SF_ready = LABEL: 247
// wait_XON = LABEL: 297
// warm_start = LABEL: 5
// welcome_start = LABEL: 3
// write_buffer_loop = LABEL: 128
// write_command = LABEL: 140
// write_spm_data = LABEL: 82
/* Program Code */
// #1: ;KCPSM3 Program - UART programming of StrataFLASH memory on the Spartan-3E Starter Kit.
// #2: ;
// #3: ;Ken Chapman - Xilinx Ltd
// #4: ;
// #5: ;Version v1.00 - 28th March 2006
// #6: ;
// #7: ;This program uses a 115200 baud UART connection with XON/XOFF flow control
// #8: ;to allow a standard MCS file for the configuration of a Spartan-3E device to
// #9: ;be programmed into the Intel StrataFLASH device on the board.
// #10: ;
// #11: ;
// #12: ;
// #13: ;
// #14: ;**************************************************************************************
// #15: ; Port definitions
// #16: ;**************************************************************************************
// #17: ;
// #18: ;
// #19: CONSTANT(status_port,0) ;UART and filter status input
// #20: CONSTANT(tx_data_present,1) ; Transmitter data present - bit0
// #21: CONSTANT(tx_half_full,2) ; FIFO half full - bit1
// #22: CONSTANT(tx_full,4) ; full - bit2
// #23: CONSTANT(rx_data_present,8) ; data present - bit3
// #24: CONSTANT(rx_half_full,16) ; Receiver half full - bit4
// #25: CONSTANT(rx_full,32) ; FIFO full - bit5
// #26: CONSTANT(spare1,64) ; spare '0' - bit6
// #27: CONSTANT(SF_STS,128) ; StrataFLASH STS - bit7
// #28: ;
// #29: CONSTANT(UART_read_port,1) ;UART Rx data input
// #30: ;
// #31: CONSTANT(UART_write_port,4) ;UART Tx data output
// #32: ;
// #33: ;
// #34: CONSTANT(SF_data_in_port,2) ;Read data from StrataFLASH device
// #35: ;
// #36: CONSTANT(SF_data_out_port,16) ;Data to write into StrataFLASH device
// #37: ;
// #38: CONSTANT(SF_addr_hi_port,128) ;StrataFLASH address[23:16]
// #39: CONSTANT(SF_addr_mi_port,64) ;StrataFLASH address[15:8]
// #40: CONSTANT(SF_addr_lo_port,32) ;StrataFLASH address[7:0]
// #41: ;
// #42: CONSTANT(SF_control_port,8) ;StrataFLASH control
// #43: CONSTANT(SF_read,1) ; active High read - bit0
// #44: CONSTANT(SF_ce,2) ; active Low device enable - bit1
// #45: CONSTANT(SF_we,4) ; active Low write - bit2
// #46: ;
// #47: ;
// #48: ;
// #49: ;**************************************************************************************
// #50: ; Special Register usage
// #51: ;**************************************************************************************
// #52: ;
// #53: NAMEREG(sF,UART_data) ;used to pass data to and from the UART
// #54: ;
// #55: ;
// #56: ;**************************************************************************************
// #57: ; Useful data constants
// #58: ;**************************************************************************************
// #59: ;
// #60: ;Constant to define a software delay of 1us. This must be adjusted to reflect the
// #61: ;clock applied to KCPSM3. Every instruction executes in 2 clock cycles making the
// #62: ;calculation highly predictable. The '6' in the following equation even allows for
// #63: ;'CALL delay_1us' instruction in the initiating code.
// #64: ;
// #65: ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
// #66: ;
// #67: ;Example: For a 50MHz clock the constant value is (10-6)/4 = 11 (0B Hex).
// #68: ;For clock rates below 10MHz the value of 1 must be used and the operation will
// #69: ;become lower than intended.
// #70: ;
// #71: CONSTANT(delay_1us_constant,11)
// #72: ;
// #73: ;
// #74: ;
// #75: ;ASCII table
// #76: ;
// #77: CONSTANT(character_a,97)
// #78: CONSTANT(character_b,98)
// #79: CONSTANT(character_c,99)
// #80: CONSTANT(character_d,100)
// #81: CONSTANT(character_e,101)
// #82: CONSTANT(character_f,102)
// #83: CONSTANT(character_g,103)
// #84: CONSTANT(character_h,104)
// #85: CONSTANT(character_i,105)
// #86: CONSTANT(character_j,106)
// #87: CONSTANT(character_k,107)
// #88: CONSTANT(character_l,108)
// #89: CONSTANT(character_m,109)
// #90: CONSTANT(character_n,110)
// #91: CONSTANT(character_o,111)
// #92: CONSTANT(character_p,112)
// #93: CONSTANT(character_q,113)
// #94: CONSTANT(character_r,114)
// #95: CONSTANT(character_s,115)
// #96: CONSTANT(character_t,116)
// #97: CONSTANT(character_u,117)
// #98: CONSTANT(character_v,118)
// #99: CONSTANT(character_w,119)
// #100: CONSTANT(character_x,120)
// #101: CONSTANT(character_y,121)
// #102: CONSTANT(character_z,122)
// #103: CONSTANT(character_A,65)
// #104: CONSTANT(character_B,66)
// #105: CONSTANT(character_C,67)
// #106: CONSTANT(character_D,68)
// #107: CONSTANT(character_E,69)
// #108: CONSTANT(character_F,70)
// #109: CONSTANT(character_G,71)
// #110: CONSTANT(character_H,72)
// #111: CONSTANT(character_I,73)
// #112: CONSTANT(character_J,74)
// #113: CONSTANT(character_K,75)
// #114: CONSTANT(character_L,76)
// #115: CONSTANT(character_M,77)
// #116: CONSTANT(character_N,78)
// #117: CONSTANT(character_O,79)
// #118: CONSTANT(character_P,80)
// #119: CONSTANT(character_Q,81)
// #120: CONSTANT(character_R,82)
// #121: CONSTANT(character_S,83)
// #122: CONSTANT(character_T,84)
// #123: CONSTANT(character_U,85)
// #124: CONSTANT(character_V,86)
// #125: CONSTANT(character_W,87)
// #126: CONSTANT(character_X,88)
// #127: CONSTANT(character_Y,89)
// #128: CONSTANT(character_Z,90)
// #129: CONSTANT(character_0,48)
// #130: CONSTANT(character_1,49)
// #131: CONSTANT(character_2,50)
// #132: CONSTANT(character_3,51)
// #133: CONSTANT(character_4,52)
// #134: CONSTANT(character_5,53)
// #135: CONSTANT(character_6,54)
// #136: CONSTANT(character_7,55)
// #137: CONSTANT(character_8,56)
// #138: CONSTANT(character_9,57)
// #139: CONSTANT(character_colon,58)
// #140: CONSTANT(character_fullstop,46)
// #141: CONSTANT(character_semi_colon,59)
// #142: CONSTANT(character_minus,45)
// #143: CONSTANT(character_plus,43)
// #144: CONSTANT(character_comma,44)
// #145: CONSTANT(character_less_than,60) ;'<'
// #146: CONSTANT(character_greater_than,62) ;'>'
// #147: CONSTANT(character_open,40) ;'('
// #148: CONSTANT(character_close,41) ;')'
// #149: CONSTANT(character_divide,47) ;'/'
// #150: CONSTANT(character_equals,61)
// #151: CONSTANT(character_space,32)
// #152: CONSTANT(character_CR,13) ;carriage return
// #153: CONSTANT(character_LF,10) ;line feed
// #154: CONSTANT(character_question,63) ;'?'
// #155: CONSTANT(character_dollar,36)
// #156: CONSTANT(character_exclaim,33) ;'!'
// #157: CONSTANT(character_BS,8) ;Back Space command character
// #158: CONSTANT(character_XON,17) ;Flow control ON
// #159: CONSTANT(character_XOFF,19) ;Flow control OFF
// #160: ;
// #161: ;
// #162: ;**************************************************************************************
// #163: ; Scratch Pad Memory Locations
// #164: ;**************************************************************************************
// #165: ;
// #166: CONSTANT(ISR_preserve_s0,0) ;preserve register during ISR
// #167: ;
// #168: ;
// #169: ;
// #170: ;Store up to one line of an MCS file as bytes
// #171: ;A typical data line consists of:-
// #172: ;: Start character which is not stored
// #173: ;10 Number of data bytes included (16 in this case)
// #174: ;aaaa Lower 16-bits of the storage address
// #175: ;00 Record type (data in this case)
// #176: ;dddd... Data bytes (typically 16 which is the maximum)
// #177: ;cc Checksum
// #178: ;CR/LF Line will end in carriage return and/or line feed which is not stored.
// #179: ;
// #180: ;So a total of 21 bytes could be stored before processing.
// #181: ;This is located at the end of scratch pad memory.
// #182: ;
// #183: CONSTANT(line_start,43) ;21 bytes until end of memory
// #184: CONSTANT(data_start,47) ;Start of data field if present
// #185: ;
// #186: ;
// #187: ;**************************************************************************************
// #188: ; Initialise the system and welcome message
// #189: ;**************************************************************************************
// #190: ;
// @000 #191: [cold_start]
30027 // @000 #191: CALL(SF_init) ;initialise StrataFLASH controls
3011a // @001 #192: CALL(delay_1s) ;delay because UART is fast and JTAG startup sequence can be slow
3c001 // @002 #193: ENABLE(INTERRUPT) ;Interrupt is used for XON/XOFF flow control
// @003 #194: [welcome_start]
30193 // @003 #194: CALL(send_CR)
30199 // @004 #195: CALL(send_welcome) ;start up message and version number
// #196: ;
// #197: ;
// #198: ;**************************************************************************************
// #199: ; Main menu and command selection
// #200: ;**************************************************************************************
// #201: ;
// #202: ;
// @005 #203: [warm_start]
30233 // @005 #203: CALL(send_Menu) ;Menu and command selection
30193 // @006 #204: CALL(send_CR)
// #205: ;
// @007 #206: [prompt]
30193 // @007 #206: CALL(send_CR)
30193 // @008 #207: CALL(send_CR)
00f3e // @009 #208: LOAD(UART_data,character_greater_than) ;prompt for input
30131 // @00a #209: CALL(send_to_UART)
30022 // @00b #210: CALL(read_upper_case)
14045 // @00c #211: COMPARE(s0,character_E) ;test for commands and execute as required
3502a // @00d #212: JUMP(Z,erase_command)
14042 // @00e #213: COMPARE(s0,character_B)
3502c // @00f #214: JUMP(Z,block_erase_command)
14050 // @010 #215: COMPARE(s0,character_P)
35047 // @011 #216: JUMP(Z,program_command)
14057 // @012 #217: COMPARE(s0,character_W)
3508c // @013 #218: JUMP(Z,write_command)
14052 // @014 #219: COMPARE(s0,character_R)
350a3 // @015 #220: JUMP(Z,read_command)
14049 // @016 #221: COMPARE(s0,character_I)
350c2 // @017 #222: JUMP(Z,SF_information)
14048 // @018 #223: COMPARE(s0,character_H)
35003 // @019 #224: JUMP(Z,welcome_start)
14053 // @01a #225: COMPARE(s0,character_S)
350d5 // @01b #226: JUMP(Z,SF_status)
30193 // @01c #227: CALL(send_CR) ;no valid command input
00f3f // @01d #228: LOAD(UART_data,character_question) ;display ???
30131 // @01e #229: CALL(send_to_UART)
30131 // @01f #230: CALL(send_to_UART)
30131 // @020 #231: CALL(send_to_UART)
34007 // @021 #232: JUMP(prompt) ;Try again!
// #233: ;
// #234: ;
// @022 #235: [read_upper_case]
3011f // @022 #235: CALL(read_from_UART) ;read command character from UART
30131 // @023 #236: CALL(send_to_UART) ;echo character
010f0 // @024 #237: LOAD(s0,UART_data) ;convert to upper case
3013e // @025 #238: CALL(upper_case)
2a000 // @026 #239: RETURN
// #240: ;
// #241: ;
// #242: ;**************************************************************************************
// #243: ; Initialise the StrataFlash Memory control signals.
// #244: ;**************************************************************************************
// #245: ;
// #246: ; SF_read = 0 - Output enable off
// #247: ; SF_ce = 1 - Deselect StrataFLASH memory
// #248: ; SF_we = 1 - Write enable off
// #249: ;
// #250: ; Register used s0
// #251: ;
// @027 #252: [SF_init]
00006 // @027 #252: LOAD(s0,6)
2c008 // @028 #253: OUTPUT(s0,SF_control_port)
2a000 // @029 #254: RETURN
// #255: ;
// #256: ;
// #257: ;**************************************************************************************
// #258: ; Erase Command - Perform bulk erase of the StrataFLASH memory
// #259: ;**************************************************************************************
// #260: ;
// #261: ; This routine executes the block erase command 128 times with a different base
// #262: ; address in each case.
// #263: ;
// #264: ; Note that this could take as long as 8 minutes 30 seconds
// #265: ; and even typical times will be approximately 2 minutes.
// #266: ;
// #267: ; Registers used s1,s7,s8,s9
// #268: ;
// @02a #269: [erase_command]
009fe // @02a #269: LOAD(s9,FE) ;define base address of block 127 = FE0000
3402d // @02b #270: JUMP(blocks_erase)
// #271: ;
// #272: ;
// #273: ;**************************************************************************************
// #274: ; Block Erase Command - Performs erase of lowest 3 blocks of StrataFLASH memory which
// #275: ; covers the address range 000000 to 05FFFF in which the configuration for an XC3S500E
// #276: ; would be able to fit (000000 to 045470).
// #277: ;**************************************************************************************
// #278: ;
// #279: ; This routine executes the block erase command 3 times with a different base
// #280: ; address in each case.
// #281: ;
// #282: ; Each block is 128K bytes and therefore has an address range of 000000 to 01FFFF.
// #283: ; So each block is separated by 020000 hex.
// #284: ;
// #285: ; Registers used s0,s1,s7,s8,s9
// #286: ;
// @02c #287: [block_erase_command]
00904 // @02c #287: LOAD(s9,4) ;define base address of block 3 = 040000
// @02d #288: [blocks_erase]
30193 // @02d #288: CALL(send_CR)
302d4 // @02e #289: CALL(send_Confirm) ;confirm command with a 'Y' which must be upper case
3011f // @02f #290: CALL(read_from_UART) ;read command character from UART
30131 // @030 #291: CALL(send_to_UART) ;echo input
14f59 // @031 #292: COMPARE(UART_data,character_Y)
3543f // @032 #293: JUMP(NZ,abort_erase)
30193 // @033 #294: CALL(send_CR)
30209 // @034 #295: CALL(send_Erase_in_progress)
30193 // @035 #296: CALL(send_CR)
00800 // @036 #297: LOAD(s8,0) ;define lower address of each block = xx0000
00700 // @037 #298: LOAD(s7,0)
// @038 #299: [blocks_erase_loop]
00f2e // @038 #299: LOAD(UART_data,character_fullstop) ;progress dots
30131 // @039 #300: CALL(send_to_UART)
30041 // @03a #301: CALL(SF_erase_block) ;erase block
1c902 // @03b #302: SUB(s9,2) ;decrement base address by 1 block
35c38 // @03c #303: JUMP(NC,blocks_erase_loop) ;repeat until block 0 is erased
3022c // @03d #304: CALL(send_OK)
34007 // @03e #305: JUMP(prompt)
// #306: ;
// @03f #307: [abort_erase]
302f1 // @03f #307: CALL(send_Abort)
34007 // @040 #308: JUMP(prompt)
// #309: ;
// #310: ;
// #311: ;**************************************************************************************
// #312: ; Erase a single 128K Byte block of the StrataFlash Memory
// #313: ;**************************************************************************************
// #314: ;
// #315: ; The 24-bit address of the block should be supplied in register set [s9,s8,s7].
// #316: ;
// #317: ; To erase a block the address must be set and then the block erase command (20 hex)
// #318: ; written to the memory followed by the write confirm command (D0 hex).
// #319: ;
// #320: ; The act of erasing a block may take up to 1 second to complete. This routine
// #321: ; waits for the memory to be ready before restoring the normal read array mode and
// #322: ; returning.
// #323: ;
// #324: ; Registers used s1,s7,s8,s9
// #325: ;
// @041 #326: [SF_erase_block]
00120 // @041 #326: LOAD(s1,32) ;block erase command
300ea // @042 #327: CALL(SF_byte_write)
001d0 // @043 #328: LOAD(s1,D0) ;write confirm command
300ea // @044 #329: CALL(SF_byte_write)
300f7 // @045 #330: CALL(wait_SF_ready) ;wait for erase to complete
2a000 // @046 #331: RETURN
// #332: ;
// #333: ;
// #334: ;**************************************************************************************
// #335: ; Program Command - Program StrataFLASH memory with data defined in an MCS file
// #336: ;**************************************************************************************
// #337: ;
// @047 #338: [program_command]
30193 // @047 #338: CALL(send_CR)
301e2 // @048 #339: CALL(send_Waiting_MCS_file)
3004c // @049 #340: CALL(program_MCS)
3022c // @04a #341: CALL(send_OK)
34007 // @04b #342: JUMP(prompt)
// #343: ;
// #344: ;**************************************************************************************
// #345: ; Program StrataFLASH memory with data defined in an MCS file
// #346: ;**************************************************************************************
// #347: ;
// #348: ;Reads the MCS file from the UART and programs the Strata FLASH device at the locations.
// #349: ;specified by the file contents.
// #350: ;
// #351: ;This routine will continue until an end of file record is detected.
// #352: ;For each line of MCS received, the current address will be output so that
// #353: ;progress can be monitored.
// #354: ;
// #355: ;
// @04c #356: [program_MCS]
30057 // @04c #356: CALL(read_MCS_line) ;read line from UART
30067 // @04d #357: CALL(MCS_address) ;find start address and record type
14b01 // @04e #358: COMPARE(sB,1) ;test for end record
2b000 // @04f #359: RETURN(Z) ;end of programming
14b04 // @050 #360: COMPARE(sB,4) ;test for extended address record
3504c // @051 #361: JUMP(Z,program_MCS) ;no data with this record and upper address now correct
// #362: ;
// #363: ;Assume data record type 00 which is data so need to program specified number
// #364: ;of bytes into memory at correct address.
// #365: ;
// @052 #366: [write_spm_data]
3016d // @052 #366: CALL(send_hex_3bytes) ;send address to indicate progress
30193 // @053 #367: CALL(send_CR)
06a2b // @054 #368: FETCH(sA,line_start) ;read number of data bytes to program
30077 // @055 #369: CALL(SF_buffer_write) ;write bytes to memory
3404c // @056 #370: JUMP(program_MCS)
// #371: ;
// #372: ;
// #373: ;**************************************************************************************
// #374: ;Read one line of an MCS file into scratch pad memory
// #375: ;**************************************************************************************
// #376: ;
// #377: ;Reads one line of MCS file format into scratch pad memory starting at location 'line_start'.
// #378: ;
// #379: ;The routine detects the line start character ':' ignoring any preceding characters. This
// #380: ;will remove any additional CR or LF characters.
// #381: ;
// #382: ;It then reads each subsequent pair of ASCII characters, converts them to true hex in the
// #383: ;range 00 to FF and stores them in scratch pad memory.
// #384: ;
// #385: ;The end of the line is determined by either a CR or LF character.
// #386: ;
// #387: ;The value last returned in register 'sE' will be the pointer to the location in
// #388: ;scratch pad memory following the last byte for the line read.
// #389: ;
// @057 #390: [read_MCS_line]
00e2b // @057 #390: LOAD(sE,line_start) ;initialise SPM memory pointer
// @058 #391: [wait_MCS_line_Start]
3011f // @058 #391: CALL(read_from_UART) ;read character
14f3a // @059 #392: COMPARE(UART_data,character_colon) ;test for start character
35458 // @05a #393: JUMP(NZ,wait_MCS_line_Start)
// @05b #394: [read_MCS_byte]
3011f // @05b #394: CALL(read_from_UART) ;read character
14f0d // @05c #395: COMPARE(UART_data,character_CR) ;test for end of line
2b000 // @05d #396: RETURN(Z)
14f0a // @05e #397: COMPARE(UART_data,character_LF) ;test for end of line
2b000 // @05f #398: RETURN(Z)
013f0 // @060 #399: LOAD(s3,UART_data) ;upper nibble character
3011f // @061 #400: CALL(read_from_UART) ;read character
012f0 // @062 #401: LOAD(s2,UART_data) ;lower nibble character
30174 // @063 #402: CALL(ASCII_byte_to_hex) ;convert to true hex value
2f0e0 // @064 #403: STORE(s0,sE) ;write to SPM
18e01 // @065 #404: ADD(sE,1) ;increment pointer
3405b // @066 #405: JUMP(read_MCS_byte)
// #406: ;
// #407: ;
// #408: ;**************************************************************************************
// #409: ;Determine the current address for the line of an MCS file in scratch pad memory
// #410: ;**************************************************************************************
// #411: ;
// #412: ;Checks the existing line data stored in scratch pad memory starting at location
// #413: ;'line_start' and determines the current address.
// #414: ;
// #415: ;The address is in the register set [s9,s8,s7] before and after this routine is
// #416: ;executed because not all address bits are defined by a given line of MCS and
// #417: ;the undefined bits remain constant.
// #418: ;
// #419: ;A record type of 04 will update [s9].
// #420: ;A record type of 00 will update [s8,s7].
// #421: ;
// #422: ;On return, the register sB will contain the record type and
// #423: ;register sC will indicate the number of data bytes stored.
// #424: ;
// @067 #425: [MCS_address]
00d2b // @067 #425: LOAD(sD,line_start) ;initialise SPM memory pointer
07cd0 // @068 #426: FETCH(sC,sD) ;read number of bytes on line
18d03 // @069 #427: ADD(sD,3) ;move to record type
07bd0 // @06a #428: FETCH(sB,sD) ;read record type
14b00 // @06b #429: COMPARE(sB,0) ;test for data record
35072 // @06c #430: JUMP(Z,new_low_address)
14b04 // @06d #431: COMPARE(sB,4) ;test for data record
2b400 // @06e #432: RETURN(NZ)
18d02 // @06f #433: ADD(sD,2) ;read upper 8-bits
079d0 // @070 #434: FETCH(s9,sD)
2a000 // @071 #435: RETURN
// @072 #436: [new_low_address]
1cd01 // @072 #436: SUB(sD,1) ;read lower 8-bits
077d0 // @073 #437: FETCH(s7,sD)
1cd01 // @074 #438: SUB(sD,1) ;read middle 8-bits
078d0 // @075 #439: FETCH(s8,sD)
2a000 // @076 #440: RETURN
// #441: ;
// #442: ;
// #443: ;**************************************************************************************
// #444: ; Write to Buffer of StrataFlash Memory and program
// #445: ;**************************************************************************************
// #446: ;
// #447: ; Writing to the buffer allows faster operation than writing individual bytes.
// #448: ; The buffer size is limited to 32 locations. To perform a buffer write the process
// #449: ; is as follows:-
// #450: ; Write command for buffer write to StrataFLASH memory (E8 hex).
// #451: ; Base address for writing should also be set.
// #452: ; Read Status register and if not ready repeat command until it is.
// #453: ; Write a value specifying the number of bytes to be written LESS ONE.
// #454: ; In this program the number of bytes will be specified in register sA
// #455: ; and this value needs to be decremented before writing to the memory.
// #456: ; Write the correct number of actual data bytes with appropriate addresses.
// #457: ; Ideally the addresses do not cross the boundary of 32 locations
// #458: ; such that LSBs are always in the range 00000 to 11111 binary.
// #459: ; Crossing the boundary is OK but will take longer to program.
// #460: ; Write command to confirm operation (D0 hex).
// #461: ; Read Status register and wait for ready.
// #462: ;
// #463: ; This routine additionally restores the normal read array mode before returning.
// #464: ;
// #465: ; The number of bytes to be written should be supplied in register sA and must be
// #466: ; a value between 1 and 32 (01 and 20 hex).
// #467: ;
// #468: ; The 24-bit base address should be supplied in register set [s9,s8,s7].
// #469: ; On return, this will be increased by the number of locations written.
// #470: ;
// #471: ; Scratch pad memory locations starting at location defined by constant
// #472: ; 'data_start' should contain the data bytes to be written.
// #473: ;
// #474: ; The act of writing the buffer to the memory array may take up to 654us to complete.
// #475: ; The time taken to program is recorded by register pair [sE,sD]. Each count
// #476: ; equates to 15 instructions which is equivalent to 30 clock cycles (600ns at 50MHz).
// #477: ;
// #478: ; Registers used s0,s1,s7,s8,s9,sA,sD,sE
// #479: ;
// #480: ;
// @077 #481: [SF_buffer_write]
001e8 // @077 #481: LOAD(s1,E8) ;command for buffer write
300ea // @078 #482: CALL(SF_byte_write)
300e0 // @079 #483: CALL(SF_byte_read) ;read status register into s0
12080 // @07a #484: TEST(s0,128) ;test ready/busy flag
35077 // @07b #485: JUMP(Z,SF_buffer_write) ;repeat command until ready
011a0 // @07c #486: LOAD(s1,sA) ;Specify number of bytes to write
1c101 // @07d #487: SUB(s1,1) ;one less than actual number!
300ea // @07e #488: CALL(SF_byte_write)
0032f // @07f #489: LOAD(s3,data_start) ;point to data in scratch pad memory
// @080 #490: [write_buffer_loop]
07130 // @080 #490: FETCH(s1,s3) ;fetch data
300ea // @081 #491: CALL(SF_byte_write) ;write to buffer
18701 // @082 #492: ADD(s7,1) ;increment address
1a800 // @083 #493: ADDCY(s8,0)
1a900 // @084 #494: ADDCY(s9,0)
18301 // @085 #495: ADD(s3,1) ;increment SPM pointer
1ca01 // @086 #496: SUB(sA,1) ;count bytes remaining
35480 // @087 #497: JUMP(NZ,write_buffer_loop)
001d0 // @088 #498: LOAD(s1,D0) ;command to confirm write
300ea // @089 #499: CALL(SF_byte_write)
300f7 // @08a #500: CALL(wait_SF_ready) ;wait for program to complete and set read array mode
2a000 // @08b #501: RETURN
// #502: ;
// #503: ;
// #504: ;**************************************************************************************
// #505: ; Write Command - Write one byte to specified address
// #506: ;**************************************************************************************
// #507: ;
// @08c #508: [write_command]
302fe // @08c #508: CALL(send_address) ;obtain 24-bit address 000000 to FFFFFF
3018d // @08d #509: CALL(obtain_8bits)
3588c // @08e #510: JUMP(C,write_command) ;bad input address
01900 // @08f #511: LOAD(s9,s0)
3018d // @090 #512: CALL(obtain_8bits)
3588c // @091 #513: JUMP(C,write_command) ;bad input address
01800 // @092 #514: LOAD(s8,s0)
3018d // @093 #515: CALL(obtain_8bits)
3588c // @094 #516: JUMP(C,write_command) ;bad input address
01700 // @095 #517: LOAD(s7,s0)
// @096 #518: [get_data]
3030e // @096 #518: CALL(send_data) ;obtain 8-bit data 00 to FF into s0
3018d // @097 #519: CALL(obtain_8bits)
35896 // @098 #520: JUMP(C,get_data) ;bad input data
3009d // @099 #521: CALL(SF_single_byte_write)
30193 // @09a #522: CALL(send_CR)
3022c // @09b #523: CALL(send_OK)
34007 // @09c #524: JUMP(prompt)
// #525: ;
// #526: ;
// #527: ;**************************************************************************************
// #528: ; Write a single byte to StrataFlash Memory
// #529: ;**************************************************************************************
// #530: ;
// #531: ; To write a single byte to StrataFLASH memory the address must be set and the
// #532: ; single-word/byte program command (40 hex) sent to the memory. Then the data byte can
// #533: ; be written to the memory using the same address.
// #534: ;
// #535: ; The 24-bit address should be supplied in register set [s9,s8,s7].
// #536: ; Register s0 should contain the byte data to be written to the memory.
// #537: ;
// #538: ; The act of writing the memory array may take up to 175us to complete. This routine
// #539: ; waits for the memory to be ready before restoring the normal read array mode and
// #540: ; returning. The time taken to program is recorded by register pair [sE,sD]. Each count
// #541: ; equates to 15 instructions which is equivalent to 30 clock cycles (600ns at 50MHz).
// #542: ;
// #543: ; Registers used s0,s1,s7,s8,s9,sD,sE (s7,s8,s9 not changed)
// #544: ;
// #545: ; Registers used s0,s1,s7,s8,s9
// #546: ;
// @09d #547: [SF_single_byte_write]
00140 // @09d #547: LOAD(s1,64) ;command for single byte program
300ea // @09e #548: CALL(SF_byte_write)
01100 // @09f #549: LOAD(s1,s0) ;write data to be programmed
300ea // @0a0 #550: CALL(SF_byte_write)
300f7 // @0a1 #551: CALL(wait_SF_ready) ;wait for program to complete
2a000 // @0a2 #552: RETURN
// #553: ;
// #554: ;
// #555: ;**************************************************************************************
// #556: ;Read Command - Read one page of memory at specified address
// #557: ;**************************************************************************************
// #558: ;
// @0a3 #559: [read_command]
302fe // @0a3 #559: CALL(send_address) ;obtain 24-bit address 000000 to FFFFFF
3018d // @0a4 #560: CALL(obtain_8bits) ;read value from UART
358a3 // @0a5 #561: JUMP(C,read_command) ;bad input address
01900 // @0a6 #562: LOAD(s9,s0)
3018d // @0a7 #563: CALL(obtain_8bits)
358a3 // @0a8 #564: JUMP(C,read_command) ;bad input address
01800 // @0a9 #565: LOAD(s8,s0)
3018d // @0aa #566: CALL(obtain_8bits)
358a3 // @0ab #567: JUMP(C,read_command) ;bad input address
01700 // @0ac #568: LOAD(s7,s0)
30193 // @0ad #569: CALL(send_CR)
300b1 // @0ae #570: CALL(send_SF_page)
3022c // @0af #571: CALL(send_OK)
34007 // @0b0 #572: JUMP(prompt)
// #573: ;
// #574: ;The start address should be provided in register set [s9,s8,s7].
// #575: ;The display will be next 256 bytes displayed as 16 lines of 16 bytes
// #576: ;with each line commencing with the address of the first byte.
// #577: ;
// @0b1 #578: [send_SF_page]
00610 // @0b1 #578: LOAD(s6,16) ;16 lines to display
// @0b2 #579: [send_SF_line]
30193 // @0b2 #579: CALL(send_CR)
3016d // @0b3 #580: CALL(send_hex_3bytes) ;display address
30196 // @0b4 #581: CALL(send_space)
00510 // @0b5 #582: LOAD(s5,16) ;16 bytes to display on a line
// @0b6 #583: [send_SF_byte]
30196 // @0b6 #583: CALL(send_space)
300e0 // @0b7 #584: CALL(SF_byte_read) ;read byte into s0
18701 // @0b8 #585: ADD(s7,1) ;increment StrataFLASH address
1a800 // @0b9 #586: ADDCY(s8,0)
1a900 // @0ba #587: ADDCY(s9,0)
30167 // @0bb #588: CALL(send_hex_byte) ;display byte
1c501 // @0bc #589: SUB(s5,1) ;count bytes per line
354b6 // @0bd #590: JUMP(NZ,send_SF_byte)
1c601 // @0be #591: SUB(s6,1) ;count lines
354b2 // @0bf #592: JUMP(NZ,send_SF_line)
30193 // @0c0 #593: CALL(send_CR)
2a000 // @0c1 #594: RETURN
// #595: ;
// #596: ;
// #597: ;**************************************************************************************
// #598: ; ID Command - Read and display the device information for the StrataFLASH FLASH memory
// #599: ;**************************************************************************************
// #600: ;
// #601: ; Normal response should be
// #602: ; Device Manufacturer Code (Intel) = 89 hex
// #603: ; Memory ID code for 128Mbit = 18 hex
// #604: ;
// #605: ; To read the device information the Read device information command (90)
// #606: ; must be written to the memory. The information is read back but assumes
// #607: ; that 16-bit words are being used and hence address bit0 is not really used.
// #608: ; hence addresses 000000 and 0000001 both return the Device Manufacturer Code and
// #609: ; addresses 000002 and 0000003 both return the Memory ID code.
// #610: ;
// #611: ; After reading the device information the read array command is written to the
// #612: ; device to put it back to normal read mode.
// #613: ;
// #614: ; Registers used s0,s7,s8,s9
// #615: ;
// @0c2 #616: [SF_information]
30193 // @0c2 #616: CALL(send_CR) ;send 'ID=' to terminal
302c6 // @0c3 #617: CALL(send_ID)
00f3d // @0c4 #618: LOAD(UART_data,character_equals)
30131 // @0c5 #619: CALL(send_to_UART)
30196 // @0c6 #620: CALL(send_space)
00900 // @0c7 #621: LOAD(s9,0) ;define base address 000000
00800 // @0c8 #622: LOAD(s8,0)
00700 // @0c9 #623: LOAD(s7,0)
00190 // @0ca #624: LOAD(s1,144) ;command to read device information
300ea // @0cb #625: CALL(SF_byte_write)
300e0 // @0cc #626: CALL(SF_byte_read) ;read Device Manufacturer Code into s0
30167 // @0cd #627: CALL(send_hex_byte) ;display byte
30196 // @0ce #628: CALL(send_space)
00702 // @0cf #629: LOAD(s7,2) ;change address
300e0 // @0d0 #630: CALL(SF_byte_read) ;read Memory ID code into s0
30167 // @0d1 #631: CALL(send_hex_byte) ;display byte
30193 // @0d2 #632: CALL(send_CR)
300f4 // @0d3 #633: CALL(set_SF_read_array_mode) ;restore normal read array mode
34007 // @0d4 #634: JUMP(prompt)
// #635: ;
// #636: ;
// #637: ;**************************************************************************************
// #638: ; Read StrataFLASH status register
// #639: ;**************************************************************************************
// #640: ;
// #641: ; The main reason for reading the status register is to determine when the memory
// #642: ; is ready or busy. This information is provided by bit7 (0=busy and 1=ready).
// #643: ;
// #644: ; The lower bits all indicate errors of some kind and therefore the only desirable
// #645: ; response is 00 hex or 80 hex. In this program, no error checking or clearing
// #646: ; is performed and the way this routine is executed from the menu only 80 hex is
// #647: ; expected.
// #648: ;
// #649: ; To read the status register the read status register command must be written to
// #650: ; the device. All subsequent reads are then result in the return of the status
// #651: ; register. A different read command must be written to the device to stop this
// #652: ; mode.
// #653: ;
// #654: ; This mode is also entered automatically when performing program and erase operations.
// #655: ;
// @0d5 #656: [SF_status]
00900 // @0d5 #656: LOAD(s9,0) ;define base address 000000
00800 // @0d6 #657: LOAD(s8,0)
00700 // @0d7 #658: LOAD(s7,0)
00170 // @0d8 #659: LOAD(s1,112) ;command to read status register
300ea // @0d9 #660: CALL(SF_byte_write)
30193 // @0da #661: CALL(send_CR)
300e0 // @0db #662: CALL(SF_byte_read) ;read status register into s0
30167 // @0dc #663: CALL(send_hex_byte) ;display byte
30193 // @0dd #664: CALL(send_CR)
300f4 // @0de #665: CALL(set_SF_read_array_mode)
34007 // @0df #666: JUMP(prompt)
// #667: ;
// #668: ;
// #669: ;**************************************************************************************
// #670: ; Read a byte from StrataFlash Memory
// #671: ;**************************************************************************************
// #672: ;
// #673: ; The 24-bit address should be supplied in register set [s9,s8,s7].
// #674: ; Register s0 will return the byte data retrieved from the memory.
// #675: ;
// #676: ; To read a byte, the address needs to be set up on the address lines
// #677: ; and the controls set as follows
// #678: ; SF_read = 1 - disable Spartan data outputs and enable StrataFlash outputs (OE=0)
// #679: ; SF_ce = 0 - enable StrataFLASH memory
// #680: ; SF_we = 1 - Write enable off
// #681: ;
// #682: ; The access time of the memory is 75ns. This is equivalent to 3.75 clock cycles at
// #683: ; 50MHz. Since each KCPSM3 instruction takes 2 clock cycles to execute, two instructions
// #684: ; provides adequate delay for the memory to be accessed.
// #685: ;
// #686: ; Registers used s0,s1,s7,s8,s9
// #687: ;
// @0e0 #688: [SF_byte_read]
2c980 // @0e0 #688: OUTPUT(s9,SF_addr_hi_port) ;set 24-bit address
2c840 // @0e1 #689: OUTPUT(s8,SF_addr_mi_port)
2c720 // @0e2 #690: OUTPUT(s7,SF_addr_lo_port)
00105 // @0e3 #691: LOAD(s1,5) ;set controls
2c108 // @0e4 #692: OUTPUT(s1,SF_control_port)
00106 // @0e5 #693: LOAD(s1,6) ;>75ns delay
00106 // @0e6 #694: LOAD(s1,6) ;but do something useful!
04002 // @0e7 #695: INPUT(s0,SF_data_in_port) ;read data byte
2c108 // @0e8 #696: OUTPUT(s1,SF_control_port) ;clear controls
2a000 // @0e9 #697: RETURN
// #698: ;
// #699: ;
// #700: ;**************************************************************************************
// #701: ; Write data or command byte to StrataFlash Memory
// #702: ;**************************************************************************************
// #703: ;
// #704: ; The 24-bit address should be supplied in register set [s9,s8,s7].
// #705: ; Register s1 should contain the byte to be written to the memory.
// #706: ;
// #707: ; To write a byte, the address needs to be set up on the address lines
// #708: ; and the controls set as follows
// #709: ; SF_read = 0 - enable Spartan data outputs and disable StrataFlash outputs (OE=1)
// #710: ; SF_ce = 0 - enable StrataFLASH memory
// #711: ; SF_we = 0 - Write enable on
// #712: ;
// #713: ; The setup time of the memory is 60ns. This is equivalent to 3 clock cycles at
// #714: ; 50MHz. Since each KCPSM3 instruction takes 2 clock cycles to execute, two instructions
// #715: ; provides adequate delay for the memory.
// #716: ;
// #717: ; Registers used s1,s7,s8,s9
// #718: ;
// @0ea #719: [SF_byte_write]
2c980 // @0ea #719: OUTPUT(s9,SF_addr_hi_port) ;set 24-bit address
2c840 // @0eb #720: OUTPUT(s8,SF_addr_mi_port)
2c720 // @0ec #721: OUTPUT(s7,SF_addr_lo_port)
2c110 // @0ed #722: OUTPUT(s1,SF_data_out_port) ;set data byte to be written
00100 // @0ee #723: LOAD(s1,0) ;set controls
2c108 // @0ef #724: OUTPUT(s1,SF_control_port)
00106 // @0f0 #725: LOAD(s1,6) ;>60ns delay
00106 // @0f1 #726: LOAD(s1,6) ;but do something useful!
2c108 // @0f2 #727: OUTPUT(s1,SF_control_port) ;clear controls
2a000 // @0f3 #728: RETURN
// #729: ;
// #730: ;
// #731: ;**************************************************************************************
// #732: ; Set 'Read Array' mode on StrataFLASH
// #733: ;**************************************************************************************
// #734: ;
// #735: ; The read array mode is the default mode of the memory and allows the contents
// #736: ; of the memory to be read based on the supplied address.
// #737: ;
// #738: ; Read array is the default mode of the device, but it must also be placed back
// #739: ; into this mode after programming, erasing or reading the status register.
// #740: ;
// #741: ; The read array command (FF hex) is written to the Strata flash memory.
// #742: ;
// #743: ; Registers used s1,s7,s8,s9
// #744: ;
// @0f4 #745: [set_SF_read_array_mode]
001ff // @0f4 #745: LOAD(s1,FF) ;command to read array
300ea // @0f5 #746: CALL(SF_byte_write)
2a000 // @0f6 #747: RETURN
// #748: ;
// #749: ;
// #750: ;**************************************************************************************
// #751: ; Wait for StrataFLASH to be ready
// #752: ;**************************************************************************************
// #753: ;
// #754: ; This routine will typically be used after instigating a program or erase
// #755: ; command. It continuously reads the StrataFLASH status register and tests the
// #756: ; information provided by bit7 which indicates if the memory is busy(0) or ready(1).
// #757: ; The routine waits for the ready condition before sending a read array command
// #758: ; which puts the memory back to normal read mode.
// #759: ;
// #760: ; During the polling process, a counter formed by register pair [sE,sD] records
// #761: ; approximately how long the memory is busy. This can be used to evaluate programming
// #762: ; and erase times if required. The timing loop is 15 instructions which is equivalent
// #763: ; to 30 clock cycles (600ns at 50MHz)
// #764: ;
// #765: ; Registers used s0,s1,s7,s8,s9,sD,sE (s7,s8,s9 not changed)
// #766: ;
// #767: ;
// @0f7 #768: [wait_SF_ready]
00e00 // @0f7 #768: LOAD(sE,0) ;clear 16-bit counter timer
00d00 // @0f8 #769: LOAD(sD,0)
// @0f9 #770: [wait_SF_loop]
18d01 // @0f9 #770: ADD(sD,1) ;increment counter timer
1ae00 // @0fa #771: ADDCY(sE,0)
300e0 // @0fb #772: CALL(SF_byte_read) ;read status register into s0
12080 // @0fc #773: TEST(s0,128) ;test ready/busy flag
350f9 // @0fd #774: JUMP(Z,wait_SF_loop)
300f4 // @0fe #775: CALL(set_SF_read_array_mode) ;restore normal read array mode
2a000 // @0ff #776: RETURN
// #777: ;
// #778: ;
// #779: ;**************************************************************************************
// #780: ; Send 16-bit value in register pair [sE,sD] to UART
// #781: ;**************************************************************************************
// #782: ;
// #783: ; In this program the register pair [sE,sD] indicates the programming time of the
// #784: ; StrataFLASH memory in 600ns increments. This routine can be used to display that
// #785: ; value if required.
// #786: ;
// @100 #787: [send_counter_timer]
30193 // @100 #787: CALL(send_CR)
010e0 // @101 #788: LOAD(s0,sE)
30167 // @102 #789: CALL(send_hex_byte)
010d0 // @103 #790: LOAD(s0,sD)
30167 // @104 #791: CALL(send_hex_byte)
30193 // @105 #792: CALL(send_CR)
2a000 // @106 #793: RETURN
// #794: ;
// #795: ;
// #796: ;**************************************************************************************
// #797: ;Software delay routines
// #798: ;**************************************************************************************
// #799: ;
// #800: ;Delay of 1us.
// #801: ;
// #802: ;Constant value defines reflects the clock applied to KCPSM3. Every instruction
// #803: ;executes in 2 clock cycles making the calculation highly predictable. The '6' in
// #804: ;the following equation even allows for 'CALL delay_1us' instruction in the initiating code.
// #805: ;
// #806: ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
// #807: ;
// #808: ;Registers used s0
// #809: ;
// @107 #810: [delay_1us]
0000b // @107 #810: LOAD(s0,delay_1us_constant)
// @108 #811: [wait_1us]
1c001 // @108 #811: SUB(s0,1)
35508 // @109 #812: JUMP(NZ,wait_1us)
2a000 // @10a #813: RETURN
// #814: ;
// #815: ;Delay of 40us.
// #816: ;
// #817: ;Registers used s0, s1
// #818: ;
// @10b #819: [delay_40us]
00128 // @10b #819: LOAD(s1,40) ;40 x 1us = 40us
// @10c #820: [wait_40us]
30107 // @10c #820: CALL(delay_1us)
1c101 // @10d #821: SUB(s1,1)
3550c // @10e #822: JUMP(NZ,wait_40us)
2a000 // @10f #823: RETURN
// #824: ;
// #825: ;
// #826: ;Delay of 1ms.
// #827: ;
// #828: ;Registers used s0, s1, s2
// #829: ;
// @110 #830: [delay_1ms]
00219 // @110 #830: LOAD(s2,25) ;25 x 40us = 1ms
// @111 #831: [wait_1ms]
3010b // @111 #831: CALL(delay_40us)
1c201 // @112 #832: SUB(s2,1)
35511 // @113 #833: JUMP(NZ,wait_1ms)
2a000 // @114 #834: RETURN
// #835: ;
// #836: ;Delay of 20ms.
// #837: ;
// #838: ;Delay of 20ms used during initialisation.
// #839: ;
// #840: ;Registers used s0, s1, s2, s3
// #841: ;
// @115 #842: [delay_20ms]
00314 // @115 #842: LOAD(s3,20) ;20 x 1ms = 20ms
// @116 #843: [wait_20ms]
30110 // @116 #843: CALL(delay_1ms)
1c301 // @117 #844: SUB(s3,1)
35516 // @118 #845: JUMP(NZ,wait_20ms)
2a000 // @119 #846: RETURN
// #847: ;
// #848: ;Delay of approximately 1 second.
// #849: ;
// #850: ;Registers used s0, s1, s2, s3, s4
// #851: ;
// @11a #852: [delay_1s]
00414 // @11a #852: LOAD(s4,20) ;50 x 20ms = 1000ms
// @11b #853: [wait_1s]
30115 // @11b #853: CALL(delay_20ms)
1c401 // @11c #854: SUB(s4,1)
3551b // @11d #855: JUMP(NZ,wait_1s)
2a000 // @11e #856: RETURN
// #857: ;
// #858: ;
// #859: ;**************************************************************************************
// #860: ;UART communication routines
// #861: ;**************************************************************************************
// #862: ;
// #863: ;Read one character from the UART
// #864: ;
// #865: ;Character read will be returned in a register called 'UART_data'.
// #866: ;
// #867: ;The routine first tests the receiver FIFO buffer to see if data is present.
// #868: ;If the FIFO is empty, the routine waits until there is a character to read.
// #869: ;As this could take any amount of time the wait loop could include a call to a
// #870: ;subroutine which performs a useful function.
// #871: ;
// #872: ;If the received character is an XOFF, then the routine will then wait
// #873: ;for an XON to be received. This means that the rest of the program is held
// #874: ;in suspense and therefore it can not transmit. Once an XON is received, it will
// #875: ;again wait for a normal character before returning.
// #876: ;
// #877: ;NOTE: Characters between the XOFF and XON will be ignored in this version of the
// #878: ;program!!!
// #879: ;
// #880: ;Interrupt is disabled during this routine to prevent a false situation. If the
// #881: ;receiver half-full flag went High it should result in an interrupt transmitting
// #882: ;an XOFF character. However, if this routine were able to read the receiver buffer
// #883: ;at just about the same as the hardware detects the half-full flag, then it could
// #884: ;think that an XON needs to be transmitted.
// #885: ;
// #886: ;
// #887: ;Registers used s0 and UART_data
// #888: ;
// @11f #889: [read_from_UART]
3c000 // @11f #889: DISABLE(INTERRUPT)
// @120 #890: [wait_Rx_character]
04000 // @120 #890: INPUT(s0,status_port) ;test Rx_FIFO buffer
12008 // @121 #891: TEST(s0,rx_data_present)
35524 // @122 #892: JUMP(NZ,read_character)
34120 // @123 #893: JUMP(wait_Rx_character)
// @124 #894: [read_character]
04f01 // @124 #894: INPUT(UART_data,UART_read_port) ;read from FIFO
14f13 // @125 #895: COMPARE(UART_data,character_XOFF) ;test for XOFF
35129 // @126 #896: JUMP(Z,wait_XON)
3c001 // @127 #897: ENABLE(INTERRUPT) ;normal finish
2a000 // @128 #898: RETURN
// @129 #899: [wait_XON]
04000 // @129 #899: INPUT(s0,status_port) ;test Rx_FIFO buffer
12008 // @12a #900: TEST(s0,rx_data_present)
3552d // @12b #901: JUMP(NZ,read_XON)
34129 // @12c #902: JUMP(wait_XON)
// @12d #903: [read_XON]
04f01 // @12d #903: INPUT(UART_data,UART_read_port) ;read from FIFO
14f11 // @12e #904: COMPARE(UART_data,character_XON) ;test for XON
35120 // @12f #905: JUMP(Z,wait_Rx_character) ;now wait for normal character
34129 // @130 #906: JUMP(wait_XON) ;continue to wait for XON
// #907: ;
// #908: ;
// #909: ;
// #910: ;Transmit one character to the UART
// #911: ;
// #912: ;Character supplied in register called 'UART_data'.
// #913: ;
// #914: ;The routine first tests the transmit FIFO buffer is empty.
// #915: ;If the FIFO currently has any data, the routine waits until it is empty.
// #916: ;Ultimately this means that only one character is sent at a time which
// #917: ;could be important if the PC at the other end of the link transmits
// #918: ;an XOFF and needs the flow of data to terminate as soon as possible.
// #919: ;
// #920: ;Registers used s0
// #921: ;
// @131 #922: [send_to_UART]
04000 // @131 #922: INPUT(s0,status_port) ;test Tx_FIFO buffer
12001 // @132 #923: TEST(s0,tx_data_present)
35135 // @133 #924: JUMP(Z,UART_write)
34131 // @134 #925: JUMP(send_to_UART)
// @135 #926: [UART_write]
2cf04 // @135 #926: OUTPUT(UART_data,UART_write_port)
2a000 // @136 #927: RETURN
// #928: ;
// #929: ;
// #930: ;**************************************************************************************
// #931: ;Useful ASCII conversion and handling routines
// #932: ;**************************************************************************************
// #933: ;
// #934: ;Convert value provided in register s0 into ASCII characters
// #935: ;
// #936: ;The value provided must in the range 0 to 99 and will be converted into
// #937: ;two ASCII characters.
// #938: ; The number of 'tens' will be represented by an ASCII character returned in register s1.
// #939: ; The number of 'units' will be represented by an ASCII character returned in register s0.
// #940: ;
// #941: ;The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex added to
// #942: ;the actual decimal value.
// #943: ;
// #944: ;Registers used s0 and s1.
// #945: ;
// @137 #946: [decimal_to_ASCII]
00130 // @137 #946: LOAD(s1,48) ;load 'tens' counter with ASCII for '0'
// @138 #947: [test_for_ten]
18101 // @138 #947: ADD(s1,1) ;increment 'tens' value
1c00a // @139 #948: SUB(s0,10) ;try to subtract 10 from the supplied value
35d38 // @13a #949: JUMP(NC,test_for_ten) ;repeat if subtraction was possible without underflow.
1c101 // @13b #950: SUB(s1,1) ;'tens' value one less ten due to underflow
1803a // @13c #951: ADD(s0,58) ;restore units value (the remainder) and convert to ASCII
2a000 // @13d #952: RETURN
// #953: ;
// #954: ;
// #955: ;
// #956: ;Convert character to upper case
// #957: ;
// #958: ;The character supplied in register s0.
// #959: ;If the character is in the range 'a' to 'z', it is converted
// #960: ;to the equivalent upper case character in the range 'A' to 'Z'.
// #961: ;All other characters remain unchanged.
// #962: ;
// #963: ;Registers used s0.
// #964: ;
// @13e #965: [upper_case]
14061 // @13e #965: COMPARE(s0,97) ;eliminate character codes below 'a' (61 hex)
2b800 // @13f #966: RETURN(C)
1407b // @140 #967: COMPARE(s0,123) ;eliminate character codes above 'z' (7A hex)
2bc00 // @141 #968: RETURN(NC)
0a0df // @142 #969: AND(s0,DF) ;mask bit5 to convert to upper case
2a000 // @143 #970: RETURN
// #971: ;
// #972: ;
// #973: ;Convert character '0' to '9' to numerical value in range 0 to 9
// #974: ;
// #975: ;The character supplied in register s0. If the character is in the
// #976: ;range '0' to '9', it is converted to the equivalent decimal value.
// #977: ;Characters not in the range '0' to '9' are signified by the return
// #978: ;with the CARRY flag set.
// #979: ;
// #980: ;Registers used s0.
// #981: ;
// @144 #982: [onechar_to_value]
180c6 // @144 #982: ADD(s0,C6) ;reject character codes above '9' (39 hex)
2b800 // @145 #983: RETURN(C) ;carry flag is set
1c0f6 // @146 #984: SUB(s0,F6) ;reject character codes below '0' (30 hex)
2a000 // @147 #985: RETURN ;carry is set if value not in range
// #986: ;
// #987: ;
// #988: ;Determine the numerical value of a two character decimal string held in
// #989: ;scratch pad memory such the result is in the range 0 to 99 (00 to 63 hex).
// #990: ;
// #991: ;The string must be stored in two consecutive memory locations and the
// #992: ;location of the first (tens) character supplied in the s1 register.
// #993: ;The result is provided in register s2. Strings not using characters in the
// #994: ;range '0' to '9' are signified by the return with the CARRY flag set.
// #995: ;
// #996: ;Registers used s0, s1 and s2.
// #997: ;
// @148 #998: [twochar_to_value]
07010 // @148 #998: FETCH(s0,s1) ;read 'tens' character
30144 // @149 #999: CALL(onechar_to_value) ;convert to numerical value
2b800 // @14a #1000: RETURN(C) ;bad character - CARRY set
01200 // @14b #1001: LOAD(s2,s0)
20206 // @14c #1002: SL0(s2) ;multiply 'tens' value by 10 (0A hex)
20206 // @14d #1003: SL0(s2)
19200 // @14e #1004: ADD(s2,s0)
20206 // @14f #1005: SL0(s2)
18101 // @150 #1006: ADD(s1,1) ;read 'units' character
07010 // @151 #1007: FETCH(s0,s1)
30144 // @152 #1008: CALL(onechar_to_value) ;convert to numerical value
2b800 // @153 #1009: RETURN(C) ;bad character - CARRY set
19200 // @154 #1010: ADD(s2,s0) ;add units to result and clear CARRY flag
2a000 // @155 #1011: RETURN
// #1012: ;
// #1013: ;
// #1014: ;Convert hexadecimal value provided in register s0 into ASCII characters
// #1015: ;
// #1016: ;The value provided must can be any value in the range 00 to FF and will be converted into
// #1017: ;two ASCII characters.
// #1018: ; The upper nibble will be represented by an ASCII character returned in register s2.
// #1019: ; The lower nibble will be represented by an ASCII character returned in register s1.
// #1020: ;
// #1021: ;The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex
// #1022: ;added to the actual decimal value. The ASCII representations of 'A' to 'F' are 41 to 46
// #1023: ;hexadecimal requiring a further addition of 07 to the 30 already added.
// #1024: ;
// #1025: ;Registers used s0, s1 and s2.
// #1026: ;
// @156 #1027: [hex_byte_to_ASCII]
01100 // @156 #1027: LOAD(s1,s0) ;remember value supplied
2000e // @157 #1028: SR0(s0) ;isolate upper nibble
2000e // @158 #1029: SR0(s0)
2000e // @159 #1030: SR0(s0)
2000e // @15a #1031: SR0(s0)
30162 // @15b #1032: CALL(hex_to_ASCII) ;convert
01200 // @15c #1033: LOAD(s2,s0) ;upper nibble value in s2
01010 // @15d #1034: LOAD(s0,s1) ;restore complete value
0a00f // @15e #1035: AND(s0,15) ;isolate lower nibble
30162 // @15f #1036: CALL(hex_to_ASCII) ;convert
01100 // @160 #1037: LOAD(s1,s0) ;lower nibble value in s1
2a000 // @161 #1038: RETURN
// #1039: ;
// #1040: ;Convert hexadecimal value provided in register s0 into ASCII character
// #1041: ;
// #1042: ;Register used s0
// #1043: ;
// @162 #1044: [hex_to_ASCII]
1c00a // @162 #1044: SUB(s0,10) ;test if value is in range 0 to 9
35965 // @163 #1045: JUMP(C,number_char)
18007 // @164 #1046: ADD(s0,7) ;ASCII char A to F in range 41 to 46
// @165 #1047: [number_char]
1803a // @165 #1047: ADD(s0,58) ;ASCII char 0 to 9 in range 30 to 40
2a000 // @166 #1048: RETURN
// #1049: ;
// #1050: ;
// #1051: ;Send the two character HEX value of the register contents 's0' to the UART
// #1052: ;
// #1053: ;Registers used s0, s1, s2
// #1054: ;
// @167 #1055: [send_hex_byte]
30156 // @167 #1055: CALL(hex_byte_to_ASCII)
01f20 // @168 #1056: LOAD(UART_data,s2)
30131 // @169 #1057: CALL(send_to_UART)
01f10 // @16a #1058: LOAD(UART_data,s1)
30131 // @16b #1059: CALL(send_to_UART)
2a000 // @16c #1060: RETURN
// #1061: ;
// #1062: ;
// #1063: ;
// #1064: ;Send the six character HEX value of the register contents [s9,s8,s7] to the UART
// #1065: ;
// #1066: ;Registers used s0, s1, s2
// #1067: ;
// @16d #1068: [send_hex_3bytes]
01090 // @16d #1068: LOAD(s0,s9)
30167 // @16e #1069: CALL(send_hex_byte)
01080 // @16f #1070: LOAD(s0,s8)
30167 // @170 #1071: CALL(send_hex_byte)
01070 // @171 #1072: LOAD(s0,s7)
30167 // @172 #1073: CALL(send_hex_byte)
2a000 // @173 #1074: RETURN
// #1075: ;
// #1076: ;
// #1077: ;Convert the HEX ASCII characters contained in 's3' and 's2' into
// #1078: ;an equivalent hexadecimal value in register 's0'.
// #1079: ; The upper nibble is represented by an ASCII character in register s3.
// #1080: ; The lower nibble is represented by an ASCII character in register s2.
// #1081: ;
// #1082: ;Input characters must be in the range 00 to FF hexadecimal or the CARRY flag
// #1083: ;will be set on return.
// #1084: ;
// #1085: ;Registers used s0, s2 and s3.
// #1086: ;
// @174 #1087: [ASCII_byte_to_hex]
01030 // @174 #1087: LOAD(s0,s3) ;Take upper nibble
30181 // @175 #1088: CALL(ASCII_to_hex) ;convert to value
2b800 // @176 #1089: RETURN(C) ;reject if out of range
01300 // @177 #1090: LOAD(s3,s0) ;remember value
20306 // @178 #1091: SL0(s3) ;multiply value by 16 to put in upper nibble
20306 // @179 #1092: SL0(s3)
20306 // @17a #1093: SL0(s3)
20306 // @17b #1094: SL0(s3)
01020 // @17c #1095: LOAD(s0,s2) ;Take lower nibble
30181 // @17d #1096: CALL(ASCII_to_hex) ;convert to value
2b800 // @17e #1097: RETURN(C) ;reject if out of range
0d030 // @17f #1098: OR(s0,s3) ;merge in the upper nibble with CARRY reset
2a000 // @180 #1099: RETURN
// #1100: ;
// #1101: ;
// #1102: ;Routine to convert ASCII data in 's0' to an equivalent HEX value.
// #1103: ;
// #1104: ;If character is not valid for hex, then CARRY is set on return.
// #1105: ;
// #1106: ;Register used s0
// #1107: ;
// @181 #1108: [ASCII_to_hex]
180b9 // @181 #1108: ADD(s0,B9) ;test for above ASCII code 46 ('F')
2b800 // @182 #1109: RETURN(C)
1c0e9 // @183 #1110: SUB(s0,E9) ;normalise 0 to 9 with A-F in 11 to 16 hex
2b800 // @184 #1111: RETURN(C) ;reject below ASCII code 30 ('0')
1c011 // @185 #1112: SUB(s0,17) ;isolate A-F down to 00 to 05 hex
35d8b // @186 #1113: JUMP(NC,ASCII_letter)
18007 // @187 #1114: ADD(s0,7) ;test for above ASCII code 46 ('F')
2b800 // @188 #1115: RETURN(C)
1c0f6 // @189 #1116: SUB(s0,F6) ;convert to range 00 to 09
2a000 // @18a #1117: RETURN
// @18b #1118: [ASCII_letter]
1800a // @18b #1118: ADD(s0,10) ;convert to range 0A to 0F
2a000 // @18c #1119: RETURN
// #1120: ;
// #1121: ;
// #1122: ;Read two hex characters from UART and convert to single byte data
// #1123: ;
// @18d #1124: [obtain_8bits]
30022 // @18d #1124: CALL(read_upper_case) ;obtain one byte from UART
01300 // @18e #1125: LOAD(s3,s0)
30022 // @18f #1126: CALL(read_upper_case)
01200 // @190 #1127: LOAD(s2,s0)
30174 // @191 #1128: CALL(ASCII_byte_to_hex)
2a000 // @192 #1129: RETURN
// #1130: ;
// #1131: ;**************************************************************************************
// #1132: ;Text messages
// #1133: ;**************************************************************************************
// #1134: ;
// #1135: ;
// #1136: ;Send Carriage Return to the UART
// #1137: ;
// @193 #1138: [send_CR]
00f0d // @193 #1138: LOAD(UART_data,character_CR)
30131 // @194 #1139: CALL(send_to_UART)
2a000 // @195 #1140: RETURN
// #1141: ;
// #1142: ;Send a space to the UART
// #1143: ;
// @196 #1144: [send_space]
00f20 // @196 #1144: LOAD(UART_data,character_space)
30131 // @197 #1145: CALL(send_to_UART)
2a000 // @198 #1146: RETURN
// #1147: ;
// #1148: ;
// #1149: ;Send 'PicoBlaze NOR FLASH Programmer' string to the UART
// #1150: ;
// @199 #1151: [send_welcome]
30193 // @199 #1151: CALL(send_CR)
30193 // @19a #1152: CALL(send_CR)
00f50 // @19b #1153: LOAD(UART_data,character_P)
30131 // @19c #1154: CALL(send_to_UART)
00f69 // @19d #1155: LOAD(UART_data,character_i)
30131 // @19e #1156: CALL(send_to_UART)
00f63 // @19f #1157: LOAD(UART_data,character_c)
30131 // @1a0 #1158: CALL(send_to_UART)
00f6f // @1a1 #1159: LOAD(UART_data,character_o)
30131 // @1a2 #1160: CALL(send_to_UART)
00f42 // @1a3 #1161: LOAD(UART_data,character_B)
30131 // @1a4 #1162: CALL(send_to_UART)
00f6c // @1a5 #1163: LOAD(UART_data,character_l)
30131 // @1a6 #1164: CALL(send_to_UART)
00f61 // @1a7 #1165: LOAD(UART_data,character_a)
30131 // @1a8 #1166: CALL(send_to_UART)
00f7a // @1a9 #1167: LOAD(UART_data,character_z)
30131 // @1aa #1168: CALL(send_to_UART)
00f65 // @1ab #1169: LOAD(UART_data,character_e)
30131 // @1ac #1170: CALL(send_to_UART)
30196 // @1ad #1171: CALL(send_space)
00f4e // @1ae #1172: LOAD(UART_data,character_N)
30131 // @1af #1173: CALL(send_to_UART)
00f4f // @1b0 #1174: LOAD(UART_data,character_O)
30131 // @1b1 #1175: CALL(send_to_UART)
00f52 // @1b2 #1176: LOAD(UART_data,character_R)
30131 // @1b3 #1177: CALL(send_to_UART)
30196 // @1b4 #1178: CALL(send_space)
00f46 // @1b5 #1179: LOAD(UART_data,character_F)
30131 // @1b6 #1180: CALL(send_to_UART)
00f4c // @1b7 #1181: LOAD(UART_data,character_L)
30131 // @1b8 #1182: CALL(send_to_UART)
00f41 // @1b9 #1183: LOAD(UART_data,character_A)
30131 // @1ba #1184: CALL(send_to_UART)
00f53 // @1bb #1185: LOAD(UART_data,character_S)
30131 // @1bc #1186: CALL(send_to_UART)
00f48 // @1bd #1187: LOAD(UART_data,character_H)
30131 // @1be #1188: CALL(send_to_UART)
30196 // @1bf #1189: CALL(send_space)
00f50 // @1c0 #1190: LOAD(UART_data,character_P)
30131 // @1c1 #1191: CALL(send_to_UART)
00f72 // @1c2 #1192: LOAD(UART_data,character_r)
30131 // @1c3 #1193: CALL(send_to_UART)
00f6f // @1c4 #1194: LOAD(UART_data,character_o)
30131 // @1c5 #1195: CALL(send_to_UART)
00f67 // @1c6 #1196: LOAD(UART_data,character_g)
30131 // @1c7 #1197: CALL(send_to_UART)
00f72 // @1c8 #1198: LOAD(UART_data,character_r)
30131 // @1c9 #1199: CALL(send_to_UART)
00f61 // @1ca #1200: LOAD(UART_data,character_a)
30131 // @1cb #1201: CALL(send_to_UART)
00f6d // @1cc #1202: LOAD(UART_data,character_m)
30131 // @1cd #1203: CALL(send_to_UART)
00f6d // @1ce #1204: LOAD(UART_data,character_m)
30131 // @1cf #1205: CALL(send_to_UART)
00f65 // @1d0 #1206: LOAD(UART_data,character_e)
30131 // @1d1 #1207: CALL(send_to_UART)
00f72 // @1d2 #1208: LOAD(UART_data,character_r)
30131 // @1d3 #1209: CALL(send_to_UART)
30196 // @1d4 #1210: CALL(send_space)
00f76 // @1d5 #1211: LOAD(UART_data,character_v)
30131 // @1d6 #1212: CALL(send_to_UART)
00f31 // @1d7 #1213: LOAD(UART_data,character_1)
30131 // @1d8 #1214: CALL(send_to_UART)
00f2e // @1d9 #1215: LOAD(UART_data,character_fullstop)
30131 // @1da #1216: CALL(send_to_UART)
00f30 // @1db #1217: LOAD(UART_data,character_0)
30131 // @1dc #1218: CALL(send_to_UART)
00f30 // @1dd #1219: LOAD(UART_data,character_0)
30131 // @1de #1220: CALL(send_to_UART)
30193 // @1df #1221: CALL(send_CR)
30193 // @1e0 #1222: CALL(send_CR)
2a000 // @1e1 #1223: RETURN
// #1224: ;
// #1225: ;
// #1226: ;
// #1227: ;Send 'Waiting_MCS_file' string to the UART
// #1228: ;
// @1e2 #1229: [send_Waiting_MCS_file]
00f57 // @1e2 #1229: LOAD(UART_data,character_W)
30131 // @1e3 #1230: CALL(send_to_UART)
00f61 // @1e4 #1231: LOAD(UART_data,character_a)
30131 // @1e5 #1232: CALL(send_to_UART)
00f69 // @1e6 #1233: LOAD(UART_data,character_i)
30131 // @1e7 #1234: CALL(send_to_UART)
00f74 // @1e8 #1235: LOAD(UART_data,character_t)
30131 // @1e9 #1236: CALL(send_to_UART)
00f69 // @1ea #1237: LOAD(UART_data,character_i)
30131 // @1eb #1238: CALL(send_to_UART)
00f6e // @1ec #1239: LOAD(UART_data,character_n)
30131 // @1ed #1240: CALL(send_to_UART)
00f67 // @1ee #1241: LOAD(UART_data,character_g)
30131 // @1ef #1242: CALL(send_to_UART)
30196 // @1f0 #1243: CALL(send_space)
00f66 // @1f1 #1244: LOAD(UART_data,character_f)
30131 // @1f2 #1245: CALL(send_to_UART)
00f6f // @1f3 #1246: LOAD(UART_data,character_o)
30131 // @1f4 #1247: CALL(send_to_UART)
00f72 // @1f5 #1248: LOAD(UART_data,character_r)
30131 // @1f6 #1249: CALL(send_to_UART)
// @1f7 #1250: [send_MCS_file]
30196 // @1f7 #1250: CALL(send_space)
00f4d // @1f8 #1251: LOAD(UART_data,character_M)
30131 // @1f9 #1252: CALL(send_to_UART)
00f43 // @1fa #1253: LOAD(UART_data,character_C)
30131 // @1fb #1254: CALL(send_to_UART)
00f53 // @1fc #1255: LOAD(UART_data,character_S)
30131 // @1fd #1256: CALL(send_to_UART)
30196 // @1fe #1257: CALL(send_space)
00f46 // @1ff #1258: LOAD(UART_data,character_F)
30131 // @200 #1259: CALL(send_to_UART)
00f69 // @201 #1260: LOAD(UART_data,character_i)
30131 // @202 #1261: CALL(send_to_UART)
00f6c // @203 #1262: LOAD(UART_data,character_l)
30131 // @204 #1263: CALL(send_to_UART)
00f65 // @205 #1264: LOAD(UART_data,character_e)
30131 // @206 #1265: CALL(send_to_UART)
30193 // @207 #1266: CALL(send_CR)
2a000 // @208 #1267: RETURN
// #1268: ;
// #1269: ;
// #1270: ;Send 'Erase in progress' string to the UART
// #1271: ;
// @209 #1272: [send_Erase_in_progress]
30220 // @209 #1272: CALL(send_Erase)
00f69 // @20a #1273: LOAD(UART_data,character_i)
30131 // @20b #1274: CALL(send_to_UART)
00f6e // @20c #1275: LOAD(UART_data,character_n)
30131 // @20d #1276: CALL(send_to_UART)
30196 // @20e #1277: CALL(send_space)
00f50 // @20f #1278: LOAD(UART_data,character_P)
30131 // @210 #1279: CALL(send_to_UART)
00f72 // @211 #1280: LOAD(UART_data,character_r)
30131 // @212 #1281: CALL(send_to_UART)
00f6f // @213 #1282: LOAD(UART_data,character_o)
30131 // @214 #1283: CALL(send_to_UART)
00f67 // @215 #1284: LOAD(UART_data,character_g)
30131 // @216 #1285: CALL(send_to_UART)
00f72 // @217 #1286: LOAD(UART_data,character_r)
30131 // @218 #1287: CALL(send_to_UART)
00f65 // @219 #1288: LOAD(UART_data,character_e)
30131 // @21a #1289: CALL(send_to_UART)
00f73 // @21b #1290: LOAD(UART_data,character_s)
30131 // @21c #1291: CALL(send_to_UART)
30131 // @21d #1292: CALL(send_to_UART)
30193 // @21e #1293: CALL(send_CR)
2a000 // @21f #1294: RETURN
// #1295: ;
// #1296: ;
// #1297: ;Send 'Erase ' string to the UART
// #1298: ;
// @220 #1299: [send_Erase]
00f45 // @220 #1299: LOAD(UART_data,character_E)
30131 // @221 #1300: CALL(send_to_UART)
00f72 // @222 #1301: LOAD(UART_data,character_r)
30131 // @223 #1302: CALL(send_to_UART)
00f61 // @224 #1303: LOAD(UART_data,character_a)
30131 // @225 #1304: CALL(send_to_UART)
00f73 // @226 #1305: LOAD(UART_data,character_s)
30131 // @227 #1306: CALL(send_to_UART)
00f65 // @228 #1307: LOAD(UART_data,character_e)
30131 // @229 #1308: CALL(send_to_UART)
30196 // @22a #1309: CALL(send_space)
2a000 // @22b #1310: RETURN
// #1311: ;
// #1312: ;
// #1313: ;Send carriage return, 'OK' and carriage return to the UART
// #1314: ;
// @22c #1315: [send_OK]
30193 // @22c #1315: CALL(send_CR)
00f4f // @22d #1316: LOAD(UART_data,character_O)
30131 // @22e #1317: CALL(send_to_UART)
00f4b // @22f #1318: LOAD(UART_data,character_K)
30131 // @230 #1319: CALL(send_to_UART)
30193 // @231 #1320: CALL(send_CR)
2a000 // @232 #1321: RETURN
// #1322: ;
// #1323: ;
// #1324: ;
// #1325: ;Send menu to the UART
// #1326: ;
// @233 #1327: [send_Menu]
30193 // @233 #1327: CALL(send_CR)
00f45 // @234 #1328: LOAD(UART_data,character_E)
30131 // @235 #1329: CALL(send_to_UART)
00f2d // @236 #1330: LOAD(UART_data,character_minus)
30131 // @237 #1331: CALL(send_to_UART)
30220 // @238 #1332: CALL(send_Erase)
00f61 // @239 #1333: LOAD(UART_data,character_a)
30131 // @23a #1334: CALL(send_to_UART)
00f6c // @23b #1335: LOAD(UART_data,character_l)
30131 // @23c #1336: CALL(send_to_UART)
30131 // @23d #1337: CALL(send_to_UART)
30193 // @23e #1338: CALL(send_CR)
00f42 // @23f #1339: LOAD(UART_data,character_B)
30131 // @240 #1340: CALL(send_to_UART)
00f2d // @241 #1341: LOAD(UART_data,character_minus)
30131 // @242 #1342: CALL(send_to_UART)
30220 // @243 #1343: CALL(send_Erase)
00f62 // @244 #1344: LOAD(UART_data,character_b)
30131 // @245 #1345: CALL(send_to_UART)
00f6c // @246 #1346: LOAD(UART_data,character_l)
30131 // @247 #1347: CALL(send_to_UART)
00f6f // @248 #1348: LOAD(UART_data,character_o)
30131 // @249 #1349: CALL(send_to_UART)
00f63 // @24a #1350: LOAD(UART_data,character_c)
30131 // @24b #1351: CALL(send_to_UART)
00f6b // @24c #1352: LOAD(UART_data,character_k)
30131 // @24d #1353: CALL(send_to_UART)
00f73 // @24e #1354: LOAD(UART_data,character_s)
30131 // @24f #1355: CALL(send_to_UART)
30196 // @250 #1356: CALL(send_space)
00f31 // @251 #1357: LOAD(UART_data,character_1)
30131 // @252 #1358: CALL(send_to_UART)
00f2d // @253 #1359: LOAD(UART_data,character_minus)
30131 // @254 #1360: CALL(send_to_UART)
00f33 // @255 #1361: LOAD(UART_data,character_3)
30131 // @256 #1362: CALL(send_to_UART)
30193 // @257 #1363: CALL(send_CR)
00f50 // @258 #1364: LOAD(UART_data,character_P)
30131 // @259 #1365: CALL(send_to_UART)
00f2d // @25a #1366: LOAD(UART_data,character_minus)
30131 // @25b #1367: CALL(send_to_UART)
00f50 // @25c #1368: LOAD(UART_data,character_P)
30131 // @25d #1369: CALL(send_to_UART)
00f72 // @25e #1370: LOAD(UART_data,character_r)
30131 // @25f #1371: CALL(send_to_UART)
00f6f // @260 #1372: LOAD(UART_data,character_o)
30131 // @261 #1373: CALL(send_to_UART)
00f67 // @262 #1374: LOAD(UART_data,character_g)
30131 // @263 #1375: CALL(send_to_UART)
00f72 // @264 #1376: LOAD(UART_data,character_r)
30131 // @265 #1377: CALL(send_to_UART)
00f61 // @266 #1378: LOAD(UART_data,character_a)
30131 // @267 #1379: CALL(send_to_UART)
00f6d // @268 #1380: LOAD(UART_data,character_m)
30131 // @269 #1381: CALL(send_to_UART)
301f7 // @26a #1382: CALL(send_MCS_file)
00f57 // @26b #1383: LOAD(UART_data,character_W)
30131 // @26c #1384: CALL(send_to_UART)
00f2d // @26d #1385: LOAD(UART_data,character_minus)
30131 // @26e #1386: CALL(send_to_UART)
00f57 // @26f #1387: LOAD(UART_data,character_W)
30131 // @270 #1388: CALL(send_to_UART)
00f72 // @271 #1389: LOAD(UART_data,character_r)
30131 // @272 #1390: CALL(send_to_UART)
00f69 // @273 #1391: LOAD(UART_data,character_i)
30131 // @274 #1392: CALL(send_to_UART)
00f74 // @275 #1393: LOAD(UART_data,character_t)
30131 // @276 #1394: CALL(send_to_UART)
00f65 // @277 #1395: LOAD(UART_data,character_e)
30131 // @278 #1396: CALL(send_to_UART)
30196 // @279 #1397: CALL(send_space)
302cb // @27a #1398: CALL(send_byte)
30193 // @27b #1399: CALL(send_CR)
00f52 // @27c #1400: LOAD(UART_data,character_R)
30131 // @27d #1401: CALL(send_to_UART)
00f2d // @27e #1402: LOAD(UART_data,character_minus)
30131 // @27f #1403: CALL(send_to_UART)
00f52 // @280 #1404: LOAD(UART_data,character_R)
30131 // @281 #1405: CALL(send_to_UART)
00f65 // @282 #1406: LOAD(UART_data,character_e)
30131 // @283 #1407: CALL(send_to_UART)
00f61 // @284 #1408: LOAD(UART_data,character_a)
30131 // @285 #1409: CALL(send_to_UART)
00f64 // @286 #1410: LOAD(UART_data,character_d)
30131 // @287 #1411: CALL(send_to_UART)
30196 // @288 #1412: CALL(send_space)
00f32 // @289 #1413: LOAD(UART_data,character_2)
30131 // @28a #1414: CALL(send_to_UART)
00f35 // @28b #1415: LOAD(UART_data,character_5)
30131 // @28c #1416: CALL(send_to_UART)
00f36 // @28d #1417: LOAD(UART_data,character_6)
30131 // @28e #1418: CALL(send_to_UART)
30196 // @28f #1419: CALL(send_space)
302cb // @290 #1420: CALL(send_byte)
00f73 // @291 #1421: LOAD(UART_data,character_s)
30131 // @292 #1422: CALL(send_to_UART)
30193 // @293 #1423: CALL(send_CR)
00f49 // @294 #1424: LOAD(UART_data,character_I)
30131 // @295 #1425: CALL(send_to_UART)
00f2d // @296 #1426: LOAD(UART_data,character_minus)
30131 // @297 #1427: CALL(send_to_UART)
00f44 // @298 #1428: LOAD(UART_data,character_D)
30131 // @299 #1429: CALL(send_to_UART)
00f65 // @29a #1430: LOAD(UART_data,character_e)
30131 // @29b #1431: CALL(send_to_UART)
00f76 // @29c #1432: LOAD(UART_data,character_v)
30131 // @29d #1433: CALL(send_to_UART)
00f69 // @29e #1434: LOAD(UART_data,character_i)
30131 // @29f #1435: CALL(send_to_UART)
00f63 // @2a0 #1436: LOAD(UART_data,character_c)
30131 // @2a1 #1437: CALL(send_to_UART)
00f65 // @2a2 #1438: LOAD(UART_data,character_e)
30131 // @2a3 #1439: CALL(send_to_UART)
30196 // @2a4 #1440: CALL(send_space)
302c6 // @2a5 #1441: CALL(send_ID)
30193 // @2a6 #1442: CALL(send_CR)
00f48 // @2a7 #1443: LOAD(UART_data,character_H)
30131 // @2a8 #1444: CALL(send_to_UART)
00f2d // @2a9 #1445: LOAD(UART_data,character_minus)
30131 // @2aa #1446: CALL(send_to_UART)
00f48 // @2ab #1447: LOAD(UART_data,character_H)
30131 // @2ac #1448: CALL(send_to_UART)
00f65 // @2ad #1449: LOAD(UART_data,character_e)
30131 // @2ae #1450: CALL(send_to_UART)
00f6c // @2af #1451: LOAD(UART_data,character_l)
30131 // @2b0 #1452: CALL(send_to_UART)
00f70 // @2b1 #1453: LOAD(UART_data,character_p)
30131 // @2b2 #1454: CALL(send_to_UART)
30193 // @2b3 #1455: CALL(send_CR)
00f53 // @2b4 #1456: LOAD(UART_data,character_S)
30131 // @2b5 #1457: CALL(send_to_UART)
00f2d // @2b6 #1458: LOAD(UART_data,character_minus)
30131 // @2b7 #1459: CALL(send_to_UART)
00f53 // @2b8 #1460: LOAD(UART_data,character_S)
30131 // @2b9 #1461: CALL(send_to_UART)
00f74 // @2ba #1462: LOAD(UART_data,character_t)
30131 // @2bb #1463: CALL(send_to_UART)
00f61 // @2bc #1464: LOAD(UART_data,character_a)
30131 // @2bd #1465: CALL(send_to_UART)
00f74 // @2be #1466: LOAD(UART_data,character_t)
30131 // @2bf #1467: CALL(send_to_UART)
00f75 // @2c0 #1468: LOAD(UART_data,character_u)
30131 // @2c1 #1469: CALL(send_to_UART)
00f73 // @2c2 #1470: LOAD(UART_data,character_s)
30131 // @2c3 #1471: CALL(send_to_UART)
30193 // @2c4 #1472: CALL(send_CR)
2a000 // @2c5 #1473: RETURN
// #1474: ;
// #1475: ;
// #1476: ;Send 'ID' to the UART
// #1477: ;
// @2c6 #1478: [send_ID]
00f49 // @2c6 #1478: LOAD(UART_data,character_I)
30131 // @2c7 #1479: CALL(send_to_UART)
00f44 // @2c8 #1480: LOAD(UART_data,character_D)
30131 // @2c9 #1481: CALL(send_to_UART)
2a000 // @2ca #1482: RETURN
// #1483: ;
// #1484: ;
// #1485: ;Send 'byte' to the UART
// #1486: ;
// @2cb #1487: [send_byte]
00f62 // @2cb #1487: LOAD(UART_data,character_b)
30131 // @2cc #1488: CALL(send_to_UART)
00f79 // @2cd #1489: LOAD(UART_data,character_y)
30131 // @2ce #1490: CALL(send_to_UART)
00f74 // @2cf #1491: LOAD(UART_data,character_t)
30131 // @2d0 #1492: CALL(send_to_UART)
00f65 // @2d1 #1493: LOAD(UART_data,character_e)
30131 // @2d2 #1494: CALL(send_to_UART)
2a000 // @2d3 #1495: RETURN
// #1496: ;
// #1497: ;
// #1498: ;Send 'Confirm Erase (Y/n) ' to the UART
// #1499: ;
// @2d4 #1500: [send_Confirm]
30193 // @2d4 #1500: CALL(send_CR)
00f43 // @2d5 #1501: LOAD(UART_data,character_C)
30131 // @2d6 #1502: CALL(send_to_UART)
00f6f // @2d7 #1503: LOAD(UART_data,character_o)
30131 // @2d8 #1504: CALL(send_to_UART)
00f6e // @2d9 #1505: LOAD(UART_data,character_n)
30131 // @2da #1506: CALL(send_to_UART)
00f66 // @2db #1507: LOAD(UART_data,character_f)
30131 // @2dc #1508: CALL(send_to_UART)
00f69 // @2dd #1509: LOAD(UART_data,character_i)
30131 // @2de #1510: CALL(send_to_UART)
00f72 // @2df #1511: LOAD(UART_data,character_r)
30131 // @2e0 #1512: CALL(send_to_UART)
00f6d // @2e1 #1513: LOAD(UART_data,character_m)
30131 // @2e2 #1514: CALL(send_to_UART)
30196 // @2e3 #1515: CALL(send_space)
30220 // @2e4 #1516: CALL(send_Erase)
00f28 // @2e5 #1517: LOAD(UART_data,character_open)
30131 // @2e6 #1518: CALL(send_to_UART)
00f59 // @2e7 #1519: LOAD(UART_data,character_Y)
30131 // @2e8 #1520: CALL(send_to_UART)
00f2f // @2e9 #1521: LOAD(UART_data,character_divide)
30131 // @2ea #1522: CALL(send_to_UART)
00f6e // @2eb #1523: LOAD(UART_data,character_n)
30131 // @2ec #1524: CALL(send_to_UART)
00f29 // @2ed #1525: LOAD(UART_data,character_close)
30131 // @2ee #1526: CALL(send_to_UART)
30196 // @2ef #1527: CALL(send_space)
2a000 // @2f0 #1528: RETURN
// #1529: ;
// #1530: ;
// #1531: ;Send 'Abort' to the UART
// #1532: ;
// @2f1 #1533: [send_Abort]
30193 // @2f1 #1533: CALL(send_CR)
00f41 // @2f2 #1534: LOAD(UART_data,character_A)
30131 // @2f3 #1535: CALL(send_to_UART)
00f62 // @2f4 #1536: LOAD(UART_data,character_b)
30131 // @2f5 #1537: CALL(send_to_UART)
00f6f // @2f6 #1538: LOAD(UART_data,character_o)
30131 // @2f7 #1539: CALL(send_to_UART)
00f72 // @2f8 #1540: LOAD(UART_data,character_r)
30131 // @2f9 #1541: CALL(send_to_UART)
00f74 // @2fa #1542: LOAD(UART_data,character_t)
30131 // @2fb #1543: CALL(send_to_UART)
30193 // @2fc #1544: CALL(send_CR)
2a000 // @2fd #1545: RETURN
// #1546: ;
// #1547: ;Send 'address=' to the UART
// #1548: ;
// @2fe #1549: [send_address]
30193 // @2fe #1549: CALL(send_CR)
00f61 // @2ff #1550: LOAD(UART_data,character_a)
30131 // @300 #1551: CALL(send_to_UART)
00f64 // @301 #1552: LOAD(UART_data,character_d)
30131 // @302 #1553: CALL(send_to_UART)
30131 // @303 #1554: CALL(send_to_UART)
00f72 // @304 #1555: LOAD(UART_data,character_r)
30131 // @305 #1556: CALL(send_to_UART)
00f65 // @306 #1557: LOAD(UART_data,character_e)
30131 // @307 #1558: CALL(send_to_UART)
00f73 // @308 #1559: LOAD(UART_data,character_s)
30131 // @309 #1560: CALL(send_to_UART)
30131 // @30a #1561: CALL(send_to_UART)
// @30b #1562: [send_equals]
00f3d // @30b #1562: LOAD(UART_data,character_equals)
30131 // @30c #1563: CALL(send_to_UART)
2a000 // @30d #1564: RETURN
// #1565: ;
// #1566: ;
// #1567: ;Send 'data=' to the UART
// #1568: ;
// @30e #1569: [send_data]
30193 // @30e #1569: CALL(send_CR)
00f64 // @30f #1570: LOAD(UART_data,character_d)
30131 // @310 #1571: CALL(send_to_UART)
00f61 // @311 #1572: LOAD(UART_data,character_a)
30131 // @312 #1573: CALL(send_to_UART)
00f74 // @313 #1574: LOAD(UART_data,character_t)
30131 // @314 #1575: CALL(send_to_UART)
00f61 // @315 #1576: LOAD(UART_data,character_a)
30131 // @316 #1577: CALL(send_to_UART)
3430b // @317 #1578: JUMP(send_equals)
// #1579: ;
// #1580: ;
// #1581: ;**************************************************************************************
// #1582: ;Interrupt Service Routine (ISR)
// #1583: ;**************************************************************************************
// #1584: ;
// #1585: ;An interrupt occurs whenever the status of the UART receiver FIFO 'half_full' flag
// #1586: ;changes.
// #1587: ;
// #1588: ;A change from Low to High means that the buffer is becoming full and therefore
// #1589: ;an XOFF character must be transmitted.
// #1590: ;
// #1591: ;A change from High to Low means that the buffer is starting to empty and therefore
// #1592: ;an XON character can be transmitted to restart the flow of new characters.
// #1593: ;
// #1594: ;
@3f5 // #1595: ADDRESS(1013) ;place at end of memory to keep separate
// @3f5 #1596: [ISR]
2e000 // @3f5 #1596: STORE(s0,ISR_preserve_s0) ;preserve register contents
04000 // @3f6 #1597: INPUT(s0,status_port) ;test 'half_full' status of receiver buffer.
12010 // @3f7 #1598: TEST(s0,rx_half_full)
353fb // @3f8 #1599: JUMP(Z,isr_send_xon)
00013 // @3f9 #1600: LOAD(s0,character_XOFF)
343fc // @3fa #1601: JUMP(isr_send_character)
// @3fb #1602: [isr_send_xon]
00011 // @3fb #1602: LOAD(s0,character_XON)
// @3fc #1603: [isr_send_character]
2c004 // @3fc #1603: OUTPUT(s0,UART_write_port)
06000 // @3fd #1604: FETCH(s0,ISR_preserve_s0) ;restore register contents
38001 // @3fe #1605: RETURNI(ENABLE)
// #1606: ;
// #1607: ;
// #1608: ;**************************************************************************************
// #1609: ;Interrupt Vector
// #1610: ;**************************************************************************************
// #1611: ;
@3ff // #1612: ADDRESS(1023)
343f5 // @3ff #1613: JUMP(ISR)
// #1614: ;
// #1615: ;