Mercurial > hg > Members > kono > os9 > sbc09
comparison vdisk.c @ 45:07c84761da6f
dd vrbf asm code
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 19 Jul 2018 16:21:47 +0900 |
parents | b26c23331d02 |
children | ec9f494497e1 |
comparison
equal
deleted
inserted
replaced
44:b26c23331d02 | 45:07c84761da6f |
---|---|
18 | 18 |
19 #ifdef USE_MMU | 19 #ifdef USE_MMU |
20 extern char *prog ; // for disass | 20 extern char *prog ; // for disass |
21 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; | 21 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; |
22 #define pmem(a) mem0(phymem,a,mmu) | 22 #define pmem(a) mem0(phymem,a,mmu) |
23 #define umem(a) (mem[0x41+IOPAGE]?mem0(phymem,a,&mem[0x21+IOPAGE]):mem0(phymem,a,&mem[0x20+IOPAGE])) | 23 #define umem(a) (mem[0x42+IOPAGE]?mem0(phymem,a,&mem[0x21+IOPAGE]):mem0(phymem,a,&mem[0x20+IOPAGE])) |
24 #else | 24 #else |
25 #define pmem(a) (&mem[a]) | 25 #define pmem(a) (&mem[a]) |
26 #define umem(a) (&mem[a]) | 26 #define umem(a) (&mem[a]) |
27 #endif | 27 #endif |
28 | 28 |
29 #define MAXPDV 256 | 29 #define MAXPDV 256 |
30 | |
30 | 31 |
31 typedef struct pathDesc { | 32 typedef struct pathDesc { |
32 char *name; | 33 char *name; |
33 FILE *fp; | 34 FILE *fp; |
34 int mode; | 35 int mode; |
35 int inode ; // lower 24 bit of unix inode, os9 lsn | 36 int inode ; // lower 24 bit of unix inode, os9 lsn |
36 int num ; | 37 int num ; |
38 int sz ; // used only for directory | |
39 char drv ; | |
37 char use ; | 40 char use ; |
38 char dir; | 41 char dir; |
39 char *fd ; | 42 char *fd ; |
40 char *dirfp; | 43 char *dirfp; |
41 } PathDesc, *PathDescPtr; | 44 } PathDesc, *PathDescPtr; |
42 | 45 |
43 | 46 #define MAXVDRV 4 |
47 | |
48 char drvRoot[] = { '.','.','.','.'}; | |
44 PathDesc pdv[MAXPDV]; | 49 PathDesc pdv[MAXPDV]; |
50 | |
51 int setVdisk(int drv,char *name) { | |
52 if (drv<0 || drv>=MAXVDRV) return -1; | |
53 drvRoot[drv] = name; | |
54 return 0; | |
55 } | |
45 | 56 |
46 PathDesc *findPD() { | 57 PathDesc *findPD() { |
47 for(int i=0;i<MAXPDV;i++) { | 58 for(int i=0;i<MAXPDV;i++) { |
48 if (!pdv[i].use) { | 59 if (!pdv[i].use) { |
49 pdv[i].use = 1; | 60 pdv[i].use = 1; |
50 pdv[i].num = i; | 61 pdv[i].num = i; |
51 pd[i].mode = 0; | 62 pdv[i].mode = 0; |
52 pd[i].fp = 0; | 63 pdv[i].fp = 0; |
53 pd[i].dirfp = 0; | 64 pdv[i].dirfp = 0; |
54 pd[i].name = 0; | 65 pdv[i].name = 0; |
55 pd[i].fd = 0; | 66 pdv[i].fd = 0; |
56 return &pdv[i]; | 67 return &pdv[i]; |
57 } | 68 } |
58 } | 69 } |
59 return 0; | 70 return 0; |
60 } | 71 } |
69 free(pd->fd); pd->fd = 0; | 80 free(pd->fd); pd->fd = 0; |
70 } | 81 } |
71 | 82 |
72 #define MAXPAHTLEN 256 | 83 #define MAXPAHTLEN 256 |
73 | 84 |
74 char *addCurdir(char *name, PathDesc *curdir) { | 85 char *addCurdir(char *name, PathDesc *pd, PathDesc *curdir) { |
75 int ns = strlen(name); | 86 int ns = strlen(name); |
76 int ps = ns; | 87 int ps = ns; |
77 int ds=0 ; | |
78 if (curdir==0 && name[0]!='/') return 0; // no current directory | 88 if (curdir==0 && name[0]!='/') return 0; // no current directory |
79 if (name[0]!='/') ps += (ds=strlen(curdir->name))+1; | 89 char *base ; |
90 if (name[0]!='/') { base = curdir->name; ps += strlen(curdir->name)+1; } | |
91 else { base = drvRoot[pd->drv]; ps += strlen(drvRoot[pd->drv])+1; } | |
80 char *path = (char*)malloc(ps+1); | 92 char *path = (char*)malloc(ps+1); |
81 int i = 0; | 93 int i = 0; |
82 if (ds) { | 94 for(;base[i];i++) path[i] = base[i]; |
83 for(;i<ds;i++) path[i] = curdir->name[i]; | 95 path[i++] = '/'; |
84 path[i++] = '/'; | |
85 } | |
86 for(int j=0;j<ns;j++,i++) path[i] = name[j]; | 96 for(int j=0;j<ns;j++,i++) path[i] = name[j]; |
87 path[i++] = 0; | 97 path[i++] = 0; |
88 return path; | 98 return path; |
89 } | 99 } |
90 | 100 |
96 if (maxlen==MAXPAHTLEN) return 0; | 106 if (maxlen==MAXPAHTLEN) return 0; |
97 if (*p!=0) { | 107 if (*p!=0) { |
98 name = (char *)malloc(p-path+1); | 108 name = (char *)malloc(p-path+1); |
99 strncpy(path,p, MAXPAHTLEN-maxlen); | 109 strncpy(path,p, MAXPAHTLEN-maxlen); |
100 } | 110 } |
101 char *name1 = addCurdir(name,curdir); | 111 char *name1 = addCurdir(name,pd,curdir); |
102 if (name1!=name && name1!=path) free(name); | 112 if (name1!=name && name1!=path) free(name); |
103 pd->name = name1; | 113 pd->name = name1; |
104 return p; | 114 return p; |
105 } | 115 } |
106 | 116 |
107 void os9setmode(char &os9mode,int mode) { | 117 void os9setmode(char *os9mode,int mode) { |
108 char m = 0; | 118 char m = 0; |
109 if (mode&S_IFDIR) m|=0x80; | 119 if (mode&S_IFDIR) m|=0x80; |
110 if (mode&S_IRUSR) m|=0x01; | 120 if (mode&S_IRUSR) m|=0x01; |
111 if (mode&S_IWUSR) m|=0x02; | 121 if (mode&S_IWUSR) m|=0x02; |
112 if (mode&S_IXUSR) m|=0x04; | 122 if (mode&S_IXUSR) m|=0x04; |
148 * FD.LS1 EQU FD.SEG+((256-FD.SEG)/FDSL.S-1)*FDSL.S | 158 * FD.LS1 EQU FD.SEG+((256-FD.SEG)/FDSL.S-1)*FDSL.S |
149 * FD.LS2 EQU (256/FDSL.S-1)*FDSL.S | 159 * FD.LS2 EQU (256/FDSL.S-1)*FDSL.S |
150 * MINSEC SET 16 | 160 * MINSEC SET 16 |
151 */ | 161 */ |
152 | 162 |
163 #define FD_ATT 0 | |
164 #define FD_OWN 1 | |
165 #define FD_DAT 3 | |
166 #define FD_LNK 8 | |
167 #define FD_SIZ 9 | |
168 #define FD_Creat 13 | |
169 #define FD_SEG 16 | |
170 | |
171 | |
153 /* | 172 /* |
154 * os9 directory structure | 173 * os9 directory structure |
155 * | 174 * |
156 * ORG 0 | 175 * ORG 0 |
157 *DIR.NM RMB 29 File name | 176 *DIR.NM RMB 29 File name |
158 *DIR.FD RMB 3 File descriptor physical sector number | 177 *DIR.FD RMB 3 File descriptor physical sector number |
159 *DIR.SZ EQU . Directory record size | 178 *DIR.SZ EQU . Directory record size |
160 */ | 179 */ |
180 #define DIR_SZ 32 | |
181 #define DIR_NM 29 | |
161 | 182 |
162 | 183 |
163 /* read direcotry entry */ | 184 /* read direcotry entry */ |
164 int os9opendir(PathDesc pd) { | 185 int os9opendir(PathDesc *pd) { |
165 DIR *dir; | 186 DIR *dir; |
166 struct dirent *dp; | 187 struct dirent *dp; |
167 dir = opendir(pd->name); | 188 dir = opendir(pd->name); |
168 pd->name=fname; | |
169 int dircount = 0; | 189 int dircount = 0; |
170 while ((dp = readdir(dirp)) != NULL) dircout++; // pass 1 to determine the size | 190 while ((dp = readdir(dir)) != NULL) dircount++; // pass 1 to determine the size |
171 if (dircount==0) return 0; // should contains . and .. at least | 191 if (dircount==0) return 0; // should contains . and .. at least |
172 pd->sz = dircount*DIR_SZ | 192 pd->sz = dircount*DIR_SZ; |
173 pd->dirfp = (char *)malloc(dircount*DIR_SZ); | 193 pd->dirfp = (char *)malloc(dircount*DIR_SZ); |
174 rewinddir(dir); | 194 rewinddir(dir); |
175 int i = 0; | 195 int i = 0; |
176 while ((dp = readdir(dirp)) != NULL) { | 196 while ((dp = readdir(dir)) != NULL) { |
177 i += DIR_SZ; | 197 i += DIR_SZ; |
178 if (i>pd->SZ) return 0; | 198 if (i>pd->sz) return 0; |
179 int j = 0; | 199 int j = 0; |
180 for(j = 0; j < DIR_NM ; j++) { | 200 for(j = 0; j < DIR_NM ; j++) { |
181 if (j< dp->d_namlen) | 201 if (j< dp->d_namlen) |
182 pd->dirfp[j] = dp->d_name[j]; | 202 pd->dirfp[j] = dp->d_name[j]; |
183 else | 203 else |
184 pd->dirfp[j] = 0; | 204 pd->dirfp[j] = 0; |
185 } | 205 } |
186 pd->dirfp[j] = (d_ino&0xff0000)>>16; | 206 pd->dirfp[j] = (dp->d_ino&0xff0000)>>16; |
187 pd->dirfp[j+1] = (d_ino&0xff00)>>8; | 207 pd->dirfp[j+1] = (dp->d_ino&0xff00)>>8; |
188 pd->dirfp[j+2] = d_ino&0xff; | 208 pd->dirfp[j+2] = dp->d_ino&0xff; |
189 } | 209 } |
190 pd->fp = fmemopen(pd->dirfp,pd->sz,"r"); | 210 pd->fp = fmemopen(pd->dirfp,pd->sz,"r"); |
191 return 0; | 211 return 0; |
192 } | 212 } |
193 | 213 |
214 void os9setdate(char *d,struct timespec * unixtime) { | |
215 // yymmddhhss | |
216 } | |
194 | 217 |
195 /* read file descriptor of Path Desc | 218 /* read file descriptor of Path Desc |
196 * create file descriptor sector if necessary | 219 * create file descriptor sector if necessary |
197 * if buf!=0, copy it | 220 * if buf!=0, copy it |
198 */ | 221 */ |
199 int filedescriptor(Byte *buf, int len, PathDesc *pd) { | 222 int filedescriptor(Byte *buf, int len, PathDesc *pd) { |
200 struct stat st; | 223 struct stat st; |
201 if (pd->fd) return 1; | 224 if (pd->fd) return 1; |
202 pd->fd = (char *)malloc(256); | 225 pd->fd = (char *)malloc(256); |
203 stat((pd->name,&st); | 226 stat(pd->name,&st); |
204 os9setmode(pd->fd,st.st_mode); | 227 os9setmode(pd->fd+FD_ATT,st.st_mode); |
205 pd->fd+FD_OWN=(st.st_uid&0xff00)>>8; | 228 pd->fd[FD_OWN]=(st.st_uid&0xff00)>>8; |
206 pd->fd+FD_OWN+1=st.st_uid&0xff; | 229 pd->fd[FD_OWN+1]=st.st_uid&0xff; |
207 os9setdate(pd->fd,st.st_mtimespec); | 230 os9setdate(pd->fd + FD_DAT,&st.st_mtimespec); |
208 pd->fd+FD_LNK+0=(st.st_uid&0xff000000)>>24; | 231 pd->fd[FD_LNK+0]=(st.st_uid&0xff000000)>>24; |
209 pd->fd+FD_LNK+1=(st.st_uid&0xff0000)>>16; | 232 pd->fd[FD_LNK+1]=(st.st_uid&0xff0000)>>16; |
210 pd->fd+FD_LNK+2=(st.st_uid&0xff00)>>8; | 233 pd->fd[FD_LNK+2]=(st.st_uid&0xff00)>>8; |
211 pd->fd+FD_LNK+3=st.st_nlink&0xff; | 234 pd->fd[FD_LNK+3]=st.st_nlink&0xff; |
212 os9setdate(pd->fd,st.st_ctimespec); | 235 os9setdate(pd->fd+FD_Creat,&st.st_ctimespec); |
213 // dummy segment list | 236 // dummy segment list |
214 for(int i=0x10 ; i < 256; i++) pd->fd[i] = 0; | 237 for(int i=FD_SEG ; i < 256; i++) pd->fd[i] = 0; |
215 return 0; | 238 return 0; |
216 } | 239 } |
217 | 240 |
218 /* read direcotry entry for any file in the directory | 241 /* read direcotry entry for any file in the directory |
219 * we only returns a file descriptor only in the current opened directory | 242 * we only returns a file descriptor only in the current opened directory |
220 * | 243 * |
221 * inode==0 should return disk id section | 244 * inode==0 should return disk id section |
222 * inode==bitmap should return disk sector map for os9 free command | 245 * inode==bitmap should return disk sector map for os9 free command |
223 */ | 246 */ |
224 int fdinfo(Byte *buf,int len, int inode) { | 247 int fdinfo(Byte *buf,int len, int inode, PathDesc *pd) { |
225 int i; | 248 int i; |
226 for(i=0;i<MAXPDV;i++) { | 249 for(i=0;i<MAXPDV;i++) { |
227 PathDesc *pd = pdv+i; | 250 PathDesc *pd = pdv+i; |
228 if (!pd->use || !pd->dir) continue; | 251 if (!pd->use || !pd->dir) continue; |
229 // find inode in directory | 252 // find inode in directory |
230 char *dir = (char *)pd->dirfp; | 253 char *dir = (char *)pd->dirfp; |
231 while( dir < dir + pd->sz ) { | 254 while( dir < dir + pd->sz ) { |
232 Byte *p = (Byte *)(dir + DIR_NM); | 255 Byte *p = (Byte *)(dir + DIR_NM); |
233 int dinode = (p[0]<<16)+(p[1]<<8)+p[2]; | 256 int dinode = (p[0]<<16)+(p[1]<<8)+p[2]; |
234 if (inode == dir) { | 257 if (inode == dinode) { |
235 filedescriptor(buf,len,pd); | 258 filedescriptor(buf,len,pd); |
236 return 1; | 259 return 1; |
237 } | 260 } |
238 } | 261 } |
239 } | 262 } |
243 /* | 266 /* |
244 * each command should have preallocated os9 path descriptor on Y | 267 * each command should have preallocated os9 path descriptor on Y |
245 * | 268 * |
246 * name or buffer, can be in a user map, pmem check that drive number ( mem[0x41+IOPAGE] 0 sys 1 user ) | 269 * name or buffer, can be in a user map, pmem check that drive number ( mem[0x41+IOPAGE] 0 sys 1 user ) |
247 * current directory path number mem[0x42+IOPAGE] | 270 * current directory path number mem[0x42+IOPAGE] |
271 * yreg has pd number | |
248 */ | 272 */ |
249 void do_vdisk(Byte cmd) { | 273 void do_vdisk(Byte cmd) { |
250 int err; | 274 int err; |
251 PathDesc *pd = pdv + *areg; | 275 PathDesc *pd = pdv + yreg; |
252 PathDesc *curdir = pdv+mem[0x42+IOPAGE]; | 276 PathDesc *curdir = pdv+mem[0x43+IOPAGE]; |
277 pd->drv = mem[0x41+IOPAGE]; | |
253 Byte mode,attr ; | 278 Byte mode,attr ; |
254 char *path,*next,*buf; | 279 char *path,*next,*buf; |
255 | 280 |
256 switch(cmd) { | 281 switch(cmd) { |
257 /* | 282 /* |
303 if (pd==0) break; | 328 if (pd==0) break; |
304 mode = *areg; | 329 mode = *areg; |
305 attr = *breg; | 330 attr = *breg; |
306 pd->fp = 0; | 331 pd->fp = 0; |
307 path = (char*)pmem(xreg); | 332 path = (char*)pmem(xreg); |
308 next = pd->name = checkFileName(path,pd,curdir); | 333 next = checkFileName(path,pd,curdir); |
309 if (next!=0) { | 334 if (next!=0) { |
310 struct stat buf; | 335 struct stat buf; |
311 if (stat(pd->name,&buf)!=0) break; | 336 if (stat(pd->name,&buf)!=0) break; |
312 if ((buf.st_mode & S_IFMT) == S_IFDIR) { | 337 if ((buf.st_mode & S_IFMT) == S_IFDIR) { |
313 pd->dir = 1; | 338 pd->dir = 1; |
314 os9opendir(pd); | 339 os9opendir(pd); |
315 } else { | 340 } else { |
316 char *fname; | |
317 pd->dir = 0; | 341 pd->dir = 0; |
318 if (curdir==0 && name[0]!='/') return 0; // no current directory | 342 pd->fp = fopen( pd->name,os9toUnixAttr(mode)); |
319 pd->fp = fopen( fname=findfile(pd->name,curdir),"r+"); | |
320 free(fname); | |
321 } | 343 } |
322 } | 344 } |
323 if (next!=0 && pd->fp !=0) { | 345 if (next!=0 && pd->fp !=0) { |
324 *areg = pd->num; | 346 *areg = pd->num; |
325 xreg += ( next - path ); | 347 xreg += ( next - path ); |
405 if (pd==0) break; | 427 if (pd==0) break; |
406 struct stat st; | 428 struct stat st; |
407 path = (char*)pmem(xreg); | 429 path = (char*)pmem(xreg); |
408 next = checkFileName(path,pd,curdir); | 430 next = checkFileName(path,pd,curdir); |
409 if (next!=0 && stat(pd->name,&st)!=0) break; | 431 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) { | 432 if (next!=0 && ((st.st_mode&S_IFDIR)?rmdir(pd->name):unlink(pd->name)) == 0) { |
411 xreg += ( next - path ); | 433 xreg += ( next - path ); |
412 *breg = 0; | 434 *breg = 0; |
413 } | 435 } |
414 } | 436 } |
415 break; | 437 break; |