Jump to content

Willsy

Members
  • Content Count

    3,144
  • Joined

  • Last visited

Everything posted by Willsy

  1. [pedantry] Actually, I don't *think* it was clever. If you wanted active low, then you would do something like: CS = PIN 9 ; CS = NOT((A1 + A2 + A3) * MEMEN) ; But you get the idea [/pedantry]
  2. Looking at Marcs logic diagrams, could the discretes not all be mopped up into a single programmable chip? Back when I was active in such things, we had chips called PALs and GALs - these were tiny, say, 12 or 16 pin DIL chips and you could program (and re-program) them with your own logic. We used a neat little program called PALASM to program the chips. You just used boolean logic equations. It was very simple and did the job perfectly. /CS = PIN 9 ; chip select will be on pin 9, true will be a low /CS = (A1 + A2 + A3) * MEMEN ; /CS=(a1 OR a2 OR a3) AND MEMEN Something like that. Does anything with this level of "simplicity" still exist? Or are they all massive big hairy FPGAs for building your own floating point processor?
  3. I personally would *love* translucent cases. Not transparent, but translucent! I had the idea of having two LEDs in the TF cart, one red, one green, and giving the user access to these: 1 GLED ( turn green led on) 0 GLED ( turn it off) 1 RLED ( turn red led on) 0 RLED ( turn it off) If the user generated an error when typing in code, the red led would turn on, etc, so the whole cart would glow red! Love it! Can we have LEDs in the design please? PLEASE?
  4. Yes It would be possible. Would require some more decoding but would work. The reason I designed it this way though was to have not only RAM and banked ROM but also a large area that was always apparent. Ideal ,in my opinion, to run a small memory manager out of (among other things.) This allows a programmer to store subroutines in banks. When a subroutine is called then that page can be swapped in and the BL made from RAM. When the sub is over then the return is made to RAM where the original calling page is brought back to life and PC restored. It's kind of like a BLWP except you have a page vector and a branch vector Example.... Say page 1 wants to call a routine in page 16..... From ROM..... Store existing ROM page# in RAM (1) Load New ROM page# in RAM (16) Load branch target in RAM (yyyy) BL to paging routine in RAM Store R11 switch banks MOVB >0010,@ROM BL to target address yyyy when routine is over..... B to ram unbanking routine Restore ROM bank MOVB >0001,@ROM restore R11 RT This would not be a large amount of code for sure but the rest of RAM could be used for common routines or data storage or whatever gets you going. Since it is always on the buss so to speak then it is available from all ROM pages. Since the cart always starts in bank 1 (hopefully) then that bank would simply download itself to the RAM and go from there. Having never done anything that works from bank switched ROM I can't speak to the advantages or disadvantages to this scheme so you will have to chime in with your thoughts. Marc, the more I think about your suggestion, the more I like it. It's kind of the opposite way around to how I've been doing it, but I like it. In TF there are two 8K banks: Bank 0: Holds the entire Forth dictionary, all words written in Forth (including the interpreter compiler), and common words written in assembly that must run quickly (I.e. I don't want to 'spend' on the time required to do a bank switch), such as all the stack manipulation words and math words. Other words (e.g. sprites etc) have their 'stubs' (i.e their Forth dictionary entries) in Bank 0, but the code just does a: BL @BANK1 DATA _SPRITE and runs the (assembly) code in bank 1. There is a "bridge" routine in pad ram (i.e. the routine BANK1, above) is in pad ram that actually pages in bank 1, and does a branch to the intended location (_SPRITE in the example above). The code in bank1 calls another routine in pad to page bank 0 back in again, and resume. Both routines are very small. However, I like the idea of just copying a routine in 4K of memory from a bank, and executing it from there. Like you say, commonly used stuff would be copied in at startup and stay there throughout the life of the application. Neat.
  5. You point out that GPL will use less storage and variables than XB and Assembly. Now you know I'm not an expert at GPL, so I'm not going to try and dissect the GPL version of the demo (post #7), but could you explain how GPL will end up using less variables with "the same program" in question ? I also know nothing about GPL, but I would have thought that the GPL version would use the same number of variables as any other languages. To understand what mean, you have to stop thinking in terms of languages, and think in terms of algorithms. Let's a take a bouncing ball that bounces off the screen edges. The minimum number of variables is 4: Current x coordinate Current y coordinate x direction (1 or -1) y direction (1 or -1) You could *possibly* do it with 3 variables, using a screen address instead of x and y coordiantes, but that just makes screen edge detection more complex. So, GPL, XB, Assembly: The *algorithm* still needs 4 (or 3!) variables. The *language* makes no difference. Therefore I don't really agree that GPL uses less variables for a given job/task. The number of variables is inherent in the algorithm, and once you have broken the algorithm down into its most efficient form, that is how many variables you need, in *any* languge. I do agree that GPL is cool though! I will definatlely try it out!
  6. It's in different places in each GROM set. That's why there's a vectored function in GPL to get the data from, and why I wrote this function in the first place. It probably is larger than the GPLLNK, but I never liked the idea of relinquishing control and hoping I get it back. Ah! OK, thanks Tursi!
  7. Okay, for me, 1K in the upper cart memory address would be just fine. Would it be possible to include a jumper for 4K or 1K RAM? (You know, since we're just kicking the tyres here!)
  8. Given that GPL is a byte based assembly language, it expect it is possible to write much more compact programs in GPL than in assembly - the tradeoff being speed, of course. Imagine if TI *had* produced a GPL processor chip (as was the rumour?) - man, that would have been something! Mark
  9. Thanks guys. I'll look at status reg #1 first as that is likely a simpler solution. Question though... How does one read a *status* register in 9900 land? We can read *VDP* registers using the normal means... Are the status regs read using the exact same technique, or is there a different address in play for those registers? I have 80 column working just fine. The whole system adapts iteself itself if you go into 80 column mode. Thats been working (and is included) in TF V1.0 - however, I would like the system to auto-detect and just enable 80 column at start-up if the 38/50 is detected. For that though, a reliable detection mechanism is critical. Can't have it trying to sdelect 80 column mode on a 40 column system! Mark
  10. Crikey mate! I reckon that takes more room than the GPLLNK routine ;[ GPLLNK ; This routine is based on the routine published in the July 1986 edition of ; Smart Programmer. Modified by yours truly to allow it be executed from ROM. gplws equ >83e0 ; GPL workspace gr4 equ gplws+8 ; GPL R4 gr6 equ gplws+12 ; GPL R6 stkpnt equ >8373 ; GPL stack pointer ldgadd equ >60 ; load and execute grom address entry point xtab27 equ >200e ; low mem XML table location 27 getstk equ >166c ; cpu register data - this data is copied into >200e onwards, so that it sits ; in R7 onwards gpllnk data glnkws ; [mapped to R7] set up BLWP vectors data glink1 ; [mapped to R8] rtnad data xmlrtn ; [mapped to R9] gxmlad data >176c ; [mapped to R10] GROM address for GPL XML 0F27 opcode data >50 ; [mapped to R11] Initialised to >50 where PUTSTK ; address resides ; this routine runs in it's own workspace, starting at >2000 glnkws equ >2000 ; GPLLNKs workspace of which only registers R7 thru R15 ; are used glink1 li r0,gpllnk ; we need to copy the cpu register data (above) to li r1,>200e ; RAM. R0=Source, R1=Destination li r2,5 ; R2=Word count gpllop mov *r0+,*r1+ ; copy the data above into r7 onwards... dec r2 ; copied all of it? jne gpllop ; loop if not mov *r11,@gr4 ; put PUTSTK address into R4 of GPL WS mov *r14+,@gr6 ; put GPL routine address in r6 of GPL WS mov r9,@xtab27 ; put XMLRTN address into >200e lwpi gplws ; load GPL workspace bl *r4 ; save current GROM address on stack mov @gxmlad,@>8302(r4) ; push GPL XML address on stack for GPL return inct @stkpnt ; adjsut the stack pointer b @ldgadd ; execute our GPL routine xmlrtn mov @getstk,r4 ; get GETSTK pointer bl *r4 ; restore GROM address off the stack lwpi glnkws ; load our ws rtwp ; all done - return to caller ;] Is there any evidence to suggest that the graphics data in GROM has ever changed location? Can I not just assume a hard-coded address? Mark
  11. I'm really very interested in GPL and plan on having a serious go with it soon. The thing about assembly language on the TI is the TMS9900 instruction set - assembly language on the 99xx is *so easy*, that once you know it well, it really doesn't make sense to 'go backwards' into other languges. Except Forth. Sorry! But you expected me to say that, didn't you!
  12. Can anyone think of a method to auto detect a V9938 or 58 in code? I seem to remember they had a special register that contained some sort of ID field, but I can't find it after scanning the data book
  13. Hmmmm... every time I turn on my TI I am instantly greeted with "Menu" (assembly program) and can select 24 assembly or XBASIC program to run instantly at the touch of a button. No loading required (on my part anyway.) And where does this reside? Afraid you missed my point. The TI was built to access 640K of GROM from the cartridge slot in 1979. This was just the console and nothing else. Really what can you do with 8K Cartridge RAM and just a console? (Answer: Sell cartriges like hot cakes just like TI did. Hottest item they sold, and attempted to shut down others that created them.) I fully understand things change but give credit to what made this possible. When the TI99 was introduced it was the GROM slot that sold the machine not the DISK programs or TAPE programs. Later DISK and TAPE took off. Everyone started with EA/MM/XB/LOGO/PASCAL or the Basic built in. All of these are GPL. Just please give credit instead of dissing GROM. All of these hacks copy what GPL does right out of the box since it was introduced. Nobody is dissing GROM. Just pointing out a bit of evidence that contradicts your wildly inaccurate statement. All computers of this era had cartridge ports so I don't understand why this attribute "makes the computer." I understand your affinity to GPL and I think it's great. But when you make silly arguments as to why it is the end all and be all of the TI then you really just hurt your own cause. As far as Turbo Forth is concerned. I may be wrong but I don't think it contains much GPL or GROM. No. No GROM and it only uses a single GPL call to load the upper case characters at startup! That's it! If I knew how to locate the characters in GROM then I could save some memory, as it is, I had to write a GPLLNK *just* to load the freaking characters!
  14. I believe you could, yes. Though, in fairness to GPL, you could also write a Forth in GPL!
  15. Street cred to both languages/implementations. Me too, I thought TF would be maybe at least twice as fast, but I guess GPL surprises a bit. It certainly does surprise! Would it run at that speed in a real console, running from GROM?
  16. That is exactly what happened with the Commodore 128.
  17. Yeah, it's the RND routine, which is just reading from memory addresses. I'm no mathematician! GPL and TF seem to be very very close indeed - they looked exactly the same speed to me. I thought TF would be a little bit faster than GPL, but it looks about the same. Mark
  18. I'll check my cart box tonight and see if I have a mini-mem in there. I'm 99% sure I do. Of course, being a British console, all our GROMS are PAL, therefore results may differ from NTSC GROMS (joke!)
  19. Good morning! Ok, a quick explanation of the code. I'll skip the definition of the graphics, I'm sure you understand that. Let's look at the color data: CREATE COLORS 2 C, 3 C, 4 C, etc.... CREATE simply creates an entry in dictionary with the name that follows CREATE. So, in the above code, a dictionary entry called COLORS is created. When we *execute* COLORS (by simply using it's name in the code) it is programmed to simply push the address of the word (the address of the 'code space') of the word. Who programs COLORS to do this? CREATE does! (You could think of CREATE as a class and COLORS as an object of type CREATE, with one single method - to push the address of its code-space). Ok, I hope that wasn't too hard to understand. Next, we use C, ("compile a char") to 'compile' numbers (called literals) directly into memory. So... 2 C, 3 C, 4 C, 5 C, 6 C, 8 C, 8 C, ...compiles 2 3 4 5 6 8 and 8 (as bytes) into memory. TF takes care of where they will be compiled (there is an internal pointer called HERE which always points to the *next* compilation address - C, uses HERE to get the address, and increments HERE by 1 afterwards). So, by "compiling" those numbers *directly after* COLORS, we find that when we execute COLORS the address returned is the address of first byte of the numbers we just compiled. What we just did is *exactly* the same as this in machine code: colors data 2,3,4,5,6,8,8 So, using simple terms, we compiled a list of bytes, and COLORS returns the address of the start of that list. Try this in TF: CREATE LIST 1 C, 2 C, 3 C, 4 C, 5 C, 6 C, : TEST LIST 6 0 DO DUP I + [email protected] . LOOP DROP ; [email protected] means "fetch byte". Words in Forth have prototypes, a bit like C, but their format is different, because Forth is stack based. Forth "prototypes" are called "stack signatures". Here is the stack signature for [email protected]: [email protected]: address -- byte The important thing in a time signature is the -- symbol. The stuff on the left shows the stack BEFORE the word executes. The stuff on the right shows the stack AFTER the word executes. So, we can see that [email protected] expects an address on the stack, and replaces that address with the value (byte) at that address. Here is SWAP: SWAP: a b -- b a So, swap takes the top two stack items, a and b and exchanges them, giving us b a. [email protected] is the same as [email protected] - however, it reads a byte from VDP: [email protected]: vdp_address -- byte_value VALUEs are very much like variables: 9900 VALUE TI ok:0 TI . 9900 ok:0 50 TO TI ok:0 TI . 50 ok:0 1+ and 2+ add 1 and two to the top-of-stack: 1+: a -- a+1 2+: a -- a+2 2DUP DUPlicates the top TWO items: 2DUP: a b -- a b a b The word 3DROP needs special explanation. 3DROP is a "compiling" word. Compiling words are quite unique to Forth, so it usually takes people a while to get their head around them. The first thing to notice is the word IMMEDIATE after the end of the definition of 3DROP - this is very important. When 3DROP is compiled into memory, nothing very special happens. It just gets compiled like any other word. However, when 3DROP is referenced in another word, something very special happens.... Normally, when the compiler is compiling a word, it just compiles a call to each word that it finds. However, if the word referenced is marked as IMMEDIATE, rather than compiling it, the compiler instead EXECUTES the word. So, when the compiler is compiling MAIN-LOOP it sees a reference to 3DROP and instead of compiling 3DROP, it executes it. Ok, so what happens then? Well, 3DROP actually compiles some words itself into memory (pointed to by HERE). It compiles a DROP then a 2DROP. Where do these get compiled to? They get compiled into the current location in MAIN-LOOP because that was where HERE was pointing to when 3DROP executed! So, 3DROP is a macro that compiles its payload into the "current definition". So, MAIN-LOOP looks like this in the source code: IF 4 OR 1 HCHAR ELSE 3DROP THEN However, in memory, it looks like this: IF 4 OR 1 HCHAR ELSE DROP 2DROP THEN Hope this helps to de-mystify Forth a little bit. It really is very simple. It's like a "super machine-code" - very very simple.
  20. Man, I wish this was around when I was writing TurboForth... This would have made life a lot easier. Any idea of the component costs?
  21. Here it is in TurboForth: : SHAPE1 DATA 4 $C0C0 0 0 0 33 DCHAR ; SHAPE1 : SHAPE2 DATA 4 $3F3F 0 0 0 34 DCHAR ; SHAPE2 : SHAPE3 DATA 4 $FFFF 0 0 0 35 DCHAR ; SHAPE3 : SHAPE4 DATA 4 0 $C0C0 $C0C0 $C0C0 36 DCHAR ; SHAPE4 : SHAPE5 DATA 4 $C0C0 $C0C0 $C0C0 $C0C0 37 DCHAR ; SHAPE5 : SHAPE6 DATA 4 $3F3F $C0C0 $C0C0 $C0C0 38 DCHAR ; SHAPE6 : SHAPE7 DATA 4 $FFFF $C0C0 $C0C0 $C0C0 39 DCHAR ; SHAPE7 : SHAPE8 DATA 8 $0000 $0000 $0000 $3F7F $0103 $0303 $0303 $FFFF ; CREATE COLORS 2 C, 3 C, 4 C, 5 C, 6 C, 8 C, 8 C, 9 C, 10 C, 11 C, 12 C, 2 C, 14 C, 15 C, : INIT 1 GMODE 13 SCREEN 4 1 0 COLOR 7 0 DO \ define bricks and set colours from colour table... SHAPE8 I 8 * 40 + DCHAR I 5 + COLORS I CELLS + DUP [email protected] SWAP 1+ [email protected] COLOR LOOP ; 0 VALUE SEED $8379 [email protected] TO SEED : RND SEED 31421 * 6927 @ + DUP TO SEED ; : 3DROP COMPILE DROP COMPILE 2DROP ; IMMEDIATE 0 VALUE R 0 VALUE C 0 VALUE BRICK : MAIN-LOOP INIT BEGIN BEGIN RND 23 MOD TO R RND 30 MOD TO C R C GCHAR 38 < R C 1+ GCHAR 38 < AND UNTIL RND 7 MOD 8 * 40 + TO BRICK R C BRICK 1 HCHAR R C 1+ BRICK 1+ 1 HCHAR \ do shadow tests... R C 2+ 2DUP GCHAR DUP 39 < IF 4 OR 1 HCHAR ELSE 3DROP THEN R 1+ C 2DUP GCHAR DUP 39 < IF 2 OR 1 HCHAR ELSE 3DROP THEN R 1+ C 1+ 2DUP GCHAR DUP 39 < IF 3 OR 1 HCHAR ELSE 3DROP THEN R 1+ C 2+ 2DUP GCHAR DUP 39 < IF 1 OR 1 HCHAR ELSE 3DROP THEN AGAIN ; MAIN-LOOP http://www.youtube.com/watch?v=CUP9vu0lNB0 Hope you like it. [Edit: No CPU overdrive was used in the above videos. Just paste the code into classic99 to try it out. Enjoy]
  22. Installed and working nicely on my ageing XP SP3 system - no problems at all! Now for 9938 emulation, and my life will be complete Thanks for all you do for us TIers...
  23. Ok, so, to be clear, its not a bug in classic99 per se, its an issue with the design of the original TI GPL interpreter, yes?
×
×
  • Create New...