+MCU_164P = MCU=atmega164p TARGET=kazzo_mega164p
+MCU_16 = MCU=atmega16 TARGET=kazzo_mega16
+
all:
- make -f firmware.mak MCU=atmega164p TARGET=kazzo_mega164p
- make -f firmware.mak MCU=atmega16 TARGET=kazzo_mega16
+ (cd firmware;make -f firmware.mak $(MCU_164P))
+ (cd firmware;make -f firmware.mak $(MCU_16))
+ (cd hostecho;make)
clean:
- make -f firmware.mak MCU=atmega164p TARGET=kazzo_mega164p clean
- make -f firmware.mak MCU=atmega16 TARGET=kazzo_mega16 clean
-
+ (cd firmware;make -f firmware.mak $(MCU_164P) clean)
+ (cd firmware;make -f firmware.mak $(MCU_16) clean)
+ (cd hostecho;make clean)
p4p:
- make -f firmware.mak MCU=atmega164p TARGET=kazzo_mega164p program
+ (cd firmware;make -f firmware.mak $(MCU_164P) program)
+++ /dev/null
-#include <avr/wdt.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "usbdrv.h"
-#include "bus_access.h"
-#include "disk_access.h"
-#include "flashmemory.h"
-#include "kazzo_request.h"
-
-//---- global variable ----
-static struct write_command{
- enum request request;
- uint16_t address, length, offset;
-}write_command;
-
-//---- function start ----
-uchar usbFunctionWrite(uchar *data, uchar len)
-{
- static uint8_t cpu_buffer[FLASH_PACKET_SIZE];
- static uint8_t ppu_buffer[FLASH_PACKET_SIZE];
- const uint16_t length = (uint16_t) len;
-
- switch(write_command.request){
- case REQUEST_CPU_WRITE_6502:
- cpu_write_6502(write_command.address + write_command.offset, length, data);
- break;
- case REQUEST_CPU_WRITE_FLASH:
- cpu_write_flash(write_command.address + write_command.offset, length, data);
- break;
- case REQUEST_PPU_WRITE:
- ppu_write(write_command.address + write_command.offset, length, data);
- break;
- case REQUEST_CPU_FLASH_PROGRAM:
- case REQUEST_PPU_FLASH_PROGRAM:{
- static uint8_t *w = cpu_buffer; //this is static pointer! be careful.
- if(write_command.offset == 0){
- if(write_command.request == REQUEST_CPU_FLASH_PROGRAM){
- w = cpu_buffer;
- }else{
- w = ppu_buffer;
- }
- }
- while(len != 0){
- *w = *data;
- w++;
- data++;
- write_command.offset += 1;
- len--;
- }
- if(write_command.length == write_command.offset){
- if(write_command.request == REQUEST_CPU_FLASH_PROGRAM){
- flash_cpu_program(write_command.address, write_command.length, cpu_buffer);
- }else{
- flash_ppu_program(write_command.address, write_command.length, ppu_buffer);
- }
- }
- }return write_command.length == write_command.offset;
- case REQUEST_CPU_FLASH_CONFIG_SET:
- case REQUEST_PPU_FLASH_CONFIG_SET:{
- static uint16_t c000x, c2aaa, c5555, unit;
- while(len != 0){
- switch(write_command.offset){
- case 0:
- c000x = *data;
- break;
- case 1:
- c000x |= *data;
- break;
- case 2:
- c2aaa = *data;
- break;
- case 3:
- c2aaa |= *data << 8;
- break;
- case 4:
- c5555 = *data;
- break;
- case 5:
- c5555 |= *data << 8;
- break;
- case 6:
- unit = *data;
- break;
- case 7:
- unit |= *data << 8;
- break;
- }
- data += 1;
- write_command.offset += 1;
- len--;
- }
- if(write_command.offset >= 8){
- if(write_command.request == REQUEST_CPU_FLASH_CONFIG_SET){
- flash_cpu_config(c000x, c2aaa, c5555, unit);
- }else{
- flash_ppu_config(c000x, c2aaa, c5555, unit);
- }
- }
- }return write_command.length == write_command.offset;
- default:
- return 1;
- }
- write_command.offset += length;
- return write_command.length == write_command.offset;
-}
-
-usbMsgLen_t usbFunctionSetup(uchar d[8])
-{
- static uint8_t readbuffer[READ_PACKET_SIZE];
- static uint8_t status[2];
- usbRequest_t *rq = (void *)d;
- uint8_t *data = readbuffer;
-
- switch((enum request) rq->bRequest){
- case REQUEST_ECHO:
- data[0] = rq->wValue.bytes[0];
- data[1] = rq->wValue.bytes[1];
- data[2] = rq->wIndex.bytes[0];
- data[3] = rq->wIndex.bytes[1];
- usbMsgPtr = data;
- return 4;
- case REQUEST_PHI2_INIT:
- flash_both_idle();
- phi2_init();
- return 0;
- case REQUEST_CPU_READ:
- cpu_read(rq->wValue.word, rq->wLength.word, data);
- goto xxx_read;
- case REQUEST_CPU_READ_6502:
- cpu_read_6502(rq->wValue.word, rq->wLength.word, data);
- goto xxx_read;
- case REQUEST_PPU_READ:
- ppu_read(rq->wValue.word, rq->wLength.word, data);
- goto xxx_read;
- xxx_read:
- usbMsgPtr = data;
- return rq->wLength.word;
- case REQUEST_CPU_WRITE_6502: case REQUEST_CPU_WRITE_FLASH:
- case REQUEST_PPU_WRITE:
- case REQUEST_CPU_FLASH_PROGRAM:
- case REQUEST_CPU_FLASH_CONFIG_SET:
- case REQUEST_PPU_FLASH_PROGRAM:
- case REQUEST_PPU_FLASH_CONFIG_SET:
- write_command.request = rq->bRequest;
- write_command.length = rq->wLength.word;
- write_command.address = rq->wValue.word;
- write_command.offset = 0;
- return USB_NO_MSG; //goto usbFunctionWrite
- case REQUEST_DISK_STATUS_GET:
- usbMsgPtr = status;
- return disk_status_get(status);
- case REQUEST_DISK_READ:
- disk_init(DISK_READ);
- return 0;
- case REQUEST_DISK_WRITE:
- disk_init(DISK_WRITE);
- return 0;
- case REQUEST_BOTH_FLASH_STATUS:
- status[0] = flash_cpu_status();
- status[1] = flash_ppu_status();
- usbMsgPtr = status;
- return 2;
- case REQUEST_CPU_FLASH_STATUS:
- status[0] = flash_cpu_status();
- usbMsgPtr = status;
- return 1;
- case REQUEST_PPU_FLASH_STATUS:
- status[0] = flash_ppu_status();
- usbMsgPtr = status;
- return 1;
- case REQUEST_CPU_FLASH_DEVICE:
- flash_cpu_device_get(status);
- return 2;
- case REQUEST_PPU_FLASH_DEVICE:
- flash_ppu_device_get(status);
- return 2;
- case REQUEST_CPU_FLASH_ERASE:
- flash_cpu_erase(rq->wValue.word);
- return 0;
- case REQUEST_PPU_FLASH_ERASE:
- flash_ppu_erase(rq->wValue.word);
- return 0;
- case REQUEST_VRAM_CONNECTION:
- status[0] = vram_connection_get();
- usbMsgPtr = status;
- return 1;
- }
- return 0;
-}
-
-int main(void)
-{
- uchar i;
-
- bus_init();
- usbInit();
- usbDeviceDisconnect();
- i = 0;
- while(--i){
- wdt_reset();
- _delay_ms(1);
- }
- usbDeviceConnect();
- sei();
- for(;;){
- wdt_reset();
- usbPoll();
- //disk_process();
- flash_process();
- }
- return 0;
-}
+++ /dev/null
-#include <util/delay.h>
-#include <avr/io.h>
-#include "type.h"
-#include "bus_access.h"
-
-//avr/io.h use many macros, I want use IO access by inline function...
-#define IO_DIRECTION(NAME) (DDR##NAME)
-#define IO_OUT(NAME) (PORT##NAME)
-#define IO_IN(NAME) (PIN##NAME)
-/* PAx: output only
-connected CPU and PPU databus*/
-#define ADDRESSBUS_A0_A7_DIR IO_DIRECTION(A)
-#define ADDRESSBUS_A0_A7_OUT IO_OUT(A)
-/* PBx: output/input
-connected address high latch(HC574), CPU and PPU databus*/
-#define DATABUS_DIR IO_DIRECTION(B)
-#define DATABUS_OUT IO_OUT(B)
-#define DATABUS_IN IO_IN(B)
-enum databus_dir{
- DATABUS_DIR_OUT = 0xff,
- DATABUS_DIR_IN = 0
-};
-/*PCx: output ADDRESS_HIGH_LATCH connect HC574 clock pin, bus control signal*/
-#define BUS_CONTROL_DIR IO_DIRECTION(C)
-#define BUS_CONTROL_OUT IO_OUT(C)
-enum iobit_bus_control{
- CPU_PHI2 = 0, CPU_ROMCS, CPU_RW,
- RESERVE_PPU_POS_A13, PPU_RD, PPU_WR,
- VRAM_CS, ADDRESS_HIGH_LATCH
-};
-//when cpu_write_flash, phi2 must be low. when phi2 is high, mmc3 and vrc4 changes bank.
-enum {
- BUS_CLOSE = 0xff
-};
-/*PDx: use input, empty pin is output*/
-#define USB_MISC_DIR IO_DIRECTION(D)
-#define USB_MISC_PULLUP IO_OUT(D)
-#define USB_MISC_IN IO_IN(D)
-enum iobit_usb_misc{
- USB_DPLUS = 2, CPU_IRQ,
- USB_DMINUS, VRAM_A10
-};
-void bus_init(void)
-{
- ADDRESSBUS_A0_A7_DIR = 0xff;
- ADDRESSBUS_A0_A7_OUT = 0;
- DATABUS_DIR = DATABUS_DIR_OUT;
- BUS_CONTROL_DIR = 0xff;
- BUS_CONTROL_OUT = BUS_CLOSE;
- USB_MISC_DIR = (0b1100 << 4) | 0b0011; //empty pin use OUT
- USB_MISC_PULLUP = (1 << CPU_IRQ) | (1 << VRAM_A10);
-}
-
-/*
-make phi2 edge signal, this is needed by namcot mapper and RP2C33.
-*/
-void phi2_init(void)
-{
- int i = 0x80;
- while(i != 0){
- BUS_CONTROL_OUT = BUS_CLOSE;
- BUS_CONTROL_OUT = BUS_CLOSE ^ (1 << CPU_PHI2);
- i--;
- }
-}
-
-static inline uint8_t bit_get_negative(enum iobit_bus_control bit)
-{
- uint8_t ret = (1 << bit);
- return ~ret;
-}
-
-//for RAM adapter DRAM refresh
-void phi2_update(void)
-{
- static uint8_t i = 0;
- uint8_t c = BUS_CLOSE;
- if(i & 0b100){
- c ^= 1 << CPU_PHI2;
- }
- BUS_CONTROL_OUT = c;
- i += 1;
-}
-/*
-address high databus assignment
-D0-D5: CPU and PPU A8-A13
-D6: CPU A14
-D7: PPU /A13
-*/
-static void address_set(uint16_t address)
-{
- ADDRESSBUS_A0_A7_OUT = address & 0xff;
- uint8_t high = (address & 0x7fff) >> 8; //mask A0-A14
- if((address & (1 << 13)) == 0){ //if A13 == 0
- high |= 0x80; //set /A13
- }
- DATABUS_OUT = high;
- BUS_CONTROL_OUT = bit_get_negative(ADDRESS_HIGH_LATCH);
- BUS_CONTROL_OUT = BUS_CLOSE;
-}
-static inline void direction_write(void)
-{
- DATABUS_DIR = DATABUS_DIR_OUT;
- asm("nop");
- asm("nop");
- asm("nop");
-}
-
-static inline void direction_read(void)
-{
- DATABUS_OUT = 0xff; //when input direction, pullup
- DATABUS_DIR = DATABUS_DIR_IN;
- asm("nop"); //wait for chaging port direction. do not remove.
- asm("nop");
- asm("nop");
-}
-//mmc5 ROM area need that phi2 is high
-void cpu_read(uint16_t address, uint16_t length, uint8_t *data)
-{
- BUS_CONTROL_OUT = BUS_CLOSE;
- while(length != 0){
-// uint8_t c = BUS_CLOSE;
- direction_write();
- address_set(address);
- if((address & 0x8000) != 0){
-// c &= bit_get_negative(CPU_ROMCS) | (1 << CPU_ROMCS);
-// BUS_CONTROL_OUT = c;
- BUS_CONTROL_OUT = bit_get_negative(CPU_ROMCS);
- }
- direction_read();
- *data = DATABUS_IN;
- data += 1;
- BUS_CONTROL_OUT = BUS_CLOSE;
- address += 1;
- length--;
- }
- direction_write();
-}
-
-void cpu_read_6502(uint16_t address, uint16_t length, uint8_t *data)
-{
- while(length != 0){
- //phi2 down
- uint8_t c = bit_get_negative(CPU_PHI2);
- BUS_CONTROL_OUT = c;
-
- //down -> up
- direction_write();
- address_set(address);
- if((address & 0x8000) != 0){
- c &= bit_get_negative(CPU_ROMCS);
- }
- BUS_CONTROL_OUT = c;
- clock_wait(1);
-
- //phi2 up
- c |= (1 << CPU_PHI2); // | (1 << CPU_ROMCS);
- BUS_CONTROL_OUT = c;
- if(1){
- direction_read();
- *data = DATABUS_IN;
- data += 1;
- }
- clock_wait(1);
- if(0){
- BUS_CONTROL_OUT = c;
- direction_read();
- *data = DATABUS_IN;
- data += 1;
- }
- BUS_CONTROL_OUT = c;
-
- //phi2 down
- if((address & 0x8000) != 0){
- c &= bit_get_negative(CPU_ROMCS);
- }
- c &= bit_get_negative(CPU_PHI2);
- if(0){
- BUS_CONTROL_OUT = c;
- direction_read();
- *data = DATABUS_IN;
- data += 1;
- }
- clock_wait(1);
-
- //bus close
- BUS_CONTROL_OUT = BUS_CLOSE;
-
- address += 1;
- length--;
- }
- direction_write();
-}
-
-void ppu_read(uint16_t address, uint16_t length, uint8_t *data)
-{
- //BUS_CONTROL_OUT = BUS_CLOSE;
- while(length != 0){
- direction_write();
- address_set(address);
- BUS_CONTROL_OUT = bit_get_negative(PPU_RD);
- direction_read();
- *data = DATABUS_IN;
- data += 1;
- BUS_CONTROL_OUT = BUS_CLOSE;
- address += 1;
- length--;
- }
- direction_write();
-}
-
-enum compare_status cpu_compare(uint16_t address, uint16_t length, const uint8_t *data)
-{
- return OK;
-}
-enum compare_status ppu_compare(uint16_t address, uint16_t length, const uint8_t *data)
-{
- while(length != 0){
- direction_write();
- address_set(address);
- BUS_CONTROL_OUT = bit_get_negative(PPU_RD);
- direction_read();
- if(DATABUS_IN != *data){
- BUS_CONTROL_OUT = BUS_CLOSE;
- direction_write();
- return NG;
- }
- data += 1;
- BUS_CONTROL_OUT = BUS_CLOSE;
- address += 1;
- length--;
- }
- direction_write();
- return OK;
-}
-
-void cpu_write_6502_nowait(uint16_t address, uint16_t length, const uint8_t *data)
-{
- while(length != 0){
- uint8_t control;
- address_set(address);
-
- //phi2 down
- control = bit_get_negative(CPU_PHI2);
- BUS_CONTROL_OUT = control;
- control &= bit_get_negative(CPU_RW);
- if((address & 0x8000) != 0){
- control &= bit_get_negative(CPU_ROMCS);
- }
- BUS_CONTROL_OUT = control;
-
- //phi2 up
- control |= (1 << CPU_PHI2) | (1 << CPU_ROMCS);
- BUS_CONTROL_OUT = control;
- DATABUS_OUT = *data;
- data++;
-
- //phi2 down
- control &= bit_get_negative(CPU_PHI2);
- if((address & 0x8000) != 0){
- control &= bit_get_negative(CPU_ROMCS);
- }
- BUS_CONTROL_OUT = control;
-
- //bus close
- BUS_CONTROL_OUT = BUS_CLOSE;
-
- address += 1;
- length--;
- }
-}
-
-/*
-/WE controlled write operation has busconflict
-PHI2 |-__________-
-R/W |----___-----
-/ROMCS|--_______---
-A0-A14|-<vaild address>-
-D0-D7 |--oo<i>**---
-o is dataout, i is datain, * is bus-confilict
-
-/CS controlled write operation is clean write cycle for flash memory
-PHI2 |-__________-
-R/W |--_______---
-/ROMCS|----___-----
-A0-A14|-<vaild address>-
-D0-D7 |----<iii>---
-*/
-static inline void cpu_write_flash_waveform(uint16_t address, uint8_t data)
-{
- uint8_t control = bit_get_negative(CPU_PHI2);
- address_set(address);
- if(0){ //R/W = /WE controlled write operation
- if((address & 0x8000) != 0){
- control &= bit_get_negative(CPU_ROMCS);
- BUS_CONTROL_OUT = control;
- }
- control &= bit_get_negative(CPU_RW);
- BUS_CONTROL_OUT = control;
- DATABUS_OUT = data;
- control |= 1 << CPU_RW; //R/W close
- BUS_CONTROL_OUT = control;
- }else{ ///ROMCS = /CS controlled write operation
- control &= bit_get_negative(CPU_RW);
- BUS_CONTROL_OUT = control;
- if((address & 0x8000) != 0){
- control &= bit_get_negative(CPU_ROMCS);
- BUS_CONTROL_OUT = control;
- }
- DATABUS_OUT = data;
- control |= 1 << CPU_ROMCS;
- BUS_CONTROL_OUT = control;
- }
- BUS_CONTROL_OUT = BUS_CLOSE;
-}
-void cpu_write_flash(uint16_t address, uint16_t length, const uint8_t *data)
-{
- direction_write();
- while(length != 0){
- cpu_write_flash_waveform(address, *data);
- data++;
- address += 1;
- length--;
- }
-}
-
-void cpu_write_flash_order(const struct flash_order *t)
-{
- int length = FLASH_PROGRAM_ORDER;
- direction_write();
- while(length != 0){
- cpu_write_flash_waveform(t->address, t->data);
- t++;
- length--;
- }
-}
-/*
-NTSC hardware timing
-Master clock fsc: 21.4772272 MHz
-CPU clock fsc/12: 1.789773MHz
-clock per second 12/fsc: 5.58*10**-7 sec, 0.55 us
-*/
-void cpu_write_6502(uint16_t address, uint16_t length, const uint8_t *data)
-{
- while(length != 0){
- uint8_t control;
- address_set(address);
-
- //phi2 down
- control = bit_get_negative(CPU_PHI2);
- BUS_CONTROL_OUT = control;
- control &= bit_get_negative(CPU_RW);
- if((address & 0x8000) != 0){
- control &= bit_get_negative(CPU_ROMCS);
- }
- BUS_CONTROL_OUT = control;
- clock_wait(1);
-
- //phi2 up
- control |= (1 << CPU_PHI2); //| (1 << CPU_ROMCS);
- DATABUS_OUT = *data;
- BUS_CONTROL_OUT = control;
-// DATABUS_OUT = *data;
- data++;
- clock_wait(1);
-
- //phi2 down
- control &= bit_get_negative(CPU_PHI2);
- BUS_CONTROL_OUT = control;
- if((address & 0x8000) != 0){
- control &= bit_get_negative(CPU_ROMCS);
- }
-// clock_wait(1);
- BUS_CONTROL_OUT = control;
-
- //bus close
-// clock_wait(1);
- BUS_CONTROL_OUT = BUS_CLOSE;
-
- address += 1;
- length--;
- }
-}
-
-static inline void ppu_write_waveform(uint16_t address, uint8_t data)
-{
- address_set(address);//PPU charcter memory /CS open
- BUS_CONTROL_OUT = bit_get_negative(PPU_WR);
- DATABUS_OUT = data;
- BUS_CONTROL_OUT = BUS_CLOSE;
- address_set(1 << 13); ///CS close
-}
-void ppu_write(uint16_t address, uint16_t length, const uint8_t *data)
-{
- while(length != 0){
- ppu_write_waveform(address, *data);
- data++;
- address += 1;
- length--;
- }
-}
-
-void ppu_write_order(const struct flash_order *t)
-{
- int length = FLASH_PROGRAM_ORDER;
- while(length != 0){
- ppu_write_waveform(t->address, t->data);
- t++;
- length--;
- }
-}
-
-uint8_t vram_connection_get(void)
-{
- uint8_t ret;
- uint16_t address = 0x2000;
- direction_write();
- address_set(address);
- ret = bit_get(USB_MISC_IN, VRAM_A10);
- address += 1 << 10;
-
- address_set(address);
- ret |= bit_get(USB_MISC_IN, VRAM_A10) << 1;
- address += 1 << 10;
-
- address_set(address);
- ret |= bit_get(USB_MISC_IN, VRAM_A10) << 2;
- address += 1 << 10;
-
- address_set(address);
- ret |= bit_get(USB_MISC_IN, VRAM_A10) << 3;
- address += 1 << 10;
-
- return ret;
-}
+++ /dev/null
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "bus_access.h"
-#include "disk_access.h"
-
-uint16_t disk_status_get(uint8_t *data)
-{
- const uint16_t length = 2;
- cpu_read(0x4030, length, data);
- return length;
-}
-static enum sequence{
- IDLE = 0,
- INIT_MOTOR_STOP, INIT_BATTERY, INIT_MOTOR_START,
- WAIT_READY,
- READ_START, READING, READ_END
-} sequence = IDLE;
-
-void disk_init(enum DISK_REQUEST r)
-{
- sequence = INIT_MOTOR_STOP;
-}
-
-enum disk_control{ //$4025 control bitfield assignment
- MOTOR = 0, //0:stop, 1:work
- TRANSFER_RESET, //1:do reset
- DIRECTION, //0:write, 1:read
- VRAM_MIRRORING,
- BLOCK_END_MARK,
- UNKOWN, //always 1
- ACCESS_START,
- INTERRUPT //0:off, 1:on
-};
-static inline uint8_t bit_set(enum disk_control bit)
-{
- return 1 << bit;
-};
-enum{
- BUFFER_ADDRESS = 0x0000,
- DRQ_COUNT = 0x0400,
- DISK_CONTROL = 0x4025
-};
-static void data_buffer_init(void)
-{
- const uint8_t filldata[] = {
- 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
- 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
- };
- uint16_t address = BUFFER_ADDRESS;
- while(address < BUFFER_ADDRESS + DRQ_COUNT){
- ppu_write(address, sizeof(filldata), filldata);
- address += sizeof(filldata);
- }
-}
-
-static inline void motor_stop(void)
-{
- uint8_t w;
- w = bit_set(UNKOWN) | bit_set(DIRECTION) | bit_set(TRANSFER_RESET);
- cpu_write_6502(DISK_CONTROL, 1, &w);
-}
-
-static inline void motor_start(void)
-{
- uint8_t w;
- w = bit_set(UNKOWN) | bit_set(DIRECTION) | bit_set(TRANSFER_RESET)| bit_set(MOTOR);
- cpu_write_6502(DISK_CONTROL, 1, &w);
- clock_wait(9);
- w = bit_set(UNKOWN) | bit_set(DIRECTION) | bit_set(MOTOR);
- cpu_write_6502(DISK_CONTROL, 1, &w);
-}
-
-volatile static uint16_t drq_count;
-void disk_process(void)
-{
- const uint16_t status = 0x4032;
- switch(sequence){
- default:
- case IDLE:
- break;
- case INIT_MOTOR_STOP:{
- const uint8_t writebuf[] = {0, 0, 0, 0x83};
- //GICR &= ~bit_set(INT1);
- data_buffer_init();
- //timer interrupt off, disk IO on
- cpu_write_6502(0x4020, sizeof(writebuf), writebuf);
- motor_stop();
- _delay_ms(0x200);
- sequence = INIT_BATTERY;
- }break;
- case INIT_BATTERY:{
- motor_start();
- _delay_ms(150);
- uint8_t w = 0xff;
- cpu_write_6502(0x4026, 1, &w);
- sequence = INIT_MOTOR_START;
- }
- break;
- case INIT_MOTOR_START:{
- motor_stop();
- motor_start();
- sequence = WAIT_READY;
- }break;
- case WAIT_READY:{
- uint8_t s;
- cpu_read_6502(status, 1, &s);
- if((s & 0b10) == 0b00){
- sequence = READ_START;
- }
- }break;
- case READ_START:{
- uint8_t w;
- _delay_ms(267 + 5);
-
- w = bit_set(ACCESS_START) | bit_set(UNKOWN) | bit_set(VRAM_MIRRORING) | bit_set(DIRECTION) | bit_set(MOTOR);
- cpu_write_6502(DISK_CONTROL, 1, &w);
- clock_wait(21 - 1);
- //DRQ enable
- //MCU INT1 init
-// GICR |= bit_set(INT1);
- drq_count = DRQ_COUNT;
- //RP2C33 IRQ enable
- w |= bit_set(INTERRUPT);
- cpu_write_6502(DISK_CONTROL, 1, &w);
- sequence = READING;
- }break;
- case READING:
- if(drq_count == 0){
- sequence = READ_END;
- }
- break;
- case READ_END:{
-/* uint8_t w;
- w = bit_set(ACCESS_START) | bit_set(UNKOWN) | bit_set(DIRECTION) | bit_set(MOTOR);
- cpu_write_6502(DISK_CONTROL, 1, &w);*/
-// GICR &= ~bit_set(INT1);
-
- sequence = IDLE;
- }break;
- }
- uint8_t w[2];
- w[0] = sequence;
- w[1] = 0x55;
- ppu_write(0x0aaa, 2, w);
- phi2_update();
-}
-
-ISR(INT1_vect)
-{
- static uint16_t buffer_pointer = BUFFER_ADDRESS;
- uint8_t d;
- cpu_read_6502(0x4031, 1, &d);
- ppu_write(buffer_pointer++, 1, &d);
- //cpu_write_6502(buffer_pointer++, 1, &d);
- if(buffer_pointer >= BUFFER_ADDRESS + DRQ_COUNT){
- buffer_pointer = 0;
- }
- drq_count -= 1;
-}
+++ /dev/null
-#include <stdint.h>
-#include "bus_access.h"
-
-//---- global variable ----
-struct flash_seqence{
- void (*const writer)(uint16_t address, uint16_t length, const uint8_t *data);
- void (*const programmer)(const struct flash_order *t);
- void (*const reader)(uint16_t address, uint16_t length, uint8_t *data);
- enum compare_status (*const compare)(uint16_t address, uint16_t length, const uint8_t *data);
- enum status{
- IDLE = 0,
- ERASE, ERASE_WAIT,
- PROGRAM, TOGGLE_FIRST, TOGGLE_CHECK
- } status, request;
- uint16_t command_000x, command_2aaa, command_5555;
- uint16_t address, length, program_unit;
- const uint8_t *data;
- uint8_t toggle, retry_count;
- struct flash_order program_command[FLASH_PROGRAM_ORDER];
-};
-static struct flash_seqence seqence_cpu = {
- .status = IDLE, .reader = cpu_read,
- .writer = cpu_write_flash, .programmer = cpu_write_flash_order,
- .compare = cpu_compare
-};
-static struct flash_seqence seqence_ppu = {
- .status = IDLE, .reader = ppu_read,
- .writer = ppu_write, .programmer = ppu_write_order,
- .compare = ppu_compare
-};
-
-//---- task registration ----
-uint8_t flash_cpu_status(void)
-{
- return seqence_cpu.status;
-}
-uint8_t flash_ppu_status(void)
-{
- return seqence_ppu.status;
-}
-void flash_both_idle(void)
-{
- seqence_cpu.status = IDLE;
- seqence_ppu.status = IDLE;
-}
-static void config_set(uint16_t c000x, uint16_t c2aaa, uint16_t c5555, uint16_t unit, struct flash_seqence *t)
-{
- t->command_000x = c000x;
- t->command_2aaa = c2aaa;
- t->command_5555 = c5555;
- t->program_unit = unit;
- t->program_command[0].address = c5555;
- t->program_command[0].data = 0xaa;
- t->program_command[1].address = c2aaa;
- t->program_command[1].data = 0x55;
- t->program_command[2].address = c5555;
- t->program_command[2].data = 0xa0;
-};
-void flash_cpu_config(uint16_t c000x, uint16_t c2aaa, uint16_t c5555, uint16_t unit)
-{
- config_set(c000x, c2aaa, c5555, unit, &seqence_cpu);
-}
-void flash_ppu_config(uint16_t c000x, uint16_t c2aaa, uint16_t c5555, uint16_t unit)
-{
- config_set(c000x, c2aaa, c5555, unit, &seqence_ppu);
-}
-
-static void program_assign(enum status status, uint16_t address, uint16_t length, const uint8_t *data, struct flash_seqence *t)
-{
- t->status = status;
- t->request = status;
- t->address = address;
- t->length = length;
- t->data = data;
- t->retry_count = 0;
-}
-void flash_cpu_program(uint16_t address, uint16_t length, const uint8_t *data)
-{
- program_assign(PROGRAM, address, length, data, &seqence_cpu);
-}
-void flash_ppu_program(uint16_t address, uint16_t length, const uint8_t *data)
-{
- program_assign(PROGRAM, address, length, data, &seqence_ppu);
-}
-#define NULL (0)
-void flash_cpu_erase(uint16_t address)
-{
- //length ¤Ë unit ¤òÅϤ·¤Æ toggle check ¸å IDLE ¤Ë¤Ê¤ë¤è¤¦¤Ë¤¹¤ë
- program_assign(ERASE, address, seqence_cpu.program_unit, NULL, &seqence_cpu);
-}
-void flash_ppu_erase(uint16_t address)
-{
- program_assign(ERASE, address, seqence_ppu.program_unit, NULL, &seqence_ppu);
-}
-
-//---- command write ----
-struct flash_command{
- enum {C2AAA, C5555, END} address;
- uint8_t data;
-};
-static void command_execute(const struct flash_command *c, const struct flash_seqence *const t)
-{
- while(c->address != END){
- uint16_t addr = 0;
- switch(c->address){
- case C2AAA:
- addr = t->command_2aaa;
- break;
- case C5555:
- addr = t->command_5555;
- break;
- case END:
- return;
- }
- t->writer(addr, 1, &c->data);
- c++;
- }
-}
-static void program(const struct flash_seqence *t)
-{
-/* static const struct flash_command c[] = {
- {C5555, 0xaa}, {C2AAA, 0x55}, {C5555, 0xa0}, {END, 0}
- };
- command_execute(c, t);*/
- t->programmer(t->program_command);
- t->writer(t->address, t->program_unit, t->data);
-}
-
-static void erase(const struct flash_seqence *t)
-{
- static const struct flash_command c[] = {
- {C5555, 0xaa}, {C2AAA, 0x55}, {C5555, 0x80},
- {C5555, 0xaa}, {C2AAA, 0x55}, {C5555, 0x10},
- {END, 0}
- };
- command_execute(c, t);
-}
-
-static void device_get(const struct flash_seqence *t, uint8_t d[2])
-{
- static const struct flash_command entry[] = {
- {C5555, 0xaa}, {C2AAA, 0x55}, {C5555, 0x90}, {END, 0}
- };
- static const struct flash_command exit[] = {
- {C5555, 0xaa}, {C2AAA, 0x55}, {C5555, 0xf0}, {END, 0}
- };
- command_execute(entry, t);
- t->reader(t->command_000x, 1, d);
- command_execute(entry, t);
- t->reader(t->command_000x + 1, 1, d + 1);
- command_execute(exit, t);
-}
-void flash_cpu_device_get(uint8_t d[2])
-{
- device_get(&seqence_cpu, d);
-}
-void flash_ppu_device_get(uint8_t d[2])
-{
- device_get(&seqence_ppu, d);
-}
-//---- status read ----
-static void toggle_first(struct flash_seqence *t)
-{
- t->reader(t->address, 1, &t->toggle);
- t->toggle &= 0x40;
-}
-static void toggle_check(struct flash_seqence *t)
-{
- uint8_t d;
- t->reader(t->address, 1, &d);
- if(t->toggle == (d & 0x40)){
- if((t->program_unit != 1) && (t->request == PROGRAM)){ //page program device retry
- if(t->retry_count >= 10){
- if(t->compare(t->address, t->program_unit, t->data) == NG){
- t->retry_count += 1;
- t->status = PROGRAM;
- return;
- }
- }
- t->retry_count = 0;
- }
- t->address += t->program_unit;
- t->data += t->program_unit;
- t->length -= t->program_unit;
- if((t->length == 0) || (t->request == ERASE)){
- t->status = IDLE;
- }else{
- t->status = PROGRAM;
- }
- }
- t->toggle = d & 0x40;
- if(0 && (d & 0x20)){ //polling DQ5, AM29F040B only
- uint8_t d0, d1;
- t->reader(t->address, 1, &d0);
- t->reader(t->address, 1, &d1);
- if((d0 & 0x40) == (d1 & 0x40)){
- t->address += t->program_unit;
- t->data += t->program_unit;
- t->length -= t->program_unit;
- if((t->length == 0) || (t->request == ERASE)){
- t->status = IDLE;
- }else{
- t->status = PROGRAM;
- }
- }
- }
-}
-
-static void erase_wait(struct flash_seqence *t)
-{
- uint8_t d;
- t->reader(t->address, 1, &d);
- if(d == 0xff){
- t->status = IDLE;
- }
-}
-//---- task execute ----
-static void process(struct flash_seqence *s)
-{
- switch(s->status){
- case IDLE:
- break;
- case ERASE:
- erase(s);
- s->status = ERASE_WAIT;
- break;
- case ERASE_WAIT:
- erase_wait(s);
- break;
- case PROGRAM:
- if((s->program_unit != 1) || (*(s->data) != 0xff)){
- program(s);
- }
- s->status = TOGGLE_FIRST;
- break;
- case TOGGLE_FIRST:
- toggle_first(s);
- s->status = TOGGLE_CHECK;
- break;
- case TOGGLE_CHECK:
- toggle_check(s); //status is updated by function
- break;
- }
-
-}
-void flash_process(void)
-{
- //for CPU and PPU dual programming
- process(&seqence_cpu);
- process(&seqence_ppu);
-}