2 #include <avr/interrupt.h>
3 #include <util/delay.h>
5 #include <avr/pgmspace.h>
7 #include "bus_access.h"
8 #include "disk_access.h"
9 #include "flashmemory.h"
10 #include "mcu_program.h"
11 #include "kazzo_request.h"
13 //---- global variable ----
14 #define REQUEST_NOP (0xee)
15 static struct write_command{
17 uint16_t address, length, offset;
18 }request_both_write, request_cpu_program, request_ppu_program;
20 //---- function start ----
21 static void flash_config_set(const uint8_t *t, void (*set)(uint16_t, uint16_t, uint16_t, uint16_t))
23 uint16_t c000x, c2aaa, c5555, unit;
32 (*set)(c000x, c2aaa, c5555, unit);
34 /*static uint8_t cpu_buffer[FLASH_PACKET_SIZE];
35 static uint8_t ppu_buffer[FLASH_PACKET_SIZE];*/
36 uchar usbFunctionWrite(uchar *data, uchar len)
38 static uint8_t cpu_buffer[FLASH_PACKET_SIZE];
39 static uint8_t ppu_buffer[FLASH_PACKET_SIZE];
40 const uint16_t length = (uint16_t) len;
43 for(i = 0; i < len; i++){
46 switch(request_both_write.request){
47 case REQUEST_CPU_WRITE_6502:
48 cpu_write_6502(request_both_write.address + request_both_write.offset, length, data);
50 case REQUEST_CPU_WRITE_FLASH:
51 cpu_write_flash(request_both_write.address + request_both_write.offset, length, data);
53 case REQUEST_PPU_WRITE:
54 ppu_write(request_both_write.address + request_both_write.offset, length, data);
57 request_both_write.offset += length;
58 int ret = request_both_write.offset == request_both_write.length;
60 request_both_write.request = REQUEST_NOP;
67 switch(request_cpu_program.request){
68 case REQUEST_FLASH_PROGRAM:
69 case REQUEST_FLASH_CONFIG_SET:{
70 static uint8_t *w = cpu_buffer; //this is static pointer! be careful.
71 if(request_cpu_program.offset == 0){
74 memcpy(w, data, length);
76 request_cpu_program.offset += length;
77 int ret = request_cpu_program.offset == request_cpu_program.length;
79 if(request_cpu_program.request == REQUEST_FLASH_CONFIG_SET){
80 flash_config_set(cpu_buffer, flash_cpu_config);
82 flash_cpu_program(request_cpu_program.address, request_cpu_program.length, cpu_buffer);
84 request_cpu_program.request = REQUEST_NOP;
90 switch(request_ppu_program.request){
91 case REQUEST_FLASH_PROGRAM:
92 case REQUEST_FLASH_CONFIG_SET:{
93 static uint8_t *w = ppu_buffer; //static pointer
94 if(request_ppu_program.offset == 0){
97 memcpy(w, data, length);
99 request_ppu_program.offset += length;
100 int ret = request_ppu_program.offset == request_ppu_program.length;
102 if(request_ppu_program.request == REQUEST_FLASH_CONFIG_SET){
103 flash_config_set(ppu_buffer, flash_ppu_config);
105 flash_ppu_program(request_ppu_program.address, request_ppu_program.length, ppu_buffer);
107 request_ppu_program.request = REQUEST_NOP;
116 //static uint8_t readbuffer[READ_PACKET_SIZE];
117 usbMsgLen_t usbFunctionSetup(uchar d[8])
119 static uint8_t readbuffer[READ_PACKET_SIZE];
120 static uint8_t status[2];
121 usbRequest_t *rq = (void *)d;
122 struct write_command *write_command;
124 switch((enum request) rq->bRequest){
126 readbuffer[0] = rq->wValue.bytes[0];
127 readbuffer[1] = rq->wValue.bytes[1];
128 readbuffer[2] = rq->wIndex.bytes[0];
129 readbuffer[3] = rq->wIndex.bytes[1];
130 usbMsgPtr = readbuffer;
132 case REQUEST_PHI2_INIT:
136 case REQUEST_CPU_READ:
137 cpu_read(rq->wValue.word, rq->wLength.word, readbuffer);
139 case REQUEST_CPU_READ_6502:
140 cpu_read_6502(rq->wValue.word, rq->wLength.word, readbuffer);
142 case REQUEST_PPU_READ:
143 ppu_read(rq->wValue.word, rq->wLength.word, readbuffer);
145 case REQUEST_CPU_WRITE_6502: case REQUEST_CPU_WRITE_FLASH:
146 case REQUEST_PPU_WRITE:
147 write_command = &request_both_write;
149 case REQUEST_FLASH_PROGRAM:
150 case REQUEST_FLASH_CONFIG_SET:
151 if(rq->wIndex.word == INDEX_CPU){
152 write_command = &request_cpu_program;
154 write_command = &request_ppu_program;
158 write_command->request = rq->bRequest;
159 write_command->length = rq->wLength.word;
160 write_command->address = rq->wValue.word;
161 write_command->offset = 0;
162 return USB_NO_MSG; //goto usbFunctionWrite
163 /* case REQUEST_FLASH_BUFFER_GET:
164 if(rq->wIndex.word == INDEX_CPU){
165 usbMsgPtr = cpu_buffer;
167 usbMsgPtr = ppu_buffer;
169 return FLASH_PACKET_SIZE;*/
170 case REQUEST_DISK_STATUS_GET:
171 //usbMsgPtr = status;
172 return 0; //disk_status_get(status);
173 case REQUEST_DISK_READ:
174 disk_init(DISK_READ);
176 case REQUEST_DISK_WRITE:
177 disk_init(DISK_WRITE);
179 case REQUEST_FLASH_STATUS:
181 switch((enum index) rq->wIndex.word){
183 status[0] = flash_cpu_status();
186 status[0] = flash_ppu_status();
189 status[0] = flash_cpu_status();
190 status[1] = flash_ppu_status();
194 case REQUEST_FLASH_DEVICE:
195 if(rq->wIndex.word == INDEX_CPU){
196 flash_cpu_device_get(status);
198 flash_ppu_device_get(status);
202 case REQUEST_FLASH_ERASE:
203 if(rq->wIndex.word == INDEX_CPU){
204 flash_cpu_erase(rq->wValue.word);
206 flash_ppu_erase(rq->wValue.word);
209 case REQUEST_VRAM_CONNECTION:
210 status[0] = vram_connection_get();
213 case REQUEST_FIRMWARE_VERSION:{
214 __attribute__ ((section(".firmware.version")))
215 static const /*PROGMEM*/ char date[VERSION_STRING_SIZE] = "kazzo16 0.1.1 " __DATE__;
216 memcpy_P(readbuffer, date, rq->wLength.word);
218 case REQUEST_FIRMWARE_PROGRAM:{
219 void (*t)(uint8_t *buf, uint16_t address, uint16_t length);
220 usbDeviceDisconnect();
221 memcpy_P(&t, &BOOTLOADER_ASSIGN.programmer, sizeof(BOOTLOADER_ASSIGN.programmer));
222 (*t)(readbuffer, rq->wValue.word, rq->wIndex.word);
224 case REQUEST_FIRMWARE_DOWNLOAD:{
225 const /*PROGMEM*/ uint8_t *firm = (const /*PROGMEM*/ uint8_t *) rq->wValue.word;
226 memcpy_P(readbuffer, firm, rq->wLength.word);
230 usbMsgPtr = readbuffer;
231 return rq->wLength.word;
238 static const struct write_command wc_init = {
239 .request = REQUEST_NOP, .length = 0, .offset = 0
241 request_both_write = wc_init;
242 request_cpu_program = wc_init;
243 request_ppu_program = wc_init;
247 usbDeviceDisconnect();
257 wdt_enable(WDTO_500MS);