void SendFileEncrypted(RAFile *file,unsigned char *key,int keysize) { unsigned char c1, c2; unsigned char headersize; unsigned int keyidx=0; unsigned long j; unsigned long n; unsigned char *p; int badbyte=0; iprintf("["); headersize=file->size&255; // ROM should be a round number of kilobytes; overspill will likely be the Amiga Forever header. RARead(file,sector_buffer,headersize); // Read extra bytes n = (file->size + (511-headersize)) >> 9; // sector count (rounded up) while (n--) { RARead(file,sector_buffer,512); for (j = 0; j < 512; j++) { sector_buffer[j]^=key[keyidx++]; if(keyidx>=keysize) keyidx-=keysize; } do { // read FPGA status EnableFpga(); c1 = SPI(0); c2 = SPI(0); SPI(0); SPI(0); SPI(0); SPI(0); DisableFpga(); } while (!(c1 & CMD_RDTRK)); if ((n & 15) == 0) iprintf("*"); // send data sector to FPGA EnableFpga(); c1 = SPI(0); c2 = SPI(0); SPI(0); SPI(0); SPI(0); SPI(0); p = sector_buffer; for (j = 0; j < 512; j++) SPI(*p++); DisableFpga(); } iprintf("]\r"); }
void user_io_file_tx(fileTYPE *file, unsigned char index) { unsigned long bytes2send = file->size; /* transmit the entire file using one transfer */ iprintf("Selected file %.11s with %lu bytes to send for index %d\n", file->name, bytes2send, index); // set index byte (0=bios rom, 1-n=OSD entry index) user_io_set_index(index); // send directory entry (for alpha amstrad core) EnableFpga(); SPI(UIO_FILE_INFO); spi_write((void*)(DirEntry+sort_table[iSelectedEntry]), sizeof(DIRENTRY)); DisableFpga(); // hexdump(DirEntry+sort_table[iSelectedEntry], sizeof(DIRENTRY), 0); // prepare transmission of new file EnableFpga(); SPI(UIO_FILE_TX); SPI(0xff); DisableFpga(); while(bytes2send) { iprintf("."); unsigned short c, chunk = (bytes2send>512)?512:bytes2send; char *p; FileRead(file, sector_buffer); EnableFpga(); SPI(UIO_FILE_TX_DAT); for(p = sector_buffer, c=0;c < chunk;c++) SPI(*p++); DisableFpga(); bytes2send -= chunk; // still bytes to send? read next sector if(bytes2send) FileNextSector(file); } // signal end of transmission EnableFpga(); SPI(UIO_FILE_TX); SPI(0x00); DisableFpga(); iprintf("\n"); }
void SendFile(RAFile *file) { DEBUG_FUNC_IN(DEBUG_F_FPGA | DEBUG_L0); unsigned char c1, c2; unsigned long j; unsigned long n; unsigned char *p; printf("["); n = (file->file.size + 511) >> 9; // sector count (rounded up) while (n--) { // read data sector from memory card RARead(file,sector_buffer,512); do { // read FPGA status EnableFpga(); c1 = SPI(0); c2 = SPI(0); SPI(0); SPI(0); SPI(0); SPI(0); DisableFpga(); } while (!(c1 & CMD_RDTRK)); if ((n & 15) == 0) printf("*"); // send data sector to FPGA EnableFpga(); c1 = SPI(0); c2 = SPI(0); SPI(0); SPI(0); SPI(0); SPI(0); p = sector_buffer; for (j = 0; j < 512; j++) SPI(*p++); DisableFpga(); } printf("]\r"); DEBUG_FUNC_OUT(DEBUG_F_FPGA | DEBUG_L0); }
static void mist_memory_write_block(char *data) { EnableFpga(); SPI(MIST_WRITE_MEMORY); spi_block_write(data); DisableFpga(); }
static void mist_memory_read_block(char *data) { EnableFpga(); SPI(MIST_READ_MEMORY); spi_block_read(data); DisableFpga(); }
static void mist_set_control(unsigned long ctrl) { EnableFpga(); SPI(MIST_SET_CONTROL); SPI((ctrl >> 24) & 0xff); SPI((ctrl >> 16) & 0xff); SPI((ctrl >> 8) & 0xff); SPI((ctrl >> 0) & 0xff); DisableFpga(); }
void tos_set_video_adjust(char axis, char value) { config.video_adjust[axis] += value; EnableFpga(); SPI(MIST_SET_VADJ); SPI(config.video_adjust[0]); SPI(config.video_adjust[1]); DisableFpga(); }
static void mist_memory_write(char *data, unsigned long words) { EnableFpga(); SPI(MIST_WRITE_MEMORY); while(words--) { SPI_WRITE(*data++); SPI_WRITE(*data++); } DisableFpga(); }
// draw on screen char BootDraw(char *data, unsigned short len, unsigned short offset) { DEBUG_FUNC_IN(); unsigned char c1, c2, c3, c4; unsigned char cmd; const char *p; unsigned short n; unsigned short i; n = (len+3)&(~3); i = 0; cmd = 1; while (1) { EnableFpga(); c1 = SPI(0x10); // track read command c2 = SPI(0x01); // disk present unsigned char x = SPI(0); unsigned char y = SPI(0); c3 = SPI(0); c4 = SPI(0); // iprintf("FPGA state: %d %d (%d %d) %d %d\n", c1, c2, x, y, c3, c4); if (c1 & CMD_RDTRK) { if (cmd) { // command phase if (c3 == 0x80 && c4 == 0x06) // command packet size must be 12 bytes { cmd = 0; SPI(CMD_HDRID >> 8); // command header SPI(CMD_HDRID & 0xFF); SPI(0x00); // cmd: 0x0001 = print text SPI(0x01); // data packet size in bytes SPI(0x00); SPI(0x00); SPI((n)>>8); SPI((n)&0xff); // +2 because only even byte count is possible to send and we have to send termination zero byte // offset SPI(0x00); SPI(0x00); SPI(offset>>8); SPI(offset&0xff); } else break; } else { // data phase if (c3 == 0x80 && c4 == ((n) >> 1))
void mist_memory_set(char data, unsigned long words) { EnableFpga(); SPI(MIST_WRITE_MEMORY); while(words--) { SPI_WRITE(data); SPI_WRITE(data); } DisableFpga(); }
static void mist_memory_read(char *data, unsigned long words) { EnableFpga(); SPI(MIST_READ_MEMORY); // transmitted bytes must be multiple of 2 (-> words) while(words--) { *data++ = SPI(0); *data++ = SPI(0); } DisableFpga(); }
static void mist_memory_set_address(unsigned long a, unsigned char s, char rw) { // iprintf("set addr = %x, %d, %d\n", a, s, rw); a |= rw?0x1000000:0; a >>= 1; EnableFpga(); SPI(MIST_SET_ADDRESS); SPI(s); SPI((a >> 16) & 0xff); SPI((a >> 8) & 0xff); SPI((a >> 0) & 0xff); DisableFpga(); }
//// HandleFpga() //// void HandleFpga(void) { // DEBUG_FUNC_IN(); unsigned char c1, c2; EnableFpga(); c1 = SPI(0); // cmd request and drive number c2 = SPI(0); // track number SPI(0); SPI(0); SPI(0); SPI(0); DisableFpga(); HandleFDD(c1, c2); HandleHDD(c1, c2); UpdateDriveStatus(); // DEBUG_FUNC_OUT(); }
void user_io_poll() { if(user_io_dip_switch1()) { // check of core has changed from a good one to a not supported on // as this likely means that the user is reloading the core via jtag unsigned char ct; static unsigned char ct_cnt = 0; EnableIO(); ct = SPI(0xff); DisableIO(); SPI(0xff); // needed for old minimig core if(ct == core_type) ct_cnt = 0; // same core type, everything is fine else { // core type has changed if(++ct_cnt == 255) { // wait for a new valid core id to appear while((ct & 0xf0) != 0xa0) { EnableIO(); ct = SPI(0xff); DisableIO(); SPI(0xff); // needed for old minimig core } // reset io controller to cope with new core *AT91C_RSTC_RCR = 0xA5 << 24 | AT91C_RSTC_PERRST | AT91C_RSTC_PROCRST; // restart for(;;); } } } if((core_type != CORE_TYPE_MINIMIG) && (core_type != CORE_TYPE_MINIMIG2) && (core_type != CORE_TYPE_PACE) && (core_type != CORE_TYPE_MIST) && (core_type != CORE_TYPE_ARCHIE) && (core_type != CORE_TYPE_8BIT)) { return; // no user io for the installed core } if(core_type == CORE_TYPE_MIST) { char redirect = tos_get_cdc_control_redirect(); ikbd_poll(); // check for input data on usart USART_Poll(); unsigned char c = 0; // check for incoming serial data. this is directly forwarded to the // arm rs232 and mixes with debug output. Useful for debugging only of // e.g. the diagnostic cartridge if(!pl2303_is_blocked()) { spi_uio_cmd_cont(UIO_SERIAL_IN); while(spi_in() && !pl2303_is_blocked()) { c = spi_in(); // if a serial/usb adapter is connected it has precesence over // any other sink if(pl2303_present()) pl2303_tx_byte(c); else { if(c != 0xff) putchar(c); // forward to USB if redirection via USB/CDC enabled if(redirect == CDC_REDIRECT_RS232) cdc_control_tx(c); } } DisableIO(); } // check for incoming parallel/midi data if((redirect == CDC_REDIRECT_PARALLEL) || (redirect == CDC_REDIRECT_MIDI)) { spi_uio_cmd_cont((redirect == CDC_REDIRECT_PARALLEL)?UIO_PARALLEL_IN:UIO_MIDI_IN); // character 0xff is returned if FPGA isn't configured c = 0; while(spi_in() && (c!= 0xff)) { c = spi_in(); cdc_control_tx(c); } DisableIO(); // always flush when doing midi to reduce latencies if(redirect == CDC_REDIRECT_MIDI) cdc_control_flush(); } } // poll db9 joysticks static int joy0_state = JOY0; if((*AT91C_PIOA_PDSR & JOY0) != joy0_state) { joy0_state = *AT91C_PIOA_PDSR & JOY0; unsigned char joy_map = 0; if(!(joy0_state & JOY0_UP)) joy_map |= JOY_UP; if(!(joy0_state & JOY0_DOWN)) joy_map |= JOY_DOWN; if(!(joy0_state & JOY0_LEFT)) joy_map |= JOY_LEFT; if(!(joy0_state & JOY0_RIGHT)) joy_map |= JOY_RIGHT; if(!(joy0_state & JOY0_BTN1)) joy_map |= JOY_BTN1; if(!(joy0_state & JOY0_BTN2)) joy_map |= JOY_BTN2; user_io_joystick(joystick_renumber(0), joy_map); } static int joy1_state = JOY1; if((*AT91C_PIOA_PDSR & JOY1) != joy1_state) { joy1_state = *AT91C_PIOA_PDSR & JOY1; unsigned char joy_map = 0; if(!(joy1_state & JOY1_UP)) joy_map |= JOY_UP; if(!(joy1_state & JOY1_DOWN)) joy_map |= JOY_DOWN; if(!(joy1_state & JOY1_LEFT)) joy_map |= JOY_LEFT; if(!(joy1_state & JOY1_RIGHT)) joy_map |= JOY_RIGHT; if(!(joy1_state & JOY1_BTN1)) joy_map |= JOY_BTN1; if(!(joy1_state & JOY1_BTN2)) joy_map |= JOY_BTN2; user_io_joystick(joystick_renumber(1), joy_map); } user_io_send_buttons(0); // mouse movement emulation is continous if(emu_mode == EMU_MOUSE) { if(CheckTimer(emu_timer)) { emu_timer = GetTimer(EMU_MOUSE_FREQ); if(emu_state & JOY_MOVE) { unsigned char b = 0; char x = 0, y = 0; if((emu_state & (JOY_LEFT | JOY_RIGHT)) == JOY_LEFT) x = -1; if((emu_state & (JOY_LEFT | JOY_RIGHT)) == JOY_RIGHT) x = +1; if((emu_state & (JOY_UP | JOY_DOWN)) == JOY_UP) y = -1; if((emu_state & (JOY_UP | JOY_DOWN)) == JOY_DOWN) y = +1; if(emu_state & JOY_BTN1) b |= 1; if(emu_state & JOY_BTN2) b |= 2; user_io_mouse(b, x, y); } } } if((core_type == CORE_TYPE_MINIMIG) || (core_type == CORE_TYPE_MINIMIG2)) { kbd_fifo_poll(); // frequently check mouse for events if(CheckTimer(mouse_timer)) { mouse_timer = GetTimer(MOUSE_FREQ); // has ps2 mouse data been updated in the meantime if(mouse_flags & 0x80) { spi_uio_cmd_cont(UIO_MOUSE); // ----- X axis ------- if(mouse_pos[X] < -128) { spi8(-128); mouse_pos[X] += 128; } else if(mouse_pos[X] > 127) { spi8(127); mouse_pos[X] -= 127; } else { spi8(mouse_pos[X]); mouse_pos[X] = 0; } // ----- Y axis ------- if(mouse_pos[Y] < -128) { spi8(-128); mouse_pos[Y] += 128; } else if(mouse_pos[Y] > 127) { spi8(127); mouse_pos[Y] -= 127; } else { spi8(mouse_pos[Y]); mouse_pos[Y] = 0; } spi8(mouse_flags & 0x03); DisableIO(); // reset flags mouse_flags = 0; } } } if(core_type == CORE_TYPE_MIST) { // do some tos specific monitoring here tos_poll(); } if(core_type == CORE_TYPE_8BIT) { unsigned char c = 1, f, p=0; // check for input data on usart USART_Poll(); // check for serial data to be sent // check for incoming serial data. this is directly forwarded to the // arm rs232 and mixes with debug output. spi_uio_cmd_cont(UIO_SIO_IN); // status byte is 1000000A with A=1 if data is available if((f = spi_in(0)) == 0x81) { iprintf("\033[1;36m"); // character 0xff is returned if FPGA isn't configured while((f == 0x81) && (c!= 0xff) && (c != 0x00) && (p < 8)) { c = spi_in(); if(c != 0xff && c != 0x00) iprintf("%c", c); f = spi_in(); p++; } iprintf("\033[0m"); } DisableIO(); // sd card emulation { static char buffer[512]; static uint32_t buffer_lba = 0xffffffff; uint32_t lba; uint8_t c = user_io_sd_get_status(&lba); // valid sd commands start with "5x" to avoid problems with // cores that don't implement this command if((c & 0xf0) == 0x50) { // debug: If the io controller reports and non-sdhc card, then // the core should never set the sdhc flag if((c & 3) && !MMC_IsSDHC() && (c & 0x04)) iprintf("WARNING: SDHC access to non-sdhc card\n"); // check if core requests configuration if(c & 0x08) { iprintf("core requests SD config\n"); user_io_sd_set_config(); } // check if system is trying to access a sdhc card from // a sd/mmc setup // check if an SDHC card is inserted if(MMC_IsSDHC()) { static char using_sdhc = 1; // SD request and if((c & 0x03) && !(c & 0x04)) { if(using_sdhc) { // we have not been using sdhc so far? // -> complain! ErrorMessage(" This core does not support\n" " SDHC cards. Using them may\n" " lead to data corruption.\n\n" " Please use an SD card <2GB!", 0); using_sdhc = 0; } } else // SDHC request from core is always ok using_sdhc = 1; } if((c & 0x03) == 0x02) { // only write if the inserted card is not sdhc or // if the core uses sdhc if((!MMC_IsSDHC()) || (c & 0x04)) { uint8_t wr_buf[512]; if(user_io_dip_switch1()) iprintf("SD WR %d\n", lba); // if we write the sector stored in the read buffer, then // update the read buffer with the new contents if(buffer_lba == lba) memcpy(buffer, wr_buf, 512); buffer_lba = 0xffffffff; // Fetch sector data from FPGA ... spi_uio_cmd_cont(UIO_SECTOR_WR); spi_block_read(wr_buf); DisableIO(); // ... and write it to disk DISKLED_ON; if(sd_image.size) { FileSeek(&sd_image, lba, SEEK_SET); FileWrite(&sd_image, wr_buf); } else MMC_Write(lba, wr_buf); DISKLED_OFF; } } if((c & 0x03) == 0x01) { if(user_io_dip_switch1()) iprintf("SD RD %d\n", lba); // are we using a file as the sd card image? // (C64 floppy does that ...) if(buffer_lba != lba) { DISKLED_ON; if(sd_image.size) { FileSeek(&sd_image, lba, SEEK_SET); FileRead(&sd_image, buffer); } else { // sector read // read sector from sd card if it is not already present in // the buffer MMC_Read(lba, buffer); } buffer_lba = lba; DISKLED_OFF; } if(buffer_lba == lba) { // data is now stored in buffer. send it to fpga spi_uio_cmd_cont(UIO_SECTOR_RD); spi_block_write(buffer); DisableIO(); // the end of this transfer acknowledges the FPGA internal // sd card emulation } // just load the next sector now, so it may be prefetched // for the next request already DISKLED_ON; if(sd_image.size) { FileSeek(&sd_image, lba+1, SEEK_SET); FileRead(&sd_image, buffer); } else { // sector read // read sector from sd card if it is not already present in // the buffer MMC_Read(lba+1, buffer); } buffer_lba = lba+1; DISKLED_OFF; } } } // frequently check ps2 mouse for events if(CheckTimer(mouse_timer)) { mouse_timer = GetTimer(MOUSE_FREQ); // has ps2 mouse data been updated in the meantime if(mouse_flags & 0x08) { unsigned char ps2_mouse[3]; // PS2 format: // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn // dx[7:0] // dy[7:0] ps2_mouse[0] = mouse_flags; // ------ X axis ----------- // store sign bit in first byte ps2_mouse[0] |= (mouse_pos[X] < 0)?0x10:0x00; if(mouse_pos[X] < -255) { // min possible value + overflow flag ps2_mouse[0] |= 0x40; ps2_mouse[1] = -128; } else if(mouse_pos[X] > 255) { // max possible value + overflow flag ps2_mouse[0] |= 0x40; ps2_mouse[1] = 255; } else ps2_mouse[1] = mouse_pos[X]; // ------ Y axis ----------- // store sign bit in first byte ps2_mouse[0] |= (mouse_pos[Y] < 0)?0x20:0x00; if(mouse_pos[Y] < -255) { // min possible value + overflow flag ps2_mouse[0] |= 0x80; ps2_mouse[2] = -128; } else if(mouse_pos[Y] > 255) { // max possible value + overflow flag ps2_mouse[0] |= 0x80; ps2_mouse[2] = 255; } else ps2_mouse[2] = mouse_pos[Y]; // collect movement info and send at predefined rate iprintf("PS2 MOUSE: %x %d %d\n", ps2_mouse[0], ps2_mouse[1], ps2_mouse[2]); spi_uio_cmd_cont(UIO_MOUSE); spi8(ps2_mouse[0]); spi8(ps2_mouse[1]); spi8(ps2_mouse[2]); DisableIO(); // reset counters mouse_flags = 0; mouse_pos[X] = mouse_pos[Y] = 0; } } // --------------- THE FOLLOWING IS DEPRECATED AND WILL BE REMOVED ------------ // ------------------------ USE SD CARD EMULATION INSTEAD --------------------- // raw sector io for the atari800 core which include a full // file system driver usually implemented using a second cpu static unsigned long bit8_status = 0; unsigned long status; /* read status byte */ EnableFpga(); SPI(UIO_GET_STATUS); status = SPI(0); status = (status << 8) | SPI(0); status = (status << 8) | SPI(0); status = (status << 8) | SPI(0); DisableFpga(); if(status != bit8_status) { unsigned long sector = (status>>8)&0xffffff; char buffer[512]; bit8_status = status; // sector read testing DISKLED_ON; // sector read if(((status & 0xff) == 0xa5) || ((status & 0x3f) == 0x29)) { // extended command with 26 bits (for 32GB SDHC) if((status & 0x3f) == 0x29) sector = (status>>6)&0x3ffffff; bit8_debugf("SECIO rd %ld", sector); if(MMC_Read(sector, buffer)) { // data is now stored in buffer. send it to fpga EnableFpga(); SPI(UIO_SECTOR_SND); // send sector data IO->FPGA spi_block_write(buffer); DisableFpga(); } else bit8_debugf("rd %ld fail", sector); } // sector write if(((status & 0xff) == 0xa6) || ((status & 0x3f) == 0x2a)) { // extended command with 26 bits (for 32GB SDHC) if((status & 0x3f) == 0x2a) sector = (status>>6)&0x3ffffff; bit8_debugf("SECIO wr %ld", sector); // read sector from FPGA EnableFpga(); SPI(UIO_SECTOR_RCV); // receive sector data FPGA->IO spi_block_read(buffer); DisableFpga(); if(!MMC_Write(sector, buffer)) bit8_debugf("wr %ld fail", sector); } DISKLED_OFF; }
static void dma_nak(void) { EnableFpga(); SPI(MIST_NAK_DMA); DisableFpga(); }
static void dma_ack(unsigned char status) { EnableFpga(); SPI(MIST_ACK_DMA); SPI(status); DisableFpga(); }
static void user_io_set_index(unsigned char index) { EnableFpga(); SPI(UIO_FILE_INDEX); SPI(index); DisableFpga(); }