PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
i28f640j5.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "acflash_internal.h"
12
13static int flash_erase(flash_addr_t addr);
14static int flash_program(flash_addr_t addr, const flash_data_t *buf, int size);
15static int flash_reset(flash_addr_t addr);
16static int flash_status(flash_addr_t addr);
17
18static struct flash_ops ops_30 = {
19 "Intel 28F640J5", 131072u, 64u, 0, &flash_erase, &flash_program, &flash_reset, &flash_status};
20
21static int flash_wait(flash_ptr_t ptr, int tick, int count)
22{
23 int threshold;
24
25 threshold = tick - 1;
26 while ( threshold >= 0 )
27 {
28 int sr;
29
30 *ptr = 0x70;
31 sr = *ptr;
32 if ( (sr & 0x80) == 0 )
33 sr = -116;
34 if ( sr >= 0 )
35 return sr;
36 threshold--;
37 }
38 do
39 {
40 int sr_v3;
41
42 DelayThread(tick);
43 *ptr = 0x70;
44 sr_v3 = *ptr;
45 if ( (sr_v3 & 0x80) == 0 )
46 sr_v3 = -116;
47 if ( sr_v3 >= 0 )
48 return sr_v3;
49 --count;
50 } while ( count >= 0 );
51 return -116;
52}
53
54static int flash_erase(flash_addr_t addr)
55{
56 *(volatile acUint16 *)addr = 0x20;
57 *(volatile acUint16 *)addr = 0xD0;
58 return ((acUint32)(~flash_wait((flash_ptr_t)addr, 400, 2)) >> 31) & 0x20000;
59}
60
61static int flash_program(flash_addr_t addr, const flash_data_t *buf, int size)
62{
63 int rest;
64 int xlen;
65 int count;
66 int threshold;
67 int v12;
68 unsigned int v14;
69 int xlen_v9;
70
71 rest = size;
72 while ( 1 )
73 {
74 int blen;
75
76 if ( rest <= 0 )
77 return size - rest;
78 blen = 0x20000 - (addr & 0x1FFFF);
79 if ( rest < blen )
80 blen = rest;
81 rest -= blen;
82 while ( blen > 0 )
83 {
84 flash_addr_t v8;
85
86 v8 = addr & 0xF;
87 xlen = 16 - v8;
88 count = 2;
89 if ( blen < (int)(16 - v8) )
90 xlen = blen;
91 threshold = 399;
92 while ( 1 )
93 {
94 *(volatile acUint16 *)addr = 0xE8;
95 v12 = *(acUint16 *)addr;
96 if ( (v12 & 0x80) != 0 )
97 break;
98 threshold--;
99 if ( threshold < 0 )
100 {
101 while ( count >= 0 )
102 {
103 DelayThread(400);
104 *(volatile acUint16 *)addr = 0xE8;
105 v12 = *(volatile acUint16 *)addr;
106 // cppcheck-suppress knownConditionTrueFalse
107 if ( (v12 & 0x80) != 0 )
108 break;
109 --count;
110 v12 = -116;
111 }
112 break;
113 }
114 }
115 v14 = xlen + 1;
116 if ( v12 < 0 )
117 break;
118 blen -= xlen;
119 *(volatile acUint16 *)addr = v14 >> 1;
120 xlen_v9 = (v14 >> 1) - 1;
121 for ( *(volatile acUint16 *)addr = *buf; xlen_v9 >= 0; addr += 2 )
122 {
123 --xlen_v9;
124 *(volatile acUint16 *)addr = *buf++;
125 }
126 *(volatile acUint16 *)(addr - 2) = 0xD0;
127 }
128 if ( flash_wait((flash_ptr_t)(addr - 2), 400, 2) < 0 || blen > 0 )
129 return rest + blen - size;
130 }
131}
132
133static int flash_reset(flash_addr_t addr)
134{
135 *(acUint16 *)addr = 0xFF;
136 return 0x800000;
137}
138
139flash_ops_t flash_probe_i28f640f5(flash_addr_t addr)
140{
141 acUint16 vendor;
142 acUint16 device;
143
144 *(volatile acUint16 *)addr = 0xFF;
145 *(volatile acUint16 *)addr = 0x90;
146 vendor = *(volatile acUint16 *)addr;
147 *(volatile acUint16 *)addr = 0x90;
148 device = *(volatile acUint16 *)(addr + 2);
149 *(volatile acUint16 *)addr = 0xFF;
150 // cppcheck-suppress knownConditionTrueFalse
151 if ( vendor != 0x89 || device != 0x15 )
152 return 0;
153 return &ops_30;
154}
155
156static int flash_status(flash_addr_t addr)
157{
158 *(volatile acUint16 *)addr = 0x70;
159 // cppcheck-suppress knownConditionTrueFalse
160 if ( (*(volatile acUint16 *)addr & 0x80) != 0 )
161 return 1;
162 return 2;
163}
u32 count
start sector of fragmented bd/file