Jump to content
IGNORED

StrangeCart


speccery

Recommended Posts

1 hour ago, Tursi said:

You can write emulation in C, you know. ;) Or any other language.

 

 

:D sure you can. I was thinking about the Basic interpreter I’ve been working on. But yes, having a good C compiler would do it. In any case my use of C++ in these embedded system environments is very close to C.

  • Like 1
Link to comment
Share on other sites

I love your basic interpreter. I've always been a one command per line guy anyways.

You'll have to add a new keyword, probably something like speed.

I think the two places the interpreter might get in to the weeds are some of the more complex mathematical statements... including doing them all in matrix-100 for compatible output, and file I/O - since many of the device DSR don't even support the same commands.

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

Continued a bit with the basic interpreter development. I've been busy with RL, not much time for this project in the past week. I discovered I am still learning basic, as one of the test programs (Escape) breaks the interpreter. It's a very nice game by the way. Of course totally unplayable on the StrangeCart, the screen blinks and its game over, so need ingest a delay loop (or a new VSYNC command) somewhere. 

 

The problem I encountered is that the basic crashes after a few "game over" screens due to for-next stack becoming full. I think I made it 16-deep, so you can have 16 nested for-next loops. The reason for the stack filling up must be that the programs uses goto to break from the for-next loop. It later then enters this same loop again, when one starts a new game after "game over". At this point my basic interpreter allocates new space in the for-next stack, and eventually exhausts the stack. I believe the original TI basic unwinds the for-next stack when one uses goto to escape a loop before running it to completion. That's pretty interesting, and means I need to make "goto" much smarter than it is. It probably means that a goto can actually unwind any level of nesting of for-next loops. Reading the TI basic manual it multiple times states that each "for" must be matched with a "next". That of course makes sense, but it does appear that this is very rigid in TI basic. A for-next block effectively constitutes a scope, and goto out of the scope has semantic meaning. To live and learn.

  • Like 2
Link to comment
Share on other sites

13 hours ago, speccery said:

That's pretty interesting, and means I need to make "goto" much smarter than it is.

Well. I think this is the classic Entscheidungsproblem ... how to decide whether or not another GOTO will bring you back? When to discard the stack-entry? 

 

I would rather think that the same FOR-Loop resets the previous instance. This would also be easier to implement. What about when the FOR isn't the top of the stack? 

  • Like 1
Link to comment
Share on other sites

6 minutes ago, SteveB said:

Well. I think this is the classic Entscheidungsproblem ... how to decide whether or not another GOTO will bring you back? When to discard the stack-entry? 

 

I would rather think that the same FOR-Loop resets the previous instance. This would also be easier to implement. What about when the FOR isn't the top of the stack? 

Yes I think you’re probably right. It would appear that a for loop setup needs to traverse through the stack. If the variable is found already in the stack, it would be reset to the proper initial value and any other entries on top of it would be purged. Either way, it kinda sucks in my opinion. What I have now is a clean implementation, which obviously is wrong. Sigh.


a couple of test would be in order.

 

I have quite a few times during this implementation project been wanting to turn this into a compiler,  but I also want to have a pure interpreter first, so patience required. The amount of all kinds of error checks an interpreter needs to do is surprisingly big. Which makes me curious to understand how the BBC model B’s Basic was done, as it was very well done and fast. Or so I hear, have never tested one in person.

Link to comment
Share on other sites

4 hours ago, SteveB said:

Well. I think this is the classic Entscheidungsproblem ... how to decide whether or not another GOTO will bring you back? When to discard the stack-entry? 

 

I would rather think that the same FOR-Loop resets the previous instance. This would also be easier to implement. What about when the FOR isn't the top of the stack? 

I run all of my games in FOR-NEXT loops with break-outs when the games are over.  This prevents me from having to use GOTO in the loop and only either GOTO or THEN to exit.  My observation of TI BASIC and XB is that restarting the loop clears the stack of the old loop.

 

Generally, GOTOing out of a loop and back into it should be considered a no-no.  Programs expecting to temporarily leave a loop should use GOSUB, instead.

  • Like 3
Link to comment
Share on other sites

37 minutes ago, OLD CS1 said:

I run all of my games in FOR-NEXT loops with break-outs when the games are over.  This prevents me from having to use GOTO in the loop and only either GOTO or THEN to exit.  My observation of TI BASIC and XB is that restarting the loop clears the stack of the old loop.

 

Generally, GOTOing out of a loop and back into it should be considered a no-no.  Programs expecting to temporarily leave a loop should use GOSUB, instead.

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) 

 

  • Like 2
Link to comment
Share on other sites

On 10/7/2021 at 8:13 PM, TheBF said:

Maybe that's the trap that could be installed in this new BASIC interpreter. 

GOTO inside a FOR/NEXT structure throws an error. ??

I would say that GOTO outside of a FOR-NEXT loop would just invalidate that loop, then throw an error when they hit NEXT.  But that will break native behavior.  I just ran a test in which I GOTO out of a loop then back into it, and the loop completes as expected.  Next test I jump out of the loop then GOTO the start of the loop, which has been running now for several minutes having restarted the loop tens of times with no problems.

 

On 10/7/2021 at 8:13 PM, TheBF said:

We have to start reigning-in the bad habits of BASIC programmers somehow.  :)

(It's a joke. Don't kill me) 

Nah, BASIC does not necessarily encourage bad habits, but it does allow them.  At the same time, if we start cracking down on bad BASIC programmer behavior we run away from native behavior.

  • Like 2
Link to comment
Share on other sites

12 hours ago, speccery said:

With this program I tested that indeed when the outer loop exists, the inner loop will also be purged even if it has not ran to completion. That at least makes sense.

Were it not for the program flow, what you attempted would seem to be legal.  Obviously you cannot jump into a loop which has already completed, so the 300 to 305 flow would definitely be an error.  But something at 301, for instance, which by-passes 305 would seem to be valid.  Silly, but valid, and I do not expect BASIC to be smart enough for that.

 

Talk about bad habits, though... who would attempt such a mad exercise in real life?!

 

EDIT: never mind :)  I saw flow go from 215 to 305, rather than 300.  Now my brain is just making up shyte to prove something.

  • Like 3
Link to comment
Share on other sites

  • 3 weeks later...
On 10/7/2021 at 7:53 PM, speccery said:

Which makes me curious to understand how the BBC model B’s Basic was done, as it was very well done and fast. Or so I hear, have never tested one in person.

A little off topic - BBC BASIC is an odd, for the time, implementation of BASIC, in that it was possibly closer to PASCAL than any other BASIC of the time. Implemented in a 16K ROM, it supported limited recursion, something so close to  jagged arrays as made no odds, and an in-line 6502 assembler. I think Sophie Wilson, the primary dev behind the language, has spoken about it. It's very much "Nicolaus Wirth complete" in my opinion, and strongly reflects the paradigms of the era (OOP was about a decade away in any meaningful sense) 
If you want to have a tinker in the last [Acorn] iteration of the language, BBC BASIC V is part of RISCOS for the Raspberry Pi.

  • Like 3
Link to comment
Share on other sites

On 11/2/2021 at 8:22 PM, artrag said:

Can you emulate other machines based on the same TMS9918 ? E.g. MSX or Colecovision ?

It should be possible to make existing opensource emulators (e.g. openmsx) run the the ARM micro-controller on the StrangeCart

That's exactly what I was thinking when I posted this on the previous page: 

 

Would be super cool to see someone tackle this. I'd love to do it myself, but since I've moved to Asia I don't have access to real hardware anymore...

Link to comment
Share on other sites

  • 2 weeks later...
On 11/13/2021 at 9:13 AM, retroclouds said:

Watched the strangecart videos again. Really cool. 

Do you have plans to do a run of assembled strangecart boards in the future? And if yes, when?

 

Also very much like the TI Basic acceleration. How complete is it? Do you also have file IO support from a TI Basic program?

Thanks! In the past few weeks I have been quite preoccupied with work and not much progress. Sorry for the slow reply to you. 

I did add some features though, including ON..GOTO and ON..GOSUB, transcendental functions, and a couple of extension, for example CALL VSYNC which will do just that, pause program execution until next VSYNC. I also realised that adding extensions means I need add them twice, so that the same program can be run in TIBASIC and within StrangeCart. Thus CALL VSYNC works on both. It's of very limited use with TIBASIC, but hopefully not with StrangeCart, which is fast enough to do some stuff even at 60fps. I think I need to add support for sprites for that to be interesting.

 

File IO support is still lacking. Among statements & keywords I am currently missing:

  • GO and SUB (GOTO and GOSUB are there, but GO TO and GO SUB not yet, none of the existing programs I've tested use them)
  • CALL SOUND is decoded but sound is not working yet
  • DEF not implemented yet (requires support for crunching, i.e. tokenisation which is not there yet)
  • LET is not yet there (but assignments without LET work - none of the test programs I tested use LET)
  • DELETE (token 0x99) is not supported, and it does not need to supported by TI BASIC either?
  • OPTION, BASE not done yet
  • OPEN, CLOSE, DISPLAY, EOF, REC, VARIABLE, RELATIVE, INTERNAL, SEQUENTIAL, OUTPUT UPDATE, APPEND, FIOXED, PERMANENT, # not done yet
  • Support for multidimensional array is half done. This is not complex, but only partially done since none of the games I used for testing use multidimensional arrays. The internal data structures of my interpreter handle multiple dimensions, but array index decoding currently only takes one argument.
  • VAL not done yet (same as DEF, requires tokeniser)
  • CALL KEY is only partially done, as is INPUT. CALL KEY currently only supports one of the scanning modes, and INPUT is really stupid in that it only waits for a single character :)

 

All of the TI BASIC tokens are decoded with CALL LIST, which enables me to see the tokens I still need to implement. Even if the list above seems quite long, there is a ton of stuff already supported and seemingly working ok. There's not that much code yet, just under 3000 lines of C++ in the BASIC part of the code. The overall codebase (not including any libraries) is about 13000 lines of C and C++ code, so the Basic is starting weigh in. The firmware size is 140k, including 45k of cartridge code, so the actual firmware is just under 100k.

 

Since I am currently using SAVE STRANGE.name (where name is just ignored) to get BASIC programs, I don't support any Basic commands or editing of programs. For substitutes there are CALL LIST and CALL RUN to run on the StrangeCart. 

 

I think a good test program for some of the file I/O is the catalog basic program, to list the directory of a disk. That is very slow indeed in Basic.

 

The current chip shortage is making manufacturing tough, but I have acquired around 30 microcontrollers before they became out of stock, and I will be hand assembling some more boards. In fact I just need to make a production test program to be able start sending out first boards, they have been laying in a box ready to go but waiting for a more comprehensive test suite. I need that since there are some I/O pins which are for optional expansion and not tested by just using the cart normally. All the boards I have built can run games etc. so they seem to work, but running games does not exercise everything.

Edited by speccery
  • Like 4
Link to comment
Share on other sites

Thanks for the update.

 

One more question, with the possibility to override the GROMS 0-2, would it be possible to use the strange cart to drive a usb keyboard instead of the built-in TI-99/4a keyboard?
I suppose it is not possible to override the system ROMS where KSCAN resides, but if the GPL interpreter is patched to not use the KSCAN.

 

Would be kinda cool to have the strangecart as a "plug-and-play" solution for running a USB keyboard. Not sure if it would work with all software as that would really require KSCAN to be modified.

Link to comment
Share on other sites

1 minute ago, retroclouds said:

Thanks for the update.

 

One more question, with the possibility to override the GROMS 0-2, would it be possible to use the strange cart to drive a usb keyboard instead of the built-in TI-99/4a keyboard?
I suppose it is not possible to override the system ROMS where KSCAN resides, but if the GPL interpreter is patched to not use the KSCAN.

 

Would be kinda cool to have the strangecart as a "plug-and-play" solution for running a USB keyboard. Not sure if it would work with all software as that would really require KSCAN to be modified.

By the way I was editing the message when you sent the reply, some more updates above.

 

The StrangeCart is not a USB host, it's a USB device. Thus it cannot directly interface with a keyboard. It would need a USB Host adapter, and I actually have those but haven't had the time to play with them - the same board used by @jedimatt42. It should be possible to have the strangecart interface with a USB Host adapter board. Or just plug a raspberry pi to the strange cart, and use it as a USB Host for a keyboard as well. In that case the USB handling would have to be changed a bit, right now the firmware uses USB as a very fast serial port.

  • Like 4
Link to comment
Share on other sites

The list I wrote a few days ago regarding the missing Basic features was looking a bit long, so last Sunday I had a bit of time and finalised support for multidimensional arrays and the OPTION BASE statement. This strikes out two lines in the list.

I also realised that to support DEF I don't need a tokeniser, so that probably is next on my list. When playing a bit with self defined TI BASIC functions (on the computer itself) I noted that if TI Basic included something similar to C's "condition ? val-if-true : val-if-false) it would be possible to create recursive functions, and we could actually code algorithms with self defined functions alone :) 

Edited by speccery
  • Like 4
Link to comment
Share on other sites

I am unfamiliar with that decision type--

 

Does it do more than just evaluate?  EG, does it let you give arbitrary values for truth and falsity for something other than a boolean?

 

eg,

 

CONDITION MyValue ? "Boots" : "Pants"

 

Where MyValue is a string, and if it contains "Boots", evaluate TRUE, and if "Pants" evaluate FALSE?

 

I am trying to determine where this would actually shine, if that is the case, where a SELECT CASE block wouldn't have basically the same function, with a little thought.

 

EG,

 

SUB FakeConditionStatement(Val1, Val2, Test)

SELECT CASE Test

CASE is = Val1

                RETURN TRUE

CASE is = Val2

               RETURN FALSE

CASE else

              RETURN ERROR

END SELECT

END SUB

 

Then use the function wherever you want...

 

IF FakeConditionStatement("Boots","Pants",MyValue)=TRUE THEN ....

or

IF FakeConditionStatement("Boots","Pants",MyValue)=FALSE THEN  ...

 

 

I get that some people get jollies over being the most obtusely terse with their syntax they can possibly be, and that this can have benefits in a constrained environment, but the strangecart has ample memory, compared to the TI, and I prefer readability over terse-ness, when it is affordable.  (I like being able to read my code 5 years later, after i have forgotten all about how it worked when I wrote it, and quickly understand what it is doing. Being obnoxiously terse, does not really afford this.)

 

 

 

Mostly, I am just looking for clarity on why the condition function would be so desirable.  I have written fully recursive programs in basic on numerous occasions, and never once used such a structure...

 

 

 

 

  • Like 1
Link to comment
Share on other sites

4 hours ago, wierd_w said:

I am unfamiliar with that decision type--   Does it do more than just evaluate?  EG, does it let you give arbitrary values for truth and falsity for something other than a boolean? eg, 

 

CONDITION MyValue ? "Boots" : "Pants"

 

Where MyValue is a string, and if it contains "Boots", evaluate TRUE, and if "Pants" evaluate FALSE?

 

No. It is simply a very cryptic if-then-else expression:

y = (x > 0) ? m : n;

is another way of expressing

if (x > 0)
   y = m;
else
   y = n;

...lee

  • Like 2
Link to comment
Share on other sites

Something like this from my recent SCSI emulation - I use it several times in each file.

 

line_state whtscsi_pld_device::scsi_cs()
{
    return (busen()
        && ((m_board->m_address & 0x0fe0)==0x0fe0)
        && (((m_board->m_address & 0x1000)!=0) == m_bank_swapped)
        && (((m_board->m_address & 1)==0) || m_word_transfer))? ASSERT_LINE : CLEAR_LINE;
}
  • Like 1
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...