GameBoy Advance Multiboot & Dumper

Dependencies:   SDFileSystem mbed

Revision:
0:66a93ef88e4e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multiboot.cpp	Mon Nov 24 13:28:15 2014 +0000
@@ -0,0 +1,171 @@
+//  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.1);
+
+    } while(r != comp);
+}
+
+int MultiBoot(char* filename) 
+{
+    spi.format(16, 3);
+    spi.frequency(100000);
+
+
+    FILE *fp = fopen(filename, "rb");
+    if(fp == NULL)
+    {
+        pc.printf("Err: Can't open file\n");
+        return EXIT_FAILURE;
+    }
+
+    fseek(fp, 0L, SEEK_END);
+    long fsize = (ftell(fp) + 0x0f) & 0xfffffff0;
+
+    if(fsize > 0x40000)
+    {
+        pc.printf("Err: Max file size 256kB\n");
+        return EXIT_FAILURE;
+    }
+
+    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 EXIT_SUCCESS;
+}