leoutil.c
5.65 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
/*
* F i l e N a m e : l e o u t i l . c
*
****************************************************************************
* (C) Copyright ALPS Electric Co., Ltd. 1995-1996
****************************************************************************
* Version:
*
* ver date
* ---- --------
* 1.06 '96-09-20 Change device-driver support is new format only .
* Change defect cylinder calculate .
* 1.05 '96-09-10 Support new format DISK ( max 12 defect per zone ) .
* Change defect cylinder calculate .
* Change LEOZONE_SCYL_TBL[] -> LEOZONE_SCYL_TBL[][] .
* 1.04 '96-08-27 See LEO_country_code to check system sector size to remove KAIHATU definition.
* 1.03 '96-06-11 Add LEOtgt_param.sec_bytes,.blk_byte calc in leoLba_to_phys().
* 1.02 '96-04-05 Change LEO_TBL .
* 1.01 '96-02-27 Rename file name util.c to leoutil.c .
* 1.00 '95-12-20 Initial Revision.
****************************************************************************
*/
#include <ultra64.h>
#include "leodefine.h"
#include "leodrive.h"
#include "leomacro.h"
/*************************************/
/* PROTOTYPE */
/*************************************/
u16 leoLba_to_phys(u32 lba);
u16 leoLba_to_vzone(u32 lba);
/*************************************/
/* EXTERNAL FUNCTIONS */
/*************************************/
/*************************************/
/* EXTERNAL RAMS */
/*************************************/
extern u16 LEOVZONE_TBL[DISK_TYPES][VZONES_PER_DRV];
extern u8 LEOVZONE_PZONEHD_TBL[DISK_TYPES][VZONES_PER_DRV];
extern u16 LEOZONE_SCYL_TBL[VZONES_PER_DRV];
extern u16 LEOZONE_OUTERCYL_TBL[(ZONES_PER_DRV-1)];
extern struct tgt_param_form LEOtgt_param;
extern union leo_sys_form LEO_sys_data;
extern u8 LEOdisk_type;
extern u8 LEOBYTE_TBL1[ZONES_PER_DRV];
extern u16 LEOBYTE_TBL2[ZONES_PER_DRV];
extern union data_trans_form LEO_country_code;
/* ==========================================================================
* Function : leoLba_to_phys
* --------------------------------------------------------------------------
* Description : TRANSLATE LBA TO PHYSICAL PARMETER
* --------------------------------------------------------------------------
* IN : LEOdisk_type
* OUT : tgt_param
* ARG : lba
* RET : 0 .. GOOD
* : NOT 0 .. NOT GOOD
* ==========================================================================
*/
u16 leoLba_to_phys(u32 lba)
{
u16 vzone_num;
u16 zone_slba;
u16 zone_scyl;
u16 zone_tk;
u16 bad_tk_num;
u32 counter;
u16 def_offset;
u16 defect;
u8 def_zone_no;
/*
* Calc accessable block in track
*/
LEOtgt_param.rdwr_blocks = (u32)0x02 - (lba & (u32)0x01);
/*
* Calc start block
*/
switch (lba & (u32)0x03)
{
case 0: /* start block = 0 */
case 3:
LEOtgt_param.start_block = (u16)0x00;
break;
default: /* start block = 1 */
LEOtgt_param.start_block = (u16)0x01;
break;
}
/*
* Calc cylinder/head.(no defect)
*/
/* calc zone */
vzone_num = leoLba_to_vzone(lba);
LEOtgt_param.zone = def_zone_no = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone_num];
LEOtgt_param.head = 0;
if (LEOtgt_param.zone > (u8)7)
{
LEOtgt_param.zone -= (u8)7;
LEOtgt_param.head = 1;
}
/* zone start cylinder */
zone_scyl = LEOZONE_SCYL_TBL[def_zone_no];
/* calc cylinder address in zone */
if (vzone_num)
{
zone_slba = LEOVZONE_TBL[LEOdisk_type][vzone_num - 1];
}
else
{
zone_slba = 0;
}
zone_tk = (lba - zone_slba) / 2;
if (LEOtgt_param.head)
{
/* seek innter to outer in side 1 */
LEOtgt_param.cylinder = zone_scyl - zone_tk;
zone_scyl = LEOZONE_OUTERCYL_TBL[LEOtgt_param.zone-1];
}
else
{
/* seek outer to inner in side 0 */
LEOtgt_param.cylinder = zone_scyl + zone_tk;
}
/*
* defect
*/
/* Calc defect num */
if (def_zone_no)
{
def_offset = LEO_sys_data.param.defect_num[def_zone_no - 1];
}
else
{
def_offset = 0;
}
bad_tk_num = LEO_sys_data.param.defect_num[def_zone_no] - def_offset;
while (bad_tk_num)
{
defect = (u16)LEO_sys_data.param.defect_data[def_offset] + zone_scyl;
if (LEOtgt_param.cylinder < defect)
break;
LEOtgt_param.cylinder++;
def_offset++;
bad_tk_num--;
}
LEOtgt_param.sec_bytes = LEOBYTE_TBL1[LEOtgt_param.zone];
LEOtgt_param.blk_bytes = LEOBYTE_TBL2[LEOtgt_param.zone];
if ((LEO_country_code.u32_data == 0) && (lba < SYS_UNCORR_LBA))
{
LEOtgt_param.sec_bytes = SEC_SIZE_SYSTEM;
LEOtgt_param.blk_bytes = SEC_SIZE_SYSTEM*USR_SECS_PER_BLK;
}
return(FUNC_OK);
}
/* ==========================================================================
* FUNCTION : leoLba_to_vzone
* --------------------------------------------------------------------------
* DESCRIPTION : calc logical zone from LBA
* --------------------------------------------------------------------------
* IN : LEOdisk_type
* OUT : ̵
* ARG : lba
* RET : logical zone (015)
* : if error then return 0xff
* ==========================================================================
*/
u16 leoLba_to_vzone(u32 lba)
{
u16 i;
u16 *ptr;
ptr = &LEOVZONE_TBL[LEOdisk_type][0];
for (i=0; i<16 ; i++)
{
if (lba < *ptr)
return(i);
ptr++;
}
return(FUNC_NG);
}