Jump to content

Maury Markowitz

  • Content Count

  • Joined

  • Last visited

Community Reputation

12 Good

About Maury Markowitz

  • Rank
    Star Raider

Recent Profile Visitors

3,996 profile views
  1. Not a hash function, the hash function 🙂 This is not how I thought Turbo worked, I thought it just pushed lines onto a list as they were encountered. But now I see how this works, it makes sense. That does raise the question those - if you're considering just the cases where the GOTO/GOSUB has a constant on the left, I wonder what the actual number of GOTO targets actually is? I'm currently hand-coding What to Do After You Hit Return, and so far it's been maybe 15 targets per program with perhaps 30 as the outside bound. So what does it do if the code is modified during runtime such that the starting point of the 256-line block moves?
  2. That's the idea that was tossed around in earlier posts, but that second part is a killer on the 8-bit. On a PC you're likely talking about a system with a small program running in a (relatively) large memory space that it can scan with some speed. Also, in Atari BASIC the RHS of the GOTO is an expression, not a constant, so in the (rare) case the expression produces a different line number you'd have to be able to deal with that too.
  3. Left-Hand Side. But I meant RHS 🙂 Ahhh right, it's a branch. But surely a straight GOTO can jump more that 128? I think I'm missing something key here, can you expand on this a bit? What is the hash function?
  4. Which version of MS BASIC is this? QBASIC or later?
  5. That's what I was thinking about. In the case of Atari BASIC you have the "this is a FP constant" token following the GOTO (well, 9 times our of 10 anyway), so when you encounter these you replace them with "this is a line number constant". This requires one more check in the parsing/eval, but if it hits (which it will that same 9 of 10), you're ready to call the GOTO. Then on SAVE you convert them all back to their original format, and on run/edit, well, I'm not 100% sure. But as the rest of this thread has noted, the single-step-of-indirect you get by placing the address in a hash somewhat offers no discernable difference in overall performance while avoiding this overhead. So I'm no longer so hot on this concept. Of course in Atari BASIC one might still wish to replace the 40-bit FP constant that does follow that 9-of-10 with a 16-bit version simply for RAM considerations. Hmm, I think the 65C02 would also allow this by having the line number addresses directly hashed and then using that ridiculously named "indexed absolute indirect" addressing on the JSR. It would mean having to put the line-number-table starting address in the zero page, however.
  6. So much for that theory. And it was such a nice theory... Agreed. Of course the table improves if the LHS is 16-bit, is that what you do on insertion? ...but that's because its cached, no? I suspect it would show up a *bit* higher in traces of the original!
  7. I got the rest of the post no problem, but this remains a bit confusing. As I understand it, constants found in the code are left in-place. Am I correct in thinking this is what you are referring to as "absolute". If so, does this flag only get "applied" during the parsing when the stack is being built? IE, this bit would never be set in the variable table itself?
  8. I'm reading over https://www.atarimax.com/jindroush.atari.org/afmtbas.html about the BASIC format and I'm confused about one thing: it says that an array of FP is indicated by a $40 or $41, and a string by $80 or $81. Is this actually true, and did Atari BASIC actually use both? Was there any reason for having two codes, or does anything with the right bit set work the same?
  9. Isn't the FP code in MS BASIC about the same size? I seem to recall 2700 bytes, but that can't be right.
  10. I'm sure that is the reason. I see that now, after thinking about a different issue in another thread. By using BDC they can have exact representations of small integers. So that lets them tokenize constants into an FP and know that when you LIST you'll get back the same number, exactly. In contrast, MS basic uses binary FP, which cannot be exactly reversed. So they leave their constants in text form, and run the text-to-fp routine every time. Skipping that conversion is likely a major speed boost. Whether that boost makes up for the general performance of BCD as opposed to non-BCD FP code is something I would love to explore.
  11. Sure, but they didn't do that when they published the results. So if you want to compare the Atari to, say, the Apple II, you either have to have both machines and run the same code, or use the published result and use the original code. As @phaeron noted, the difference is somewhere like a factor of 2x, so this is non-trivial. And yes, it would be about 2x on the Apple II as well.
  12. Wild! But I think I know why... To be honest, I'm not sure what Atari BASIC (AB herein) does here. I know for normal numeric constants, like A=A+10, the constant is parsed and replaced by it's FP representation, with a $0E placed in front of it to indicate a constant. The FP is 40-bits, so the total length of any constant is 1-byte + 6-bytes. I'm not sure if they do this for line numbers, I'll have to look. It would save the conversion at runtime, but since AB's maximum line number is 32767, it's 7 bytes of constant vs. maximum of 5 bytes of text, and typically maybe 3 bytes. Moreover, you have to convert the resulting FP number into the 16-bit line number anyway (which it uses, like MS), so there's still a little performance hit. And wow, I just realized why they used a BCD math package! Its because if you tokenize a number into a "real" FP, as opposed to BCD, then when you convert it back to a string you might get line 99.999999... This doesn't really do anything, but it sure looks weird - too weird. That's the problem you were avoiding by storing the original string constant. AB doesn't have to do that, small integers will always convert back correctly. Which brings me full circle on the whole int-FP question. If AB had 16-bit int constants, a relatively trivial upgrade, then you wouldn't need to use FP for (most) constants, and then you could replace the FP package with the MS one with few downsides. That makes for a very interesting test! In AB I would do that by using a unique token for the original 16-bit line number, say $0B, and then if you encounter an $0B during runtime... Oh, wait, this works perfectly! ... if you encounter a $0B during runtime, you run the line-lookup routine, change the $0B to $0A, and change the 16-bit line number to a 16-bit line address. I didn't think this would work because I think doing the scan-and-replace at program startup would be a high cost, especially in long programs. I note that BASIC XL does this if you use the FAST command. I concluded the table-lookup was the only solution that offered both a performance improvement and avoided startup issues. But looking at it now, you don't have to do this replacement for every line, only the ones that actually get called. And you only know that at runtime, so just do that then. This does introduce some randomness in the performance of the GOTO, but its worst case is still MS's best case. Of course one could combine the two approaches. When a $0B is encountered, you do the line-number-lookup and replace it in-place. But then you also put it in a lookup table. So then when the next unconverted GOTO pointed to the same line is seen, you can convert it using the table. However, I'm not convinced this is worthwhile given the complexity it would add to the runtime. It seems a direct comparison of the two (three?) approaches would be needed. Unfortunately, existing benches would be useless for this, because they are very small and only have one or zero GOTOs. You'd want to run something much longer with lots of typical BASIC spaghetti to know what's really going on. Super Star Trek would be great, but I can't imagine a way to benchmark it.
  13. I am curious, does overseas entail a trip eastward or westward?
  • Create New...