Jump to content


+AtariAge Subscriber
  • Content Count

  • Joined

  • Last visited

Community Reputation

2,750 Excellent

About TheBF

  • Rank
    River Patroller

Profile Information

  • Gender
  • Location
    The Great White North
  • Interests
    Music/music production, The Forth programming language and implementations.
  • Currently Playing
  • Playing Next
    Trumpet ;)

Recent Profile Visitors

6,563 profile views
  1. Ah so not the complete absence of ELSE but rather XB enhancements. Thanks.
  2. Not too bad then. I didn't know about the loss of ELSE. Wonder why.
  3. Compiling a language designed to be interpreted always requires adapting language in some way. XB is so slow however it has driven people to go with compiling and tolerating the extra work. "There no such thing as free lunch" is true with computers for sure. As my grandfather used to sing after a few bottles of the amber liquid: 😢 "Gone are the days when free lunches went with beer. These memories still fill my eyes with tears..."
  4. Not sure if this of any help but this seems to work here. TOS is just R4. Looks like I used bit 21 to test if character is ready to read. And 18 to reset (This is not the entire file. ) [CC] DECIMAL [TC] CODE CKEY? ( -- n ) \ "com-key" 0 LIMI, R12 RPUSH, \ save R12 on return stack *Needed?* CARD @@ R12 MOV, \ set base address of CARD TOS PUSH, \ give us a new TOS register (R4) TOS CLR, \ erase it \ *** handshake hardware ON *** 5 SBZ, \ CARD CTS line LOW. You are clear to send UART @@ R12 ADD, \ add UART, >1300+40 = CRU address 21 TB, \ test if char ready EQ IF, TOS 8 STCR, \ read the char 18 SBZ, \ reset 9902 rcv buffer TOS SWPB, \ shift char to other byte ENDIF, \ *** handshake hardware off *** CARD @@ R12 MOV, \ select card 5 SBO, \ CTS line HIGH. I am busy! \ ****************************** R12 RPOP, \ restore old R12 *Needed?* 2 LIMI, NEXT, ENDCODE
  5. Are we sure it's not the code? Perhaps you could give us all a peek.
  6. So you had a huge amount of code inside 1000 iteration loop. I think that was the problem. I am also wondering if the amount of code in the comparison would be less by just checking for non-zero in CLS(7) ... CLS(15) as in the BASIC code above. I just tested BASIC with this so I know the IF statement works this way in the interpreter. Don't about the compiler. 100 X=0 110 IF X THEN 120 ELSE 130 120 PRINT "TRUE" 130 PRINT "FALSE"
  7. You would have to look at the code the compiler generates. Is that easy to see?
  8. Replacing the Assembler with Machine Forth I am finally doing some experiments to see how this will work. My conclusion so far is that it is best to allow naming the registers to fit with the architecture of the 9900. However the register names will be Forth names. In the case of CAMEL99 they would be: \ R0 temp \ R1 temp \ R2 temp \ R3 AREG \ address register \ TOS R4 is top of stack cache (you need to manage it) :-) \ SP data stack pointer \ RP return stack pointer : NOS *SP ; \ Next on Stack : 3RD 2 (SP) ; : 4TH 3 (SP) ; : 5TH 4 (SP) ; TOS (top of stack) and NOS (next on stack) are register names from the F21 Forth CPU. So this is consistent with Chuck Moore's work. I have not decided if some machine Forth instructions should use the TOS NOS pair implicitly sometimes, so it is more like Forth or mandate that registers be explicitly used to make it more Assembler like. I am starting with explicit registers because that is the best fit to the 9900 architecture. I renamed the Assembler jump tokens to make the code look more Forth-like. (not sure they are all correct) HEX \ Action if TRUE 01 CONSTANT > \ JLT to ENDIF, *signed 02 CONSTANT U> \ JLE to ENDIF, 03 CONSTANT 0<> \ JEQ to ENDIF, 04 CONSTANT U< \ JHE to ENDIF, 05 CONSTANT <= \ JGT to ENDIF, *signed 06 CONSTANT 0= \ JNE to ENDIF, 07 CONSTANT OC \ JNC to ENDIF, 08 CONSTANT NC \ JOC to ENDIF, 09 CONSTANT OO \ JNO to ENDIF, 0A CONSTANT U< \ JLO to ENDIF, 0B CONSTANT U>= \ JH to ENDIF, 0C CONSTANT NP \ JOP to ENDIF, The concept works at least at the simple level. Here are two programs that generate the same machine code: HEX \ Code in Forth Assembler ASSEMBLER CODE ASM1 TOS FFFF LI, BEGIN, TOS DEC, EQ UNTIL, NEXT, ENDCODE \ Same code in MForth Assembler. \ NOTE: Registers must be explictly referenced MFORTH CODE MFORTH1 FFFF TOS !# BEGIN TOS 1- 0= UNTIL NEXT, ENDCODE I have added the '->' operator to compile memory to memory MOV instructions. (I suppose I will need C-> or something like that for byte moves) Here is a test program that works \ using variables/addresses MFORTH CODE MFORTH2 FFFF TOS !# BEGIN TOS 1- TOS X ! X -> Y \ mem2mem X->X assignment Y -> Z \ Y -> X 0= UNTIL NEXT, ENDCODE So yes it is a new notation to learn but it does make something of a universal Assembler that could in theory allow machine code to be generated on other machines quite easily. Here is the code generated by MFORTH2 DADE 0204 li R4,>ffff DAE2 0604 dec R4 DAE4 C804 mov R4,@>da8e DAE8 C820 mov @>da8e,@>da98 DAEE C820 mov @>da98,@>daa2 DAF4 16F6 jne >dae2 DAF6 045A b *R10
  9. ok. This makes me wonder if the compiled code would be smaller (and therefore faster) if you just summed the contents of the CLS() array in a FOR/NEXT loop. That would be like an AND on each value but I don't know if the compiler will make faster code than that inline statement. The loop overhead would be not bad in machine code. Might be worth a try. You might have to change the initial value in the array . ?
  10. Just curious. Is most of the Geneve code written in Assembler?
  11. When I look at all those logical conditions I find myself wondering if there is one of them that is critical? Maybe there are two that are show-stoppers. If so those could be part of an IF statement so that you shortcut testing everything IF you don't need to. Using logical flags with AND and OR can save time for two conditions vs IF under the right conditions, but I think you are forcing the machine to compute all of the logical operations, even if you fail the first one. That could be a bottle-neck maybe. (?) But maybe it has to be that way for your program. Just a thought. The compiler make fast code but it's not very speedy processor under the hood.
  12. To CREATE/DOES> or not to CREATE/DOES>, that might be the question After embedding myself in Machine Forth I started wondering about an idea I had some time back which was: Can I replace the 9900 Assembler mnemonics with equivalent Forth names and make a "machine forth" Assembler. The answer so far is "I think so". (whether anybody cares is another matter) However in the course of looking at the existing Assembler that we inherited from TI-Forth I see some needless complexity. It might just be young engineers saying "Look how cool my code is!" The CREATE DOES> or <BUILDS DOES> idea is really neat but it adds run-time overhead and takes up extra space in the system so its use should be reserved for those times when it really solves the problem. Compare these two ways to make the simpler instructions for TMS9900 Original: : 0OP CREATE , DOES> @ , ; 0340 0OP IDLE, 0360 0OP RSET, 03C0 0OP CKOF, 03A0 0OP CKON, 03E0 0OP LREX, 0380 0OP RTWP, : ROP CREATE , DOES> @ + , ; 02C0 ROP STST, 02A0 ROP STWP, : IOP CREATE , DOES> @ , , ; 02E0 IOP LWPI, 0300 IOP LIMI, Versus: HEX \ : IDLE, ( -- ) 0340 , ; \ "Should not be used on the HOME Computer" \ : RSET, ( -- ) 0360 , ; \ : CKOF, ( -- ) 03C0 , ; \ : CKON, ( -- ) 03A0 , ; \ : LREX, ( -- ) 03E0 , ; : RTWP ( -- ) 0380 , ; : STST ( reg -- ) 02C0 + , ; : STWP ( reg -- ) 02A0 + , ; : LWPI ( addr --) 02E0 , , ; : LIMI ( n -- ) 0300 , , ; Which one is easier to understand? Which one is compiles to less bytes? Which one will Assemble code faster? Edit: Corrected instruction CKOF mistake IDLE REST CKON CKOFF "...should not be used on the Home Computer..." E/A Manual. So they will be removed from the Camel99 Assembler to save space.
  13. So you want convenient syntax AND optimization too? Just kidding. I think it can be hard to do both in a single pass. (?) I have new found respect for code generating programs after my recent research project.
  14. My pop/push optimizer problem seems to have been my logic on when to invoke it. It seems to work reliably now. In this little program program it was used 8 times which saved 48 bytes! To be clear "Forth" is not in the program. It's just native code glued together by Forth. So here is a little video of how it works. There is still lots of work to do to make it something someone else could use but I have always wanted to know more about Forth generating native code so this is a bit of personal victory. It pales in comparison to XB256 but it is a compiler that can generate fast code so it could be "library enabled". Here is the entire benchmark program using some tricks so that it runs as fast as I can make it go. The video shows it built and run. You could run it from within Forth and return to Forth, but I wanted to show the EA5 creation function. I gotta go make pizza. Happy weekend MachineForthTest.mp4
  • Create New...