├── pcb ├── UMR2-BOM.xls └── UMR2-cradle.brd ├── doc ├── UMR2-PIC-Programming.png └── UMR2-User-Manual-RevC-V1.0.pdf ├── src ├── UMR2-worksheet-Rev-c.ods ├── config-bits.asm ├── umr2.inc ├── checksum.asm ├── learn-isr.asm ├── boot.asm ├── tx-map.asm ├── normal-isr.asm ├── eedata.asm ├── rx-map.asm ├── normal-operation.asm ├── 16f1939.lkr ├── fupdate.asm └── learn-operation.asm ├── LICENSE.txt ├── README.md └── hex └── UMR2.hex /pcb/UMR2-BOM.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/staskevich/UMR2/HEAD/pcb/UMR2-BOM.xls -------------------------------------------------------------------------------- /doc/UMR2-PIC-Programming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/staskevich/UMR2/HEAD/doc/UMR2-PIC-Programming.png -------------------------------------------------------------------------------- /src/UMR2-worksheet-Rev-c.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/staskevich/UMR2/HEAD/src/UMR2-worksheet-Rev-c.ods -------------------------------------------------------------------------------- /doc/UMR2-User-Manual-RevC-V1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/staskevich/UMR2/HEAD/doc/UMR2-User-Manual-RevC-V1.0.pdf -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | UMR2 2 | 3 | copyright John Staskevich, 2017 4 | 5 | john@codeandcopper.com 6 | 7 | 8 | This work is licensed under a Creative Commons Attribution 4.0 International License. 9 | http://creativecommons.org/licenses/by/4.0/ 10 | -------------------------------------------------------------------------------- /src/config-bits.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; config-bits.asm 9 | ; 10 | ; PIC config bits 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | 16 | ;Program Configuration Register 17 | ; with ROM protection 18 | __CONFIG _CONFIG1, 0x3E44 19 | 20 | ; no ROM protection 21 | ; __CONFIG _CONFIG1, 0x3FC4 22 | 23 | __CONFIG _CONFIG2, 0x1FEF 24 | 25 | end 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | UMR2 2 | 3 | copyright John Staskevich, 2017 4 | 5 | john@codeandcopper.com 6 | 7 | 8 | This work is licensed under a Creative Commons Attribution 4.0 International License. 9 | http://creativecommons.org/licenses/by/4.0/ 10 | 11 | 12 | HARDWARE: 13 | 14 | 15 | An Eagle 6 board layout file and BOM are included in the pcb/ folder. There is also a design for a "programming cradle" that mates the test points on the UMR2 with a PIC programmer. 16 | 17 | 18 | A public CircuitHub project is available for on-demand manufacturing: 19 | https://circuithub.com/projects/CodeandCopper1/UMR 20 | 21 | 22 | FIRMWARE: 23 | 24 | 25 | The code in the src/ folder can be assembled for the PIC16F1939 device using Microchip's MPASM assembler. Selected firmware images are located in the hex/ folder. 26 | -------------------------------------------------------------------------------- /src/umr2.inc: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; umr2.inc 9 | ; 10 | ; Include file with global variables, constants 11 | ; 12 | 13 | ; ================================= 14 | ; 15 | ; Bank 0 Variables 16 | ; 17 | ; ================================= 18 | 19 | COUNTER_L equ 0x20 20 | COUNTER_M equ 0x21 21 | COUNTER_H equ 0x22 22 | COUNTER_T0 equ 0x23 23 | FIRST_NOTE equ 0x24 24 | NOTE_COUNT equ 0x25 25 | SETUP_COUNT equ 0x26 26 | 27 | SELECT_FLAGS equ 0x50 28 | KEY_BITS equ 0x60 29 | 30 | ; global space for routines that access multiple banks 31 | INBOUND_STATUS equ 0x70 32 | INBOUND_D0 equ 0x71 33 | BYTE_COUNT equ 0x72 34 | NOTE_ON_STATUS equ 0x73 35 | NOTE_ON_STATUS_LEARN equ 0x73 36 | NOTE_OFF_STATUS equ 0x74 37 | ; General purpose registers for data manipulation 38 | TEMP equ 0x75 39 | TEMP_2 equ 0x76 40 | TEMP_3 equ 0x77 41 | TEMP_4 equ 0x78 42 | TEMP_5 equ 0x79 43 | TEMP_6 equ 0x7A 44 | TEMP_7 equ 0x7B 45 | MESSAGE_TYPE equ 0x7C 46 | TEMP_ISR equ 0x7E 47 | STATE_FLAGS equ 0x7F 48 | 49 | ; ================================= 50 | ; 51 | ; Bank 1 Variables 52 | ; 53 | ; ================================= 54 | 55 | FIRMWARE_BUFFER equ 0xA0 56 | 57 | ; ================================= 58 | ; 59 | ; Bank 2 Variables 60 | ; 61 | ; ================================= 62 | 63 | ; ================================= 64 | ; 65 | ; Bank 3 Variables 66 | ; 67 | ; ================================= 68 | 69 | ; ================================= 70 | ; 71 | ; Constants 72 | ; 73 | ; ================================= 74 | 75 | ; Values for MESSAGE_TYPE 76 | NOT_SUPPORTED equ B'00000000' 77 | NOTE_OFF equ B'00000001' 78 | NOTE_ON equ B'00000010' 79 | AFTERTOUCH equ B'00000100' 80 | CONTROLLER equ B'00001000' 81 | PROGRAM_CHANGE equ B'00010000' 82 | CHANNEL_PRESSURE equ B'00100000' 83 | PITCH_WHEEL equ B'01000000' 84 | SYSEX equ B'10000000' 85 | 86 | ; EEPROM addresses 87 | PROM_VERSION equ 0x00 88 | PROM_CHECKSUM equ 0x01 89 | PROM_CHANNEL equ 0x03 90 | PROM_FIRST_NOTE equ 0x04 91 | PROM_NOTE_COUNT equ 0x05 92 | PROM_SETUP_COUNT equ 0x06 93 | 94 | ; Sysex-related constants 95 | ; Fixed data for header 96 | ; Manufacturer ID 97 | SYSEX_HEADER_0 equ 0x00 98 | SYSEX_HEADER_1 equ 0x01 99 | SYSEX_HEADER_2 equ 0x5D 100 | ; Product ID 101 | SYSEX_HEADER_3 equ 0x07 102 | 103 | ; Other 104 | COUNTER_T0_MAX equ 0x1F 105 | -------------------------------------------------------------------------------- /src/checksum.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; checksum.asm 9 | ; 10 | ; Checksum the application firmware image. 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | 16 | checksum_code code 0x740 17 | 18 | ; ================================= 19 | ; 20 | ; Flush the RX buffer 21 | ; 22 | ; ================================ 23 | 24 | GLOBAL compute_checksum 25 | compute_checksum 26 | 27 | ; checksum the firmware 28 | clrf TEMP 29 | clrf TEMP_2 30 | banksel EEADRL 31 | clrf EEADRL 32 | clrf EEADRH 33 | bsf EECON1,EEPGD 34 | 35 | ; add all opcodes from 0x0000 to 0x1FFF 36 | checksum_loop 37 | bsf EECON1,RD 38 | nop 39 | nop 40 | movfw EEDATL 41 | addwf TEMP,f 42 | movfw EEDATH 43 | addwfc TEMP_2,f 44 | ; increment program address 45 | incfsz EEADRL,f 46 | goto checksum_loop 47 | incf EEADRH,f 48 | btfss EEADRH,5 49 | goto checksum_loop 50 | 51 | ; sum value is now in TEMP_2,TEMP 52 | movlw PROM_CHECKSUM 53 | movwf EEADRL 54 | bcf EECON1,EEPGD 55 | bsf EECON1,RD 56 | movfw EEDATL 57 | movwf TEMP_4 58 | incf EEADRL,f 59 | bsf EECON1,RD 60 | movfw EEDATL 61 | movwf TEMP_3 62 | 63 | ; complement value is now in TEMP_4,TEMP_3 64 | bsf STATUS,C 65 | movfw TEMP_3 66 | addwfc TEMP,f 67 | movfw TEMP_4 68 | addwfc TEMP_2,f 69 | 70 | ; check for zero 71 | movfw TEMP_2 72 | bnz checksum_error 73 | movfw TEMP 74 | bnz checksum_error 75 | 76 | checksum_ok 77 | ; continue with init 78 | clrf BSR 79 | return 80 | 81 | checksum_error 82 | ; blink the activity LED and do nothing. 83 | clrf BSR 84 | ; blink off 85 | checksum_error_blink 86 | movlw B'00001100' 87 | movwf PORTC 88 | clrf COUNTER_L 89 | clrf COUNTER_M 90 | movlw 0x08 91 | movwf COUNTER_H 92 | error_loop_a 93 | nop 94 | decfsz COUNTER_L,f 95 | goto error_loop_a 96 | decfsz COUNTER_M,f 97 | goto error_loop_a 98 | decfsz COUNTER_H,f 99 | goto error_loop_a 100 | 101 | ; blink on 102 | movlw B'00000100' 103 | movwf PORTC 104 | clrf COUNTER_L 105 | clrf COUNTER_M 106 | movlw 0x08 107 | movwf COUNTER_H 108 | error_loop_b 109 | nop 110 | decfsz COUNTER_L,f 111 | goto error_loop_b 112 | decfsz COUNTER_M,f 113 | goto error_loop_b 114 | decfsz COUNTER_H,f 115 | goto error_loop_b 116 | 117 | goto checksum_error_blink 118 | 119 | ; should never execute here. 120 | return 121 | end 122 | -------------------------------------------------------------------------------- /src/learn-isr.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; learn-isr.asm 9 | ; 10 | ; Interrupt service routines for "learning" about host key matrix 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | 16 | ; ================================================================== 17 | ; ================================================================== 18 | ; 19 | ; Learn-Mode ISR 20 | ; 21 | ; ================================================================== 22 | ; ================================================================== 23 | 24 | isr_learn_vector code 0x1004 25 | GLOBAL isr_learn_vector 26 | isr_learn_vector 27 | ; goto isr_learn 28 | ;isr_learn code 29 | isr_learn 30 | 31 | ; New context 32 | clrf BSR 33 | 34 | ; Check for serial receive 35 | btfsc PIR1,RCIF 36 | goto handle_rx_learn 37 | 38 | ; Check for timer0 expiry 39 | btfsc INTCON,TMR0IF 40 | goto handle_timer_0_learn 41 | 42 | retfie 43 | 44 | ; ================================= 45 | ; 46 | ; process incoming midi byte 47 | ; 48 | ; ================================= 49 | 50 | handle_rx_learn 51 | 52 | ; Grab the incoming byte 53 | banksel RCREG 54 | movfw RCREG 55 | movwf TEMP_ISR 56 | banksel PORTA 57 | ; Check if first note has been received yet. 58 | btfss STATE_FLAGS,3 59 | goto handle_rx_learn_process 60 | 61 | ; shut down the RX 62 | banksel PIE1 63 | bcf PIE1,RCIE 64 | retfie 65 | 66 | handle_rx_learn_process 67 | ; If byte is a data byte, process it 68 | btfss TEMP_ISR,7 69 | goto process_data_byte_learn 70 | 71 | process_status_byte_learn 72 | ; Don't let real time messages interrupt running status - check for them now 73 | ; real time message is status B'11111xxx' 74 | comf TEMP_ISR,w 75 | andlw B'11111000' 76 | btfsc STATUS,Z 77 | retfie 78 | ; Check for note-on (0x9?) 79 | movlw B'11110000' 80 | andwf TEMP_ISR,w 81 | sublw 0x90 82 | bz flag_note_on_learn 83 | ; All other status bytes and subsequent data are ignored. 84 | ignore_message_learn 85 | ; Data will be ignored for other status bytes. 86 | clrf MESSAGE_TYPE 87 | retfie 88 | 89 | flag_note_on_learn 90 | movlw NOTE_ON 91 | movwf MESSAGE_TYPE 92 | ; store note-on status. We'll use channel later. 93 | movfw TEMP_ISR 94 | movwf NOTE_ON_STATUS 95 | ; reset byte count 96 | bcf STATE_FLAGS,1 97 | retfie 98 | 99 | process_data_byte_learn 100 | ; always store the first data byte 101 | btfss STATE_FLAGS,1 102 | goto store_d0_learn 103 | 104 | ; second data byte. reset byte count and check for relevant status 105 | bcf STATE_FLAGS,1 106 | ; ignore data for message other than note on 107 | btfsc MESSAGE_TYPE,1 108 | goto process_note_on_learn 109 | retfie 110 | 111 | store_d0_learn 112 | movfw TEMP_ISR 113 | movwf INBOUND_D0 114 | bsf STATE_FLAGS,1 115 | retfie 116 | 117 | ; ================================= 118 | ; 119 | ; handle Note On message 120 | ; 121 | ; ================================= 122 | 123 | process_note_on_learn 124 | ; Check for zero velocity (note off) 125 | movf TEMP_ISR,f 126 | btfsc STATUS,Z 127 | retfie 128 | 129 | ; store the note number. 130 | movfw INBOUND_D0 131 | movwf FIRST_NOTE 132 | 133 | ; advance to next step in learn procedure 134 | bsf STATE_FLAGS,3 135 | retfie 136 | 137 | ; ================================= 138 | ; 139 | ; handle Timer 0 expiry 140 | ; 141 | ; ================================= 142 | 143 | handle_timer_0_learn 144 | ; blinking STBY LED stuff 145 | bcf INTCON,TMR0IF 146 | decfsz COUNTER_T0,f 147 | retfie 148 | 149 | movlw COUNTER_T0_MAX 150 | movwf COUNTER_T0 151 | movlw B'00000100' 152 | xorwf PORTC,f 153 | retfie 154 | 155 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 156 | 157 | end 158 | 159 | -------------------------------------------------------------------------------- /src/boot.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; boot.asm 9 | ; 10 | ; Board initialization 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | 16 | EXTERN start_normal_vector 17 | EXTERN start_learn_vector 18 | EXTERN isr_normal_vector 19 | EXTERN isr_learn_vector 20 | EXTERN isr_fupdate 21 | EXTERN compute_checksum 22 | 23 | ; ================================= 24 | ; 25 | ; vectors 26 | ; 27 | ; ================================= 28 | 29 | reset_code code 0x0000 30 | goto go_boot 31 | isr_code code 0x0004 32 | ; new context 33 | ; clrf STATUS 34 | ; clrf BSR 35 | clrf PCLATH 36 | ; check for firmware update / learn mode 37 | btfsc STATE_FLAGS,0 38 | goto isr_select 39 | ; normal operation isr 40 | pagesel isr_normal_vector 41 | goto isr_normal_vector 42 | 43 | isr_select 44 | ; choose alternate isr 45 | btfss STATE_FLAGS,2 46 | goto isr_fupdate 47 | 48 | pagesel isr_learn_vector 49 | goto isr_learn_vector 50 | 51 | 52 | boot_code code 0x0700 53 | 54 | go_boot 55 | 56 | ; ================================= 57 | ; 58 | ; boot 59 | ; 60 | ; ================================= 61 | 62 | ; Init the output ports & clock source 63 | 64 | ; Configure Timer 0 and PORTB pull-ups 65 | ; pull-ups off 66 | ; timer as slow as possible 67 | banksel OPTION_REG 68 | movlw B'10000111' 69 | movwf OPTION_REG 70 | 71 | ; Init output ports 72 | clrf BSR 73 | clrf PORTA 74 | clrf PORTB 75 | ; start with LEDs off 76 | movlw B'11001100' 77 | movwf PORTC 78 | clrf PORTD 79 | clrf PORTE 80 | ; banksel LATA 81 | ; clrf LATA 82 | ; clrf LATB 83 | ; clrf LATD 84 | ; clrf LATE 85 | banksel ANSELA 86 | clrf ANSELA 87 | clrf ANSELB 88 | clrf ANSELD 89 | clrf ANSELE 90 | 91 | ; Configure the internal clock 92 | banksel OSCCON 93 | movlw B'11110000' 94 | movwf OSCCON 95 | 96 | ; Configure port A for digital i/o. 97 | banksel TRISA 98 | movlw B'01111111' 99 | movwf TRISA 100 | 101 | ; Configure port B for digital i/o. 102 | movlw B'11111111' 103 | movwf TRISB 104 | 105 | ; Configure port C for digital i/o. 106 | movlw B'11100000' 107 | movwf TRISC 108 | 109 | ; Configure port D for digital i/o. 110 | movlw B'11111111' 111 | movwf TRISD 112 | 113 | ; Configure port E for digital i/o. 114 | movlw B'11111000' 115 | movwf TRISE 116 | 117 | 118 | ; ================================= 119 | ; 120 | ; Set up the USART 121 | ; 122 | ; ================================= 123 | 124 | ; Set up the baud rate generator 125 | ; 32 MHz / 31.25 kHz / 16 - 1 = 63 126 | ; 32 MHz / [16 (63 + 1)] = 31250 127 | banksel SPBRGL 128 | movlw D'63' 129 | movwf SPBRGL 130 | ; Set the transmit control bits 131 | movlw B'00100110' 132 | movwf TXSTA 133 | ; Set the receive control bits 134 | movlw B'10010000' 135 | movwf RCSTA 136 | 137 | ; Enable receive interrupts 138 | banksel PIE1 139 | bsf PIE1,RCIE 140 | 141 | ; init state flags 142 | clrf BSR 143 | clrf STATE_FLAGS 144 | ; check for PRGM input 145 | btfss PORTA,5 146 | goto fupdate_wait 147 | 148 | ; firmware checksum 149 | call compute_checksum 150 | ; normal operation 151 | pagesel start_normal_vector 152 | goto start_normal_vector 153 | 154 | fupdate_wait 155 | ; set LEDs 156 | movlw B'11000100' 157 | movwf PORTC 158 | ; set flag for fupdate mode and for learn mode 159 | bsf STATE_FLAGS,0 160 | ; Listen for incoming MIDI 161 | movlw B'11000000' 162 | movwf INTCON 163 | ; Check if the PRGM0 input is released. 164 | ; If not, wait forever for update sysex. 165 | btfss PORTA,5 166 | goto $-1 167 | ; PRGM0 released--enter learn mode 168 | bcf INTCON,GIE 169 | nop 170 | nop 171 | bsf STATE_FLAGS,2 172 | ; firmware checksum 173 | call compute_checksum 174 | ; start learn mode 175 | pagesel start_learn_vector 176 | goto start_learn_vector 177 | 178 | 179 | 180 | 181 | 182 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 183 | 184 | end 185 | 186 | -------------------------------------------------------------------------------- /src/tx-map.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; tx-map.asm 9 | ; 10 | ; Map local keys on host to outbound MIDI notes 11 | ; 12 | tx_note_map code 0x3C00 13 | 14 | ; note numbers for each select line and data bit. 15 | ; used for sending notes from keyboard activity. 16 | ; 17 | ; 12 blocks, 8 bytes (note numbers) in each block. 18 | ; 19 | ; fill with 0xff. when bit 7 is set, this indicates that no midi note 20 | ; is associated with this particular select/data pattern. 21 | ; 0x3C00 22 | data 0xFF 23 | data 0xFF 24 | data 0xFF 25 | data 0xFF 26 | data 0xFF 27 | data 0xFF 28 | data 0xFF 29 | data 0xFF 30 | data 0xFF 31 | data 0xFF 32 | data 0xFF 33 | data 0xFF 34 | data 0xFF 35 | data 0xFF 36 | data 0xFF 37 | data 0xFF 38 | data 0xFF 39 | data 0xFF 40 | data 0xFF 41 | data 0xFF 42 | data 0xFF 43 | data 0xFF 44 | data 0xFF 45 | data 0xFF 46 | data 0xFF 47 | data 0xFF 48 | data 0xFF 49 | data 0xFF 50 | data 0xFF 51 | data 0xFF 52 | data 0xFF 53 | data 0xFF 54 | data 0xFF 55 | data 0xFF 56 | data 0xFF 57 | data 0xFF 58 | data 0xFF 59 | data 0xFF 60 | data 0xFF 61 | data 0xFF 62 | data 0xFF 63 | data 0xFF 64 | data 0xFF 65 | data 0xFF 66 | data 0xFF 67 | data 0xFF 68 | data 0xFF 69 | data 0xFF 70 | data 0xFF 71 | data 0xFF 72 | data 0xFF 73 | data 0xFF 74 | data 0xFF 75 | data 0xFF 76 | data 0xFF 77 | data 0xFF 78 | data 0xFF 79 | data 0xFF 80 | data 0xFF 81 | data 0xFF 82 | data 0xFF 83 | data 0xFF 84 | data 0xFF 85 | data 0xFF 86 | data 0xFF 87 | data 0xFF 88 | data 0xFF 89 | data 0xFF 90 | data 0xFF 91 | data 0xFF 92 | data 0xFF 93 | data 0xFF 94 | data 0xFF 95 | data 0xFF 96 | data 0xFF 97 | data 0xFF 98 | data 0xFF 99 | data 0xFF 100 | data 0xFF 101 | data 0xFF 102 | data 0xFF 103 | data 0xFF 104 | data 0xFF 105 | data 0xFF 106 | data 0xFF 107 | data 0xFF 108 | data 0xFF 109 | data 0xFF 110 | data 0xFF 111 | data 0xFF 112 | data 0xFF 113 | data 0xFF 114 | data 0xFF 115 | data 0xFF 116 | data 0xFF 117 | data 0xFF 118 | data 0xFF 119 | data 0xFF 120 | data 0xFF 121 | data 0xFF 122 | data 0xFF 123 | data 0xFF 124 | data 0xFF 125 | data 0xFF 126 | data 0xFF 127 | data 0xFF 128 | data 0xFF 129 | data 0xFF 130 | data 0xFF 131 | data 0xFF 132 | data 0xFF 133 | data 0xFF 134 | data 0xFF 135 | data 0xFF 136 | data 0xFF 137 | data 0xFF 138 | data 0xFF 139 | data 0xFF 140 | data 0xFF 141 | data 0xFF 142 | data 0xFF 143 | data 0xFF 144 | data 0xFF 145 | data 0xFF 146 | data 0xFF 147 | data 0xFF 148 | data 0xFF 149 | data 0xFF 150 | data 0xFF 151 | data 0xFF 152 | data 0xFF 153 | data 0xFF 154 | data 0xFF 155 | data 0xFF 156 | data 0xFF 157 | data 0xFF 158 | data 0xFF 159 | data 0xFF 160 | data 0xFF 161 | data 0xFF 162 | data 0xFF 163 | data 0xFF 164 | data 0xFF 165 | data 0xFF 166 | data 0xFF 167 | data 0xFF 168 | data 0xFF 169 | data 0xFF 170 | data 0xFF 171 | data 0xFF 172 | data 0xFF 173 | data 0xFF 174 | data 0xFF 175 | data 0xFF 176 | data 0xFF 177 | data 0xFF 178 | data 0xFF 179 | data 0xFF 180 | data 0xFF 181 | data 0xFF 182 | data 0xFF 183 | data 0xFF 184 | data 0xFF 185 | data 0xFF 186 | data 0xFF 187 | data 0xFF 188 | data 0xFF 189 | data 0xFF 190 | data 0xFF 191 | data 0xFF 192 | data 0xFF 193 | data 0xFF 194 | data 0xFF 195 | data 0xFF 196 | data 0xFF 197 | data 0xFF 198 | data 0xFF 199 | data 0xFF 200 | data 0xFF 201 | data 0xFF 202 | data 0xFF 203 | data 0xFF 204 | data 0xFF 205 | data 0xFF 206 | data 0xFF 207 | data 0xFF 208 | data 0xFF 209 | data 0xFF 210 | data 0xFF 211 | data 0xFF 212 | data 0xFF 213 | data 0xFF 214 | data 0xFF 215 | data 0xFF 216 | data 0xFF 217 | data 0xFF 218 | data 0xFF 219 | data 0xFF 220 | data 0xFF 221 | data 0xFF 222 | data 0xFF 223 | data 0xFF 224 | data 0xFF 225 | data 0xFF 226 | data 0xFF 227 | data 0xFF 228 | data 0xFF 229 | data 0xFF 230 | data 0xFF 231 | data 0xFF 232 | data 0xFF 233 | data 0xFF 234 | data 0xFF 235 | data 0xFF 236 | data 0xFF 237 | data 0xFF 238 | data 0xFF 239 | data 0xFF 240 | data 0xFF 241 | data 0xFF 242 | data 0xFF 243 | data 0xFF 244 | data 0xFF 245 | data 0xFF 246 | data 0xFF 247 | data 0xFF 248 | data 0xFF 249 | data 0xFF 250 | data 0xFF 251 | data 0xFF 252 | data 0xFF 253 | data 0xFF 254 | data 0xFF 255 | data 0xFF 256 | data 0xFF 257 | data 0xFF 258 | data 0xFF 259 | data 0xFF 260 | data 0xFF 261 | data 0xFF 262 | data 0xFF 263 | data 0xFF 264 | data 0xFF 265 | data 0xFF 266 | data 0xFF 267 | data 0xFF 268 | data 0xFF 269 | data 0xFF 270 | data 0xFF 271 | data 0xFF 272 | data 0xFF 273 | data 0xFF 274 | data 0xFF 275 | data 0xFF 276 | data 0xFF 277 | data 0xFF 278 | 279 | end 280 | -------------------------------------------------------------------------------- /src/normal-isr.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; normal-isr.asm 9 | ; 10 | ; Interrupt service routines. 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | 16 | ; ================================================================== 17 | ; ================================================================== 18 | ; 19 | ; ISR 20 | ; 21 | ; ================================================================== 22 | ; ================================================================== 23 | 24 | isr_normal_vector code 0x0804 25 | GLOBAL isr_normal_vector 26 | isr_normal_vector 27 | ; goto isr_normal 28 | ;isr_normal code 29 | isr_normal 30 | ; New context 31 | clrf BSR 32 | 33 | ; Check for serial receive 34 | btfsc PIR1,RCIF 35 | goto handle_rx 36 | 37 | ; Check for timer0 expiry 38 | btfsc INTCON,TMR0IF 39 | goto handle_timer_0 40 | 41 | retfie 42 | 43 | ; ================================= 44 | ; 45 | ; Handle Timer 0 expiry 46 | ; 47 | ; ================================= 48 | 49 | handle_timer_0 50 | bcf INTCON,TMR0IE 51 | bcf INTCON,TMR0IF 52 | ; Turn off blinked LED 53 | movlw B'00001000' 54 | movwf PORTC 55 | retfie 56 | 57 | ; ================================= 58 | ; 59 | ; process incoming midi byte 60 | ; 61 | ; ================================= 62 | 63 | handle_rx 64 | ; Grab the incoming byte 65 | banksel RCREG 66 | movfw RCREG 67 | movwf TXREG 68 | movwf TEMP_ISR 69 | clrf BSR 70 | 71 | ; If byte is a data byte, process it 72 | btfss TEMP_ISR,7 73 | goto process_data_byte 74 | 75 | process_status_byte 76 | ; Don't let real time messages interrupt running status - check for them now 77 | ; real time message is status B'11111xxx' 78 | comf TEMP_ISR,w 79 | andlw B'11111000' 80 | btfsc STATUS,Z 81 | retfie 82 | ; check for note-off (0x8?) 83 | movfw NOTE_OFF_STATUS 84 | subwf TEMP_ISR,f 85 | bz flag_note_off 86 | ; Check for note-on (0x9?) 87 | movlw 0x10 88 | subwf TEMP_ISR,f 89 | bz flag_note_on 90 | ; All other status bytes and subsequent data are ignored. 91 | ignore_message 92 | ; Data will be ignored for other status bytes. 93 | clrf MESSAGE_TYPE 94 | retfie 95 | 96 | flag_note_on 97 | movlw NOTE_ON 98 | movwf MESSAGE_TYPE 99 | ; reset byte count 100 | bcf STATE_FLAGS,1 101 | retfie 102 | flag_note_off 103 | movlw NOTE_OFF 104 | movwf MESSAGE_TYPE 105 | ; reset byte count 106 | bcf STATE_FLAGS,1 107 | retfie 108 | 109 | 110 | process_data_byte 111 | ; always store the first data byte 112 | btfss STATE_FLAGS,1 113 | goto store_d0 114 | 115 | ; second data byte. reset byte count and check for relevant status 116 | bcf STATE_FLAGS,1 117 | ; ignore data for message other than note off/on 118 | btfsc MESSAGE_TYPE,0 119 | goto process_note_off 120 | btfsc MESSAGE_TYPE,1 121 | goto process_note_on 122 | retfie 123 | 124 | store_d0 125 | ; subtract first note from D0 to get internal note number. 126 | ; wrap at 128. 127 | movfw FIRST_NOTE 128 | subwf TEMP_ISR,w 129 | andlw B'01111111' 130 | movwf INBOUND_D0 131 | bsf STATE_FLAGS,1 132 | ; blink activity LED 133 | clrf PORTC 134 | clrf TMR0 135 | bcf INTCON,TMR0IF 136 | bsf INTCON,TMR0IE 137 | retfie 138 | 139 | ; ================================= 140 | ; 141 | ; handle Note Off message 142 | ; 143 | ; ================================= 144 | 145 | process_note_off 146 | ; clear the key bit for this note number. 147 | movfw INBOUND_D0 148 | movwf FSR0L 149 | movlw 0xBD 150 | movwf FSR0H 151 | ; 3-byte record for each note number: 152 | ; - lo indirect address for keybits byte 153 | movfw INDF0 154 | movwf FSR1L 155 | ; - hi indirect address for keybits byte 156 | incf FSR0H,f 157 | movfw INDF0 158 | movwf FSR1H 159 | ; - bitmask to apply to keybits byte 160 | incf FSR0H,f 161 | comf INDF0,w 162 | andwf INDF1,f 163 | ; blink the activity LED 164 | ; clrf PORTC 165 | ; clrf TMR0 166 | ; bcf INTCON,TMR0IF 167 | ; bsf INTCON,TMR0IE 168 | retfie 169 | 170 | ; ================================= 171 | ; 172 | ; handle Note On message 173 | ; 174 | ; ================================= 175 | 176 | process_note_on 177 | ; Check for zero velocity (note off) 178 | movf TEMP_ISR,f 179 | bz process_note_off 180 | 181 | ; set the key bit for this note number. 182 | movfw INBOUND_D0 183 | movwf FSR0L 184 | movlw 0xBD 185 | movwf FSR0H 186 | ; 3-byte record for each note number: 187 | ; - lo indirect address for keybits byte 188 | movfw INDF0 189 | movwf FSR1L 190 | ; - hi indirect address for keybits byte 191 | incf FSR0H,f 192 | movfw INDF0 193 | movwf FSR1H 194 | ; - bitmask to apply to keybits byte 195 | incf FSR0H,f 196 | movfw INDF0 197 | iorwf INDF1,f 198 | ; blink the activity LED 199 | ; clrf PORTC 200 | ; clrf TMR0 201 | ; bcf INTCON,TMR0IF 202 | ; bsf INTCON,TMR0IE 203 | retfie 204 | 205 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 206 | 207 | end 208 | 209 | -------------------------------------------------------------------------------- /src/eedata.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; eedata.asm 9 | ; 10 | ; Data eeprom initial values 11 | ; 12 | list p=16F1939 13 | #include 14 | 15 | ; ================================= 16 | ; 17 | ; EEPROM initial values 18 | ; 19 | ; ================================= 20 | 21 | 22 | eedata code 0xF000 23 | ; Version 24 | data 0x00 25 | ; Checksum 26 | data 0x31 27 | data 0x87 28 | ; Channel 29 | data 0x00 30 | ; First Note 31 | data 0x00 32 | ; Last Note 33 | data 0x00 34 | ; Setup Count 35 | data 0x00 36 | ; Reserved (248 bytes) 37 | data 0x00 38 | data 0x00 39 | data 0x00 40 | data 0x00 41 | data 0x00 42 | data 0x00 43 | data 0x00 44 | data 0x00 45 | data 0x00 46 | data 0x00 47 | data 0x00 48 | data 0x00 49 | data 0x00 50 | data 0x00 51 | data 0x00 52 | data 0x00 53 | data 0x00 54 | data 0x00 55 | data 0x00 56 | data 0x00 57 | data 0x00 58 | data 0x00 59 | data 0x00 60 | data 0x00 61 | data 0x00 62 | data 0x00 63 | data 0x00 64 | data 0x00 65 | data 0x00 66 | data 0x00 67 | data 0x00 68 | data 0x00 69 | data 0x00 70 | data 0x00 71 | data 0x00 72 | data 0x00 73 | data 0x00 74 | data 0x00 75 | data 0x00 76 | data 0x00 77 | data 0x00 78 | data 0x00 79 | data 0x00 80 | data 0x00 81 | data 0x00 82 | data 0x00 83 | data 0x00 84 | data 0x00 85 | data 0x00 86 | data 0x00 87 | data 0x00 88 | data 0x00 89 | data 0x00 90 | data 0x00 91 | data 0x00 92 | data 0x00 93 | data 0x00 94 | data 0x00 95 | data 0x00 96 | data 0x00 97 | data 0x00 98 | data 0x00 99 | data 0x00 100 | data 0x00 101 | data 0x00 102 | data 0x00 103 | data 0x00 104 | data 0x00 105 | data 0x00 106 | data 0x00 107 | data 0x00 108 | data 0x00 109 | data 0x00 110 | data 0x00 111 | data 0x00 112 | data 0x00 113 | data 0x00 114 | data 0x00 115 | data 0x00 116 | data 0x00 117 | data 0x00 118 | data 0x00 119 | data 0x00 120 | data 0x00 121 | data 0x00 122 | data 0x00 123 | data 0x00 124 | data 0x00 125 | data 0x00 126 | data 0x00 127 | data 0x00 128 | data 0x00 129 | data 0x00 130 | data 0x00 131 | data 0x00 132 | data 0x00 133 | data 0x00 134 | data 0x00 135 | data 0x00 136 | data 0x00 137 | data 0x00 138 | data 0x00 139 | data 0x00 140 | data 0x00 141 | data 0x00 142 | data 0x00 143 | data 0x00 144 | data 0x00 145 | data 0x00 146 | data 0x00 147 | data 0x00 148 | data 0x00 149 | data 0x00 150 | data 0x00 151 | data 0x00 152 | data 0x00 153 | data 0x00 154 | data 0x00 155 | data 0x00 156 | data 0x00 157 | data 0x00 158 | data 0x00 159 | data 0x00 160 | data 0x00 161 | data 0x00 162 | data 0x00 163 | data 0x00 164 | data 0x00 165 | data 0x00 166 | data 0x00 167 | data 0x00 168 | data 0x00 169 | data 0x00 170 | data 0x00 171 | data 0x00 172 | data 0x00 173 | data 0x00 174 | data 0x00 175 | data 0x00 176 | data 0x00 177 | data 0x00 178 | data 0x00 179 | data 0x00 180 | data 0x00 181 | data 0x00 182 | data 0x00 183 | data 0x00 184 | data 0x00 185 | data 0x00 186 | data 0x00 187 | data 0x00 188 | data 0x00 189 | data 0x00 190 | data 0x00 191 | data 0x00 192 | data 0x00 193 | data 0x00 194 | data 0x00 195 | data 0x00 196 | data 0x00 197 | data 0x00 198 | data 0x00 199 | data 0x00 200 | data 0x00 201 | data 0x00 202 | data 0x00 203 | data 0x00 204 | data 0x00 205 | data 0x00 206 | data 0x00 207 | data 0x00 208 | data 0x00 209 | data 0x00 210 | data 0x00 211 | data 0x00 212 | data 0x00 213 | data 0x00 214 | data 0x00 215 | data 0x00 216 | data 0x00 217 | data 0x00 218 | data 0x00 219 | data 0x00 220 | data 0x00 221 | data 0x00 222 | data 0x00 223 | data 0x00 224 | data 0x00 225 | data 0x00 226 | data 0x00 227 | data 0x00 228 | data 0x00 229 | data 0x00 230 | data 0x00 231 | data 0x00 232 | data 0x00 233 | data 0x00 234 | data 0x00 235 | data 0x00 236 | data 0x00 237 | data 0x00 238 | data 0x00 239 | data 0x00 240 | data 0x00 241 | data 0x00 242 | data 0x00 243 | data 0x00 244 | data 0x00 245 | data 0x00 246 | data 0x00 247 | data 0x00 248 | data 0x00 249 | data 0x00 250 | data 0x00 251 | data 0x00 252 | data 0x00 253 | data 0x00 254 | data 0x00 255 | data 0x00 256 | data 0x00 257 | data 0x00 258 | data 0x00 259 | data 0x00 260 | data 0x00 261 | data 0x00 262 | data 0x00 263 | data 0x00 264 | data 0x00 265 | data 0x00 266 | data 0x00 267 | data 0x00 268 | data 0x00 269 | data 0x00 270 | data 0x00 271 | data 0x00 272 | data 0x00 273 | data 0x00 274 | data 0x00 275 | data 0x00 276 | data 0x00 277 | data 0x00 278 | data 0x00 279 | data 0x00 280 | data 0x00 281 | data 0x00 282 | data 0x00 283 | data 0x00 284 | data 0x00 285 | 286 | end 287 | -------------------------------------------------------------------------------- /src/rx-map.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; rx-map.asm 9 | ; 10 | ; Map incoming MIDI notes to matrix keys 11 | ; 12 | note_map_low code 0x3D00 13 | 14 | ; rx note map: select address and data bit for each MIDI note. 15 | ; used to trigger keys from MIDI input. 16 | ;0 17 | data 0x00 18 | data 0x00 19 | data 0x00 20 | data 0x00 21 | data 0x00 22 | data 0x00 23 | data 0x00 24 | data 0x00 25 | data 0x00 26 | data 0x00 27 | ; 10 28 | data 0x00 29 | data 0x00 30 | data 0x00 31 | data 0x00 32 | data 0x00 33 | data 0x00 34 | data 0x00 35 | data 0x00 36 | data 0x00 37 | data 0x00 38 | ; 20 39 | data 0x00 40 | data 0x00 41 | data 0x00 42 | data 0x00 43 | data 0x00 44 | data 0x00 45 | data 0x00 46 | data 0x00 47 | data 0x00 48 | data 0x00 49 | ; 30 50 | data 0x00 51 | data 0x00 52 | data 0x00 53 | data 0x00 54 | data 0x00 55 | data 0x00 56 | data 0x00 57 | data 0x00 58 | data 0x00 59 | data 0x00 60 | ; 40 61 | data 0x00 62 | data 0x00 63 | data 0x00 64 | data 0x00 65 | data 0x00 66 | data 0x00 67 | data 0x00 68 | data 0x00 69 | data 0x00 70 | data 0x00 71 | ; 50 72 | data 0x00 73 | data 0x00 74 | data 0x00 75 | data 0x00 76 | data 0x00 77 | data 0x00 78 | data 0x00 79 | data 0x00 80 | data 0x00 81 | data 0x00 82 | ; 60 83 | data 0x00 84 | data 0x00 85 | data 0x00 86 | data 0x00 87 | data 0x00 88 | data 0x00 89 | data 0x00 90 | data 0x00 91 | data 0x00 92 | data 0x00 93 | ; 70 94 | data 0x00 95 | data 0x00 96 | data 0x00 97 | data 0x00 98 | data 0x00 99 | data 0x00 100 | data 0x00 101 | data 0x00 102 | data 0x00 103 | data 0x00 104 | ; 80 105 | data 0x00 106 | data 0x00 107 | data 0x00 108 | data 0x00 109 | data 0x00 110 | data 0x00 111 | data 0x00 112 | data 0x00 113 | data 0x00 114 | data 0x00 115 | ; 90 116 | data 0x00 117 | data 0x00 118 | data 0x00 119 | data 0x00 120 | data 0x00 121 | data 0x00 122 | data 0x00 123 | data 0x00 124 | data 0x00 125 | data 0x00 126 | ; 100 127 | data 0x00 128 | data 0x00 129 | data 0x00 130 | data 0x00 131 | data 0x00 132 | data 0x00 133 | data 0x00 134 | data 0x00 135 | data 0x00 136 | data 0x00 137 | ; 110 138 | data 0x00 139 | data 0x00 140 | data 0x00 141 | data 0x00 142 | data 0x00 143 | data 0x00 144 | data 0x00 145 | data 0x00 146 | data 0x00 147 | data 0x00 148 | ; 120 149 | data 0x00 150 | data 0x00 151 | data 0x00 152 | data 0x00 153 | data 0x00 154 | data 0x00 155 | data 0x00 156 | data 0x00 157 | 158 | note_map_high code 0x3E00 159 | 160 | ; note map: key bit address high byte 161 | ; 0 162 | data 0x22 ; 0x00 : 000 163 | data 0x22 ; 0x01 : 001 164 | data 0x22 ; 0x02 : 002 165 | data 0x22 ; 0x03 : 003 166 | data 0x22 ; 0x04 : 004 167 | data 0x22 ; 0x05 : 005 168 | data 0x22 ; 0x06 : 006 169 | data 0x22 ; 0x07 : 007 170 | data 0x22 ; 0x08 : 008 171 | data 0x22 ; 0x09 : 009 172 | ; 10 173 | data 0x22 ; 0x0A : 010 174 | data 0x22 ; 0x0B : 011 175 | data 0x22 ; 0x0C : 012 176 | data 0x22 ; 0x0D : 013 177 | data 0x22 ; 0x0E : 014 178 | data 0x22 ; 0x0F : 015 179 | data 0x22 ; 0x10 : 016 180 | data 0x22 ; 0x11 : 017 181 | data 0x22 ; 0x12 : 018 182 | data 0x22 ; 0x13 : 019 183 | ; 20 184 | data 0x22 ; 0x14 : 020 185 | data 0x22 ; 0x15 : 021 186 | data 0x22 ; 0x16 : 022 187 | data 0x22 ; 0x17 : 023 188 | data 0x22 ; 0x18 : 024 189 | data 0x22 ; 0x19 : 025 190 | data 0x22 ; 0x1A : 026 191 | data 0x22 ; 0x1B : 027 192 | data 0x22 ; 0x1C : 028 193 | data 0x22 ; 0x1D : 029 194 | ; 30 195 | data 0x22 ; 0x1E : 030 196 | data 0x22 ; 0x1F : 031 197 | data 0x22 ; 0x20 : 032 198 | data 0x22 ; 0x21 : 033 199 | data 0x22 ; 0x22 : 034 200 | data 0x22 ; 0x23 : 035 201 | data 0x22 ; 0x24 : 036 202 | data 0x22 ; 0x25 : 037 203 | data 0x22 ; 0x26 : 038 204 | data 0x22 ; 0x27 : 039 205 | ; 40 206 | data 0x22 ; 0x28 : 040 207 | data 0x22 ; 0x29 : 041 208 | data 0x22 ; 0x2A : 042 209 | data 0x22 ; 0x2B : 043 210 | data 0x22 ; 0x2C : 044 211 | data 0x22 ; 0x2D : 045 212 | data 0x22 ; 0x2E : 046 213 | data 0x22 ; 0x2F : 047 214 | data 0x22 ; 0x30 : 048 215 | data 0x22 ; 0x31 : 049 216 | ; 50 217 | data 0x22 ; 0x32 : 050 218 | data 0x22 ; 0x33 : 051 219 | data 0x22 ; 0x34 : 052 220 | data 0x22 ; 0x35 : 053 221 | data 0x22 ; 0x36 : 054 222 | data 0x22 ; 0x37 : 055 223 | data 0x22 ; 0x38 : 056 224 | data 0x22 ; 0x39 : 057 225 | data 0x22 ; 0x3A : 058 226 | data 0x22 ; 0x3B : 059 227 | ; 60 228 | data 0x22 ; 0x3C : 060 229 | data 0x22 ; 0x3D : 061 230 | data 0x22 ; 0x3E : 062 231 | data 0x22 ; 0x3F : 063 232 | data 0x22 ; 0x40 : 064 233 | data 0x22 ; 0x41 : 065 234 | data 0x22 ; 0x42 : 066 235 | data 0x22 ; 0x43 : 067 236 | data 0x22 ; 0x44 : 068 237 | data 0x22 ; 0x45 : 069 238 | ; 70 239 | data 0x22 ; 0x46 : 070 240 | data 0x22 ; 0x47 : 071 241 | data 0x22 ; 0x48 : 072 242 | data 0x22 ; 0x49 : 073 243 | data 0x22 ; 0x4A : 074 244 | data 0x22 ; 0x4B : 075 245 | data 0x22 ; 0x4C : 076 246 | data 0x22 ; 0x4D : 077 247 | data 0x22 ; 0x4E : 078 248 | data 0x22 ; 0x4F : 079 249 | ; 80 250 | data 0x22 ; 0x50 : 080 251 | data 0x22 ; 0x51 : 081 252 | data 0x22 ; 0x52 : 082 253 | data 0x22 ; 0x53 : 083 254 | data 0x22 ; 0x54 : 084 255 | data 0x22 ; 0x55 : 085 256 | data 0x22 ; 0x56 : 086 257 | data 0x22 ; 0x57 : 087 258 | data 0x22 ; 0x58 : 088 259 | data 0x22 ; 0x59 : 089 260 | ; 90 261 | data 0x22 ; 0x5A : 090 262 | data 0x22 ; 0x5B : 091 263 | data 0x22 ; 0x5C : 092 264 | data 0x22 ; 0x5D : 093 265 | data 0x22 ; 0x5E : 094 266 | data 0x22 ; 0x5F : 095 267 | data 0x22 ; 0x60 : 096 268 | data 0x22 ; 0x61 : 097 269 | data 0x22 ; 0x62 : 098 270 | data 0x22 ; 0x63 : 099 271 | ; 100 272 | data 0x22 ; 0x64 : 100 273 | data 0x22 ; 0x65 : 101 274 | data 0x22 ; 0x66 : 102 275 | data 0x22 ; 0x67 : 103 276 | data 0x22 ; 0x68 : 104 277 | data 0x22 ; 0x69 : 105 278 | data 0x22 ; 0x6A : 106 279 | data 0x22 ; 0x6B : 107 280 | data 0x22 ; 0x6C : 108 281 | data 0x22 ; 0x6D : 109 282 | ; 110 283 | data 0x22 ; 0x6E : 110 284 | data 0x22 ; 0x6F : 111 285 | data 0x22 ; 0x70 : 112 286 | data 0x22 ; 0x71 : 113 287 | data 0x22 ; 0x72 : 114 288 | data 0x22 ; 0x73 : 115 289 | data 0x22 ; 0x74 : 116 290 | data 0x22 ; 0x75 : 117 291 | data 0x22 ; 0x76 : 118 292 | data 0x22 ; 0x77 : 119 293 | ; 120 294 | data 0x22 ; 0x78 : 120 295 | data 0x22 ; 0x79 : 121 296 | data 0x22 ; 0x7A : 122 297 | data 0x22 ; 0x7B : 123 298 | data 0x22 ; 0x7C : 124 299 | data 0x22 ; 0x7D : 125 300 | data 0x22 ; 0x7E : 126 301 | data 0x22 ; 0x7F : 127 302 | 303 | note_map_bitmask code 0x3F00 304 | 305 | ; note map: key bitmask 306 | ; 0 307 | data 0x00 308 | data 0x00 309 | data 0x00 310 | data 0x00 311 | data 0x00 312 | data 0x00 313 | data 0x00 314 | data 0x00 315 | data 0x00 316 | data 0x00 317 | ; 10 318 | data 0x00 319 | data 0x00 320 | data 0x00 321 | data 0x00 322 | data 0x00 323 | data 0x00 324 | data 0x00 325 | data 0x00 326 | data 0x00 327 | data 0x00 328 | ; 20 329 | data 0x00 330 | data 0x00 331 | data 0x00 332 | data 0x00 333 | data 0x00 334 | data 0x00 335 | data 0x00 336 | data 0x00 337 | data 0x00 338 | data 0x00 339 | ; 30 340 | data 0x00 341 | data 0x00 342 | data 0x00 343 | data 0x00 344 | data 0x00 345 | data 0x00 346 | data 0x00 347 | data 0x00 348 | data 0x00 349 | data 0x00 350 | ; 40 351 | data 0x00 352 | data 0x00 353 | data 0x00 354 | data 0x00 355 | data 0x00 356 | data 0x00 357 | data 0x00 358 | data 0x00 359 | data 0x00 360 | data 0x00 361 | ; 50 362 | data 0x00 363 | data 0x00 364 | data 0x00 365 | data 0x00 366 | data 0x00 367 | data 0x00 368 | data 0x00 369 | data 0x00 370 | data 0x00 371 | data 0x00 372 | ; 60 373 | data 0x00 374 | data 0x00 375 | data 0x00 376 | data 0x00 377 | data 0x00 378 | data 0x00 379 | data 0x00 380 | data 0x00 381 | data 0x00 382 | data 0x00 383 | ; 70 384 | data 0x00 385 | data 0x00 386 | data 0x00 387 | data 0x00 388 | data 0x00 389 | data 0x00 390 | data 0x00 391 | data 0x00 392 | data 0x00 393 | data 0x00 394 | ; 80 395 | data 0x00 396 | data 0x00 397 | data 0x00 398 | data 0x00 399 | data 0x00 400 | data 0x00 401 | data 0x00 402 | data 0x00 403 | data 0x00 404 | data 0x00 405 | ; 90 406 | data 0x00 407 | data 0x00 408 | data 0x00 409 | data 0x00 410 | data 0x00 411 | data 0x00 412 | data 0x00 413 | data 0x00 414 | data 0x00 415 | data 0x00 416 | ; 100 417 | data 0x00 418 | data 0x00 419 | data 0x00 420 | data 0x00 421 | data 0x00 422 | data 0x00 423 | data 0x00 424 | data 0x00 425 | data 0x00 426 | data 0x00 427 | ; 110 428 | data 0x00 429 | data 0x00 430 | data 0x00 431 | data 0x00 432 | data 0x00 433 | data 0x00 434 | data 0x00 435 | data 0x00 436 | data 0x00 437 | data 0x00 438 | ; 120 439 | data 0x00 440 | data 0x00 441 | data 0x00 442 | data 0x00 443 | data 0x00 444 | data 0x00 445 | data 0x00 446 | data 0x00 447 | 448 | 449 | end 450 | -------------------------------------------------------------------------------- /src/normal-operation.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; isr.asm 9 | ; 10 | ; Main program loop 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | 16 | ; ================================= 17 | ; 18 | ; Normal Operation 19 | ; 20 | ; ================================= 21 | 22 | start_normal_vector code 0x0800 23 | GLOBAL start_normal_vector 24 | start_normal_vector 25 | goto start_normal 26 | ;start_normal code 27 | start_normal code 0x0C00 28 | start_normal 29 | 30 | 31 | ; ================================= 32 | ; 33 | ; Variable Init 34 | ; 35 | ; ================================= 36 | clrf STATE_FLAGS 37 | ; check mode 38 | btfss PORTA,4 39 | bsf STATE_FLAGS,4 40 | ; load channel and first note setting from data PROM. 41 | banksel EEADRL 42 | movlw PROM_CHANNEL 43 | movwf EEADRL 44 | bcf EECON1,EEPGD 45 | bsf EECON1,RD 46 | ; store channel in TEMP 47 | movfw EEDATL 48 | movwf TEMP 49 | ; store first note in TEMP_2 50 | incf EEADRL,f 51 | bsf EECON1,RD 52 | movfw EEDATL 53 | movwf TEMP_2 54 | ; store setup flag in TEMP_3 55 | incf EEADRL,f 56 | bsf EECON1,RD 57 | movfw EEDATL 58 | movwf TEMP_3 59 | clrf BSR 60 | ; init channel 61 | movfw TEMP 62 | addlw 0x80 63 | movwf NOTE_OFF_STATUS 64 | addlw 0x10 65 | movwf NOTE_ON_STATUS 66 | ; init first note 67 | movfw TEMP_2 68 | movwf FIRST_NOTE 69 | ; if setup procedure has not been completed, don't operate. 70 | ; btfss TEMP_3,0 71 | ; goto normal_no_setup 72 | 73 | ; wipe the key state buffer 74 | ; there are 512 bytes in buffer (9 select lines: 2^9 bytes) 75 | clrf FSR0L 76 | movlw 0x22 77 | movwf FSR0H 78 | key_bit_wipe_loop 79 | clrf INDF0 80 | incfsz FSR0L,f 81 | goto key_bit_wipe_loop 82 | 83 | incf FSR0H,f 84 | key_bit_wipe_loop2 85 | clrf INDF0 86 | incfsz FSR0L,f 87 | goto key_bit_wipe_loop2 88 | 89 | ; set up pointer to key state bits 90 | ; INDF0 should point to 0x2200 91 | decf FSR0H,f 92 | 93 | ; ================================= 94 | ; 95 | ; Configure Timers 96 | ; 97 | ; ================================= 98 | 99 | ; ================================= 100 | ; 101 | ; LED Init 102 | ; 103 | ; ================================= 104 | 105 | ; LED init & test 106 | clrf PORTC 107 | call blink_delay 108 | call blink_delay 109 | call blink_delay 110 | 111 | ; check matrix polarity 112 | ; if polarity input = high (pulled up), then clear PORTD bits 113 | ; if polarity input = low (pulled down), then set PORTD bits 114 | movlw 0xff 115 | movwf PORTD 116 | btfsc PORTC,5 117 | clrf PORTD 118 | 119 | ; Reset Activity LED 120 | movlw B'00001000' 121 | movwf PORTC 122 | 123 | 124 | ; ================================= 125 | ; 126 | ; MIDI Init 127 | ; 128 | ; ================================= 129 | 130 | ; Flush the FIFO 131 | banksel RCREG 132 | movfw RCREG 133 | movfw RCREG 134 | ; flush out any bytes & errors sitting around 135 | banksel RCSTA 136 | bcf RCSTA,CREN 137 | ; if TX mode, leave RX disabled. 138 | btfss STATE_FLAGS,4 139 | bsf RCSTA,CREN 140 | clrf BSR 141 | ; Flush more 142 | banksel RCREG 143 | movfw RCREG 144 | movfw RCREG 145 | clrf BSR 146 | ; Enable Interrupts 147 | movlw B'11000000' 148 | movwf INTCON 149 | 150 | ; ================================================================== 151 | ; ================================================================== 152 | ; 153 | ; MAIN LOOP 154 | ; 155 | ; ================================================================== 156 | ; ================================================================== 157 | 158 | ; check mode. 159 | btfsc STATE_FLAGS,4 160 | goto go_tx 161 | ; check polarity. If negative, we'll have to complement the select address. 162 | btfsc PORTC,5 163 | goto poll_rx_neg 164 | 165 | ; continuously load key states from select address onto data lines 166 | poll_rx_pos 167 | movfw PORTB 168 | movwf FSR0L 169 | bcf FSR0H,0 170 | btfsc PORTA,0 171 | bsf FSR0H,0 172 | bsf BSR,0 173 | comf INDF0,w 174 | movwf TRISD 175 | clrf BSR 176 | goto poll_rx_pos 177 | 178 | poll_rx_neg 179 | comf PORTB,w 180 | movwf FSR0L 181 | bcf FSR0H,0 182 | btfss PORTA,0 183 | bsf FSR0H,0 184 | bsf BSR,0 185 | comf INDF0,w 186 | movwf TRISD 187 | clrf BSR 188 | goto poll_rx_neg 189 | 190 | go_tx 191 | ; sample select & data states to get defaults. 192 | poll_tx_normal 193 | ; sample select & data. 194 | call take_snapshot_normal 195 | ; is number of active select lines exactly 1? 196 | decfsz TEMP_4,f 197 | goto poll_tx_normal 198 | ; new key activity? 199 | call point_to_key_data_normal 200 | movfw TEMP_3 201 | xorwf INDF0,w 202 | bz poll_tx_normal 203 | ; store change bit pattern in TEMP_4 204 | movwf TEMP_4 205 | ; does this key correspond to a note? 206 | call point_to_tx_map_normal 207 | btfsc INDF1,7 208 | goto poll_tx_normal 209 | ; groom the change bitmask so it has only one bit set. 210 | groom_0 211 | btfss TEMP_4,0 212 | goto groom_1 213 | movlw B'00000001' 214 | movwf TEMP_4 215 | goto groom_complete 216 | groom_1 217 | btfss TEMP_4,1 218 | goto groom_2 219 | movlw B'00000010' 220 | movwf TEMP_4 221 | goto groom_complete 222 | groom_2 223 | btfss TEMP_4,2 224 | goto groom_3 225 | movlw B'00000100' 226 | movwf TEMP_4 227 | goto groom_complete 228 | groom_3 229 | btfss TEMP_4,3 230 | goto groom_4 231 | movlw B'00001000' 232 | movwf TEMP_4 233 | goto groom_complete 234 | groom_4 235 | btfss TEMP_4,4 236 | goto groom_5 237 | movlw B'00010000' 238 | movwf TEMP_4 239 | goto groom_complete 240 | groom_5 241 | btfss TEMP_4,5 242 | goto groom_6 243 | movlw B'00100000' 244 | movwf TEMP_4 245 | goto groom_complete 246 | groom_6 247 | btfss TEMP_4,6 248 | goto groom_7 249 | movlw B'01000000' 250 | movwf TEMP_4 251 | goto groom_complete 252 | groom_7 253 | movlw B'10000000' 254 | movwf TEMP_4 255 | groom_complete 256 | ; send note on or off 257 | ; LED indication 258 | clrf PORTC 259 | clrf TMR0 260 | bcf INTCON,TMR0IF 261 | bsf INTCON,TMR0IE 262 | ; internal note number is in INDF1 263 | ; put velocity in TEMP_5 264 | movlw 0x7F 265 | movwf TEMP_5 266 | movfw TEMP_4 267 | andwf TEMP_3,w 268 | btfsc STATUS,Z 269 | clrf TEMP_5 270 | movfw NOTE_ON_STATUS 271 | call transmit_byte_normal 272 | movfw INDF1 273 | addwf FIRST_NOTE,w 274 | andlw B'01111111' 275 | call transmit_byte_normal 276 | movfw TEMP_5 277 | call transmit_byte_normal 278 | ; update key state. 279 | movfw TEMP_4 280 | xorwf INDF0,f 281 | goto poll_tx_normal 282 | 283 | ; ================================= 284 | ; 285 | ; delay to for slow LED blink 286 | ; 287 | ; ================================= 288 | blink_delay 289 | movlw 0xff 290 | movwf COUNTER_H 291 | blink_loop_a 292 | movlw 0xff 293 | movwf COUNTER_L 294 | blink_loop_b 295 | nop 296 | nop 297 | nop 298 | nop 299 | nop 300 | nop 301 | nop 302 | nop 303 | nop 304 | nop 305 | nop 306 | nop 307 | nop 308 | nop 309 | nop 310 | nop 311 | nop 312 | nop 313 | nop 314 | nop 315 | nop 316 | nop 317 | nop 318 | nop 319 | 320 | decfsz COUNTER_L,f 321 | goto blink_loop_b 322 | decfsz COUNTER_H,f 323 | goto blink_loop_a 324 | 325 | return 326 | 327 | ; ================================= 328 | ; 329 | ; take a snapshot of select and data lines 330 | ; select in TEMP_2:TEMP 331 | ; data in TEMP_3 332 | ; 333 | ; ================================= 334 | take_snapshot_normal 335 | ; TEMP: Select 8-1 336 | movfw PORTB 337 | movwf TEMP 338 | ; TEMP_2: Select 9 339 | movfw PORTA 340 | movwf TEMP_2 341 | ; TEMP_3: Data 1-8 342 | movfw PORTD 343 | movwf TEMP_3 344 | ; resample a to make sure snapshot is stable 345 | movfw PORTB 346 | subwf TEMP,w 347 | btfss STATUS,Z 348 | return 349 | movfw PORTA 350 | subwf TEMP_2,w 351 | btfss STATUS,Z 352 | return 353 | movfw PORTD 354 | subwf TEMP_3,w 355 | btfss STATUS,Z 356 | return 357 | ; check matrix polarity 358 | btfss PORTC,5 359 | goto count_active_select_normal 360 | ; negative polarity. complement everything. 361 | comf TEMP,f 362 | comf TEMP_2,f 363 | comf TEMP_3,f 364 | count_active_select_normal 365 | ; sample is only valid if the number of active select lines is 1 366 | ; store number of active select lines in TEMP_4 367 | clrf TEMP_4 368 | btfsc TEMP,0 369 | incf TEMP_4,f 370 | btfsc TEMP,1 371 | incf TEMP_4,f 372 | btfsc TEMP,2 373 | incf TEMP_4,f 374 | btfsc TEMP,3 375 | incf TEMP_4,f 376 | btfsc TEMP,4 377 | incf TEMP_4,f 378 | btfsc TEMP,5 379 | incf TEMP_4,f 380 | btfsc TEMP,6 381 | incf TEMP_4,f 382 | btfsc TEMP,7 383 | incf TEMP_4,f 384 | btfsc TEMP_2,0 385 | incf TEMP_4,f 386 | 387 | return 388 | 389 | ; ================================= 390 | ; 391 | ; Set up FSR0 to point to key state data 392 | ; FSR0L is select line number from 0-8. 393 | ; 394 | ; ================================= 395 | point_to_key_data_normal 396 | clrf FSR0H 397 | movlw KEY_BITS 398 | movwf FSR0L 399 | 400 | btfsc TEMP,0 401 | return 402 | incf FSR0L,f 403 | btfsc TEMP,1 404 | return 405 | incf FSR0L,f 406 | btfsc TEMP,2 407 | return 408 | incf FSR0L,f 409 | btfsc TEMP,3 410 | return 411 | incf FSR0L,f 412 | btfsc TEMP,4 413 | return 414 | incf FSR0L,f 415 | btfsc TEMP,5 416 | return 417 | incf FSR0L,f 418 | btfsc TEMP,6 419 | return 420 | incf FSR0L,f 421 | btfsc TEMP,7 422 | return 423 | ; at this point, TEMP_2,0 is assumed to be set 424 | incf FSR0L,f 425 | return 426 | 427 | point_to_tx_map_normal 428 | ; tx map info. one byte indexed by select 1-12 x data 1-8 429 | movlw 0xBC 430 | movwf FSR1H 431 | movlw 0x80 432 | movwf FSR1L 433 | ; point to correct block of 8. 434 | point_to_tx_map_select_normal 435 | btfsc TEMP,0 436 | goto point_to_tx_map_data_normal 437 | movlw D'8' 438 | addwf FSR1L,f 439 | btfsc TEMP,1 440 | goto point_to_tx_map_data_normal 441 | movlw D'8' 442 | addwf FSR1L,f 443 | btfsc TEMP,2 444 | goto point_to_tx_map_data_normal 445 | movlw D'8' 446 | addwf FSR1L,f 447 | btfsc TEMP,3 448 | goto point_to_tx_map_data_normal 449 | movlw D'8' 450 | addwf FSR1L,f 451 | btfsc TEMP,4 452 | goto point_to_tx_map_data_normal 453 | movlw D'8' 454 | addwf FSR1L,f 455 | btfsc TEMP,5 456 | goto point_to_tx_map_data_normal 457 | movlw D'8' 458 | addwf FSR1L,f 459 | btfsc TEMP,6 460 | goto point_to_tx_map_data_normal 461 | movlw D'8' 462 | addwf FSR1L,f 463 | btfsc TEMP,7 464 | goto point_to_tx_map_data_normal 465 | ; at this point, TEMP_2,0 is assumed to be set 466 | movlw D'8' 467 | addwf FSR1L,f 468 | ; point to correct byte. 469 | point_to_tx_map_data_normal 470 | btfsc TEMP_4,0 471 | return 472 | incf FSR1L,f 473 | btfsc TEMP_4,1 474 | return 475 | incf FSR1L,f 476 | btfsc TEMP_4,2 477 | return 478 | incf FSR1L,f 479 | btfsc TEMP_4,3 480 | return 481 | incf FSR1L,f 482 | btfsc TEMP_4,4 483 | return 484 | incf FSR1L,f 485 | btfsc TEMP_4,5 486 | return 487 | incf FSR1L,f 488 | btfsc TEMP_4,6 489 | return 490 | ; at this point, TEMP_4,7 is assumed to be set. 491 | incf FSR1L,f 492 | return 493 | 494 | 495 | ; ================================= 496 | ; 497 | ; Send a MIDI byte from W register. 498 | ; Wait to make sure USART is ready. 499 | ; 500 | ; ================================= 501 | transmit_byte_normal 502 | nop 503 | nop 504 | btfss PIR1,TXIF 505 | goto $-1 506 | banksel TXREG 507 | movwf TXREG 508 | clrf BSR 509 | return 510 | 511 | ; ================================= 512 | ; 513 | ; operation halts if setup procedure was not completed. 514 | ; 515 | ; ================================= 516 | ;normal_no_setup 517 | ; movlw B'00001100' 518 | ; movwf PORTC 519 | ; call blink_delay 520 | ; movlw B'00000000' 521 | ; movwf PORTC 522 | ; call blink_delay 523 | ; goto normal_no_setup 524 | 525 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 526 | 527 | end 528 | 529 | -------------------------------------------------------------------------------- /src/16f1939.lkr: -------------------------------------------------------------------------------- 1 | // File: 16f1939_g.lkr 2 | // Generic linker script for the PIC16F1939 processor 3 | 4 | #DEFINE _CODEEND _DEBUGCODESTART - 1 5 | #DEFINE _CEND _CODEEND + _DEBUGCODELEN 6 | #DEFINE _DATAEND _DEBUGDATASTART - 1 7 | #DEFINE _DEND _DATAEND + _DEBUGDATALEN 8 | 9 | LIBPATH . 10 | 11 | CODEPAGE NAME=page0 START=0x0 END=0x7FF PROTECTED FILL=0x0000 12 | CODEPAGE NAME=page1 START=0x800 END=0xFFF PROTECTED FILL=0x0000 13 | CODEPAGE NAME=page2 START=0x1000 END=0x17FF FILL=0x0000 14 | CODEPAGE NAME=page3 START=0x1800 END=0x1FFF PROTECTED FILL=0x0000 15 | CODEPAGE NAME=page4 START=0x2000 END=0x27FF PROTECTED 16 | CODEPAGE NAME=page5 START=0x2800 END=0x2FFF PROTECTED 17 | CODEPAGE NAME=page6 START=0x3000 END=0x37FF PROTECTED 18 | CODEPAGE NAME=page7 START=0x3800 END=0x3FFF PROTECTED 19 | 20 | CODEPAGE NAME=.idlocs START=0x8000 END=0x8003 PROTECTED 21 | CODEPAGE NAME=.devid START=0x8006 END=0x8006 PROTECTED 22 | CODEPAGE NAME=.config START=0x8007 END=0x8008 PROTECTED 23 | CODEPAGE NAME=eedata START=0xF000 END=0xF0FF PROTECTED 24 | 25 | LINEARMEM NAME=linear0 START=0x2000 END=0x23EF PROTECTED 26 | 27 | DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED 28 | DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED 29 | DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED 30 | DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED 31 | DATABANK NAME=sfr4 START=0x200 END=0x21F PROTECTED 32 | DATABANK NAME=sfr5 START=0x280 END=0x29F PROTECTED 33 | DATABANK NAME=sfr6 START=0x300 END=0x31F PROTECTED 34 | DATABANK NAME=sfr7 START=0x380 END=0x39F PROTECTED 35 | DATABANK NAME=sfr8 START=0x400 END=0x41F PROTECTED 36 | DATABANK NAME=sfr9 START=0x480 END=0x49F PROTECTED 37 | DATABANK NAME=sfr10 START=0x500 END=0x51F PROTECTED 38 | DATABANK NAME=sfr11 START=0x580 END=0x59F PROTECTED 39 | DATABANK NAME=sfr12 START=0x600 END=0x61F PROTECTED 40 | DATABANK NAME=sfr13 START=0x680 END=0x69F PROTECTED 41 | DATABANK NAME=sfr14 START=0x700 END=0x71F PROTECTED 42 | DATABANK NAME=sfr15 START=0x780 END=0x7EF PROTECTED 43 | DATABANK NAME=sfr16 START=0x800 END=0x81F PROTECTED 44 | DATABANK NAME=sfr17 START=0x880 END=0x89F PROTECTED 45 | DATABANK NAME=sfr18 START=0x900 END=0x91F PROTECTED 46 | DATABANK NAME=sfr19 START=0x980 END=0x99F PROTECTED 47 | DATABANK NAME=sfr20 START=0xA00 END=0xA1F PROTECTED 48 | DATABANK NAME=sfr21 START=0xA80 END=0xA9F PROTECTED 49 | DATABANK NAME=sfr22 START=0xB00 END=0xB1F PROTECTED 50 | DATABANK NAME=sfr23 START=0xB80 END=0xB9F PROTECTED 51 | DATABANK NAME=sfr24 START=0xC00 END=0xC1F PROTECTED 52 | DATABANK NAME=sfr25 START=0xC80 END=0xC9F PROTECTED 53 | DATABANK NAME=sfr26 START=0xD00 END=0xD1F PROTECTED 54 | DATABANK NAME=sfr27 START=0xD80 END=0xD9F PROTECTED 55 | DATABANK NAME=sfr28 START=0xE00 END=0xE1F PROTECTED 56 | DATABANK NAME=sfr29 START=0xE80 END=0xE9F PROTECTED 57 | DATABANK NAME=sfr30 START=0xF00 END=0xF1F PROTECTED 58 | DATABANK NAME=sfr31 START=0xF80 END=0xFEF PROTECTED 59 | 60 | DATABANK NAME=gpr0 START=0x20 END=0x6F SHADOW=linear0:0x2000 61 | DATABANK NAME=gpr1 START=0xA0 END=0xEF SHADOW=linear0:0x2050 62 | DATABANK NAME=gpr2 START=0x120 END=0x16F SHADOW=linear0:0x20A0 63 | DATABANK NAME=gpr3 START=0x1A0 END=0x1EF SHADOW=linear0:0x20F0 64 | DATABANK NAME=gpr4 START=0x220 END=0x26F SHADOW=linear0:0x2140 65 | DATABANK NAME=gpr5 START=0x2A0 END=0x2EF SHADOW=linear0:0x2190 66 | DATABANK NAME=gpr6 START=0x320 END=0x36F SHADOW=linear0:0x21E0 67 | DATABANK NAME=gpr7 START=0x3A0 END=0x3EF SHADOW=linear0:0x2230 68 | DATABANK NAME=gpr8 START=0x420 END=0x46F SHADOW=linear0:0x2280 69 | DATABANK NAME=gpr9 START=0x4A0 END=0x4EF SHADOW=linear0:0x22D0 70 | DATABANK NAME=gpr10 START=0x520 END=0x56F SHADOW=linear0:0x2320 71 | DATABANK NAME=gpr11 START=0x5A0 END=0x5EF SHADOW=linear0:0x2370 72 | 73 | #IFDEF _DEBUGDATASTART 74 | DATABANK NAME=gpr12 START=0x620 END=_DATAEND SHADOW=linear0:0x23C0 75 | DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED 76 | #ELSE //no debug 77 | DATABANK NAME=gpr12 START=0x620 END=0x64F SHADOW=linear0:0x23C0 78 | #FI 79 | 80 | 81 | #IFDEF _DEBUGDATASTART 82 | SHAREBANK NAME=dbgnobnk START=0x70 END=0x70 RESERVED 83 | SHAREBANK NAME=dbgnobnk START=0xF0 END=0xF0 RESERVED 84 | SHAREBANK NAME=dbgnobnk START=0x170 END=0x170 RESERVED 85 | SHAREBANK NAME=dbgnobnk START=0x1F0 END=0x1F0 RESERVED 86 | SHAREBANK NAME=dbgnobnk START=0x270 END=0x270 RESERVED 87 | SHAREBANK NAME=dbgnobnk START=0x2F0 END=0x2F0 RESERVED 88 | SHAREBANK NAME=dbgnobnk START=0x370 END=0x370 RESERVED 89 | SHAREBANK NAME=dbgnobnk START=0x3F0 END=0x3F0 RESERVED 90 | SHAREBANK NAME=dbgnobnk START=0x470 END=0x470 RESERVED 91 | SHAREBANK NAME=dbgnobnk START=0x4F0 END=0x4F0 RESERVED 92 | SHAREBANK NAME=dbgnobnk START=0x570 END=0x570 RESERVED 93 | SHAREBANK NAME=dbgnobnk START=0x5F0 END=0x5F0 RESERVED 94 | SHAREBANK NAME=dbgnobnk START=0x670 END=0x670 RESERVED 95 | SHAREBANK NAME=dbgnobnk START=0x6F0 END=0x6F0 RESERVED 96 | SHAREBANK NAME=dbgnobnk START=0x770 END=0x770 RESERVED 97 | SHAREBANK NAME=dbgnobnk START=0x7F0 END=0x7F0 RESERVED 98 | SHAREBANK NAME=dbgnobnk START=0x870 END=0x870 RESERVED 99 | SHAREBANK NAME=dbgnobnk START=0x8F0 END=0x8F0 RESERVED 100 | SHAREBANK NAME=dbgnobnk START=0x970 END=0x970 RESERVED 101 | SHAREBANK NAME=dbgnobnk START=0x9F0 END=0x9F0 RESERVED 102 | SHAREBANK NAME=dbgnobnk START=0xA70 END=0xA70 RESERVED 103 | SHAREBANK NAME=dbgnobnk START=0xAF0 END=0xAF0 RESERVED 104 | SHAREBANK NAME=dbgnobnk START=0xB70 END=0xB70 RESERVED 105 | SHAREBANK NAME=dbgnobnk START=0xBF0 END=0xBF0 RESERVED 106 | SHAREBANK NAME=dbgnobnk START=0xC70 END=0xC70 RESERVED 107 | SHAREBANK NAME=dbgnobnk START=0xCF0 END=0xCF0 RESERVED 108 | SHAREBANK NAME=dbgnobnk START=0xD70 END=0xD70 RESERVED 109 | SHAREBANK NAME=dbgnobnk START=0xDF0 END=0xDF0 RESERVED 110 | SHAREBANK NAME=dbgnobnk START=0xE70 END=0xE70 RESERVED 111 | SHAREBANK NAME=dbgnobnk START=0xEF0 END=0xEF0 RESERVED 112 | SHAREBANK NAME=dbgnobnk START=0xF70 END=0xF70 RESERVED 113 | SHAREBANK NAME=dbgnobnk START=0xFF0 END=0xFF0 RESERVED 114 | 115 | SHAREBANK NAME=gprnobank START=0x71 END=0x7F 116 | SHAREBANK NAME=gprnobank START=0xF1 END=0xFF PROTECTED 117 | SHAREBANK NAME=gprnobank START=0x171 END=0x17F PROTECTED 118 | SHAREBANK NAME=gprnobank START=0x1F1 END=0x1FF PROTECTED 119 | SHAREBANK NAME=gprnobank START=0x271 END=0x27F PROTECTED 120 | SHAREBANK NAME=gprnobank START=0x2F1 END=0x2FF PROTECTED 121 | SHAREBANK NAME=gprnobank START=0x371 END=0x37F PROTECTED 122 | SHAREBANK NAME=gprnobank START=0x3F1 END=0x3FF PROTECTED 123 | SHAREBANK NAME=gprnobank START=0x471 END=0x47F PROTECTED 124 | SHAREBANK NAME=gprnobank START=0x4F1 END=0x4FF PROTECTED 125 | SHAREBANK NAME=gprnobank START=0x571 END=0x57F PROTECTED 126 | SHAREBANK NAME=gprnobank START=0x5F1 END=0x5FF PROTECTED 127 | SHAREBANK NAME=gprnobank START=0x671 END=0x67F PROTECTED 128 | SHAREBANK NAME=gprnobank START=0x6F1 END=0x6FF PROTECTED 129 | SHAREBANK NAME=gprnobank START=0x771 END=0x77F PROTECTED 130 | SHAREBANK NAME=gprnobank START=0x7F1 END=0x7FF PROTECTED 131 | SHAREBANK NAME=gprnobank START=0x871 END=0x87F PROTECTED 132 | SHAREBANK NAME=gprnobank START=0x8F1 END=0x8FF PROTECTED 133 | SHAREBANK NAME=gprnobank START=0x971 END=0x97F PROTECTED 134 | SHAREBANK NAME=gprnobank START=0x9F1 END=0x9FF PROTECTED 135 | SHAREBANK NAME=gprnobank START=0xA71 END=0xA7F PROTECTED 136 | SHAREBANK NAME=gprnobank START=0xAF1 END=0xAFF PROTECTED 137 | SHAREBANK NAME=gprnobank START=0xB71 END=0xB7F PROTECTED 138 | SHAREBANK NAME=gprnobank START=0xBF1 END=0xBFF PROTECTED 139 | SHAREBANK NAME=gprnobank START=0xC71 END=0xC7F PROTECTED 140 | SHAREBANK NAME=gprnobank START=0xCF1 END=0xCFF PROTECTED 141 | SHAREBANK NAME=gprnobank START=0xD71 END=0xD7F PROTECTED 142 | SHAREBANK NAME=gprnobank START=0xDF1 END=0xDFF PROTECTED 143 | SHAREBANK NAME=gprnobank START=0xE71 END=0xE7F PROTECTED 144 | SHAREBANK NAME=gprnobank START=0xEF1 END=0xEFF PROTECTED 145 | SHAREBANK NAME=gprnobank START=0xF71 END=0xF7F PROTECTED 146 | SHAREBANK NAME=gprnobank START=0xFF1 END=0xFFF PROTECTED 147 | #ELSE 148 | SHAREBANK NAME=gprnobank START=0x70 END=0x7F 149 | SHAREBANK NAME=gprnobank START=0xF0 END=0xFF PROTECTED 150 | SHAREBANK NAME=gprnobank START=0x170 END=0x17F PROTECTED 151 | SHAREBANK NAME=gprnobank START=0x1F0 END=0x1FF PROTECTED 152 | SHAREBANK NAME=gprnobank START=0x270 END=0x27F PROTECTED 153 | SHAREBANK NAME=gprnobank START=0x2F0 END=0x2FF PROTECTED 154 | SHAREBANK NAME=gprnobank START=0x370 END=0x37F PROTECTED 155 | SHAREBANK NAME=gprnobank START=0x3F0 END=0x3FF PROTECTED 156 | SHAREBANK NAME=gprnobank START=0x470 END=0x47F PROTECTED 157 | SHAREBANK NAME=gprnobank START=0x4F0 END=0x4FF PROTECTED 158 | SHAREBANK NAME=gprnobank START=0x570 END=0x57F PROTECTED 159 | SHAREBANK NAME=gprnobank START=0x5F0 END=0x5FF PROTECTED 160 | SHAREBANK NAME=gprnobank START=0x670 END=0x67F PROTECTED 161 | SHAREBANK NAME=gprnobank START=0x6F0 END=0x6FF PROTECTED 162 | SHAREBANK NAME=gprnobank START=0x770 END=0x77F PROTECTED 163 | SHAREBANK NAME=gprnobank START=0x7F0 END=0x7FF PROTECTED 164 | SHAREBANK NAME=gprnobank START=0x870 END=0x87F PROTECTED 165 | SHAREBANK NAME=gprnobank START=0x8F0 END=0x8FF PROTECTED 166 | SHAREBANK NAME=gprnobank START=0x970 END=0x97F PROTECTED 167 | SHAREBANK NAME=gprnobank START=0x9F0 END=0x9FF PROTECTED 168 | SHAREBANK NAME=gprnobank START=0xA70 END=0xA7F PROTECTED 169 | SHAREBANK NAME=gprnobank START=0xAF0 END=0xAFF PROTECTED 170 | SHAREBANK NAME=gprnobank START=0xB70 END=0xB7F PROTECTED 171 | SHAREBANK NAME=gprnobank START=0xBF0 END=0xBFF PROTECTED 172 | SHAREBANK NAME=gprnobank START=0xC70 END=0xC7F PROTECTED 173 | SHAREBANK NAME=gprnobank START=0xCF0 END=0xCFF PROTECTED 174 | SHAREBANK NAME=gprnobank START=0xD70 END=0xD7F PROTECTED 175 | SHAREBANK NAME=gprnobank START=0xDF0 END=0xDFF PROTECTED 176 | SHAREBANK NAME=gprnobank START=0xE70 END=0xE7F PROTECTED 177 | SHAREBANK NAME=gprnobank START=0xEF0 END=0xEFF PROTECTED 178 | SHAREBANK NAME=gprnobank START=0xF70 END=0xF7F PROTECTED 179 | SHAREBANK NAME=gprnobank START=0xFF0 END=0xFFF PROTECTED 180 | #FI 181 | 182 | SECTION NAME=PROG0 ROM=page0 // ROM code space - page0 183 | SECTION NAME=PROG1 ROM=page1 // ROM code space - page1 184 | SECTION NAME=PROG2 ROM=page2 // ROM code space - page2 185 | SECTION NAME=PROG3 ROM=page3 // ROM code space - page3 186 | SECTION NAME=PROG4 ROM=page4 // ROM code space - page4 187 | SECTION NAME=PROG5 ROM=page5 // ROM code space - page5 188 | SECTION NAME=PROG6 ROM=page6 // ROM code space - page6 189 | SECTION NAME=PROG7 ROM=page7 // ROM code space - page7 190 | SECTION NAME=IDLOCS ROM=.idlocs // ID locations 191 | SECTION NAME=DEEPROM ROM=eedata // Data EEPROM 192 | SECTION NAME=LINEAR0 RAM=linear0 // Linear Memory 193 | 194 | -------------------------------------------------------------------------------- /src/fupdate.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; fupdate.asm 9 | ; 10 | ; bootloader / firmware update over MIDI 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | ; ================================= 16 | ; 17 | ; Firmware Update ISR 18 | ; 19 | ; ================================= 20 | isr_fupdate_code code 0x0100 21 | 22 | ; ================================================================== 23 | ; 24 | ; firmware update--all functionality in isr. 25 | ; 26 | ; ================================================================== 27 | 28 | ; STATE_FLAGS alternative bits 29 | ; 0 - Sysex has begun and we're listening 30 | ; 1 - Sysex Header is Valid 31 | ; 2 - 32 | ; 3 - Firmware Update Mode (isr selector) 33 | ; 4 - Current chunk is checksum 34 | ; 5 - Current chunk is code 35 | ; 6 - 36 | ; 7 - 37 | 38 | GLOBAL isr_fupdate 39 | isr_fupdate 40 | ; new context 41 | clrf STATUS 42 | clrf BSR 43 | ; clrf PCLATH 44 | ; check for RX interrupt 45 | btfsc PIR1,RCIF 46 | goto fupdate_handle_rx 47 | ; no other interrupts should be on! 48 | goto fupdate_sysex_error 49 | 50 | 51 | fupdate_handle_rx 52 | ; Grab the RX byte 53 | banksel RCREG 54 | movfw RCREG 55 | ; movwf TXREG 56 | movwf TEMP 57 | clrf BSR 58 | 59 | ; retfie 60 | 61 | ; is SysEx begin? 62 | movlw 0xF0 63 | subwf TEMP,w 64 | bz fupdate_sysex_begin 65 | 66 | ; is SysEx end? 67 | movlw 0xF7 68 | subwf TEMP,w 69 | bz fupdate_sysex_end 70 | 71 | ; real time status (ignored)? 72 | movfw TEMP 73 | andlw B'11111000' 74 | sublw B'11111000' 75 | bz fupdate_isr_finish 76 | 77 | ; some other status? 78 | btfsc TEMP,7 79 | goto fupdate_sysex_error 80 | 81 | ; are we still checking? 82 | btfss STATE_FLAGS,0 83 | goto fupdate_isr_finish 84 | 85 | ; is the header complete? 86 | btfsc STATE_FLAGS,1 87 | goto fupdate_get_data 88 | 89 | ; check header for validity 90 | fupdate_check 91 | incf BYTE_COUNT,f 92 | movfw BYTE_COUNT 93 | movwf TEMP_2 94 | 95 | fupdate_check_1 96 | decfsz TEMP_2,f 97 | goto fupdate_check_2 98 | movlw 0x00 99 | subwf TEMP,w 100 | bnz fupdate_sysex_error 101 | goto fupdate_isr_finish 102 | 103 | fupdate_check_2 104 | decfsz TEMP_2,f 105 | goto fupdate_check_3 106 | movlw 0x01 107 | subwf TEMP,w 108 | bnz fupdate_sysex_error 109 | goto fupdate_isr_finish 110 | 111 | fupdate_check_3 112 | decfsz TEMP_2,f 113 | goto fupdate_check_4 114 | movlw 0x5D 115 | subwf TEMP,w 116 | bnz fupdate_sysex_error 117 | goto fupdate_isr_finish 118 | 119 | fupdate_check_4 120 | decfsz TEMP_2,f 121 | goto fupdate_sysex_error 122 | movlw 0x07 123 | subwf TEMP,w 124 | bnz fupdate_sysex_error 125 | ; header now relevant 126 | bsf STATE_FLAGS,1 127 | ; reset bytecount 128 | clrf BYTE_COUNT 129 | goto fupdate_isr_finish 130 | 131 | fupdate_sysex_begin 132 | ; new message 133 | clrf BYTE_COUNT 134 | ; incomplete 135 | bsf STATE_FLAGS,0 136 | ; not yet relevant 137 | bcf STATE_FLAGS,1 138 | goto fupdate_isr_finish 139 | 140 | fupdate_get_data 141 | ; check for chunk start 142 | incf BYTE_COUNT,f 143 | movfw BYTE_COUNT 144 | movwf TEMP_2 145 | 146 | fupdate_get_1 147 | decfsz TEMP_2,f 148 | goto fupdate_get_chunk_body 149 | movlw 0x7E 150 | subwf TEMP,w 151 | bz fupdate_get_code_begin 152 | movlw 0x7F 153 | subwf TEMP,w 154 | bz fupdate_get_checksum_begin 155 | 156 | movfw TEMP 157 | bnz fupdate_sysex_error 158 | ; for zero byte, treat as filler and wait for a chunk start byte 159 | decf BYTE_COUNT,f 160 | goto fupdate_isr_finish 161 | 162 | fupdate_get_chunk_body 163 | btfsc STATE_FLAGS,5 164 | goto fupdate_get_code_chunk 165 | btfsc STATE_FLAGS,4 166 | goto fupdate_get_checksum_chunk 167 | goto fupdate_sysex_error 168 | 169 | fupdate_get_code_begin 170 | ; set the code chunk flag 171 | bsf STATE_FLAGS,5 172 | ; clear the code counter 173 | clrf TEMP_3 174 | goto fupdate_isr_finish 175 | 176 | fupdate_get_checksum_begin 177 | ; set the checksum chunk flag 178 | bsf STATE_FLAGS,4 179 | goto fupdate_isr_finish 180 | 181 | fupdate_get_checksum_chunk 182 | fg_sum_1 183 | decfsz TEMP_2,f 184 | goto fg_sum_2 185 | ; checksum low data 186 | movfw TEMP 187 | movwf TEMP_4 188 | goto fupdate_isr_finish 189 | fg_sum_2 190 | decfsz TEMP_2,f 191 | goto fg_sum_3 192 | ; checksum low check 193 | movfw TEMP_4 194 | addlw B'10000000' 195 | addwf TEMP,f 196 | incfsz TEMP,f 197 | goto fupdate_sysex_error 198 | goto fupdate_isr_finish 199 | fg_sum_3 200 | decfsz TEMP_2,f 201 | goto fg_sum_4 202 | ; checksum mid data 203 | movfw TEMP 204 | movwf TEMP_6 205 | goto fupdate_isr_finish 206 | fg_sum_4 207 | decfsz TEMP_2,f 208 | goto fg_sum_5 209 | ; checksum mid check 210 | movfw TEMP_6 211 | addlw B'10000000' 212 | addwf TEMP,f 213 | incfsz TEMP,f 214 | goto fupdate_sysex_error 215 | goto fupdate_isr_finish 216 | fg_sum_5 217 | decfsz TEMP_2,f 218 | goto fg_sum_6 219 | ; checksum high data 220 | movfw TEMP 221 | movwf TEMP_7 222 | goto fupdate_isr_finish 223 | fg_sum_6 224 | decfsz TEMP_2,f 225 | goto fg_sum_7 226 | ; checksum high check 227 | movfw TEMP_7 228 | addlw B'10000000' 229 | addwf TEMP,f 230 | incfsz TEMP,f 231 | goto fupdate_sysex_error 232 | ; move all 16 bits to TEMP_6,TEMP_4 233 | btfsc TEMP_6,0 234 | bsf TEMP_4,7 235 | btfsc TEMP_7,0 236 | bsf TEMP_6,7 237 | bcf STATUS,C 238 | rrf TEMP_6,f 239 | btfsc TEMP_7,1 240 | bsf TEMP_6,7 241 | goto fupdate_isr_finish 242 | fg_sum_7 243 | decfsz TEMP_2,f 244 | goto fg_sum_8 245 | ; version data 246 | movfw TEMP 247 | movwf TEMP_7 248 | goto fupdate_isr_finish 249 | fg_sum_8 250 | decfsz TEMP_2,f 251 | goto fupdate_sysex_error 252 | ; version check 253 | movfw TEMP_7 254 | addlw B'10000000' 255 | addwf TEMP,f 256 | incfsz TEMP,f 257 | goto fupdate_sysex_error 258 | ; store the checksum & version to data EEPROM 259 | ; store to EEPROM 260 | ; turn off all interrupts 261 | bcf INTCON,GIE 262 | btfsc INTCON,GIE 263 | goto $-2 264 | ; make sure any writes are complete 265 | banksel EECON1 266 | btfsc EECON1,WR 267 | goto $-1 268 | ; write version 269 | movfw TEMP_7 270 | movwf EEDATL 271 | movlw PROM_VERSION 272 | movwf EEADRL 273 | bcf EECON1,EEPGD 274 | bsf EECON1,WREN 275 | movlw 0x55 276 | movwf EECON2 277 | movlw 0xAA 278 | movwf EECON2 279 | bsf EECON1,WR 280 | ; make sure any writes are complete 281 | btfsc EECON1,WR 282 | goto $-1 283 | ; write high byte 284 | movfw TEMP_6 285 | movwf EEDATL 286 | incf EEADRL,f 287 | bsf EECON1,WREN 288 | movlw 0x55 289 | movwf EECON2 290 | movlw 0xAA 291 | movwf EECON2 292 | bsf EECON1,WR 293 | ; make sure any writes are complete 294 | btfsc EECON1,WR 295 | goto $-1 296 | ; write low byte 297 | movfw TEMP_4 298 | movwf EEDATL 299 | incf EEADRL,f 300 | bcf EECON1,EEPGD 301 | bsf EECON1,WREN 302 | movlw 0x55 303 | movwf EECON2 304 | movlw 0xAA 305 | movwf EECON2 306 | bsf EECON1,WR 307 | ; make sure any writes are complete 308 | btfsc EECON1,WR 309 | goto $-1 310 | ; shut off activity LED and wait for user to power cycle 311 | clrf BSR 312 | movlw B'11001100' 313 | movwf PORTC 314 | fupdate_wait_for_reset 315 | goto fupdate_wait_for_reset 316 | 317 | fupdate_get_code_chunk 318 | fg_code_1 319 | decfsz TEMP_2,f 320 | goto fg_code_2 321 | ; address low data 322 | movfw TEMP 323 | movwf TEMP_6 324 | goto fupdate_isr_finish 325 | 326 | fg_code_2 327 | decfsz TEMP_2,f 328 | goto fg_code_3 329 | ; address low check 330 | movfw TEMP_6 331 | addlw B'10000000' 332 | addwf TEMP,f 333 | incfsz TEMP,f 334 | goto fupdate_sysex_error 335 | goto fupdate_isr_finish 336 | 337 | fg_code_3 338 | decfsz TEMP_2,f 339 | goto fg_code_4 340 | ; address high data 341 | movfw TEMP 342 | movwf TEMP_7 343 | goto fupdate_isr_finish 344 | 345 | fg_code_4 346 | decfsz TEMP_2,f 347 | goto fg_code_5 348 | ; address high check 349 | movfw TEMP_7 350 | addlw B'10000000' 351 | addwf TEMP,f 352 | incfsz TEMP,f 353 | goto fupdate_sysex_error 354 | ; change address from 7:7 to 6:8 355 | btfsc TEMP_7,0 356 | bsf TEMP_6,7 357 | bcf STATUS,C 358 | rrf TEMP_7,f 359 | goto fupdate_isr_finish 360 | 361 | fg_code_5 362 | decfsz TEMP_2,f 363 | goto fg_code_6 364 | ; opcode low data 365 | movfw TEMP 366 | ; movwf TEMP_4 367 | movwf TEMP_5 368 | goto fupdate_isr_finish 369 | 370 | fg_code_6 371 | decfsz TEMP_2,f 372 | goto fg_code_7 373 | ; opcode low check 374 | ; movfw TEMP_4 375 | movfw TEMP_5 376 | addlw B'10000000' 377 | addwf TEMP,f 378 | incfsz TEMP,f 379 | goto fupdate_sysex_error 380 | goto fupdate_isr_finish 381 | 382 | fg_code_7 383 | decfsz TEMP_2,f 384 | goto fg_code_8 385 | ; opcode high data 386 | movfw TEMP 387 | movwf TEMP_4 388 | goto fupdate_isr_finish 389 | 390 | fg_code_8 391 | decfsz TEMP_2,f 392 | goto fupdate_sysex_error 393 | ; opcdode high check 394 | movfw TEMP_4 395 | addlw B'10000000' 396 | addwf TEMP,f 397 | incfsz TEMP,f 398 | goto fupdate_sysex_error 399 | ; ok--munged opcode is now TEMP_4(7) : TEMP_5 (7) 400 | ; change from 7:7 to 6:8 401 | btfsc TEMP_4,0 402 | bsf TEMP_5,7 403 | bcf STATUS,C 404 | rrf TEMP_4,f 405 | ; ok--munged opcode is now in TEMP_4:TEMP_5 406 | ; de-munge the opcode 407 | movfw TEMP_4 408 | bnz demunge_check_clrw 409 | ; high byte is zero-- 410 | ; no operations necessary. 411 | goto fg_code_store 412 | 413 | ; clrw (1 0000 0000) 414 | demunge_check_clrw 415 | movfw TEMP_4 416 | sublw 0x01 417 | bnz demunge_bit_oriented 418 | movfw TEMP_5 419 | bz fg_code_store 420 | 421 | ; de-munge the bit-oriented opcodes 422 | ; use the opcode counter to cycle modifications 423 | demunge_bit_oriented 424 | ; bit oriented instructions are 01 iibb bfff ffff 425 | ; check for the 01 426 | movfw TEMP_4 427 | andlw B'00110000' 428 | sublw B'00010000' 429 | bnz demunge_reg_lit 430 | 431 | btfsc TEMP_3,1 432 | goto demunge_bit_oriented_1x 433 | demunge_bit_oriented_0x 434 | btfsc TEMP_3,0 435 | goto demunge_bit_oriented_01 436 | demunge_bit_oriented_00 437 | movlw B'00001001' 438 | xorwf TEMP_4,f 439 | goto demunge_reg_lit 440 | demunge_bit_oriented_01 441 | movlw B'00000010' 442 | xorwf TEMP_4,f 443 | goto demunge_reg_lit 444 | demunge_bit_oriented_1x 445 | btfsc TEMP_3,0 446 | goto demunge_bit_oriented_11 447 | demunge_bit_oriented_10 448 | movlw B'00001110' 449 | xorwf TEMP_4,f 450 | goto demunge_reg_lit 451 | demunge_bit_oriented_11 452 | movlw B'00000101' 453 | xorwf TEMP_4,f 454 | 455 | ; de-munge the registers & literals 456 | ; use the opcode counter to cycle modifications 457 | demunge_reg_lit 458 | btfsc TEMP_3,1 459 | goto demunge_reg_lit_1x 460 | demunge_reg_lit_0x 461 | btfsc TEMP_3,0 462 | goto demunge_reg_lit_01 463 | demunge_reg_lit_00 464 | movlw B'00011011' 465 | xorwf TEMP_5,f 466 | goto fg_code_store 467 | demunge_reg_lit_01 468 | movlw B'00100001' 469 | xorwf TEMP_5,f 470 | goto fg_code_store 471 | demunge_reg_lit_1x 472 | btfsc TEMP_3,0 473 | goto demunge_reg_lit_11 474 | demunge_reg_lit_10 475 | movlw B'00000111' 476 | xorwf TEMP_5,f 477 | goto fg_code_store 478 | demunge_reg_lit_11 479 | movlw B'00110010' 480 | xorwf TEMP_5,f 481 | 482 | 483 | fg_code_store 484 | ; store opcode low byte in buffer 485 | clrf FSR0H 486 | movlw FIRMWARE_BUFFER 487 | movwf FSR0L 488 | movfw TEMP_3 489 | addwf FSR0L,f 490 | addwf FSR0L,f 491 | movfw TEMP_5 492 | movwf INDF0 493 | ; store opcode high byte in buffer 494 | incf FSR0L,f 495 | movfw TEMP_4 496 | movwf INDF0 497 | ; increment the opcode counter 498 | incf TEMP_3,f 499 | ; check for chunk completion 500 | movlw D'32' 501 | subwf TEMP_3,w 502 | bz fg_code_chunk_complete 503 | ; prepare bytecount for next 4-byte opcode 504 | movlw 0x04 505 | subwf BYTE_COUNT,f 506 | goto fupdate_isr_finish 507 | 508 | fg_code_chunk_complete 509 | ; write the code chunk to program EEPROM 510 | ; disable interrupts 511 | bcf INTCON,GIE 512 | btfsc INTCON,GIE 513 | goto $-2 514 | 515 | ; goto fupdate_flush 516 | 517 | ;;;; 518 | ; erase EEPROM block before write 519 | ;;;; 520 | banksel EEADRH 521 | movfw TEMP_7 522 | movwf EEADRH 523 | movfw TEMP_6 524 | movwf EEADRL 525 | bsf EECON1,EEPGD 526 | bsf EECON1,WREN 527 | bsf EECON1,FREE 528 | movlw 0x55 529 | movwf EECON2 530 | movlw 0xAA 531 | movwf EECON2 532 | bsf EECON1,WR 533 | nop 534 | nop 535 | bcf EECON1,FREE 536 | bcf EECON1,WREN 537 | ;;;; 538 | ; write code to EEPROM 539 | ;;;; 540 | ; FSR0L points to code buffer 541 | clrf FSR0H 542 | movlw FIRMWARE_BUFFER 543 | movwf FSR0L 544 | ; EEADRH:EEADR point to program chunk to write 545 | movfw TEMP_7 546 | movwf EEADRH 547 | movfw TEMP_6 548 | movwf EEADRL 549 | ; EECON1 stuff 550 | bsf EECON1,WREN 551 | ; 32 words to write 552 | movlw D'32' 553 | movwf TEMP 554 | fg_code_write_loop 555 | ; set up the opcode 556 | moviw INDF0++ 557 | movwf EEDATL 558 | moviw INDF0++ 559 | movwf EEDATH 560 | ; clear LWLO only for last of groups of 8 words 561 | ; ---> EEADRL[2:0] = B'111' 562 | bsf EECON1,LWLO 563 | movf EEADRL,w 564 | xorlw 0x07 565 | andlw 0x07 566 | btfsc STATUS,Z 567 | bcf EECON1,LWLO 568 | fg_code_write_trigger 569 | ; trigger the write 570 | movlw 0x55 571 | movwf EECON2 572 | movlw 0xAA 573 | movwf EECON2 574 | bsf EECON1,WR 575 | nop 576 | nop 577 | ; next opcode 578 | incf EEADR,f 579 | ; in aligned 32-word chunk, EEADRH is never incremented 580 | decfsz TEMP,f 581 | goto fg_code_write_loop 582 | bcf EECON1,WREN 583 | 584 | fupdate_flush 585 | ; flush RX 586 | banksel RCREG 587 | movfw RCREG 588 | movfw RCREG 589 | banksel PIR1 590 | bcf PIR1,5 591 | banksel RCREG 592 | bcf RCSTA,4 593 | bsf RCSTA,4 594 | clrf BSR 595 | ; re-enable interrupts 596 | bsf INTCON,GIE 597 | ; clear the code chunk flag 598 | bcf STATE_FLAGS,5 599 | ; reset the bytecount 600 | clrf BYTE_COUNT 601 | ; wait for more chunks 602 | goto fupdate_isr_finish 603 | 604 | 605 | fupdate_sysex_end 606 | ; execution here is an error condition 607 | ; ignore other data 608 | bcf STATE_FLAGS,1 609 | bcf STATE_FLAGS,0 610 | ; clear LED 611 | clrf BSR 612 | ; porta read-mod-write ok here 613 | ; bsf PORTA,0 614 | goto $-1 615 | 616 | 617 | fupdate_sysex_error 618 | ; ignore rest of message. 619 | bcf STATE_FLAGS,1 620 | bcf STATE_FLAGS,0 621 | ; blink the activity LED and do nothing. 622 | clrf BSR 623 | ; blink off 624 | fupdate_error_blink 625 | movlw B'11001100' 626 | movwf PORTC 627 | clrf COUNTER_L 628 | clrf COUNTER_H 629 | nop 630 | nop 631 | nop 632 | nop 633 | decfsz COUNTER_L,f 634 | goto $-5 635 | decfsz COUNTER_H,f 636 | goto $-7 637 | 638 | ; blink on 639 | movlw B'11000100' 640 | movwf PORTC 641 | clrf COUNTER_L 642 | clrf COUNTER_H 643 | nop 644 | nop 645 | nop 646 | nop 647 | decfsz COUNTER_L,f 648 | goto $-5 649 | decfsz COUNTER_H,f 650 | goto $-7 651 | goto fupdate_error_blink 652 | 653 | fupdate_isr_finish 654 | retfie 655 | 656 | end 657 | 658 | -------------------------------------------------------------------------------- /src/learn-operation.asm: -------------------------------------------------------------------------------- 1 | ; UMR2 2 | ; copyright John Staskevich, 2017 3 | ; john@codeandcopper.com 4 | ; 5 | ; This work is licensed under a Creative Commons Attribution 4.0 International License. 6 | ; http://creativecommons.org/licenses/by/4.0/ 7 | ; 8 | ; learn-operation.asm 9 | ; 10 | ; Main program loop for "learning" host keyboard configuration 11 | ; 12 | list p=16F1939 13 | #include 14 | #include 15 | 16 | ; ================================= 17 | ; 18 | ; Learn Mode Operation 19 | ; 20 | ; ================================= 21 | 22 | start_learn_vector code 0x1000 23 | GLOBAL start_learn_vector 24 | start_learn_vector 25 | goto start_learn 26 | start_learn code 0x1400 27 | start_learn 28 | 29 | ; ================================= 30 | ; 31 | ; Configuration Report 32 | ; Send config data via sysex. Useful for debugging & customer support. 33 | ; 34 | ; ================================= 35 | 36 | call send_sysex_config 37 | ; store setup count for later increment 38 | movfw TEMP_4 39 | movwf SETUP_COUNT 40 | 41 | ; ================================= 42 | ; 43 | ; Variable Init 44 | ; 45 | ; ================================= 46 | 47 | ; ================================= 48 | ; 49 | ; LED Init 50 | ; 51 | ; ================================= 52 | 53 | ; turn off both LEDs. 54 | movlw B'00001100' 55 | movwf PORTC 56 | ; enable Timer 0 so that STBY LED blinks. 57 | ; Enable Interrupts so the first note can be recorded. 58 | movlw COUNTER_T0_MAX 59 | movwf COUNTER_T0 60 | movlw B'11100000' 61 | movwf INTCON 62 | 63 | ; flush out any rx errors 64 | call flush_rx_learn 65 | 66 | ; ================================= 67 | ; 68 | ; Wait for first note 69 | ; 70 | ; ================================= 71 | 72 | wait_for_first_note 73 | btfss STATE_FLAGS,3 74 | goto wait_for_first_note 75 | ; disable MIDI receive 76 | banksel PIE1 77 | bcf PIE1,RCIE 78 | clrf BSR 79 | ; disable interrupts 80 | bcf INTCON,GIE 81 | ; set the activity LED, clear the STBY LED 82 | movlw B'00000100' 83 | movwf PORTC 84 | ; store the MIDI channel number in data EEPROM 85 | movlw 0x0F 86 | andwf NOTE_ON_STATUS,w 87 | ; make sure EEPROM is ready to go 88 | banksel EECON1 89 | btfsc EECON1,WR 90 | goto $-1 91 | ; write channel 92 | movwf EEDATL 93 | movlw PROM_CHANNEL 94 | movwf EEADRL 95 | bcf EECON1,EEPGD 96 | bsf EECON1,WREN 97 | movlw 0x55 98 | movwf EECON2 99 | movlw 0xAA 100 | movwf EECON2 101 | bsf EECON1,WR 102 | ; store the first note number in data EEPROM 103 | clrf BSR 104 | movfw FIRST_NOTE 105 | ; make sure EEPROM is ready to go 106 | banksel EECON1 107 | btfsc EECON1,WR 108 | goto $-1 109 | ; write first note 110 | movwf EEDATL 111 | movlw PROM_FIRST_NOTE 112 | movwf EEADRL 113 | bcf EECON1,EEPGD 114 | bsf EECON1,WREN 115 | movlw 0x55 116 | movwf EECON2 117 | movlw 0xAA 118 | movwf EECON2 119 | bsf EECON1,WR 120 | ; make sure write is complete 121 | banksel EECON1 122 | btfsc EECON1,WR 123 | goto $-1 124 | clrf BSR 125 | 126 | ; ================================= 127 | ; 128 | ; Record the default data states for each select line 129 | ; 130 | ; ================================= 131 | ; init default key bits and select flags 132 | clrf SELECT_FLAGS 133 | clrf SELECT_FLAGS+D'1' 134 | clrf SELECT_FLAGS+D'2' 135 | clrf SELECT_FLAGS+D'3' 136 | clrf SELECT_FLAGS+D'4' 137 | clrf SELECT_FLAGS+D'5' 138 | clrf SELECT_FLAGS+D'6' 139 | clrf SELECT_FLAGS+D'7' 140 | clrf SELECT_FLAGS+D'8' 141 | clrf KEY_BITS 142 | clrf KEY_BITS+D'1' 143 | clrf KEY_BITS+D'2' 144 | clrf KEY_BITS+D'3' 145 | clrf KEY_BITS+D'4' 146 | clrf KEY_BITS+D'5' 147 | clrf KEY_BITS+D'6' 148 | clrf KEY_BITS+D'7' 149 | clrf KEY_BITS+D'8' 150 | ; init the rx map 151 | clrf FSR0L 152 | rx_map_init_loop 153 | movlw 0x21 154 | movwf FSR0H 155 | clrf INDF0 156 | incf FSR0H,f 157 | movlw 0x22 158 | movwf INDF0 159 | incf FSR0H,f 160 | clrf INDF0 161 | incfsz FSR0L,f 162 | goto rx_map_init_loop 163 | ; init the tx map 164 | movlw 0x20 165 | movwf FSR0H 166 | movlw 0x80 167 | movwf FSR0L 168 | tx_map_init_loop 169 | movlw 0xFF 170 | movwf INDF0 171 | incfsz FSR0L,f 172 | goto tx_map_init_loop 173 | 174 | ; poll a fixed number of times 175 | clrf COUNTER_L 176 | clrf COUNTER_M 177 | movlw 0x08 178 | movwf COUNTER_H 179 | 180 | poll_default_keys 181 | decfsz COUNTER_L,f 182 | goto poll_default_keys_go 183 | decfsz COUNTER_M,f 184 | goto poll_default_keys_go 185 | decfsz COUNTER_H,f 186 | goto poll_default_keys_go 187 | goto poll_default_keys_complete 188 | 189 | poll_default_keys_go 190 | ; take a snapshot of select and data lines 191 | call take_snapshot_learn 192 | ; is number of active select lines exactly 1? 193 | decfsz TEMP_4,f 194 | goto poll_default_keys 195 | ; point to the data state register for this select line 196 | call point_to_key_data_learn 197 | ; flag storage of this select state 198 | bsf INDF0,0 199 | ; store the state. 200 | movlw 0x10 201 | addwf FSR0L,f 202 | movfw TEMP_3 203 | movwf INDF0 204 | goto poll_default_keys 205 | 206 | poll_default_keys_complete 207 | ; clear activity LED 208 | movlw B'00001100' 209 | movwf PORTC 210 | ; start STBY LED blinking again 211 | movlw COUNTER_T0_MAX 212 | movwf COUNTER_T0 213 | bsf INTCON,GIE 214 | 215 | ; ================================= 216 | ; 217 | ; Monitor keystrokes. For each, record select/data/note number 218 | ; 219 | ; ================================= 220 | 221 | ; FSR1L is MIDI note number 0-127 for the next keystroke 222 | ; movfw FIRST_NOTE 223 | ; movwf FSR1L 224 | ; start notes at location 0. First note will be used as an offset 225 | ; in runtime. 226 | clrf FSR1L 227 | 228 | poll_setup_keystrokes 229 | ; check for user signal that setup is complete 230 | btfss PORTA,5 231 | goto setup_write 232 | ; take a snapshot of select and data lines 233 | call take_snapshot_learn 234 | ; is number of active select lines exactly 1? 235 | decfsz TEMP_4,f 236 | goto poll_setup_keystrokes 237 | ; point to the data state register for this select line 238 | call point_to_key_data_learn 239 | ; does this select have a default recorded? 240 | btfss INDF0,0 241 | goto poll_setup_keystrokes 242 | ; check the data state. 243 | movlw 0x10 244 | addwf FSR0L,f 245 | movfw TEMP_3 246 | xorwf INDF0,w 247 | ; no change? do nothing. 248 | bz poll_setup_keystrokes 249 | ; data state has changed. store select and data states for current note. 250 | ; put changed bit into TEMP_4 251 | movwf TEMP_4 252 | ; rx map info. 3 bytes indexed by note number. 253 | ; select low 254 | movlw 0x21 255 | movwf FSR1H 256 | movfw TEMP 257 | movwf INDF1 258 | ; select high. add in base address for normal operation 259 | incf FSR1H,f 260 | movfw TEMP_2 261 | andlw B'00000001' 262 | addlw 0x22 263 | movwf INDF1 264 | ; data 265 | incf FSR1H,f 266 | movfw TEMP_4 267 | movwf INDF1 268 | ; tx map info. one byte indexed by select 1-12 x data 1-8 269 | movlw 0x20 270 | movwf FSR0H 271 | movlw 0x80 272 | movwf FSR0L 273 | ; point to correct block of 8. 274 | point_to_tx_map_select 275 | btfsc TEMP,0 276 | goto point_to_tx_map_data 277 | movlw D'8' 278 | addwf FSR0L,f 279 | btfsc TEMP,1 280 | goto point_to_tx_map_data 281 | movlw D'8' 282 | addwf FSR0L,f 283 | btfsc TEMP,2 284 | goto point_to_tx_map_data 285 | movlw D'8' 286 | addwf FSR0L,f 287 | btfsc TEMP,3 288 | goto point_to_tx_map_data 289 | movlw D'8' 290 | addwf FSR0L,f 291 | btfsc TEMP,4 292 | goto point_to_tx_map_data 293 | movlw D'8' 294 | addwf FSR0L,f 295 | btfsc TEMP,5 296 | goto point_to_tx_map_data 297 | movlw D'8' 298 | addwf FSR0L,f 299 | btfsc TEMP,6 300 | goto point_to_tx_map_data 301 | movlw D'8' 302 | addwf FSR0L,f 303 | btfsc TEMP,7 304 | goto point_to_tx_map_data 305 | ; at this point, TEMP_2,0 is assumed to be set 306 | movlw D'8' 307 | addwf FSR0L,f 308 | ; point to correct byte. 309 | point_to_tx_map_data 310 | btfsc TEMP_4,0 311 | goto store_tx_map_note 312 | incf FSR0L,f 313 | btfsc TEMP_4,1 314 | goto store_tx_map_note 315 | incf FSR0L,f 316 | btfsc TEMP_4,2 317 | goto store_tx_map_note 318 | incf FSR0L,f 319 | btfsc TEMP_4,3 320 | goto store_tx_map_note 321 | incf FSR0L,f 322 | btfsc TEMP_4,4 323 | goto store_tx_map_note 324 | incf FSR0L,f 325 | btfsc TEMP_4,5 326 | goto store_tx_map_note 327 | incf FSR0L,f 328 | btfsc TEMP_4,6 329 | goto store_tx_map_note 330 | ; at this point, TEMP_4,7 is assumed to be set. 331 | incf FSR0L,f 332 | store_tx_map_note 333 | ; move the current note number in FSR1L (not INDF1!) into tx map 334 | movfw FSR1L 335 | movwf INDF0 336 | ; advance to next note. wrap at 128. 337 | incf FSR1L,f 338 | movlw B'01111111' 339 | andwf FSR1L,f 340 | 341 | ; blink activity LED 342 | bcf INTCON,GIE 343 | nop 344 | nop 345 | movlw B'00000100' 346 | movwf PORTC 347 | call blink_delay_learn 348 | movlw B'00001000' 349 | movwf PORTC 350 | movlw COUNTER_T0_MAX 351 | movwf COUNTER_T0 352 | bsf INTCON,GIE 353 | goto poll_setup_keystrokes 354 | 355 | setup_write 356 | ; don't need interrupts anymore. 357 | bcf INTCON,GIE 358 | ; set the activity LED 359 | movlw B'00000100' 360 | movwf PORTC 361 | ; write tx map and rx map to program ROM 362 | movlw 0x20 363 | movwf TEMP_5 364 | clrf TEMP_4 365 | movlw 0x3C 366 | movwf TEMP_7 367 | clrf TEMP_6 368 | setup_write_loop 369 | ; write 32 bytes at a time. 370 | call write_32_learn 371 | ; next RAM block 372 | movlw 0x20 373 | addwf TEMP_4,f 374 | btfsc STATUS,C 375 | incf TEMP_5,f 376 | ; next ROM block 377 | addwf TEMP_6,f 378 | btfsc STATUS,C 379 | incf TEMP_7,f 380 | ; check for completion at PROM 0x4000 381 | btfss TEMP_7,6 382 | goto setup_write_loop 383 | 384 | ; write the note count 385 | ; make sure EEPROM is ready to go 386 | banksel EECON1 387 | btfsc EECON1,WR 388 | goto $-1 389 | ; write the note count. Limit to 7 bits. 390 | movfw FSR1L 391 | andlw B'01111111' 392 | movwf EEDATL 393 | movlw PROM_NOTE_COUNT 394 | movwf EEADRL 395 | bcf EECON1,EEPGD 396 | bsf EECON1,WREN 397 | movlw 0x55 398 | movwf EECON2 399 | movlw 0xAA 400 | movwf EECON2 401 | bsf EECON1,WR 402 | ; write the setup completion flag 403 | ; make sure EEPROM is ready to go 404 | banksel EECON1 405 | btfsc EECON1,WR 406 | goto $-1 407 | ; write setup count 408 | ; increment the previous value by one. Limit to 7 bits. 409 | clrf BSR 410 | incf SETUP_COUNT,w 411 | andlw B'01111111' 412 | banksel EEDATL 413 | movwf EEDATL 414 | movlw PROM_SETUP_COUNT 415 | movwf EEADRL 416 | bcf EECON1,EEPGD 417 | bsf EECON1,WREN 418 | movlw 0x55 419 | movwf EECON2 420 | movlw 0xAA 421 | movwf EECON2 422 | bsf EECON1,WR 423 | ; make sure write is complete 424 | banksel EECON1 425 | btfsc EECON1,WR 426 | goto $-1 427 | clrf BSR 428 | 429 | ; Send config data via sysex. Useful for debugging & customer support. 430 | call send_sysex_config 431 | ; all done. shut down. 432 | ; wait for a sec 433 | call blink_delay_learn 434 | call blink_delay_learn 435 | ; clear LEDs 436 | movlw B'00001100' 437 | movwf PORTC 438 | nop 439 | goto $-1 440 | 441 | 442 | ; ================================= 443 | ; 444 | ; delay to for slow LED blink 445 | ; 446 | ; ================================= 447 | 448 | blink_delay_learn 449 | movlw 0x04 450 | movwf COUNTER_H 451 | blink_loop_a_learn 452 | movlw 0xff 453 | movwf COUNTER_M 454 | blink_loop_b_learn 455 | movlw 0xff 456 | movwf COUNTER_L 457 | blink_loop_c_learn 458 | nop 459 | nop 460 | nop 461 | nop 462 | nop 463 | nop 464 | nop 465 | nop 466 | nop 467 | nop 468 | nop 469 | nop 470 | nop 471 | nop 472 | nop 473 | nop 474 | nop 475 | nop 476 | nop 477 | nop 478 | nop 479 | nop 480 | nop 481 | nop 482 | 483 | decfsz COUNTER_L,f 484 | goto blink_loop_c_learn 485 | decfsz COUNTER_M,f 486 | goto blink_loop_b_learn 487 | decfsz COUNTER_H,f 488 | goto blink_loop_a_learn 489 | 490 | return 491 | 492 | ; ================================= 493 | ; 494 | ; take a snapshot of select and data lines 495 | ; select in TEMP_2:TEMP 496 | ; data in TEMP_3 497 | ; 498 | ; ================================= 499 | take_snapshot_learn 500 | ; TEMP: Select 8-1 501 | movfw PORTB 502 | movwf TEMP 503 | ; TEMP_2: Select 9 504 | movfw PORTA 505 | movwf TEMP_2 506 | ; TEMP_3: Data 1-8 507 | movfw PORTD 508 | movwf TEMP_3 509 | ; resample a to make sure snapshot is stable 510 | movfw PORTB 511 | subwf TEMP,w 512 | btfss STATUS,Z 513 | return 514 | movfw PORTA 515 | subwf TEMP_2,w 516 | btfss STATUS,Z 517 | return 518 | movfw PORTD 519 | subwf TEMP_3,w 520 | btfss STATUS,Z 521 | return 522 | ; check matrix polarity 523 | btfss PORTC,5 524 | goto count_active_select_learn 525 | ; negative polarity. complement everything. 526 | comf TEMP,f 527 | comf TEMP_2,f 528 | comf TEMP_3,f 529 | count_active_select_learn 530 | ; sample is only valid if the number of active select lines is 1 531 | ; store number of active select lines in TEMP_4 532 | clrf TEMP_4 533 | btfsc TEMP,0 534 | incf TEMP_4,f 535 | btfsc TEMP,1 536 | incf TEMP_4,f 537 | btfsc TEMP,2 538 | incf TEMP_4,f 539 | btfsc TEMP,3 540 | incf TEMP_4,f 541 | btfsc TEMP,4 542 | incf TEMP_4,f 543 | btfsc TEMP,5 544 | incf TEMP_4,f 545 | btfsc TEMP,6 546 | incf TEMP_4,f 547 | btfsc TEMP,7 548 | incf TEMP_4,f 549 | btfsc TEMP_2,0 550 | incf TEMP_4,f 551 | 552 | return 553 | 554 | ; ================================= 555 | ; 556 | ; Set up FSR0 to point to key state data 557 | ; FSR0L is select line number from 0-8. 558 | ; 559 | ; ================================= 560 | point_to_key_data_learn 561 | clrf FSR0H 562 | movlw SELECT_FLAGS 563 | movwf FSR0L 564 | 565 | btfsc TEMP,0 566 | return 567 | incf FSR0L,f 568 | btfsc TEMP,1 569 | return 570 | incf FSR0L,f 571 | btfsc TEMP,2 572 | return 573 | incf FSR0L,f 574 | btfsc TEMP,3 575 | return 576 | incf FSR0L,f 577 | btfsc TEMP,4 578 | return 579 | incf FSR0L,f 580 | btfsc TEMP,5 581 | return 582 | incf FSR0L,f 583 | btfsc TEMP,6 584 | return 585 | incf FSR0L,f 586 | btfsc TEMP,7 587 | return 588 | ; at this point, TEMP_2,0 is assumed to be set 589 | incf FSR0L,f 590 | return 591 | 592 | ; ================================= 593 | ; 594 | ; clear out the receive FIFO 595 | ; 596 | ; ================================= 597 | flush_rx_learn 598 | ; Flush the FIFO 599 | banksel RCREG 600 | movfw RCREG 601 | movfw RCREG 602 | ; Flush out any bytes & errors sitting around 603 | banksel RCSTA 604 | bcf RCSTA,4 605 | bsf RCSTA,4 606 | clrf BSR 607 | 608 | return 609 | 610 | ; ================================= 611 | ; 612 | ; write 32 bytes to program PROM 613 | ; from RAM: TEMP_5:TEMP_4 614 | ; to program ROM: TEMP_7:TEMP_6 615 | ; 616 | ; ================================= 617 | write_32_learn 618 | movfw TEMP_5 619 | movwf FSR0H 620 | movfw TEMP_4 621 | movwf FSR0L 622 | ; erase EEPROM block before write 623 | banksel EEADRH 624 | movfw TEMP_7 625 | movwf EEADRH 626 | movfw TEMP_6 627 | movwf EEADRL 628 | bsf EECON1,EEPGD 629 | bsf EECON1,WREN 630 | bsf EECON1,FREE 631 | movlw 0x55 632 | movwf EECON2 633 | movlw 0xAA 634 | movwf EECON2 635 | bsf EECON1,WR 636 | nop 637 | nop 638 | bcf EECON1,FREE 639 | bcf EECON1,WREN 640 | ; write EEPROM block 641 | ; EEADRH:EEADRL points to program EEPROM 642 | movfw TEMP_7 643 | movwf EEADRH 644 | movfw TEMP_6 645 | movwf EEADRL 646 | ; EECON1 stuff 647 | bsf EECON1,WREN 648 | ; 32 words to write 649 | movlw D'32' 650 | movwf TEMP 651 | write_buffer_learn_loop 652 | ; we're only using the low byte for storage. clear the high byte. 653 | moviw INDF0++ 654 | movwf EEDATL 655 | clrf EEDATH 656 | ; clear LWLO only for last of groups of 8 words 657 | ; ---> EEADRL[2:0] = B'111' 658 | bsf EECON1,LWLO 659 | movf EEADRL,w 660 | xorlw 0x07 661 | andlw 0x07 662 | btfsc STATUS,Z 663 | bcf EECON1,LWLO 664 | ; trigger the write 665 | movlw 0x55 666 | movwf EECON2 667 | movlw 0xAA 668 | movwf EECON2 669 | bsf EECON1,WR 670 | nop 671 | nop 672 | ; next word 673 | incf EEADR,f 674 | decfsz TEMP,f 675 | goto write_buffer_learn_loop 676 | bcf EECON1,WREN 677 | 678 | clrf BSR 679 | 680 | return 681 | 682 | ; ================================= 683 | ; 684 | ; fill 32 bytes to program PROM 685 | ; to program ROM: TEMP_6:TEMP_5 686 | ; fill data from TEMP_2 687 | ; 688 | ; ================================= 689 | fill_32_learn 690 | ; erase EEPROM block before write 691 | banksel EEADRH 692 | movfw TEMP_6 693 | movwf EEADRH 694 | movfw TEMP_5 695 | movwf EEADRL 696 | bsf EECON1,EEPGD 697 | bsf EECON1,WREN 698 | bsf EECON1,FREE 699 | movlw 0x55 700 | movwf EECON2 701 | movlw 0xAA 702 | movwf EECON2 703 | bsf EECON1,WR 704 | nop 705 | nop 706 | bcf EECON1,FREE 707 | bcf EECON1,WREN 708 | ; write EEPROM block 709 | ; EEADRH:EEADRL points to program EEPROM 710 | movfw TEMP_6 711 | movwf EEADRH 712 | movfw TEMP_5 713 | movwf EEADRL 714 | ; EECON1 stuff 715 | bsf EECON1,WREN 716 | ; 16 words to write 717 | movlw D'32' 718 | movwf TEMP 719 | fill_buffer_learn_loop 720 | ; we're only using the low byte for storage. clear the high byte. 721 | movfw TEMP_2 722 | ; movfw EEADRL 723 | movwf EEDATL 724 | clrf EEDATH 725 | ; clear LWLO only for last of groups of 8 words 726 | ; ---> EEADRL[2:0] = B'111' 727 | bsf EECON1,LWLO 728 | movf EEADRL,w 729 | xorlw 0x07 730 | andlw 0x07 731 | btfsc STATUS,Z 732 | bcf EECON1,LWLO 733 | ; trigger the write 734 | movlw 0x55 735 | movwf EECON2 736 | movlw 0xAA 737 | movwf EECON2 738 | bsf EECON1,WR 739 | nop 740 | nop 741 | ; next word 742 | incf EEADR,f 743 | decfsz TEMP,f 744 | goto fill_buffer_learn_loop 745 | bcf EECON1,WREN 746 | 747 | clrf BSR 748 | 749 | return 750 | 751 | ; ================================= 752 | ; 753 | ; Send config info via sysex. 754 | ; 755 | ; ================================= 756 | send_sysex_config 757 | ; grab bytes from data prom 758 | banksel EEADRL 759 | bcf EECON1,EEPGD 760 | ; version 761 | clrf EEADRL 762 | bsf EECON1,RD 763 | movfw EEDATL 764 | movwf TEMP 765 | ; channel 766 | movlw PROM_CHANNEL 767 | movwf EEADRL 768 | bsf EECON1,RD 769 | movfw EEDATL 770 | movwf TEMP_2 771 | ; first note 772 | incf EEADRL,f 773 | bsf EECON1,RD 774 | movfw EEDATL 775 | movwf TEMP_3 776 | ; note count 777 | incf EEADRL,f 778 | bsf EECON1,RD 779 | movfw EEDATL 780 | movwf TEMP_5 781 | ; setup complete flag 782 | incf EEADRL,f 783 | bsf EECON1,RD 784 | movfw EEDATL 785 | movwf TEMP_4 786 | clrf BSR 787 | ; send sysex header 788 | movlw 0xF0 789 | call transmit_byte_learn 790 | movlw 0x00 791 | call transmit_byte_learn 792 | movlw 0x01 793 | call transmit_byte_learn 794 | movlw 0x5D 795 | call transmit_byte_learn 796 | movlw 0x07 797 | call transmit_byte_learn 798 | movlw 0x00 799 | call transmit_byte_learn 800 | ; firmware version 801 | movfw TEMP 802 | call transmit_byte_learn 803 | ; polarity jumper 804 | movlw 0x01 805 | btfss PORTC,5 806 | clrw 807 | call transmit_byte_learn 808 | ; setup count 809 | movfw TEMP_4 810 | call transmit_byte_learn 811 | ; channel 812 | movfw TEMP_2 813 | call transmit_byte_learn 814 | ; first note 815 | movfw TEMP_3 816 | call transmit_byte_learn 817 | ; note count 818 | movfw TEMP_5 819 | call transmit_byte_learn 820 | ; footer 821 | movlw 0xF7 822 | call transmit_byte_learn 823 | 824 | return 825 | 826 | ; ================================= 827 | ; 828 | ; Send a MIDI byte from W register. 829 | ; Wait to make sure USART is ready. 830 | ; 831 | ; ================================= 832 | transmit_byte_learn 833 | nop 834 | nop 835 | btfss PIR1,TXIF 836 | goto $-1 837 | banksel TXREG 838 | movwf TXREG 839 | clrf BSR 840 | return 841 | 842 | ; ================================= 843 | ; 844 | ; Reset to "factory" state 845 | ; 846 | ; ================================= 847 | wipe_config 848 | ; clear the program rom 849 | ; first, the tx map 850 | movlw 0xFF 851 | movwf TEMP_2 852 | movlw 0x30 853 | movwf TEMP_6 854 | clrf TEMP_5 855 | wipe_config_loop_a 856 | call fill_32_learn 857 | movlw 0x20 858 | addwf TEMP_5,f 859 | btfsc STATUS,C 860 | incf TEMP_6,f 861 | ; check for completion at PROM 0x3800 862 | btfss TEMP_6,3 863 | goto wipe_config_loop_a 864 | ; second, the rx map 865 | clrf TEMP 866 | movlw 0x3D 867 | movwf TEMP_6 868 | clrf TEMP_5 869 | wipe_config_loop_b 870 | call fill_32_learn 871 | movlw 0x20 872 | addwf TEMP_5,f 873 | btfsc STATUS,C 874 | incf TEMP_6,f 875 | ; check for completion at PROM 0x4000 876 | btfss TEMP_6,6 877 | goto wipe_config_loop_b 878 | ; clear the data rom 879 | ; make sure EEPROM is ready to go 880 | banksel EECON1 881 | btfsc EECON1,WR 882 | goto $-1 883 | ; wipe channel 884 | clrf EEDATL 885 | movlw PROM_CHANNEL 886 | movwf EEADRL 887 | bcf EECON1,EEPGD 888 | bsf EECON1,WREN 889 | movlw 0x55 890 | movwf EECON2 891 | movlw 0xAA 892 | movwf EECON2 893 | bsf EECON1,WR 894 | ; make sure EEPROM is ready to go 895 | banksel EECON1 896 | btfsc EECON1,WR 897 | goto $-1 898 | ; wipe first note 899 | incf EEADRL,f 900 | bcf EECON1,EEPGD 901 | bsf EECON1,WREN 902 | movlw 0x55 903 | movwf EECON2 904 | movlw 0xAA 905 | movwf EECON2 906 | bsf EECON1,WR 907 | ; make sure EEPROM is ready to go 908 | banksel EECON1 909 | btfsc EECON1,WR 910 | goto $-1 911 | ; wipe setup complete flag 912 | incf EEADRL,f 913 | bcf EECON1,EEPGD 914 | bsf EECON1,WREN 915 | movlw 0x55 916 | movwf EECON2 917 | movlw 0xAA 918 | movwf EECON2 919 | bsf EECON1,WR 920 | ; make sure write is complete 921 | banksel EECON1 922 | btfsc EECON1,WR 923 | goto $-1 924 | clrf BSR 925 | 926 | return 927 | 928 | 929 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 930 | 931 | end 932 | 933 | -------------------------------------------------------------------------------- /pcb/UMR2-cradle.brd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | UMR2 CRADLE REV B 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | UMR2 Programming Cradle 118 | 119 | copyright John Staskevich, 2017 120 | 121 | john@codeandcopper.com 122 | 123 | 124 | This work is licensed under a Creative Commons Attribution 4.0 International License. 125 | http://creativecommons.org/licenses/by/4.0/ 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | >NAME 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | <b>VOLTAGE REGULATOR</b> 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | >NAME 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | <b>RESISTOR</b><p> 208 | type 0204, grid 5 mm 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | >NAME 228 | 229 | 230 | <b>CAPACITOR</b><p> 231 | grid 2.5 mm, outline 2.5 x 5 mm 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | >NAME 249 | >VALUE 250 | 251 | 252 | <b>ELECTROLYTIC CAPACITOR</b><p> 253 | grid 2.54 mm, diameter 5 mm 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | >NAME 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | <b>EAGLE Design Rules</b> 283 | <p> 284 | This Sunstone Circuits 2 Layer .DRU has been set to cover our minimum requirements for our double sided products. For questions, comments, suggestions, please contact Sunstone Customer Support Email: mailto:support@sunstone.com 285 | Phone: 503-829-9108 x555.<p> v1.1Mod10/16/07~Layers-core reversal.Distance C/D.Restring%.Supply G%.<p> v1.2 Mod12/06/07~Distance C/D to 20mils.<p>v1.3Mod12/12/07~Supply/Annulus Value to 12.5mils<p>1/15/08 SSC-EAGLE-2Lyr_v1.0.0.3~For Release<p> 286 | 287 | <p> 288 | <i>Attention: Upon running the design check and making modifications, please remember to save any changes before closing the application and sending in your board file to Sunstone Circuits for conversion.<i> 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | Since Version 6.2.2 text objects can contain more than one line, 608 | which will not be processed correctly with this version. 609 | 610 | 611 | 612 | -------------------------------------------------------------------------------- /hex/UMR2.hex: -------------------------------------------------------------------------------- 1 | :020000040000FA 2 | :02000000002FCF 3 | :06000200000000000000F8 4 | :080008008A017F1809288831E4 5 | :0A00100004287F1D00299031042808 6 | :06001A00000000000000E0 7 | :1000200000000000000000000000000000000000D0 8 | :1000300000000000000000000000000000000000C0 9 | :1000400000000000000000000000000000000000B0 10 | :1000500000000000000000000000000000000000A0 11 | :100060000000000000000000000000000000000090 12 | :100070000000000000000000000000000000000080 13 | :100080000000000000000000000000000000000070 14 | :100090000000000000000000000000000000000060 15 | :1000A0000000000000000000000000000000000050 16 | :1000B0000000000000000000000000000000000040 17 | :1000C0000000000000000000000000000000000030 18 | :1000D0000000000000000000000000000000000020 19 | :1000E0000000000000000000000000000000000010 20 | :1000F0000000000000000000000000000000000000 21 | :1001000000000000000000000000000000000000EF 22 | :1001100000000000000000000000000000000000DF 23 | :1001200000000000000000000000000000000000CF 24 | :1001300000000000000000000000000000000000BF 25 | :1001400000000000000000000000000000000000AF 26 | :10015000000000000000000000000000000000009F 27 | :10016000000000000000000000000000000000008F 28 | :10017000000000000000000000000000000000007F 29 | :10018000000000000000000000000000000000006F 30 | :10019000000000000000000000000000000000005F 31 | :1001A000000000000000000000000000000000004F 32 | :1001B000000000000000000000000000000000003F 33 | :1001C000000000000000000000000000000000002F 34 | :1001D000000000000000000000000000000000001F 35 | :1001E000000000000000000000000000000000000F 36 | :1001F00000000000000000000000000000000000FF 37 | :1002000083018801911A05298A2A23001908F5001B 38 | :100210008801F030750203193D29F7307502031982 39 | :10022000862A7508F839F83C0319A62AF51B8A2A8C 40 | :100230007F1CA62AFF184129F20A7208F600F60B65 41 | :10024000262900307502031D8A2AA62AF60B2D29BD 42 | :1002500001307502031D8A2AA62AF60B34295D3067 43 | :100260007502031D8A2AA62AF60B8A2A0730750210 44 | :10027000031D8A2AFF14F201A62AF2017F14FF103F 45 | :10028000A62AF20A7208F600F60B53297E30750290 46 | :10029000031958297F30750203195B297508031D5E 47 | :1002A0008A2AF203A62AFF1AC6297F1A5D298A2AFA 48 | :1002B000FF16F701A62A7F16A62AF60B62297508F3 49 | :1002C000F800A62AF60B6A297808803EF507F50F94 50 | :1002D0008A2AA62AF60B6F297508FA00A62AF60BB9 51 | :1002E00077297A08803EF507F50F8A2AA62AF60BA9 52 | :1002F0007C297508FB00A62AF60B8C297B08803E1A 53 | :10030000F507F50F8A2A7A18F8177B18FA170310E1 54 | :10031000FA0CFB18FA17A62AF60B91297508FB00B0 55 | :10032000A62AF60B8A2A7B08803EF507F50F8A2A53 56 | :100330008B138B1B9829230095189C297B0893000D 57 | :10034000003091009513151555309600AA3096008F 58 | :1003500095149518A9297A089300910A1515553016 59 | :100360009600AA30960095149518B4297808930041 60 | :10037000910A9513151555309600AA3096009514DC 61 | :100380009518C0298801CC308E00C529F60BCB29E1 62 | :100390007508FA00A62AF60BD3297A08803EF507DD 63 | :1003A000F50F8A2AA62AF60BD8297508FB00A62A7B 64 | :1003B000F60BE4297B08803EF507F50F8A2A7B18A7 65 | :1003C000FA170310FB0CA62AF60BE9297508F900A9 66 | :1003D000A62AF60BF1297908803EF507F50F8A2A3F 67 | :1003E000A62AF60BF6297508F800A62AF60B8A2A23 68 | :1003F0007808803EF507F50F8A2A7818F917031058 69 | :10040000F80C7808031D052A332A7808013C031DDF 70 | :100410000C2A79080319332A78083039103C031D57 71 | :10042000222AF7181B2A7718182A0930F806222AD8 72 | :100430000230F806222A7718202A0E30F806222ADF 73 | :100440000530F806F7182C2A7718292A1B30F906E8 74 | :10045000332A2130F906332A7718312A0730F90672 75 | :10046000332A3230F9068501A030840077088407EA 76 | :10047000840779088000840A78088000F70A203011 77 | :1004800077020319462A0430F202A62A8B138B1B2B 78 | :10049000462A23007B0892007A08910095171515CB 79 | :1004A000151655309600AA309600951400000000ED 80 | :1004B000151215118501A03084007B0892007A087E 81 | :1004C000910015152030F5001200930012009400E1 82 | :1004D00095161108073A07390319951255309600F9 83 | :1004E000AA309600951400000000910AF50B642ACA 84 | :1004F00015112300190819082000911223001D125C 85 | :100500001D1688018B17FF12F201A62AFF107F101B 86 | :100510008801882AFF107F108801CC308E00A0014E 87 | :10052000A2010000000000000000A00B912AA20B15 88 | :10053000912AC4308E00A001A2010000000000003A 89 | :0E0540000000A00B9D2AA20B9D2A8D2A090007 90 | :02054E000000AB 91 | :10055000000000000000000000000000000000009B 92 | :10056000000000000000000000000000000000008B 93 | :10057000000000000000000000000000000000007B 94 | :10058000000000000000000000000000000000006B 95 | :10059000000000000000000000000000000000005B 96 | :1005A000000000000000000000000000000000004B 97 | :1005B000000000000000000000000000000000003B 98 | :1005C000000000000000000000000000000000002B 99 | :1005D000000000000000000000000000000000001B 100 | :1005E000000000000000000000000000000000000B 101 | :1005F00000000000000000000000000000000000FB 102 | :1006000000000000000000000000000000000000EA 103 | :1006100000000000000000000000000000000000DA 104 | :1006200000000000000000000000000000000000CA 105 | :1006300000000000000000000000000000000000BA 106 | :1006400000000000000000000000000000000000AA 107 | :10065000000000000000000000000000000000009A 108 | :10066000000000000000000000000000000000008A 109 | :10067000000000000000000000000000000000007A 110 | :10068000000000000000000000000000000000006A 111 | :10069000000000000000000000000000000000005A 112 | :1006A000000000000000000000000000000000004A 113 | :1006B000000000000000000000000000000000003A 114 | :1006C000000000000000000000000000000000002A 115 | :1006D000000000000000000000000000000000001A 116 | :1006E000000000000000000000000000000000000A 117 | :1006F00000000000000000000000000000000000FA 118 | :1007000000000000000000000000000000000000E9 119 | :1007100000000000000000000000000000000000D9 120 | :1007200000000000000000000000000000000000C9 121 | :1007300000000000000000000000000000000000B9 122 | :1007400000000000000000000000000000000000A9 123 | :100750000000000000000000000000000000000099 124 | :100760000000000000000000000000000000000089 125 | :100770000000000000000000000000000000000079 126 | :100780000000000000000000000000000000000069 127 | :100790000000000000000000000000000000000059 128 | :1007A0000000000000000000000000000000000049 129 | :1007B0000000000000000000000000000000000039 130 | :1007C0000000000000000000000000000000000029 131 | :1007D0000000000000000000000000000000000019 132 | :1007E0000000000000000000000000000000000009 133 | :1007F00000000000000000000000000000000000F9 134 | :1008000000000000000000000000000000000000E8 135 | :1008100000000000000000000000000000000000D8 136 | :1008200000000000000000000000000000000000C8 137 | :1008300000000000000000000000000000000000B8 138 | :1008400000000000000000000000000000000000A8 139 | :100850000000000000000000000000000000000098 140 | :100860000000000000000000000000000000000088 141 | :100870000000000000000000000000000000000078 142 | :100880000000000000000000000000000000000068 143 | :100890000000000000000000000000000000000058 144 | :1008A0000000000000000000000000000000000048 145 | :1008B0000000000000000000000000000000000038 146 | :1008C0000000000000000000000000000000000028 147 | :1008D0000000000000000000000000000000000018 148 | :1008E0000000000000000000000000000000000008 149 | :1008F00000000000000000000000000000000000F8 150 | :1009000000000000000000000000000000000000E7 151 | :1009100000000000000000000000000000000000D7 152 | :1009200000000000000000000000000000000000C7 153 | :1009300000000000000000000000000000000000B7 154 | :1009400000000000000000000000000000000000A7 155 | :100950000000000000000000000000000000000097 156 | :100960000000000000000000000000000000000087 157 | :100970000000000000000000000000000000000077 158 | :100980000000000000000000000000000000000067 159 | :100990000000000000000000000000000000000057 160 | :1009A0000000000000000000000000000000000047 161 | :1009B0000000000000000000000000000000000037 162 | :1009C0000000000000000000000000000000000027 163 | :1009D0000000000000000000000000000000000017 164 | :1009E0000000000000000000000000000000000007 165 | :1009F00000000000000000000000000000000000F7 166 | :100A000000000000000000000000000000000000E6 167 | :100A100000000000000000000000000000000000D6 168 | :100A200000000000000000000000000000000000C6 169 | :100A300000000000000000000000000000000000B6 170 | :100A400000000000000000000000000000000000A6 171 | :100A50000000000000000000000000000000000096 172 | :100A60000000000000000000000000000000000086 173 | :100A70000000000000000000000000000000000076 174 | :100A80000000000000000000000000000000000066 175 | :100A90000000000000000000000000000000000056 176 | :100AA0000000000000000000000000000000000046 177 | :100AB0000000000000000000000000000000000036 178 | :100AC0000000000000000000000000000000000026 179 | :100AD0000000000000000000000000000000000016 180 | :100AE0000000000000000000000000000000000006 181 | :100AF00000000000000000000000000000000000F6 182 | :100B000000000000000000000000000000000000E5 183 | :100B100000000000000000000000000000000000D5 184 | :100B200000000000000000000000000000000000C5 185 | :100B300000000000000000000000000000000000B5 186 | :100B400000000000000000000000000000000000A5 187 | :100B50000000000000000000000000000000000095 188 | :100B60000000000000000000000000000000000085 189 | :100B70000000000000000000000000000000000075 190 | :100B80000000000000000000000000000000000065 191 | :100B90000000000000000000000000000000000055 192 | :100BA0000000000000000000000000000000000045 193 | :100BB0000000000000000000000000000000000035 194 | :100BC0000000000000000000000000000000000025 195 | :100BD0000000000000000000000000000000000015 196 | :100BE0000000000000000000000000000000000005 197 | :100BF00000000000000000000000000000000000F5 198 | :100C000000000000000000000000000000000000E4 199 | :100C100000000000000000000000000000000000D4 200 | :100C200000000000000000000000000000000000C4 201 | :100C300000000000000000000000000000000000B4 202 | :100C400000000000000000000000000000000000A4 203 | :100C50000000000000000000000000000000000094 204 | :100C60000000000000000000000000000000000084 205 | :100C70000000000000000000000000000000000074 206 | :100C80000000000000000000000000000000000064 207 | :100C90000000000000000000000000000000000054 208 | :100CA0000000000000000000000000000000000044 209 | :100CB0000000000000000000000000000000000034 210 | :100CC0000000000000000000000000000000000024 211 | :100CD0000000000000000000000000000000000014 212 | :100CE0000000000000000000000000000000000004 213 | :100CF00000000000000000000000000000000000F4 214 | :100D000000000000000000000000000000000000E3 215 | :100D100000000000000000000000000000000000D3 216 | :100D200000000000000000000000000000000000C3 217 | :100D300000000000000000000000000000000000B3 218 | :100D400000000000000000000000000000000000A3 219 | :100D50000000000000000000000000000000000093 220 | :100D60000000000000000000000000000000000083 221 | :100D70000000000000000000000000000000000073 222 | :100D80000000000000000000000000000000000063 223 | :100D90000000000000000000000000000000000053 224 | :100DA0000000000000000000000000000000000043 225 | :100DB0000000000000000000000000000000000033 226 | :100DC0000000000000000000000000000000000023 227 | :100DD0000000000000000000000000000000000013 228 | :100DE0000000000000000000000000000000000003 229 | :100DF00000000000000000000000000000000000F3 230 | :100E000021008730950088018C018D01CC308E0047 231 | :100E10008F01900123008C018D018F019001210031 232 | :100E2000F030990021007F308C00FF308D00E030E1 233 | :100E30008E00FF308F00F830900023003F309B0081 234 | :100E400026309E0090309D00210091168801FF0100 235 | :100E50008C1E2D2F402788310028C4308E007F142F 236 | :100E6000C0308B008C1E322F8B13000000007F15CA 237 | :060E70004027903100282C 238 | :0A0E76000000000000000000000072 239 | :100E8000F501F60123009101920195171514000058 240 | :100E900000001308F5071408F63D910F462F920A3B 241 | :100EA000921E462F01309100951315141308F80077 242 | :100EB000910A15141308F70003147708F53D780814 243 | :100EC000F63D7608031D692F7508031D692F8801FB 244 | :100ED000080088010C308E00A001A1010830A2009A 245 | :100EE0000000A00B702FA10B702FA20B702F0430ED 246 | :100EF0008E00A001A1010830A2000000A00B7D2FF0 247 | :0C0F0000A10B7D2FA20B7D2F6A2F080093 248 | :040F0C0000000000E1 249 | :100F100000000000000000000000000000000000D1 250 | :100F200000000000000000000000000000000000C1 251 | :100F300000000000000000000000000000000000B1 252 | :100F400000000000000000000000000000000000A1 253 | :100F50000000000000000000000000000000000091 254 | :100F60000000000000000000000000000000000081 255 | :100F70000000000000000000000000000000000071 256 | :100F80000000000000000000000000000000000061 257 | :100F90000000000000000000000000000000000051 258 | :100FA0000000000000000000000000000000000041 259 | :100FB0000000000000000000000000000000000031 260 | :100FC0000000000000000000000000000000000021 261 | :100FD0000000000000000000000000000000000011 262 | :100FE0000000000000000000000000000000000001 263 | :100FF00000000000000000000000000000000000F1 264 | :02100000002CC2 265 | :06100200000000000000E8 266 | :081008008801911A0F280B1951 267 | :101010000A2809008B120B1108308E0009002300EA 268 | :1010200019089A00FE008801FE1F2C287E09F83955 269 | :10103000031909007408FE02031928281030FE0263 270 | :1010400003192428FC0109000230FC00FF100900EC 271 | :101050000130FC00FF100900FF1C3428FF107C1831 272 | :101060003E28FC184B28090024087E027F39F10035 273 | :10107000FF148E0195010B118B1609007108840075 274 | :10108000BD30850000088600850A00088700850AB3 275 | :10109000000981050900FE0803193E287108840033 276 | :1010A000BD30850000088600850A00088700850A93 277 | :0610B000000881040900A4 278 | :0A10B6000000000000000000000030 279 | :1010C0000000000000000000000000000000000020 280 | :1010D0000000000000000000000000000000000010 281 | :1010E0000000000000000000000000000000000000 282 | :1010F00000000000000000000000000000000000F0 283 | :1011000000000000000000000000000000000000DF 284 | :1011100000000000000000000000000000000000CF 285 | :1011200000000000000000000000000000000000BF 286 | :1011300000000000000000000000000000000000AF 287 | :10114000000000000000000000000000000000009F 288 | :10115000000000000000000000000000000000008F 289 | :10116000000000000000000000000000000000007F 290 | :10117000000000000000000000000000000000006F 291 | :10118000000000000000000000000000000000005F 292 | :10119000000000000000000000000000000000004F 293 | :1011A000000000000000000000000000000000003F 294 | :1011B000000000000000000000000000000000002F 295 | :1011C000000000000000000000000000000000001F 296 | :1011D000000000000000000000000000000000000F 297 | :1011E00000000000000000000000000000000000FF 298 | :1011F00000000000000000000000000000000000EF 299 | :1012000000000000000000000000000000000000DE 300 | :1012100000000000000000000000000000000000CE 301 | :1012200000000000000000000000000000000000BE 302 | :1012300000000000000000000000000000000000AE 303 | :10124000000000000000000000000000000000009E 304 | :10125000000000000000000000000000000000008E 305 | :10126000000000000000000000000000000000007E 306 | :10127000000000000000000000000000000000006E 307 | :10128000000000000000000000000000000000005E 308 | :10129000000000000000000000000000000000004E 309 | :1012A000000000000000000000000000000000003E 310 | :1012B000000000000000000000000000000000002E 311 | :1012C000000000000000000000000000000000001E 312 | :1012D000000000000000000000000000000000000E 313 | :1012E00000000000000000000000000000000000FE 314 | :1012F00000000000000000000000000000000000EE 315 | :1013000000000000000000000000000000000000DD 316 | :1013100000000000000000000000000000000000CD 317 | :1013200000000000000000000000000000000000BD 318 | :1013300000000000000000000000000000000000AD 319 | :10134000000000000000000000000000000000009D 320 | :10135000000000000000000000000000000000008D 321 | :10136000000000000000000000000000000000007D 322 | :10137000000000000000000000000000000000006D 323 | :10138000000000000000000000000000000000005D 324 | :10139000000000000000000000000000000000004D 325 | :1013A000000000000000000000000000000000003D 326 | :1013B000000000000000000000000000000000002D 327 | :1013C000000000000000000000000000000000001D 328 | :1013D000000000000000000000000000000000000D 329 | :1013E00000000000000000000000000000000000FD 330 | :1013F00000000000000000000000000000000000ED 331 | :1014000000000000000000000000000000000000DC 332 | :1014100000000000000000000000000000000000CC 333 | :1014200000000000000000000000000000000000BC 334 | :1014300000000000000000000000000000000000AC 335 | :10144000000000000000000000000000000000009C 336 | :10145000000000000000000000000000000000008C 337 | :10146000000000000000000000000000000000007C 338 | :10147000000000000000000000000000000000006C 339 | :10148000000000000000000000000000000000005C 340 | :10149000000000000000000000000000000000004C 341 | :1014A000000000000000000000000000000000003C 342 | :1014B000000000000000000000000000000000002C 343 | :1014C000000000000000000000000000000000001C 344 | :1014D000000000000000000000000000000000000C 345 | :1014E00000000000000000000000000000000000FC 346 | :1014F00000000000000000000000000000000000EC 347 | :1015000000000000000000000000000000000000DB 348 | :1015100000000000000000000000000000000000CB 349 | :1015200000000000000000000000000000000000BB 350 | :1015300000000000000000000000000000000000AB 351 | :10154000000000000000000000000000000000009B 352 | :10155000000000000000000000000000000000008B 353 | :10156000000000000000000000000000000000007B 354 | :10157000000000000000000000000000000000006B 355 | :10158000000000000000000000000000000000005B 356 | :10159000000000000000000000000000000000004B 357 | :1015A000000000000000000000000000000000003B 358 | :1015B000000000000000000000000000000000002B 359 | :1015C000000000000000000000000000000000001B 360 | :1015D000000000000000000000000000000000000B 361 | :1015E00000000000000000000000000000000000FB 362 | :1015F00000000000000000000000000000000000EB 363 | :1016000000000000000000000000000000000000DA 364 | :1016100000000000000000000000000000000000CA 365 | :1016200000000000000000000000000000000000BA 366 | :1016300000000000000000000000000000000000AA 367 | :10164000000000000000000000000000000000009A 368 | :10165000000000000000000000000000000000008A 369 | :10166000000000000000000000000000000000007A 370 | :10167000000000000000000000000000000000006A 371 | :10168000000000000000000000000000000000005A 372 | :10169000000000000000000000000000000000004A 373 | :1016A000000000000000000000000000000000003A 374 | :1016B000000000000000000000000000000000002A 375 | :1016C000000000000000000000000000000000001A 376 | :1016D000000000000000000000000000000000000A 377 | :1016E00000000000000000000000000000000000FA 378 | :1016F00000000000000000000000000000000000EA 379 | :1017000000000000000000000000000000000000D9 380 | :1017100000000000000000000000000000000000C9 381 | :1017200000000000000000000000000000000000B9 382 | :1017300000000000000000000000000000000000A9 383 | :101740000000000000000000000000000000000099 384 | :101750000000000000000000000000000000000089 385 | :101760000000000000000000000000000000000079 386 | :101770000000000000000000000000000000000069 387 | :101780000000000000000000000000000000000059 388 | :101790000000000000000000000000000000000049 389 | :1017A0000000000000000000000000000000000039 390 | :1017B0000000000000000000000000000000000029 391 | :1017C0000000000000000000000000000000000019 392 | :1017D0000000000000000000000000000000000009 393 | :1017E00000000000000000000000000000000000F9 394 | :1017F00000000000000000000000000000000000E9 395 | :10180000FF010C1E7F162300033091009513151461 396 | :101810001308F500910A15141308F600910A15141F 397 | :101820001308F70088017508803EF400103EF300AD 398 | :101830007608A4008401223085008001840F1D2CCD 399 | :10184000850A8001840F212C85038E019B249B2413 400 | :101850009B24FF308F008E1A8F0108308E002300EA 401 | :101860001908190823001D127F1E1D168801230068 402 | :10187000190819088801C0308B007F1A552C8E1A60 403 | :101880004B2C0D08840005100C18051408140009D1 404 | :101890008F008801412C0D09840005100C1C0514D3 405 | :1018A000081400098F0088014B2CBC24F80B552C20 406 | :1018B000E724770800060319552CF8000325811B3F 407 | :1018C000552C781C662C0130F800862CF81C6B2CEB 408 | :1018D0000230F800862C781D702C0430F800862C1D 409 | :1018E000F81D752C0830F800862C781E7A2C1030E4 410 | :1018F000F800862CF81E7F2C2030F800862C781FEC 411 | :10190000842C4030F800862C8030F8008E01950140 412 | :101910000B118B167F30F900780877050319F90150 413 | :1019200073083D25010824077F393D2579083D25A9 414 | :1019300078088006552CFF30A200FF30A000000080 415 | :101940000000000000000000000000000000000097 416 | :101950000000000000000000000000000000000087 417 | :101960000000000000000000000000000000A00BCC 418 | :101970009F2CA20B9D2C08000D08F5000C08F6000A 419 | :101980000F08F7000D087502031D08000C08760209 420 | :10199000031D08000F087702031D08008E1ED32CBC 421 | :1019A000F509F609F709F8017518F80AF518F80AA3 422 | :1019B0007519F80AF519F80A751AF80AF51AF80AE5 423 | :1019C000751BF80AF51BF80A7618F80A0800850155 424 | :1019D0006030840075180800840AF5180800840A2D 425 | :1019E00075190800840AF5190800840A751A080098 426 | :1019F000840AF51A0800840A751B0800840AF51B7E 427 | :101A00000800840A0800BC30870080308600751802 428 | :101A1000272D08308607F518272D083086077519F9 429 | :101A2000272D08308607F519272D08308607751AE7 430 | :101A3000272D08308607F51A272D08308607751BD5 431 | :101A4000272D08308607F51B272D083086077818C4 432 | :101A50000800860AF8180800860A78190800860A1D 433 | :101A6000F8190800860A781A0800860AF81A080089 434 | :101A7000860A781B0800860A080000000000111E74 435 | :0A1A80003F2D23009A0088010800A2 436 | :061A8A0000000000000056 437 | :101A90000000000000000000000000000000000046 438 | :101AA0000000000000000000000000000000000036 439 | :101AB0000000000000000000000000000000000026 440 | :101AC0000000000000000000000000000000000016 441 | :101AD0000000000000000000000000000000000006 442 | :101AE00000000000000000000000000000000000F6 443 | :101AF00000000000000000000000000000000000E6 444 | :101B000000000000000000000000000000000000D5 445 | :101B100000000000000000000000000000000000C5 446 | :101B200000000000000000000000000000000000B5 447 | :101B300000000000000000000000000000000000A5 448 | :101B40000000000000000000000000000000000095 449 | :101B50000000000000000000000000000000000085 450 | :101B60000000000000000000000000000000000075 451 | :101B70000000000000000000000000000000000065 452 | :101B80000000000000000000000000000000000055 453 | :101B90000000000000000000000000000000000045 454 | :101BA0000000000000000000000000000000000035 455 | :101BB0000000000000000000000000000000000025 456 | :101BC0000000000000000000000000000000000015 457 | :101BD0000000000000000000000000000000000005 458 | :101BE00000000000000000000000000000000000F5 459 | :101BF00000000000000000000000000000000000E5 460 | :101C000000000000000000000000000000000000D4 461 | :101C100000000000000000000000000000000000C4 462 | :101C200000000000000000000000000000000000B4 463 | :101C300000000000000000000000000000000000A4 464 | :101C40000000000000000000000000000000000094 465 | :101C50000000000000000000000000000000000084 466 | :101C60000000000000000000000000000000000074 467 | :101C70000000000000000000000000000000000064 468 | :101C80000000000000000000000000000000000054 469 | :101C90000000000000000000000000000000000044 470 | :101CA0000000000000000000000000000000000034 471 | :101CB0000000000000000000000000000000000024 472 | :101CC0000000000000000000000000000000000014 473 | :101CD0000000000000000000000000000000000004 474 | :101CE00000000000000000000000000000000000F4 475 | :101CF00000000000000000000000000000000000E4 476 | :101D000000000000000000000000000000000000D3 477 | :101D100000000000000000000000000000000000C3 478 | :101D200000000000000000000000000000000000B3 479 | :101D300000000000000000000000000000000000A3 480 | :101D40000000000000000000000000000000000093 481 | :101D50000000000000000000000000000000000083 482 | :101D60000000000000000000000000000000000073 483 | :101D70000000000000000000000000000000000063 484 | :101D80000000000000000000000000000000000053 485 | :101D90000000000000000000000000000000000043 486 | :101DA0000000000000000000000000000000000033 487 | :101DB0000000000000000000000000000000000023 488 | :101DC0000000000000000000000000000000000013 489 | :101DD0000000000000000000000000000000000003 490 | :101DE00000000000000000000000000000000000F3 491 | :101DF00000000000000000000000000000000000E3 492 | :101E000000000000000000000000000000000000D2 493 | :101E100000000000000000000000000000000000C2 494 | :101E200000000000000000000000000000000000B2 495 | :101E300000000000000000000000000000000000A2 496 | :101E40000000000000000000000000000000000092 497 | :101E50000000000000000000000000000000000082 498 | :101E60000000000000000000000000000000000072 499 | :101E70000000000000000000000000000000000062 500 | :101E80000000000000000000000000000000000052 501 | :101E90000000000000000000000000000000000042 502 | :101EA0000000000000000000000000000000000032 503 | :101EB0000000000000000000000000000000000022 504 | :101EC0000000000000000000000000000000000012 505 | :101ED0000000000000000000000000000000000002 506 | :101EE00000000000000000000000000000000000F2 507 | :101EF00000000000000000000000000000000000E2 508 | :101F000000000000000000000000000000000000D1 509 | :101F100000000000000000000000000000000000C1 510 | :101F200000000000000000000000000000000000B1 511 | :101F300000000000000000000000000000000000A1 512 | :101F40000000000000000000000000000000000091 513 | :101F50000000000000000000000000000000000081 514 | :101F60000000000000000000000000000000000071 515 | :101F70000000000000000000000000000000000061 516 | :101F80000000000000000000000000000000000051 517 | :101F90000000000000000000000000000000000041 518 | :101FA0000000000000000000000000000000000031 519 | :101FB0000000000000000000000000000000000021 520 | :101FC0000000000000000000000000000000000011 521 | :101FD0000000000000000000000000000000000001 522 | :101FE00000000000000000000000000000000000F1 523 | :101FF00000000000000000000000000000000000E1 524 | :02200000002CB2 525 | :042002000034003472 526 | :022006000000D8 527 | :082008008801911A0A280B1946 528 | :102010003728090023001908FE002000FF1D13289F 529 | :10202000210091120900FE1F26287E09F8390319A4 530 | :102030000900F0307E05903C03192028FC010900BE 531 | :102040000230FC007E08F300FF100900FF1C2C2862 532 | :10205000FF10FC18302809007E08F100FF14090069 533 | :10206000FE08031909007108A400FF1509000B11EF 534 | :0E207000A30B09001F30A30004308E060900E8 535 | :02207E00000060 536 | :102080000000000000000000000000000000000050 537 | :102090000000000000000000000000000000000040 538 | :1020A0000000000000000000000000000000000030 539 | :1020B0000000000000000000000000000000000020 540 | :1020C0000000000000000000000000000000000010 541 | :1020D0000000000000000000000000000000000000 542 | :1020E00000000000000000000000000000000000F0 543 | :1020F00000000000000000000000000000000000E0 544 | :1021000000000000000000000000000000000000CF 545 | :1021100000000000000000000000000000000000BF 546 | :1021200000000000000000000000000000000000AF 547 | :10213000000000000000000000000000000000009F 548 | :10214000000000000000000000000000000000008F 549 | :10215000000000000000000000000000000000007F 550 | :10216000000000000000000000000000000000006F 551 | :10217000000000000000000000000000000000005F 552 | :10218000000000000000000000000000000000004F 553 | :10219000000000000000000000000000000000003F 554 | :1021A000000000000000000000000000000000002F 555 | :1021B000000000000000000000000000000000001F 556 | :1021C000000000000000000000000000000000000F 557 | :1021D00000000000000000000000000000000000FF 558 | :1021E00000000000000000000000000000000000EF 559 | :1021F00000000000000000000000000000000000DF 560 | :1022000000000000000000000000000000000000CE 561 | :1022100000000000000000000000000000000000BE 562 | :1022200000000000000000000000000000000000AE 563 | :10223000000000000000000000000000000000009E 564 | :10224000000000000000000000000000000000008E 565 | :10225000000000000000000000000000000000007E 566 | :10226000000000000000000000000000000000006E 567 | :10227000000000000000000000000000000000005E 568 | :10228000000000000000000000000000000000004E 569 | :10229000000000000000000000000000000000003E 570 | :1022A000000000000000000000000000000000002E 571 | :1022B000000000000000000000000000000000001E 572 | :1022C000000000000000000000000000000000000E 573 | :1022D00000000000000000000000000000000000FE 574 | :1022E00000000000000000000000000000000000EE 575 | :1022F00000000000000000000000000000000000DE 576 | :1023000000000000000000000000000000000000CD 577 | :1023100000000000000000000000000000000000BD 578 | :1023200000000000000000000000000000000000AD 579 | :10233000000000000000000000000000000000009D 580 | :10234000000000000000000000000000000000008D 581 | :10235000000000000000000000000000000000007D 582 | :10236000000000000000000000000000000000006D 583 | :10237000000000000000000000000000000000005D 584 | :10238000000000000000000000000000000000004D 585 | :10239000000000000000000000000000000000003D 586 | :1023A000000000000000000000000000000000002D 587 | :1023B000000000000000000000000000000000001D 588 | :1023C000000000000000000000000000000000000D 589 | :1023D00000000000000000000000000000000000FD 590 | :1023E00000000000000000000000000000000000ED 591 | :1023F00000000000000000000000000000000000DD 592 | :1024000000000000000000000000000000000000CC 593 | :1024100000000000000000000000000000000000BC 594 | :1024200000000000000000000000000000000000AC 595 | :10243000000000000000000000000000000000009C 596 | :10244000000000000000000000000000000000008C 597 | :10245000000000000000000000000000000000007C 598 | :10246000000000000000000000000000000000006C 599 | :10247000000000000000000000000000000000005C 600 | :10248000000000000000000000000000000000004C 601 | :10249000000000000000000000000000000000003C 602 | :1024A000000000000000000000000000000000002C 603 | :1024B000000000000000000000000000000000001C 604 | :1024C000000000000000000000000000000000000C 605 | :1024D00000000000000000000000000000000000FC 606 | :1024E00000000000000000000000000000000000EC 607 | :1024F00000000000000000000000000000000000DC 608 | :1025000000000000000000000000000000000000CB 609 | :1025100000000000000000000000000000000000BB 610 | :1025200000000000000000000000000000000000AB 611 | :10253000000000000000000000000000000000009B 612 | :10254000000000000000000000000000000000008B 613 | :10255000000000000000000000000000000000007B 614 | :10256000000000000000000000000000000000006B 615 | :10257000000000000000000000000000000000005B 616 | :10258000000000000000000000000000000000004B 617 | :10259000000000000000000000000000000000003B 618 | :1025A000000000000000000000000000000000002B 619 | :1025B000000000000000000000000000000000001B 620 | :1025C000000000000000000000000000000000000B 621 | :1025D00000000000000000000000000000000000FB 622 | :1025E00000000000000000000000000000000000EB 623 | :1025F00000000000000000000000000000000000DB 624 | :1026000000000000000000000000000000000000CA 625 | :1026100000000000000000000000000000000000BA 626 | :1026200000000000000000000000000000000000AA 627 | :10263000000000000000000000000000000000009A 628 | :10264000000000000000000000000000000000008A 629 | :10265000000000000000000000000000000000007A 630 | :10266000000000000000000000000000000000006A 631 | :10267000000000000000000000000000000000005A 632 | :10268000000000000000000000000000000000004A 633 | :10269000000000000000000000000000000000003A 634 | :1026A000000000000000000000000000000000002A 635 | :1026B000000000000000000000000000000000001A 636 | :1026C000000000000000000000000000000000000A 637 | :1026D00000000000000000000000000000000000FA 638 | :1026E00000000000000000000000000000000000EA 639 | :1026F00000000000000000000000000000000000DA 640 | :1027000000000000000000000000000000000000C9 641 | :1027100000000000000000000000000000000000B9 642 | :1027200000000000000000000000000000000000A9 643 | :102730000000000000000000000000000000000099 644 | :102740000000000000000000000000000000000089 645 | :102750000000000000000000000000000000000079 646 | :102760000000000000000000000000000000000069 647 | :102770000000000000000000000000000000000059 648 | :102780000000000000000000000000000000000049 649 | :102790000000000000000000000000000000000039 650 | :1027A0000000000000000000000000000000000029 651 | :1027B0000000000000000000000000000000000019 652 | :1027C0000000000000000000000000000000000009 653 | :1027D00000000000000000000000000000000000F9 654 | :1027E00000000000000000000000000000000000E9 655 | :1027F00000000000000000000000000000000000D9 656 | :10280000EB257808A6000C308E001F30A300E030C6 657 | :102810008B008325FF1D0A2C2100911288018B1348 658 | :1028200004308E000F30730523009518152C93008B 659 | :10283000033091009513151555309600AA30960077 660 | :1028400095148801240823009518242C9300043043 661 | :1028500091009513151555309600AA3096009514E1 662 | :1028600023009518312C8801D001D101D201D30168 663 | :10287000D401D501D601D701D801E001E101E2017F 664 | :10288000E301E401E501E601E701E801840121300B 665 | :1028900085008001850A22308000850A8001840F2E 666 | :1028A000472C2030850080308400FF308000840F6A 667 | :1028B000552CA001A1010830A200A00B642CA10B93 668 | :1028C000642CA20B642C6E2C3C25F80B5D2C672528 669 | :1028D000001410308407770880005D2C0C308E00C7 670 | :1028E0001F30A3008B1786018C1ED92C3C25F80BBA 671 | :1028F000742C6725001C742C1030840777080006A0 672 | :102900000319742CF8002130870075088100870AAC 673 | :1029100076080139223E8100870A7808810020303C 674 | :102920008500803084007518B32C08308407F518B2 675 | :10293000B32C083084077519B32C08308407F519B7 676 | :10294000B32C08308407751AB32C08308407F51AA5 677 | :10295000B32C08308407751BB32C08308407F51B93 678 | :10296000B32C083084077818C82C840AF818C82CAF 679 | :10297000840A7819C82C840AF819C82C840A781A91 680 | :10298000C82C840AF81AC82C840A781BC82C840A1C 681 | :1029900006088000860A7F3086058B130000000041 682 | :1029A00004308E00172508308E001F30A3008B17CF 683 | :1029B000742C8B1304308E002030F900F8013C3069 684 | :1029C000FB00FA018B252030F8070318F90AFA07F3 685 | :1029D0000318FB0A7B1FE22C23009518ED2C060838 686 | :1029E0007F399300053091009513151555309600E9 687 | :1029F000AA309600951423009518FC2C8801260A0D 688 | :102A00007F3923009300063091009513151555303A 689 | :102A10009600AA3096009514230095180D2D880174 690 | :102A2000EB25172517250C308E000000152D0430DE 691 | :102A3000A200FF30A100FF30A00000000000000055 692 | :102A40000000000000000000000000000000000086 693 | :102A50000000000000000000000000000000000076 694 | :102A600000000000000000000000A00B1D2DA10BC5 695 | :102A70001B2DA20B192D08000D08F5000C08F600FF 696 | :102A80000F08F7000D087502031D08000C087602F8 697 | :102A9000031D08000F087702031D08008E1E532D2A 698 | :102AA000F509F609F709F8017518F80AF518F80A92 699 | :102AB0007519F80AF519F80A751AF80AF51AF80AD4 700 | :102AC000751BF80AF51BF80A7618F80A0800850144 701 | :102AD0005030840075180800840AF5180800840A2C 702 | :102AE00075190800840AF5190800840A751A080087 703 | :102AF000840AF51A0800840A751B0800840AF51B6D 704 | :102B00000800840A080023001908190823001D1270 705 | :102B10001D168801080079088500780884002300C4 706 | :102B20007B0892007A0891009517151515165530F7 707 | :102B30009600AA3096009514000000001512151199 708 | :102B40007B0892007A08910015152030F5001200DC 709 | :102B50009300940195161108073A07390319951245 710 | :102B600055309600AA309600951400000000910A96 711 | :102B7000F50BA72D15118801080023007A08920093 712 | :102B80007908910095171515151655309600AA303D 713 | :102B90009600951400000000151215117A08920095 714 | :102BA0007908910015152030F500760893009401FE 715 | :102BB00095161108073A07390319951255309600F2 716 | :102BC000AA309600951400000000910AF50BD52D4F 717 | :102BD000151188010800230095139101151413089D 718 | :102BE000F5000330910015141308F600910A15142E 719 | :102BF0001308F700910A15141308F900910A151427 720 | :102C00001308F8008801F03020260030202601301B 721 | :102C100020265D302026073020260030202675082B 722 | :102C2000202601308E1E03012026780820267608F3 723 | :102C300020267708202679082026F730202608004D 724 | :102C400000000000111E222E23009A0088010800B7 725 | :102C5000FF30F6003030FA00F901BD252030F907C9 726 | :102C60000318FA0AFA1D2D2EF5013D30FA00F9017C 727 | :102C7000BD252030F9070318FA0A7A1F382E2300E1 728 | :102C80009518402E9301033091009513151555307A 729 | :102C90009600AA3096009514230095184D2E910A9F 730 | :102CA0009513151555309600AA30960095142300FB 731 | :102CB0009518582E910A9513151555309600AA307F 732 | :0E2CC0009600951423009518632E88010800D5 733 | :022CCE00000004 734 | :102CD00000000000000000000000000000000000F4 735 | :102CE00000000000000000000000000000000000E4 736 | :102CF00000000000000000000000000000000000D4 737 | :102D000000000000000000000000000000000000C3 738 | :102D100000000000000000000000000000000000B3 739 | :102D200000000000000000000000000000000000A3 740 | :102D30000000000000000000000000000000000093 741 | :102D40000000000000000000000000000000000083 742 | :102D50000000000000000000000000000000000073 743 | :102D60000000000000000000000000000000000063 744 | :102D70000000000000000000000000000000000053 745 | :102D80000000000000000000000000000000000043 746 | :102D90000000000000000000000000000000000033 747 | :102DA0000000000000000000000000000000000023 748 | :102DB0000000000000000000000000000000000013 749 | :102DC0000000000000000000000000000000000003 750 | :102DD00000000000000000000000000000000000F3 751 | :102DE00000000000000000000000000000000000E3 752 | :102DF00000000000000000000000000000000000D3 753 | :102E000000000000000000000000000000000000C2 754 | :102E100000000000000000000000000000000000B2 755 | :102E200000000000000000000000000000000000A2 756 | :102E30000000000000000000000000000000000092 757 | :102E40000000000000000000000000000000000082 758 | :102E50000000000000000000000000000000000072 759 | :102E60000000000000000000000000000000000062 760 | :102E70000000000000000000000000000000000052 761 | :102E80000000000000000000000000000000000042 762 | :102E90000000000000000000000000000000000032 763 | :102EA0000000000000000000000000000000000022 764 | :102EB0000000000000000000000000000000000012 765 | :102EC0000000000000000000000000000000000002 766 | :102ED00000000000000000000000000000000000F2 767 | :102EE00000000000000000000000000000000000E2 768 | :102EF00000000000000000000000000000000000D2 769 | :102F000000000000000000000000000000000000C1 770 | :102F100000000000000000000000000000000000B1 771 | :102F200000000000000000000000000000000000A1 772 | :102F30000000000000000000000000000000000091 773 | :102F40000000000000000000000000000000000081 774 | :102F50000000000000000000000000000000000071 775 | :102F60000000000000000000000000000000000061 776 | :102F70000000000000000000000000000000000051 777 | :102F80000000000000000000000000000000000041 778 | :102F90000000000000000000000000000000000031 779 | :102FA0000000000000000000000000000000000021 780 | :102FB0000000000000000000000000000000000011 781 | :102FC0000000000000000000000000000000000001 782 | :102FD00000000000000000000000000000000000F1 783 | :102FE00000000000000000000000000000000000E1 784 | :102FF00000000000000000000000000000000000D1 785 | :1030000000380138023803380438053806380738E4 786 | :10301000083809380A380B380C380D380E380F3894 787 | :103020001038113812381338143815381638173844 788 | :10303000183819381A381B381C381D381E381F38F4 789 | :1030400020382138223823382438253826382738A4 790 | :10305000283829382A382B382C382D382E382F3854 791 | :103060003038313832383338343835383638373804 792 | :10307000383839383A383B383C383D383E383F38B4 793 | :103080004038413842384338443845384638473864 794 | :10309000483849384A384B384C384D384E384F3814 795 | :1030A00050385138523853385438553856385738C4 796 | :1030B000583859385A385B385C385D385E385F3874 797 | :1030C0006038613862386338643865386638673824 798 | :1030D000683869386A386B386C386D386E386F38D4 799 | :1030E0007038713872387338743875387638773884 800 | :1030F000783879387A387B387C387D387E387F3834 801 | :1031000080388138823883388438853886388738E3 802 | :10311000883889388A388B388C388D388E388F3893 803 | :103120009038913892389338943895389638973843 804 | :10313000983899389A389B389C389D389E389F38F3 805 | :10314000A038A138A238A338A438A538A638A738A3 806 | :10315000A838A938AA38AB38AC38AD38AE38AF3853 807 | :10316000B038B138B238B338B438B538B638B73803 808 | :10317000B838B938BA38BB38BC38BD38BE38BF38B3 809 | :10318000C038C138C238C338C438C538C638C73863 810 | :10319000C838C938CA38CB38CC38CD38CE38CF3813 811 | :1031A000D038D138D238D338D438D538D638D738C3 812 | :1031B000D838D938DA38DB38DC38DD38DE38DF3873 813 | :1031C000E038E138E238E338E438E538E638E73823 814 | :1031D000E838E938EA38EB38EC38ED38EE38EF38D3 815 | :1031E000F038F138F238F338F438F538F638F73883 816 | :1031F000F838F938FA38FB38FC38FD38FE38FF3833 817 | :1032000000390139023903390439053906390739DA 818 | :10321000083909390A390B390C390D390E390F398A 819 | :10322000103911391239133914391539163917393A 820 | :10323000183919391A391B391C391D391E391F39EA 821 | :10324000203921392239233924392539263927399A 822 | :10325000283929392A392B392C392D392E392F394A 823 | :1032600030393139323933393439353936393739FA 824 | :10327000383939393A393B393C393D393E393F39AA 825 | :10328000403941394239433944394539463947395A 826 | :10329000483949394A394B394C394D394E394F390A 827 | :1032A00050395139523953395439553956395739BA 828 | :1032B000583959395A395B395C395D395E395F396A 829 | :1032C000603961396239633964396539663967391A 830 | :1032D000683969396A396B396C396D396E396F39CA 831 | :1032E000703971397239733974397539763977397A 832 | :1032F000783979397A397B397C397D397E397F392A 833 | :1033000080398139823983398439853986398739D9 834 | :10331000883989398A398B398C398D398E398F3989 835 | :103320009039913992399339943995399639973939 836 | :10333000983999399A399B399C399D399E399F39E9 837 | :10334000A039A139A239A339A439A539A639A73999 838 | :10335000A839A939AA39AB39AC39AD39AE39AF3949 839 | :10336000B039B139B239B339B439B539B639B739F9 840 | :10337000B839B939BA39BB39BC39BD39BE39BF39A9 841 | :10338000C039C139C239C339C439C539C639C73959 842 | :10339000C839C939CA39CB39CC39CD39CE39CF3909 843 | :1033A000D039D139D239D339D439D539D639D739B9 844 | :1033B000D839D939DA39DB39DC39DD39DE39DF3969 845 | :1033C000E039E139E239E339E439E539E639E73919 846 | :1033D000E839E939EA39EB39EC39ED39EE39EF39C9 847 | :1033E000F039F139F239F339F439F539F639F73979 848 | :1033F000F839F939FA39FB39FC39FD39FE39FF3929 849 | :10340000003A013A023A033A043A053A063A073AD0 850 | :10341000083A093A0A3A0B3A0C3A0D3A0E3A0F3A80 851 | :10342000103A113A123A133A143A153A163A173A30 852 | :10343000183A193A1A3A1B3A1C3A1D3A1E3A1F3AE0 853 | :10344000203A213A223A233A243A253A263A273A90 854 | :10345000283A293A2A3A2B3A2C3A2D3A2E3A2F3A40 855 | :10346000303A313A323A333A343A353A363A373AF0 856 | :10347000383A393A3A3A3B3A3C3A3D3A3E3A3F3AA0 857 | :10348000403A413A423A433A443A453A463A473A50 858 | :10349000483A493A4A3A4B3A4C3A4D3A4E3A4F3A00 859 | :1034A000503A513A523A533A543A553A563A573AB0 860 | :1034B000583A593A5A3A5B3A5C3A5D3A5E3A5F3A60 861 | :1034C000603A613A623A633A643A653A663A673A10 862 | :1034D000683A693A6A3A6B3A6C3A6D3A6E3A6F3AC0 863 | :1034E000703A713A723A733A743A753A763A773A70 864 | :1034F000783A793A7A3A7B3A7C3A7D3A7E3A7F3A20 865 | :10350000803A813A823A833A843A853A863A873ACF 866 | :10351000883A893A8A3A8B3A8C3A8D3A8E3A8F3A7F 867 | :10352000903A913A923A933A943A953A963A973A2F 868 | :10353000983A993A9A3A9B3A9C3A9D3A9E3A9F3ADF 869 | :10354000A03AA13AA23AA33AA43AA53AA63AA73A8F 870 | :10355000A83AA93AAA3AAB3AAC3AAD3AAE3AAF3A3F 871 | :10356000B03AB13AB23AB33AB43AB53AB63AB73AEF 872 | :10357000B83AB93ABA3ABB3ABC3ABD3ABE3ABF3A9F 873 | :10358000C03AC13AC23AC33AC43AC53AC63AC73A4F 874 | :10359000C83AC93ACA3ACB3ACC3ACD3ACE3ACF3AFF 875 | :1035A000D03AD13AD23AD33AD43AD53AD63AD73AAF 876 | :1035B000D83AD93ADA3ADB3ADC3ADD3ADE3ADF3A5F 877 | :1035C000E03AE13AE23AE33AE43AE53AE63AE73A0F 878 | :1035D000E83AE93AEA3AEB3AEC3AED3AEE3AEF3ABF 879 | :1035E000F03AF13AF23AF33AF43AF53AF63AF73A6F 880 | :1035F000F83AF93AFA3AFB3AFC3AFD3AFE3AFF3A1F 881 | :10360000003B013B023B033B043B053B063B073BC6 882 | :10361000083B093B0A3B0B3B0C3B0D3B0E3B0F3B76 883 | :10362000103B113B123B133B143B153B163B173B26 884 | :10363000183B193B1A3B1B3B1C3B1D3B1E3B1F3BD6 885 | :10364000203B213B223B233B243B253B263B273B86 886 | :10365000283B293B2A3B2B3B2C3B2D3B2E3B2F3B36 887 | :10366000303B313B323B333B343B353B363B373BE6 888 | :10367000383B393B3A3B3B3B3C3B3D3B3E3B3F3B96 889 | :10368000403B413B423B433B443B453B463B473B46 890 | :10369000483B493B4A3B4B3B4C3B4D3B4E3B4F3BF6 891 | :1036A000503B513B523B533B543B553B563B573BA6 892 | :1036B000583B593B5A3B5B3B5C3B5D3B5E3B5F3B56 893 | :1036C000603B613B623B633B643B653B663B673B06 894 | :1036D000683B693B6A3B6B3B6C3B6D3B6E3B6F3BB6 895 | :1036E000703B713B723B733B743B753B763B773B66 896 | :1036F000783B793B7A3B7B3B7C3B7D3B7E3B7F3B16 897 | :10370000803B813B823B833B843B853B863B873BC5 898 | :10371000883B893B8A3B8B3B8C3B8D3B8E3B8F3B75 899 | :10372000903B913B923B933B943B953B963B973B25 900 | :10373000983B993B9A3B9B3B9C3B9D3B9E3B9F3BD5 901 | :10374000A03BA13BA23BA33BA43BA53BA63BA73B85 902 | :10375000A83BA93BAA3BAB3BAC3BAD3BAE3BAF3B35 903 | :10376000B03BB13BB23BB33BB43BB53BB63BB73BE5 904 | :10377000B83BB93BBA3BBB3BBC3BBD3BBE3BBF3B95 905 | :10378000C03BC13BC23BC33BC43BC53BC63BC73B45 906 | :10379000C83BC93BCA3BCB3BCC3BCD3BCE3BCF3BF5 907 | :1037A000D03BD13BD23BD33BD43BD53BD63BD73BA5 908 | :1037B000D83BD93BDA3BDB3BDC3BDD3BDE3BDF3B55 909 | :1037C000E03BE13BE23BE33BE43BE53BE63BE73B05 910 | :1037D000E83BE93BEA3BEB3BEC3BED3BEE3BEF3BB5 911 | :1037E000F03BF13BF23BF33BF43BF53BF63BF73B65 912 | :1037F000F83BF93BFA3BFB3BFC3BFD3BFE3BFF3B15 913 | :10380000003C013C023C033C043C053C063C073CBC 914 | :10381000083C093C0A3C0B3C0C3C0D3C0E3C0F3C6C 915 | :10382000103C113C123C133C143C153C163C173C1C 916 | :10383000183C193C1A3C1B3C1C3C1D3C1E3C1F3CCC 917 | :10384000203C213C223C233C243C253C263C273C7C 918 | :10385000283C293C2A3C2B3C2C3C2D3C2E3C2F3C2C 919 | :10386000303C313C323C333C343C353C363C373CDC 920 | :10387000383C393C3A3C3B3C3C3C3D3C3E3C3F3C8C 921 | :10388000403C413C423C433C443C453C463C473C3C 922 | :10389000483C493C4A3C4B3C4C3C4D3C4E3C4F3CEC 923 | :1038A000503C513C523C533C543C553C563C573C9C 924 | :1038B000583C593C5A3C5B3C5C3C5D3C5E3C5F3C4C 925 | :1038C000603C613C623C633C643C653C663C673CFC 926 | :1038D000683C693C6A3C6B3C6C3C6D3C6E3C6F3CAC 927 | :1038E000703C713C723C733C743C753C763C773C5C 928 | :1038F000783C793C7A3C7B3C7C3C7D3C7E3C7F3C0C 929 | :10390000803C813C823C833C843C853C863C873CBB 930 | :10391000883C893C8A3C8B3C8C3C8D3C8E3C8F3C6B 931 | :10392000903C913C923C933C943C953C963C973C1B 932 | :10393000983C993C9A3C9B3C9C3C9D3C9E3C9F3CCB 933 | :10394000A03CA13CA23CA33CA43CA53CA63CA73C7B 934 | :10395000A83CA93CAA3CAB3CAC3CAD3CAE3CAF3C2B 935 | :10396000B03CB13CB23CB33CB43CB53CB63CB73CDB 936 | :10397000B83CB93CBA3CBB3CBC3CBD3CBE3CBF3C8B 937 | :10398000C03CC13CC23CC33CC43CC53CC63CC73C3B 938 | :10399000C83CC93CCA3CCB3CCC3CCD3CCE3CCF3CEB 939 | :1039A000D03CD13CD23CD33CD43CD53CD63CD73C9B 940 | :1039B000D83CD93CDA3CDB3CDC3CDD3CDE3CDF3C4B 941 | :1039C000E03CE13CE23CE33CE43CE53CE63CE73CFB 942 | :1039D000E83CE93CEA3CEB3CEC3CED3CEE3CEF3CAB 943 | :1039E000F03CF13CF23CF33CF43CF53CF63CF73C5B 944 | :1039F000F83CF93CFA3CFB3CFC3CFD3CFE3CFF3C0B 945 | :103A0000003D013D023D033D043D053D063D073DB2 946 | :103A1000083D093D0A3D0B3D0C3D0D3D0E3D0F3D62 947 | :103A2000103D113D123D133D143D153D163D173D12 948 | :103A3000183D193D1A3D1B3D1C3D1D3D1E3D1F3DC2 949 | :103A4000203D213D223D233D243D253D263D273D72 950 | :103A5000283D293D2A3D2B3D2C3D2D3D2E3D2F3D22 951 | :103A6000303D313D323D333D343D353D363D373DD2 952 | :103A7000383D393D3A3D3B3D3C3D3D3D3E3D3F3D82 953 | :103A8000403D413D423D433D443D453D463D473D32 954 | :103A9000483D493D4A3D4B3D4C3D4D3D4E3D4F3DE2 955 | :103AA000503D513D523D533D543D553D563D573D92 956 | :103AB000583D593D5A3D5B3D5C3D5D3D5E3D5F3D42 957 | :103AC000603D613D623D633D643D653D663D673DF2 958 | :103AD000683D693D6A3D6B3D6C3D6D3D6E3D6F3DA2 959 | :103AE000703D713D723D733D743D753D763D773D52 960 | :103AF000783D793D7A3D7B3D7C3D7D3D7E3D7F3D02 961 | :103B0000803D813D823D833D843D853D863D873DB1 962 | :103B1000883D893D8A3D8B3D8C3D8D3D8E3D8F3D61 963 | :103B2000903D913D923D933D943D953D963D973D11 964 | :103B3000983D993D9A3D9B3D9C3D9D3D9E3D9F3DC1 965 | :103B4000A03DA13DA23DA33DA43DA53DA63DA73D71 966 | :103B5000A83DA93DAA3DAB3DAC3DAD3DAE3DAF3D21 967 | :103B6000B03DB13DB23DB33DB43DB53DB63DB73DD1 968 | :103B7000B83DB93DBA3DBB3DBC3DBD3DBE3DBF3D81 969 | :103B8000C03DC13DC23DC33DC43DC53DC63DC73D31 970 | :103B9000C83DC93DCA3DCB3DCC3DCD3DCE3DCF3DE1 971 | :103BA000D03DD13DD23DD33DD43DD53DD63DD73D91 972 | :103BB000D83DD93DDA3DDB3DDC3DDD3DDE3DDF3D41 973 | :103BC000E03DE13DE23DE33DE43DE53DE63DE73DF1 974 | :103BD000E83DE93DEA3DEB3DEC3DED3DEE3DEF3DA1 975 | :103BE000F03DF13DF23DF33DF43DF53DF63DF73D51 976 | :103BF000F83DF93DFA3DFB3DFC3DFD3DFE3DFF3D01 977 | :103C0000003E013E023E033E043E053E063E073EA8 978 | :103C1000083E093E0A3E0B3E0C3E0D3E0E3E0F3E58 979 | :103C2000103E113E123E133E143E153E163E173E08 980 | :103C3000183E193E1A3E1B3E1C3E1D3E1E3E1F3EB8 981 | :103C4000203E213E223E233E243E253E263E273E68 982 | :103C5000283E293E2A3E2B3E2C3E2D3E2E3E2F3E18 983 | :103C6000303E313E323E333E343E353E363E373EC8 984 | :103C7000383E393E3A3E3B3E3C3E3D3E3E3E3F3E78 985 | :103C8000403E413E423E433E443E453E463E473E28 986 | :103C9000483E493E4A3E4B3E4C3E4D3E4E3E4F3ED8 987 | :103CA000503E513E523E533E543E553E563E573E88 988 | :103CB000583E593E5A3E5B3E5C3E5D3E5E3E5F3E38 989 | :103CC000603E613E623E633E643E653E663E673EE8 990 | :103CD000683E693E6A3E6B3E6C3E6D3E6E3E6F3E98 991 | :103CE000703E713E723E733E743E753E763E773E48 992 | :103CF000783E793E7A3E7B3E7C3E7D3E7E3E7F3EF8 993 | :103D0000803E813E823E833E843E853E863E873EA7 994 | :103D1000883E893E8A3E8B3E8C3E8D3E8E3E8F3E57 995 | :103D2000903E913E923E933E943E953E963E973E07 996 | :103D3000983E993E9A3E9B3E9C3E9D3E9E3E9F3EB7 997 | :103D4000A03EA13EA23EA33EA43EA53EA63EA73E67 998 | :103D5000A83EA93EAA3EAB3EAC3EAD3EAE3EAF3E17 999 | :103D6000B03EB13EB23EB33EB43EB53EB63EB73EC7 1000 | :103D7000B83EB93EBA3EBB3EBC3EBD3EBE3EBF3E77 1001 | :103D8000C03EC13EC23EC33EC43EC53EC63EC73E27 1002 | :103D9000C83EC93ECA3ECB3ECC3ECD3ECE3ECF3ED7 1003 | :103DA000D03ED13ED23ED33ED43ED53ED63ED73E87 1004 | :103DB000D83ED93EDA3EDB3EDC3EDD3EDE3EDF3E37 1005 | :103DC000E03EE13EE23EE33EE43EE53EE63EE73EE7 1006 | :103DD000E83EE93EEA3EEB3EEC3EED3EEE3EEF3E97 1007 | :103DE000F03EF13EF23EF33EF43EF53EF63EF73E47 1008 | :103DF000F83EF93EFA3EFB3EFC3EFD3EFE3EFF3EF7 1009 | :103E0000003F013F023F033F043F053F063F073F9E 1010 | :103E1000083F093F0A3F0B3F0C3F0D3F0E3F0F3F4E 1011 | :103E2000103F113F123F133F143F153F163F173FFE 1012 | :103E3000183F193F1A3F1B3F1C3F1D3F1E3F1F3FAE 1013 | :103E4000203F213F223F233F243F253F263F273F5E 1014 | :103E5000283F293F2A3F2B3F2C3F2D3F2E3F2F3F0E 1015 | :103E6000303F313F323F333F343F353F363F373FBE 1016 | :103E7000383F393F3A3F3B3F3C3F3D3F3E3F3F3F6E 1017 | :103E8000403F413F423F433F443F453F463F473F1E 1018 | :103E9000483F493F4A3F4B3F4C3F4D3F4E3F4F3FCE 1019 | :103EA000503F513F523F533F543F553F563F573F7E 1020 | :103EB000583F593F5A3F5B3F5C3F5D3F5E3F5F3F2E 1021 | :103EC000603F613F623F633F643F653F663F673FDE 1022 | :103ED000683F693F6A3F6B3F6C3F6D3F6E3F6F3F8E 1023 | :103EE000703F713F723F733F743F753F763F773F3E 1024 | :103EF000783F793F7A3F7B3F7C3F7D3F7E3F7F3FEE 1025 | :103F0000803F813F823F833F843F853F863F873F9D 1026 | :103F1000883F893F8A3F8B3F8C3F8D3F8E3F8F3F4D 1027 | :103F2000903F913F923F933F943F953F963F973FFD 1028 | :103F3000983F993F9A3F9B3F9C3F9D3F9E3F9F3FAD 1029 | :103F4000A03FA13FA23FA33FA43FA53FA63FA73F5D 1030 | :103F5000A83FA93FAA3FAB3FAC3FAD3FAE3FAF3F0D 1031 | :103F6000B03FB13FB23FB33FB43FB53FB63FB73FBD 1032 | :103F7000B83FB93FBA3FBB3FBC3FBD3FBE3FBF3F6D 1033 | :103F8000C03FC13FC23FC33FC43FC53FC63FC73F1D 1034 | :103F9000C83FC93FCA3FCB3FCC3FCD3FCE3FCF3FCD 1035 | :103FA000D03FD13FD23FD33FD43FD53FD63FD73F7D 1036 | :103FB000D83FD93FDA3FDB3FDC3FDD3FDE3FDF3F2D 1037 | :103FC000E03FE13FE23FE33FE43FE53FE63FE73FDD 1038 | :103FD000E83FE93FEA3FEB3FEC3FED3FEE3FEF3F8D 1039 | :103FE000F03FF13FF23FF33FF43FF53FF63FF73F3D 1040 | :103FF000F83FF93FFA3FFB3FFC3FFD3FFE3FFF3FED 1041 | :10780000FF00FF00FF00FF00FF00FF00FF00FF0080 1042 | :10781000FF00FF00FF00FF00FF00FF00FF00FF0070 1043 | :10782000FF00FF00FF00FF00FF00FF00FF00FF0060 1044 | :10783000FF00FF00FF00FF00FF00FF00FF00FF0050 1045 | :10784000FF00FF00FF00FF00FF00FF00FF00FF0040 1046 | :10785000FF00FF00FF00FF00FF00FF00FF00FF0030 1047 | :10786000FF00FF00FF00FF00FF00FF00FF00FF0020 1048 | :10787000FF00FF00FF00FF00FF00FF00FF00FF0010 1049 | :10788000FF00FF00FF00FF00FF00FF00FF00FF0000 1050 | :10789000FF00FF00FF00FF00FF00FF00FF00FF00F0 1051 | :1078A000FF00FF00FF00FF00FF00FF00FF00FF00E0 1052 | :1078B000FF00FF00FF00FF00FF00FF00FF00FF00D0 1053 | :1078C000FF00FF00FF00FF00FF00FF00FF00FF00C0 1054 | :1078D000FF00FF00FF00FF00FF00FF00FF00FF00B0 1055 | :1078E000FF00FF00FF00FF00FF00FF00FF00FF00A0 1056 | :1078F000FF00FF00FF00FF00FF00FF00FF00FF0090 1057 | :10790000FF00FF00FF00FF00FF00FF00FF00FF007F 1058 | :10791000FF00FF00FF00FF00FF00FF00FF00FF006F 1059 | :10792000FF00FF00FF00FF00FF00FF00FF00FF005F 1060 | :10793000FF00FF00FF00FF00FF00FF00FF00FF004F 1061 | :10794000FF00FF00FF00FF00FF00FF00FF00FF003F 1062 | :10795000FF00FF00FF00FF00FF00FF00FF00FF002F 1063 | :10796000FF00FF00FF00FF00FF00FF00FF00FF001F 1064 | :10797000FF00FF00FF00FF00FF00FF00FF00FF000F 1065 | :10798000FF00FF00FF00FF00FF00FF00FF00FF00FF 1066 | :10799000FF00FF00FF00FF00FF00FF00FF00FF00EF 1067 | :1079A000FF00FF00FF00FF00FF00FF00FF00FF00DF 1068 | :1079B000FF00FF00FF00FF00FF00FF00FF00FF00CF 1069 | :1079C000FF00FF00FF00FF00FF00FF00FF00FF00BF 1070 | :1079D000FF00FF00FF00FF00FF00FF00FF00FF00AF 1071 | :1079E000FF00FF00FF00FF00FF00FF00FF00FF009F 1072 | :1079F000FF00FF00FF00FF00FF00FF00FF00FF008F 1073 | :107A00000000000000000000000000000000000076 1074 | :107A10000000000000000000000000000000000066 1075 | :107A20000000000000000000000000000000000056 1076 | :107A30000000000000000000000000000000000046 1077 | :107A40000000000000000000000000000000000036 1078 | :107A50000000000000000000000000000000000026 1079 | :107A60000000000000000000000000000000000016 1080 | :107A70000000000000000000000000000000000006 1081 | :107A800000000000000000000000000000000000F6 1082 | :107A900000000000000000000000000000000000E6 1083 | :107AA00000000000000000000000000000000000D6 1084 | :107AB00000000000000000000000000000000000C6 1085 | :107AC00000000000000000000000000000000000B6 1086 | :107AD00000000000000000000000000000000000A6 1087 | :107AE0000000000000000000000000000000000096 1088 | :107AF0000000000000000000000000000000000086 1089 | :107C00002200220022002200220022002200220064 1090 | :107C10002200220022002200220022002200220054 1091 | :107C20002200220022002200220022002200220044 1092 | :107C30002200220022002200220022002200220034 1093 | :107C40002200220022002200220022002200220024 1094 | :107C50002200220022002200220022002200220014 1095 | :107C60002200220022002200220022002200220004 1096 | :107C700022002200220022002200220022002200F4 1097 | :107C800022002200220022002200220022002200E4 1098 | :107C900022002200220022002200220022002200D4 1099 | :107CA00022002200220022002200220022002200C4 1100 | :107CB00022002200220022002200220022002200B4 1101 | :107CC00022002200220022002200220022002200A4 1102 | :107CD0002200220022002200220022002200220094 1103 | :107CE0002200220022002200220022002200220084 1104 | :107CF0002200220022002200220022002200220074 1105 | :107E00000000000000000000000000000000000072 1106 | :107E10000000000000000000000000000000000062 1107 | :107E20000000000000000000000000000000000052 1108 | :107E30000000000000000000000000000000000042 1109 | :107E40000000000000000000000000000000000032 1110 | :107E50000000000000000000000000000000000022 1111 | :107E60000000000000000000000000000000000012 1112 | :107E70000000000000000000000000000000000002 1113 | :107E800000000000000000000000000000000000F2 1114 | :107E900000000000000000000000000000000000E2 1115 | :107EA00000000000000000000000000000000000D2 1116 | :107EB00000000000000000000000000000000000C2 1117 | :107EC00000000000000000000000000000000000B2 1118 | :107ED00000000000000000000000000000000000A2 1119 | :107EE0000000000000000000000000000000000092 1120 | :107EF0000000000000000000000000000000000082 1121 | :020000040001F9 1122 | :02000E00443E6E 1123 | :02001000EF1FE0 1124 | :10E000000000310087000000000000000000000058 1125 | :10E010000000000000000000000000000000000000 1126 | :10E0200000000000000000000000000000000000F0 1127 | :10E0300000000000000000000000000000000000E0 1128 | :10E0400000000000000000000000000000000000D0 1129 | :10E0500000000000000000000000000000000000C0 1130 | :10E0600000000000000000000000000000000000B0 1131 | :10E0700000000000000000000000000000000000A0 1132 | :10E080000000000000000000000000000000000090 1133 | :10E090000000000000000000000000000000000080 1134 | :10E0A0000000000000000000000000000000000070 1135 | :10E0B0000000000000000000000000000000000060 1136 | :10E0C0000000000000000000000000000000000050 1137 | :10E0D0000000000000000000000000000000000040 1138 | :10E0E0000000000000000000000000000000000030 1139 | :10E0F0000000000000000000000000000000000020 1140 | :10E10000000000000000000000000000000000000F 1141 | :10E1100000000000000000000000000000000000FF 1142 | :10E1200000000000000000000000000000000000EF 1143 | :10E1300000000000000000000000000000000000DF 1144 | :10E1400000000000000000000000000000000000CF 1145 | :10E1500000000000000000000000000000000000BF 1146 | :10E1600000000000000000000000000000000000AF 1147 | :10E17000000000000000000000000000000000009F 1148 | :10E18000000000000000000000000000000000008F 1149 | :10E19000000000000000000000000000000000007F 1150 | :10E1A000000000000000000000000000000000006F 1151 | :10E1B000000000000000000000000000000000005F 1152 | :10E1C000000000000000000000000000000000004F 1153 | :10E1D000000000000000000000000000000000003F 1154 | :10E1E000000000000000000000000000000000002F 1155 | :0EE1F000000000000000000000000000000021 1156 | :00000001FF 1157 | --------------------------------------------------------------------------------