Jump to content


+AtariAge Subscriber
  • Content Count

  • Joined

  • Last visited

Everything posted by TheBF

  1. Sometimes maintenance is worthwhile. I had hacked together a version of -TRAILING like this. (-TRAILING removes trailing spaces from a string) CODE -TRAILING ( addr len -- addr len') *SP W MOV, \ DUP addr in W TOS W ADD, \ add len R1 2000 LI, \ R1 holds the space character W DEC, \ w=address of last char BEGIN, *W R1 CMPB, \ compare to ascii >20 EQ WHILE, W DEC, \ move back 1 char TOS DEC, \ dec len in TOS REPEAT, TOS 0 CI, 1 JGT, TOS CLR, NEXT, ENDCODE Looking at it I didn't like having two DEC instructions inside the loop and I really didn't like the negative length test at the end. This is about 13% faster. It seems to test solidly. HEX CODE -TRAILING ( addr len -- addr len') *SP TOS ADD, \ add len TOS DEC, R1 2000 LI, \ R1 holds the space character BEGIN, *TOS R1 CMPB, \ compare to ascii >20 EQ WHILE, TOS DEC, \ move back 1 char REPEAT, *SP TOS SUB, TOS INC, NEXT, ENDCODE
  2. Have the heads, pinch-roller and capstan been cleaned?
  3. Obsessed with SAMS I have managed to take out 4 more bytes per definition. Two in SAMS memory and two in the forth Dictionary entry. I removed the GOTO SAVEHERE line and replaced it with FARSEMIS. This is a run-time exit from a SAMS definition so it can go in SAMS memory at the end of a definition. The caller's IP address is pulled from the return stack so that's that. Changing the dictionary pointer is a compile time complication so that is handled by ;FAR when we compile a new SAMS word. My ultimate goal here is to get the entire FAR: definition living in SAMS memory and then modify FIND to search through SAMS banks first in declining order before searching Forth. This will make FAR: definitions look similar to ANS Forth wordlists but we can have a lot more of these SAMS lists than wordlists. I only have room for 9 in the kernel. I have also moved my INCLUDE line buffer into high RAM. I was using PAD but when INCLUDEing into a SAMS block PAD is in the SAMS memory and so it prevents using the last 127 bytes of the SAMS bank. The other thing that is interesting is how compact headless Forth code is. All these files compiled into 4K with 380 bytes to spare. Of course there was another 1800 bytes of header code over in CPU RAM. (I need to make a way to leverage this idea to create headless programs that can be saved as EA5 images.) DECIMAL 240 SETBANK HEX INCLUDE DSK1.ELAPSE INCLUDE DSK1.UDOTR INCLUDE DSK1.ANSFILES INCLUDE DSK1.CATALOG INCLUDE DSK1.DIR INCLUDE DSK1.MORE INCLUDE DSK1.BUFFER INCLUDE DSK1.COMPARE INCLUDE DSK1.CASE INCLUDE DSK1.VALUES INCLUDE DSK1.TRAILING INCLUDE DSK1.SYNONYM INCLUDE DSK1.3RD4TH INCLUDE DSK1.MALLOC INCLUDE DSK1.VDPMEM INCLUDE DSK1.FASTCASE INCLUDE DSK1.ASMLABELS INCLUDE DSK1.GRAFIX INCLUDE DSK1.DIRSPRIT INCLUDE DSK1.COOLSPRITE
  4. How much of the 64K ROM space does Stevie use. Asking for a friend... (that's an enviable code space)
  5. I updated the code above to remove the HOLDER buffer and just used PAD. Then I realized if you wanted to, the compiler could just put the bytes directly into VDP RAM in the pattern table. You just replace C, with VC, Then you just need a word to set the VDP memory pointer to the correct location in the pattern table for the character you want to change. This code does that. So no CPU RAM is used to hold the patterns. The downside of course is that the patterns have to be re-compiled each time you want them. But I see this as simple way to design patterns on real iron.
  6. I was doing some folder housekeeping and found something I tried to do a long time ago. I guess I have learned something over the last few years because it was clear to me that it was all wrong. The objective was to make a character pattern compiler the lets you "draw" your character patterns in text in your source code like these examples. CREATE BIG-O \ 01234567 | **** | | * * | | * * | | * * | | * * | | * * | | * * | | **** | CREATE SQUARE \ 01234567 | ********| | ********| | ********| | ********| | ********| | ********| | ********| | ********| The better idea was to convert a string of asterisks and spaces into a string of ones and zeros. A string of ones and zeros can be "evaluated" by Forth as a binary number. That number can then be compiled into memory as one byte of a pattern definition. It's not nearly as fancy as a program that let's you draw on the screen but its a heck of lot easier than HEX bytes in a string. Here is the code with the examples above. Code Edit: Removed HOLDER buffer and used PAD instead. Saves bytes
  7. I am confused. (No shock there) Are we talking about file "pipes"? Pipelining to me is a technique in CPU design where you make an instruction pipeline so you can minimize stalling the CPU. If we are talking about pipes then as you say MSDOS later versions had pipes without multi-tasking. I am not certain of the exact mechanism used. (Temporary files as output/input buffers?) This sounds like something I should add to the Fox Shell with some filter programs. hmm... 🤔 with multi-tasking too.
  8. Could you get/put a low resistance shunt somewhere and compute the current?
  9. So I did a benchmark program in two versions. One that lives in completely in CPU RAM. The 2nd has the outer loop in SAMS F9 but the inner loop is in SAMS F8. This forces a cross SAMS page call. Here is the code. The screen shots tell the tale. Pages were toggling... Speed is VERY good.
  10. I have something that seems useful now although some code that I have in my libraries breaks when loaded in SAMS. Need to understand why. This version runs faster because MAPPER is now smart and does not map in a SAMS page if it is already in memory. I will do a benchmark comparison between CPU RAM and SAMS memory. Here is the code Here is a test suite using a SAMS wordlist to hold a the SAMS version of : and ; plus all the SAMS words. COMPILE-2-SAMS.mp4
  11. Maybe that's the trap that could be installed in this new BASIC interpreter. GOTO inside a FOR/NEXT structure throws an error. ?? We have to start reigning-in the bad habits of BASIC programmers somehow. :) (It's a joke. Don't kill me)
  12. "Bug for bug compatibility"
  13. You could use the EQU to reference the string address but you need a BSS with a label somewhere with the string in it. And for a string you can also use I think. TEXT 'DSK1.1234567890'
  14. When I regained consciousness... I found that I finally had a working version of FAR: / ;FAR That reduced the overhead in the Dictionary. Using the original Turbo Forth method translated to Camel99 Forth this empty definition: FAR: TEST ;FAR Took 26 dictionary bytes and 4 SAMS bytes With the work I did this week, the same definition consumes 16 Dictionary bytes and 4 SAMS bytes. I did this by making a proper colon definition for FAR: that has it's own run-time code. This replaces all the "compiled" words in the TF code and it should be faster as well. I use two data fields: Bank# and SAMS dictionary pointer. The code word FARCOL uses the IP register to read these sequential bytes into their appropriate places. It's still not giving me as much efficiency as I would like but it reduces the Forth dictionary consumption by about 40% when I load my ANS Files library. I have tested the calling overhead yet. Bugs: 1. There is a SAMS memory bug somewhere because I cannot squeeze as many files into a 4K block as I can with more direct translation of TF version that I did earlier. ?? I think I am advancing an extra cell after each definition. More sleuthing needed... 2. Changing Banks is not reliable yet. This has been way harder than I wanted it to be but thanks to Mark paving the way I had a place to begin. Here is the current state of the code: Now if you want to load existing code need to alias FAR: ;FAR to : /; The easiest way is to use a vocabulary I think. I have not tried this but it should work. VOCABULARY SAMS ONLY FORTH ALSO SAMS DEFINITIONS \ rename normal : ; so we don't over-ride them and can still use them : H: : ; : ;H POSTPONE ; ; IMMEDIATE H: : FAR: ;H H: ; ;FAR ;H IMMEDIATE There are other ways to this that don't need vocabularies. Adding vocabulary/wordlists to my system uses 550ish valuable bytes.
  15. Don't know if this is of any value but I did something with SAMS that is pretty simple but effective. It comes from a function in Forth called BLOCK. Normally BLOCK is used for files that work as virtual memory. BLOCK takes a numerical argument from 0 to >FF It returns the CPU address of a buffer, where a block of a file is loaded, but in this case it is a 4K SAMS page that is mapped into the space. I used all of the low RAM for two 4K buffers. If the SAMS page is already in memory, nothing happens. If the page is not in memory it is pulled into the last used buffer. I only have the code in reverse polish assembler. Happy to share it but you can probably make it better yourself for your purposes. It doesn't get much simpler but it lets you grab any page anytime.
  16. It would be great to have him hanging around here again. BTW I may have discovered why Mark used a separate stack for his SAMS pages. I think you need that default page# on the bottom that he has. More experiments needed.
  17. Been there going to real iron. My condolences.
  18. Why make a new stack when you already have two? : FAR: ( -- ) : \ compile header in CPU RAM \ Run-time action POSTPONE _BANK \ compile my bank# POSTPONE DUP>R POSTPONE CMAP \ push & MAP the bank into RAM POSTPONE GOTO _BANK ]HERE @ DUP , \ compile jump to here for this bank \ compile-time action HERE TO _NHERE \ save "normal here" DP ! \ set dp to _bank's "here" _BANK CMAP \ map in the appropriate bank ; : ;FAR ( -- ) \ end banked compilation POSTPONE GOTO _NHERE , HERE _BANK ]HERE ! \ update here for bank _NHERE DP ! \ restore dp to "normal" memory POSTPONE R> POSTPONE CMAP POSTPONE ; ; IMMEDIATE I can now confirm that the code above works reliably using the return stack for SAMS pages but I think I have exhausted the possibilities of this method to put CODE into SAMS. Lee made mention of it in the Foxit thread regarding the large headers created in the Forth dictionary. I vectored the function of : and ; to be FAR: and FAR; and then compiled the following list of files into a single 4K SAMS page. INCLUDE DSK1.ANSFILES INCLUDE DSK1.CATALOG INCLUDE DSK1.DIR INCLUDE DSK1.MORE INCLUDE DSK1.GRAFIX INCLUDE DSK1.DIRSPRIT INCLUDE DSK1.COOLSPRITE Before I loaded the file I had 13,518 bytes remaining in my CPU RAM. (Forth kernel+SAMS code stuff+Tools) After loading the files here are the numbers: SAMS Page: 698 bytes free, so 3,398 bytes used CPU Free: 9514 free, so 4004 bytes used >> just for the headers<< So I will take this learning and incorporate some of it into my next work.
  19. Look another shiny object (I should be on Ritalin) I made the mistake of looking at Mark's code for compiling code into SAMS pages. It's a pretty neat hack. I would not have thought of doing it quite like this. I was able to translate it but it didn't work. Hmmm... Why? Well, TF branches to literal addresses internally. Camel Forth branches to an +/- offsets Where Mark compiles BRANCH that doesn't work in Camel Forth so I created a new Forth word: GOTO 🤣 CODE GOTO ( addr -- ) *IP IP MOV, NEXT, ENDCODE Once I discovered the magic word I started trimming it down. I have removed some of the sugar because I have less space, not using a cartridge. Colon/semi-colon is not overloaded. If you want to compile a word in SAMS use FAR: / ;FAR This is consistent with the Chuck's rule "Let the dictionary be your case statement" SETBANK is much simpler because it just tests for range and sets the _BANK value. The Bank stack has been re-written using ideas I got from Camel Forth internals. It's a little less code than using VALUEs. CMAP is narrow focused for this job and so is quite a bit smaller and faster than >MAP Todo: I think I can remove the HERE array but using the last CELL of each block to hold the dictionary pointer of the block we map in. Settle on the actual range of SAMS pages I want to use for CODE and fix the limits. Make the headers and footers in FAR: and ;FAR smaller by factoring out the existing code into a few words (some CODE would speed this up too) Use the return stack instead of _NHERE to save the Forth dictionary pointer on entry to a new word. Here is the code for CAMEL99 Forth
  20. Wonder what the converts to in metric... 🤔
  21. For reference here is MAP when you decide what it needs to do up front rather than computing stuff in the code. \ "CMAP" brings pages of code into the window called CSEG \ The SAMS register is pre-calculated as constant CREG CODE CMAP ( bank# -- ) \ ** bank# must be in low byte of R4 020C , 1E00 , \ R12 1E00 LI, 1D00 , \ 0 SBO, \ turn on the card C804 , CREG , \ TOS CREG @@ MOV, \ store bank# in SAMS register 1E00 , \ 0 SBZ, \ turn off card C136 , \ DROP \ refill top of stack register NEXT, ENDCODE
  22. With code I posted you choose the page address by setting CSEG. Your choice. Mark's code uses >3000 by default. By making the decision at compile time for the page to use, MAP becomes over 2X faster and since MAP is happening every time the word runs it's important to keep it fast.
  23. I think this can be done by storing all the extra stuff in the SAMS page that you pull in. That way you only need to remember the SAMS page# and all the data is available as soon as you MAP in the page. I did this last year but it got confusing with wordlists and vocabularies. I am looking at doing an ultra simple version because my projects are "growing to fill the know universe" I am also looking at just using the return stack for the page# value. I don't think we need a separate stack since there is a SAMS : and a SAMS ; They should save the page# and retrieve the page# when you enter and exit the words. MAP can be really simplified because we always know that the code page maps into >3000. Here it is in Forth. Computing stuff at compile time means this can be used in FbForth by changing CSEG to >E000 or where ever you need it. (SAMSCARD is just a constant for >1E00 ) : SAMSCARD ( -- ) 1E00 'R12 ! ; \ select sams card \ SAMS memory management for code HEX 3000 CONSTANT CSEG \ CPU RAM window for SAMS code 4000 CSEG 0B RSHIFT + CONSTANT CREG \ compute CSEG SAMS register CSEG 4 RSHIFT CONSTANT PASSTHRU \ default SAMS page \ "CMAP" brings pages of code into the window called CSEG \ *should be CODE for best speed : CMAP ( bank# -- ) \ ** bank# must be in low byte** SAMSCARD 0SBO \ turn on the card ( bank#) CREG ! \ store bank# in SAMS register 0SBZ ; \ turn off card I also think overloading : and ; is extra baggage that takes precious space. Using code to select the right operation at run time can be eliminated by just having a BANK selector and special colon/semi-colon pair like FAR: ;FAR The ultimate thing for me will be modifying FIND so SAMS words can call SAMS words in other pages. 🙂
  24. I just took another look at Mark's code. When I first saw it my system was not stable enough to dream about it but it all looks pretty much like I thought it should now. He uses the word SETBANK. USE I believe selects the BLOCK file. I will take a run at translating this to Camel99 Forth. I have some ideas about the bank stack implementation that could make it a bit smaller. Thanks again for the reminder about this.
  25. Sounds like you have a clear vision of where you are going and 10 or so keywords is certainly not too many to hard code them all. I have never tried TF's SAMS words but there is a bit of extra cruft needed to remember the page no. and how to return. I will have to take a look again at how Mark did that. However all that being so, we all know how very easy it is to code away and consume more resources. As Murphy's law of computing states: "All systems grow to fill the known universe" Forth can bite you because of the dictionary header and the name of the word being in the code. They say write lots of small words which helps the programmer but it eats up bytes too. Assembler on the 9900 is very efficient at inline code but nesting sub-routines can add a lot of fat that catches me by surprise in this machine Forth compiler I am trying to master. Utopia is hard to find. Keep on keepin' on with Foxit. It will be fun to see it come to life.
  • Create New...