GameBoy Advance Multiboot

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
kek
Date:
Sat Nov 13 10:42:21 2010 +0000
Commit message:

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r b046e1b46227 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Nov 13 10:42:21 2010 +0000
@@ -0,0 +1,204 @@
+//  mbed GBA Loader - Boot up a GameBoy Advance using Multiboot (no cart req.)
+//
+//  Ken Kaarvik   kkaarvik@yahoo.com
+//  Nov 13, 2010
+//
+//  mbed            gba serial port
+//   1-0V           6-0V
+//  p5-mosi         3-SI
+//  p6-miso         2-SO
+//  p7-sck          5-SC
+//  p8-input        1-3V3
+//
+//  p15-analogIn    0-3V3 test voltage pot
+//  p16-analogIn    0-3V3 test voltage pot
+//
+//  note: the GBA does not power the mbed
+//
+//  The GBA file that you wish to load into the GBA is stored on the mbed's local file system.
+//  (Just drag and drop it onto the drive where mbed is located.)
+//  The GBA can be multibooted with a maximum file size of 256kB (the mbed shows up on my
+//  computer as a flash drive with 2MB of memory, room for several GBA files!)
+//
+//  Apply power to the mbed (or reset) before turning on the GBA.
+//
+
+#include "mbed.h"
+
+Serial pc(USBTX, USBRX);    //debug info - see raw data being transferred back and forth as GBA is booting
+
+SPI spi(p5, p6, p7); // mosi, miso, sclk
+
+LocalFileSystem local("local");
+
+DigitalIn gba_present(p8);
+
+DigitalOut myled1(LED1);    //used for my demo program (volt4.gba)
+DigitalOut myled2(LED2);    //used for my demo program (volt4.gba)
+DigitalOut myled3(LED3);    //used for my demo program (volt4.gba)
+DigitalOut myled4(LED4);    //used for my demo program (volt4.gba)
+AnalogIn voltmeter1(p15);   //used for my demo program (volt4.gba)
+AnalogIn voltmeter2(p16);   //used for my demo program (volt4.gba)
+
+unsigned long read_from_gba;
+//unsigned long test_counter;
+
+long writeSPI32bits(long write32)
+{
+    pc.printf("0x%08x ",write32);
+    long read32 = (spi.write(write32>>16))<<16;
+    read32 = (spi.write(write32))|read32;
+    pc.printf("0x%08x ",read32);
+    return  read32;
+}
+
+long writeSPI32bits_nodebug(long write32)
+{
+    long read32 = (spi.write(write32>>16))<<16;
+    read32 = (spi.write(write32))|read32;
+    return  read32;
+}
+
+int main() 
+{
+    // Setup the spi for 8 bit data, high steady state clock,
+    // second edge capture, with a 100 kHz clock rate
+    spi.format(16,3);
+    spi.frequency(100000);
+
+    pc.printf("\n\n\r.....GBA Multiboot Hack......\n\n\r");
+    if (gba_present)
+        pc.printf(".....Please turn off GBA.....\n\r");
+    while(gba_present);    
+    wait(0.2);    
+    if(!gba_present)    
+        pc.printf(".....Please turn on GBA......\n\r");
+    while(!gba_present);            
+    wait(0.2);
+    pc.printf(".....GBA power up detected!..\n\r");        
+
+    FILE *fp = fopen("/local/volt4.gba", "rb");             //*****change .gba file here***** 
+    pc.printf(".....Opening GBA file readonly\r\n");
+
+    fseek(fp, 0L, SEEK_END);                                //get *.gba file length
+    long gba_file_length= ftell(fp);
+    gba_file_length = (gba_file_length+0x0f)&0xfffffff0;    //align length to xfer to 16
+    fseek(fp, 0L, SEEK_SET);
+    pc.printf(".....GBA file length 0x%08x\r\n\n",gba_file_length);    
+    pc.printf("MBED(mstr) GBA(slave) \r\n\n");
+      
+    while(read_from_gba!=0x72026202)
+        {
+        wait(0.01);
+        read_from_gba = writeSPI32bits(0x00006202);
+        pc.printf(" ;Looking for GBA\r\n");        
+        }
+        
+    read_from_gba = writeSPI32bits(0x00006202);
+    pc.printf(" ;Found GBA\r\n");
+
+    read_from_gba = writeSPI32bits(0x00006102);
+    pc.printf(" ;Recognition ok\r\n");
+
+    int i;
+    for(int Counter=0;Counter<=0x5f;Counter++)
+    {
+        i = getc(fp);                //Read in 16 bits of .gba file
+        i = getc(fp)<<8|i;           //Read in 16 bits of .gba file
+
+        read_from_gba =    writeSPI32bits_nodebug(0x0000ffff&i);
+       // pc.printf(" ;send header a\r\n");
+    }
+
+    read_from_gba = writeSPI32bits(0x00006200);
+    pc.printf(" ;Transfer of header data complete\r\n");
+ 
+    read_from_gba = writeSPI32bits(0x00006202);
+    pc.printf(" ;Exchange master/slave info again\r\n");
+    
+    read_from_gba = writeSPI32bits(0x000063d1);  
+    pc.printf(" ;Send palette data\r\n");
+
+    read_from_gba = writeSPI32bits(0x000063d1);  
+    pc.printf(" ;Send palette data, receive 0x73hh****\r\n");
+
+    long m    =    ((read_from_gba&0x00ff0000)>>8)+0xffff00d1;
+    long hh    =    ((read_from_gba&0x00ff0000)>>16)+0xf;
+
+    writeSPI32bits((((read_from_gba>>16)+0x0000000f)&0xff)|0x00006400);
+    pc.printf(" ;Send handshake data\r\n");
+
+    read_from_gba = writeSPI32bits((gba_file_length-0x190)/4);
+    pc.printf(" ;Send length info, receive seed 0x**cc****\r\n");
+
+    long    c    =    0x0000c387;
+    long    f   =   ((((read_from_gba&0x00ff0000)>>8)+hh)+0x00)|0xffff0000;
+
+    pc.printf("                       ;Send encrypted data (takes too long to show it all!)\r\n");
+
+    unsigned int gba_file_location = 0xc0;
+    while(gba_file_location<gba_file_length)
+    {    
+        long gba_data = getc(fp);               //Read in 32 bits of .gba file
+        gba_data = getc(fp)<<8|gba_data;               
+        gba_data = getc(fp)<<16|gba_data;        
+        gba_data = getc(fp)<<24|gba_data;        
+        
+        long gba_data2 = gba_data;
+       
+        for(int bit=0;bit<32;bit++)
+        {                
+            if((c^gba_data)&0x01)
+                c =(c>>1)^0x0000c37b;
+            else
+                c = c>>1;      
+            gba_data = gba_data>>1;        
+         }            
+         m = (0x6f646573*m)+1;
+         writeSPI32bits_nodebug(gba_data2^((~(0x02000000+gba_file_location))+1)^m^0x43202f2f);//This line or next two
+//         writeSPI32bits(gba_data2^((~(0x02000000+gba_file_location))+1)^m^0x43202f2f);   //*****Uncomment two line to see all data being transfered*****
+//         pc.printf(" ;\n\r");                                                            //*****Uncomment two line to see all data being transfered*****
+         gba_file_location=gba_file_location+4;
+     }
+
+    for(int bit=0;bit<32;bit++)
+    {
+        if((c^f)&0x01)
+            c =(c>>1)^0x0000c37b;
+        else
+            c = c>>1;               
+        f = f>>1;
+    }
+        
+    while (writeSPI32bits(0x00000065)!=0x00750065)
+    {
+        pc.printf(" ;Wait for GBA to respond with CRC\n\r");
+    }
+    
+    pc.printf(" ;GBA ready with CRC\n\r");
+    
+    writeSPI32bits(0x00000066);
+    
+    pc.printf(" ;Let's exchange CRC!\n\r");
+
+    writeSPI32bits(c);
+
+    pc.printf(" ;CRC ...hope they match!\n\r");
+    pc.printf("                       ;All done!\n\r\n");
+
+    fclose(fp);         //****Done with multiboot********************************************************
+    
+                        //****Following is code to talk to GBA running my custom program (volt4.gba)*****
+    
+    while(1)   //read in analog values on p15 and p16, only use 9 bits from both, pack up and send to GBA 
+    {
+    read_from_gba = writeSPI32bits((voltmeter1.read_u16()>>7)|((voltmeter2.read_u16()&0xff80)<<2));
+    pc.printf("\r");
+    read_from_gba =(~read_from_gba)&0x3ff;
+    myled1 = (read_from_gba & 0x1); //turn on led1 when "A" button on GBA is pressed
+    myled2 = (read_from_gba & 0x2); //B
+    myled3 = (read_from_gba & 0x4); //Select
+    myled4 = (read_from_gba & 0x8); //Start
+    }
+
+}
diff -r 000000000000 -r b046e1b46227 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Nov 13 10:42:21 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e