/******************************************************** * * * BDS-C Supplementary Library * * release 2 * * * * Steve de Plater, Nov. 1980 * * 66 Priam St. * * Chester Hill, * * NSW, 2162 * * Australia * * Phone: (02) 644 4009 * * * * This file: GC0.C release 1 * * * ********************************************************/ /*======================================================= This routine creates a standard inverse video character set for the Exidy Sorcerer. The inverse character generator resides in both the standard and user graphics areas (ie from 0xfc00 through to 0xffff). */ invid() { int *p1,*p2; for (p1=0xf800,p2=0xfc00;p2;*p2++=~(*p1++)); } /*=======================================================*/ pgraf(filename) char *filename; /* This is "pgraf" which: (1) creates a file called "filename", (2) writes the graphics areas of the Sorcerer (ie char generators for ASCII characters 0x80 to 0xFF) to the file just created. The return codes are: (1) 0 if successful, or (2) -1 otherwise. This allows statements of the form: "if pgraf("mygrafix.txt") goodsave();" */ { int fd; char *buf; return swapout(filename,0xfc00,0xffff); } /*======================================================*/ ggraf(filename) char *filename; /* This is "ggraf" which: (1) reads the file "filename" into the graphics area of the Sorcerer. No check is made on file length (users beware!) (2) is designed to undo what "pgraf" does. The return codes are: (1) 0 if successful, or (2) -1 otherwise. This allows statements of the form: "if ggraf("mygrafix.txt") goodload();" */ { return swapin(filename,0xfc00); } /*======================================================= The Standard Exidy Monitor caller! Calling sequence is of the form: x=monitor("SA IDIOT 100 2BFF 2"); ie it is passed a pointer to a Standard Monitor command string. The required CR is appended automatically by this routine. The value returned is: 0 for an error in the command string, 1 for a successful operation, or NO RETURN AT ALL for errors caught by the monitor itself (sorry about that!) */ monitor(s) char *s; { char *inbuf; inbuf = mwa(); strcpy(inbuf,s); while (*inbuf=toupper(*inbuf)) inbuf++; *inbuf = '\r'; return exycall(); } /*======================================================= This routine returns a character from the console device WITHOUT echoing it to the screen */ char inchar() { return bios(3,0); } /*======================================================= This routine returns a STRING from the console device WITHOUT echoing it to the screen. The string is terminated with a CR (not included in the string). The return value is the length of the string. 's' is a pointer to the string space (which must be large enough to hold it!) */ char instr(s) char *s; { char c, *temp; temp=s; while ((c=bios(3,0)) != '\r') *s++=c; *s='\0'; return strlen(temp); } /*======================================================= Reads Standard Exidy tape file of name 'name' from tape 'unit' into address 'addr'. Returns 0 for bad, 1 for ok. */ rtape(name,unit,addr) char *name; int unit, addr; { char monbuf[50]; sprintf(monbuf,"LO %s %x %x",name,unit,addr); return monitor(monbuf); } /*======================================================= Writes standard Exidy tape file of 'name' from address 'addr1' to address 'addr2' to tape 'unit'. Returns 0 for bad, 1 for ok. */ wtape(name,addr1,addr2,unit) char *name; int addr1, addr2, unit; { char monbuf[50]; sprintf(monbuf,"SA %s %x %x %x",name,addr1,addr2,unit); return monitor(monbuf); } /*======================================================= Reads standard Exidy tape as in 'rtape' but then chains to the execution address on the tape header. NO return values (of course!) */ rtapeg(name,unit,addr) char *name; int unit, addr; { char monbuf[50]; sprintf(monbuf,"LOG %s %x %x",name,unit,addr); monitor(monbuf); } /*======================================================= Undoes what swapin does: ie swaps out to a filename pointed to by name the contents of memory between saddr and eaddr (inclusive). Actually the end addr is calculated to the next 128 bytes ABOVE if the amount of data to be transferred is not actually a multiple of 128. Previous contents are discarded. Returns either 0 if successful, or -1 otherwise. */ swapout(name,saddr,eaddr) char *name; int saddr, eaddr; { int nbl; int fd; if ((fd=creat(name)) == -1) return fd; nbl=((eaddr-saddr)/128)+1; if (write(fd,saddr,nbl) != nbl) { unlink(name); return -1; } close(fd); return 0; } /*======================================================= Fills the plot area from the string pointed to by s. The string is reused until the plot area is full. The address of the (0,0) position of the screen is returned. */ fillplot(s) char *s; { int *pbase,*psize; pbase=getplot(); psize=pbase+3; /* pointers are NOT integers! */ fill(*pbase,*psize,s,1); return *pbase; /* return the screen RAM addr */ } /*======================================================= If (mode==0) fills the plot area from the beginning of the current line to the cursor address. else fills the plot area from the cursor address to the end of the current line. The string pointed to by s is used as many times as needed to fill the area. Returns the cursor address. */ linefill(mode,s) char *s; int mode; { int csr,k,l,*pbase,*ysize,*xsize; csr=cursor(-1); pbase=getplot(); ysize=pbase+1; xsize=ysize+1; l=*pbase; for (k=0;k<*xsize;k++) { if (l>csr) break; l+=*ysize; } if (mode==0) { k=l-*ysize; fill(k,csr,s,0); } else { k=l-1; fill(csr,k,s,0); } return csr; /* return the cursor position */ } /*======================================================= if (mode==0) fills from the beginning of the screen to the cursor. else fills from the cursor to the end of the screen. The string pointed to by s is used as many times as required to fill. Returns the cursor address. */ fillcur(mode,s) char *s; int mode; { int csr,*pbase,*psize,pend; csr=cursor(-1); pbase=getplot(); psize=pbase+3; pend =*pbase+*psize-1; if (mode==0) fill(*pbase,csr,s,0); else fill(csr,pend,s,0); return csr; /* return the cursor position */ } /*======================================================= Returns: 1 if bit 'bit' is set in the word pointed to by 'word', or 0 otherwise. Bits are numbered 0 to 15, right to left. */ tstbit(word,bit) unsigned *word,bit; { if ((1<