comparison vdisk.c @ 44:b26c23331d02

add more function on vdisk
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 19 Jul 2018 11:31:17 +0900
parents 7a83a6a1685a
children 07c84761da6f
comparison
equal deleted inserted replaced
43:7a83a6a1685a 44:b26c23331d02
3 * 3 *
4 * Shinji KONO (kono@ie.u-ryukyu.ac.jp) 2018/7/17 4 * Shinji KONO (kono@ie.u-ryukyu.ac.jp) 2018/7/17
5 * GPL v1 license 5 * GPL v1 license
6 */ 6 */
7 7
8 #define engine extern
9 #include "v09.h"
8 #include <stdio.h> 10 #include <stdio.h>
9 #include <stdlib.h> 11 #include <stdlib.h>
10 #include <unistd.h> 12 #include <unistd.h>
11 #include <sys/stat.h> 13 #include <sys/stat.h>
12 #include <sys/select.h> 14 #include <sys/select.h>
13 15 #include <dirent.h>
14 16 #include <string.h>
15 /**************************** 17
16 * 18
17 * Main entry point for RBF 19 #ifdef USE_MMU
18 * 20 extern char *prog ; // for disass
19 lbra Open 21 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ;
20 lbra MakDir 22 #define pmem(a) mem0(phymem,a,mmu)
21 lbra ChgDir 23 #define umem(a) (mem[0x41+IOPAGE]?mem0(phymem,a,&mem[0x21+IOPAGE]):mem0(phymem,a,&mem[0x20+IOPAGE]))
22 lbra Delete 24 #else
23 lbra Seek 25 #define pmem(a) (&mem[a])
24 lbra Read 26 #define umem(a) (&mem[a])
25 lbra Write 27 #endif
26 lbra ReadLn 28
27 lbra WriteLn 29 #define MAXPDV 256
28 lbra GetStat 30
29 lbra SetStat 31 typedef struct pathDesc {
30 lbra Close 32 char *name;
31 */ 33 FILE *fp;
32 34 int mode;
33 35 int inode ; // lower 24 bit of unix inode, os9 lsn
34 /* 36 int num ;
35 * I$Create Entry Point 37 char use ;
36 * 38 char dir;
37 * Entry: A = access mode desired 39 char *fd ;
38 * B = file attributes 40 char *dirfp;
39 * X = address of the pathlist 41 } PathDesc, *PathDescPtr;
40 * 42
41 * Exit: A = pathnum 43
42 * X = last byte of pathlist address 44 PathDesc pdv[MAXPDV];
43 * 45
44 * Error: CC Carry set 46 PathDesc *findPD() {
45 * B = errcode 47 for(int i=0;i<MAXPDV;i++) {
46 */ 48 if (!pdv[i].use) {
49 pdv[i].use = 1;
50 pdv[i].num = i;
51 pd[i].mode = 0;
52 pd[i].fp = 0;
53 pd[i].dirfp = 0;
54 pd[i].name = 0;
55 pd[i].fd = 0;
56 return &pdv[i];
57 }
58 }
59 return 0;
60 }
61
62 void closepd(PathDesc *pd) {
63 int err = fclose(pd->fp) ;
64 pd->use = 0;
65 pd->fp = 0;
66 pd->mode = 0;
67 free(pd->dirfp); pd->dirfp = 0;
68 free(pd->name); pd->name = 0;
69 free(pd->fd); pd->fd = 0;
70 }
47 71
48 #define MAXPAHTLEN 256 72 #define MAXPAHTLEN 256
49 73
50 char * checkFileName(char *path, PathDesc *pd) { 74 char *addCurdir(char *name, PathDesc *curdir) {
75 int ns = strlen(name);
76 int ps = ns;
77 int ds=0 ;
78 if (curdir==0 && name[0]!='/') return 0; // no current directory
79 if (name[0]!='/') ps += (ds=strlen(curdir->name))+1;
80 char *path = (char*)malloc(ps+1);
81 int i = 0;
82 if (ds) {
83 for(;i<ds;i++) path[i] = curdir->name[i];
84 path[i++] = '/';
85 }
86 for(int j=0;j<ns;j++,i++) path[i] = name[j];
87 path[i++] = 0;
88 return path;
89 }
90
91 char * checkFileName(char *path, PathDesc *pd, PathDesc *curdir) {
51 char *p = path; 92 char *p = path;
93 char *name = path;
52 int maxlen = MAXPAHTLEN; 94 int maxlen = MAXPAHTLEN;
53 pd->lastChar = p;
54 while(*p!=0 && (*p&80)==0 && maxlen-->0) p++; 95 while(*p!=0 && (*p&80)==0 && maxlen-->0) p++;
55 if (maxlen==MAXPAHTLEN) return 0; 96 if (maxlen==MAXPAHTLEN) return 0;
56 pd->lastChar = p;
57 if (*p!=0) { 97 if (*p!=0) {
58 p = (char *)malloc(len+1); 98 name = (char *)malloc(p-path+1);
59 strncpy(path,p, MAXPAHTLEN-maxlen); 99 strncpy(path,p, MAXPAHTLEN-maxlen);
60 } 100 }
101 char *name1 = addCurdir(name,curdir);
102 if (name1!=name && name1!=path) free(name);
103 pd->name = name1;
61 return p; 104 return p;
62 } 105 }
63 106
64 int os9toUnixAttr(Byte attr) { 107 void os9setmode(char &os9mode,int mode) {
65 return "r+"; 108 char m = 0;
66 } 109 if (mode&S_IFDIR) m|=0x80;
67 110 if (mode&S_IRUSR) m|=0x01;
68 int vrbf_create(byte mode,Byte attr,char *path,PathDesc *pd) { 111 if (mode&S_IWUSR) m|=0x02;
69 char *p = pd->unixName = checkFileName(path,pd); 112 if (mode&S_IXUSR) m|=0x04;
70 if (p==0) return -1; 113 if (mode&S_IROTH) m|=0x08;
71 p->dir = 0; 114 if (mode&S_IWOTH) m|=0x10;
72 p->fp = fopen(p->unixName,"w+"); // os9toUnixAttr(attr)); 115 if (mode&S_IXOTH) m|=0x20;
73 if (fd) return 0; 116 m|=0x60; // always sharable
74 return -1; 117 *os9mode = m;
75 } 118 }
76 119
120 char * os9toUnixAttr(Byte attr) {
121 if ((attr&0x1) && (attr&0x2)) return "r+";
122 if (!(attr&0x1) && (attr&0x2)) return "w";
123 if ((attr&0x1) && !(attr&0x2)) return "r";
124 return "r";
125 }
77 126
78 /* 127 /*
79 * I$Open Entry Point 128 * os9 file descriptor
80 * 129 * * File Descriptor Format
81 * Entry: A = access mode desired 130 *
82 * X = address of the pathlist 131 * The file descriptor is a sector that is present for every file
83 * 132 * on an RBF device. It contains attributes, modification dates,
84 * Exit: A = pathnum 133 * and segment information on a file.
85 * X = last byte of pathlist address 134 *
86 * 135 * ORG 0
87 * Error: CC Carry set 136 *FD.ATT RMB 1 Attributes
88 * B = errcode 137 *FD.OWN RMB 2 Owner
89 */ 138 *FD.DAT RMB 5 Date last modified
90 139 *FD.LNK RMB 1 Link count
91 int vrbf_open(byte mode,char *path, PathDesc *pd) { 140 *FD.SIZ RMB 4 File size
92 char *p = pd->unixName = checkFileName(path,pd); 141 *FD.Creat RMB 3 File creation date (YY/MM/DD)
93 if (p==0) return -1; 142 *FD.SEG EQU . Beginning of segment list
94 struct stat buf; 143 * Segment List Entry Format
95 if (stat(p,&buf)!=0) return -1; 144 ORG 0
96 if ((buf.st_mode & S_IFMT) == S_IFDIR) { 145 * FDSL.A RMB 3 Segment beginning physical sector number
97 pd->dir = 1; 146 * FDSL.B RMB 2 Segment size
98 return 0; 147 * FDSL.S EQU . Segment list entry size
148 * FD.LS1 EQU FD.SEG+((256-FD.SEG)/FDSL.S-1)*FDSL.S
149 * FD.LS2 EQU (256/FDSL.S-1)*FDSL.S
150 * MINSEC SET 16
151 */
152
153 /*
154 * os9 directory structure
155 *
156 * ORG 0
157 *DIR.NM RMB 29 File name
158 *DIR.FD RMB 3 File descriptor physical sector number
159 *DIR.SZ EQU . Directory record size
160 */
161
162
163 /* read direcotry entry */
164 int os9opendir(PathDesc pd) {
165 DIR *dir;
166 struct dirent *dp;
167 dir = opendir(pd->name);
168 pd->name=fname;
169 int dircount = 0;
170 while ((dp = readdir(dirp)) != NULL) dircout++; // pass 1 to determine the size
171 if (dircount==0) return 0; // should contains . and .. at least
172 pd->sz = dircount*DIR_SZ
173 pd->dirfp = (char *)malloc(dircount*DIR_SZ);
174 rewinddir(dir);
175 int i = 0;
176 while ((dp = readdir(dirp)) != NULL) {
177 i += DIR_SZ;
178 if (i>pd->SZ) return 0;
179 int j = 0;
180 for(j = 0; j < DIR_NM ; j++) {
181 if (j< dp->d_namlen)
182 pd->dirfp[j] = dp->d_name[j];
183 else
184 pd->dirfp[j] = 0;
185 }
186 pd->dirfp[j] = (d_ino&0xff0000)>>16;
187 pd->dirfp[j+1] = (d_ino&0xff00)>>8;
188 pd->dirfp[j+2] = d_ino&0xff;
99 } 189 }
100 pd->dir = 0; 190 pd->fp = fmemopen(pd->dirfp,pd->sz,"r");
101 pd->fp = fopen(p->unixName,"r"); // os9toUnixAttr(attr)); 191 return 0;
102 if (fp) return 0; 192 }
103 return -1; 193
104 } 194
105 195 /* read file descriptor of Path Desc
196 * create file descriptor sector if necessary
197 * if buf!=0, copy it
198 */
199 int filedescriptor(Byte *buf, int len, PathDesc *pd) {
200 struct stat st;
201 if (pd->fd) return 1;
202 pd->fd = (char *)malloc(256);
203 stat((pd->name,&st);
204 os9setmode(pd->fd,st.st_mode);
205 pd->fd+FD_OWN=(st.st_uid&0xff00)>>8;
206 pd->fd+FD_OWN+1=st.st_uid&0xff;
207 os9setdate(pd->fd,st.st_mtimespec);
208 pd->fd+FD_LNK+0=(st.st_uid&0xff000000)>>24;
209 pd->fd+FD_LNK+1=(st.st_uid&0xff0000)>>16;
210 pd->fd+FD_LNK+2=(st.st_uid&0xff00)>>8;
211 pd->fd+FD_LNK+3=st.st_nlink&0xff;
212 os9setdate(pd->fd,st.st_ctimespec);
213 // dummy segment list
214 for(int i=0x10 ; i < 256; i++) pd->fd[i] = 0;
215 return 0;
216 }
217
218 /* read direcotry entry for any file in the directory
219 * we only returns a file descriptor only in the current opened directory
220 *
221 * inode==0 should return disk id section
222 * inode==bitmap should return disk sector map for os9 free command
223 */
224 int fdinfo(Byte *buf,int len, int inode) {
225 int i;
226 for(i=0;i<MAXPDV;i++) {
227 PathDesc *pd = pdv+i;
228 if (!pd->use || !pd->dir) continue;
229 // find inode in directory
230 char *dir = (char *)pd->dirfp;
231 while( dir < dir + pd->sz ) {
232 Byte *p = (Byte *)(dir + DIR_NM);
233 int dinode = (p[0]<<16)+(p[1]<<8)+p[2];
234 if (inode == dir) {
235 filedescriptor(buf,len,pd);
236 return 1;
237 }
238 }
239 }
240 return 0;
241 }
106 242
107 /* 243 /*
108 * I$MakDir Entry Point 244 * each command should have preallocated os9 path descriptor on Y
109 * 245 *
110 * Entry: X = address of the pathlist 246 * name or buffer, can be in a user map, pmem check that drive number ( mem[0x41+IOPAGE] 0 sys 1 user )
111 * 247 * current directory path number mem[0x42+IOPAGE]
112 * Exit: X = last byte of pathlist address 248 */
113 * 249 void do_vdisk(Byte cmd) {
114 * Error: CC Carry set 250 int err;
115 * B = errcode 251 PathDesc *pd = pdv + *areg;
116 */ 252 PathDesc *curdir = pdv+mem[0x42+IOPAGE];
117 253 Byte mode,attr ;
118 int vrbf_mkdir(char **path,PathDesc *pd) { 254 char *path,*next,*buf;
119 char *p = checkFileName(path,pd); 255
120 if (p==0) return -1; 256 switch(cmd) {
121 return mkdir(p,0); 257 /*
122 } 258 * I$Create Entry Point
123 259 *
124 /* 260 * Entry: A = access mode desired
125 * I$ChgDir Entry Point 261 * B = file attributes
126 * 262 * X = address of the pathlist
127 * Entry: 263 *
128 * 264 * Exit: A = pathnum
129 * Exit: 265 * X = last byte of pathlist address
130 * 266 *
131 * Error: CC Carry set 267 * Error: CC Carry set
132 * B = errcode 268 * B = errcode
133 */ 269 */
134 270 case 0xd1:
135 char * vrbf_chdir(char *path) { 271 pd = findPD();
136 cahr *p = checkFileName(path); 272 if (pd==0) { *breg = 0xff; break; }
137 if (p==0) return -1; 273 mode = *areg;
138 struct stat buf; 274 attr = *breg;
139 if (stat(p,&buf)!=0) return -1; 275 path = (char *)pmem(xreg);
140 if ((buf.st_mode & S_IFMT) == S_IFDIR) { 276 next = pd->name = checkFileName(path,pd,curdir);
141 chdir(p); 277 pd->dir = 0;
142 return p; 278 pd->fp = fopen(pd->name, os9toUnixAttr(attr));
143 } 279 if (next!=0 && pd->fp ) {
144 return -1; 280 xreg += ( next - path );
145 } 281 pd->use = 1;
146 282 } else {
147 283 *breg = 0xff;
148 /* 284 free(pd->name);
149 * I$Delete Entry Point 285 }
150 * 286 break;
151 * Entry: 287
152 * 288 /*
153 * Exit: 289 * I$Open Entry Point
154 * 290 *
155 * Error: CC Carry set 291 * Entry: A = access mode desired
156 * B = errcode 292 * X = address of the pathlist
157 */ 293 *
158 294 * Exit: A = pathnum
159 int vrbf_delete(char *path) { 295 * X = last byte of pathlist address
160 cahr *p = checkFileName(path); 296 *
161 if (p==0) return -1; 297 * Error: CC Carry set
162 return rmdir(p); 298 * B = errcode
163 } 299 */
164 300 case 0xd2:
165 301 pd = findPD();
166 /* 302 *breg = 0xff;
167 * I$Seek Entry Point 303 if (pd==0) break;
168 * 304 mode = *areg;
169 * Entry: 305 attr = *breg;
170 * 306 pd->fp = 0;
171 * Exit: 307 path = (char*)pmem(xreg);
172 * 308 next = pd->name = checkFileName(path,pd,curdir);
173 * Error: CC Carry set 309 if (next!=0) {
174 * B = errcode 310 struct stat buf;
175 */ 311 if (stat(pd->name,&buf)!=0) break;
176 312 if ((buf.st_mode & S_IFMT) == S_IFDIR) {
177 int vrbf_seek(PathDesc *p, int seek) { 313 pd->dir = 1;
178 return fseek(p->fp,(off_t)seek,SEEK_SET); 314 os9opendir(pd);
179 } 315 } else {
180 316 char *fname;
181 317 pd->dir = 0;
182 * 318 if (curdir==0 && name[0]!='/') return 0; // no current directory
183 * I$ReadLn Entry Point 319 pd->fp = fopen( fname=findfile(pd->name,curdir),"r+");
184 * 320 free(fname);
185 * Entry: 321 }
186 * 322 }
187 * Exit: 323 if (next!=0 && pd->fp !=0) {
188 * 324 *areg = pd->num;
189 * Error: CC Carry set 325 xreg += ( next - path );
190 * B = errcode 326 }
191 * 327 break;
192 * 328
193 int vrbf_readln(PathDesc *p, byte *buf, int len) { 329 /*
194 if (p->dir) return -1; 330 * I$MakDir Entry Point
195 if (fgets(buf,len,p->fp)) { 331 *
196 int i; 332 * Entry: X = address of the pathlist
197 for(i=0;i<len && buf[i];i++); 333 * B = directory attributes
198 if (i>0 && buf[i-1]=='\n') { 334 *
199 buf[i-1] = '\r'; 335 * Exit: X = last byte of pathlist address
200 return i; 336 *
201 } 337 * Error: CC Carry set
202 } 338 * B = errcode
203 return -1; 339 */
204 } 340
205 341 case 0xd3:
206 /* 342 pd = findPD();
207 * I$Read Entry Point 343 *breg = 0xff;
208 * 344 if (pd==0) break;
209 * Entry: 345 path = (char*)pmem(xreg);
210 * 346 next = checkFileName(path,pd,curdir);
211 * Exit: 347 if (next!=0 && mkdir(pd->name,0)!= 0 ) {
212 * 348 xreg += ( next - path );
213 * Error: CC Carry set 349 *breg = 0;
214 * B = errcode 350 }
215 */ 351 closepd(pd);
216 352 break;
217 int vrbf_read(PathDesc *p, byte *buf, int len) { 353
218 if (p->dir) return dirread(p,buf,len); 354 /*
219 return fread(buf,len,1,p->fp); 355 * I$ChgDir Entry Point
220 } 356 *
221 357 * data dir P$DIO 3-5 contains open dir Path number
222 /* 358 * exec dir P$DIO 9-11 contains open dir Path number
223 * I$WritLn Entry Point 359 *
224 * 360 * Entry:
225 * Entry: 361 *
226 * 362 * *areg = access mode
227 * Exit: 363 * 0 = Use any special device capabilities
228 * 364 * 1 = Read only
229 * Error: CC Carry set 365 * 2 = Write only
230 * B = errcode 366 * 3 = Update (read and write)
231 */ 367 * Entry: X = address of the pathlist
232 368 *
233 int vrbf_writeln(PathDesc *p, byte *buf, int len) { 369 * Exit: X = last byte of pathlist address
234 if (p->dir) return -1; 370 * A = open directory Path Number
235 int = 0; 371 *
236 while(len>0 && *buf !='\r) { 372 * Error: CC Carry set
237 fputc(buf[i++],p->fp); 373 * B = errcode
238 len--; 374 */
375 case 0xd4:
376 pd = findPD();
377 if (pd==0) { *breg = 0xff; break; }
378 path = (char*)pmem(xreg);
379 next = checkFileName(path,pd,curdir);
380 if (next!=0 && os9opendir(pd)) {
381 if (curdir!=pd) closepd(curdir);
382 if (pd->name != path) {
383 free(path);
384 }
385 xreg += ( next - path );
386 *areg = pd->num;
387 *breg = 0;
388 break;
389 }
390 *breg = 0xff;
391 break;
392
393 /*
394 * I$Delete Entry Point
395 *
396 * Entry:
397 *
398 * Exit:
399 *
400 * Error: CC Carry set
401 * B = errcode
402 */
403 case 0xd5: {
404 *breg = 0xff;
405 if (pd==0) break;
406 struct stat st;
407 path = (char*)pmem(xreg);
408 next = checkFileName(path,pd,curdir);
409 if (next!=0 && stat(pd->name,&st)!=0) break;
410 if (next!=0 && ((st->st_mode&S_IFDIR)?rmdir(pd->name):unlink(pd->name)) == 0) {
411 xreg += ( next - path );
412 *breg = 0;
413 }
414 }
415 break;
416
417 /*
418 * I$Seek Entry Point
419 *
420 * Entry Conditions
421 * A path number
422 * X MS 16 bits of the desired file position
423 * Y LS 16 bits of the desired file position
424 *
425 * Exit:
426 *
427 * Error: CC Carry set
428 * B = errcode
429 */
430 case 0xd6: {
431 *breg = 0xff;
432 if (pd==0) break;
433 off_t seek = (xreg<<16)+yreg;
434 *breg = fseek(pd->fp,(off_t)seek,SEEK_SET);
435 break;
436 }
437 /*
438 * I$ReadLn Entry Point
439 *
440 * Entry:
441 * Entry Conditions in correct mmu map
442 * A path number
443 * X address at which to store data
444 * Y maximum number of bytes to read
445 *
446 * Exit:
447 *
448 * Y number of bytes read
449 *
450 * Error: CC Carry set
451 * B = errcode
452 *
453 *
454 */
455 case 0xd7:
456 *breg = 0xff;
457 if (pd==0) break;
458 if (pd->dir) break;
459 buf = (char*)pmem(xreg);
460 if (fgets(buf,yreg,pd->fp)) {
461 int len = yreg;
462 int i;
463 for(i=0;i<len && buf[i];i++);
464 if (i>0 && buf[i-1]=='\n') {
465 buf[i-1] = '\r';
466 yreg = i;
467 }
468 *breg = 0;
469 }
470 break;
471
472 /*
473 * I$Read Entry Point
474 *
475 * Entry:
476 *
477 * Exit:
478 *
479 * Error: CC Carry set
480 * B = errcode
481 */
482 case 0xd8:
483 *breg = 0xff;
484 if (pd==0) break;
485 buf = (char*)pmem(xreg);
486 err = fread(buf,yreg,1,pd->fp);
487 *breg = err==0?0xff:0 ;
488 yreg = err ;
489 break;
490
491 /*
492 * I$WritLn Entry Point
493 *
494 * Entry:
495 * A path number
496 * X address of the data to write
497 * Y maximum number of bytes to read
498
499 *
500 * Exit:
501 * Y number of bytes written
502 *
503 * Error: CC Carry set
504 * B = errcode
505 */
506 case 0xd9:
507 *breg = 0xff;
508 if (pd==0) break;
509 if (pd->dir) break;
510 int len = yreg;
511 int i = 0;
512 Byte *buf = pmem(xreg);
513 while(len>0 && *buf !='\r') {
514 fputc(buf[i++],pd->fp);
515 len--;
516 }
517 if (buf[i]=='\r') {
518 fputc('\n',pd->fp);
519 i++;
520 }
521 *breg = 0;
522 yreg = i;
523 break;
524
525 /*
526 * I$Write Entry Point
527 *
528 * Entry:
529 *
530 * Exit:
531 *
532 * Error: CC Carry set
533 * B = errcode
534 */
535 case 0xda :
536 *breg = 0xff;
537 if (!pd->dir) {
538 Byte *buf = pmem(xreg);
539 int len = yreg;
540 int err = fwrite(buf,len,1,pd->fp);
541 *breg = err?0xff:0;
542 yreg = err;
543 }
544 break;
545
546 /* I$Close Entry Point
547 *
548 * Entry: A = path number
549 *
550 * Exit:
551 *
552 * Error: CC Carry set
553 * B = errcode
554 *
555 */
556 case 0xdb:
557 *breg = 0xff;
558 if (pd==0) break;
559 closepd(pd);
560 *breg = 0;
561 break;
562
563 /*
564 * I$GetStat Entry Point
565 *
566 * Entry:
567 *
568 * Exit:
569 *
570 * Error: CC Carry set
571 * B = errcode
572 */
573 case 0xdc: {
574 struct stat st;
575 off_t pos;
576 switch (*breg) {
577 case 01: // SS.Ready
578 *breg = 0xff;
579 if (pd==0) break;
580 fstat(fileno(pd->fp),&st);
581 if ((pos = ftell(pd->fp))) {
582 xreg = st.st_size - pos;
583 *breg = 0;
584 }
585 break;
586 case 02: // SS.SIZ
587 *breg = 0xff;
588 if (pd==0) break;
589 fstat(fileno(pd->fp),&st);
590 xreg = st.st_size ;
591 *breg = 0;
592 break;
593 case 05: // SS.Pos
594 *breg = 0xff;
595 if (pd==0) break;
596 xreg = ftell(pd->fp);
597 *breg = 0;
598 break;
599 case 15: // SS.FD
600 /* SS.FD ($0F) - Returns a file descriptor
601 * Entry: R$A=Path #
602 * R$B=SS.FD ($0F)
603 * R$X=Pointer to a 256 byte buffer
604 * R$Y=# bytes of FD required
605 * this should be handled in vrbf
606 */
607 *breg = 0xff;
608 if (pd==0) break;
609 *breg = filedescriptor(pmem(xreg), yreg,pd) ;
610 break;
611 case 0x20: // Pos.FDInf mandatry for dir command
612 /* SS.FDInf ($20) - Directly reads a file descriptor from anywhere
613 * on drive.
614 * Entry: R$A=Path #
615 * R$B=SS.FDInf ($20)
616 * R$X=Pointer to a 256 byte buffer
617 * R$Y= MSB - Length of read
618 * LSB - MSB of logical sector #
619 * R$U= LSW of logical sector #
620 */
621 *breg = 0xff;
622 if (pd==0) break;
623 *breg = fdinfo(pmem(xreg),yreg,xreg*0x10000+ureg,pd);
624 break;
625 default:
626 *breg = 0xff;
627 }
628 break;
629 }
630
631 /*
632 * I$SetStat Entry Point
633 *
634 * Entry:
635 *
636 * Exit:
637 *
638 *
639 * Error: CC Carry set
640 * B = errcode
641 */
642 case 0xdd:
643 switch (*breg) {
644 case 0: // SS.Opt
645 case 02: // SS.SIZ
646 case 15: // SS.FD
647 case 0x11: // SS.Lock
648 case 0x10: // SS.Ticks
649 case 0x20: // SS.RsBit
650 case 0x1c: // SS.Attr
651 default:
652 *breg = 0xff;
653 }
654 break;
239 } 655 }
240 if (buf[i]=='\r') { 656 }
241 fputc('\n',p->fp); 657
242 i++; 658
243 }
244 return i;
245 }
246
247 /*
248 * I$Write Entry Point
249 *
250 * Entry:
251 *
252 * Exit:
253 *
254 * Error: CC Carry set
255 * B = errcode
256 */
257
258 int vrbf_write(PathDesc *p, byte *buf, int len) {
259 if (p->dir) return -1;
260 return fwrite(buf,len,1,p->fp);
261 }
262
263 /* I$Close Entry Point
264 *
265 * Entry: A = path number
266 *
267 * Exit:
268 *
269 * Error: CC Carry set
270 * B = errcode
271 *
272 */
273
274 int vrbf_close(PathDesc *p, byte *buf) {
275 return fclose(p->fp);
276 }
277
278 /*
279 * I$GetStat Entry Point
280 *
281 * Entry:
282 *
283 * Exit:
284 *
285 * Error: CC Carry set
286 * B = errcode
287 */
288
289 int vrbf_getstat(int code,OPathDesc *p, O9Stat *s) {
290 struct stat st;
291
292 switch (code) {
293 case 01: // SS.Ready
294 fstat(fileno(p->fp),&st);
295 if (pos = ftell(fp)) {
296 return st.size - pos;
297 }
298 break;
299 case 02: // SS.SIZ
300 fstat(fileno(p->fp),&st);
301 return st.size ;
302 break;
303 case 05: // SS.Pos
304 return ftell(s->fp);
305 break;
306 case 15: // SS.FD
307 break;
308 case 0x20: // Pos.FDInf
309 break;
310 default: return -1;
311 }
312 return -1;
313 }
314
315 /*
316 * I$SetStat Entry Point
317 *
318 * Entry:
319 *
320 * Exit:
321 *
322 * Error: CC Carry set
323 * B = errcode
324 */
325
326 int vrbf_getstat(int code,OPathDesc *p, O9Stat *s) {
327 switch (code) {
328 case 0: // SS.Opt
329 break;
330 case 02: // SS.SIZ
331 break;
332 case 15: // SS.FD
333 break;
334 case 0x11: // SS.Lock
335 break;
336 case 0x10: // SS.Ticks
337 break;
338 case 0x20: // SS.RsBit
339 break;
340 case 0x1c: // SS.Attr
341 break;
342 default: return -1;
343 }
344 }
345
346