akkera 102
/
gba_rpc
GameBoy Advance Multiboot & RPC
multiboot.cpp
- Committer:
- akkera102
- Date:
- 2014-12-09
- Revision:
- 0:147f4cedc929
File content as of revision 0:147f4cedc929:
// mbed GBA Loader - Boot up a GameBoy Advance using Multiboot (no cart req.) // // Ken Kaarvik kkaarvik@yahoo.com Nov 13, 2010 // akkera102 Nov 08, 2014(modified) // // mbed(LPC1768) gba serial port(color) // p1-0V 6-GND (blue) // p5-mosi 3-SI (orange) // p6-miso 2-SO (red) // p7-sck 5-SC (green) // // The GBA file that you wish to load into the GBA is stored on the mbed's local file system. // Apply power to the mbed (or reset) before turning on the GBA. #include "multiboot.h" static LocalFileSystem local("local"); static Serial pc(USBTX, USBRX); static SPI spi(p5, p6, p7); uint32_t WriteSPI32(uint32_t w, char* msg) { uint32_t r = WriteSPI32NoDebug(w); pc.printf("0x%08x 0x%08x ; %s\n",r , w, msg); return r; } uint32_t WriteSPI32NoDebug(uint32_t w) { uint16_t w1 = w >> 16; uint16_t w2 = w & 0xffff; uint32_t r; r = spi.write(w1) << 16; r = spi.write(w2) | r; return r; } void WaitSPI32(uint32_t w, uint32_t comp, char* msg) { pc.printf("%s 0x%08x\n", msg, comp); uint32_t r; do { r = WriteSPI32NoDebug(w); wait(0.01); } while(r != comp); } int MultiBoot(char* filename) { spi.format(16, 3); spi.frequency(100000); // 100 kHz FILE *fp = fopen(filename, "rb"); if(fp == NULL) { pc.printf("Err: Can't open file\n"); return 1; } fseek(fp, 0L, SEEK_END); long fsize = (ftell(fp) + 0x0f) & 0xfffffff0; if(fsize > 0x40000) { pc.printf("Err: Max file size 256kB\n"); return 1; } fseek(fp, 0L, SEEK_SET); long fcnt = 0; uint32_t r, w, w2; int i, bit; WaitSPI32(0x00006202, 0x72026202, "Looking for GBA"); r = WriteSPI32(0x00006202, "Found GBA"); r = WriteSPI32(0x00006102, "Recognition OK"); pc.printf("Send Header(NoDebug)\n"); for(i=0; i<=0x5f; i++) { w = getc(fp); w = getc(fp) << 8 | w; fcnt += 2; r = WriteSPI32NoDebug(w); } r = WriteSPI32(0x00006200, "Transfer of header data complete"); r = WriteSPI32(0x00006202, "Exchange master/slave info again"); r = WriteSPI32(0x000063d1, "Send palette data"); r = WriteSPI32(0x000063d1, "Send palette data, receive 0x73hh****"); uint32_t m = ((r & 0x00ff0000) >> 8) + 0xffff00d1; uint32_t h = ((r & 0x00ff0000) >> 16) + 0xf; r = WriteSPI32((((r >> 16) + 0xf) & 0xff) | 0x00006400, "Send handshake data"); r = WriteSPI32((fsize - 0x190) / 4, "Send length info, receive seed 0x**cc****"); uint32_t f = (((r & 0x00ff0000) >> 8) + h) | 0xffff0000; uint32_t c = 0x0000c387; pc.printf("Send encrypted data(NoDebug)\n"); while(fcnt < fsize) { w = getc(fp); w = getc(fp) << 8 | w; w = getc(fp) << 16 | w; w = getc(fp) << 24 | w; w2 = w; for(bit=0; bit<32; bit++) { if((c ^ w) & 0x01) { c = (c >> 1) ^ 0x0000c37b; } else { c = c >> 1; } w = w >> 1; } m = (0x6f646573 * m) + 1; WriteSPI32NoDebug(w2 ^ ((~(0x02000000 + fcnt)) + 1) ^m ^0x43202f2f); fcnt = fcnt + 4; } fclose(fp); for(bit=0; bit<32; bit++) { if((c ^ f) & 0x01) { c =( c >> 1) ^ 0x0000c37b; } else { c = c >> 1; } f = f >> 1; } WaitSPI32(0x00000065, 0x00750065, "Wait for GBA to respond with CRC"); r = WriteSPI32(0x00000066, "GBA ready with CRC"); r = WriteSPI32(c, "Let's exchange CRC!"); pc.printf("CRC ...hope they match!\n"); pc.printf("MulitBoot done\n"); return 0; }