changeset 49:947cbecdd8d5

read and dir worked. exec failed
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 21 Jul 2018 19:25:53 +0900
parents ea1b17311bf3
children 1430678cd4fb
files io.c os9/level2/vrbf.asm vdisk.c
diffstat 3 files changed, 161 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/io.c	Fri Jul 20 21:28:57 2018 +0900
+++ b/io.c	Sat Jul 21 19:25:53 2018 +0900
@@ -77,8 +77,8 @@
  *                                       0xd1- VDISK command
  *   IOPAGE + 0x41   drive no           / VDISK drv
  *   IOPAGE + 0x42   LSN2               / VDISK sysmode  0 for system, 1 for user 
- *   IOPAGE + 0x43   LSN1               / VDISK Curdir pd number (2 byte)
- *   IOPAGE + 0x44   LSN0     
+ *   IOPAGE + 0x43   LSN1
+ *   IOPAGE + 0x44   LSN0               / VDISK Curdir pd number 
  *   IOPAGE + 0x45   ADR2               / VDISK caller stack
  *   IOPAGE + 0x46   ADR1
  *   IOPAGE + 0x47                      / VDISK path descriptor address (Y)
--- a/os9/level2/vrbf.asm	Fri Jul 20 21:28:57 2018 +0900
+++ b/os9/level2/vrbf.asm	Sat Jul 21 19:25:53 2018 +0900
@@ -123,10 +123,10 @@
          lda   R$A,u
          bita  #EXEC.
          bne   usechx
-         ldd   P$DIO+4,y        get curwdir #pdnumber
+         ldb   P$DIO+3,y        get curwdir #pdnumber
          bra   s1
-usechx   ldd   P$DIO+10,y       get curxdir #pdnumber
-s1       std   3,x
+usechx   ldb   P$DIO+9,y       get curxdir #pdnumber
+s1       stb   4,x
          rts
 
 er00     puls  y,u,cc
@@ -200,13 +200,11 @@
          bitb  #UPDAT.		read or write mode?
          beq   CD30D		no, skip ahead
 * Change current data dir
-         clr   P$DIO+4,x
-         sta   P$DIO+5,x
+         sta   P$DIO+3,x
 CD30D    bitb  #EXEC.		is it execution dir?
          beq   ok01		no, skip ahead
 * Change current execution directory
-         clr   P$DIO+10,x
-         sta   P$DIO+11,x
+         sta   P$DIO+9,x
          bra   ok01
 
 *
--- a/vdisk.c	Fri Jul 20 21:28:57 2018 +0900
+++ b/vdisk.c	Sat Jul 21 19:25:53 2018 +0900
@@ -15,20 +15,18 @@
 #include <dirent.h>
 #include <string.h>
 #include <time.h>
-
+#include <arpa/inet.h>
 
+static int vdiskdebug = 1;  //   1 trace, 2 filename
 
+extern char *prog ;   // for disass
 #ifdef USE_MMU
-extern char *prog ;   // for disass
 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ;
-//  pmem physical address using current mmu
 //  smem physical address using system mmu
 //  umem physical address using caller's mmu
-#define pmem(a)  mem0(phymem,a,mmu)
 #define smem(a)  mem0(phymem,a,&mem[0x20+IOPAGE])
 #define umem(a)  (mem[0x42+IOPAGE]?mem0(phymem,a,&mem[0x28+IOPAGE]):mem0(phymem,a,&mem[0x20+IOPAGE]))
 #else
-#define pmem(a)  (&mem[a])
 #define umem(a)  (&mem[a])
 #define smem(a)  (&mem[a])
 #endif
@@ -50,18 +48,39 @@
     char *dirfp;
 } PathDesc, *PathDescPtr;
 
+static void 
+vdisklog(Word u,PathDesc *pd, Word pdptr, int curdir,FILE *fp) ;
+
 #define MAXVDRV 4
 
-char *drvRoot[] = { ".",".",".","."};
-PathDesc pdv[MAXPDV];
+static char *drvRoot[] = { ".",".",".","."};
+static PathDesc pdv[MAXPDV];
 
-int setVdisk(int drv,char *name) {
+/*
+ * us 0 system
+ *    1 caller
+ */
+static inline Word 
+getword(Byte *adr) {
+    Word *padr = (Word*)adr;
+    return ntohs(*padr);
+}
+
+static inline void 
+setword(Byte *adr,Word value) {
+    Word *padr = (Word*)adr;
+    *padr = htons(value);
+}
+
+static int 
+setVdisk(int drv,char *name) {
     if (drv<0 || drv>=MAXVDRV) return -1;
     drvRoot[drv] = name;
     return 0;
 }
 
-void closepd(PathDesc *pd) {
+static void 
+closepd(PathDesc *pd) {
     if(pd->fp) fclose(pd->fp) ;
     pd->dir = 0;
     pd->use = 0;
@@ -71,19 +90,54 @@
     free(pd->name); pd->name = 0;
 }
 
+/*
+ * keep track current directory ( most recently 256 entry )
+ * too easy approach
+ */
+char *cdt[512];
+static int cdtptr = 0;
+
+Byte
+setcd(char *name) {
+    int len;
+    for(int i=0;i<256;i++) {
+        if (cdt[i] && strcmp(name,cdt[i])==0) return i;
+    }
+    cdtptr &= 0xff;
+    if (cdt[cdtptr]) free(cdt[cdtptr]);
+    cdt[cdtptr] = (char*)malloc(len=strlen(name)+1);
+    strcpy(cdt[cdtptr],name);
+    return cdtptr++;
+}
+
 #define MAXPAHTLEN 256
 
-char *addCurdir(char *name, PathDesc *pd, PathDesc *curdir) {
+static void
+putOs9str(char *s) {
+    if (s==0) {
+        printf("(null)");
+        return;
+    }
+    while(*s && *s>=' ' && ((*s&0x80)==0)) {
+        putchar(*s); s++;
+    }
+    if (*s&0x80) putchar(*s&0x7f);
+}
+
+static char *
+addCurdir(char *name, PathDesc *pd, int curdir) {
     int ns =0 ;
     char *n = name;
+if(vdiskdebug&0x2) { printf("addcur \""); putOs9str(name); printf("\" cur \""); putOs9str( cdt[curdir]); printf("\"\n"); }
     if (name[0]=='/') {
-        while(*name !='/' && *name!=0) name ++ ; // skip /d0
+        name++; while(*name !='/' && *name!=0) name ++ ; // skip /d0
         while(name[ns]!=0) ns++;
-    } else if (curdir==0 || !curdir->name ) return 0; // no current directory
+    } else if (!cdt[curdir] ) return 0; // no current directory
+    else ns = strlen(name);
     int ps = ns;
     char *base ; 
-    if (name[0]-='/') { 
-        base = drvRoot[pd->drv]; ps += strlen(drvRoot[pd->drv])+1; 
+    if (name[0]=='/') { 
+        base = drvRoot[pd->drv]; ps += strlen(drvRoot[pd->drv])+1;  name++;
     } else if (name[0]==0) { 
         base = drvRoot[pd->drv];
         char *path = (char*)malloc(strlen(base)+1);   // we'll free this, malloc it.
@@ -92,36 +146,47 @@
         path[i]=0;
         return path;
     } else { 
-        name++; base = curdir->name; ps += strlen(curdir->name)+1; 
+        base = cdt[curdir]; ps += strlen(cdt[curdir])+2; 
     }
-    char *path = (char*)malloc(ps+1);
+    char *path = (char*)malloc(ps);
     int i = 0;
     for(;base[i];i++) path[i] = base[i];
     path[i++] = '/';
-    for(int j=0;j<ns;j++,i++) path[i] = name[j];
+    for(int j=0;j<ps;j++,i++) path[i] = name[j];
     path[i++] = 0;
     return path;
 }
 
-char * checkFileName(char *path, PathDesc *pd, PathDesc *curdir) {
+static char * 
+checkFileName(char *path, PathDesc *pd, int curdir) {
     char *p = path;
     char *name = path;
     int maxlen = MAXPAHTLEN;
+if(vdiskdebug) { printf("checkf \""); putOs9str(name); printf("\"\n"); }
     while(*p!=0 && (*p&0x80)==0 && (*p>0x1f) && maxlen-->0) p++;
     if (maxlen==MAXPAHTLEN) return 0;
     if (*p!=0) {
         name = (char *)malloc(p-path+1); 
         strncpy(name,path, MAXPAHTLEN-maxlen);
+        name[MAXPAHTLEN-maxlen-1] &= 0x7f;
         name[MAXPAHTLEN-maxlen] = 0;
     }
     char *name1 = addCurdir(name,pd,curdir);
     if (name1!=name && name1!=path) free(name);
     if (name1==0) return 0;
     pd->name = name1;
+if(vdiskdebug) {
+    printf(" remain = \"");
+    char *p1 = p;
+    while(*p1 && (*p1&0x80)==0 ) { if (*p1<0x20)  printf("(0x%02x)",*p1); else  putchar(*p1); p1++; }
+    if (*p1)  { if ((*p1&0x7f)<0x20)  printf("(0x%02x)",*p1); else  putchar(*p1&0x7f); }
+    printf("\" checkname result \""); putOs9str(pd->name); printf("\"\n");
+}
     return p;
 }
 
-void os9setmode(char *os9mode,int mode) {
+static void 
+os9setmode(char *os9mode,int mode) {
     char m = 0;
     if (mode&S_IFDIR) m|=0x80;
     if (mode&S_IRUSR) m|=0x01;
@@ -134,7 +199,8 @@
     *os9mode = m;
 }
 
-char * os9toUnixAttr(Byte attr) {
+static char * 
+os9toUnixAttr(Byte attr) {
     if ((attr&0x1) && (attr&0x2)) return "r+";
     if (!(attr&0x1) && (attr&0x2)) return "w";
     if ((attr&0x1) && !(attr&0x2)) return "r";
@@ -189,7 +255,8 @@
 
 
 /* read direcotry entry */
-int os9opendir(PathDesc *pd) {
+static int 
+os9opendir(PathDesc *pd) {
     DIR *dir;
     struct dirent *dp;
     if (pd->dirfp) return 0; // already opened
@@ -222,7 +289,8 @@
     return 0;
 }
 
-void os9setdate(char *d,struct timespec * unixtime) {
+static void 
+os9setdate(char *d,struct timespec * unixtime) {
     //   yymmddhhss
     struct tm r;
     localtime_r(&unixtime->tv_sec,&r);
@@ -238,7 +306,8 @@
  *    create file descriptor sector if necessary
  *    if buf!=0, copy it 
  */
-int filedescriptor(Byte *buf, int len, PathDesc *pd) {
+static int 
+filedescriptor(Byte *buf, int len, PathDesc *pd) {
     struct stat st;
     if (pd->fd) return 1;
     pd->fd = (char *)malloc(256);
@@ -247,10 +316,11 @@
     pd->fd[FD_OWN]=(st.st_uid&0xff00)>>8;
     pd->fd[FD_OWN+1]=st.st_uid&0xff;
     os9setdate(pd->fd + FD_DAT,&st.st_mtimespec);
-    pd->fd[FD_LNK+0]=(st.st_uid&0xff000000)>>24;
-    pd->fd[FD_LNK+1]=(st.st_uid&0xff0000)>>16;
-    pd->fd[FD_LNK+2]=(st.st_uid&0xff00)>>8;
-    pd->fd[FD_LNK+3]=st.st_nlink&0xff;
+    pd->fd[FD_LNK]=st.st_nlink&0xff;
+    pd->fd[FD_SIZ+0]=(st.st_size&0xff000000)>>24;
+    pd->fd[FD_SIZ+1]=(st.st_size&0xff0000)>>16;
+    pd->fd[FD_SIZ+2]=(st.st_size&0xff00)>>8;
+    pd->fd[FD_SIZ+3]=st.st_size&0xff;
     os9setdate(pd->fd+FD_Creat,&st.st_ctimespec);
     // dummy segment list
     for(int i=FD_SEG ; i < 256; i++) pd->fd[i] = 0;
@@ -263,20 +333,23 @@
  *     inode==0 should return disk id section
  *     inode==bitmap should return disk sector map for os9 free command
  */
-int fdinfo(Byte *buf,int len, int inode, PathDesc *pd) {
+static int 
+fdinfo(Byte *buf,int len, int inode, PathDesc *pd) {
     int i;
     for(i=0;i<MAXPDV;i++) {
         PathDesc *pd = pdv+i;
         if (!pd->use || !pd->dir) continue;
         //  find inode in directory
         char *dir = (char *)pd->dirfp;
-        while( dir < dir + pd->sz ) {
+        char *end = (char *)pd->dirfp + pd->sz;
+        while( dir < end ) {
             Byte *p = (Byte *)(dir + DIR_NM);
             int dinode = (p[0]<<16)+(p[1]<<8)+p[2];
             if (inode == dinode) {
                 filedescriptor(buf,len,pd);
                 return 1;
             }
+            dir += 0x20;
         }
     }
     return 0;
@@ -285,25 +358,28 @@
 /*
  *   each command should have preallocated os9 path descriptor on Y
  *
- *   name or buffer, can be in a user map, pmem check that drive number ( mem[0x41+IOPAGE]  0 sys 1 user )
+ *   name or buffer, can be in a user map, check that drive number ( mem[0x41+IOPAGE]  0 sys 1 user )
  *   current directory path number                                        mem[0x42+IOPAGE]  
  *   yreg has pd number
  */
-void do_vdisk(Byte cmd) {
+void 
+do_vdisk(Byte cmd) {
     int err;
-    PathDesc *curdir = pdv+mem[0x44+IOPAGE];  // garbage until set
+    int curdir = mem[0x44+IOPAGE];  // garbage until set
     Byte attr ;
-    Word u =  (mem[0x45+IOPAGE]<<8)+mem[0x46+IOPAGE];   // caller's stack in system segment
-    xreg = (*smem(u+4)<<8)+*smem(u+5);
-    yreg = (*smem(u+6)<<8)+*smem(u+7);
+    Word u = getword(&mem[0x45+IOPAGE]);   // caller's stack in system segment
+    Byte *frame = smem(u);
+    xreg = getword(frame+4);
+    yreg = getword(frame+6);
     *areg = *smem(u+1);
     *breg = *smem(u+2);
-    Byte mode = yreg&0xff;
-    Byte *os9pd = smem((mem[0x47+IOPAGE]<<8)+mem[0x48+IOPAGE]);
+    Byte mode = 0;
+    Byte *os9pd = smem(getword(&mem[0x47+IOPAGE]));
     PathDesc *pd = pdv+*os9pd;
     pd->num = *os9pd;
     pd->drv = mem[0x41+IOPAGE];
     char *path,*next,*buf;
+    if (vdiskdebug&1) vdisklog(u,pd,getword(&mem[0x47+IOPAGE]),curdir,stdout);
 
     switch(cmd) {
         /*
@@ -371,6 +447,7 @@
             if (next!=0 && pd->fp !=0) {
                 *breg = 0;
                 *areg = pd->num;
+                *smem(u+1) = *areg ;
                 xreg += ( next - path );
                 pd->use = 1;
             } else {
@@ -421,15 +498,22 @@
         *
         * Error: CC Carry set
         *        B = errcode
+        *
+        *
+        * we keep track a cwd and a cxd for a process using 8bit id
         */
         case 0xd4:
             path = (char*)umem(xreg);
             next = checkFileName(path,pd,curdir);
-            if (next!=0 && os9opendir(pd)==0) {
-                if (curdir!=pd) closepd(curdir);
+            if (next!=0) { 
+                struct stat buf;
+                if (stat(pd->name,&buf)!=0) break;
+                if ((buf.st_mode & S_IFMT) != S_IFDIR) break;
                 xreg += ( next - path );
-                *areg = pd->num;
+                *areg = setcd(pd->name);
+                *smem(u+1) = *areg ;
                 pd->use = 1;
+                pd->dir = 1;
                 *breg = 0;
                 break;
             } 
@@ -467,7 +551,7 @@
         * Entry Conditions
         * A path number
         * X MS 16 bits of the desired file position
-        * Y LS 16 bits of the desired file position
+        * U LS 16 bits of the desired file position
         * 
         * Exit:
         *
@@ -476,7 +560,8 @@
         */
         case 0xd6: {
             *breg = 0xff;
-            off_t seek = (xreg<<16)+yreg;
+            ureg = (*smem(u+8)<<8)+*smem(u+9);
+            off_t seek = (xreg<<16)+ureg;
             *breg = fseek(pd->fp,(off_t)seek,SEEK_SET);
             break;
             }
@@ -503,20 +588,18 @@
             buf = (char*)umem(xreg);
             char *b;
             if ((b=fgets(buf,yreg,pd->fp))) {
-                // set y 
-                *smem(u+6) = (err>>8)&0xff;
-                *smem(u+7) = err&0xff;
                 if (b==0) {
                     *breg = 0xd3;
                     break;
                 }
-                int len = err;
                 int i;
-                for(i=0;i<len && buf[i];i++);
+                for(i=0;i<yreg && buf[i];i++);
                 if (i>0 && buf[i-1]=='\n') {
                     buf[i-1] = '\r';
                     yreg = i;
                 }
+                // set y 
+                setword(smem(u+6),yreg);
                 *breg = 0;
             } 
             break;
@@ -536,8 +619,7 @@
             buf = (char*)umem(xreg);
             int i =  fread(buf,1,yreg,pd->fp);
             // set y 
-            *smem(u+6) = (i>>8)&0xff;
-            *smem(u+7) = i&0xff;
+            setword(smem(u+6),i);
             *breg = (i==0?0xd3:0) ;
             break;
 
@@ -572,8 +654,7 @@
             }
             *breg = 0;
             // set y 
-            *smem(u+6) = (i>>8)&0xff;
-            *smem(u+7) = i&0xff;
+            setword(smem(u+6),i);
             break; 
          }
 
@@ -593,10 +674,9 @@
                 Byte *buf = umem(xreg);
                 int len = yreg;
                 int err = fwrite(buf,1,len,pd->fp);
-                *breg = err?0xff:0;
+                *breg = err?0:0xff;
                 // set y 
-                *smem(u+6) = (i>>8)&0xff;
-                *smem(u+7) = i&0xff;
+                setword(smem(u+6),err);
             }
             break;
 
@@ -677,8 +757,8 @@
                  */
                     *breg = 0xff;
                     if (pd==0) break;
-                    ureg = (*smem(u+8)<<8)+*smem(u+9);
-                    *breg  = fdinfo(pmem(xreg),yreg,xreg*0x10000+ureg,pd);
+                    ureg = getword(smem(u+8));
+                    *breg  = fdinfo(umem(xreg),yreg,xreg*0x10000+ureg,pd);
                     break;
                 default:
                 *breg = 0xff;
@@ -714,9 +794,25 @@
     // return value
     mem[0xffc0] = *breg;
     *smem(u+2) = *breg ;
-    *smem(u+4) = (xreg & 0xff00) >> 8;
-    *smem(u+5) = xreg & 0xff;
+    setword(smem(u+4),xreg);
+}
 
+static void 
+vdisklog(Word u,PathDesc *pd, Word pdptr, int curdir, FILE *fp) {
+    char *cd = cdt[curdir]?cdt[curdir]:"(null)";
+    fprintf(fp,"pd %d 0x%x cd[%d]=%s ",pd->num, pdptr, curdir,cd);
+    Byte *frame = smem(u);
+    sreg  = u;
+    ccreg = frame[0];
+    *areg = frame[1];
+    *breg = frame[2];
+    xreg  = getword(frame+4);
+    yreg  = getword(frame+6);
+    ureg  = getword(frame+8);
+    pcreg  = getword(frame+10)-3;
+    prog = (char*)(umem(pcreg) - pcreg);
+    do_trace(fp);
 }
 
 
+/* end */