source: thomson/code/C/HxCHost/main.c@ ee447bf

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

More work on write support :

  • Avoid using the same buffer over and over again for everything, when writing this creates some problems.
  • Editing the configuration now works.

git-svn-id: svn://localhost/thomson@19 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 = "HXCSDFE.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 unsigned char* confbuf[29];
117 // If it's HXCSDFE.CFG, enter config mode
118 // Read the config part of the file
119 WORD byteCount = 29;
120 FRESULT r = pf_read(confbuf, byteCount, &byteCount);
121 if (r != 0 || byteCount != 29)
122 {
123 my_puts("read error");
124 abort();
125 }
126
127 BYTE selected;
128 for(;;) {
129 for (int j = 0; j < 7; j++)
130 {
131 my_puts(options[j].name);
132 mon_putc(0x1B); // Select back color
133 mon_putc(selected == j ? 0x54: 0x50) // Blue
134 if(options[j].type)
135 printhex(*(confbuf+options[j].off));
136 else
137 my_puts(*(confbuf+options[j].off) ? "ON":"OFF");
138 mon_putc(0x1B); // Select back color
139 mon_putc(0x50); // Select back color
140 }
141
142 do {
143 asm("SWI \t \t;\n"
144 ".fcb \t0x0A\t;GETC\n");
145 } while(KEY == 0);
146
147 switch(KEY)
148 {
149 case 0x08: // UP
150 // select next file
151 if (selected != 0) --selected;
152 // TODO next page ?
153 break;
154
155 case 0x19: // SPACE
156 // save configuration
157 pf_lseek(0);
158 byteCount = 29;
159 r = pf_write(confbuf, byteCount, &byteCount);
160 if (r || byteCount != 29) {
161 my_puts("can't write cfg");
162 printhex(r);
163 abort();
164 }
165 r = pf_write(0, 0, &byteCount); // flush sector
166 if (r) {
167 my_puts("can't close cfg");
168 printhex(r);
169 abort();
170 }
171 // fall through
172 do {
173 asm("SWI \t \t;\n"
174 ".fcb \t0x0A\t;GETC\n");
175 } while(KEY == 0);
176 case 0x10: // LEFT
177 // Quit (without saving)
178 return;
179
180 case 0x18: // DOWN
181 // select previous file
182 if (++selected > 7) selected = 7;
183 // TODO previous page ?
184 break;
185 case 0x13: // -
186 // decrease current option value
187 if(options[selected].type)
188 --*(confbuf+options[selected].off);
189 else
190 *(confbuf+options[selected].off) = 0;
191 break;
192 case 0x0B: // +
193 if(options[selected].type)
194 ++*(confbuf+options[selected].off);
195 else
196 *(confbuf+options[selected].off) = 0xFF;
197 break;
198 }
199 }
200}
201
202int __attribute__((noreturn)) main(void)
203{
204 // Detect HxC and print version code
205 seek();
206 read(255, 0, secbuf);
207 my_puts("Firmware ");
208 my_puts(secbuf + 8);
209
210 // Read FAT / Init card
211 FATFS fs;
212 FRESULT r = pf_mount(&fs);
213 if (r != 0) {
214 my_puts("mount error ");
215 printhex(r);
216 exit(0);
217 }
218
219 // Enter "fixed timings" mode - make sure track 255 sends index pulses
220 // every 200ms. Makes everything a bit slower, but the CD90-640 ROM
221 // requires it.
222 int j = 8;
223 mark[j++] = 3;
224 mark[j++] = 0xFF;
225 for(; j <512; j++) mark[j] = 0;
226 write(255,0,mark);
227
228 // Open root directory
229 pf_opendir(&d, "");
230
231 // List files
232 ls(DIRECTORY_BUFFER);
233
234 int selected = 0;
235 // Main input loop
236 for(;;) {
237 // TODO : refresh only the changed items ?
238 mon_putc(0x1B) // Select back color
239 mon_putc(0x50) // Black
240 mon_putc(0x0C) // clear screen
241
242 FILINFO* fp = DIRECTORY_BUFFER;
243 int i = 0;
244 while(*fp->fname != 0) {
245 mon_putc(0x1B); // Select back color
246 if (i++ == selected)
247 mon_putc(0x54) // Blue
248 else
249 mon_putc(0x50) // Black
250
251 mon_putc(0x1B); // Select front color
252 if (fp->fattrib & AM_DIR)
253 mon_putc(0x41) // Red
254 else
255 mon_putc(0x47) // white
256
257 my_puts(fp->fname);
258 mon_putc('\n');
259 mon_putc('\r');
260
261 fp++;
262 }
263 if (selected > i) selected = i;
264
265 // Allow the user to select a file
266 do {
267 asm("SWI \t \t;\n"
268 ".fcb \t0x0A\t;GETC\n");
269 } while(KEY == 0);
270
271 switch(KEY)
272 {
273 case 0x08: // UP
274 // select next file
275 if (selected != 0) --selected;
276 // TODO next page ?
277 break;
278
279 case 0x10: // LEFT
280 parent();
281 ls(DIRECTORY_BUFFER);
282 break;
283
284 case 0x18: // DOWN
285 // select previous file
286 if (selected++ >= i) selected = i-1;
287 // TODO previous page ?
288 break;
289
290 case 0x19: // SPACE
291 fp = DIRECTORY_BUFFER;
292 fp += selected; // Point on the current direntry
293
294 if(fp->fattrib & AM_DIR)
295 {
296 // If it's a dir, enter it
297 chdir(fp->fname);
298 selected = 0;
299 ls(DIRECTORY_BUFFER);
300 } else {
301 const char* cmp = HXCSDFECFG;
302 FRESULT res = pf_open(cmp);
303 if (res) {
304 my_puts("Can't open CFG file: ");
305 printhex(res);
306 exit(0);
307 }
308 if (*(long*)(fp->fname) == *(long*)(cmp)
309 && *(long*)(fp->fname + 4) == *(long*)(cmp+4)
310 && *(long*)(fp->fname + 8) == *(long*)(cmp+8)
311 )
312 {
313 config();
314 } else {
315 my_puts("LOADING FILE");
316 // If it's an HFE file, load it in HxCSDFE.CFG, then reboot
317
318 // reboot
319 exit(0);
320 }
321 }
322 break;
323
324 default:
325 printhex(KEY);
326 break;
327 }
328 }
329}
Note: See TracBrowser for help on using the repository browser.