gbpaksramreadwrite.c
7.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*---------------------------------------------------------------------
Copyright (C) 1998, Nintendo.
File gbpaksramreadwrite.c
Coded by Koji Mitsunari. Oct 2, 1997.
Modified by Koji Mitsunari. Jul 28, 1998.
Comments 64GB-PAK SRAM Read/Write for MBC1
$Id:
---------------------------------------------------------------------*/
/**************************************************************************
*
* $Revision: 1.1.1.1 $
* $Date: 2002/05/02 03:27:32 $
* $Source:
*
**************************************************************************/
#include <ultra64.h>
static u8 srambank[MAXCONTROLLERS]; /* GB の SRAM のバンク */
/*------------------------------------------------------------------------*
* 64GBパック MBC1 SRAM アクセス用初期化関数 GbpakSramInit()
*
* [構文]
* #include <ultra64.h>
* extern s32 GbpakSramInit(OSPfs *);
*
* s32 GbpakSramInit(OSPfs *pfs);
*
* [説明]
* 関数 GbpakSramReadWrite()を呼ぶための、初期化関数です。
* MBC1 ゲームボーイ・カートリッジの SRAM のデータを読むための、レジス
* タのセットを行なっています。
* GbpakSramReadWrite()の前には、必ずこの関数を呼ぶ必要があります。
*
* エラーが発生した場合、この関数が返すエラーコードには以下のものがあ
* ります。
*
* PFS_ERR_NOPACK
* 指定したコントローラに 64GBパックが挿し込まれていません。
* PFS_ERR_DEVICE
* 64GBパックではないデバイスがコントローラに差し込まれてい
* ます。
* PFS_ERR_CONTRFAIL
* コントローラとのデータ転送の失敗です。
* コントローラが正しく接続されていないか、あるいは、64GBパッ
* クかコントローラコネクタに異常がある可能性があります。
* PFS_ERR_NO_GBCART
* 64GBパックに GBカートリッジが差し込まれていません。
* PFS_ERR_NEW_GBCART
* GBカートリッジの抜き差しが行なわれました。
*
*------------------------------------------------------------------------*/
s32
GbpakSramInit(OSPfs *pfs)
{
s32 i, ret;
u8 status;
u8 temp[32];
/*--- GBカートリッジが抜き差しされていないか ---*/
ret = osGbpakGetStatus(pfs, &status);
if (ret != 0){
return(ret);
}
/*--- MBC1 のレジスタ 3(0x6000)へのセット ---*/
/*--- これにより、レジスタ 2(0x4000)が SRAM のバンク切り替えになる ---*/
for (i = 0 ; i < BLOCKSIZE ; temp[i++] = 1 );
if ( (ret = osGbpakReadWrite(pfs, OS_WRITE,
0x6000, temp, BLOCKSIZE)) != 0 ) {
return(ret);
}
/*--- MBC1 のレジスタ 0(0x0000)へのセット ---*/
/*--- これにより、SRAM のアクセスが可能になる ---*/
for ( i = 0 ; i < BLOCKSIZE ; temp[i++] = 0 );
temp[BLOCKSIZE-1] = 0x0a;
if ( (ret = osGbpakReadWrite(pfs, OS_WRITE, 0x0000, temp, 32)) != 0 ) {
return(ret);
}
/*--- 現在の SRAM のバンク。最初は不定なので、ダミーの値を入れておく ---*/
srambank[pfs->channel] = 0xff;
/*--- GBカートリッジが抜き差しされていないか ---*/
ret = osGbpakGetStatus(pfs, &status);
/*--- GBカートリッジへの電源が OFF になってしまっていないか ---*/
/*--- (つまり、読み書き中にコントローラごと抜かれてないか) ---*/
if (ret == 0){
if (!(status & OS_GBPAK_POWER)) {
ret = PFS_ERR_CONTRFAIL;
}
}
return(ret);
} /* End of GbpakSramInit */
/*------------------------------------------------------------------------*
* 64GBパック MBC1 SRAM バンク切り替え関数 GbpakSramSetBank()
*
* [構文]
* #include <ultra64.h>
* s32 GbpakSramSetBank(OSPfs *pfs, u8 bank);
*
* [説明]
* 関数 GbpakSramReadWrite()内で呼ばれる、SRAM のバンク切り替え関数で
* す。
*
*------------------------------------------------------------------------*/
static s32
GbpakSramSetBank(OSPfs *pfs, u8 bank)
{
s32 i , ret = 0;
u8 temp[32];
/*--- 書くのは 32 バイト単位なので、32 バイトすべてに ---*/
/*--- 切り替えたい sram の bank の値をセットしておく ---*/
for (i = 0 ; i < BLOCKSIZE ; temp[i++] = bank );
/*--- MBC1 レジスタ 2 をセットして、SRAM のバンクを切り替える ---*/
if ( (ret = osGbpakReadWrite(pfs, OS_WRITE,
0x4000, temp, BLOCKSIZE)) == 0 ) {
/*--- バンク切り替えに成功したときは、そのバンクの値をおいておく ---*/
srambank[pfs->channel] = bank;
}
return(ret);
} /* End of GbpakSramSetBank */
/*------------------------------------------------------------------------*
* 64GBパック MBC1 SRAM アクセス関数 GbpakSramReadWrite()
*
* [構文]
* #include <ultra64.h>
* extern s32 GbpakSramReadWrite(OSPfs *, u16, u32, u8 *, u32);
*
* s32 GbpakSramReadWrite(OSPfs *pfs, u16 flag, u16 address, u8 *buffer,
* u16 size);
*
* [説明]
* 関数 GbpakSramReadWrite()は、ゲームボーイ・カートリッジの SRAM の
* データを読み書きするための関数です。MBC1にのみ対応しています。
*
* flagには、OS_READ または、OS_WRITE を指定します。
* OS_READのときはゲームボーイ・カートリッジからの読み込み、OS_WRITE
* のときはゲームボーイ・カートリッジへの書き込みを行ないます。
* address には、GBカセットの RAM アドレスの値(0x0000〜0x7fff)を
* 指定します。
* sizeには読み書きするバイト数を指定します。
* address と size は32の倍数でなければなりません。
* bufferは、読み書きを行なう RDRAM上のバッファです。
* OSPfs構造体 pfsは 関数 osGbpakInit で初期化されたハンドルです。
*
* エラーが発生した場合、この関数が返すエラーコードには以下のものがあ
* ります。
*
* PFS_ERR_NOPACK
* 指定したコントローラに 64GBパックが挿し込まれていません。
* PFS_ERR_DEVICE
* 64GBパックではないデバイスがコントローラに差し込まれてい
* ます。
* PFS_ERR_CONTRFAIL
* コントローラとのデータ転送の失敗です。
* コントローラが正しく接続されていないか、あるいは、64GBパッ
* クかコントローラコネクタに異常がある可能性があります。
* PFS_ERR_NO_GBCART
* 64GBパックに GBカートリッジが差し込まれていません。
* PFS_ERR_NEW_GBCART
* GBカートリッジの抜き差しが行なわれました。
*
*------------------------------------------------------------------------*/
s32
GbpakSramReadWrite(OSPfs *pfs, u16 flag, u32 address, u8 *buffer, u32 size)
{
s32 ret, addr_end;
u8 status;
u8 bank;
/*--- GBカートリッジが抜き差しされていないか ---*/
ret = osGbpakGetStatus(pfs, &status);
if (ret != 0){
return(ret);
}
/*--- 開始アドレスの上位 3ビットから、SRAM バンクを決定 ---*/
bank = (u8)(address >> 13);
if ( bank != srambank[pfs->channel] ) { /* Check SRAM active bank */
if ((ret = GbpakSramSetBank(pfs, bank)) != 0 ) {
return(ret);
}
}
/* 実際にアクセスするのは 0xa000〜0xbfff までの 0x2000 の領域だから */
address &= 0x1fff;
addr_end = address + size;
while (1) {
if ( addr_end > 0x2000 ) { /* 次のバンクにまたがってしまうとき */
addr_end -= 0x2000; /* 次のバンクの先頭からのアドレス */
/*--- とりあえず、現在のバンクの最後(0xbfff)まで読み書き ---*/
ret = osGbpakReadWrite(pfs, flag, (address+0xa000),
buffer, 0x2000-address);
if (ret != 0 ) break;
/*--- 読み書きしたぶんだけ、RDRAM 側のポインタを進めておく ---*/
buffer += (0x2000-address);
/*--- 次のバンクに切り替え ---*/
if ( (ret = GbpakSramSetBank(pfs, ++bank)) != 0 ) break;
size = addr_end;
address = 0;
} else { /*--- このバンクだけで済む場合 ---*/
ret = osGbpakReadWrite(pfs, flag, (address+0xa000), buffer, size);
break;
}
}
if (ret == 0) {
/*--- GBカートリッジが抜き差しされていないか ---*/
ret = osGbpakGetStatus(pfs, &status);
}
if (ret == 0){
/*--- GBカートリッジへの電源が OFF になってしまっていないか ---*/
/*--- (つまり、読み書き中にコントローラごと抜かれてないか) ---*/
if (!(status & OS_GBPAK_POWER)) {
ret = PFS_ERR_CONTRFAIL;
} else if (status & OS_GBPAK_RSTB_DETECTION) {
ret = PFS_ERR_CONTRFAIL;
}
}
return(ret);
} /* End of GbpakSramReadWrite */