2022-12-19 00:14:03 Chuck's F21 instruction set is documented here: 2022-12-19 00:14:08 https://files.jjn.one/wp-uploads/forth/machine-forth/F21_CPU.html 2022-12-19 00:14:39 It's one of his odd "non-power-of-2" bus width designs. 2022-12-19 00:14:46 20 bit cells in this case. 2022-12-19 00:15:12 I assume those arose from him having some particular application in mind, and that was what he needed for it. 2022-12-19 00:15:35 This one has is "address register" words in it. 2022-12-19 00:16:20 I wonder where you could get one of these nowadays other than an FPGA 2022-12-19 00:16:26 to play around with 2022-12-19 00:16:36 Somewhere in that Ultra Technology papers he discusses that - instead of @ he has A! @A. 2022-12-19 00:16:51 According to him, that changes the way you write algorithms. 2022-12-19 00:17:06 For the better in his opinion, one would presume. 2022-12-19 00:17:32 registers?! that cant be 2022-12-19 00:17:32 And he can use the top of the return stack as an address register too, and both of those offer auto-increment options. 2022-12-19 00:17:32 shades of Sapir-Whorf 2022-12-19 00:17:40 I know. 2022-12-19 00:17:58 But I find it easy enough to understand the allure of auto-increment. 2022-12-19 00:19:50 pretty soon youll be saying the registers should be general purpose 2022-12-19 00:19:52 @A+ !R+ moves a cell from A addr to R addr and increments both. It's his fastest way of moving blocks of data. 2022-12-19 00:20:12 its a slippery slope from there to having a bunch of them 2022-12-19 00:20:19 Yeah. 2022-12-19 00:21:35 honestly juggling three addresses in a loop in forth is unpractical in my experience. using 1 or more registers seems like an improvement 2022-12-19 00:22:08 One comment he made, though, was to opine that the processor shouldn't be optimized for arithmetic. He felt that modern applications (in contrast to the older more scientific applications he began with) profit from optimizing for moving data around. 2022-12-19 00:22:31 Oh, also a lot of these processors seemed to work with cells only. 2022-12-19 00:22:41 There weren't any instruction level operations for handling bytes. 2022-12-19 00:23:04 So if you wanted to deal with bytes you'd need to shift and mask. 2022-12-19 00:23:24 And the older processors at least didn't seem to have barrel shifters. 2022-12-19 00:25:15 I've seen references to an A register, and sometimes A and B, in the Forth literature for a long time. 2022-12-19 00:25:33 Those were already at least mentioned even back in the mid/late 1980's. 2022-12-19 00:26:59 ya those are at the hardware level to execute the instructions as I understand it 2022-12-19 00:27:06 not separate registers you get to control 2022-12-19 00:32:32 Oh, no - look at that instruction set I just linked. 2022-12-19 00:32:54 You have A@ to do A -> T, A! to do T -> A, etc. 2022-12-19 00:32:59 You set them, explicitly. 2022-12-19 00:34:03 Then the only ways to fetch from RAM are with @A, @A+, and @R+. 2022-12-19 00:37:50 KipIngram: yeah, you can use OpenGL from it. 2022-12-19 00:38:12 w.r.t SDL. 2022-12-19 00:38:30 I just found a reference to this document in a forum: 2022-12-19 00:38:33 http://forth.org/OffeteStore/4001-footstepsFinal.pdf 2022-12-19 00:38:51 It's a Dr. Ting work, and it describes Chuck's "cmForth" in detail. 2022-12-19 00:39:18 Somewhere in those Ultra Tech pages Chuck (at the time of writing) regarded cmForth as the best of the Forths he'd written up until then. 2022-12-19 00:39:38 Looks like it has some unusual (by broad Forth methods) ways of doing things. 2022-12-19 00:39:44 For one thing, there are no immediate words. 2022-12-19 00:39:54 no immediate words? 2022-12-19 00:39:55 Instead, there are separate word lists for compile and interpret. 2022-12-19 00:40:05 If you're compiling, the compile list is searched first. 2022-12-19 00:40:29 ] *is* the compiler. [ just returns you from it to the interpreter. 2022-12-19 00:40:47 They're separate loops, rather than being mingled with conditional haandling based on STATE. 2022-12-19 00:41:20 decay: In Forth an immediate word is a word that executes right away, even if you're compiling a colon definition. 2022-12-19 00:41:25 I know. 2022-12-19 00:41:33 Oh, ok - sorry. 2022-12-19 00:41:41 just was wondering how they get along without them lol. 2022-12-19 00:41:47 if it's a different vocabulary, that makes sense. 2022-12-19 00:42:09 Yeah, the compiler will only compile words it finds in the compiler list; if it has to go to the interpreter list then it will execute it. 2022-12-19 00:42:27 any sample code that demonstrates that? 2022-12-19 00:42:39 I haven't really read the doc yet. 2022-12-19 00:43:13 Avoiding STATE is usually considered a "good thing" (tm), but the usual way is a pretty strong habit for me at this point. 2022-12-19 00:43:49 there is also freeforth which doesn't have interpret mode, all is compiled, so no STATE, which i think is very nice. 2022-12-19 00:44:56 I take it that it has macros. 2022-12-19 00:47:30 There is a discussion of the difficultires of IMMEDIATE, particularly in cross-compiling applicaitons, here: 2022-12-19 00:47:31 http://computer-programming-forum.com/22-forth/8837e323016a8a52.htm 2022-12-19 00:47:53 Rather explains it a ways down the page. 2022-12-19 00:48:33 In its original incarnation, immediate just had to set a bit. But in cross-compile applications, there's a bunch of word-list management going on too, and apparently it gets messy. 2022-12-19 00:49:21 iyzsong: How do you actually do something, other than compile, then? 2022-12-19 00:50:53 Anyway, re: the address registers, I presume moving to those was part of Chuck shifting his emphasis from arithmetic to data moving / management. 2022-12-19 00:52:04 One thing that's nice about it, for hardware Forths, is that it eliminates ! which requires poping two items from the stack. It's the only word that requires popping two items, so if you don't need it the circuitry is simplified. 2022-12-19 00:52:04 KipIngram: it use anonymous definitions, every line in REPL is compiled as a anonymous definition then executed, http://christophe.lavarenne.free.fr/ff/index.html#whatzat 2022-12-19 00:52:25 Ah - ok. I think I've seen something about that kind of approach before. 2022-12-19 00:52:47 ah, I understand. 2022-12-19 00:53:00 if a word is defined with a backquote, it's executed. 2022-12-19 00:53:07 anything outside a definition is executed. 2022-12-19 00:53:14 otherwise it's compiled. 2022-12-19 00:55:02 i'm a very beginner here, and haven't write his first forth yet :o 2022-12-19 00:56:23 my current first todo is understand jonesforth (with a fasmg port), and port it to a bare mental board (arm or risc-v). 2022-12-19 00:59:19 Welcome; hope you have fun getting to know this stuff. 2022-12-19 00:59:53 welcome to the fray. 2022-12-19 00:59:56 yeah, thank you :) 2022-12-19 01:00:33 Forth has a way of "sucking you in." 2022-12-19 01:00:38 You have been warned. :-) 2022-12-19 01:04:48 at least playing forth is more profits than games, lol 2022-12-19 01:06:47 I do think just toying with the ideas is good "mental training." 2022-12-19 01:07:39 days ago, i dreamed a voice programming forth envirmont for show, you bring some outdoor equiptments (led, music synths), and stand there shout out words: "LET THERE BE LIGHT" lol 2022-12-19 01:08:35 other programming languages will be more hard to parsed by voice i think 2022-12-19 01:11:41 I'm going to need to think about this immediate+cross compile issue. Cross compiling is something I want to be able to do cleanly. 2022-12-19 01:13:25 Just to take IF ... THEN as an example, you'd think that maybe what you'd want would be for IF and THEN to just specify some target-specific actions, to be done at compile time. They'd always be the same *functional* actions, but the details would depend on the target you were compiling for. 2022-12-19 01:13:47 So they couldn't be hard-compiled words that just ran and always did the same thing. 2022-12-19 01:14:47 the conditional jump that got compiled would need to be the conditional jump for your target, and the size of the offset field might vary from target to target. 2022-12-19 01:15:38 Of course, you could define IF and THEN per-target. 2022-12-19 01:15:52 And then just make sure you found the right ones. 2022-12-19 01:23:34 You know, with the right hardware there would be a way to use the stack to do high speed block moves. Imagine that @+ and !+ use the second element on the stack as their address, and post increment that cell. 2022-12-19 01:23:55 Then A B @+ !+ @+ !+ @+ !+ ... would move a block. 2022-12-19 01:24:06 The @+ would find A in slot 2, would fetch from it and increment it. 2022-12-19 01:24:41 And now since that value is on the stack, B has moved to the second element. !+ stores to B, increments its value, and now we have A+n and B+n on the stack. 2022-12-19 01:25:55 If the top of the return stack could be used as a counter, then MOVE would look something like >R DO @+ !+ LOOP 2022-12-19 01:26:14 With a somewhat non-standard DO ... LOOP. 2022-12-19 01:27:08 In a packed opcode system you might have something more like >r @+ !+ rep 2022-12-19 01:27:28 Where rep just repeats the cell until the counter exhausts and then pops return and moves on. 2022-12-19 01:28:36 That doesn't need actual address REGISTERS (not explicit ones, at least), and it nests. 2022-12-19 10:51:18 So, I have these "stack frame" words in my Forth, that let me use operands further down in the stack. I've defended them as "occasionally necessary." I can't help wondering, though, if that's realy true. Maybe in those situations I just havn't found the best way to do the job yet. Maybe Chuck's right, and the "best" solution to problems just doesn't need tha capability. 2022-12-19 10:52:59 Another useful feature they offer me is that "arbitrary stack cleanup" I get when I close out a frame. That makes my multi-level conditional returns easier to use - I can return back to within a frame without worrying about the different paths leaving different amounts of stuff on the stack. 2022-12-19 10:59:42 I'm trying to do a 5-bit opcode set for a CPLD-based Forth this morning. 2022-12-19 11:06:50 I still like that little internal "loop back stack" I described a day or two ago. Haven't seen any problems with that yet. 2022-12-19 11:08:33 I kind of like 32 bits, which would let a cell hold six 5-bit opcodes. If I do that "rep" looping over a cell I mentioned, the rep would take one slot and that would leave up to five for the fast loop; five is enough to actually do some interesting things. 2022-12-19 11:09:08 would the rep be conditional? 2022-12-19 11:09:15 Counted. 2022-12-19 11:09:29 Down counter on the top of return stack. 2022-12-19 11:09:42 ahh 2022-12-19 11:09:46 interestinc 2022-12-19 11:10:04 I'd have conditional return and loopback, like I do now; one opcode for each and the slot after would specify the condition code. 2022-12-19 11:10:07 might be worth adding a base opcode of R+1 2022-12-19 11:10:16 That gives room for all of my conditional stuff I have now. 2022-12-19 11:10:45 Sorry - don't quite follow that; what do you mean? 2022-12-19 11:12:01 you could use the rep opcode as a general looping mechanism for everything if you had an opcode that added 1 to the top of the rstack 2022-12-19 11:12:31 Oh. Hmmmm. I'll need to mull that over. 2022-12-19 11:12:44 At the moment I've got all of the capability planned in that my Forth does now. 2022-12-19 11:12:49 Plus some things. 2022-12-19 11:13:08 But I'm missing Chuck's +* opcode from the F21. 2022-12-19 11:13:17 That supports software multiplication. 2022-12-19 11:13:35 But I think I've got everything else he had in there. 2022-12-19 11:13:58 Except I'm planning at the moment around that way I described last night of having auto-increment addresses on the stack instead of in registers. 2022-12-19 11:14:14 That drops the need for moving stuff between the stack and the A register. 2022-12-19 11:14:23 So it saves a couple of opcodes 2022-12-19 11:16:15 I'm grimacing a little over not having a barrel shifter, but they really are kind of expensive hardware-wise. 2022-12-19 11:19:31 Everything's not going to fit in 32 opcodes, though. I think I'm going to need a "prefix" opecode that lets me use the next cell to pick up some necessary functions that aren't used very often. 2022-12-19 11:19:42 Like actually reading and setting the stack pointers, for example. 2022-12-19 11:19:50 Can't get by without that. :-) 2022-12-19 11:20:21 And once that step's taken, then there would be plenty of room. 2022-12-19 11:21:09 I'd just have to decide which operations would pay that cost. 2022-12-19 11:21:34 Reading and setting the stack pointers definitely belong in that category. 2022-12-19 11:21:41 We don't do that too often. 2022-12-19 11:22:18 Maybe +* goes there too; we actually don't multiply that often eeither. 2022-12-19 11:23:36 what part will the CPLD do? 2022-12-19 11:24:07 Probably also the opcodes supporting my "exception" mechanism, that lets me jump out from way down deep in a code stack. I've only used that once or twice in my system, but my god it was handy. Simplifed the code for FIND enormously. 2022-12-19 11:24:33 Um, hang on a minute. I closed a bunch of tabs yesterday, but there is one I was considering. 2022-12-19 11:28:39 Lattice MachXO3D. That may be more of an FPGA than a CPLD, but it comes in low-power versions. 2022-12-19 11:28:47 9400 LUTs. 2022-12-19 11:29:13 But that was a very preliminary interest. There are all kinds of options out there. 2022-12-19 11:29:31 I was actually looking at a different one earlier, but couldn't get the design software for it to run on my computer. 2022-12-19 11:29:42 I've got the "Diamond" Lattice software in and running, though. 2022-12-19 11:31:26 I'm quite liking this internal loop-back stack. It completely eliminates the need to use cells to store any jump offsets. 2022-12-19 11:35:35 And also removes the need for those "offset equipped" words to have to have a header bit specifying them as such. 2022-12-19 11:35:45 They become completely standard. 2022-12-19 11:46:05 I did something along these lines quite a few years ago (like 15 or something), and found a rather nice encoding for the opcodes that made managing the hardware resources pretty clean. I no longer have a record of that, though, unfortunately. 2022-12-19 11:52:58 I'd fetch the 32-bit cells, and opcode cells would go into an execution register that I could shift by five bits, to work through the operations. Then either shift twice or also have a 10-bit shift option for the two-slot instructions. 2022-12-19 11:53:24 Which would depend on how much adding the 10-bit option slowed the logic down. 2022-12-19 11:53:52 That's one of those things that might make it run slower, whether the 10-bit shift was being done or not. 2022-12-19 11:54:09 Won't know until I've played with the circuit some. 2022-12-19 11:59:03 When I do this sort of thing, I try to design it so that when flip flop outputs change on clock edges, those signals only have to pass through two layers of LUT logic before they reach the flip flop inputs again. 2022-12-19 12:00:32 Then clock period has to be greater than + 2* + . 2022-12-19 12:01:26 how many bypass “lanes” does that thing have? 2022-12-19 12:01:57 or busses 2022-12-19 12:03:13 Don't know yet. 2022-12-19 12:03:41 Block RAMs in these devices are generally dual ported, and it makes sense to use both ports. 2022-12-19 12:03:56 Usually one for instruction fetching and the other for code execution. 2022-12-19 12:04:20 But of course if you want to you can organize those block RAMs into more than one separate module. 2022-12-19 12:04:30 what I am talking about is part of the routing fabric 2022-12-19 12:04:35 If you wanted something more Harvard like. 2022-12-19 12:04:39 Oh, I don't know yet. 2022-12-19 12:05:10 I'll take a harder look at devices after I've gotten the instruction set and some of the logic settled. 2022-12-19 12:05:17 And an encoding. 2022-12-19 12:13:12 I suspect the things I'm considering here will wind up menaing that the top two stack elements, and the top return stack element, are all registers, rather than being in RAM. 2022-12-19 12:13:43 A decision I need to make is whether to do those stacks "conventionally," in general address space, or to have them be separate dedicated RAMs. 2022-12-19 12:14:12 seperate dedicated RAMs is what I support 2022-12-19 12:14:19 If I make the data stack a separate RAM, that means that my frame access words will have to be special - just being able to put the right address onto the stack won't be enough. 2022-12-19 12:14:26 So that would inflate opcodes. 2022-12-19 12:15:04 with TOS, NOS in registers and the rest in a RAM block you can use the same tricks s excamera J1 2022-12-19 12:15:14 Yes. 2022-12-19 12:15:41 But these post-increment methods I'm considering involve post-incrementing the next-on-stack value, so it probably needs to be in a register. 2022-12-19 12:15:46 pick and co are generally a bad idea 2022-12-19 12:15:53 I know. 2022-12-19 12:16:28 In my past coding experience, I've run across a handful of situations I just couldn't figure out how to handle without having the ability to get at elements a few deeper in the stack than Chuck believes in. 2022-12-19 12:16:41 That's what I was talking about earlier - maybe I just havn't found the "right" solution yet. 2022-12-19 12:16:59 what mind of situations? 2022-12-19 12:17:08 kind* 2022-12-19 12:18:17 Um, one example was in my EXPECT word. At one point in there, values in play are 1) buffer address, 2) buffer max size, 3) buffer current size, 4) cursor position, 5) keystroke data. And once I added support for UTF8 I needed the "current position" both in the buffer and on the screen, so that added one more. 2022-12-19 12:18:37 So that's six things, and doing everything you need to do involves all of them at one time or another. 2022-12-19 12:18:43 That was the most overt example where it helped me. 2022-12-19 12:19:03 I try not to use it - I've only fallen back on it when I just got too frustrated to keep trying. 2022-12-19 12:19:12 But it *massively* reduces "stack juggling." 2022-12-19 12:19:19 Actually almost totally eliminates it. 2022-12-19 12:19:42 Of course, EXPECT is a user-action speed word. 2022-12-19 12:19:49 I could just declare globals for all those things. 2022-12-19 12:19:51 that is way too much of stuff in one word 2022-12-19 12:20:13 I know, but if you're working with editing a string, how do you get rid of those things? 2022-12-19 12:20:25 They're all pertinent to what you're doing. 2022-12-19 12:20:33 Like I said - maybe I just haven't tried hard enough. 2022-12-19 12:20:42 It's the sort of thing Chuck might work on for weeks or months. 2022-12-19 12:21:03 So far I've failed to do better. 2022-12-19 12:21:27 Globals are ugly too. 2022-12-19 12:21:40 So it's sort of a "pick your poison" kind of thing. 2022-12-19 12:22:00 editing a string involves a lot of tasks no? 2022-12-19 12:22:18 Sure - I actually do have it factored pretty heavily. 2022-12-19 12:22:34 But I just haven't found a way that makes me "not need" the stuff that's further down in the stack here and there. 2022-12-19 12:22:49 The definitions are of nice length. 2022-12-19 12:23:05 But maybe there's another factoring that just magically works better. Don't know. 2022-12-19 12:23:30 If I could find a nice clean way to do all this without having to use the frame thing, I'd be DELIGHTED. 2022-12-19 12:23:43 I actually "believe in" the "don't PICK" rule. 2022-12-19 12:24:26 If I could figure a better way to do EXPECT, I'd probably jettison those words, because I think if that problem can be solved, then it's likely that any problem can be solved. 2022-12-19 12:24:36 And having done it once, I'd have a better feel for how to do it generally. 2022-12-19 12:24:48 what is it that EXPECT is supposed to do? and how is it supposed to be used? 2022-12-19 12:24:49 I'd have "learned something," and that would be very satisfying. 2022-12-19 12:25:19 Well, traditionally it reads a capped length string from the keyboard into a buffer. 2022-12-19 12:25:47 It's simpler when you aren't doing utf8, and it woudl be simpler still if you gave up being able to cursor around in the string and change stuff. 2022-12-19 12:25:53 If you could only backspace, for example. 2022-12-19 12:25:59 so read a key and insert it into buffer, that is it? 2022-12-19 12:26:15 Yes, repetitively. 2022-12-19 12:26:31 oh, you are implementing readline basically 2022-12-19 12:26:32 With support for HOME, END, backspace, cursor left, cursor right. 2022-12-19 12:26:37 Right. 2022-12-19 12:26:49 And I have a related word EDIT that lets me jump into an existing string and modify it. 2022-12-19 12:27:01 In that case I also can specify the starting cursor position. 2022-12-19 12:27:08 no wonder it has so much on stack 2022-12-19 12:27:11 The idea is that that EDIT word is the backbone of a block editor. 2022-12-19 12:27:38 Right. All that info is needed - it's just a matter of whether we can factor in a way that doesn't need it in an "all mixed up way." 2022-12-19 12:28:05 I don't think I've been STUPID about it - it's a tough goal. 2022-12-19 12:28:22 I just don't know if I REALLY "can't" solve it, vs. just haven't solved it yet. 2022-12-19 12:28:52 so, you have a loop in there that does ?key and switch on the special control codes, no? 2022-12-19 12:29:02 Essentially, yeah. 2022-12-19 12:29:40 Exits on enter, handles the cursor and backspace keys, etc. 2022-12-19 12:29:52 utf8 characters come in packed in the result of KEY. 2022-12-19 12:30:17 So if the top 7 bytes are non-zero, it's utf8. 2022-12-19 12:30:33 so you really just need four items on stack 2022-12-19 12:30:41 List them? 2022-12-19 12:31:42 buffer_addr, buffer_max, buffer_cursor, cursorpos 2022-12-19 12:32:10 We have to have 1) buffer address, 2) buffer size, 3) current length, 4) cursor pos on screen, 5) cursor pos in buffer. And somewhere in there we need the keystroke data. 2022-12-19 12:32:16 What of that can we dismiss? 2022-12-19 12:32:18 and expect returns what on the stack? 2022-12-19 12:33:09 swap 4 and 5 2022-12-19 12:33:40 Traditionally nothing. But in mine the buffer address, max size, and cursor position (only one of them) remain, so that I can save that info, or re-edit, or whatever. 2022-12-19 12:33:56 It figures out the other cursor position and the current length at the start. 2022-12-19 12:33:57 those first four are about the buffer then 2022-12-19 12:34:16 Well, yeah - the buffer and where you are in it. 2022-12-19 12:34:46 cursor position on screen should live in a global 2022-12-19 12:34:50 Remember I might exit on a vertical cursor motion key, and then I'd be jumping into an edit of the line right above or below. 2022-12-19 12:35:07 Or I might be moving through a command history. 2022-12-19 12:35:36 you are trying to do too much with expect 2022-12-19 12:35:44 But look, even at the outset you have a problem. Your buffer address is the deepest one, and you certainly need it almost right away. 2022-12-19 12:36:07 are you doing readline style edit or emacs buffer style edit? 2022-12-19 12:36:23 Not sure how you distinguish those. 2022-12-19 12:36:39 I've diddled my termios so that I process every keystroke. 2022-12-19 12:37:21 you are trying to solve two things with one word 2022-12-19 12:37:31 Possibly. 2022-12-19 12:37:55 Do you mean I shouldn't have KEY inside EXPECT at all? 2022-12-19 12:38:13 That's certainly an alternative I could look at. 2022-12-19 12:38:58 And if I go down this SDL road we were discussing last night, that might work better, because keystrokes will come from the main event loop. 2022-12-19 12:39:07 I won't "call a word" and have it getting keys. 2022-12-19 12:39:14 I'll get keys and pass them into words. 2022-12-19 12:39:16 no, you should have two diffrent words for the two diffrent things 2022-12-19 12:39:26 Which two things? 2022-12-19 12:40:02 the readline vs the text buffer editor 2022-12-19 12:40:29 How is re-editing a line that different from the inital acquisition (and editing) of the line? 2022-12-19 12:40:45 I want to be able to edit WITHIN the line even while I'm first entering it. 2022-12-19 12:41:34 But now you've got me thinking about the other thing I just mentioned. 2022-12-19 12:41:51 Getting keystrokes is part of how the SYSTEM works. What I do with those keystrokes depends on what's going on. 2022-12-19 12:41:53 I am talking about readline as in the functionality of https://man7.org/linux/man-pages/man3/readline.3.html 2022-12-19 12:42:06 So I'm thinking that the traditional operation of EXPECT may not be the way to go at all. 2022-12-19 12:42:26 Lemme look at that. 2022-12-19 12:43:01 Ok, but I don't want the standard readline behavior. That's why I adjust the termios. 2022-12-19 12:43:14 I want a shot at every keystroke. 2022-12-19 12:43:32 I don't want what out of the box readln decides to do with some of them. 2022-12-19 12:43:32 used for the line editing of commands and such. The cooked mode in termino is using that 2022-12-19 12:43:59 Right. Among other naughty things it does, it gives you a newline before it returns the string to you. 2022-12-19 12:44:11 Which makes it impossible to print "ok" out there after you've processed that line. 2022-12-19 12:44:11 you misunderstood me. You are trying to implement two diffrent functionalities with one word 2022-12-19 12:44:26 Well, I understood that. But exactly which two functionalities? 2022-12-19 12:44:41 one functionality is the readline functionality 2022-12-19 12:44:57 Which you need everytime you are typing in a buffer. 2022-12-19 12:45:00 And? 2022-12-19 12:45:06 the other functionality is a emacs like buffer editor 2022-12-19 12:45:35 with screen coords and who knows what 2022-12-19 12:45:38 Ok, but the point I'm trying to make is that I want the keys to do all the same things while I'm first getting the line as when I edit it later. 2022-12-19 12:45:43 those are more or less the same thing. 2022-12-19 12:45:50 I see no profit in replicating all that code. 2022-12-19 12:46:06 they ARE NOT the same! 2022-12-19 12:46:17 Ok, let's say I type 1 2 3 . . . 2022-12-19 12:46:24 and get my 3 2 1 ok output. 2022-12-19 12:46:45 Now let's say I type 1 2 and then realize, oh wait, I just did that command - cursor up enter to repeat it. 2022-12-19 12:46:53 Bash style command history. 2022-12-19 12:46:54 okay that is part of the QUIT loop 2022-12-19 12:47:46 So my readln has to be able to exit back out, then, and say QUITE loop handles moving me to another line of history. I should then be able to cursor back down and find the partial line I was entering in readln that last time. 2022-12-19 12:47:59 bash history is a LIST of str_addr str_length pairs, no? 2022-12-19 12:48:31 See, now we're getting back to handling keystrokes outside of these buffer operations, which is what you got me thinking about a few minutes ago. 2022-12-19 12:48:56 That may be the answer - not have the traditional Forth EXPECT structure at all, but rather get keystrokes in the main event loop, decide what to do with them, and then do that. 2022-12-19 12:49:15 In that case if the key needs to go into the middle of some string, I call a word that does that and that only. 2022-12-19 12:49:15 which bash implements by replacing the contents of your current buffer after it has stashed the prior contents somewhere else 2022-12-19 12:49:21 And then comes back out for more events. 2022-12-19 12:49:32 Sure, right. 2022-12-19 12:50:14 See, moving keystroke acquisition out to the outermost loop in the system - that is a new idea that I haven't previously considered. 2022-12-19 12:50:28 But I've tramped all over the territory where KEY is inside the EXPECT loop. 2022-12-19 12:51:18 And a command history, or the lines of a file/block I'm editing, that's exactly the kind of thing that I'll expect to have in global memory somehow, in some data structure. 2022-12-19 12:51:34 That seems like a proper use of RAM variables. 2022-12-19 12:51:56 the flipping through history is handled by the switch case or such that you use to handle the arrow key control codes, backspace, home, end, etc and the default case is to insert the character into the buffer 2022-12-19 12:51:58 I don't think I've followed you exactly where you wanted to go, but you've nonetheless helped me. 2022-12-19 12:52:19 Right - which becomes much cleaner if I move KEY out of the EXPECT loop. 2022-12-19 12:53:18 have slightly diffrent EXPECT words for diffrent kind of tasks 2022-12-19 12:53:47 I think I may wind up getting rid of EXPECT altogether. 2022-12-19 12:53:48 they can share refactored words 2022-12-19 12:54:27 I'll have a word that inserts a character in a string. A word that removes one. A word that adjusts "position within that particular string." Etc. 2022-12-19 12:54:37 All of which I call based on user interface events. 2022-12-19 12:54:55 I mean, I haven't really thought through that path yet. 2022-12-19 12:55:13 But it seems at least reasonable that it might turn out a lot cleaner, and it certainly fits into an SDL-based architecture better. 2022-12-19 12:56:09 It's something to try, at least. 2022-12-19 12:56:32 With the current setup, let's say instead of hitting a key I do something with the mouse instead? 2022-12-19 12:56:38 Well, that's just not possible currently. 2022-12-19 12:56:44 EXPECT doesn't check for mouse events. 2022-12-19 12:56:54 It waits for keystrokes, and that's the only thing it does. 2022-12-19 12:58:01 Of course, I could add that. But then I'm adding checks for stuff all over the frigging place. 2022-12-19 12:58:02 Ugly. 2022-12-19 12:58:50 This is non-traditional territory, though - I have no idea exactly where it will lead. 2022-12-19 12:59:57 maybe look at how games manage input under sdl? 2022-12-19 13:00:16 Traditional Forth has just three things here. It has KEY, which gets a char to the stack, it has EXPECT which gets chars into RAM, and it has QUERY which focuses EXPECT on the text input buffer (a particular place in RAM). 2022-12-19 13:00:28 And that's IT - that's the whole story of how Forth normally interfaces the keyboard. 2022-12-19 13:01:04 Yeah, I've already seen that to some extent. There's generally an outermost loop in your application, that waits for and handles user interface (and other) events. 2022-12-19 13:01:20 Everything else is "inside" that. 2022-12-19 13:01:45 Like if you click the little X box in your window, that generates a QUIT event. 2022-12-19 13:03:12 See, this change will mean that several of those stack parameters I have in EXPECT will naturally be living in some kind of data structure, which keeps up with what buffer is currently being affected by keystrokes, among other things. 2022-12-19 13:03:22 The stack will no longer be "home base" for several of those values. 2022-12-19 13:03:28 It will lessen the congestion. 2022-12-19 13:03:31 I think. 2022-12-19 13:04:22 Most keystrokes will trigger an "insert this char in this buffer" operation. Other events might cause me to switch buffers, or do other things. 2022-12-19 13:04:36 But it FEELS like it may turn out fairly manageable. 2022-12-19 13:04:50 But it's VERY non-traditional. 2022-12-19 13:09:03 See, it would just stick in my craw really bad to take my current EXPECT and move a bunch of that stuff into globals just to have a lighter stack. 2022-12-19 13:09:18 But if the architeture naturally puts them in RAM, that's an entirely different proposition. 2022-12-19 13:26:16 Hmmm. The word tuck doesn't look particularly easy to implement as a hardware single operation. 2022-12-19 13:27:27 Oh, well, wait - if second on stack is in a register then it's not as bad. 2022-12-19 13:27:41 You just push TOS to the ram part of the stack. 2022-12-19 13:28:02 : tuck ( a b c — a c b c ) swap over ; 2022-12-19 13:28:29 Right; easy to do that way. I was thinking about the hardware motion of doing it as a single instruction. 2022-12-19 13:28:47 If you only have tos registered, then it's a read and two writes. 2022-12-19 13:28:49 why do it in single instruction? 2022-12-19 13:29:08 "If it's easy." I likely wouldn't in a tos register only design. 2022-12-19 13:29:24 But it becomes very simple in a tos + 2os regisgered design. 2022-12-19 13:29:33 Almost becomes a "why not?" sort of thing. 2022-12-19 13:29:38 Except it consumes an opcode. 2022-12-19 13:29:45 but because you have both TOS and NOS in registers, it is easy 2022-12-19 13:29:51 Yes. 2022-12-19 13:30:02 Just a push. 2022-12-19 13:30:32 And nip is just a pop to NOS. 2022-12-19 13:31:06 nos? 2022-12-19 13:32:23 Next on stack. 2022-12-19 13:32:26 ah 2022-12-19 13:32:28 Second stack item. 2022-12-19 13:32:59 I'd already decided earlier, for other reasons, that that one probably also needs to be registered, to do all the things I'm considering. 2022-12-19 13:33:10 Having it facilitate tuck is a bonus. 2022-12-19 13:39:02 I don't base decisions about what to make primitives ONLY on expected frequency of use, though that's a factor, of course. How easily it can be implemented, as a primitive, is also a factor. If something is only an instruction or two in a primitive, then I prone to making it one if I expect to use it AT ALL. 2022-12-19 13:39:02 feels like tos in reg is optimal for one architecurr and nos in reg is optimal for another 2022-12-19 13:39:03 but its evading me 2022-12-19 13:39:03 something about the way RISC has 3 regs for two parameter instructions 2022-12-19 13:39:11 Yes, I think so. 2022-12-19 13:39:45 And perhaps optimal in a custom hardware situation, and perhaps not in a standard processor situation. 2022-12-19 13:40:00 If I were doing it on x86, then that would create the need for more moving of stuff around. 2022-12-19 13:40:08 But in hardware those moves can be done in parallel. 2022-12-19 13:40:29 the thing is that the nos and tos registers can feed directly in various arithetic and logic operations continously 2022-12-19 13:40:36 Right. 2022-12-19 13:40:55 And SWAP becomes really fast too - just clock NOS into TOS and TOS into NOS. 2022-12-19 13:40:58 No ram access. 2022-12-19 13:41:26 when the instruction fetch and decode part see the instruction is an operation of such kind it just need to mux the already calculated answer 2022-12-19 13:41:43 Yes. 2022-12-19 13:42:31 So, you've convinced me now to try to do without the deeper stack access words. That restructuring we talked about just feels like something that will wind up solving the problem. 2022-12-19 13:42:35 if you time it right it would make multiply, and divide look like it only took one instruction worth of time 2022-12-19 13:42:46 That leaves me with the question of whether to keep { and } or not. 2022-12-19 13:43:00 Those are the words that set up and close the stack frames in the first place. 2022-12-19 13:43:09 The reason I might keep them is that they offer a secondary benefit. 2022-12-19 13:43:17 I invented them to facilitate the deep stack access. 2022-12-19 13:43:31 But then later I discovered they offered stack cleanup benefit too. 2022-12-19 13:43:52 { saves the current stack pointer (in the frame register), and } restores it and shifts it by a count taken from the stack. 2022-12-19 13:44:19 The way I use my conditional and double-return words, I often arrive back at the top of a definition set from various places below. 2022-12-19 13:44:40 If I'm inside { ... }, then I don't have to worry about whether those return paths leave variant amounts of stuff on the stack. 2022-12-19 13:44:48 The } "universally cleans things up." 2022-12-19 13:45:13 Without those, I'd have to make sure all of my "paths out" were balanced. 2022-12-19 13:45:49 Some folks might look askance at that, but the way I see it if I'm doing it consciously and with forethought, it's fine. 2022-12-19 13:47:00 I've also got {| and |} which "mark" both stacks, and with |} I can return from arbitrary depth back to the definition containing the {| 2022-12-19 13:47:41 I use that in FIND - when I "succeed" in a name match, I'm way way down at the bottom of a stack of definitions, but... I'm DONE. I want out, and I don't want to have to pass that success all the way back up through the tree. 2022-12-19 13:48:19 The middle layers never even see success - they just loop over a name string, loop over a linked list, or loop through a list of vocabularies. 2022-12-19 13:48:27 Until they "run out." 2022-12-19 13:48:38 In which case the search fails. 2022-12-19 13:48:59 I was DELIGHTED with how tight and compact that whole process wound up being. 2022-12-19 13:49:31 But I don't use {| ... |} very often, so those will be in the prefixed opcode set. 2022-12-19 13:56:19 what you just described escape clauses and ejectors from E 2022-12-19 14:03:55 Oh, cool. Yeah - I never figure I've really "invented" anything. 2022-12-19 14:04:28 But it was just another thing that looked "somewhat useful" and also "really easy to do." 2022-12-19 14:05:27 Here's where the instruction set thoughts are so far: 2022-12-19 14:05:37 One-Byte 2022-12-19 14:05:39 -------------------------------------------------------------- 2022-12-19 14:05:41 and or not xor :. rep { } 2022-12-19 14:05:43 swap drop dup over nip tuck ; ;? 2022-12-19 14:05:45 + - 1+ 1- 1<< 1>> me me? 2022-12-19 14:05:47 >r r> @ ! @+ !+ nop ext 2022-12-19 14:05:49 Extended 2022-12-19 14:05:51 -------------------------------------------------------------- 2022-12-19 14:05:53 {| |} +* +c -b exec lit r@ 2022-12-19 14:05:55 ;; ;;? 8<< 8>> 2022-12-19 14:08:34 Neat! 2022-12-19 14:08:35 variable width instruction sets are a bit annoying to deal with 2022-12-19 14:08:43 I agree. 2022-12-19 14:08:57 But there were too many things left after I filled up the 32 ops. 2022-12-19 14:09:04 KipIngram: ya you can go far on an FPGA but pretty tough to do something like this on a CPLD 2022-12-19 14:09:06 It won't be that bad in custom hardware. 2022-12-19 14:09:42 The chip I'm looking at is actually described as an FPGA, but it comes in a very low power version. I suspect it's actually kind of in a middle ground between the two. 2022-12-19 14:10:00 I haven't delved far enough into it yet to know if it's going to go smoothly. 2022-12-19 14:12:53 eris: What I plan to do here is fetch the packed instruction cells into a register. The lowest order five bits will be the "now" opcode; I'll have the ability to shift it in five bit chunks to move the opcodes through that slot. 2022-12-19 14:13:09 If that s lot happens to be the EXT code, then that will just defer to logic that is watching the second five bits. 2022-12-19 14:13:19 thats cool 2022-12-19 14:13:25 And in those cases I'll have to shift twice or shift 10 bits when moving on. 2022-12-19 14:16:41 I won't be trying to let EXT be the last five bits of a cell and the extended opcode first in the next cell. That just won't be allowed. 2022-12-19 14:17:01 If I only have one slot left and need a two-slot instruction, I'll nop out that last slot. 2022-12-19 14:43:07 sounds like GA144 :P 2022-12-19 14:43:24 youll be able to make an awesome design for this in an FPGA 2022-12-19 14:45:48 re MuP21, I met a guy a few years ago who has some and offered some to me 2022-12-19 14:46:05 dunno what I would do with them though. it seems kind of speciality for TV stuff 2022-12-19 14:48:37 KipIngram: one of the things I like w.r.t designing instruction sets is that a byte can pack a lot of instructions but not a lot of data. "lit" for example can be split into 16 instructions (or 17 depending on treatment) that shift nybbles into whatever storage mechanism you want to use. 2022-12-19 14:49:29 so 1234 reads literally as "shift the number at TOS to the left by 4 bits, 'or' with 0001, shift the number at TOS to the left by 4 bits, 'or' with 0010..." 2022-12-19 14:50:02 or something to that effect. the components of a literal are your commands. 2022-12-19 14:50:23 Yeah, that is a possibility. What I have in mind at the moment is that the lit instruction will cause the cell at IP (the cell following the one the opcode is in) to be pushed to TOS, and IP will be incremented past it. 2022-12-19 14:50:38 So it will pick up a whole 32-bit literal. 2022-12-19 14:50:51 But I've seen designs that do what you described. 2022-12-19 14:53:39 I think the advantage of the literal-as-commands is that if you bop the instructions into the lower regions of the 256 values you have to work with, you can read them pretty easily. 2022-12-19 14:53:57 vs. having to adjust your eyesight every time you see something that looks ahead in the instruction stream. 2022-12-19 14:54:24 plus you can do lookahead. if you're scanning through the program 4 bytes at a time, that's the window for literals, so you can just execute all 4 of those commands at once. 2022-12-19 14:54:38 instead of having an explicit delimiter. 2022-12-19 14:57:32 One things that need about the 32-bit, six packed 5-bit instruction option (vs. the 16-bit, 3-packed) is that you have TWO leftover bits instead of one. 2022-12-19 14:57:46 In the 16-bit design, that one bit tells you whether it's opcodes or a call. 2022-12-19 14:58:00 one leftover bit after the evil bit 2022-12-19 14:58:19 In the 32-bit design, though, you have more options, so you can have 1) opcodes, 2) call, 3) jump (for tail recursion) and 4) . 2022-12-19 14:58:50 Actually not for tail RECURSION; I'll use "me" for that. But tail *optimization*. 2022-12-19 14:59:19 load iteral? 2022-12-19 15:00:02 Maybe, though I already have a lit opcode. Don't really need another way of doing that. 2022-12-19 15:00:13 But yeah, that would be a possibility. 2022-12-19 15:00:56 If it was set up as a 30-bit literal with the range centered on 0, how often would I REALLY need the values that didn't cover? 2022-12-19 15:01:00 Probably hardly ever. 2022-12-19 15:03:46 ahh 2022-12-19 15:03:58 is the other load two 32 bit words then? 2022-12-19 15:04:22 No, the lit opcode loads one 32-bit word. I'm planning it as a 32-bit system at the moment. 2022-12-19 15:04:54 But if you wanted to load a 64-bit word, you could just say lit lit. 2022-12-19 15:05:16 how would that work. 2022-12-19 15:05:26 shifts? 2022-12-19 15:05:55 Well, after the cell with the opcodes in it is fetched, the IP is pointing to the following cell (while the opcodes are being executed). RAM can be being referenced in parallel. 2022-12-19 15:06:02 lit opcode will just push RAM output to TOS. 2022-12-19 15:06:12 And increment IP. 2022-12-19 15:06:22 If another lit opcode comes right after, it would just do it again. 2022-12-19 15:06:37 So you'd have stacked the two 32-bit cells following the opcode cell. 2022-12-19 15:06:49 ah, so your cell sizes are 32 bits in this. 2022-12-19 15:06:56 I was assuming larger sizes. 2022-12-19 15:07:07 If things were all aligned right you could have six lit opcodes in a cell, and the six cells following would be moved to the stack and skipped over. 2022-12-19 15:07:12 Yes. 2022-12-19 15:07:23 should rename lit to ' or `. 2022-12-19 15:07:27 And that will hold six 5-bit opcodes, with two control bits to spare. 2022-12-19 15:07:38 ```` 2022-12-19 15:07:38 ? Why? 2022-12-19 15:07:43 unlambda. :P 2022-12-19 15:07:52 it's a prefix code. 2022-12-19 15:07:55 Heh. Ok, my ignorance is showing. 2022-12-19 15:08:07 https://en.wikipedia.org/wiki/Unlambda 2022-12-19 15:08:15 I think Chuck called it # in the F21. 2022-12-19 15:08:25 I guess for "number." 2022-12-19 15:08:36 makes sense. shorter typing too. 2022-12-19 15:10:06 Yes. 2022-12-19 15:10:22 I may wind up doing so as well - I generally like short symbolic names. 2022-12-19 15:10:52 That aspect of APL appealed to me, and I preferred it over the variants that wrote out longer names. 2022-12-19 15:11:49 I'm always tempted to use & | ~ ^ instead of and or not xor, too. 2022-12-19 15:12:21 % and not mod 2022-12-19 15:16:47 KipIngram: sorry, I meant is the other instruction two 32 bit words since one is the instruction and one if the 32 bit literal 2022-12-19 15:16:56 I guess it would be a 5 bit instruction though and 32 bit literal 2022-12-19 15:17:25 Yes, except that at the moment I have lit as one of the instruction in the extended set, so that one would take 10 bits. 2022-12-19 15:17:39 Though I may shuffle those decisions around along the way. 2022-12-19 15:18:25 11111 opcode will be "ext," for "extended," and will basically say use the next five bits to know what to do. And that will be a different set of operations from the primary opcodes. 2022-12-19 15:18:28 you could have two or the four left overs load a 31 bit literal 2022-12-19 15:18:40 to the high 31 bits then or in the bottom bit if necessary 2022-12-19 15:19:12 so how many unique instructions can be encoded in a 32 bit sequence? 2022-12-19 15:19:47 using this encoding scheme. 2022-12-19 15:19:49 Well, that has six 5-bit slots, with two bits left to tell me how to interpret the 30 bits. 2022-12-19 15:20:15 is each of the slots an instruction? 2022-12-19 15:20:21 Five bits gives me 32 possibilities, but one is used for the "extension prefix." So all told I'd be able to have 31 primary and 32 extended instructions. 2022-12-19 15:20:36 I don't expect to use all the extended options, though. 2022-12-19 15:20:47 that's a pretty low density encoding. 2022-12-19 15:20:54 Yes, unless it's extended, in which case the instruction is in two slots. 2022-12-19 15:21:17 Well, certainly if you break it into slots like this you reduce the number of possibilities. 2022-12-19 15:21:40 is the slot thing for instruction fetch simplicity 2022-12-19 15:22:23 because 63 instructions in 32 bits seems like a bad tradeoff. 2022-12-19 15:22:31 Well, it's oriented toward simplicity to some degree yes - if I'm understanding you right using the whole 30 bits would give me a billion possible instructions, and I could have the instructions be much more complex. 2022-12-19 15:22:40 That's just more complexity that I want to get into. 2022-12-19 15:22:49 it's moreso the encoding can be simpler and more compact. 2022-12-19 15:23:08 you're preallocating space when the encoding itself could be more clever. 2022-12-19 15:23:23 Or rather the decoding. Yes, certainly if I did 30-bit instructions then I could use one hot and other things to simplify the logic required to know what to do. 2022-12-19 15:23:34 So doing it this way is to increase code density. 2022-12-19 15:23:50 or single byte instructions with a cell-sized window for instruction fetches. 2022-12-19 15:23:52 Fetching cells from memory will be slow compared to executing instructions in registers / on the stack. 2022-12-19 15:24:02 So this way I get multiple instructions to execute for each fetch. 2022-12-19 15:24:32 The RAM could be more or less 6x sl ower than the internal logic and still keep up. 2022-12-19 15:24:36 right, but if I had single-byte instructions, I get 4 instructions for each fetch and a larger space for the instructions. 2022-12-19 15:24:48 Yes, that's true. 2022-12-19 15:24:55 Definitely an alternative. 2022-12-19 15:25:04 it's also more amenable to less decode logic. 2022-12-19 15:25:13 because you don't have to detect prefix bits. 2022-12-19 15:25:25 I could also do five 6-bit instructions, then I wouldn't need that prefix scheme to have enough opcodes. 2022-12-19 15:25:34 you could do a majority of it in 8-to-N ROM. 2022-12-19 15:25:38 But there is value in more instructions. 2022-12-19 15:26:06 I'm including a "rep" instruction that will keep a counter in the top of return stack register and count it down - until it's zero it will just repeat the opcodes in that one cell. 2022-12-19 15:26:13 Sort of a "microloop." 2022-12-19 15:26:34 The rep will take one of the six slots, but this option lets me have five-instruction-long microloops. 2022-12-19 15:27:02 It'll just repetitively fire those opcodes over and over, until the count is exhausted. 2022-12-19 15:27:37 I can do more with five working instructions in such loops than I could with four (or three once you lose one to rep). 2022-12-19 15:27:54 Also, one reason I'm going this way is because it's got a track record. 2022-12-19 15:27:54 I like the idea of a microloop. 2022-12-19 15:27:57 that is really nice. 2022-12-19 15:28:10 Chuck did one that packed three 5-bit opcodes into a 16-bit cell. 2022-12-19 15:28:20 yeah but he was working with custom silicon. 2022-12-19 15:28:26 Yes. 2022-12-19 15:29:03 I sure think that would be fun. Maybe if I'm flush enough in retirment I'll spring for a MOSIS run and try that out. 2022-12-19 15:29:11 But... that's a good bit of $$$. 2022-12-19 15:29:20 `rep` as a fixed instruction length while loop is actually an interesting brain teaser. 2022-12-19 15:29:29 can you chain loops. 2022-12-19 15:29:46 and what's the minimum loop length to be TC. 2022-12-19 15:29:49 Yeah - it wouldn't HAVE to be a five instruction loop - nothing says the rep has to be the last slot. 2022-12-19 15:30:00 And you could certainly use any remaining slots after the loop expired. 2022-12-19 15:30:07 It will just always start with slot 0. 2022-12-19 15:30:34 that is still neat. 2022-12-19 15:30:39 I never thought of that before. 2022-12-19 15:30:58 I've had that mechanism in mind for a long time, ever since I first played with these ideas with Spartan 6 on my mind. 2022-12-19 15:31:01 Never built it, though. 2022-12-19 15:31:20 That was when I actually sussed out an encoding for the opcodes I quite liked. 2022-12-19 15:31:26 you'd need some kind of loop stack if you were to chain them. 2022-12-19 15:31:47 The microloop will only operate within a cell, and one level deep. 2022-12-19 15:31:54 ` rep ... rep ... rep ...` 2022-12-19 15:32:01 Actually I only intend to have one-deep loops at any one definition level. 2022-12-19 15:32:08 If I need nested loops I will have nested words. 2022-12-19 15:32:16 yeah I'm really curious how this extends to more general nested loops. 2022-12-19 15:32:42 Well, in what you just type, each ... rep would start on a cell boundary. 2022-12-19 15:32:51 It won't back up cells - only slots in a cell. 2022-12-19 15:33:10 "me" and conditional "me" is for longer loops. 2022-12-19 15:33:18 what's that do. 2022-12-19 15:33:45 Ok, so each time I nest into a new word, the starting address of that word's def will be pushed to an internal, invisible to the programmer additional stack. 2022-12-19 15:33:52 The loop-back stack. 2022-12-19 15:33:59 Return will pop the top entry away. 2022-12-19 15:34:13 ayy, just like I said. 2022-12-19 15:34:30 And I have an opcode :. that will overwrite that top entry with the now-current IP. In any case, the top item of the loop-back stack is the target for jumps. 2022-12-19 15:34:51 "me" unconditionally jumps back to there (that is, it just copies that top value into IP). 2022-12-19 15:35:05 :. is used when you don't want to go all the way back to the start of the definition. 2022-12-19 15:35:12 what would a sample loop look like for this. 2022-12-19 15:35:26 me? is a conditional form of that operation and uses the following slot to select the condition. 2022-12-19 15:35:57 : foo ...init... :. ...loop... me? ; 2022-12-19 15:36:18 me? isn't what you'd actually type; that's the compiled structure. 2022-12-19 15:36:20 neat. 2022-12-19 15:36:32 In your source it would be something like 0>=me 2022-12-19 15:36:59 I have a whole fleet of such words in my existing system. 2022-12-19 15:37:11 Same type of principle for conditional returns, which I use extensively. 2022-12-19 15:37:18 And I have conditional double-returns too. 2022-12-19 15:37:56 In fact, those things (conditional "me", conditional ; and conditional ;;) are my only conditional control structures. 2022-12-19 15:38:04 I don't even have IF, WHILE, UNTIL, etc. 2022-12-19 15:38:18 so for the slot system, what happens when you have a bunch of extended opcodes? 2022-12-19 15:38:23 and use rep? 2022-12-19 15:38:34 that shortens your loop length. 2022-12-19 15:38:41 You put them in that cell if they fit, and when they don't you nop the last slot and start a fresh cell. 2022-12-19 15:38:57 ah. 2022-12-19 15:39:01 Yes, for sure. My goal will be to make the two-slot instructions the infrequently used ones. 2022-12-19 15:39:19 I'm sure once in a while I'll encounter that, and it will lower my code density. 2022-12-19 15:39:45 Note, though, that the rep mechanism doesn't use condition codes. 2022-12-19 15:39:54 It just counts down the counter - it'll be counted loops only. 2022-12-19 15:40:16 Primarily moves, I guess. 2022-12-19 15:40:48 Per the stuff I read in the last day or two, Chuck started out his career trying to optimize arithmetic performance. Most computing was scientific computing. 2022-12-19 15:41:09 But later he began to feel that "moving data around" had become more important, so he recommended optimizing for that instead. 2022-12-19 15:41:42 That's when he added address registers that could post-increment. 2022-12-19 15:41:52 counted loops are still incredibly useful, especially when you can have loop bodies that modify the count. 2022-12-19 15:42:17 a pure conditional loop is just something that resets the condition at the end. 2022-12-19 15:42:22 Well, nothing would stop me from doing that except that five operations is my max loop limit in that "rep" mode. 2022-12-19 15:42:25 yeah. 2022-12-19 15:43:05 It's worth the rep opcode to me just to be able to use it for MOVE. 2022-12-19 15:44:08 yeeeeah, memory copies and such become really easy. 2022-12-19 15:45:38 I was thinking that instead of explicit address registers I had to load, I'd use the top items of the stack for those addresses. In some ways that's nice, but it does limit what you can do inside such a loop. 2022-12-19 15:45:52 An alternative would be to use return stack top elements. 2022-12-19 15:46:12 That seems a little untidy to me, and would force more >r r> on me. 2022-12-19 15:46:17 Before and after the loop. 2022-12-19 15:46:29 But it would let me do anything I wanted to on the data stack inside the loop. 2022-12-19 15:47:16 So that's three ways of doing it - explicit addr regs, data stack slots, return stack slots. 2022-12-19 15:47:22 I'll have to ponder on it. 2022-12-19 15:56:18 Oh, hmmm. In the F21 Chuck doesn't appear to have add with carry / subtract with borrow instructions. 2022-12-19 15:56:36 Looks like he has the ability to check the carry flag and implements those manually. 2022-12-19 15:57:02 as like, sequences of instructions? 2022-12-19 15:58:20 Yes. 2022-12-19 15:58:30 the overhead... yeesh. 2022-12-19 15:58:44 I know - he must have just figured he'd rarely need to do it. 2022-12-19 15:59:28 The F21 is one of his strange word size devices. 2022-12-19 15:59:37 20 bits. 2022-12-19 16:00:07 f18 is his most recent design 2022-12-19 16:00:07 18bits 2022-12-19 16:00:10 it had a carry flag 2022-12-19 16:00:26 Yes, F21 has one too. 2022-12-19 16:00:28 it just took time to propagate 2022-12-19 16:00:40 Right - same in the F21. Ripple carry. 2022-12-19 16:00:44 oh, i mean add had carry 2022-12-19 16:01:11 So had to preceed the + instruction with nops as required. 2022-12-19 16:01:18 Depending on how many bits were going to ripple. 2022-12-19 16:01:28 postceed for f18 2022-12-19 16:01:38 Looks like the + instruction really just clocked the appropriate ALU output into the target. 2022-12-19 16:02:57 rarely needed add with carry? damn. I mean I guess if you're not dealing with larger numbers.. 2022-12-19 16:03:20 Well, I have the impression that most of Chuck's work has been aimed at various types of embedded systems. 2022-12-19 16:03:40 Building a "general purpose CPU" isn't his sticht. 2022-12-19 16:04:06 He's kind of fanatic about solving the problem you have ow, and not including "hooks" for future expansion. 2022-12-19 16:04:15 He claims you'll never predict the future right anyway. 2022-12-19 16:04:37 That's why the odd word sizes too - they're as big as they need to be to do whatever he faced at the time. 2022-12-19 16:04:47 so more present-oriented than future-oriented 2022-12-19 16:05:35 kinda difficult when the present is always moving away from you and the future is always moving towards you. 2022-12-19 16:06:24 Yes. I see both sides of the coin. 2022-12-19 16:07:03 But Chuck's feeling would probably be that if a new problem came along there would probably be things he wanted to take OUT of the design too - things that weren't helpful for that problem, and just complicated and bogged down the design. 2022-12-19 16:07:21 He's been more focused on that concept over the years than anyone else I've ever known of. 2022-12-19 16:07:54 he's certainly not wrong w.r.t the need to pare down your design. 2022-12-19 16:08:02 In my own Forth design, though, I've had more of a tendency to regard what I'm doing as building a system that I might do all kinds of different things with. 2022-12-19 16:08:20 but.. yeah. general purpose computing is unfortunately the dominator. 2022-12-19 16:08:34 and as we scale further and further up, we can chuck general purpose processors in everything. 2022-12-19 16:08:41 Hence me deciding to make this particular thought process 32 bits. 2022-12-19 16:09:11 64 would be great, but it would double a lot of the logic and just in general be more resource hungry. 2022-12-19 16:09:37 are you actually building silicon or are you working in the confines of an existing chip family. 2022-12-19 16:10:02 And I like the longer micro-loops the 6 slots give me over 3, and the fact that there are two control bits left over instead of 1. 2022-12-19 16:10:22 Well, for now I'll be choosing some existing chip to focus on. 2022-12-19 16:10:45 And we'll see if I ever actually get anything designed - I haven't so far in my life and this isn't the first time I've thought about things like this. 2022-12-19 16:11:19 I think designing custom silicon would be a blast, and if I did it I'd want to try to do it in a way similar to how Chuck did it - write my own software to do the design. 2022-12-19 16:11:28 well, considering a lot of chips are 64-bit, word fetches cost the same as 32 bits. 2022-12-19 16:11:41 But whether I will ever be willing to give MOSIS $15k-$20k or something is a VERY open question. 2022-12-19 16:11:50 Yes, that's true. 2022-12-19 16:11:52 you can do it for cheaper. 2022-12-19 16:11:52 For sure. 2022-12-19 16:11:55 if you use FPGAs. 2022-12-19 16:12:10 lots of services offer "ship us a design and we'll burn in an FPGA for you". 2022-12-19 16:12:17 And there is really just no such thing as address space limitation in a 64-bit processor. 2022-12-19 16:12:21 Not practically speaking. 2022-12-19 16:12:40 Who knows - it's possible I might promote it to 64 bits. 2022-12-19 16:12:48 If I'm rolling in logic resources. 2022-12-19 16:12:53 you're more than likely to run out of physical address space vs. virtual. :P 2022-12-19 16:12:55 the address space limitation is called Chrome 2022-12-19 16:20:58 ACTION mutters octect 2022-12-19 16:51:13 "ship us a design" - that takes 90% of the fun out of it. 2022-12-19 16:51:24 This is all mostly a hobby for me these days. 2022-12-19 16:52:26 That's why I said a little while ago I might eventually want to write software like that Chuck wrote and design and simulate a chip, whether I ever get to build it or not. 2022-12-19 16:53:08 I've always found that accomplishment - the guy actually began with a bare metal 386 PC and programmed it from scratch - and wound up with working integrated circuits. 2022-12-19 16:53:20 Oh, didn't f inish my sentence. I've always found that quite amazing. 2022-12-19 16:53:39 Borderline superhuman. 2022-12-19 17:12:23 decay: I have more or less no interest in Verilog used in a "behavioral" way, where I just describe what I want to happen and let a synthesizer arrange logic to do it. I want to define the circuit, directly myself. 2022-12-19 17:14:29 KipIngram: so like BLIFF output from logisim evolution. Basically you get netlist and components but have to layout it yourself 2022-12-19 17:15:04 Yeah, though Chuck just laid out the silicon shape and then wrote code to extract the netlist and do the simulation. 2022-12-19 17:16:33 It's not just shockingly complicated sounding; after all, all a transistor on an IC is is a little sandwich of materials. 2022-12-19 17:17:11 And the layer stackup is a given, for a given process - all that's left for you to do is decide what shape to make the things on each layer. 2022-12-19 20:08:47 You know, the Spartan 6 had 6-input LUTs, and that was nice, because you could do a bit of a 4-way mux in one. Four inputs, two selection bits - nice fit. 2022-12-19 20:09:13 Four input LUTs suck by comparison. You can only get a two-way mux in it, and it doesn't even use all of the resources. 2022-12-19 20:09:39 So a 4-1 mux for a 32-bit quantity will take 96 4-input LUTS. 2022-12-19 20:10:16 Of course, this chip I'm looking at has 9400 of them. 2022-12-19 21:33:33 Jesus. 2022-12-19 21:33:43 I'm installing the Xilinx Vivado design suite. 2022-12-19 21:33:50 72 GB of space required. 2022-12-19 21:33:53 That is INSANE. 2022-12-19 21:33:59 BABY GOT BACK 2022-12-19 21:34:18 What the HELL are they doing with all that space? 2022-12-19 21:34:19 ... some gamedevs were complaining about some framework taking 40G of memory recently 2022-12-19 21:34:30 How do you even THINK ABOUT enough stuff to do to take that much space? 2022-12-19 21:35:26 As soon as this is in and working I'm going to order an Artix 7 dev board. 2022-12-19 21:38:58 At least they HAVE a recently maintained Linux version - hats off to them for that.