createleomanager.c
4.47 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
#include <ultra64.h>
#include "osint.h"
#include "leodrive.h"
#ifndef _LONGCMD
#include <leo.h>
#else
#include <leosp.h>
#endif
#ifndef INIT_DISK /* カセット起動 */
#define __LEO_DRIVE_A 3
#define __LEO_DRIVE_ADASH 5
#define __LEO_DRIVE_C 1
#define __LEO_DRIVE_D 4
#define JAPAN 0xe848d316
#define USA 0x2263ee56
#endif /* not INIT_DISK */
#define IPL_COUNTRY_CODE 0x0009ff00
#define CODE_JAPAN 0xc3
#define CODE_USA 0x04
extern s32 __leoActive;
extern LEOVersion __leoVersion;
/* export from ISR */
extern char leoDiskStack[];
extern s32 __osLeoInterrupt(void);
#ifndef INIT_DISK /* カセット起動 */
/* export from leo device driver */
extern u32 LEO_country_code;
extern s32 __leoSetReset(void);
#endif /* not INIT_DISK */
#ifndef INIT_DISK
# ifdef INIT_JAPAN
s32 LeoCJCreateLeoManager(OSPri comPri, OSPri intPri,
OSMesg *cmdBuf, s32 cmdMsgCnt)
# else /* INIT_JAPAN */
s32 LeoCACreateLeoManager(OSPri comPri, OSPri intPri,
OSMesg *cmdBuf, s32 cmdMsgCnt)
# endif /* INIT_JAPAN */
#else /* INIT_DISK */
s32 LeoCreateLeoManager(OSPri comPri, OSPri intPri,
OSMesg *cmdBuf, s32 cmdMsgCnt)
#endif /* INIT_DISK */
{
OSPiHandle *driveRomHandle;
OSPiHandle *leoDiskHandle;
volatile LEOCmdInquiry cmdBlockInq;
volatile LEOCmd cmdBlockID;
LEODiskID thisID;
u32 stat, data;
/* If Leo Manager is already running, simply return */
if (__leoActive)
return 0;
/*
* ハンドラー取得の前に、ドライブの存在を確認
*/
if (! LeoDriveExist() )
return LEO_ERROR_DEVICE_COMMUNICATION_FAILURE;
/*
* Get the handlers to access drive rom and disk
*/
leoDiskHandle = osLeoDiskInit();
driveRomHandle = osDriveRomInit();
__leoActive = 1;
/*
* ISR の関数登録およびスタック登録(例外ハンドラに対して)
*/
__osSetHWIntrRoutine((OSHWIntr)1, __osLeoInterrupt,
(void *)(leoDiskStack + 4080));
/*
* Create command and interrupt threads
*/
leoInitialize(comPri, intPri, cmdBuf, cmdMsgCnt);
#ifndef INIT_DISK
if (osResetType == 1)
{
/*
* NMI occurred. Reset the drive.
*/
__leoSetReset();
}
#endif /* not INIT_DISK */
/*
* Now, read the version number of the hardware in advance.
*/
/*
* Fill up command block
*/
cmdBlockInq.header.command = LEO_COMMAND_INQUIRY;
cmdBlockInq.header.reserve1 = 0;
cmdBlockInq.header.control = 0;
cmdBlockInq.header.reserve3 = 0;
leoCommand((void *)&cmdBlockInq);
/*
* dummy code for security
*/
{
volatile s32 dummy;
#ifdef INIT_JAPAN
dummy = (s32)( (u32)&cmdBlockInq & 0x00ffffff );
while(dummy > 0)
dummy -= (s32)( ((u32)__leoSetReset & 0x00ffffff) | 0x00403df4 );
#else
dummy = (s32)( (u32)__osSetHWIntrRoutine & 0x00a48d3c );
while(dummy < 0xe00000)
dummy += (s32)( ( ((u32)leoCommand & 0x000000ff) | 0x8a ) << 16 );
#endif
}
while(cmdBlockInq.header.status == LEO_STATUS_BUSY)
;
if(cmdBlockInq.header.status != LEO_STATUS_GOOD)
return (cmdBlockInq.header.sense);
__leoVersion.drive = cmdBlockInq.version;
__leoVersion.driver = LEO_SW_VERSION;
__leoVersion.deviceType = cmdBlockInq.dev_type;
__leoVersion.ndevices = cmdBlockInq.dev_num;
#ifndef INIT_DISK /* カセット起動の場合 */
if( (__leoVersion.drive & 0x0f) == __LEO_DRIVE_D )
{
LEO_country_code = 0;
}
#ifdef _WRITER
else if( ((__leoVersion.drive & 0x0f) == __LEO_DRIVE_A) ||
((__leoVersion.drive & 0x0f) == __LEO_DRIVE_ADASH) ||
((__leoVersion.drive & 0x0f) == __LEO_DRIVE_C) )
#else
else if( ((__leoVersion.drive & 0x0f) == __LEO_DRIVE_A) ||
((__leoVersion.drive & 0x0f) == __LEO_DRIVE_C) )
#endif
{
osEPiReadIo(driveRomHandle, (u32)IPL_COUNTRY_CODE, (u32 *)&data);
data = (data & 0xff000000) >> 24;
#ifdef INIT_JAPAN
/*
* dummy code for security
*/
{
volatile u32 dummy;
dummy = 0x3ed98f23;
if (data != CODE_JAPAN)
for(;;);
dummy *= data;
dummy -= (u32)&cmdBlockInq;
}
LEO_country_code = JAPAN;
#else /* i.e. INIT_USA currently */
/*
* dummy code for security
*/
{
volatile u32 dummy;
if (data != CODE_USA)
for(;;);
dummy = 0x32f8eb20;
/*
* 意味のあるコード
*/
LEO_country_code = USA;
dummy += (u32)&__leoActive;
}
#endif /* INIT_JAPAN */
} /* else if (drive = A drive) or (drive = C drive) */
else /* error */
{
for(;;);
}
#endif /* not INIT_DISK */
return 0;
}