+dhe Posted December 3, 2021 Share Posted December 3, 2021 I recently re-setup Vern Jensen's c99 Starter Kit on Classic99, and though I'd put my notes here. The starting article can be found here: http://ftp.whtech.com/magazines/micropendium/mp961112.pdf -- isn't ftp.whtech.com a great resources? Many sites have come and gone, but this one has been around forever! Software you will need: Tursi's Classic99 - http://harmlesslion.com/software/classic99 Fred Kaal's ti99dir - https://www.ti99-geek.nl/Projects/ti99dir/ti99dir.html Vern L. Jensens StarterKit - https://ftp.whtech.com/programming/c99/StarterKit/ Get all of the files: Size Name of Archive File 120,704 c99ccfwb.ark 51,072 c99docs.ark 34,688 c99libs.ark 04,576 c99prog.ark 1,152 c99readme 55,936 c99utils.ark Classic99 Setup Notes: A few tricks I use with Classic99, of course we live in America, so you can also HIYW. I have a folder called classic99_vm\ under there I have directories with configured environments like c99, rxb, tp99, fortran99 classic99_vm\c99 \tp99 \rxb {etc} The default for Classic99 is having a bunch of directories off the root of classic99 like DSK1, DSK2, DSK3. I prefer to make a subdirectory called mydisks, then I create directories in lower case dsk1 .. dsk6. This scheme keeps you from potentially having any upgrades write in to your disk file directories, also it's easy enough to copy mydisks and past them some place else as a backup. When I go to do a full backup, I just copy the Classic99_vm folder (under everything under it) to a USB sticker and rename it with the data. Let's start Classic99 and point the disks setup to the six directories you just made. Make sure you can catalog each without error. Shutdown Classic99. Let's take a quick look at the readme from 1999. "README These five archive files represent the content of the five disk in Vernon Jensens c99 starter kit. These disk were originally offered as a companion for a series of tutorials on c99 the Vernon wrote for Micropendium. 1. Funnelweb + c99 compiler c99ccfwb@ 2. c99 Programs c99prog@ 3. c99 Utils by Bruce Harrison c99utils@ 4. c99 Libraries c99libs@ 5. c99 Documentation c99docs@ Each archive file can unarc to a diskette with 720 free sectors, ie. ds/sd or ss/dd. They were originally distributed in ds/sd format. Warning: The document files are in a combination of formats, runoff and TI Writer Formatter. Dan H. Eicher <== still kicking. 03.29.1999 eicher@delphi.com <== Email address deader then a door nail. Copy the files where your going to need/use them: -------------------------------------------------------------- Start up ti99dir. (say a silent thanks to Fred). Go to where you stashed the Starterkit Files. Put the contents of c99ccfwb.ark in to mydisks\dsk1\ Put the contents of both c99libs.ark and c99utils.ark in mydisks\dsk2\ Well put aside dsk3. for our source code. Well put aside dsk5 compiling to assembler, and compiling from assembler to object. dsk6 we can utilize for utilities - like I like to have dm2k on hand. maybe put in here some rxb utilitiy programs that help you in your programming. ------------------------------------------- While the versions of the docs are for c99 Ver4, the c99 compiler was upgraded by Winfried Winkler and displays REV# 5.1.FW You can let Vern's articles walk you from here, just remember, he was constrained by most people having only two drives, with Classic99 we can have as many as we want... 5 Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 3, 2021 Author Share Posted December 3, 2021 Has anyone stayed in touch with Winfried - I think it's Dr. Winkler? It would be nice to have the source code to his version 5.1 available... 1 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted December 3, 2021 Share Posted December 3, 2021 20 minutes ago, dhe said: Has anyone stayed in touch with Winfried - I think it's Dr. Winkler? It would be nice to have the source code to his version 5.1 available... He's still in Berlin, last I knew. He showed up to one of the European Treffs a few years ago, IIRC. 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 6, 2021 Author Share Posted December 6, 2021 From Vern Jensen's Starter Kit: "If, after quitting the c99 program, your computer locks up, it is because the c99 program was loaded "on top" of Funnelweb in memory and, therefore, when the TI tried to return to the Funnelweb program, it locked up. This won't happen if you load the c99 program from the Editor/Assembler cartridge, because the E/A program is kept on the cartridge, not in RAM, and therefore can't be overwritten. This isn't terribly important because most programs don't have a "Quit" option anyway; they simply force you to reset your computer when you want to stop the program." Would it be reasonably possible, with assembler, to dump SRAM and 32K out to SAMS card, run Tom Bently's loader, run c99 program, then as a last assembly routine, copy everything back in place begin execution at the fweb menu screen - or are there two many variable like gpws, cpu status registers to make that viable? - or would a better approach be - Since running this on a pc, a more productive approach, figure out how to make Tom Bentley's C-Loader run automatically on restart of Classic99 and keep another window open with the Funnelweb Menu? Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 22, 2021 Author Share Posted December 22, 2021 My current dev environment is open two copies of Classic99. In one open Freds Editor. In the 2nd copy funnelweb as configured in the starter pack. The c compiler will eat your source if you accidentally type output for input. So I keep a copy in memory so when that happens the day is saved, by just saving back out the source. Does anyone have the source code to either c99 R4 by Clint or 5.1 by Winfried Winkler? Those would be very helpful to have. Supposedly each of these where available for the cost of a disk. Last question for the night, did funnelweb ever make it back in to a compile-able form? Other tricks - F7 pulls up QD Quick and dirty? directory manager, which is handy and sometimes if there is a problem with your compile, using the funnelweb editor you can pull up the assembler source and track the problem down. I have a program that lists some examples and questions I will be putting up. TI's documents where very liberal with examples, the c99 docs not so much. Next challenge is a bit of file I/O - then I'll work up to the wall I hit in TP99 - doing a diskette directory. If anyone has Clint's phone, I'd be happy to call him. PM me please. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 22, 2021 Share Posted December 22, 2021 11 minutes ago, dhe said: Does anyone have the source code to either c99 R4 by Clint or 5.1 by Winfried Winkler? Have you looked at Fred’s (@F.G. Kaal) C99 stuff on the Projects page on his website? ...lee Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 22, 2021 Author Share Posted December 22, 2021 Yea, Lee appreciate your pointing out that resource. I'd seen it, and I'm hoping to learn to craw in c99 before I walk. One of the quirks of c99 I'm getting adjusted to, is that the c compiler, almost always compiles. It's when you go to the assembly process you get problems and have to look in to the assembler source. Also, getting used to the fact, assembler comes with a manual, forth comes with a manual. c99 comes with some programmer notes and a wish of good luck! ? 3 Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 22, 2021 Author Share Posted December 22, 2021 I've been stitching up some example programs in to working examples. I've found just like old floppies that experience bit rot, how-to articles suffer bit route and need correcting either because of versioning issues or printing issues. Here are the examples I've gotten working so far. The biggest quirk I couldn't figure out was the switch function. I could not get the function to execute, until I assigned a variable to the function.. ODD... DSK3.HELLO;L /* THE LOADER FOR THE CODE */ DSK4.HELLO;O DSK2.CSUP DSK2.PRINTF DSK2.GRF1 #include "DSK2.STDIO" #include "DSK2.GRF1;H" /* includes are dv */ extern printf(); /* extern are df - must be loaded */ #define FALSE 0 #define TRUE 1 /* sometimes true is def as !FALSE */ int num; /* used for pointer test */ int a; /* dumby variable */ int *p1; /* pointer must be char or int types */ char Ain[10]; /* buffer to hold input */ int x,y; main() { int c; /* compiler angered if vars not defined at begining */ num=10; /* only avaiable to main, not functions */ x=2; y=19; puts("\nHello World\n\n"); /* display values in decimal, oct and hex */ printf(">Print value of num different ways< \n"); printf("Num in Dec is: %d \n", num); printf("Num in Oct is: %o \n", num); printf("Num in Hex is: %x \n", num); Fwait(); /* define values */ printf(">Display defined values< \n"); printf("def Value of FALSE is: %d \n",FALSE); printf("def Value of TRUE is: %d \n",TRUE); Fwait(); /* call a function */ c=Fadd(5,2); /* call dan made function */ printf(">Call a function to add 5 and 2< \n"); printf("Result of add fct: %d \n",c); Fwait(); /* keyboard input */ printf(">Get keyboard input< \n"); printf("Hello. What's your name? \n"); a=gets(Ain); puts("Nice to meet you: "); printf("%s \n",Ain); Fwait(); /* pointer */ printf(">Pointer Examples< \n"); printf("Address of var num: %d \n", &num); p1 = # /* load memory address of num in p1 */ printf("var num has a value of: %d \n",*p1); /* give me the value at this memory address */ printf("Value X,Y %d, %d \n",x,y); a=Fswitch(&x,&y); printf("After switch.. \n"); printf("Value X,Y %d, %d \n",x,y); Fwait(); /* graphics and text */ text(); printf(">Text Mode Example< \n"); printf("01234567890123456789001234567890123456789 \n"); Fwait(); grf1(); printf(">Graphics 1 Mode Examples< \n"); printf("01234567890123456789001234567890123456789 \n"); Fwait(); exit(0); } Fadd(n1,n2) int n1, n2; { int sum; sum=n1+n2; return(sum); } Fswitch(n1,n2) int *n1,*n2; { int temp; temp=*n1; *n1=*n2; *n2=temp; } Fwait() { printf("Press any key to continue. \n\n"); a=getchar(); /* wait to end */ } /* dhe L.D.O.M. 12/21/2021 */ /* need to figure out puts/twrite/display */ /* because we are using twos compliment for decimal rep we get back negative numbers */ /* Doesn't look like fprint respect %x vs %X */ /* puts doesn't accept format specs like %s */ /* 12/20/2021 Odd quirk Fadd works, Fswitch didn't. the only diff c=fadd(); vs fswitch after adding an c=fswitch(); then it was actually called To keep sane, make sure you have a line between int x,y,z and then next line of code */ /* naming conventions starts with: A Array Ain[] = array input F Function Fwait = a wait funtion */ Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 22, 2021 Author Share Posted December 22, 2021 In February 1986 - Tom Bentley release TCIO for file I/O. In November 1986 - Clint Pulley released version 4 of his c99 compiler - and it included fscanf. Is anyone here familiar enough with the two libraries to list the advantages/dis-advantages of each? Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 23, 2021 Share Posted December 23, 2021 I know it doesn't matter too much if you're just programming for fun, but be warned that c99's syntax is /really/ obsolete and it will teach you bad habits that will make moving to gcc or anything more modern a little harder. I know this, because that's the path I took and the battles I fought. It's a good compiler, but it's really really dated. The code it generates is also very naive - this is mentioned in the manual. There's little to no optimization. According to the docs, even stuff like "A=4+1;" is compiled as adding 4 to 1, and storing it in A. So your assembly code will be much larger than with an optimizing compiler. It's almost more of a translator. Quote main() I recommend specifying return types - that's one of the rules that got stricter in modern c. It will save you lots of fixups if you ever port your code forward. Good time to learn that habit. Quote int c; /* compiler angered if vars not defined at begining */ That's a requirement of C. It wasn't loosened until C99, IIRC (the 1999 spec, not c99 ), and even then there are limits. Quote Fadd(n1,n2) int n1, n2; This is the original K&R syntax, and you've probably noticed it's completely gone from modern code. You don't have any choice, just be aware of it... the types are now declared inline with the function declaration instead of after it. The issue commented with Fswitch() is interesting, but when you don't declare a return type, it's assumed to be int. Perhaps declaring the function as "void Fswitch(n1, n2)" would fix it... I can't help with the libs. I did a lot of c99 but I didn't get the libraries back then 4 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 23, 2021 Author Share Posted December 23, 2021 I have been working on moving off TCIO - which Vern Jensen did a good job documented, to fscanf - which came out in R4 of c99. Vern mentions he was learning the new system, with the help of Dr. Donald L Mahler of the BCS. After a good bit of trial and error, I hit this little snag. Now, where in the heck is that routine? I think I might have found it, but it was using a sledgehammer to find it... root@DESKTOP-TTA01OD:/mnt/d/classic99_vms/c99/mydisks/dsk2# strings -f -- * | grep ASCAN FSCANF: VASCAN 4 SCANF: 0ASCAN F : 99/4 AS 00413 SSCANF: PASCAN F : 99/4 AS 0011MOV @CARG,8 I think I need to load scanf, even though, I'm not directly using it. For now, I'm in search of as many BCS articles by Dr. Mahler as I can find. Fortunately, his articles, are around 88/89/90 - so he would have been using the latest libraries, and not referencing limitations of prior libraries. 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted December 24, 2021 Author Share Posted December 24, 2021 Another one of the better writers on c99 was Dr. Donald L. Mahler (dlm) here is some of his stuff I found on whtech - what and where: BCS / Dr. Donald L Mahler (dlm) Often times, in his programs, you’ll see modified from Chirlian. I’ll save you the google. Paul M. Chirlian - Introduction to C. 8703 - Nada 8704 - FWB & C99 and how to create a program image. 8707 - Two dimensional array with strcmp and index of earlier columns. 8804 - Version 4, scanf, printf 8806 - Nothing from dlm 8808 - tips for using c99 on the geneve, full updated VJ program scanf, printf, fprintf 8809 - strlen ex. Warren Agee, fix for VJ sort program, and update changing base program 8810 - Nothing from dlm 8811 - A calculating benchmark in c99 - to compare to a similar UCSD program 8901 - Array’s of pointers and pointer arithmetics 8902 - Duplicate of article in 8901 8903 - Exponent test and find the ph value 8904 - Nada by dlm 8905 - Release of c99MDOS and 70 page manual, example of volume of box, scanf and sprintf examples - MDOS environment. 8906 - nothing from dlm - JPH gone, after JPH graduated the local content of the newsletter decreased dramatically. 8908 - volume of a sphere writing in c99 with old libs, Vern Jensen’s lib and new TIC libs. 8909 - Demo of graphic functions available in tic (c99mdos) - using prior volume of sphere 9004 - nothing from dlm 9005 - nothing from dlm 900607 - using multiplan by dlm - no c99 content. 9008 - nothing from dlm 901011 - nothing from dlm 9102 - nothing from dlm 9103 - nothing from dlm 910405 - nothing from dlm 910708 - nothing from dlm 9109 - nothing from dlm - fweb 4.4 released 9112 - nothing from dlm - BT’s CAN - Cottage Archiving and Networking. 9202 - nothing from dlm Note: Lot’s of good P-System information in this newsletter by Ron Williams. 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 4, 2022 Author Share Posted January 4, 2022 Yep, loading the scanf library provided the required ascan routine! Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 8, 2022 Author Share Posted January 8, 2022 How to know if your missing a library: Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 8, 2022 Author Share Posted January 8, 2022 After looking through whtech and the cyc, I couldn't find an example of fscanf, unfortunately, by the time Clint released version 4 and Winfried released version 5.1, most of the columnist had moved on. So the example code we are left with mainly revolves around the TCIO library. After perseverance, I did manage to get fscanf going, and here is the example. One trick I didn't know about, or had forgotten, was being able to right or left justify a field using printf. GRADE;L DSK3.GRADE;O DSK2.CSUP DSK2.PRINTF DSK2.GRF1 DSK2.FSCANF DSK2.CFIO DSK2.SCANF GRADE;C #include "DSK2.STDIO" #include "DSK2.GRF1;H" /* includes are dv */ extern printf(),fprintf(),scanf(),fscanf(); /* extern are df - must be loaded */ #define FALSE 0 #define TRUE 1 /* sometimes true is def as !FALSE */ char a; /* used by Fwait sub */ int num; int reccnt; /* holds number of records read */ int grdtot; /* total of all grades */ int grdavg; /* used to hold simple average */ int filptr; char buff[81]; main() { char fname[10]; int fgrade; reccnt=0; grdtot=0; text(); clear(); filptr=fopen("DSK3.GRADE;D","r"); /* printf("file pointer: %d \n", &filptr); */ if (filptr==NULL) { printf("no such file"); return(0); } printf(">File IO Example< \n\n"); printf("Student Grade \n\n"); while (!feof(filptr)) { fscanf(filptr,"%s %d",fname, &fgrade); printf("%-10s ", fname); printf("%3d \n", fgrade); reccnt++; grdtot=grdtot+fgrade; } printf("\n"); grdavg=grdtot/reccnt; /* get a simple average */ printf("Average Grade: %d \n\n",grdavg); Fwait(); exit(0); Fwait(); } /* end of main */ Fadd(n1,n2) int n1, n2; { int sum; sum=n1+n2; return(sum); } Fswitch(n1,n2) int *n1,*n2; { int temp; temp=*n1; *n1=*n2; *n2=temp; } Fwait() { printf("Press any key to continue. \n\n"); a=getchar(); /* wait to end */ } /* dhe L.D.O.M. 01/05/2022 */ /* need to figure out puts/twrite/display */ /* because we are using twos compliment for decimal rep we get back negative numbers */ /* Doesn't look like fprint respect %x vs %X */ /* puts doesn't accept format specs like %s */ /* other formatting things.... printf %10d - will pad a field to 10 chars, your text on the right %10d - will pad to the right, your chars on the right printf doesn't respect \t */ /* NULL already define, compiler unhappy if you try to define it */ /* 12/20/2021 Odd quirk Fadd works, Fswitch didn't. the only diff c=fadd(); vs fswitch after adding an c=fswitch(); then it was actually called To keep sane, make sure you have a line between int x,y,z and then next line of code */ /* naming conventions starts with: A Array Ain[] = array input F Function Fwait = a wait funtion */ /* 12/23/2021 great swap from tcio to console i/o functions fopen is contained in CFIO library only ref so far - 6:1:16 trials of a c beginner points to articles by Dr. Donald I Mahler of the BCS */ GRADE;D DAN 100 SALLY 70 BOB 43 KIM 97 The run: 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted January 8, 2022 Share Posted January 8, 2022 Very good sleuthing by you. It took me a second to understand that this meant. Looks strange. #include "DSK2.GRF1;H" I use a comma in these cases now. Semi-colon is burned too hard into my brain as the end of the something. I remember Small C generating working code but tending to be not overly efficient. Is C99 a "regular" Small implementation from what you see or is there some optimization going on? 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 13, 2022 Author Share Posted January 13, 2022 Vern Jensen's starterpack is pretty easy to find on WHTECH. Vern Jensen's Beginning c99 articles are easy to find in Micropendium. What I was missing was the source code to his signature program virus attack. It was not published in Micropendium, nor part of the starter pack. It took a bit of digging on WHTECH, but I found Virus.ark, it has not only the executable, but the source to snake (which was in Micropendium) and Virus Attack. virus.ark 3 2 Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 15, 2022 Author Share Posted January 15, 2022 Grade File I/O Example. New and improved using Floating Point. FPEX;l DSK3.FPEX;O DSK2.CSUP DSK2.PRINTF DSK2.GRF1 DSK2.FSCANF DSK2.CFIO DSK2.SCANF DSK2.FLOAT FPEX;C #include "DSK2.STDIO" #include "DSK2.GRF1;H" #include "DSK2.FLOAT;H" /* includes are dv */ extern printf(),fprintf(),scanf(),fscanf(); /* extern are df - must be loaded */ #define FALSE 0 #define TRUE 1 /* sometimes true is def as !FALSE */ char a; /* used by Fwait sub */ int num; float frcnt[8]; /* mirror of int based vars */ float fgtot[8]; float fgavg[8]; char sgrdav[12]; /* string for grade avg */ int reccnt; /* holds number of records read */ int grdtot; /* total of all grades */ int grdavg; /* used to hold simple average */ int filptr; char buff[81]; main() { char fname[10]; /* variable to hold values read from file */ int fgrade; reccnt=0; grdtot=0; text(); clear(); filptr=fopen("DSK3.GRADE;D","r"); /* printf("file pointer: %d \n", &filptr); */ if (filptr==NULL) { printf("no such file"); return(0); } printf(">File IO w/t FP Example< \n\n"); printf("Student Grade \n\n"); while (!feof(filptr)) { fscanf(filptr,"%s %d",fname, &fgrade); printf("%-10s ", fname); printf("%3d \n", fgrade); reccnt++; grdtot=grdtot+fgrade; } printf("\n"); grdavg=grdtot/reccnt; /* get a simple average */ printf("Average Grade: %d \n\n",grdavg); itof(grdtot,fgtot); itof(reccnt,frcnt); fexp(fgtot,"/",frcnt,fgavg); ftos(fgavg,sgrdav,0,0,0); printf("Float Avg. Grade: %s \n\n", sgrdav); /* fpput(fgavg,sgrdav); */ /* combines ftos and print */ Fwait(); exit(0); Fwait(); } /* end of main */ Fadd(n1,n2) int n1, n2; { int sum; sum=n1+n2; return(sum); } Fswitch(n1,n2) int *n1,*n2; { int temp; temp=*n1; *n1=*n2; *n2=temp; } Fwait() { printf("Press any key to continue. \n\n"); a=getchar(); /* wait to end */ } /* dhe L.D.O.M. 01/13/2022 */ /* need to figure out puts/twrite/display */ /* because we are using twos compliment for decimal rep we get back negative numbers */ /* Doesn't look like fprint respect %x vs %X */ /* puts doesn't accept format specs like %s */ /* other formatting things.... printf %10d - will pad a field to 10 chars, your text on the right %10d - will pad to the right, your chars on the right printf doesn't respect \t */ /* NULL already define, compiler unhappy if you try to define it */ /* 12/20/2021 Odd quirk Fadd works, Fswitch didn't. the only diff c=fadd(); vs fswitch after adding an c=fswitch(); then it was actually called To keep sane, make sure you have a line between int x,y,z and then next line of code */ /* naming conventions starts with: A Array Ain[] = array input F Function Fwait = a wait funtion */ /* 12/23/2021 great swap from tcio to console i/o functions fopen is contained in CFIO library only ref so far - 6:1:16 trials of a c beginner points to articles by Dr. Donald I Mahler of the BCS */ 2 Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 23, 2022 Author Share Posted January 23, 2022 I wanted to do a program in TGPSCC (TM) that would do relative (random) file I/O. I have never done that thing before on the TI. After hitting a couple of road blocks, I decided to prototype a working program in RXB2020. I went back to my my trio of TICodED, RXB2020 and Classic99. I was surprised at how fast using these three tools, I was able to prototype some simple working examples. Since in this program I was trying to figure out what was going on with file I/O, Fred's TI99dir was of great value. It allow me to perform a function and look at the resulting data file in real time by looking at another window. One thing that kind of surprised me, was the TI Basic doesn't have a delete record. To delete a record you need to write something that will tell you program to skip record processing that record. Then later you could write a compression utility, that would skip over that record, writing keeper records to another file, then rename the new file as/if needed. The other problem, which I didn't know until I hit the Basic Manual PHA2603 - and I suspect the reason my c99 code wasn't working, is relative I/O doesn't work with variable data, you have to have fixed. Now that I have a working example, I will try moving on to implementing the same with TGPSCC. rem createdb rem 01-19-2022 - dhe call clear open #1:"DSK4.GRADE-D",OUTPUT,FIXED,DISPLAY,RELATIVE rem lets write data Name, Grade, Exam # print "Creating Records" print #1:"Dan,",96,",",1 print #1:"Sally,",87,",",1 print #1:"Harry,",72,",",1 print #1:"Bob,",44,",",1 print #1:"Greyson,",77,",",1 close #1 rem Yes, looks strange, guess you have to manually enter the field seperator. rem optionally you can add :delete print "go check your file, I'll wait." call my_wait open #1:"DSK4.GRADE-D",APPEND,FIXED,DISPLAY,RELATIVE print "" print "Adding a record with append" print #1:"Thorton,",99,",",1 close #1 rem record doesn't get added to file until you close the file. print "Record added, go check" print "don't forget to refresh dir in ti99dir" call my_wait open #1:"DSK4.GRADE-D",INPUT,FIXED,DISPLAY,RELATIVE print "" print "Fetching 3rd record" input #1,REC 3:Name$,Grade,Exam print Name$;Grade;Exam close #1 print "press any key to continue" call my_wait open #1:"DSK4.GRADE-D",UPDATE,FIXED,DISPLAY,RELATIVE print "" print "Print Modifying old Bob" Print #1,REC 3:"Robert,",Grade,",",Exam input #1,REC 3:Name$,Grade,Exam print Name$;Grade;Exam close #1 print "press any key to continue" call my_wait print "" print "Record Count" reccnt = 0 open #1:"DSK4.GRADE-D",UPDATE,FIXED,DISPLAY,RELATIVE mylabel1: if eof(1) then mylabel2 reccnt = reccnt + 1 input #1:Name$,Grade,Exam goto mylabel1 mylabel2: print "There are";reccnt;"records." close #1 sub my_wait loop1: call key(5,k,s) if s=0 then loop1 subend rem a couple of things here. rem 1) output will overwrite, not append. rem 2) ti99dir doesn't update unless you re-read the directory. rem INPUT files may be read only. rem OUTPUT files may be written only. new file created rem UPDATE files may be both read and written rem The usual processing is to read a record, change it in some way, then write the altered record back out on the file. rem APPEND mode allows data to be added rem !! in order to use RELATIVE (RANDOM ACCESS) file must be of the type fixed. !! rem Delete - the only way to delete appears to be writting something like blanks rem to all fields and skipping them. Then you need to write a file compressor rem utility. rem see relative files by James H. Harvey. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted January 23, 2022 Share Posted January 23, 2022 33 minutes ago, dhe said: One thing that kind of surprised me, was the TI Basic doesn't have a delete record. To delete a record you need to write something that will tell you program to skip record processing that record. Then later you could write a compression utility, that would skip over that record, writing keeper records to another file, then rename the new file as/if needed. Yeah—Though “SCRATCH RECORD” is listed in the Editor/Assembler Manual, p. 297: 18.2.1.9 SCRATCH RECORD-8 The SCRATCH RECORD operation removes the record specified in bytes 6 and 7 (Record Number) from the specified relative record file. This operation causes an error for peripherals opened as sequential files. it was never implemented in the TI disk DSR past linking its opcode (8) directly to the error routine with a “bad attributes” error. ...lee 2 Quote Link to comment Share on other sites More sharing options...
+RXB Posted January 23, 2022 Share Posted January 23, 2022 DON ONEIL of Western Horizon had a ROS for his Western Horizon RAMDISK. But like my GPL Scratch Record in RXB was to slow to be really useful. 1. Search file for the record to delete and here is a snag if it is not unusual it only works on first one. Example: files has names and it the one you want is SMITH out of 20 it picks first one. 2. Unless you know exactly where it is the entire thing is like looking for a needle in haystack. Example: You know where this particular "SMITH" is at record 47 out of 800 records. 3. Now you need twice as much space to run SCRATCH RECORD as normal due to needing twice the buffers. Example: even if you find the record and replace it two buffers are needed to recheck your results. 4. It takes a long long time to read every record and write it again. Not to mention you cannot use one single file to do it. Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 27, 2022 Author Share Posted January 27, 2022 Today's Mis-Adventures in Programming! Printing out an array of strings. Output (this tells me printf doesn’t know the size to print): Try passing printf a pointer.. And it increments one character position. Which indicates what exactly? The solution was found in this posting... https://www.delftstack.com/howto/c/array-of-strings-in-c/ char arr2[NUM_STRINGS][MAX_LENGTH] = { {"first string"}, {"second string"}, {"third string"}, {"fourth string"}, {"fifth string"} }; VS char *arr3[NUM_STRINGS] = { "first string", "second string", "third string", "fourth string", "fifth string" }; So at the end of the day {literally} the fix was to put an * in front of names on the array declaration line! The three main tutorials we have our Kirkwood (Micropendium), Jensen (Micropendium) and Agee (Orphan Survival Guide). None of them covered an array of strings. 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted January 28, 2022 Share Posted January 28, 2022 21 hours ago, dhe said: char arr2[NUM_STRINGS][MAX_LENGTH] = { {"first string"}, {"second string"}, {"third string"}, {"fourth string"}, {"fifth string"} }; VS char *arr3[NUM_STRINGS] = { "first string", "second string", "third string", "fourth string", "fifth string" }; So at the end of the day {literally} the fix was to put an * in front of names on the array declaration line! So a quick discussion of why... C pointers are probably the most confusing aspect of it, especially with "strings". The first concept to really internalize is there is no such thing as a string in C. There are only series of bytes. The double quotes tell the compiler to put a 0 byte at the end of the sequence, and that's really it. Now type declarations: char arr2[NUM_STRINGS][MAX_LENGTH] : this defines a two-dimensional array. The type of the elements is "char", a single byte integer. char *arr3[NUM_STRINGS] : this defines a one-dimensional array. The type of the elements is "char *", a pointer to a single byte integer. Let's look at the initialization. In the first case, you are defining five strings. The byte patterns that define these strings, including the 0, are copied into arr2 at arr2[0], arr2[1], arr2[2], etc. The unused space in MAX_LENGTH is undefined, but usually zeroed on modern systems and not zeroed on older systems. You can access one of the strings like "arr2[0]", but because this is a 2 dimensional array, the compiler knows you really want "&arr2[0][0]" ('&' meaning "address of"... basically, leaving off the array index turns it into a pointer. This is why printing it works!) Because the data is loaded into the array, it is fully read/write (ie: you can change the strings). In memory, it looks like this (using your screenshot code cause the strings are shorter): arr2: BYTE D, A, N, 0, ?, ?, ?, ?, ?, ? BYTE S, T, E, V, E, 0, ?, ?, ?, ?, BYTE B, I, L, L, 0, ?, ?, ?, ?, ?, BYTE G, R, E, G, 0, ?, ?, ?, ?, ?, BYTE ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ('?' represents uninitialized memory - could be anything) In the second case, you are also defining five strings, but there is no copying this time. The strings are stored where the compiler sees fit, and arr3 is loaded with the memory addresses of each string (ie: the pointers). The strings are also defined as constants, which means that trying to change them may not work, depending on the compiler and operating system. In memory, it looks something like this: STRING1: BYTE D, A, N, 0 STRING2: BYTE S, T, E, V, E, 0 STRING3: BYTE B, I, L, L, 0 STRING4: BYTE G, R, E, G, 0 arr3: DATA STRING1, STRING2, STRING3, STRING4, ? Note there is far less padding, because the data type (char *) is fully used. So finally, let's look at the samples. Your first example actually /should/ work (except, of course, that names[4] is undefined). That suggests your C compiler isn't handling the incomplete array reference properly. names[a] and &names[a] should be equivalent. That's just something you'll need to be aware of - code that you reference from others won't include the address operator when using it that way. The increment on your second example tells me the compiler is not remembering that it's a two dimensional array, and so doing the pointer math incorrectly. It should be multiplying 'a' by 10 (the size of names[x] is 10 bytes), but it's multiplying by 1 (the size of 'char'). To be honest, this is a pretty major bug and would dissuade me from using it. At the very least, you should probably assume that two dimensional arrays are buggy. My point is, both of those examples should have worked. So why does the final version work? Probably because it's a one dimensional array. The size of "char *" on the TI is 2 bytes, and the compiler is correctly multiplying 'a' by that to get a pointer to the constant string, thus your strings work. Unfortunately, with retro and embedded software development, buggy compilers is a fact of life that you learn to deal with - so it's valuable to learn what works and what to avoid. But I want to emphasize that as far as C code goes, your first pass was correct. The only advice I'd have given on it would be to initialize all entries of the array. 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted January 28, 2022 Author Share Posted January 28, 2022 Thank you very much for the detailed explanation. Quote Link to comment Share on other sites More sharing options...
Tursi Posted January 29, 2022 Share Posted January 29, 2022 It occurs to me that it might be interesting to see if the 2D array works with "&names[a][0]", just to remind the compiler there are two dimensions. Something in the back of my head tells me I used to do this 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.