Mercurial > hg > Members > kono > os9 > sbc09
annotate src/io.c @ 191:d0f5894e9b3a default tip
some how load: confilicts in gmake
author | kono |
---|---|
date | Thu, 07 Dec 2023 09:37:15 +0900 |
parents | b93996f54090 |
children |
rev | line source |
---|---|
9 | 1 /* 6808 Simulator V092 |
34 | 2 created 1993,1994 by L.C. Benschop. copyleft (c) 1994-2014 |
3 by the sbc09 team, see AUTHORS for more details. license: GNU | |
4 General Public License version 2, see LICENSE for more details. | |
0 | 5 |
6 This program simulates a 6809 processor. | |
7 | |
8 System dependencies: short must be 16 bits. | |
9 char must be 8 bits. | |
10 long must be more than 16 bits. | |
11 arrays up to 65536 bytes must be supported. | |
12 machine must be twos complement. | |
13 Most Unix machines will work. For MSODS you need long pointers | |
14 and you may have to malloc() the mem array of 65536 bytes. | |
15 | |
16 Define BIG_ENDIAN if you have a big-endian machine (680x0 etc) | |
17 | |
18 Special instructions: | |
19 SWI2 writes char to stdout from register B. | |
20 SWI3 reads char from stdout to register B, sets carry at EOF. | |
21 (or when no key available when using term control). | |
22 SWI retains its normal function. | |
23 CWAI and SYNC stop simulator. | |
24 | |
25 */ | |
26 | |
27 #include<stdio.h> | |
28 #include<stdlib.h> | |
29 #include<ctype.h> | |
30 #include<signal.h> | |
31 #include<sys/time.h> | |
153 | 32 #include<strings.h> |
0 | 33 |
34 #include <unistd.h> | |
35 #include <fcntl.h> | |
36 #include <string.h> | |
1 | 37 #include <time.h> |
0 | 38 |
39 #ifdef USE_TERMIOS | |
40 #include <termios.h> | |
41 #endif | |
42 | |
43 #define engine extern | |
44 #include "v09.h" | |
45 | |
1 | 46 /* |
3 | 47 * IO Map ( can be overrupped by ROM ) |
48 * | |
46 | 49 * In do_input/do_output call, we cannot access 6809 registers, since it is in i*reg, |
50 * which is a local variable of interpr | |
51 * | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
52 * IOPAGE ~ IOPAGE+0x7f |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
53 * for OS9 level2 |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
54 * IOPAGE 0xff80 means ioport beging 0xff80 but IOPAGE itself starts 0xff00 |
34 | 55 * 0xfe00-0xff7f, 0xffe0-0xffff can be used as RAM in fixed area in level2 |
56 * and these are ROM in level1 | |
57 * | |
1 | 58 * |
3 | 59 * IOPAGE + 0x00 ACIA control |
60 * IOPAGE + 0x01 ACIA data | |
1 | 61 * |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
62 * IOPAGE + 0x11 MMU Taskreg 0 system map, 1 user map |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
63 * IOPAGE + 0x20-0x27 MMU reg system map |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
64 * IOPAGE + 0x28-0x2f MMU reg user map |
3 | 65 * |
66 * on reset tr==0 and only IOPAGE is valid | |
67 * translatation occur only on non-IOPAGE | |
68 * mem == phymem + 0x70000 | |
69 * phy addr = phymem[ ( mmu[ adr >> 13 ] <<13 ) + (adr & 0x1fff ) ] | |
70 * tr=0 mmu=IOPAGE+0xa0 | |
71 * tr=1 mmu=IOPAGE+0xa8 | |
1 | 72 * |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
73 * IOPAGE + 0x30 Timer control 0x8f start timer/0x80 stop timer/0x04 update date |
34 | 74 * read 0x10 bit menas timer |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
75 * IOPAGE + 0x31- YY/MM/DD/HH/MM/SS |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
76 * |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
77 * IOPAGE + 0x40 Disk control 0x81 read/0x55 write 0 ... ok / 0xff .. error |
45 | 78 * 0xd1- VDISK command |
79 * IOPAGE + 0x41 drive no / VDISK drv | |
80 * IOPAGE + 0x42 LSN2 / VDISK sysmode 0 for system, 1 for user | |
49 | 81 * IOPAGE + 0x43 LSN1 |
82 * IOPAGE + 0x44 LSN0 / VDISK Curdir pd number | |
46 | 83 * IOPAGE + 0x45 ADR2 / VDISK caller stack |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
84 * IOPAGE + 0x46 ADR1 |
47 | 85 * IOPAGE + 0x47 / VDISK path descriptor address (Y) |
86 * IOPAGE + 0x48 | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
87 * |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
88 * |
1 | 89 */ |
90 | |
91 #define SECSIZE 256 | |
92 | |
19 | 93 |
190 | 94 extern int timer ; |
55 | 95 int timer_usec = 20000; // 50Hz |
190 | 96 extern struct termios termsetting; |
20 | 97 struct termios newterm; |
98 struct itimerval timercontrol; | |
0 | 99 |
20 | 100 int tflags; |
0 | 101 int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */ |
102 unsigned char xmbuf[132]; | |
103 int xidx; | |
104 int acknak; | |
105 int rcvdnak; | |
106 int blocknum; | |
34 | 107 int timer_irq = 2 ; // 2 = FIRQ, 1 = IRQ |
0 | 108 |
109 FILE *infile; | |
110 FILE *xfile; | |
20 | 111 FILE *logfile; |
1 | 112 FILE *disk[] = {0,0}; |
0 | 113 |
46 | 114 #ifdef USE_VDISK |
115 extern void do_vdisk(int c); | |
116 #endif | |
117 | |
118 | |
9 | 119 #ifdef USE_MMU |
120 extern char *prog ; // for disass | |
11 | 121 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; |
44
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
122 #define pmem(a) mem0(phymem,a,mmu) |
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
123 #else |
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
124 #define pmem(a) (&mem[a]) |
9 | 125 #endif |
126 | |
153 | 127 #if _POSIX_SOURCE>=200809L |
128 | |
129 void usleep(long usec) | |
130 { | |
131 struct timespec rdtp; | |
132 bzero(&rdtp,sizeof(struct timespec)); | |
133 rdtp.tv_nsec = usec*1000; | |
134 nanosleep(&rdtp,0); | |
135 } | |
136 | |
137 #endif | |
44
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
138 |
20 | 139 extern int bpskip ; |
140 extern int stkskip ; | |
141 extern FILE *logfile; | |
0 | 142 |
1 | 143 void do_timer(int,int); |
144 void do_disk(int,int); | |
4 | 145 void do_mmu(int,int); |
0 | 146 |
147 int char_input(void) { | |
148 int c, w, sum; | |
149 if (!xmstat) { | |
150 if (infile) { | |
151 c = getc(infile); | |
152 if (c == EOF) { | |
153 fclose(infile); | |
154 infile = 0; | |
155 return char_input(); | |
156 } | |
157 if (c == '\n') | |
158 c = '\r'; | |
159 return c; | |
2
31d96e2b364e
add virtual hd option to v09
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1
diff
changeset
|
160 } else { |
31d96e2b364e
add virtual hd option to v09
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1
diff
changeset
|
161 usleep(100); |
0 | 162 return getchar(); |
2
31d96e2b364e
add virtual hd option to v09
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1
diff
changeset
|
163 } |
0 | 164 } else if (xmstat == 1) { |
165 if (xidx) { | |
166 c = xmbuf[xidx++]; | |
167 if (xidx == 132) { | |
168 xidx = 0; | |
169 rcvdnak = EOF; | |
170 acknak = 6; | |
171 } | |
172 } else { | |
173 if ((acknak == 21 && rcvdnak == 21) || (acknak == 6 && rcvdnak == 6)) { | |
174 rcvdnak = 0; | |
175 memset(xmbuf, 0, 132); | |
176 w = fread(xmbuf + 3, 1, 128, xfile); | |
177 if (w) { | |
178 printf("Block %3d transmitted, ", blocknum); | |
179 xmbuf[0] = 1; | |
180 xmbuf[1] = blocknum; | |
181 xmbuf[2] = 255 - blocknum; | |
182 blocknum = (blocknum + 1) & 255; | |
183 sum = 0; | |
184 for (w = 3; w < 131; w++) | |
185 sum = (sum + xmbuf[w]) & 255; | |
186 xmbuf[131] = sum; | |
187 acknak = 6; | |
188 c = 1; | |
189 xidx = 1; | |
190 } else { | |
191 printf("EOT transmitted, "); | |
192 acknak = 4; | |
193 c = 4; | |
194 } | |
195 } else if (rcvdnak == 21) { | |
196 rcvdnak = 0; | |
197 printf("Block %3d retransmitted, ", xmbuf[1]); | |
198 c = xmbuf[xidx++]; /*retransmit the same block */ | |
199 } else | |
200 c = EOF; | |
201 } | |
202 return c; | |
203 } else { | |
204 if (acknak == 4) { | |
205 c = 6; | |
206 acknak = 0; | |
207 fclose(xfile); | |
208 xfile = 0; | |
209 xmstat = 0; | |
210 } else if (acknak) { | |
211 c = acknak; | |
212 acknak = 0; | |
213 } else | |
214 c = EOF; | |
215 if (c == 6) | |
216 printf("ACK\n"); | |
217 if (c == 21) | |
218 printf("NAK\n"); | |
219 return c; | |
220 } | |
221 } | |
222 | |
9 | 223 int do_input(int a) { |
0 | 224 static int c, f = EOF; |
18 | 225 if (a == 0+(IOPAGE&0x1ff)) { |
0 | 226 if (f == EOF) |
227 f = char_input(); | |
34 | 228 if (f != EOF) { |
0 | 229 c = f; |
34 | 230 mem[(IOPAGE&0xfe00) + a] = c; |
231 } | |
232 mem[(IOPAGE&0xfe00) + a] = c = 2 + (f != EOF); | |
233 return c; | |
18 | 234 } else if (a == 1+(IOPAGE&0x1ff)) { /*data port*/ |
0 | 235 if (f == EOF) |
236 f = char_input(); | |
237 if (f != EOF) { | |
238 c = f; | |
239 f = EOF; | |
34 | 240 mem[(IOPAGE&0xfe00) + a] = c; |
0 | 241 } |
242 return c; | |
243 } | |
18 | 244 return mem[(IOPAGE&0xfe00) + a]; |
0 | 245 } |
246 | |
247 void do_output(int a, int c) { | |
248 int i, sum; | |
18 | 249 if (a == 1+(IOPAGE&0x1ff)) { /* ACIA data port,ignore address */ |
0 | 250 if (!xmstat) { |
251 if (logfile && c != 127 && (c >= ' ' || c == '\n')) | |
252 putc(c, logfile); | |
253 putchar(c); | |
254 fflush(stdout); | |
255 } else if (xmstat == 1) { | |
256 rcvdnak = c; | |
257 if (c == 6 && acknak == 4) { | |
258 fclose(xfile); | |
259 xfile = 0; | |
260 xmstat = 0; | |
261 } | |
262 if (c == 6) | |
263 printf("ACK\n"); | |
264 if (c == 21) | |
265 printf("NAK\n"); | |
266 if (c == 24) { | |
267 printf("CAN\n"); | |
268 fclose(xfile); | |
269 xmstat = 0; | |
270 xfile = 0; | |
271 } | |
272 } else { | |
273 if (xidx == 0 && c == 4) { | |
274 acknak = 4; | |
275 printf("EOT received, "); | |
276 } | |
277 xmbuf[xidx++] = c; | |
278 if (xidx == 132) { | |
279 sum = 0; | |
280 for (i = 3; i < 131; i++) | |
281 sum = (sum + xmbuf[i]) & 255; | |
282 if (xmbuf[0] == 1 && xmbuf[1] == 255 - xmbuf[2] | |
283 && sum == xmbuf[131]) | |
284 acknak = 6; | |
285 else | |
286 acknak = 21; | |
287 printf("Block %3d received, ", xmbuf[1]); | |
288 if (blocknum == xmbuf[1]) { | |
289 blocknum = (blocknum + 1) & 255; | |
290 fwrite(xmbuf + 3, 1, 128, xfile); | |
291 } | |
292 xidx = 0; | |
293 } | |
294 } | |
18 | 295 } else if (a >= 0x40+(IOPAGE&0x1ff)) { /* disk */ |
11 | 296 do_disk(a,c); |
18 | 297 } else if (a >= 0x30+(IOPAGE&0x1ff)) { /* timer */ |
11 | 298 do_timer(a,c); |
18 | 299 } else if (a >= 0x10+(IOPAGE&0x1ff)) { /* mmu */ |
4 | 300 do_mmu(a,c); |
35 | 301 #ifdef USE_MMU |
302 } else { /* fixed ram */ | |
303 mem[ a + 0xfe00 ] = c; | |
304 #endif | |
0 | 305 } |
306 } | |
307 | |
189
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
308 void start_timer(void) { |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
309 struct itimerval timercontrol; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
310 timercontrol.it_interval.tv_sec = 0; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
311 timercontrol.it_interval.tv_usec = timer_usec; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
312 timercontrol.it_value.tv_sec = 0; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
313 timercontrol.it_value.tv_usec = timer_usec; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
314 timer_irq = 1; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
315 setitimer(ITIMER_REAL, &timercontrol, NULL); |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
316 } |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
317 |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
318 void stop_timer(void) { |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
319 timercontrol.it_interval.tv_sec = 0; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
320 timercontrol.it_interval.tv_usec = 0; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
321 setitimer(ITIMER_REAL, &timercontrol, NULL); |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
322 } |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
323 |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
324 void set_date(void) { |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
325 time_t tm = time(0); |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
326 struct tm *t = localtime(&tm); |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
327 mem[IOPAGE+0x31] = t->tm_year; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
328 mem[IOPAGE+0x32] = t->tm_mon+1; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
329 mem[IOPAGE+0x33] = t->tm_mday; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
330 mem[IOPAGE+0x34] = t->tm_hour; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
331 mem[IOPAGE+0x35] = t->tm_min; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
332 mem[IOPAGE+0x36] = t->tm_sec; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
333 } |
0 | 334 |
1 | 335 void do_timer(int a, int c) { |
336 struct itimerval timercontrol; | |
18 | 337 if (a==0x30+(IOPAGE&0x1ff) && c==0x8f) { |
189
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
338 if ((timer&2)==0) return; |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
339 start_timer(); |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
340 mem[(IOPAGE&0xfe00)+a]=c; |
18 | 341 } else if (a==0x30+(IOPAGE&0x1ff) && c==0x80) { |
189
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
342 stop_timer(); |
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
343 mem[(IOPAGE&0xfe00)+a]=c; |
18 | 344 } else if (a==0x30+(IOPAGE&0x1ff) && c==0x04) { |
189
f524c0c95559
add instros9 source and break instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
153
diff
changeset
|
345 set_date(); |
1 | 346 } else { |
18 | 347 mem[(IOPAGE&0xfe00)+a]=c; |
1 | 348 } |
349 } | |
350 | |
44
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
351 |
1 | 352 void do_disk(int a, int c) { |
18 | 353 if (a!=0x40+(IOPAGE&0x1ff)) { |
354 mem[(IOPAGE&0xfe00)+a]=c; | |
1 | 355 return; |
356 } | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
357 int drv = mem[IOPAGE+0x41]; |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
358 int lsn = (mem[IOPAGE+0x42]<<16) + (mem[IOPAGE+0x43]<<8) + mem[IOPAGE+0x44]; |
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
359 int buf = (mem[IOPAGE+0x45]<<8) + mem[IOPAGE+0x46]; |
44
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
360 Byte *phy = pmem(buf); |
1 | 361 if (c==0x81) { |
52
51b437557f42
boot without disk image
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
362 if (drv > 1 || disk[drv]==0) goto error; |
1 | 363 if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; |
30 | 364 if (read(fileno(disk[drv]),phy,SECSIZE)==-1) goto error; |
1 | 365 } else if (c==0x55) { |
52
51b437557f42
boot without disk image
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
366 if (drv > 1 || disk[drv]==0) goto error; |
1 | 367 if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; |
30 | 368 if (write(fileno(disk[drv]),phy,SECSIZE)==-1) goto error; |
46 | 369 #ifdef USE_VDISK |
44
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
370 } else { |
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
371 do_vdisk(c); |
48
ea1b17311bf3
dir /v0 worked but dir /v0/src and chd /v0; dir does not
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
372 return; |
44
b26c23331d02
add more function on vdisk
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
35
diff
changeset
|
373 #endif |
1 | 374 } |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
375 mem[IOPAGE+0x40] = 0; |
1 | 376 return; |
377 error : | |
7
a6db579d8c11
level 2 rom preparing...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
378 mem[IOPAGE+0x40] = 0xff; |
1 | 379 } |
380 | |
4 | 381 void do_mmu(int a, int c) |
382 { | |
383 #ifdef USE_MMU | |
384 | |
18 | 385 if (a==0x11+(IOPAGE&0x1ff)) { |
13 | 386 if (c&1) { |
23 | 387 mmu = &mem[0xffa8]; |
13 | 388 } else { |
23 | 389 mmu = &mem[0xffa0]; |
4 | 390 } |
391 } | |
18 | 392 mem[(IOPAGE&0xfe00)+a] = c; // other register such as 0xffa0-0xffaf |
4 | 393 #endif |
394 } | |
395 | |
0 | 396 void timehandler(int sig) { |
397 attention = 1; | |
55 | 398 irq = timerirq; |
53 | 399 mem[IOPAGE+0x30] |= 0x10 ; |
34 | 400 // signal(SIGALRM, timehandler); |
0 | 401 } |
402 | |
403 void handler(int sig) { | |
404 escape = 1; | |
405 attention = 1; | |
406 bpskip = 0; | |
407 stkskip = 0; | |
408 } | |
409 | |
20 | 410 void init_term(void) { |
411 tcgetattr(0, &termsetting); | |
412 tflags = fcntl(0, F_GETFL, 0); | |
413 } | |
414 | |
0 | 415 void set_term(char c) { |
416 signal(SIGQUIT, SIG_IGN); | |
417 signal(SIGTSTP, SIG_IGN); | |
418 signal(SIGINT, handler); | |
419 signal(SIGUSR1, handler); | |
420 newterm = termsetting; | |
421 newterm.c_iflag = newterm.c_iflag & ~INLCR & ~ICRNL; | |
422 newterm.c_lflag = newterm.c_lflag & ~ECHO & ~ICANON; | |
423 newterm.c_cc[VTIME] = 0; | |
424 newterm.c_cc[VMIN] = 1; | |
425 newterm.c_cc[VINTR] = escchar; | |
426 tcsetattr(0, TCSAFLUSH, &newterm); | |
153 | 427 // fcntl(0, F_SETFL, tflags | O_NDELAY); /* Make input from stdin non-blocking */ |
428 fcntl(0, F_SETFL, tflags | O_NONBLOCK); /* Make input from stdin non-blocking */ | |
0 | 429 signal(SIGALRM, timehandler); |
430 timercontrol.it_interval.tv_sec = 0; | |
55 | 431 timercontrol.it_interval.tv_usec = timer_usec; |
0 | 432 timercontrol.it_value.tv_sec = 0; |
55 | 433 timercontrol.it_value.tv_usec = timer_usec; |
61 | 434 if (!timer) // original sbc09 start timer from the beginning |
0 | 435 setitimer(ITIMER_REAL, &timercontrol, NULL); |
436 } | |
20 | 437 |
438 void restore_term(void) { | |
22 | 439 termsetting.c_iflag = termsetting.c_iflag | INLCR | ICRNL; |
20 | 440 tcsetattr(0, TCSAFLUSH, &termsetting); |
441 fcntl(0, F_SETFL, tflags); | |
442 signal(SIGALRM, SIG_IGN); | |
443 } | |
444 | |
445 | |
446 | |
447 |