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 }