2023-12-30 08:20:57 So, I was chatting with vms14 yesterday about splitting disk reads into two words, one to start the read (non-blocking) and one to finish it (blocking if the read isn't done yet). Back when I was tinkering with Forth hardware I had an architecture with separate fetch and execute units. In that plan I thought about splitting conditional branches in the same way. My reasoning was that SOMETIMES the 2023-12-30 08:20:59 application might allow you to know how to do the "test" for a conditional branch earlier than the time the branch is actually taken, and in those situations the split would let me begin the branch calculation early, have some additional application work to do, and by the time I came to the actual branch point the prefetch process would have had time to buffer up some code along the correct path. 2023-12-30 08:21:09 Has anyone seen anything like this done elsewhere? 2023-12-30 08:21:43 It wouldn't always be possible to start early - the last computed data might be necessary for the branch decision. In those cases... I just wouldn't be able to do the trick. 2023-12-30 08:22:37 The idea was that the execute unit would calculate the branch decision and then "post" it in some way to the fetch unit. As long as that happened before the fetch unit reached the branch point, fetching would never need to pause. 2023-12-30 08:24:05 That design was one of those "cell is either a call address or packed opcodes," and the GENERAL idea was that fetch would peel down through calls until it found opcodes, and pipe those on forward to the execute unit. 2023-12-30 08:24:50 The goal was to, as much as possible, never let execute's stream of opcodes run dry. 2023-12-30 08:25:49 sounds like what javascript calls a promise 2023-12-30 08:25:53 I was going to do it by having a set of registers that execute could write and fetch could read - two-bit registers that could be either true, false, or "empty." 2023-12-30 08:26:13 Cool - I'll look that up. 2023-12-30 08:26:40 It would be up to the programmer to select one of the registers for each branch decision - so it would allow some degree of loop nesting. 2023-12-30 08:28:11 I never really thought through the case where execute wanted to write a port and it was already full - I suppose that would just stall execute until fetch used the existing content (which would empty the port). 2023-12-30 08:29:30 Yeah, that does bear a fairly strong resemblence. 2023-12-30 08:31:49 I never got that part designed. I did get the execute unit pretty thoroughly designed, though (on paper). That was back before I had much of a clue about Verilog (I knew about it - hadn't used it any), and it was all actual logic circuits sketched out on paper. It used five bit opcodes and I had the hardware stacks and the ALU all mapped out. 2023-12-30 08:32:31 The encoding was fairly careful - the hardware stacks were directly controlled by the five bits without any sort of microcode mapping or anything like that. 2023-12-30 08:33:20 I kind of lost interest in it when I realized how power hungry it would be (every cell of the hardware stacks changed every time they were pushed or popped). 2023-12-30 08:34:27 And the ALU did the standard trick of computing everything, with the opcode selecting the desired result. 2023-12-30 08:35:09 It was a Harvard architecture, and writing to the code RAM was somewhat tricky and required some hoop jumping. 2023-12-30 08:36:25 I had Spartan 6 in mind when i wrote it - it was all optimized for that family's 6-input LUTs. 2023-12-30 08:38:00 Oh, it also split @ into two pieces, because that one required two cycles. It was strictly one instruction, one cycle. 2023-12-30 08:39:01 And the execute unit only had two LUT layers between register outputs and inputs. 2023-12-30 08:40:13 Letting a third layer creep in would have knocked the clock rate down by a third or something like that. 2023-12-30 08:48:00 Hey - progress; 2023-12-30 08:48:02 https://www.electronicdesign.com/technologies/industrial/displays/video/21260865/electronic-design-e-ink-brings-tens-of-thousands-of-colors-to-ereaders 2023-12-30 08:48:28 Sooner or later someone will speed that up enough to make it work for "real" displays. 2023-12-30 09:14:54 Oh. 23andMe has modified my genetic "composition data." Formerly I was like 87% British, about 10% Scandinavian, and a smattering of other nearby things. They've now shifted about 8.5% of the Scandinavian to French/German. 2023-12-30 09:15:31 Um, not 8.55 of the 10% - 8.5% overall, leaving 1.5% Scandinavian. 2023-12-30 09:16:24 They've got the British part localized - looks like it falls most likely in these parts of Britain: 2023-12-30 09:16:26 https://en.wikipedia.org/wiki/File:Yorkshire_and_the_Humber_in_England.svg 2023-12-30 09:16:33 https://upload.wikimedia.org/wikipedia/commons/5/5e/East_Midlands_in_England.svg 2023-12-30 10:50:26 i wonder how easy it would be to convince : to ignore a comment between it and the new word's name 2023-12-30 10:50:47 it just occurred to me that this seems more natural: : ( stack effect ) foo ... ; 2023-12-30 10:51:01 because you show the stack before the word as it would be called in practice 2023-12-30 10:51:40 and then it naturally lends itself to a new word, :( stack effect ) foo ... ; where you actually parse the stack effect and use it for some compile time checking 2023-12-30 11:07:58 Hmmm. That would be difficult. I think you'd have to code : to do that itself - its normal behavior is to take the next word in the stream and use it to name a new word. To get what you want it would have to check that word string and take special action in special cases. 2023-12-30 11:08:32 Not "difficult," I guess. It would be straightforward, but it would be kind of tediously "manual,' if you get my drift. 2023-12-30 11:09:08 The way I've always written it it doesn't pay any attention at all to what the word IS - it just blindly takes the characters and makes a new header. 2023-12-30 11:09:15 yeah, i think so too. and then you couldn't define ( with :. there is a part of me that is tempted to add a : :( postpone ( postpone : ; word now, though, and start using it. maybe some day i'll get inspired to actually start parsing those stack effects and add some compile time checking 2023-12-30 11:09:19 Doesn't look at the existing dictionary at all. 2023-12-30 11:10:06 I think it's common for systems to warn you when you reuse a name, so they do have to do a search to achieve that. 2023-12-30 11:10:09 I just don't bother. 2023-12-30 11:22:37 How are if and then implemented in color forth? Does if put the address on the return stack? 2023-12-30 11:33:40 I think he still has jump and conditional jump instructions. 2023-12-30 11:34:25 If you have tail optimization then you basically have to have a jump. 2023-12-30 11:38:00 Looking at the colorforth asm file, I don't see an if but there's a jump which I think is like a computed jump so could be used for conditional branching 2023-12-30 11:38:38 I believe that the GA144 cores use the F18A architecture, which you can see the instruction set of here: 2023-12-30 11:38:42 https://www.greenarraychips.com/home/documents/greg/PB003-110412-F18A.pdf 2023-12-30 11:39:12 It has if and -if instructions, which do conditional jumps. 2023-12-30 11:39:25 Jump if T=0 and jump if T>=0. 2023-12-30 11:40:04 I'm using this architecture to some extent in my next system, but I'm not slavishly following every detail. 2023-12-30 11:41:25 My recent trend has been to restrict jumps to be "back to the beginning of the word." Well, either that or tail optimizaiton jumps, which would go to some other word potentially. 2023-12-30 11:42:06 I may include an instruction, though, that lets me "pull forward" that target from "start of word" to the place I execute the instruction. 2023-12-30 12:03:14 Anyway, I don't know if the F18A is "exactly" ColorForth, but I suspect it's close. 2023-12-30 12:06:59 this is nice. https://rainbowforth.sourceforge.net/blocks.html 2023-12-30 12:10:01 Ah, I do like that straightforward layout. 2023-12-30 12:10:43 http://rainbowforth.appspot.com/ is good too 2023-12-30 12:10:51 ACTION is entertained by https://www.youtube.com/watch?v=yAEveAH2KwI 2023-12-30 12:11:02 That's very much how I'm planning to approach my next system. i'm going to write it in blocks right from the start, and have a C program initially to interpret/compile that material, but the system should wind up capable of re-building itself from the same source. 2023-12-30 12:11:25 In fact, if I can I want to gradually "hand off" responsibility from the C to the "system itself." 2023-12-30 12:11:35 So that as soon as I've written a piece of code I'm using it. 2023-12-30 12:12:32 Oh, Mathologer is great. 2023-12-30 12:12:46 I haven't seen this one before. 2023-12-30 13:51:23 I want to write a very simple infix calculator in forth as an exercise, and later on expand it to have variables and user-defined function, and with a bit of hope extend that to a barely practicaly programming language. Any suggestions on how to start? 2023-12-30 13:52:16 I think the Forth Scientific Library has an infix parser 2023-12-30 13:52:44 or http://tumbleforth.hardcoded.net/ 2023-12-30 13:52:45 Thanks, I'll check that out. My first guess was looking at shunting-yard. 2023-12-30 13:57:33 For the lexer my first guess was to start with something like : lexer abort" Error: couldn't find a matching token for character " over c@ emit cr ; 2023-12-30 13:58:31 Then we could add tokens with : lexer insert-code-here ( flag ) if exit then lexer ; 2023-12-30 13:58:49 Rather error prone, but it felt forthy. 2023-12-30 14:01:26 > Had I thrown you directly to Leo, you’d have whipped up GForth, a Forth implementation that is too complex for its own good 2023-12-30 14:01:35 That made me smile :) 2023-12-30 14:02:38 I had a quick look at the FSL and could see anything so I'm probably misremembering 2023-12-30 14:02:43 Er, couldn't 2023-12-30 14:08:46 GeDaMo: Appreciated! 2023-12-30 15:11:11 user51: you know of jonesforth? 2023-12-30 15:23:23 Darn, already gone? :D