Jump to content

TheBF

+AtariAge Subscriber
  • Posts

    4,059
  • Joined

  • Last visited

Everything posted by TheBF

  1. Ah. Clever. Thanks For context switching a Forth system once all the workspaces are setup, RTWP is just too temping to avoid. The entire context switch plus test for awake/sleeping is 4 instructions. It would be smaller if I used a register for the status flag instead of a workspace relative variable.
  2. I remember searching the instruction set for way to do that LWP instruction for round-robin multi-tasking. Eventually I figured out that I could do it "back-handed" by pre-loading R13,14,15 and executing RTWP. Weird, but it worked.
  3. The level of computer knowledge in this forum is awe inspiring.
  4. Whenever I said "Great minds think alike" to my mother she would say "Or fools seldom differ". We can choose whatever fits. Never did a Golden mean program. Now I have to go read stuff.
  5. Alternatively you could paste your block file in a post here and we could get at it that way. (I have wanted to see this code since the first day you posted it back when) Oops: It's on real iron so that might be tricky.
  6. Can I play? You could use 30 sprites at 12 degree spacing... \ CIRClE of sprites Aug 2023 Brian Fox \ NEEDS DUMP FROM DSK1.TOOLS NEEDS SIN FROM DSK1.TRIG NEEDS SPRITE FROM DSK1.DIRSPRIT DECIMAL 14 CONSTANT magenta 15 CONSTANT gray 92 CONSTANT Xbias 122 CONSTANT Ybias 130 CONSTANT Scale 128 CONSTANT BALL S" 3C7EFFFFFFFF7E3C" BALL CALLCHAR : SIN() ( n -- x) 12 * SIN Scale / Xbias + ; : COS() ( n -- y) 12 * COS Scale / Ybias + ; : CIRCLE 30 0 DO BALL magenta I COS() I SIN() I SPRITE LOOP ; : RUN PAGE CIRCLE KEY DROP DELALL ; sprite-circle.mp4
  7. Or whatever else might want to call 'em.
  8. Not a lot of detail but they allude to it on page 2-2. Illustration 2-1 of this book. vdp_pg.pdf (oratronik.de)
  9. Very slick using the extra cell.
  10. I had to take a break on that project. I have to confess that building on real iron is rather frustrating after having Classic99. I will get back to it this Tuesday. (Long weekend up here this week)
  11. Just for testing I ran my FORNEXT demo program with elapsed timing. Wow did this change to the new #FOR code make a difference! \ 1,000,000 iterations \ V .73 14.51 seconds \ V .81 10.11 seconds CODE NESTED 100 #FOR 100 #FOR 100 #FOR NEXT NEXT NEXT ;CODE \ 1,000,000 iterations \ v .73 35.1 seconds \ V.81 23.8 seconds CODE DEEPER 10 #FOR 10 #FOR 10 #FOR 10 #FOR 10 #FOR 10 #FOR NEXT NEXT NEXT NEXT NEXT NEXT ;CODE
  12. I looked at this after a few hours and realized that since the loop counter is now a register, #FOR can take the loop length as a literal number in the source code. I can load R11 with #!. #! is an alias for the LI instruction. So this gets far simpler and removes a bunch of instructions generated by the # operator. : #FOR ( arg --) R11 RPUSH \ save R11 ( arg) R11 #! \ LI R11,arg BEGIN ;
  13. Now that I have my head in this ASMForth, I realized that my FOR NEXT loop could be improved very easily. Edit: Updated binary program files are here: ASMFORTH/bin/DSK2 at main · bfox9900/ASMFORTH · GitHub The first version pushed the loop limit onto the return stack and decremented the value in memory. *RP DEC, According to my notes this is about 11% slower than using a register as the down counter. I was ok with that because I was just happy the darned thing worked at all. However now I realize that R11 is available as a loop counter as long as I save it on the return stack and then pop it back with NEXT. Re-running the Byte Mag. Sieve with this new FOR NEXT loop reduced the runtime from 9.94 seconds to 9.25 seconds, a 7 % improvement. The high level parts of the compiler are written in ASMForth II , so here is what the FOR NEXT code looks like now. I am still giddy over this kind of thing actually working. : FOR ( arg --) R11 RPUSH ( ARG) R11 ! BEGIN ; \ Alternative using literal number, N goes thru TOS -> R11 : #FOR ( n --) # \ put literal into TOS register R11 RPUSH \ save R11 TOS R11 ! \ put loop limit into R11 DROP \ restore TOS register from stack memory BEGIN ; : NEXT ( -- ) R11 1- \ DEC R11 NC UNTIL \ JOC BEGIN R11 RPOP ; \ MOV *RP+,R11 : NEXT2 \ dect loop counter by 2 R11 2- NC UNTIL R11 RPOP ; Here is the slightly altered Sieve code. (FILLW had one instruction removed) ASMforth II .81 Sieve.mp4
  14. Not a BASIC expert here but here are my 2 cents: Should I use an emulator with a new compiler dedicated game BASIC? Yes. Classic99 is great on windows. Way faster development times. I can do it all, or as a team or even just as a consultant or designer. If you want to be involved at all PM me. There is a ton of talent in this forum. Is it worth doing? Are there games out there that are so close it's not worth doing? Always (It's a hobby) So much more can be added to what I did the first time. When compiled, game play was fast and you were never bored because even when just flying around those mines and energy pellets kept you busy. The BASIC compiler is amazing compared to what we had 40 years ago. Not sure how it handles really large programs, but I think you can chain. Expert input required here. I just got a brand new baby sized laptop. Can this be used to do everything? I can't think of a reason why not. Check the resources link at the top of this Forum to collect your tools and books to get you started. Let me know what you think. I just want people to have fun. Fun seems to be what we do here.
  15. What is the range of the RADAR that you set Vorticon? I may try to build a little tank toolkit to try some different strategies on my Forth version. I never did finish it. In theory I could make a few difference versions all running on the board that runs pretty quickly. The challenge is to make the domain specific commands easy to use so they can be reconfigured easily.
  16. It's 1923 in the AI world. Just imagine what 10 years brings. State of the art Dusenberg 1923. Versus a 1933 Dusenberg The Duesenberg Model SJ 1933 was powered by a supercharged 420 cubic inch V-8 engine that generated 320 horsepower. - The engine featured a twin overhead camshaft design with four valves per cylinder. - The car had a top speed of around 130 miles per hour, making it one of the fastest cars of its time.
  17. I used to read Jeff Fox talking about you can do things in Forth with 10X less code. I didn't believe it because "I" couldn't do it. Over the years I am "starting" to get how you do it but it means really exploring what all these little trivial words do in a Forth system and what else you could use them for. It seems to be more like an instruction set for a CPU where it takes time to figure out the best way to use the instructions for different situations. It's just not obvious what "else" you can do with the wee beasties. One that made say "WHAT?!" was using COUNT to index into a stack string. (not a byte counted string) : TYPE ( addr len -- ) 0 DO COUNT EMIT LOOP DROP ;
  18. It keeps the code for THEN simpler I suspect. In the CORTEX scheme, THEN only has one purpose; resolving where IF has to branch to. There always is a GOTO in BASIC so the designer elected to let GOTO do the job it was made for in every case. It's a fair trade-off, but is probably something the interpreter writer believes in versus it being better or worse.
  19. I just saw something on comp.lang.forth that I would have never thought of but apparently others have used it. It is not guaranteed to work on all Forth systems. You need the Forth83 style word CREATE so it doesn't work in FbForth without making that word. Let's say you wanted to create a vector table of these actions that you have written up. : FIZZ ; : BUZZ ; : BLEEP ; : HALT ; In many Forth systems you can do this to make the table of executable "tokens" (addresses) CREATE TABLE ] FIZZ BUZZ BLEEP HALT [ For the Forth student: How does it work? Because ] turns on the compiler so the token for each word is looked up in the dictionary and is compiled into memory as each word is parsed. Then [ turns off the compiler ie: turns on the interpreter again And then to run them you might do something like this. : DOIT ( n -- ) CELLS TABLE + @ EXECUTE ; \ Usage: 0 DOIT 1 DOIT etc. (no protection on this example so you can blow up the system if you type 4 DOIT. ) ( I will leave it to the reader to implement protection ) (always wanted to say that) More stuff you'll probably never need but now you know.
  20. Is it using a much smaller floating point number format Bill?
  21. Nice. I gotta get me a couple of those. Might be the same reason we all ask all the rest of the questions about design decisions on this machine. I used to work with a guy who came from Nortel. He designed telephones in the 1980-90 time period. He would have designs sent back to remove 10 cents from the manufactured cost per unit. Could be that kind of thinking.
  22. I am of the same opinion. A comment to the right of an instruction should pertain to the instruction. Comments for a block of code should be on the line preceding the code. Good catch on the duplicate label and data. Better minds than mine...
  23. Cool. I looked at this and the first thing I saw was a misleading comment IMHO. SETBD1 LI R12,>80 SET THE BAUD RATE FOR THE FIRST PORT This sets the CRU address of the 1st port.
  24. Of course now I have to go back and review the instruction manual and demo programs and then test the programs. To give you a feel of how this looks compared to Forth and Assembler here is a demo that can copy data from one array to another. \ CODE word that can be called from Forth CODE MOVECELLS ( src dst n -- ) \ tos=n NOS=DST 3rd=src NOS^ R1 ! \ POP dst into a register for auto-incrementing NOS^ R0 ! \ POP source into a register TOS FOR \ FOR takes n from TOS register and pushes it onto Rstack R0 @+ R1 @+ ! \ store a cell and auto-increment both registers NEXT DROP \ refill TOS register from data stack memory ;CODE In the video we copy 4096 CELLS (8k bytes) from the ROM at >0000 to low RAM at >2000 very fast. ASMForth II MOVECELLS.mp4
  25. I was away for a few days and when I came back I wanted to address an idea that had been bubbling in my head for ASMForth II. It's not rocket science but it does make the "language" a bit higher level. The idea is to leverage the fact that 9900 can use memory almost as easily as it uses registers. Remember that ASMForth is an Assembler that renames 9900 instructions to use Forth nomenclature where ever possible. The new idea was to add some simple smarts so that operations would detect if an argument was an address or a register. It turned out that I needed to deal with two situations. Source arguments and destination arguments. Once I realized that, it became pretty simple. DECIMAL : ADDRESS? ( n -- ?) 8191 U> ; \ lowest RAM address is 8192 HEX : REG? ( n -- ?) 0 10 WITHIN ; : MODE? ( n -- ?) 1F 30 WITHIN ; : <SRC> ( n -- n | n 20) \ used with fetch operators DUP ADDRESS? IF @@ EXIT THEN DUP REG? IF ** EXIT THEN DUP MODE? IF ( nothing) THEN ; : <DST> ( n -- n | n 20) \ used with store operators DUP ADDRESS? IF @@ THEN ; With these simple tests we just modified @ and ! like this: Using Fetch '@' on a register simply gives you indirect addressing mode; on an address you get symbolic addressing. \ SMART fetch operator : @ ( addr|reg -- u | Rx n) <SRC> ; : C@ ( addr|reg -- u | Rx n) <SRC> ; \ Add some smarts to store : ! ( src dst -- ) <DST> MOV, ; : +! ( src mem -- ) <DST> ADD, ; : C! ( c dst -- ) <DST> MOVB, ; I also added some compile time error checks to protect operations that must have a register argument and also where an address was expected. \ aborting error detection words : ?ADDR ( addr -- addr) DUP ADDRESS? 0= ABORT" Valid address expected" ; : ?REGISTER ( reg --reg) DUP REG? 0= ABORT" Register expected" ; So what you might ask? Well the result is that we can get some pretty nice code out of this thing that reads kind of like Forth but generates native machine code. This is the one I think I like the best. VARIABLE X VARIABLE Y CODE MEM2MEM X @ Y ! ;CODE This generates the following code: DE76 C820 mov @>de5c,@>de66 The implication of this is that all the operations that can work on memory or registers like those below now do not need any extra syntax. They just work. And if you try to use an address where a register is required it aborts on that line. (at least on the operations that I have added that too) This might take some getting use to coming from Assembler, but it makes a pretty high level Assembler. : 1+ ( arg -- ) <DST> INC, ; : 1- ( arg -- ) <DST> DEC, ; : 2+ ( arg -- ) <DST> INCT, ; : 2- ( arg -- ) <DST> DECT, ; : >< ( arg -- ) <DST> SWPB, ; : ABS ( arg -- ) <DST> ABS, ; : NEGATE ( arg -- ) <DST> NEG, ; : ON ( arg -- ) <DST> SETO, ; : OFF ( arg -- ) <DST> CLR, ; : NEGATE ( arg -- ) <DST> NEG, ; : OR ( src dst --) <DST> SOC, ; : ON ( arg -- ) <DST> SETO, ; : OFF ( arg -- ) <DST> CLR, ; : CMP ( reg gad) <DST> CMP, ; : CMPB ( reg gad) <DST> CMPB, ; Another minor change was made to make 9900 LI and AI instructions work more like Forth where the number comes first, then the destination register and then the instruction. 99 R1 #! 7 R1 #+!
×
×
  • Create New...