6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 20, 2024 7:29 am

All times are UTC




Post new topic Reply to topic  [ 110 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8  Next
Author Message
 Post subject: Re: screen editor design
PostPosted: Fri Jul 04, 2014 5:26 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1922
Location: Sacramento, CA, USA
The subject is a bit too advanced for me to comment on it's feasibility, but maybe I could just offer the following:

How much effort and time would you need to explore this possibility far enough to form a solid opinion, and are you prepared to throw that effort and time away if it turns into a dead end?

It boils down to a "risk vs. benefit" type situation. I would be tempted to go for it, but your personal situation may be different than mine.

Best wishes either way,

Mike


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Sun Jul 06, 2014 5:07 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
All I'm doing here is reworking INTERPRET, from one of four sources
1) "TIB" terminal input buffer, an 80 character buffer that starts at TIB with SPAN characters in it from the last time the user hit return, and a cursor >IN that counts from 0 to 79
2) "BLOCK" 1024 characters that can be treated like a single continuous line

so far, nothing new.

3) "SCREEN" 1003 character structure that starts with 24 bits of linewrap followed by 1000 characters of Commodore screencodes (where "A" = $01 not $41, etc..) This is a tricky one. The screen is really nothing more than a block, tagged as a screen by a bit of metadata in the packet header. It is to be parsed as a collection of 40/80 column lines per the linewrap bits, with an implied carriage return (whitespace) after each line.
4) "FILE" sequential file of ASCII text, parsed as a continuous stream until EOF. Another tricky one, because tape loads 191 bytes of data at a time (and a 1-byte block type at the start of the tape buffer), so words probably will break in the middle between REFILL operations

Plan is to use SOURCE and REFILL words, consistently do lazy-loading within INTERPRET, and probably vector the SOURCE and REFILL words to handle the different source types.


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Mon Jul 14, 2014 4:11 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
Well. It's working. I can edit, save, load and run screens of code.


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Mon Jul 14, 2014 4:49 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10789
Location: England
Good work!


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Tue Jul 15, 2014 4:12 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
I put together a quick and dirty (emphasis on the latter) Ruby script to analyze the binary for duplicate strings exceeding some minimum length, and squeezed and refactored as much of that out as I could.

Code:
#!/home/chitselb/bin/ruby
# suchen.rb
#
# Analyzes a hexdump of the latest build, searching for duplicate strings
# that might be factorable
#
minimum_size=13


all = File.binread("build/pettil.obj")

i = 0
(all.size-minimum_size).times do
    seek = all[i+=1, minimum_size]
    j = all.index(seek,i+1)
    if !j.nil?
        seek.each_byte {|b| print b.to_s(16).rjust(2,'0')," "}
        print   " ", (i+0x6bfc).to_s(16).rjust(4,'0'), \
                " ", (j+0x6bfc).to_s(16).rjust(4,'0'), "\n"   
    end
end


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Tue Jul 15, 2014 12:25 pm 
Offline

Joined: Tue Jan 07, 2014 8:40 am
Posts: 91
Say, that Ruby script looks handy. I may use it myself. Thanks!

_________________
Because there are never enough Forth implementations: http://www.camelforth.com


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Fri Jul 18, 2014 8:25 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
I'm redoing FORGET (so that it will actually work properly with redefinitions) New blog post has many of the gory details, and commit 8293a0057d6c33f01b5bdd5f50fec4e99576eb19 at http://github.com/chitselb/pettil reflects the almost-there code at the time of this post. I'm going to do it all over again, because 371 total bytes of code (so far) is unacceptable IMHO.

In other news, I turn 52 tomorrow.


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Wed Jul 23, 2014 2:30 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
FORGET works! It reawakens formerly forgotten (but redefined) words, even if they're in the transient dictionary. I'm pretty sure I got it right.

At some point I need to address automated regression testing. What I was thinking is to just throw together a few lines or maybe even a screen of code for each word to give it a workout and check the results vs. what was expected. How do other Forths do this?


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Wed Jul 23, 2014 12:02 pm 
Offline

Joined: Tue Jan 07, 2014 8:40 am
Posts: 91
For ANS Forth I use the automated test suite developed by John Hayes. The basic test engine is here and the set of tests for the ANS core is here. Some tests are specific to ANS Forth, but most are generally applicable.

I gather that there is a more comprehensive ANS test here, but I haven't tried it, and most of the additions seem to be for the extension word sets that you haven't implemented.

_________________
Because there are never enough Forth implementations: http://www.camelforth.com


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Wed Jul 23, 2014 4:52 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
Thanks, that's very useful! In PETTIL, underflowing the stack first poops on the I do-loop index, then the ILIM do-loop limit, and then the User Pointer followed by the NEXT routine (usually with disastrous results). I notice in here that he just pushes zeroes on the stack to bring it back. Conceptually, it looks like it's a matter of comparing expected stack results vs. actuals, and that's a pretty good start.


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Wed Jul 23, 2014 9:50 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
That was easy! Now I just have to write piles and piles of tests, and figure out some way to capture and/or summarize the output so it won't just go scrolling off the screen.

For my next trick, I'm revisiting vocabulary search order. The DPANS document http://lars.nocrew.org/dpans/dpansa16.htm has me a little confused, but the word set itself at http://lars.nocrew.org/dpans/dpans16.htm makes some sense. My scheme is to set the "V" bit and append a Vocabulary ID(tm) byte to names that are in a vocabulary other than FORTH. Vocabulary IDs start with 0x01, which will be the ASSEMBLER vocabulary in PETTIL. As far as search order, I'm a little up in the air and open to (pleading for) suggestions.

Within FIND I'd like there to be some byte array, maybe 10 or 12 bytes, with a list of vocabularies to search through. FIND would process these in left to right order. The last one would always be 0x00 for the core FORTH word set. Maybe there is value in being able to search FORTH before searching vocabularies? Having the zero come last would make it easier for FIND to know that it's done. There would be a parent-child relationship among vocabularies, with FORTH being the root parent of all vocabularies. Here's an imaginary use-case:

VOCABULARY LATIN
LATIN DEFINITIONS
: EPLURIBUSUNUM ;
VOCABULARY PIGLATIN
PIGLATIN DEFINITIONS
: IXNAY ;
FORTH DEFINITIONS
VOCABULARY FRENCH
FRENCH DEFINITIONS
: FROMAGE ;
: OUI ;
IXNAY not found
FROMAGE ok
DUP DROP ok ( forth is accessible from everywhere, because it gets searched last )
PIGLATIN not found
FORTH PIGLATIN not found
LATIN ok
EPLURIBUSUNUM ok
IXNAY not found
PIGLATIN ok
IXNAY ok
EPLURIBUSUNUM ok
FROMAGE not found


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Tue Jun 02, 2015 3:16 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
It has been a while since I visited this thread. The as-of-right-now commit of http://github.com/chitselb/pettil is pretty stable, after spending way too much time rewriting BLOCK and UPDATE and a foray into +LOOP , but those are stable too, as is the editor. Yes, even the editor which has been broken for about a month. Time to revisit <BUILDS ... DOES> ...

There are two separate dictionary spaces, "core" and "transient" with a symbol table "symtab". Once all the editing, assembling, interpreting, compiling (in short, anything that touches the symbol table) are done with, only "core" will remain, currently residing from $0400-$1B1F. Virtual memory (BLOCK / UPDATE / LOAD-BUFFERS / SAVE-BUFFERS) will stick around in "core" and everything above that will become room for application code and data.

Without a symbol table, CREATE is pretty worthless, so it lives in the transient dictionary. I'd like for all the code in between <BUILDS and DOES> to also go up in transient, something like
Code:
USER TDP ( transient dictionary pointer, was initialized at cold start )
: @SWAP!  ( var1 var2 -- )
    2DUP 2>R @ SWAP @ R> !  R> ! ;
: NEW-PARENT-WORD  ( address value == ) ( -- )
 <BUILDS  , ,  DOES> DUP @ SWAP 2+ @ EXECUTE ; ( or something similar )
: DRAW   ( value -- ) ... code to draw something ;
' DRAW 42 NEW-PARENT-WORD CHILD-WORD
"<BUILDS" is immediate and performs a DP TDP @SWAP! to target the transient dictionary.
the " , ,XT " code is then compiled in the transient dictionary
"DOES>" is also immediate, switches the dictionaries again, the rest of the code compiles to core dictionary
the " DUP @ SWAP 2+ @ EXECUTE " runtime behavior of all child words is compiled once in the core dictionary at newparentwordruntime
The top of core would now look something like:
Code:
newparentwordruntime
    .word dup  ( jsr enter is not required or compiled for DOES> blocks. dodoes points IP to here )
    .word fetch
    .word swap
    .word twoplus
    ...etc...
    .word execute
    .word exit  ( exits the child word )

child-word
    jsr dodoes ( CFA )
    .word newparentwordruntime ( PFA+0 )
    .word 42  ( PFA + 2 )
    .word draw  ( PFA + 4)
This means <BUILDS and DOES> would both be immediate, to switch dictionaries when NEW-PARENT-WORD is compiled. This feels messy. I also don't like using PFA+0 to store the address of the child word's runtime behavior, because that is something that probably belongs in the child word CFA.

It would be nice if CREATE ... DOES> also worked, but in a more vanilla way, without the target dictionary swapping. These behave the same, with the difference being where the " , , " is compiled. For 2KONSTA it goes in TDICT, at TDP, and for 2KONSTB it goes in core, at HERE .
Code:
: 2KONSTA <BUILDS , , DOES> 2@ ;
: 2KONSTB CREATE , , DOES> 2@ ;
DOES> would only swap dictionaries when DP @ is greater than TDICT @ (pointer to the base of the transient dictionary, presently $6C00 on a 32K PET). I suppose it would be possible to associate a list of behaviors (like Java's class methods) with a parent/defining word and have each child word's PFA+0 point to the base of that list, with the remainder of the child's PFA behaving like Java's instance fields.

That's where the design is for now, tormenting me in my dreams and waking hours. All feedback (even "what a stupid idea! and here's why...") will be welcome


Top
 Profile  
Reply with quote  
 Post subject: Re: screen editor design
PostPosted: Wed Jun 03, 2015 1:12 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
Today I went through all the PETTIL assembler code and ensured that every secondary and 'JSR word' (it's direct-threaded) would have the CFA pointing directly at the JSR instruction, instead of the NOP or two NOPs that precede it when page alignment is required. I also rewrote ": (CREATE) ( cfa -- ) ;" to do the same. That means if I do CREATE FOO FOO 2- (or 3-) I can change that first instruction or the address at run time, which opens up the possibility of late binding. I'm happy with that.


Top
 Profile  
Reply with quote  
PostPosted: Tue Aug 11, 2015 12:27 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
I don't mean to brag, I don't mean to boast, but I like hot butter on my breakfast toast. Also, I recoded the Ragsdale assembler and got it to fit in 569 (decimal) bytes of code plus 576 bytes of symbol table, total 1145 bytes.

EDIT: oops. ouch. denied. 767 code + 648 symbol after adding BEGIN, UNTIL, IF, THEN, ELSE, AGAIN, WHILE, REPEAT, NOT CS 0= 0< >= VS words


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 21, 2015 7:47 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
A little research shows that the rewrite of Ragsdale's assembler was still a huge win in memory. PETTIL's words: { doasmmode docpu INSTR, DECODE M/CPU } total 128 bytes of code, and are headerless (occupy no symbol table space). In Blazin' Forth's assembler, the words { M/CPU UPMODE CPU } take up 251 bytes, which includes the word names, link fields and code field address, as Blazin' is ITC. A net savings of 123 bytes for rewriting the assembler in 6502 assembler


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 110 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: