source: thomson/code/C/HxCHost/main.c@ 1b74fa2

main
Last change on this file since 1b74fa2 was 1b74fa2, checked in by Adrien Destugues <pulkomandy@…>, 12 years ago

work in progress write support.

  • With latest beta firmware there is no spinup problem anymore in direct access mode,
  • Read the CFG file and display settings menu
  • Save settings (not perfectly working yet)
  • Some tweaks all around.
  • Move code downwards in memory, because we run out of space !

git-svn-id: svn://localhost/thomson@18 85ae3b6b-dc8f-4344-a89d-598714f2e4e5

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/* HcX floppy Emulator Host Software for TO8 and MO5
2 * Copyright 2011, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
3 * Distributed under the terms of the MIT Licence
4 */
5
6#include "pff/pff.h"
7#include "macros.h"
8
9void asm_write();
10
11#if PLATFORM == 5
12 #define DIRECTORY_BUFFER (FILINFO*)0x3000
13#else
14 // Thomson TO8 code
15 #define DIRECTORY_BUFFER (FILINFO*)0xA000
16#endif
17
18unsigned char mark[512 + 16] = "HxCFEDA";
19unsigned char* secbuf = mark+16;
20
21const char* HXCSDFECFG = "HXCTEST.CFG";
22
23void printhex(unsigned char n)
24{
25 unsigned char a = n >> 4;
26 a += '0';
27 if (a > '9')
28 a += 'A'-10-'0';
29 mon_putc(a)
30 a = (n&0xF) + '0';
31 if (a > '9')
32 a += 'A'-10-'0';
33 mon_putc(a)
34}
35
36// Program exit point (required by compiler...)
37void __attribute__((noreturn)) exit(int a)
38{
39 for(;;);
40}
41
42// Error exit (required by compiler ...)
43void __attribute__((noreturn)) abort()
44{
45 for(;;);
46}
47
48void my_puts(char* s)
49{
50 int j = 0;
51 while(s[j]) mon_putc(s[j++]);
52}
53
54DIR d;
55char path[256] = "";
56char* pathend = path;
57
58void chdir(char* dirname)
59{
60 *(pathend++) = '/';
61
62 do {
63 *(pathend++) = *(dirname++);
64 } while(*(dirname) != 0);
65
66 *(pathend) = 0;
67
68 FRESULT r = pf_opendir(&d, path);
69
70 if (r != 0) my_puts("directory error");
71}
72
73void parent(void)
74{
75 while(*(pathend) != '/' && pathend > path) pathend--;
76
77 *(pathend) = 0;
78 FRESULT r = pf_opendir(&d, path);
79 if (r != 0) my_puts("directory error");
80}
81
82void ls(FILINFO* fp)
83{
84 for(int i = 23; i > 0; --i) {
85 FRESULT r = pf_readdir(&d, fp);
86 if (r != 0) my_puts("File error");
87 if (*fp->fname == 0) break;
88
89 fp ++;
90 }
91}
92
93struct opt
94{
95 char* name;
96 BYTE off;
97 BYTE type;
98};
99
100static const struct opt options[7] =
101{
102 {"\x1B\x50\x0CHxC floppy emulator setup\r\n"
103 "UP/DOWN move - +/- change\r\n"
104 "space save - left quit\r\n"
105 "Step sound ", 16, 0},
106 {"\r\nGUI sound ", 17, 0},
107 {"\r\nBacklight delay ", 18, 1},
108 {"\r\nStandby delay ", 19, 1},
109 {"\r\nDrive selector ", 20, 0},
110 {"\r\nLoad last floppy ", 26, 0},
111 {"\r\nLCD scroll speed ", 28, 1},
112};
113
114inline static void config()
115{
116 // If it's HXCSDFE.CFG, enter config mode
117 // Read the config part of the file
118 WORD byteCount = 29;
119 FRESULT r = pf_read(secbuf, byteCount, &byteCount);
120 if (r != 0 || byteCount != 29)
121 {
122 my_puts("read error");
123 abort();
124 }
125
126 BYTE selected;
127 for(;;) {
128 for (int j = 0; j < 7; j++)
129 {
130 my_puts(options[j].name);
131 mon_putc(0x1B); // Select back color
132 mon_putc(selected == j ? 0x54: 0x50) // Blue
133 if(options[j].type)
134 printhex(*(secbuf+options[j].off));
135 else
136 my_puts(*(secbuf+options[j].off) ? "ON":"OFF");
137 mon_putc(0x1B); // Select back color
138 mon_putc(0x50); // Select back color
139 }
140
141 do {
142 asm("SWI \t \t;\n"
143 ".fcb \t0x0A\t;GETC\n");
144 } while(KEY == 0);
145
146 switch(KEY)
147 {
148 case 0x08: // UP
149 // select next file
150 if (selected != 0) --selected;
151 // TODO next page ?
152 break;
153
154 case 0x19: // SPACE
155 // save configuration
156 r = pf_open(HXCSDFECFG);
157 if (r) {
158 my_puts("can't open cfg");
159 printhex(r);
160 }
161 byteCount = 29;
162 r = pf_write(secbuf, byteCount, &byteCount);
163 if (r || byteCount != 29) {
164 my_puts("can't write cfg");
165 printhex(r);
166 }
167 r = pf_write(0, 0, &byteCount); // flush sector
168 if (r) {
169 my_puts("can't close cfg");
170 printhex(r);
171 }
172 // fall through
173 case 0x10: // LEFT
174 // Quit (without saving)
175 return;
176 break;
177
178 case 0x18: // DOWN
179 // select previous file
180 if (++selected > 7) selected = 7;
181 // TODO previous page ?
182 break;
183 case 0x13: // -
184 // decrease current option value
185 if(options[selected].type)
186 --*(secbuf+options[selected].off);
187 else
188 *(secbuf+options[selected].off) = 0;
189 break;
190 case 0x0B: // +
191 if(options[selected].type)
192 ++*(secbuf+options[selected].off);
193 else
194 *(secbuf+options[selected].off) = 0xFF;
195 break;
196 }
197 }
198}
199
200int __attribute__((noreturn)) main(void)
201{
202 // Detect HxC and print version code
203 seek();
204 read(255, 0, secbuf);
205 my_puts("Firmware ");
206 my_puts(secbuf + 8);
207
208 // Read FAT / Init card
209 FATFS fs;
210 FRESULT r = pf_mount(&fs);
211 if (r != 0) {
212 my_puts("mount error ");
213 printhex(r);
214 exit(0);
215 }
216
217 // Enter "fixed timings" mode - make sure track 255 sends index pulses
218 // every 200ms. Makes everything a bit slower, but the CD90-640 ROM
219 // requires it.
220 int j = 8;
221 mark[j++] = 3;
222 mark[j++] = 0xFF;
223 for(; j <512; j++) mark[j] = 0;
224 write(255,0,mark);
225
226 // Open root directory
227 pf_opendir(&d, "");
228
229 // List files
230 ls(DIRECTORY_BUFFER);
231
232 int selected = 0;
233 // Main input loop
234 for(;;) {
235 // TODO : refresh only the changed items ?
236 mon_putc(0x1B) // Select back color
237 mon_putc(0x50) // Black
238 mon_putc(0x0C) // clear screen
239
240 FILINFO* fp = DIRECTORY_BUFFER;
241 int i = 0;
242 while(*fp->fname != 0) {
243 mon_putc(0x1B); // Select back color
244 if (i++ == selected)
245 mon_putc(0x54) // Blue
246 else
247 mon_putc(0x50) // Black
248
249 mon_putc(0x1B); // Select front color
250 if (fp->fattrib & AM_DIR)
251 mon_putc(0x41) // Red
252 else
253 mon_putc(0x47) // white
254
255 my_puts(fp->fname);
256 mon_putc('\n');
257 mon_putc('\r');
258
259 fp++;
260 }
261 if (selected > i) selected = i;
262
263 // Allow the user to select a file
264 do {
265 asm("SWI \t \t;\n"
266 ".fcb \t0x0A\t;GETC\n");
267 } while(KEY == 0);
268
269 switch(KEY)
270 {
271 case 0x08: // UP
272 // select next file
273 if (selected != 0) --selected;
274 // TODO next page ?
275 break;
276
277 case 0x10: // LEFT
278 parent();
279 ls(DIRECTORY_BUFFER);
280 break;
281
282 case 0x18: // DOWN
283 // select previous file
284 if (selected++ >= i) selected = i-1;
285 // TODO previous page ?
286 break;
287
288 case 0x19: // SPACE
289 fp = DIRECTORY_BUFFER;
290 fp += selected; // Point on the current direntry
291
292 if(fp->fattrib & AM_DIR)
293 {
294 // If it's a dir, enter it
295 chdir(fp->fname);
296 selected = 0;
297 ls(DIRECTORY_BUFFER);
298 } else {
299 const char* cmp = HXCSDFECFG;
300 FRESULT res = pf_open(cmp);
301 if (res) {
302 my_puts("Can't open CFG file: ");
303 printhex(res);
304 exit(0);
305 }
306 if (*(long*)(fp->fname) == *(long*)(cmp)
307 && *(long*)(fp->fname + 4) == *(long*)(cmp+4)
308 && *(long*)(fp->fname + 8) == *(long*)(cmp+8)
309 )
310 {
311 config();
312 } else {
313 my_puts("LOADING FILE");
314 // If it's an HFE file, load it in HxCSDFE.CFG, then reboot
315
316 // reboot
317 exit(0);
318 }
319 }
320 break;
321
322 default:
323 printhex(KEY);
324 break;
325 }
326 }
327}
Note: See TracBrowser for help on using the repository browser.