speccery Posted September 28, 2021 Author Share Posted September 28, 2021 1 hour ago, Tursi said: You can write emulation in C, you know. Or any other language. 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. 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted September 28, 2021 Share Posted September 28, 2021 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. 2 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 7, 2021 Author Share Posted October 7, 2021 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. 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 7, 2021 Share Posted October 7, 2021 "Bug for bug compatibility" 2 Quote Link to comment Share on other sites More sharing options...
SteveB Posted October 7, 2021 Share Posted October 7, 2021 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? 1 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 7, 2021 Author Share Posted October 7, 2021 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. Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted October 7, 2021 Share Posted October 7, 2021 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. 3 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted October 8, 2021 Share Posted October 8, 2021 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) 2 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted October 8, 2021 Share Posted October 8, 2021 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. 2 Quote Link to comment Share on other sites More sharing options...
GDMike Posted October 8, 2021 Share Posted October 8, 2021 I'm really good at having bad programming behaviors. 5 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 9, 2021 Author Share Posted October 9, 2021 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. 4 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted October 9, 2021 Share Posted October 9, 2021 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. 3 Quote Link to comment Share on other sites More sharing options...
speccery Posted October 16, 2021 Author Share Posted October 16, 2021 In the latest episode for RCR podcast #243 (Retro Computing Roundtable) the strangecart project was covered a bit. That was nice! I thought the comments were a bit different from what I expected, so I posted some feedback on their Facebook page, and that seems to be well received. 3 Quote Link to comment Share on other sites More sharing options...
artrag Posted November 2, 2021 Share Posted November 2, 2021 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 2 Quote Link to comment Share on other sites More sharing options...
rodonn Posted November 2, 2021 Share Posted November 2, 2021 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. 3 Quote Link to comment Share on other sites More sharing options...
TheMole Posted November 4, 2021 Share Posted November 4, 2021 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... Quote Link to comment Share on other sites More sharing options...
+retroclouds Posted November 13, 2021 Share Posted November 13, 2021 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? Quote Link to comment Share on other sites More sharing options...
speccery Posted November 20, 2021 Author Share Posted November 20, 2021 (edited) 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 November 20, 2021 by speccery 4 Quote Link to comment Share on other sites More sharing options...
+retroclouds Posted November 20, 2021 Share Posted November 20, 2021 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. Quote Link to comment Share on other sites More sharing options...
speccery Posted November 20, 2021 Author Share Posted November 20, 2021 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. 4 Quote Link to comment Share on other sites More sharing options...
speccery Posted November 23, 2021 Author Share Posted November 23, 2021 (edited) 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 November 23, 2021 by speccery 4 Quote Link to comment Share on other sites More sharing options...
wierd_w Posted November 24, 2021 Share Posted November 24, 2021 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... 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted November 24, 2021 Share Posted November 24, 2021 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 2 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted November 24, 2021 Share Posted November 24, 2021 The ternary operator ( cond ? true_value : false_value ) was one of my favorite constructs in C, and I use it a LOT in PHP. 1 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted November 24, 2021 Share Posted November 24, 2021 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; } 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.