Mercurial > hg > Members > kono > os9 > sbc09
comparison io.c @ 7:a6db579d8c11
level 2 rom preparing...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 05 Jul 2018 02:00:14 +0900 |
parents | 6159cc57d44e |
children | cb7aa75418b8 |
comparison
equal
deleted
inserted
replaced
6:9c2602e1d716 | 7:a6db579d8c11 |
---|---|
1 /* 6809 Simulator V09. | 1 /* 6808 Simulator V09. |
2 | 2 |
3 created 1993,1994 by L.C. Benschop. | 3 created 1993,1994 by L.C. Benschop. |
4 copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. | 4 copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. |
5 license: GNU General Public License version 2, see LICENSE for more details. | 5 license: GNU General Public License version 2, see LICENSE for more details. |
6 | 6 |
44 #include "v09.h" | 44 #include "v09.h" |
45 | 45 |
46 /* | 46 /* |
47 * IO Map ( can be overrupped by ROM ) | 47 * IO Map ( can be overrupped by ROM ) |
48 * | 48 * |
49 * IOPAGE ~ IOPAGE+0xff | 49 * IOPAGE ~ IOPAGE+0x7f |
50 * for OS9 level2 | |
51 * IOPAGE 0xff80 means ioport beging 0xff80 but IOPAGE itself starts 0xff00 | |
52 * 0xff00-0xff7f, 0xffe0-0xffff can be used as ROM in fixed area | |
50 * | 53 * |
51 * IOPAGE + 0x00 ACIA control | 54 * IOPAGE + 0x00 ACIA control |
52 * IOPAGE + 0x01 ACIA data | 55 * IOPAGE + 0x01 ACIA data |
53 * | 56 * |
54 * IOPAGE + 0x10 Timer control 0x8f start timer/0x80 stop timer/0x04 update date | 57 * IOPAGE + 0x11 MMU Taskreg 0 system map, 1 user map |
55 * IOPAGE + 0x11- YY/MM/DD/HH/MM/SS | 58 * IOPAGE + 0x20-0x27 MMU reg system map |
56 * | 59 * IOPAGE + 0x28-0x2f MMU reg user map |
57 * IOPAGE + 0x20 Disk control 0x81 read/0x55 write 0 ... ok / 0xff .. error | |
58 * IOPAGE + 0x21 drive no | |
59 * IOPAGE + 0x22 LSN2 | |
60 * IOPAGE + 0x23 LSN1 | |
61 * IOPAGE + 0x24 LSN0 | |
62 * IOPAGE + 0x25 ADR2 | |
63 * IOPAGE + 0x26 ADR1 | |
64 * | |
65 * IOPAGE + 0x91 MMU Taskreg 0 system map, 1 user map | |
66 * IOPAGE + 0xa0-0xa7 MMU reg system map | |
67 * IOPAGE + 0xa8-0xaf MMU reg user map | |
68 * | 60 * |
69 * on reset tr==0 and only IOPAGE is valid | 61 * on reset tr==0 and only IOPAGE is valid |
70 * translatation occur only on non-IOPAGE | 62 * translatation occur only on non-IOPAGE |
71 * mem == phymem + 0x70000 | 63 * mem == phymem + 0x70000 |
72 * phy addr = phymem[ ( mmu[ adr >> 13 ] <<13 ) + (adr & 0x1fff ) ] | 64 * phy addr = phymem[ ( mmu[ adr >> 13 ] <<13 ) + (adr & 0x1fff ) ] |
73 * tr=0 mmu=IOPAGE+0xa0 | 65 * tr=0 mmu=IOPAGE+0xa0 |
74 * tr=1 mmu=IOPAGE+0xa8 | 66 * tr=1 mmu=IOPAGE+0xa8 |
67 * | |
68 * IOPAGE + 0x30 Timer control 0x8f start timer/0x80 stop timer/0x04 update date | |
69 * IOPAGE + 0x31- YY/MM/DD/HH/MM/SS | |
70 * | |
71 * IOPAGE + 0x40 Disk control 0x81 read/0x55 write 0 ... ok / 0xff .. error | |
72 * IOPAGE + 0x41 drive no | |
73 * IOPAGE + 0x42 LSN2 | |
74 * IOPAGE + 0x43 LSN1 | |
75 * IOPAGE + 0x44 LSN0 | |
76 * IOPAGE + 0x45 ADR2 | |
77 * IOPAGE + 0x46 ADR1 | |
78 * | |
75 * | 79 * |
76 */ | 80 */ |
77 | 81 |
78 #define SECSIZE 256 | 82 #define SECSIZE 256 |
79 | 83 |
176 } | 180 } |
177 } | 181 } |
178 | 182 |
179 int do_input( a) { | 183 int do_input( a) { |
180 static int c, f = EOF; | 184 static int c, f = EOF; |
181 if (a == 0) { | 185 if (a == 0+(IOPAGE&0xff)) { |
182 if (f == EOF) | 186 if (f == EOF) |
183 f = char_input(); | 187 f = char_input(); |
184 if (f != EOF) | 188 if (f != EOF) |
185 c = f; | 189 c = f; |
186 return 2 + (f != EOF); | 190 return 2 + (f != EOF); |
187 } else if (a == 1) { /*data port*/ | 191 } else if (a == 1+(IOPAGE&0xff)) { /*data port*/ |
188 if (f == EOF) | 192 if (f == EOF) |
189 f = char_input(); | 193 f = char_input(); |
190 if (f != EOF) { | 194 if (f != EOF) { |
191 c = f; | 195 c = f; |
192 f = EOF; | 196 f = EOF; |
196 return mem[IOPAGE + a]; | 200 return mem[IOPAGE + a]; |
197 } | 201 } |
198 | 202 |
199 void do_output(int a, int c) { | 203 void do_output(int a, int c) { |
200 int i, sum; | 204 int i, sum; |
201 if (a == 1) { /* ACIA data port,ignore address */ | 205 if (a == 1+(IOPAGE&0xff)) { /* ACIA data port,ignore address */ |
202 if (!xmstat) { | 206 if (!xmstat) { |
203 if (logfile && c != 127 && (c >= ' ' || c == '\n')) | 207 if (logfile && c != 127 && (c >= ' ' || c == '\n')) |
204 putc(c, logfile); | 208 putc(c, logfile); |
205 putchar(c); | 209 putchar(c); |
206 fflush(stdout); | 210 fflush(stdout); |
242 fwrite(xmbuf + 3, 1, 128, xfile); | 246 fwrite(xmbuf + 3, 1, 128, xfile); |
243 } | 247 } |
244 xidx = 0; | 248 xidx = 0; |
245 } | 249 } |
246 } | 250 } |
247 } else if (a >= 0x90) { /* mmu */ | 251 } else if (a >= 0x10+(IOPAGE&0xff)) { /* mmu */ |
248 do_mmu(a,c); | 252 do_mmu(a,c); |
249 } else if (a >= 0x20) { /* disk */ | 253 } else if (a >= 0x30+(IOPAGE&0xff)) { /* timer */ |
254 do_timer(a,c); | |
255 } else if (a >= 0x40+(IOPAGE&0xff)) { /* disk */ | |
250 do_disk(a,c); | 256 do_disk(a,c); |
251 } else if (a >= 0x10) { /* disk */ | |
252 do_timer(a,c); | |
253 } | 257 } |
254 } | 258 } |
255 | 259 |
256 void restore_term(void) { | 260 void restore_term(void) { |
257 tcsetattr(0, TCSAFLUSH, &termsetting); | 261 tcsetattr(0, TCSAFLUSH, &termsetting); |
264 exit(0); | 268 exit(0); |
265 } | 269 } |
266 | 270 |
267 void do_timer(int a, int c) { | 271 void do_timer(int a, int c) { |
268 struct itimerval timercontrol; | 272 struct itimerval timercontrol; |
269 if (a==0x10 && c==0x8f) { | 273 if (a==0x30 && c==0x8f) { |
270 timercontrol.it_interval.tv_sec = 0; | 274 timercontrol.it_interval.tv_sec = 0; |
271 timercontrol.it_interval.tv_usec = 20000; | 275 timercontrol.it_interval.tv_usec = 20000; |
272 timercontrol.it_value.tv_sec = 0; | 276 timercontrol.it_value.tv_sec = 0; |
273 timercontrol.it_value.tv_usec = 20000; | 277 timercontrol.it_value.tv_usec = 20000; |
274 setitimer(ITIMER_REAL, &timercontrol, NULL); | 278 setitimer(ITIMER_REAL, &timercontrol, NULL); |
275 } else if (a==0x10 && c==0x80) { | 279 } else if (a==0x30 && c==0x80) { |
276 timercontrol.it_interval.tv_sec = 0; | 280 timercontrol.it_interval.tv_sec = 0; |
277 timercontrol.it_interval.tv_usec = 0; | 281 timercontrol.it_interval.tv_usec = 0; |
278 setitimer(ITIMER_REAL, &timercontrol, NULL); | 282 setitimer(ITIMER_REAL, &timercontrol, NULL); |
279 } else if (a==0x10 && c==0x04) { | 283 } else if (a==0x30 && c==0x04) { |
280 time_t tm = time(0); | 284 time_t tm = time(0); |
281 struct tm *t = localtime(&tm); | 285 struct tm *t = localtime(&tm); |
282 mem[IOPAGE+0x11] = t->tm_year; | 286 mem[IOPAGE+0x31] = t->tm_year; |
283 mem[IOPAGE+0x12] = t->tm_mon; | 287 mem[IOPAGE+0x32] = t->tm_mon; |
284 mem[IOPAGE+0x13] = t->tm_mday; | 288 mem[IOPAGE+0x33] = t->tm_mday; |
285 mem[IOPAGE+0x14] = t->tm_hour; | 289 mem[IOPAGE+0x34] = t->tm_hour; |
286 mem[IOPAGE+0x15] = t->tm_min; | 290 mem[IOPAGE+0x35] = t->tm_min; |
287 mem[IOPAGE+0x16] = t->tm_sec; | 291 mem[IOPAGE+0x36] = t->tm_sec; |
288 } else { | 292 } else { |
289 mem[IOPAGE+a]=c; | 293 mem[IOPAGE+a]=c; |
290 } | 294 } |
291 } | 295 } |
292 | 296 |
293 void do_disk(int a, int c) { | 297 void do_disk(int a, int c) { |
294 if (a!=0x20) { | 298 if (a!=0x40) { |
295 mem[IOPAGE+a]=c; | 299 mem[IOPAGE+a]=c; |
296 return; | 300 return; |
297 } | 301 } |
298 int drv = mem[IOPAGE+0x21]; | 302 int drv = mem[IOPAGE+0x41]; |
299 int lsn = (mem[IOPAGE+0x22]<<16) + (mem[IOPAGE+0x23]<<8) + mem[IOPAGE+0x24]; | 303 int lsn = (mem[IOPAGE+0x42]<<16) + (mem[IOPAGE+0x43]<<8) + mem[IOPAGE+0x44]; |
300 int buf = (mem[IOPAGE+0x25]<<8) + mem[IOPAGE+0x26]; | 304 int buf = (mem[IOPAGE+0x45]<<8) + mem[IOPAGE+0x46]; |
301 if (drv > 1 || disk[drv]==0) goto error; | 305 if (drv > 1 || disk[drv]==0) goto error; |
302 if (c==0x81) { | 306 if (c==0x81) { |
303 if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; | 307 if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; |
304 if (read(fileno(disk[drv]),&mem[buf],SECSIZE)==-1) goto error; | 308 if (read(fileno(disk[drv]),&mem[buf],SECSIZE)==-1) goto error; |
305 } else if (c==0x55) { | 309 } else if (c==0x55) { |
306 if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; | 310 if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; |
307 if (write(fileno(disk[drv]),&mem[buf],SECSIZE)==-1) goto error; | 311 if (write(fileno(disk[drv]),&mem[buf],SECSIZE)==-1) goto error; |
308 } | 312 } |
309 mem[IOPAGE+0x20] = 0; | 313 mem[IOPAGE+0x40] = 0; |
310 return; | 314 return; |
311 error : | 315 error : |
312 mem[IOPAGE+0x20] = 0xff; | 316 mem[IOPAGE+0x40] = 0xff; |
313 } | 317 } |
314 | 318 |
315 void do_mmu(int a, int c) | 319 void do_mmu(int a, int c) |
316 { | 320 { |
317 #ifdef USE_MMU | 321 #ifdef USE_MMU |
318 | 322 |
319 if (a==0x91) { | 323 if (a==0x11) { |
320 if (c&0) { | 324 if (c&0) { |
321 mmu = phymem+memsize-0x10000+0xffa0; | 325 mmu = phymem+memsize-0x10000+0xffa0; |
322 } else { | 326 } else { |
323 mmu = phymem+memsize-0x10000+0xffa8; | 327 mmu = phymem+memsize-0x10000+0xffa8; |
324 } | 328 } |
325 mem[IOPAGE+a] = c; | 329 mem[IOPAGE+a] = c; |
326 } if (0xa0 <= a && a <= 0xaf) { | 330 } if (0x20 <= a && a <= 0x2f) { |
327 mem[IOPAGE+a] = c; | 331 mem[IOPAGE+a] = c; |
328 } | 332 } |
329 | 333 |
330 #endif | 334 #endif |
331 } | 335 } |