# HG changeset patch # User Shinji KONO # Date 1531967477 -32400 # Node ID b26c23331d02a6657babd8c79ca331f333204304 # Parent 7a83a6a1685acc14a2f268af39a8bedc23ec4d57 add more function on vdisk diff -r 7a83a6a1685a -r b26c23331d02 Makefile --- a/Makefile Tue Jul 17 17:08:09 2018 +0900 +++ b/Makefile Thu Jul 19 11:31:17 2018 +0900 @@ -22,7 +22,7 @@ # will be installed to ".." BIN=a09 v09 v09c d09 $(SIM_BIN) v09.rom -TARGETS=$(BIN) $(APPS) +TARGETS=$(BIN) $(APPS) vdisk.o OTHER=monitor.s makerom @@ -58,6 +58,9 @@ io.o: io.c $(CC) -c $(CFLAGS) $(V09FLAGS) $< +vdisk.o: vdisk.c v09.h + $(CC) -c $(CFLAGS) $(V09FLAGS) $< + trace.o: trace.c v09.h $(CC) -c $(CFLAGS) $(V09FLAGS) $< diff -r 7a83a6a1685a -r b26c23331d02 io.c --- a/io.c Tue Jul 17 17:08:09 2018 +0900 +++ b/io.c Thu Jul 19 11:31:17 2018 +0900 @@ -71,7 +71,7 @@ * IOPAGE + 0x31- YY/MM/DD/HH/MM/SS * * IOPAGE + 0x40 Disk control 0x81 read/0x55 write 0 ... ok / 0xff .. error - * IOPAGE + 0x41 drive no + * IOPAGE + 0x41 drive no / ( VDISK 0 for system, 1 for user ) * IOPAGE + 0x42 LSN2 * IOPAGE + 0x43 LSN1 * IOPAGE + 0x44 LSN0 @@ -106,8 +106,12 @@ #ifdef USE_MMU extern char *prog ; // for disass extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; +#define pmem(a) mem0(phymem,a,mmu) +#else +#define pmem(a) (&mem[a]) #endif + extern int bpskip ; extern int stkskip ; extern FILE *logfile; @@ -307,6 +311,7 @@ } } + void do_disk(int a, int c) { if (a!=0x40+(IOPAGE&0x1ff)) { mem[(IOPAGE&0xfe00)+a]=c; @@ -316,17 +321,17 @@ int lsn = (mem[IOPAGE+0x42]<<16) + (mem[IOPAGE+0x43]<<8) + mem[IOPAGE+0x44]; int buf = (mem[IOPAGE+0x45]<<8) + mem[IOPAGE+0x46]; if (drv > 1 || disk[drv]==0) goto error; -#ifdef USE_MMU - Byte *phy = mem0(phymem,buf,mmu); -#else - Byte *phy = &mem[buf]; -#endif + Byte *phy = pmem(buf); if (c==0x81) { if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; if (read(fileno(disk[drv]),phy,SECSIZE)==-1) goto error; } else if (c==0x55) { if (lseek(fileno(disk[drv]),lsn*SECSIZE,SEEK_SET)==-1) goto error; if (write(fileno(disk[drv]),phy,SECSIZE)==-1) goto error; +#ifdef VDISK + } else { + do_vdisk(c); +#endif } mem[IOPAGE+0x40] = 0; return; diff -r 7a83a6a1685a -r b26c23331d02 v09.h --- a/v09.h Tue Jul 17 17:08:09 2018 +0900 +++ b/v09.h Thu Jul 19 11:31:17 2018 +0900 @@ -7,6 +7,8 @@ */ +#include + typedef unsigned char Byte; typedef unsigned short Word; diff -r 7a83a6a1685a -r b26c23331d02 vdisk.c --- a/vdisk.c Tue Jul 17 17:08:09 2018 +0900 +++ b/vdisk.c Thu Jul 19 11:31:17 2018 +0900 @@ -5,341 +5,653 @@ * GPL v1 license */ +#define engine extern +#include "v09.h" #include #include #include #include #include +#include +#include -/**************************** -* -* Main entry point for RBF -* - lbra Open - lbra MakDir - lbra ChgDir - lbra Delete - lbra Seek - lbra Read - lbra Write - lbra ReadLn - lbra WriteLn - lbra GetStat - lbra SetStat - lbra Close - */ +#ifdef USE_MMU +extern char *prog ; // for disass +extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; +#define pmem(a) mem0(phymem,a,mmu) +#define umem(a) (mem[0x41+IOPAGE]?mem0(phymem,a,&mem[0x21+IOPAGE]):mem0(phymem,a,&mem[0x20+IOPAGE])) +#else +#define pmem(a) (&mem[a]) +#define umem(a) (&mem[a]) +#endif + +#define MAXPDV 256 + +typedef struct pathDesc { + char *name; + FILE *fp; + int mode; + int inode ; // lower 24 bit of unix inode, os9 lsn + int num ; + char use ; + char dir; + char *fd ; + char *dirfp; +} PathDesc, *PathDescPtr; -/* -* I$Create Entry Point -* -* Entry: A = access mode desired -* B = file attributes -* X = address of the pathlist -* -* Exit: A = pathnum -* X = last byte of pathlist address -* -* Error: CC Carry set -* B = errcode -*/ +PathDesc pdv[MAXPDV]; + +PathDesc *findPD() { + for(int i=0;ifp) ; + pd->use = 0; + pd->fp = 0; + pd->mode = 0; + free(pd->dirfp); pd->dirfp = 0; + free(pd->name); pd->name = 0; + free(pd->fd); pd->fd = 0; +} #define MAXPAHTLEN 256 -char * checkFileName(char *path, PathDesc *pd) { +char *addCurdir(char *name, PathDesc *curdir) { + int ns = strlen(name); + int ps = ns; + int ds=0 ; + if (curdir==0 && name[0]!='/') return 0; // no current directory + if (name[0]!='/') ps += (ds=strlen(curdir->name))+1; + char *path = (char*)malloc(ps+1); + int i = 0; + if (ds) { + for(;iname[i]; + path[i++] = '/'; + } + for(int j=0;jlastChar = p; while(*p!=0 && (*p&80)==0 && maxlen-->0) p++; if (maxlen==MAXPAHTLEN) return 0; - pd->lastChar = p; if (*p!=0) { - p = (char *)malloc(len+1); + name = (char *)malloc(p-path+1); strncpy(path,p, MAXPAHTLEN-maxlen); } + char *name1 = addCurdir(name,curdir); + if (name1!=name && name1!=path) free(name); + pd->name = name1; return p; } -int os9toUnixAttr(Byte attr) { - return "r+"; -} - -int vrbf_create(byte mode,Byte attr,char *path,PathDesc *pd) { - char *p = pd->unixName = checkFileName(path,pd); - if (p==0) return -1; - p->dir = 0; - p->fp = fopen(p->unixName,"w+"); // os9toUnixAttr(attr)); - if (fd) return 0; - return -1; +void os9setmode(char &os9mode,int mode) { + char m = 0; + if (mode&S_IFDIR) m|=0x80; + if (mode&S_IRUSR) m|=0x01; + if (mode&S_IWUSR) m|=0x02; + if (mode&S_IXUSR) m|=0x04; + if (mode&S_IROTH) m|=0x08; + if (mode&S_IWOTH) m|=0x10; + if (mode&S_IXOTH) m|=0x20; + m|=0x60; // always sharable + *os9mode = m; } - -/* -* I$Open Entry Point -* -* Entry: A = access mode desired -* X = address of the pathlist -* -* Exit: A = pathnum -* X = last byte of pathlist address -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_open(byte mode,char *path, PathDesc *pd) { - char *p = pd->unixName = checkFileName(path,pd); - if (p==0) return -1; - struct stat buf; - if (stat(p,&buf)!=0) return -1; - if ((buf.st_mode & S_IFMT) == S_IFDIR) { - pd->dir = 1; - return 0; - } - pd->dir = 0; - pd->fp = fopen(p->unixName,"r"); // os9toUnixAttr(attr)); - if (fp) return 0; - return -1; -} - - -/* -* I$MakDir Entry Point -* -* Entry: X = address of the pathlist -* -* Exit: X = last byte of pathlist address -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_mkdir(char **path,PathDesc *pd) { - char *p = checkFileName(path,pd); - if (p==0) return -1; - return mkdir(p,0); +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"; + return "r"; } /* -* I$ChgDir Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ + * os9 file descriptor + * * File Descriptor Format + * + * The file descriptor is a sector that is present for every file + * on an RBF device. It contains attributes, modification dates, + * and segment information on a file. + * + * ORG 0 + *FD.ATT RMB 1 Attributes + *FD.OWN RMB 2 Owner + *FD.DAT RMB 5 Date last modified + *FD.LNK RMB 1 Link count + *FD.SIZ RMB 4 File size + *FD.Creat RMB 3 File creation date (YY/MM/DD) + *FD.SEG EQU . Beginning of segment list + * Segment List Entry Format + ORG 0 + * FDSL.A RMB 3 Segment beginning physical sector number + * FDSL.B RMB 2 Segment size + * FDSL.S EQU . Segment list entry size + * FD.LS1 EQU FD.SEG+((256-FD.SEG)/FDSL.S-1)*FDSL.S + * FD.LS2 EQU (256/FDSL.S-1)*FDSL.S + * MINSEC SET 16 + */ -char * vrbf_chdir(char *path) { - cahr *p = checkFileName(path); - if (p==0) return -1; - struct stat buf; - if (stat(p,&buf)!=0) return -1; - if ((buf.st_mode & S_IFMT) == S_IFDIR) { - chdir(p); - return p; - } - return -1; -} +/* + * os9 directory structure + * + * ORG 0 + *DIR.NM RMB 29 File name + *DIR.FD RMB 3 File descriptor physical sector number + *DIR.SZ EQU . Directory record size + */ -/* -* I$Delete Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_delete(char *path) { - cahr *p = checkFileName(path); - if (p==0) return -1; - return rmdir(p); +/* read direcotry entry */ +int os9opendir(PathDesc pd) { + DIR *dir; + struct dirent *dp; + dir = opendir(pd->name); + pd->name=fname; + int dircount = 0; + while ((dp = readdir(dirp)) != NULL) dircout++; // pass 1 to determine the size + if (dircount==0) return 0; // should contains . and .. at least + pd->sz = dircount*DIR_SZ + pd->dirfp = (char *)malloc(dircount*DIR_SZ); + rewinddir(dir); + int i = 0; + while ((dp = readdir(dirp)) != NULL) { + i += DIR_SZ; + if (i>pd->SZ) return 0; + int j = 0; + for(j = 0; j < DIR_NM ; j++) { + if (j< dp->d_namlen) + pd->dirfp[j] = dp->d_name[j]; + else + pd->dirfp[j] = 0; + } + pd->dirfp[j] = (d_ino&0xff0000)>>16; + pd->dirfp[j+1] = (d_ino&0xff00)>>8; + pd->dirfp[j+2] = d_ino&0xff; + } + pd->fp = fmemopen(pd->dirfp,pd->sz,"r"); + return 0; } -/* -* I$Seek Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_seek(PathDesc *p, int seek) { - return fseek(p->fp,(off_t)seek,SEEK_SET); -} - - -* -* I$ReadLn Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -* -* -int vrbf_readln(PathDesc *p, byte *buf, int len) { - if (p->dir) return -1; - if (fgets(buf,len,p->fp)) { - int i; - for(i=0;i0 && buf[i-1]=='\n') { - buf[i-1] = '\r'; - return i; - } - } - return -1; +/* read file descriptor of Path Desc + * create file descriptor sector if necessary + * if buf!=0, copy it + */ +int filedescriptor(Byte *buf, int len, PathDesc *pd) { + struct stat st; + if (pd->fd) return 1; + pd->fd = (char *)malloc(256); + stat((pd->name,&st); + os9setmode(pd->fd,st.st_mode); + pd->fd+FD_OWN=(st.st_uid&0xff00)>>8; + pd->fd+FD_OWN+1=st.st_uid&0xff; + os9setdate(pd->fd,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; + os9setdate(pd->fd,st.st_ctimespec); + // dummy segment list + for(int i=0x10 ; i < 256; i++) pd->fd[i] = 0; + return 0; } -/* -* I$Read Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_read(PathDesc *p, byte *buf, int len) { - if (p->dir) return dirread(p,buf,len); - return fread(buf,len,1,p->fp); -} - -/* -* I$WritLn Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_writeln(PathDesc *p, byte *buf, int len) { - if (p->dir) return -1; - int = 0; - while(len>0 && *buf !='\r) { - fputc(buf[i++],p->fp); - len--; +/* read direcotry entry for any file in the directory + * we only returns a file descriptor only in the current opened directory + * + * 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) { + int i; + for(i=0;iuse || !pd->dir) continue; + // find inode in directory + char *dir = (char *)pd->dirfp; + while( dir < dir + pd->sz ) { + Byte *p = (Byte *)(dir + DIR_NM); + int dinode = (p[0]<<16)+(p[1]<<8)+p[2]; + if (inode == dir) { + filedescriptor(buf,len,pd); + return 1; + } + } } - if (buf[i]=='\r') { - fputc('\n',p->fp); - i++; - } - return i; + return 0; } /* -* I$Write Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_write(PathDesc *p, byte *buf, int len) { - if (p->dir) return -1; - return fwrite(buf,len,1,p->fp); -} + * 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 ) + * current directory path number mem[0x42+IOPAGE] + */ +void do_vdisk(Byte cmd) { + int err; + PathDesc *pd = pdv + *areg; + PathDesc *curdir = pdv+mem[0x42+IOPAGE]; + Byte mode,attr ; + char *path,*next,*buf; -/* I$Close Entry Point -* -* Entry: A = path number -* -* Exit: -* -* Error: CC Carry set -* B = errcode -* -*/ - -int vrbf_close(PathDesc *p, byte *buf) { - return fclose(p->fp); -} - -/* -* I$GetStat Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ - -int vrbf_getstat(int code,OPathDesc *p, O9Stat *s) { - struct stat st; - - switch (code) { - case 01: // SS.Ready - fstat(fileno(p->fp),&st); - if (pos = ftell(fp)) { - return st.size - pos; + switch(cmd) { + /* + * I$Create Entry Point + * + * Entry: A = access mode desired + * B = file attributes + * X = address of the pathlist + * + * Exit: A = pathnum + * X = last byte of pathlist address + * + * Error: CC Carry set + * B = errcode + */ + case 0xd1: + pd = findPD(); + if (pd==0) { *breg = 0xff; break; } + mode = *areg; + attr = *breg; + path = (char *)pmem(xreg); + next = pd->name = checkFileName(path,pd,curdir); + pd->dir = 0; + pd->fp = fopen(pd->name, os9toUnixAttr(attr)); + if (next!=0 && pd->fp ) { + xreg += ( next - path ); + pd->use = 1; + } else { + *breg = 0xff; + free(pd->name); } break; - case 02: // SS.SIZ - fstat(fileno(p->fp),&st); - return st.size ; - break; - case 05: // SS.Pos - return ftell(s->fp); + + /* + * I$Open Entry Point + * + * Entry: A = access mode desired + * X = address of the pathlist + * + * Exit: A = pathnum + * X = last byte of pathlist address + * + * Error: CC Carry set + * B = errcode + */ + case 0xd2: + pd = findPD(); + *breg = 0xff; + if (pd==0) break; + mode = *areg; + attr = *breg; + pd->fp = 0; + path = (char*)pmem(xreg); + next = pd->name = checkFileName(path,pd,curdir); + if (next!=0) { + struct stat buf; + if (stat(pd->name,&buf)!=0) break; + if ((buf.st_mode & S_IFMT) == S_IFDIR) { + pd->dir = 1; + os9opendir(pd); + } else { + char *fname; + pd->dir = 0; + if (curdir==0 && name[0]!='/') return 0; // no current directory + pd->fp = fopen( fname=findfile(pd->name,curdir),"r+"); + free(fname); + } + } + if (next!=0 && pd->fp !=0) { + *areg = pd->num; + xreg += ( next - path ); + } break; - case 15: // SS.FD - break; - case 0x20: // Pos.FDInf + + /* + * I$MakDir Entry Point + * + * Entry: X = address of the pathlist + * B = directory attributes + * + * Exit: X = last byte of pathlist address + * + * Error: CC Carry set + * B = errcode + */ + + case 0xd3: + pd = findPD(); + *breg = 0xff; + if (pd==0) break; + path = (char*)pmem(xreg); + next = checkFileName(path,pd,curdir); + if (next!=0 && mkdir(pd->name,0)!= 0 ) { + xreg += ( next - path ); + *breg = 0; + } + closepd(pd); break; - default: return -1; - } - return -1; -} + + /* + * I$ChgDir Entry Point + * + * data dir P$DIO 3-5 contains open dir Path number + * exec dir P$DIO 9-11 contains open dir Path number + * + * Entry: + * + * *areg = access mode + * 0 = Use any special device capabilities + * 1 = Read only + * 2 = Write only + * 3 = Update (read and write) + * Entry: X = address of the pathlist + * + * Exit: X = last byte of pathlist address + * A = open directory Path Number + * + * Error: CC Carry set + * B = errcode + */ + case 0xd4: + pd = findPD(); + if (pd==0) { *breg = 0xff; break; } + path = (char*)pmem(xreg); + next = checkFileName(path,pd,curdir); + if (next!=0 && os9opendir(pd)) { + if (curdir!=pd) closepd(curdir); + if (pd->name != path) { + free(path); + } + xreg += ( next - path ); + *areg = pd->num; + *breg = 0; + break; + } + *breg = 0xff; + break; + + /* + * I$Delete Entry Point + * + * Entry: + * + * Exit: + * + * Error: CC Carry set + * B = errcode + */ + case 0xd5: { + *breg = 0xff; + if (pd==0) break; + struct stat st; + path = (char*)pmem(xreg); + next = checkFileName(path,pd,curdir); + if (next!=0 && stat(pd->name,&st)!=0) break; + if (next!=0 && ((st->st_mode&S_IFDIR)?rmdir(pd->name):unlink(pd->name)) == 0) { + xreg += ( next - path ); + *breg = 0; + } + } + break; -/* -* I$SetStat Entry Point -* -* Entry: -* -* Exit: -* -* Error: CC Carry set -* B = errcode -*/ + /* + * I$Seek Entry Point + * + * Entry Conditions + * A path number + * X MS 16 bits of the desired file position + * Y LS 16 bits of the desired file position + * + * Exit: + * + * Error: CC Carry set + * B = errcode + */ + case 0xd6: { + *breg = 0xff; + if (pd==0) break; + off_t seek = (xreg<<16)+yreg; + *breg = fseek(pd->fp,(off_t)seek,SEEK_SET); + break; + } + /* + * I$ReadLn Entry Point + * + * Entry: + * Entry Conditions in correct mmu map + * A path number + * X address at which to store data + * Y maximum number of bytes to read + * + * Exit: + * + * Y number of bytes read + * + * Error: CC Carry set + * B = errcode + * + * + */ + case 0xd7: + *breg = 0xff; + if (pd==0) break; + if (pd->dir) break; + buf = (char*)pmem(xreg); + if (fgets(buf,yreg,pd->fp)) { + int len = yreg; + int i; + for(i=0;i0 && buf[i-1]=='\n') { + buf[i-1] = '\r'; + yreg = i; + } + *breg = 0; + } + break; + + /* + * I$Read Entry Point + * + * Entry: + * + * Exit: + * + * Error: CC Carry set + * B = errcode + */ + case 0xd8: + *breg = 0xff; + if (pd==0) break; + buf = (char*)pmem(xreg); + err = fread(buf,yreg,1,pd->fp); + *breg = err==0?0xff:0 ; + yreg = err ; + break; + + /* + * I$WritLn Entry Point + * + * Entry: + * A path number + * X address of the data to write + * Y maximum number of bytes to read + + * + * Exit: + * Y number of bytes written + * + * Error: CC Carry set + * B = errcode + */ + case 0xd9: + *breg = 0xff; + if (pd==0) break; + if (pd->dir) break; + int len = yreg; + int i = 0; + Byte *buf = pmem(xreg); + while(len>0 && *buf !='\r') { + fputc(buf[i++],pd->fp); + len--; + } + if (buf[i]=='\r') { + fputc('\n',pd->fp); + i++; + } + *breg = 0; + yreg = i; + break; -int vrbf_getstat(int code,OPathDesc *p, O9Stat *s) { - switch (code) { - case 0: // SS.Opt + /* + * I$Write Entry Point + * + * Entry: + * + * Exit: + * + * Error: CC Carry set + * B = errcode + */ + case 0xda : + *breg = 0xff; + if (!pd->dir) { + Byte *buf = pmem(xreg); + int len = yreg; + int err = fwrite(buf,len,1,pd->fp); + *breg = err?0xff:0; + yreg = err; + } break; - case 02: // SS.SIZ - break; - case 15: // SS.FD + + /* I$Close Entry Point + * + * Entry: A = path number + * + * Exit: + * + * Error: CC Carry set + * B = errcode + * + */ + case 0xdb: + *breg = 0xff; + if (pd==0) break; + closepd(pd); + *breg = 0; break; - case 0x11: // SS.Lock - break; - case 0x10: // SS.Ticks + + /* + * I$GetStat Entry Point + * + * Entry: + * + * Exit: + * + * Error: CC Carry set + * B = errcode + */ + case 0xdc: { + struct stat st; + off_t pos; + switch (*breg) { + case 01: // SS.Ready + *breg = 0xff; + if (pd==0) break; + fstat(fileno(pd->fp),&st); + if ((pos = ftell(pd->fp))) { + xreg = st.st_size - pos; + *breg = 0; + } + break; + case 02: // SS.SIZ + *breg = 0xff; + if (pd==0) break; + fstat(fileno(pd->fp),&st); + xreg = st.st_size ; + *breg = 0; + break; + case 05: // SS.Pos + *breg = 0xff; + if (pd==0) break; + xreg = ftell(pd->fp); + *breg = 0; + break; + case 15: // SS.FD + /* SS.FD ($0F) - Returns a file descriptor + * Entry: R$A=Path # + * R$B=SS.FD ($0F) + * R$X=Pointer to a 256 byte buffer + * R$Y=# bytes of FD required + * this should be handled in vrbf + */ + *breg = 0xff; + if (pd==0) break; + *breg = filedescriptor(pmem(xreg), yreg,pd) ; + break; + case 0x20: // Pos.FDInf mandatry for dir command + /* SS.FDInf ($20) - Directly reads a file descriptor from anywhere + * on drive. + * Entry: R$A=Path # + * R$B=SS.FDInf ($20) + * R$X=Pointer to a 256 byte buffer + * R$Y= MSB - Length of read + * LSB - MSB of logical sector # + * R$U= LSW of logical sector # + */ + *breg = 0xff; + if (pd==0) break; + *breg = fdinfo(pmem(xreg),yreg,xreg*0x10000+ureg,pd); + break; + default: + *breg = 0xff; + } break; - case 0x20: // SS.RsBit + } + + /* + * I$SetStat Entry Point + * + * Entry: + * + * Exit: + * + * + * Error: CC Carry set + * B = errcode + */ + case 0xdd: + switch (*breg) { + case 0: // SS.Opt + case 02: // SS.SIZ + case 15: // SS.FD + case 0x11: // SS.Lock + case 0x10: // SS.Ticks + case 0x20: // SS.RsBit + case 0x1c: // SS.Attr + default: + *breg = 0xff; + } break; - case 0x1c: // SS.Attr - break; - default: return -1; } }