about summary refs log tree commit diff stats
path: root/gba/source
diff options
context:
space:
mode:
Diffstat (limited to 'gba/source')
-rw-r--r--gba/source/libSave.c114
-rw-r--r--gba/source/main.c80
2 files changed, 63 insertions, 131 deletions
diff --git a/gba/source/libSave.c b/gba/source/libSave.c index d545a5f..e3bda1d 100644 --- a/gba/source/libSave.c +++ b/gba/source/libSave.c
@@ -4,92 +4,18 @@
4 routine with a pointer to an appropriately sized array of data to 4 routine with a pointer to an appropriately sized array of data to
5 be read from or written to the cartridge. 5 be read from or written to the cartridge.
6 Data types are from wintermute's gba_types.h libgba library. 6 Data types are from wintermute's gba_types.h libgba library.
7 Original file from SendSave by Chishm
7*/ 8*/
8 9
9#include <stdio.h> 10#include <stdio.h>
10#include <stdlib.h> 11#include <stdlib.h>
11#include <string.h> 12#include <string.h>
12//--------------------------------------------------------------------------------- 13#include <gba_dma.h>
13#ifndef _gba_types_h_
14#define _gba_types_h_
15//---------------------------------------------------------------------------------
16
17//---------------------------------------------------------------------------------
18// Data types
19//---------------------------------------------------------------------------------
20/** Unsigned 8 bit value
21
22*/
23typedef unsigned char u8;
24/** Unsigned 16 bit value
25
26*/
27typedef unsigned short int u16;
28/** Unsigned 32 bit value
29
30*/
31typedef unsigned int u32;
32 14
33/** signed 8 bit value 15#define EEPROM_ADDRESS (0xDFFFF00)
34 16#define REG_EEPROM *(vu16 *)(EEPROM_ADDRESS)
35*/ 17#define REG_DMA3CNT_H *(vu16 *)(REG_BASE + 0x0de)
36typedef signed char s8; 18#define REG_WAITCNT *(vu16 *)(REG_BASE + 0x204)
37/** Signed 16 bit value
38
39*/
40typedef signed short int s16;
41/** Signed 32 bit value
42
43*/
44typedef signed int s32;
45
46/** Unsigned volatile 8 bit value
47
48*/
49typedef volatile u8 vu8;
50/** Unsigned volatile 16 bit value
51
52*/
53typedef volatile u16 vu16;
54/** Unsigned volatile 32 bit value
55
56*/
57typedef volatile u32 vu32;
58
59/** Unsigned volatile 8 bit value
60
61*/
62typedef volatile s8 vs8;
63/** Signed volatile 16 bit value
64
65*/
66typedef volatile s16 vs16;
67/** Signed volatile 32 bit value
68
69*/
70typedef volatile s32 vs32;
71
72#ifndef __cplusplus
73/** C++ compatible bool for C
74
75*/
76typedef enum { false, true } bool;
77#endif
78
79//---------------------------------------------------------------------------------
80#endif // data types
81//---------------------------------------------------------------------------------
82
83
84#define EEPROM_ADDRESS (volatile u16*)0xDFFFF00
85#define SRAM_ADDRESS (volatile u16*)0x0E000000
86#define FLASH_1M_ADDRESS (volatile u16*)0x09FE0000
87#define REG_EEPROM (*(volatile u16*)0xDFFFF00)
88#define REG_DM3SAD (*(volatile u32*)0x40000D4)
89#define REG_DM3DAD (*(volatile u32*)0x40000D8)
90#define REG_DM3CNT (*(volatile u32*)0x40000DC)
91#define REG_DM3CNT_H (*(volatile u16*)0x40000DE)
92#define REG_WAITCNT (*(volatile u16*)0x4000204)
93 19
94//----------------------------------------------------------------------- 20//-----------------------------------------------------------------------
95// Common EEPROM Routines 21// Common EEPROM Routines
@@ -98,19 +24,19 @@ typedef enum { false, true } bool;
98void EEPROM_SendPacket( u16* packet, int size ) 24void EEPROM_SendPacket( u16* packet, int size )
99{ 25{
100 REG_WAITCNT = (REG_WAITCNT & 0xF8FF) | 0x0300; 26 REG_WAITCNT = (REG_WAITCNT & 0xF8FF) | 0x0300;
101 REG_DM3SAD = (u32)packet; 27 REG_DMA3SAD = (u32)packet;
102 REG_DM3DAD = (u32)EEPROM_ADDRESS; 28 REG_DMA3DAD = EEPROM_ADDRESS;
103 REG_DM3CNT = 0x80000000 + size; 29 REG_DMA3CNT = 0x80000000 + size;
104 while((REG_DM3CNT_H & 0x8000) != 0) ; 30 while((REG_DMA3CNT_H & 0x8000) != 0) ;
105} 31}
106 32
107void EEPROM_ReceivePacket( u16* packet, int size ) 33void EEPROM_ReceivePacket( u16* packet, int size )
108{ 34{
109 REG_WAITCNT = (REG_WAITCNT & 0xF8FF) | 0x0300; 35 REG_WAITCNT = (REG_WAITCNT & 0xF8FF) | 0x0300;
110 REG_DM3SAD = (u32)EEPROM_ADDRESS; 36 REG_DMA3SAD = EEPROM_ADDRESS;
111 REG_DM3DAD = (u32)packet; 37 REG_DMA3DAD = (u32)packet;
112 REG_DM3CNT = 0x80000000 + size; 38 REG_DMA3CNT = 0x80000000 + size;
113 while((REG_DM3CNT_H & 0x8000) != 0) ; 39 while((REG_DMA3CNT_H & 0x8000) != 0) ;
114} 40}
115 41
116//----------------------------------------------------------------------- 42//-----------------------------------------------------------------------
@@ -213,9 +139,6 @@ void GetSave_EEPROM_512B(u8* data)
213 volatile u8 x; 139 volatile u8 x;
214 u32 sleep; 140 u32 sleep;
215 141
216 // Set up waitstates for EEPROM access etc.
217 *(volatile unsigned short *)0x04000204 = 0x4317;
218
219 for (x=0;x<64;++x){ 142 for (x=0;x<64;++x){
220 EEPROM_Read_512B(x,&data[x*8]); 143 EEPROM_Read_512B(x,&data[x*8]);
221 for(sleep=0;sleep<512000;sleep++); 144 for(sleep=0;sleep<512000;sleep++);
@@ -229,9 +152,6 @@ void PutSave_EEPROM_512B(u8* data)
229 volatile u8 x; 152 volatile u8 x;
230 u32 sleep; 153 u32 sleep;
231 154
232 // Set up waitstates for EEPROM access etc.
233 *(volatile unsigned short *)0x04000204 = 0x4317;
234
235 for (x=0;x<64;x++){ 155 for (x=0;x<64;x++){
236 EEPROM_Write_512B(x,&data[x*8]); 156 EEPROM_Write_512B(x,&data[x*8]);
237 for(sleep=0;sleep<512000;sleep++); 157 for(sleep=0;sleep<512000;sleep++);
@@ -354,9 +274,6 @@ void GetSave_EEPROM_8KB(u8* data)
354 volatile u16 x; 274 volatile u16 x;
355 u32 sleep; 275 u32 sleep;
356 276
357 // Set up waitstates for EEPROM access etc.
358 *(volatile unsigned short *)0x04000204 = 0x4317;
359
360 for (x=0;x<1024;x++){ 277 for (x=0;x<1024;x++){
361 EEPROM_Read_8KB(x,&data[x*8]); 278 EEPROM_Read_8KB(x,&data[x*8]);
362 for(sleep=0;sleep<512000;sleep++); 279 for(sleep=0;sleep<512000;sleep++);
@@ -371,9 +288,6 @@ void PutSave_EEPROM_8KB(u8* data)
371 volatile u16 x; 288 volatile u16 x;
372 u32 sleep; 289 u32 sleep;
373 290
374 // Set up waitstates for EEPROM access etc.
375 *(volatile unsigned short *)0x04000204 = 0x4317;
376
377 for (x=0;x<1024;x++){ 291 for (x=0;x<1024;x++){
378 EEPROM_Write_8KB(x,&data[x*8]); 292 EEPROM_Write_8KB(x,&data[x*8]);
379 for(sleep=0;sleep<512000;sleep++); 293 for(sleep=0;sleep<512000;sleep++);
diff --git a/gba/source/main.c b/gba/source/main.c index 567165a..49cf2a1 100644 --- a/gba/source/main.c +++ b/gba/source/main.c
@@ -1,14 +1,19 @@
1 1/*
2#include <gba_console.h> 2 * Copyright (C) 2016 FIX94
3#include <gba_video.h> 3 *
4#include <gba_interrupt.h> 4 * This software may be modified and distributed under the terms
5#include <gba_systemcalls.h> 5 * of the MIT license. See the LICENSE file for details.
6#include <gba_input.h> 6 */
7#include <gba_sio.h> 7#include <gba.h>
8#include <stdio.h> 8#include <stdio.h>
9#include <stdlib.h> 9#include <stdlib.h>
10#include "libSave.h" 10#include "libSave.h"
11 11
12#define REG_WAITCNT *(vu16 *)(REG_BASE + 0x204)
13#define JOY_WRITE 2
14#define JOY_READ 4
15#define JOY_RW 6
16
12u8 save_data[0x20000] __attribute__ ((section (".sbss"))); 17u8 save_data[0x20000] __attribute__ ((section (".sbss")));
13 18
14s32 getGameSize(void) 19s32 getGameSize(void)
@@ -33,8 +38,7 @@ s32 getGameSize(void)
33 } 38 }
34 return i; 39 return i;
35} 40}
36#define JOY_WRITE 2 41
37#define JOY_READ 4
38//--------------------------------------------------------------------------------- 42//---------------------------------------------------------------------------------
39// Program entry point 43// Program entry point
40//--------------------------------------------------------------------------------- 44//---------------------------------------------------------------------------------
@@ -52,31 +56,32 @@ int main(void) {
52 // ansi escape sequence to set print co-ordinates 56 // ansi escape sequence to set print co-ordinates
53 // /x1b[line;columnH 57 // /x1b[line;columnH
54 u32 i; 58 u32 i;
55 iprintf("\x1b[9;10HROM Dumper\n"); 59 iprintf("\x1b[9;2HGBA Link Cable Dumper v1.3\n");
56 iprintf("\x1b[10;5HPlease look at the TV\n"); 60 iprintf("\x1b[10;4HPlease look at the TV\n");
57 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 61 // disable this, needs power
58 u32 prevIrqMask = REG_IME; 62 SNDSTAT = 0;
63 SNDBIAS = 0;
64 // Set up waitstates for EEPROM access etc.
65 REG_WAITCNT = 0x0317;
66 //clear out previous messages
67 REG_HS_CTRL |= JOY_RW;
59 while (1) { 68 while (1) {
60 if((REG_HS_CTRL&JOY_READ)) 69 if((REG_HS_CTRL&JOY_READ))
61 { 70 {
62 irqDisable(IRQ_VBLANK); 71 REG_HS_CTRL |= JOY_RW;
63 REG_IME = 0;
64 REG_HS_CTRL |= (JOY_WRITE|JOY_READ);
65 s32 gamesize = getGameSize(); 72 s32 gamesize = getGameSize();
66 u32 savesize = SaveSize(save_data,gamesize); 73 u32 savesize = SaveSize(save_data,gamesize);
67 REG_JOYTR = gamesize; 74 REG_JOYTR = gamesize;
68 //wait for a cmd receive for safety 75 //wait for a cmd receive for safety
69 while((REG_HS_CTRL&JOY_WRITE) == 0) ; 76 while((REG_HS_CTRL&JOY_WRITE) == 0) ;
70 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 77 REG_HS_CTRL |= JOY_RW;
71 REG_JOYTR = savesize; 78 REG_JOYTR = savesize;
72 //wait for a cmd receive for safety 79 //wait for a cmd receive for safety
73 while((REG_HS_CTRL&JOY_WRITE) == 0) ; 80 while((REG_HS_CTRL&JOY_WRITE) == 0) ;
74 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 81 REG_HS_CTRL |= JOY_RW;
75 if(gamesize == -1) 82 if(gamesize == -1)
76 { 83 {
77 REG_JOYTR = 0; 84 REG_JOYTR = 0;
78 REG_IME = prevIrqMask;
79 irqEnable(IRQ_VBLANK);
80 continue; //nothing to read 85 continue; //nothing to read
81 } 86 }
82 //game in, send header 87 //game in, send header
@@ -84,32 +89,38 @@ int main(void) {
84 { 89 {
85 REG_JOYTR = *(vu32*)(0x08000000+i); 90 REG_JOYTR = *(vu32*)(0x08000000+i);
86 while((REG_HS_CTRL&JOY_READ) == 0) ; 91 while((REG_HS_CTRL&JOY_READ) == 0) ;
87 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 92 REG_HS_CTRL |= JOY_RW;
88 } 93 }
89 REG_JOYTR = 0; 94 REG_JOYTR = 0;
90 //wait for other side to choose 95 //wait for other side to choose
91 while((REG_HS_CTRL&JOY_WRITE) == 0) ; 96 while((REG_HS_CTRL&JOY_WRITE) == 0) ;
92 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 97 REG_HS_CTRL |= JOY_RW;
93 u32 choseval = REG_JOYRE; 98 u32 choseval = REG_JOYRE;
94 if(choseval == 0) 99 if(choseval == 0)
95 { 100 {
96 REG_JOYTR = 0; 101 REG_JOYTR = 0;
97 REG_IME = prevIrqMask;
98 irqEnable(IRQ_VBLANK);
99 continue; //nothing to read 102 continue; //nothing to read
100 } 103 }
101 else if(choseval == 1) 104 else if(choseval == 1)
102 { 105 {
106 //disable interrupts
107 u32 prevIrqMask = REG_IME;
108 REG_IME = 0;
103 //dump the game 109 //dump the game
104 for(i = 0; i < gamesize; i+=4) 110 for(i = 0; i < gamesize; i+=4)
105 { 111 {
106 REG_JOYTR = *(vu32*)(0x08000000+i); 112 REG_JOYTR = *(vu32*)(0x08000000+i);
107 while((REG_HS_CTRL&JOY_READ) == 0) ; 113 while((REG_HS_CTRL&JOY_READ) == 0) ;
108 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 114 REG_HS_CTRL |= JOY_RW;
109 } 115 }
116 //restore interrupts
117 REG_IME = prevIrqMask;
110 } 118 }
111 else if(choseval == 2) 119 else if(choseval == 2)
112 { 120 {
121 //disable interrupts
122 u32 prevIrqMask = REG_IME;
123 REG_IME = 0;
113 //backup save 124 //backup save
114 switch (savesize){ 125 switch (savesize){
115 case 0x200: 126 case 0x200:
@@ -130,16 +141,19 @@ int main(void) {
130 default: 141 default:
131 break; 142 break;
132 } 143 }
144 //restore interrupts
145 REG_IME = prevIrqMask;
146 //say gc side we read it
133 REG_JOYTR = savesize; 147 REG_JOYTR = savesize;
134 //wait for a cmd receive for safety 148 //wait for a cmd receive for safety
135 while((REG_HS_CTRL&JOY_WRITE) == 0) ; 149 while((REG_HS_CTRL&JOY_WRITE) == 0) ;
136 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 150 REG_HS_CTRL |= JOY_RW;
137 //send the save 151 //send the save
138 for(i = 0; i < savesize; i+=4) 152 for(i = 0; i < savesize; i+=4)
139 { 153 {
140 REG_JOYTR = *(vu32*)(save_data+i); 154 REG_JOYTR = *(vu32*)(save_data+i);
141 while((REG_HS_CTRL&JOY_READ) == 0) ; 155 while((REG_HS_CTRL&JOY_READ) == 0) ;
142 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 156 REG_HS_CTRL |= JOY_RW;
143 } 157 }
144 } 158 }
145 else if(choseval == 3) 159 else if(choseval == 3)
@@ -149,9 +163,12 @@ int main(void) {
149 for(i = 0; i < savesize; i+=4) 163 for(i = 0; i < savesize; i+=4)
150 { 164 {
151 while((REG_HS_CTRL&JOY_WRITE) == 0) ; 165 while((REG_HS_CTRL&JOY_WRITE) == 0) ;
152 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 166 REG_HS_CTRL |= JOY_RW;
153 *(vu32*)(save_data+i) = REG_JOYRE; 167 *(vu32*)(save_data+i) = REG_JOYRE;
154 } 168 }
169 //disable interrupts
170 u32 prevIrqMask = REG_IME;
171 REG_IME = 0;
155 //write it 172 //write it
156 switch (savesize){ 173 switch (savesize){
157 case 0x200: 174 case 0x200:
@@ -172,14 +189,15 @@ int main(void) {
172 default: 189 default:
173 break; 190 break;
174 } 191 }
192 //restore interrupts
193 REG_IME = prevIrqMask;
194 //say gc side we're done
175 REG_JOYTR = 0; 195 REG_JOYTR = 0;
176 //wait for a cmd receive for safety 196 //wait for a cmd receive for safety
177 while((REG_HS_CTRL&JOY_WRITE) == 0) ; 197 while((REG_HS_CTRL&JOY_WRITE) == 0) ;
178 REG_HS_CTRL |= (JOY_WRITE|JOY_READ); 198 REG_HS_CTRL |= JOY_RW;
179 } 199 }
180 REG_JOYTR = 0; 200 REG_JOYTR = 0;
181 REG_IME = prevIrqMask;
182 irqEnable(IRQ_VBLANK);
183 } 201 }
184 Halt(); 202 Halt();
185 } 203 }