int RARead(RAFile *file,unsigned char *pBuffer, unsigned long bytes) { DEBUG_FUNC_IN(DEBUG_F_RAFILE | DEBUG_L2); int result=1; // Since we can only read from the SD card on 512-byte aligned boundaries, // we need to copy in multiple pieces. unsigned long blockoffset=file->ptr&511; // Offset within the current 512 block at which the previous read finished // Bytes blockoffset to 512 will be drained first, before reading new data. if(blockoffset) // If blockoffset is zero we'll just use aligned reads and don't need to drain the buffer. { int i; int l=bytes; if(l>512) l=512; for(i=blockoffset;i<l;++i) { *pBuffer++=file->buffer[i]; } file->ptr+=l-blockoffset; bytes-=l-blockoffset; } // We've now read any bytes left over from a previous read. If any data remains to be read we can read it // in 512-byte aligned chunks, until the last block. while(bytes>511) { result&=FileRead(&file->file,pBuffer); // Read direct to pBuffer FileNextSector(&file->file); bytes-=512; file->ptr+=512; pBuffer+=512; } if(bytes) // Do we have any bytes left to read? { unsigned int i; result&=FileRead(&file->file,file->buffer); // Read to temporary buffer, allowing us to preserve any leftover for the next read. FileNextSector(&file->file); for(i=0;i<bytes;++i) { *pBuffer++=file->buffer[i]; } file->ptr+=bytes; } return(result); DEBUG_FUNC_OUT(DEBUG_F_RAFILE | DEBUG_L2); }
//// UploadKickstart() //// char UploadKickstart(char *name) { int keysize=0; char filename[12]; strncpy(filename, name, 8); // copy base name strcpy(&filename[8], "ROM"); // add extension BootPrint("Checking for Amiga Forever key file:"); if(FileOpen(&file,"ROM KEY")) { keysize=file.size; if(file.size<sizeof(romkey)) { int c=0; while(c<keysize) { FileRead(&file, &romkey[c]); c+=512; FileNextSector(&file); } BootPrint("Loaded Amiga Forever key file"); } else { BootPrint("Amiga Forever keyfile is too large!"); } } BootPrint("Loading file: "); BootPrint(filename); if (RAOpen(&romfile, filename)) { if (romfile.size == 0x100000) { // 1MB Kickstart ROM BootPrint("Uploading 1MB Kickstart ..."); SendFileV2(&romfile, NULL, 0, 0xe00000, romfile.size>>10); SendFileV2(&romfile, NULL, 0, 0xf80000, romfile.size>>10); return(1); } else if(romfile.size == 0x80000) {
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"); }
static int LoadROM(const char *filename) { int result=0; int opened; ResetLoader(); HW_HOST(REG_HOST_CONTROL)=HOST_CONTROL_RESET; if((opened=FileOpen(&file,filename))) { int filesize=file.size; unsigned int c=0; int bits; HW_HOST(REG_HOST_ROMSIZE) = file.size; bits=0; c=filesize-1; while(c) { ++bits; c>>=1; } bits-=9; result=1; while(filesize>0) { OSD_ProgressBar(c,bits); if(FileRead(&file,sector_buffer)) { int i; int *p=(int *)§or_buffer; for(i=0;i<512;i+=4) { unsigned int t=*p++; HW_HOST(REG_HOST_BOOTDATA)=t; } } else { result=0; filesize=512; } FileNextSector(&file); filesize-=512; ++c; } }
int RASeek(RAFile *file,unsigned long offset,unsigned long origin) { int result=1; unsigned long blockoffset; unsigned long blockaddress; if(origin==SEEK_CUR) offset+=file->ptr; blockoffset=offset&511; blockaddress=offset-blockoffset; // 512-byte-aligned... result&=FileSeek(&file->file,blockaddress,SEEK_SET); if(result && blockoffset) // If we're seeking into the middle of a block, we need to buffer it... { result&=FileRead(&file->file,file->buffer); FileNextSector(&file->file); } file->ptr=offset; return(result); }
void main(void) { DEBUG_FUNC_IN(); fileTYPE ft; int i; // !!! a pointer to start of RAM unsigned char * ram = ((unsigned char *)0x400000); // initialize SD card LEDS(led=0xf); if (!MMC_Init()) FatalError(); // find drive LEDS(led=0x8); if (!FindDrive()) FatalError(); // open file LEDS(led=0x3); LoadFile(firmware,ram); #if 0 if (!FileOpen(&ft, firmware)) FatalError(); // load firmware to RAM LEDS(led=0x1); for(i=0; i<((ft.size>>9)+1); i++) { FileRead(&ft, ram+(i*512)); FileNextSector(&ft); } #endif // jump to RAM firmware LEDS(led=0x0); DisableCard(); sys_jump(0x400004); // loop forever while(1); DEBUG_FUNC_OUT(); }
// Altera FPGA configuration RAMFUNC unsigned char ConfigureFpga(char *name) { unsigned long i; unsigned char *ptr; // set outputs *AT91C_PIOA_SODR = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG; // enable outputs *AT91C_PIOA_OER = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG; if(!name) name = "CORE RBF"; // open bitstream file if (FileOpen(&file, name) == 0) { iprintf("No FPGA configuration file found!\r"); FatalError(4); } iprintf("FPGA bitstream file opened, file size = %d\r", file.size); iprintf("["); // send all bytes to FPGA in loop ptr = sector_buffer; /* Drive a transition of 0 to 1 to NCONFIG to indicate start of configuration */ for(i=0;i<10;i++) *AT91C_PIOA_CODR = ALTERA_NCONFIG; // must be low for at least 500ns *AT91C_PIOA_SODR = ALTERA_NCONFIG; // now wait for NSTATUS to go high // specs: max 800us i = 1000000; while (!(*AT91C_PIOA_PDSR & ALTERA_NSTATUS)) { if (--i == 0) { iprintf("FPGA NSTATUS is NOT high!\r"); FatalError(3); } } DISKLED_ON; int t = 0; int n = file.size >> 3; /* Loop through every single byte */ for ( i = 0; i < file.size; ) { // read sector if 512 (64*8) bytes done if ((i & 0x1FF) == 0) { if (i & (1<<13)) DISKLED_OFF else DISKLED_ON if ((i & 0x3FFF) == 0) iprintf("*"); if (!FileRead(&file, sector_buffer)) return(0); ptr = sector_buffer; } int bytes2copy = (i < file.size - 8)?8:file.size-i; i += bytes2copy; while(bytes2copy) { ShiftFpga(*ptr++); bytes2copy--; } /* Check for error through NSTATUS for every 10KB programmed and the last byte */ if ( !(i % 10240) || (i == file.size - 1) ) { if ( !*AT91C_PIOA_PDSR & ALTERA_NSTATUS ) { iprintf("FPGA NSTATUS is NOT high!\r"); FatalError(5); } } // read next sector if 512 (64*8) bytes done if ((i & 0x1FF) == 0) FileNextSector(&file); } iprintf("]\r"); iprintf("FPGA bitstream loaded\r"); DISKLED_OFF; // check if DONE is high if (!(*AT91C_PIOA_PDSR & ALTERA_DONE)) { iprintf("FPGA Configuration done but contains error... CONF_DONE is LOW\r"); FatalError(5); } /* Start initialization */ /* Clock another extra DCLK cycles while initialization is in progress through internal oscillator or driving clock cycles into CLKUSR pin */ /* These extra DCLK cycles do not initialize the device into USER MODE */ /* It is not required to drive extra DCLK cycles at the end of configuration */ /* The purpose of driving extra DCLK cycles here is to insert some delay while waiting for the initialization of the device to complete before checking the CONFDONE and NSTATUS signals at the end of whole configuration cycle */ for ( i = 0; i < 50; i++ ) { *AT91C_PIOA_CODR = ALTERA_DCLK; *AT91C_PIOA_SODR = ALTERA_DCLK; } /* Initialization end */ if ( !(*AT91C_PIOA_PDSR & ALTERA_NSTATUS) || !(*AT91C_PIOA_PDSR & ALTERA_DONE)) { iprintf("FPGA Initialization finish but contains error: NSTATUS is %s and CONF_DONE is %s.\r", ((*AT91C_PIOA_PDSR & ALTERA_NSTATUS)?"HIGH":"LOW"), ((*AT91C_PIOA_PDSR & ALTERA_DONE)?"HIGH":"LOW") ); FatalError(5); } return 1; }
// Xilinx FPGA configuration // was before unsigned char ConfigureFpga(void) RAMFUNC unsigned char ConfigureFpga(char *name) { unsigned long t; unsigned long n; unsigned char *ptr; // set outputs *AT91C_PIOA_SODR = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B; // enable outputs *AT91C_PIOA_OER = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B; // reset FGPA configuration sequence // specs: PROG_B pulse min 0.3 us t = 15; while (--t) *AT91C_PIOA_CODR = XILINX_PROG_B; *AT91C_PIOA_SODR = XILINX_PROG_B; // now wait for INIT to go high // specs: max 2ms t = 100000; while (!(*AT91C_PIOA_PDSR & XILINX_INIT_B)) { if (--t == 0) { iprintf("FPGA init is NOT high!\r"); FatalError(3); } } iprintf("FPGA init is high\r"); if (*AT91C_PIOA_PDSR & XILINX_DONE) { iprintf("FPGA done is high before configuration!\r"); FatalError(3); } if(!name) // name = "CORE BIN"; name = "XESM38 BIN"; // open bitstream file if (FileOpen(&file, name) == 0) { iprintf("No FPGA configuration file found!\r"); FatalError(4); } iprintf("FPGA bitstream file opened, file size = %d\r", file.size); iprintf("["); // send all bytes to FPGA in loop t = 0; n = file.size >> 3; ptr = sector_buffer; do { // read sector if 512 (64*8) bytes done if ((t & 0x3F) == 0) { if (t & (1<<10)) DISKLED_OFF else DISKLED_ON if ((t & 0x1FF) == 0) iprintf("*"); if (!FileRead(&file, sector_buffer)) return(0); ptr = sector_buffer; } // send data in packets of 8 bytes ShiftFpga(*ptr++); ShiftFpga(*ptr++); ShiftFpga(*ptr++); ShiftFpga(*ptr++); ShiftFpga(*ptr++); ShiftFpga(*ptr++); ShiftFpga(*ptr++); ShiftFpga(*ptr++); t++; // read next sector if 512 (64*8) bytes done if ((t & 0x3F) == 0) FileNextSector(&file); } while (t < n); // disable outputs *AT91C_PIOA_ODR = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B; iprintf("]\r"); iprintf("FPGA bitstream loaded\r"); DISKLED_OFF; // check if DONE is high if (*AT91C_PIOA_PDSR & XILINX_DONE) return(1); iprintf("FPGA done is NOT high!\r"); FatalError(5); return 0; }
unsigned char CheckFirmware(fileTYPE *file, char *name) { UPGRADE *pUpgrade = (UPGRADE*)sector_buffer; unsigned long crc; unsigned long size; unsigned long rom_size; unsigned long rom_crc; unsigned long read_size; Error = ERROR_FILE_NOT_FOUND; if (FileOpen(file, name)) { Error = ERROR_INVALID_DATA; iprintf("Upgrade file size : %lu\r", file->size); iprintf("Upgrade header size : %lu\r", (unsigned long)sizeof(UPGRADE)); if (file->size >= sizeof(UPGRADE)) { FileRead(file, sector_buffer); crc = ~CalculateCRC32(-1, sector_buffer, sizeof(UPGRADE) - 4); iprintf("Upgrade ROM size : %lu\r", pUpgrade->rom.size); iprintf("Upgrade header CRC : %08lX\r", pUpgrade->crc); iprintf("Calculated header CRC : %08lX\r", crc); if (pUpgrade->crc == crc) { if (strncmp((const char*)pUpgrade->id, "MNMGUPG", 7) == 0 && pUpgrade->id[7] == 0) { if (pUpgrade->rom.size == file->size - sizeof(UPGRADE)) { rom_size = pUpgrade->rom.size; rom_crc = pUpgrade->rom.crc; crc = -1; // initial CRC32 value size = rom_size; while (size) { if (size > 512) read_size = 512; else read_size = size; FileNextSector(file); FileRead(file, sector_buffer); crc = CalculateCRC32(crc, sector_buffer, read_size); size -= read_size; } iprintf("Calculated ROM CRC : %08lX\r", ~crc); iprintf("ROM CRC from header : %08lX\r", rom_crc); if (~crc == rom_crc) { // upgrade file CRC is OK so go back to the beginning of the file FileSeek(file, 0, SEEK_SET); Error = ERROR_NONE; return 1; } else iprintf("ROM CRC mismatch! from header: %08lX, calculated: %08lX\r", rom_crc, ~crc); } else iprintf("ROM size mismatch! from header: %lu, from file: %lu\r", pUpgrade->rom.size, file->size-sizeof(UPGRADE)); } else iprintf("Invalid upgrade file header!\r"); } else iprintf("Header CRC mismatch! from header: %08lX, calculated: %08lX\r", pUpgrade->crc, crc); } else iprintf("Upgrade file size too small: %lu\r", file->size); } else iprintf("Cannot open firmware file!\r"); return 0; }
RAMFUNC __noinline void WriteFirmware(fileTYPE *file, char *name) { unsigned long read_size; unsigned long i; unsigned long k; unsigned long page; unsigned long *pSrc; unsigned long *pDst; unsigned long size; // All interrupts have to be disabled. asm volatile ("mrs r12, CPSR; orr r12, r12, #0xC0; msr CPSR_c, r12" : /* No outputs */ : /* No inputs */ : "r12", "cc"); // Since the file may have changed in the meantime, it needs to be // opened again... if (!FileOpen(file, name)) return; size = file->size - sizeof(UPGRADE); page = 0; pDst = 0; *AT91C_MC_FMR = 48 << 16 | FWS << 8; // MCLK cycles in 1us for (i = 0; i < 16; i++) if (*AT91C_MC_FSR & 1 << 16 + i) { // page is locked while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready *AT91C_MC_FCR = 0x5A << 24 | i << 6 + 8 | AT91C_MC_FCMD_UNLOCK; // unlock page while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready } *AT91C_MC_FMR = 72 << 16 | FWS << 8; // MCLK cycles in 1.5us while (size) { if (size > 512) read_size = 512; else read_size = size; // On _any_ error the upgrade will fail :-( // then the firmware needs to be upgraded by another way! FileNextSector(file); FileRead(file, sector_buffer); #ifndef GCC_OPTIMZES_TOO_MUCH // the latest gcc 4.8.0 calls memset for this // it doesn't hurt to not do this at all // fill the rest of buffer for (i = read_size; i < 512; i++) sector_buffer[i] = 0xFF; #endif // programming time: 13.2 ms per disk sector (512B) pSrc = (unsigned long*)sector_buffer; k = 2; while (k--) { DISKLED_ON; #ifndef GCC_OPTIMZES_TOO_MUCH // the latest gcc 4.8.0 calls memcpy for this i = 256 / 4; while (i--) *pDst++ = *pSrc++; #else i = 256 / 8; while (i--) { *pDst++ = *pSrc++; *pDst++ = *pSrc++; } #if 0 *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; *pDst++ = *pSrc++; #endif #endif DISKLED_OFF; while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready *AT91C_MC_FCR = 0x5A << 24 | page << 8 | AT91C_MC_FCMD_START_PROG; // key: 0x5A while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready page++; } size -= read_size; } *AT91C_RSTC_RCR = 0xA5 << 24 | AT91C_RSTC_PERRST | AT91C_RSTC_PROCRST; // restart for(;;); }
static int Boot(enum boot_settings settings) { int result=0; int opened; OSD_Puts("Initializing SD card\n"); if(spi_init()) { int dipsw=GetDIPSwitch(); if(!FindDrive()) return(0); if(sd_ishc()) { OSD_Puts("SDHC not supported;"); OSD_Puts("\ndisabling SD card\n\x10 OK\n"); WaitEnter(); dipsw|=4; // Disable SD card. HW_HOST(HW_HOST_CTRL)=HW_HOST_CTRLF_RESET; // Put OCMSX into Reset again HW_HOST(HW_HOST_SW)=dipsw; SetDIPSwitch(dipsw); } else if(IsFat32()) { OSD_Puts("Fat32 not supported;"); OSD_Puts("\ndisabling SD card\n\x10 OK\n"); WaitEnter(); dipsw|=4; // Disable SD card. HW_HOST(HW_HOST_CTRL)=HW_HOST_CTRLF_RESET; // Put OCMSX into Reset again HW_HOST(HW_HOST_SW)=dipsw; SetDIPSwitch(dipsw); } HW_HOST(HW_HOST_CTRL)=HW_HOST_CTRLF_SDCARD; // Release reset but steal SD card if(opened=FileOpen(&file,"OCMSX CFG")) // Do we have a configuration file? { if(settings==BOOT_SAVESETTINGS) // If so, are we saving to it, or loading from it? { int i; int *p=(int *)sector_buffer; *p++=dipsw; *p++=GetVolumes(); *p++=GetMouseSettings(); for(i=0;i<125;++i) // Clear remainder of buffer *p++=0; FileWrite(&file,sector_buffer); } else if(settings==BOOT_LOADSETTINGS) { FileRead(&file,sector_buffer); dipsw=*(int *)(§or_buffer[0]); SetVolumes(*(int *)(§or_buffer[4])); SetMouseSettings(*(int *)(§or_buffer[8])); HW_HOST(HW_HOST_SW)=dipsw; SetDIPSwitch(dipsw); } // printf("DIP %d, Vol %d\n",dipsw,GetVolumes()); } OSD_Puts("Trying MSX3BIOS.SYS\n"); if(!(opened=FileOpen(&file,"MSX3BIOSSYS"))) // Try and load MSX3 BIOS first { OSD_Puts("Trying BIOS_M2P.ROM\n"); opened=FileOpen(&file,"BIOS_M2PROM"); // If failure, load MSX2 BIOS. } if(opened) { OSD_Puts("Loading BIOS\n"); int filesize=file.size; unsigned int c=0; int bits; bits=0; c=filesize; while(c) { ++bits; c>>=1; } bits-=9; while(filesize>0) { OSD_ProgressBar(c,bits); if(FileRead(&file,sector_buffer)) { int i; int *p=(int *)§or_buffer; for(i=0;i<(filesize<512 ? filesize : 512) ;i+=4) { int t=*p++; int t1=t&255; int t2=(t>>8)&255; int t3=(t>>16)&255; int t4=(t>>24)&255; HW_HOST(HW_HOST_BOOTDATA)=t4; HW_HOST(HW_HOST_BOOTDATA)=t3; HW_HOST(HW_HOST_BOOTDATA)=t2; HW_HOST(HW_HOST_BOOTDATA)=t1; } } else { OSD_Puts("Read failed\n"); return(0); } FileNextSector(&file); filesize-=512; ++c; } HW_HOST(HW_HOST_CTRL)=HW_HOST_CTRLF_BOOTDONE; // Release SD card and early-terminate any remaining requests for boot data return(1); }
//// UploadKickstart() //// char UploadKickstart(char *name) { int keysize=0; char filename[12]; strncpy(filename, name, 8); // copy base name strcpy(&filename[8], "ROM"); // add extension BootPrint("Checking for Amiga Forever key file:"); if(FileOpen(&file,"ROM KEY")) { keysize=file.size; if(file.size<sizeof(romkey)) { int c=0; while(c<keysize) { FileRead(&file, &romkey[c]); c+=512; FileNextSector(&file); } BootPrint("Loaded Amiga Forever key file"); } else { BootPrint("Amiga Forever keyfile is too large!"); } } BootPrint("Loading file: "); BootPrint(filename); if(minimig_v1()) { if (RAOpen(&romfile, filename)) { if (romfile.size == 0x80000) { // 512KB Kickstart ROM BootPrint("Uploading 512 KB Kickstart..."); PrepareBootUpload(0xF8, 0x08); SendFile(&romfile); return(1); } else if ((romfile.size == 0x8000b) && keysize) { // 512KB Kickstart ROM BootPrint("Uploading 512 KB Kickstart (Probably Amiga Forever encrypted...)"); PrepareBootUpload(0xF8, 0x08); SendFileEncrypted(&romfile,romkey,keysize); return(1); } else if (romfile.size == 0x40000) { // 256KB Kickstart ROM BootPrint("Uploading 256 KB Kickstart..."); PrepareBootUpload(0xF8, 0x04); SendFile(&romfile); return(1); } else if ((romfile.size == 0x4000b) && keysize) { // 256KB Kickstart ROM BootPrint("Uploading 256 KB Kickstart (Probably Amiga Forever encrypted..."); PrepareBootUpload(0xF8, 0x04); SendFileEncrypted(&romfile,romkey,keysize); return(1); } else { BootPrint("Unsupported ROM file size!"); } } else { siprintf(s, "No \"%s\" file!", filename); BootPrint(s); } } else { if (RAOpen(&romfile, filename)) { int i,j; unsigned int adr, size, base=0x180000, offset=0xc00000, data; puts("Uploading 512KB Kickstart ..."); size = ((romfile.file.size)+511)>>9; iprintf("File size: %d.%01dkB\r", romfile.file.size>>10, romfile.file.size&0x3ff); iprintf("["); for (i=0; i<size; i++) { if (!(i&31)) iprintf("*"); RARead(&romfile,sector_buffer,512); EnableOsd(); adr = 0xf80000 + i*512; SPI(OSD_CMD_WR); SPIN(); SPIN(); SPIN(); SPIN(); SPI(adr&0xff); adr = adr>>8; SPI(adr&0xff); adr = adr>>8; SPIN(); SPIN(); SPIN(); SPIN(); SPI(adr&0xff); adr = adr>>8; SPI(adr&0xff); adr = adr>>8; SPIN(); SPIN(); SPIN(); SPIN(); for (j=0; j<512; j=j+4) { SPI(sector_buffer[j+0]); SPI(sector_buffer[j+1]); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); SPI(sector_buffer[j+2]); SPI(sector_buffer[j+3]); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); SPIN(); } DisableOsd(); } iprintf("]\r"); return(1); } }