00:00:00 --- log: started forth/18.10.26 00:11:18 --- quit: pierpal (Read error: Connection reset by peer) 00:14:25 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 00:16:01 --- quit: pierpal (Client Quit) 00:16:32 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 00:35:54 --- join: xek (~xek@apn-37-248-138-81.dynamic.gprs.plus.pl) joined #forth 00:39:35 --- quit: pierpal (Ping timeout: 245 seconds) 02:30:57 --- quit: wa5qjh (Ping timeout: 246 seconds) 02:37:48 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 02:39:59 --- quit: pierpal (Read error: Connection reset by peer) 02:40:11 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 02:42:36 --- quit: pierpal (Read error: Connection reset by peer) 03:14:57 --- quit: dave0 (Quit: dave's not here) 03:18:00 --- join: dave0 (~dave@90.20.215.218.dyn.iprimus.net.au) joined #forth 03:20:06 re 04:38:28 --- quit: Zarutian (Read error: Connection reset by peer) 04:38:53 --- join: Zarutian (~zarutian@173-133-17-89.fiber.hringdu.is) joined #forth 04:55:46 Hey Dave. Re. 04:56:01 Oh, shoot - I got de-nicked. 04:56:24 --- nick: Guest89117 -> KipIngram 04:56:33 --- mode: ChanServ set +v KipIngram 04:57:02 There. 04:57:03 hi KipIngram 04:57:36 --- join: ncv (~neceve@unaffiliated/neceve) joined #forth 05:10:16 --- quit: dave0 (Quit: dave's not here) 05:12:11 Figuring out how to draw single pixels 05:12:31 Well it's pretty easy, each byte is mapped bit for bit with the screen 05:12:55 So writing 00010000 to a specific memory location turns a single pixel on 05:13:49 so 4 5 PX-ON draws a pixel at (4,5) 05:14:08 The issue is just trying to squeeze very bit of performance from it. 05:19:37 too bad you cant optimize and calculate the address and bit pattern from 4 5 05:20:09 as compile time constants I mean 05:20:54 siraben: something like? : calc-screen-addr-offset ( x y -- addr offset ) SCREEN_WIDTH @ * + 8 /% SCREEN_ADDR @ + ; : PX-ON ( x y ) calc-screen-addr-offset 1 SWAP << SWAP DUP @ SWAP OR SWAP ! ; 05:21:49 there is an error in there, it is yours to find 05:23:02 Zarutian (IRC): Thanks, I'll get some inspiration from yours. 05:28:35 siraben: I'd think that would be possible (compile-time mapping your pixels). 05:28:48 Of course, only if the address is a constant. 05:29:33 The address is constant 05:30:49 What's your screen dimensions? 05:31:12 * siraben opens up documentation 05:31:59 96 pixels wide and 64 pixels tall 05:32:14 Ok. 96 isn't a power of two, but it's a sum of two powers of two. 05:32:26 768 bytes in total 05:32:27 I'd try to build it around shifts and avoid * and / and mod. 05:32:35 Right, shifts. 05:33:47 5 << dup 2* + gets you a 96 * 05:34:00 But you probably want bytes instead of pixels at that point. 05:34:19 For fun I've set HERE to point at the start of the screen memory location, and visualize the new words I defined. 05:34:25 So 2 << dup 2* + maybe. 05:34:34 Oh, that is fun. :-) 05:34:48 (plus I'm relying on the OS calls to plot) 05:35:55 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 05:37:06 I haven't been doing much modification to my interpreter, it's quite stable at this point, but more substantial changes planned (i.e. floating point) 05:37:55 --- quit: ncv (Remote host closed the connection) 05:39:00 For floating point I only had to modify NUMBER. 05:39:08 --- join: ncv (~neceve@unaffiliated/neceve) joined #forth 05:39:20 I broke with convention a bit, and have NUMBER consult STATE and for interpret/compile decision. 05:39:36 It was just easy to do there, because I had different exit points form NUMBER for ints and floats. 05:39:52 Once you come back out to the interpreter you'd need a flag telling you what the last number was. 05:40:17 I needed that because I put floats on the FPU stack (i.e., not in the same place as ints). 05:42:05 --- quit: pierpal (Ping timeout: 244 seconds) 06:05:51 Right. I have an FPU stack as well. 06:18:53 it's too bad that an 8-pixel wide font where you could just copy in a byte per pixel row would be too huge for that screen 06:22:08 to turn pixels within a byte on, i guess it would be like, fetch, AND with the inverse of the byte with the pixels in it, then OR with the non-inverted byte 06:24:27 and you only need to do that if you want to keep some of the old pixels in that byte of screen memory 06:26:53 Ah, what's here is that I don't worry about the textual output/scrolling of the screen, the OS handles that. I just worry about the specific memory location that I can plot. 06:27:05 There's a word in my Forth called PLOT which displays the memory contents of that region on screen. 06:27:22 But yes, if I were to add a custom font to be displayed, it would be a hassle. 06:32:44 plotting pixels one at a time with pointer arithmetic is going to be slow regardless 06:34:13 if this is for stuff like polygon drawing you could write a routine to draw a span where all but the first and last byte of display memory in the span just get written with 0xFF 06:34:56 and the endcaps are 0xFF shifted right for the left endcap and left for the right endcap 06:35:03 (assuming the memory is laid out how i imagine) 06:35:58 is reading display memory as fast as reading normal memory 06:36:57 I wonder how the calculator manages to do graphical plotting. 06:37:04 It's not by any means fast though. 06:37:09 You can see the line being drawn. 06:37:30 But there's a lot of BASIC commands, PX-ON, PX-OFF, PX-TOGGLE etc. 06:37:31 but for a signle pixel, is it just byte is y*12+(x>>3) and position within the byte is x&3 ? 06:37:45 I believe so 06:38:46 am unclear on whether you don't need help and i should stop rambling :P 06:40:20 I don't currently need help. 06:40:20 But your rambling helps :) 06:41:21 re fonts: there is that LEM1802 4x8 font that you could use 06:45:31 sorry i meant x&7 in 13:37 UTC 06:45:49 Zarutian (IRC): Currently using the built-in one in the calculator. 06:46:02 There's also a small font variation, which I should try, but it's really small 06:46:44 Actually, it doesn't seem like it's really that small, never mind. 06:50:39 the sad thing about a 4-wide font there is that it is probably borderline unreadable without a blank pixel between character cells, and then it doesn't line up nicely on byte boundaries anymore :/ 06:50:50 but that would be true about anything <8 too 06:51:36 otoh there is so little display memory that the routines would have to be *really* slow for it to matter 07:10:10 siraben: This is where a richer suite of "to RAM" operators would be handy. 07:10:31 Not just +! but +! -! &! |! ^! etc. (and, or, xor). 07:10:44 as well as their "c" counterparts, c&! etc. 07:10:45 Ah yes, that makes sense. 07:10:57 Definitely would improve your graphics performance. 07:11:56 I realized / recollected yesterday that my old calculators had a strong suite of such things, that could be applied on either store or recall 07:12:11 And they could access the stack registers, which have names in those calculator environments. 07:12:24 The older calcs had four-element stacks, they were named X Y Z T. 07:12:36 So you could say ST+ Z or RCL* T etc. 07:12:44 I used those A LOT. 07:12:55 My HP-41CV didn't have RCL operations - only ST. 07:13:15 But both the 42S and the WP 34S have both. 07:13:49 One trick I've read about is to manipulate the stack pointer register so that I can use it to quickly clear out chucks of RAM 07:13:59 Of course, restoring it at the end. 07:14:10 You mean point it somewhere and then execute 0 0 0 0 0 ... 07:14:12 ? 07:14:23 But there is FILL in most Forths. 07:14:42 Which in the x86 can usually use a rep prefixed instruction. 07:15:11 http://tutorials.eeems.ca/ASMin28Days/lesson/day10.html#sto 07:15:18 I recall WAY long ago I had a book called "The Cheap Video Cookbook." 07:15:27 I have to disable interrupts before I abuse SP though 07:15:31 It was about how to get pretty powerful video from a nothing bottom-end processor. 07:16:02 Interesting. 07:16:05 oh right because i guess z80 doesn't have string instructions so the stack is your only option for doing load/store and incrementing a pointer in one instruction? 07:16:08 They designed the circuit so that it would execute a whole chain of noop instructions - a special circuit fed the processor noop instructions as it "fetched" from video memory. 07:16:17 So it was basically pumping video data out of the RAM. 07:16:31 Could be - makes sense. 07:16:47 So what you're talking about and that video book were "playing similar tricks." 07:16:58 Causing processor reosurces to be used for non-standard purposes. 07:17:43 have done similar on x86 when sizecoding 07:18:09 (not recently) 07:19:44 koisoke (IRC): The largest hammer I have when it comes to copying memory locations is the LDIR instruction 07:20:26 "Transfers a byte of data from the memory location pointed to by HL to the 07:20:27 memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing." 07:20:44 oh so it does have string instructions (!) 07:20:50 i should know this :P 07:20:55 Basically, HL = source, DE = destination, BC = amount 07:21:01 It doesn't have anything beyond that 07:21:19 There's LDI which is functionally equivalent to LD BC, 1 \ LDIR 07:21:38 i.e. it transfers a since byte from pointers HL to DE and increments both 07:21:46 is there an equivalent for store? 07:21:57 And a couple others, but nothing like the x86 07:21:57 Store? 07:24:23 ah nm misunderstood for a moment 07:24:43 (read: conflating z80 and 6502) 07:26:55 there is ldir and lddr but no ldr? 07:27:50 ok, time to read the real instruction set reference and not random things on personal webpages :| 07:32:31 just wrote an integer conversion routine in asm because i had a vision of a beautiful one in my mind but somehow it is less beautiful in the editor buffer than in my imagination 07:32:37 --- nick: catern_ -> catern 07:34:57 I'm not sure whether interrupts can happen during an x86 rep movs instruction or not. 07:35:35 i sure would hope so but i don't know either 07:36:09 they can but i forget how they get restarted after the interrupt handler completes 07:37:13 --- quit: tabemann (Ping timeout: 252 seconds) 07:43:40 actually not 100% sure i have ever known 07:45:23 unless the return pointer is either before or after the rep instruction depending on its state when interrupted 07:45:35 but that would be a lot of logic to put on the die back in the day 08:09:04 koisoke: and stil is lot of logic to put on the die today. Even though the area cost has shrunk it is still expensive. 08:20:51 i guess it wouldn't be terribly bad if instructions with a rep prefix just don't advance the instruction pointer until after they complete 08:21:07 and then correct behavior seems to fall out of that for cases i can think of now 08:26:36 cleaned up the conversion routine a bit. i like it better now. https://bpaste.net/show/b22553bb816f 08:31:12 Ah, you wrote numeric conversion in assembly. I was expecting Forth. :-) 08:31:38 sorry 08:31:58 No worries. 08:32:05 You don't like outdenting labels? 08:32:32 not local ones usually 08:32:40 I see. Ok - makes sense. 08:32:59 It looks pretty tight. It would take me a while to completely absorb it. 08:33:04 unsigned ins only? 08:33:06 ints 08:33:19 Base 10? 08:33:26 base 2-36 08:33:27 Oh, no - I see you have a radix. 08:33:34 Cool. 08:33:46 I went to 62. 08:34:06 unsigned. signed just needs a wrapper that checks for a leading '-' and negates the result if present 08:34:08 For bases 37 and above letters are case sensitive, but for base 2-36 it's case insensitive. 08:34:16 ! 08:34:17 Right. 08:34:53 Yeah, I can't claim credit for that idea - I made it work 2-62 but figured I'd wind up limiting it to 2-36, because I figured I'd want case insensitivity. 08:35:07 But he suggested having it engage that conditionally - I loved the idea. 08:35:23 I include my radix in the number. 08:35:31 : 08:35:39 i can't imagine wanting to actually use such a thing but it is cool 08:35:41 So it starts out doing a number conversion in base 10. 08:36:02 And if it sees a : it takes what it's got at that point and pushes it into the base and starts over with a zeroed accumulator. 08:36:18 Yeah, I tend to agree. 08:36:31 I *might* decide to tinker around with Sumerian astronomy or something. 08:36:42 wasn't that just base 60? 08:36:50 Yes. 08:36:52 or no or something i..nevermind 08:36:59 It is 60. 08:37:18 Apparently they had certain things more accurate - I suspect it has to do with having more resolution per digit. 08:37:55 it was an entertaining coding exercise - that number converter. 08:38:10 can believe it. 08:38:16 Yours would run circles around mine performance-wise, I imagine. 08:39:11 but it's not typically a performance-critical thing 08:39:21 right now i'm just doing little silly stuff to get unstuck from not feeling like programming 08:40:07 :-) 08:40:14 I need to get back to working on mine. 08:40:20 and then i don't feel like setting up a proper dev environment either, so silly stuff is picked from the set of things with minimal infrastructure needs 08:40:25 Haven't really done anything except correct an error I found for like a month. 08:40:35 Just been pretty up to my eyeballs with work. 08:44:01 happens 08:53:10 The thing I fixed had to do with sp@ and sp! - I realized they weren't compatible. sp@ was returning the actual SP value, which designates the second item on the stack, since I have TOS in a register. 08:53:45 I decided (and verified via GForth) that it made more sense for it to return the location the TOS would reside at if it were in memory. 08:54:24 And once I changed that, I had to change a few other things, like DEPTH, underflow checking, and some stuff involved with my error recovery. 08:55:28 I must have been tired when I wrote those, because I "made them work" with the faulty sp@ without really catching on that something was amiss. 08:55:29 sp! has an implicit drop because the pointer is in the register of course 08:55:44 Yes, sp! didn't need to be changed. 08:56:00 But the way it was the code sequence sp@ sp! would drop / underflow the stack. 08:57:11 seems like they should be symmetric if sp@ returns the value of the stack pointer after the push to add the value to the stack. or that is what you mean? 08:59:07 so, like, if sp@ is push eax; mov eax,esp and sp! is mov esp,eax;pop eax 08:59:33 --- quit: Lord_Nightmare (Quit: ZNC - http://znc.in) 09:02:49 --- join: Lord_Nightmare (Lord_Night@unaffiliated/lordnlptp) joined #forth 09:03:05 Well, SP! obviously pushes whatever value you give it into the stack pointer, but it also has to reload TOS. So it takes the content of that location (the address you gave it), brings it into TOS, and that causes SP to change. 09:03:29 So SP itself doesn't have the value you gave SP! immediately after the operation. 09:03:50 The number you specify as an argument to sp! corresponds to where your "after the operation" TOS would go in RAM if it were in RAM. 09:03:51 should it? 09:03:56 I think so, yes. 09:04:08 You have to put SOMETHING in TOS after you've stored the address. 09:04:17 Think of it like this. 09:04:28 Say I have the numbers 1 2 3 in memory starting at A. 09:04:33 So 1 is at address A. 09:04:36 And I say A SP!. 09:04:45 that seems like it would complicate a lot of things vs "the location of the stack to start using" 09:04:45 That's me saying I want that 1 2 3 to be my stack. 09:04:55 So after I do that, I want 1 in TOS, and SP pointing at 2. 09:05:10 yes 09:05:31 And if I then say SP@, that should be the address the 1 is at. 09:05:40 yes 09:05:59 I.e., it should behave in every way the way it would if I wasn't caching TOS in a register. 09:06:09 but that behavior falls out of the fact that you have to push the register to the stack in memory before putting the sp value in tos 09:06:15 I think that's the right design criterion - it shouldn't "matter" except for performance whether TOS is cached or not. 09:06:23 *push the tos register to the stack in memory 09:06:28 Right - it does fall out. 09:06:40 But before I fixed it I hadn't done it that way - I had this: 09:06:55 MOV W, SP; PUSH TOS; MOV TOS, W. 09:06:57 And that's not right. 09:07:09 It's simpler now - it's just PUSH TOS; MOV TOS, SP. 09:07:17 Capitalizing on what you just said. 09:08:43 hm. what architecture is that? 09:12:02 x86 09:12:14 Those are macros and register aliases, though. 09:12:57 PUSH actually expands to add r11, 8; mov [r11], 09:13:12 ah 09:13:22 or rather add SP, CELL; mov [SP], 09:13:34 And SP is an alias for r11, TOS is an alias for rcx. 09:14:03 I've got 100% of my assembly code expressed using such macros and aliases - the idea is that for a port I'd only have to redefine the macros and aliases. 09:19:32 if performance isn't too important, sure 09:24:13 well x86 is just JIT or interpreted nowdays 09:31:55 I was careful about how I did these - I didn't impair my performance. 09:32:04 It was written in straight assembly first, with performance the objective. 09:32:10 Then I "translated," and didn't give anything up. 09:41:15 the individual code words are fast i'm sure. it's just that your options for writing an optimizer are pretty limited when the code generation is macro concatenation like that 09:41:22 which can be fine of course 09:48:18 (i have never written a code generator to a usable state more complex than a subroutine threader with some really basic optimizations) 10:15:33 Oh, well, I don't know that I'd base a Forth assembler on that. 10:15:46 This was just to make my system itself portable. 10:18:04 I wrote the assembly in the first place as high-performance as I reasonably could - including virtual machine architecture decisions. 10:18:13 Then the macros were designed to let me produce that same code without change. 10:29:07 right 10:29:16 wasn't saying it was bad 10:53:29 I see your point, though - I couldn't use those macros to reproduce *any* sequence of assembly instructions; I couldn't write any possible program in a performance optimal way with them. 10:54:02 So I don't think I could have written the macros FIRST and then expected to get an optimal Forth out of it. 10:54:15 I wrote them with a specific target already in mind. 10:55:28 Actually, I was HOPING to be able to use the same macros for the ARM port and get optimal code there too - in a couple I added macros that were basically just two other macros strung together, because I knew that was something I could do in a single instruction on the Arm. 10:55:46 But I still wound up failing - I hadn't studied the Arm instruction set well enough at the time and I didn't get that result out of it. 10:55:53 I'll have to revisit all that after I know my Arm better. 10:56:12 Specifically, I didn't realize that load and store were the only RAM accessing instructions in Arm. 10:58:23 KipIngram: the subtitle "Load Store architecture" was enought of hint for ya? (RISC is load store arch and Arm stands for Acorn Risc Machines) 10:58:36 I know, I know. 10:59:03 See, I didn't know that's what Arm stood for. 10:59:17 right! that is okay. 10:59:17 --- quit: xek (Read error: Connection reset by peer) 10:59:31 I've paid ARM extremely little attention over the years, beyond just knowing it was out there and was becoming very pervasive. 11:00:29 well, it is power efficient there fore became popular on smartphones 11:01:43 hell, they discovered it was power efficient enough that their first arm chip ran with the vcc pin disconnected. The io pins when high fed enough power to the device via the ESD defense diodes 11:05:14 in studying various ISAs I have found that conceptually splitting up the addressing modes into list of operations that either end in @ or ! and happen before or after the execution of the instruction makes it much easier to understand them. 11:10:09 Oh, that's fun (run with vcc disconnected). So it was being powered by the other chips sending inputs to it. 12:05:56 --- join: dddddd (~dddddd@unaffiliated/dddddd) joined #forth 14:05:35 --- join: dave0 (~dave@90.20.215.218.dyn.iprimus.net.au) joined #forth 14:05:49 hi 14:16:02 Hi Dave. 14:16:30 hi KipIngram 14:16:31 sup? 14:16:42 FRIDAY! 14:16:49 8-D 14:17:00 aha it's saturday morning for me :-p 14:17:19 Heh. I've got more of my weekend left than you do. 14:18:04 Gonna try to do some Forth coding this weekend. 14:18:09 It's been on the shelf long enough. 14:20:05 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 14:22:23 yes it is time to code 14:22:44 --- quit: pierpal (Read error: Connection reset by peer) 14:22:53 I'm still thinking disk words. 14:52:04 --- quit: jedb (Ping timeout: 252 seconds) 14:58:38 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 15:04:50 --- join: jedb (~jedb@199.66.90.113) joined #forth 15:25:30 --- join: [1]MrMobius (~default@c-73-134-82-217.hsd1.va.comcast.net) joined #forth 15:27:49 --- quit: MrMobius (Ping timeout: 240 seconds) 15:27:49 --- nick: [1]MrMobius -> MrMobius 15:53:50 --- join: leaverite (~quassel@110.54.218.186) joined #forth 15:53:50 --- quit: leaverite (Changing host) 15:53:50 --- join: leaverite (~quassel@freebsd/user/wa5qjh) joined #forth 15:53:59 --- quit: wa5qjh (Ping timeout: 246 seconds) 15:56:30 Well I was writing code today 15:56:50 quite efficiently too, and then I realised, gforth doesn't have a "between" word 15:57:33 so I typed `: BETWIXT >R OVER <= SWAP R> <= AND` because the word betwixt is funny 15:57:53 i haven't been able to touch this document because the word betwixt is tickline my funny bone too much 15:58:09 and that's how I wasted an hour of programming time 15:58:19 haha 15:58:30 there is WITHIN 15:58:52 oh it's optional 15:59:05 oh you're joking 16:00:43 man 16:01:11 what a waste of my time! 16:06:40 thanks dave tbh. Now I know `: WITHIN OVER - >R - R> U< ; 16:24:46 --- quit: leaverite (Remote host closed the connection) 16:28:41 --- join: wa5qjh (~quassel@175.158.225.194) joined #forth 16:28:41 --- quit: wa5qjh (Changing host) 16:28:41 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 17:00:24 --- quit: wa5qjh (Remote host closed the connection) 17:01:50 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 17:40:38 WilhelmVonWeiner: What's your stack comment for that word? 17:40:49 ( n a b -- f) or something? 17:41:16 True if n >= a and n < b? 17:42:26 With my primitives I'm more efficient if I don't have a separate word with a flag for that. 17:42:29 I do something like this: 17:43:23 : a .<; b >=; ... code if n within (a,b) ... ; 17:44:01 Actually that should have been .>=; 17:44:27 And the rub there is that if n isn't within (a,b) and one of the returns is taken, n is still on the stack, so the calling code has to know that. 17:59:11 mark4: When you create a new context stack, what gets searched right then? Before you have "defined" that context in any way - you just made the fresh context. 18:17:31 What I think might make the most sense is for the new context created by context: to be a copy of my existing context. 18:18:11 then it could be modified at will, but yet could still specify things I wanted to pass in, like a set of words defined in either DEBUG or SHIP mode. 18:18:40 That also solves the problem that arises if the fresh context is empty. 18:18:49 If the context is empty, how do you find ANYTHING at that point? 18:19:15 I could implement this by allocating a heap page and copying the existing context into it. That would become the current context. 18:19:25 Then previous would pop tha tlist and free the page. 18:25:24 Hello Forthwrights :) 18:25:32 Greetings. 18:27:29 Hi KipIngram 18:29:30 --- quit: wa5qjh (Remote host closed the connection) 18:29:41 Checking in on Forth chat with my morning coffee is my new routine 18:30:51 Yes, I usually take a peek then too. 18:31:05 Just checked the Forth sub-reddit, nothing new for days 18:31:43 This channel is the most active Forth community I'm aware of. 18:31:58 I've been alternating Forth stuff and stuff about Jim Butcher's Dresden Files book series. 18:32:29 yeah, it's great here. It used to be REALLY quiet. 18:32:30 --- join: wa5qjh (~quassel@110.54.223.60) joined #forth 18:32:30 --- quit: wa5qjh (Changing host) 18:32:30 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 18:32:49 clf is active, but most of the discussions are ANS oriented 18:39:31 How about we start a word or the day? 18:39:47 split Distribute the set bits of amongst two cells based on . 18:40:02 : split ( x mask -- x&mask x&~mask ) over and tuck xor ;inline 18:44:00 Anybody have a WOTD to share? 18:46:55 Have to feed the dogs, brb 18:54:19 --- quit: wa5qjh (Remote host closed the connection) 19:00:06 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 19:06:49 --- quit: wa5qjh (Remote host closed the connection) 19:07:10 --- join: wa5qjh (~quassel@110.54.152.229) joined #forth 19:07:10 --- quit: wa5qjh (Changing host) 19:07:10 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 19:23:26 I suppose LOOP is worth a mention, one of the first words I learned and is undoubtedly one of the most flexible. 19:31:47 --- quit: wa5qjh (Remote host closed the connection) 19:33:56 --- join: wa5qjh (~quassel@110.54.193.61) joined #forth 19:33:56 --- quit: wa5qjh (Changing host) 19:33:56 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 19:36:07 --- join: tabemann (~tabemann@2602:30a:c0d3:1890:d004:a860:b5ff:7c1c) joined #forth 19:47:36 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 19:50:32 I've been reading more about interrupts and they seem very powerful 19:51:10 I can disable them to speed up parts of my interpreter, among other things 19:54:01 --- quit: pierpal (Ping timeout: 252 seconds) 19:54:31 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 19:55:24 --- quit: wa5qjh (Remote host closed the connection) 20:03:03 --- quit: pierpal (Ping timeout: 246 seconds) 20:17:42 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 20:19:21 --- quit: Zarutian (Ping timeout: 252 seconds) 20:25:31 --- join: Zarutian (~zarutian@173-133-17-89.fiber.hringdu.is) joined #forth 20:29:04 You should not disable interrupts any longer than absolutely necessary if you're running on top of an OS. 20:29:22 Siraben 20:29:44 Right 20:29:54 I'm figuring out exactly where to use them 20:34:55 Disabling interrupts temporary would be something you do in an interrupt handler, or when you need atomicity, e.g. when the instruction set doesn't provide a cmpxchg instruction. 20:35:05 *temporarily 20:41:43 https://en.wikipedia.org/wiki/Linearizability 20:43:40 https://en.wikipedia.org/wiki/Interrupt 21:05:21 --- quit: dddddd (Remote host closed the connection) 21:11:40 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 21:28:39 hey guys 21:52:28 --- quit: ncv (Remote host closed the connection) 21:55:20 Hi tabemann 21:57:10 I sped up Attoforth quite a bit by taking out the by-default support for stack checks and tracing 21:57:26 it still supports them, but they have to be turned on with a compile-time flag 21:59:50 things had slown down too much when I replaced a key element of compilation (looking up words) from something compiled-in to a word written in Forth 22:02:22 I'm not sure I understood the last sentence 22:04:07 what I meant is that replacing word lookup in the kernel with word lookup written in Forth had had too much of a performance hit, so I felt the need to speed things up some 22:05:03 there is still word lookup in the kernel, for the purposes of bootstrapping, but this will not be used for compiling user programs 22:08:25 I'm still wondering how I can remove the outer interpreter bakes into the kernel, since it is only used for bootstrapping purposes but all primitives have to take it into account design-wise 22:09:40 What are you calling 'the kernel' in your Forth? 22:09:54 the part written in pure C 22:11:21 Ah, I see. You have a virtual machine written in C. 22:14:14 So your Forth is token-threaded? 22:14:24 it's not a virtual machine in the traditional sense, but rather an indirect-threaded Forth written in C rather than assembly 22:14:54 there's no virtual instruction set or anything 22:15:02 Oh 22:19:02 Are you basing it on any existing Forth that follows such a model? I'm not sure I see the pluses of such an approach. 22:20:44 the main plus is portability 22:21:02 because I plan on targeting x86, x86-64, ARM, and ARM64 22:21:36 You would get portability from the VM approach as well. 22:22:47 I don't see the advantage of a portable VM, unless you mean separate VMs each programmed in assembly, where then one sacrifices portability 22:23:13 and I'm not targeting systems which are constrained to the point where a token-threaded approach would be advantageous 22:23:43 (the smallest sort of system I see this running on is the likes of the Raspberry Pi) 22:25:06 The VM can be written in C, just like you're doing with your kernel. 22:26:13 the main disadvantage I see with a VM is the added overhead of instruction decoding 22:26:26 unless you're going to do a JIT 22:26:50 where then why not just code your Forth in assembly, as it's not going to be portable anyways 22:29:04 Let's rewind, I'm getting confused. You have written a "kernel" for your Forth in C for portability reasons. Yes? 22:31:31 yes 22:31:31 --- quit: wa5qjh (Read error: Connection reset by peer) 22:32:24 and partly simply because I don't really know x86, x86-64, ARM, or ARM64 assembly that well 22:32:51 --- join: wa5qjh (~quassel@175.158.225.223) joined #forth 22:32:51 --- quit: wa5qjh (Changing host) 22:32:51 --- join: wa5qjh (~quassel@freebsd/user/wa5qjh) joined #forth 22:32:59 Is this "kernel" an executable file? 22:35:28 there's an executable file that includes both the C component of the Forth system, and a large portion of the Forth system written in Forth but embedded in the executable itself 22:36:30 the latter has to be part of the executable because the core C component of the Forth system is by itself incapable of loading outside Forth source files into memory and executing them 22:38:44 outside the Forth executable there is another source file which provides much of the functionality necessary to have a working and user-friendly Forth environment (specifically it provides Readline-style line editing) 22:39:20 --- quit: pierpal (Quit: Poof) 22:39:40 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 22:43:53 It sounds not too different from the C-based host forth for my umbilical. At least I think... not sure. 22:44:47 --- quit: pierpal (Read error: Connection reset by peer) 22:48:43 okay, I think I've figured out how to break the builtin outer interpreter out of the inner interpreter loop, which should provide a performance boost 22:49:57 My VM is coded in C for POSIX. The VM is an executable that loads a Forth image into it's memory at startup and jumps to a boot address in the image. 22:50:44 I use this only for the host side on POSIX boxes, not for target Forths. 22:52:06 my Forth doesn't load a Forth image but rather compiles itself at startup 22:55:02 hah - my removing the Forth outer interpreter used for bogtstrapping from the inner loop worked on the first try 22:55:15 no crashes or anything 22:55:33 I see, I have a metacompiler for generating a new startup image from scratch if I need one, but usually I just reload the last saved image and work from there. 22:56:08 Cool 22:57:34 the thing is that my threaded code is not very relocatable 22:58:23 it could be relocated, by parsing all the threaded code and adding an offset to all the addresses... but I would have to add separate (LITERAL-NUMERIC) and (LITERAL-ADDRESS) words 22:59:09 and also some things are allocated into memory currently in the heap but referenced via (LITERAL) that would have to be changed to being compiled inline, namely ." and s" strings 23:00:09 it would be doable, but it would be a lot of work 23:02:58 well... actually... the problem is that code can be compiled into any part of the heap, because each thread has its own data space, and because closures can exist anywhere and are by default heap-allocated 23:03:23 Sounds like a complicated system 23:04:10 Gotta go, lunch is ready. Nice chatting with you. 23:04:32 --- quit: rdrop-exit (Quit: Lost terminal) 23:59:59 --- log: ended forth/18.10.26