6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 7:24 pm

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Thu Feb 16, 2017 7:00 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
I stumbled upon a couple of curiosities using BLOCK I/O that had not occurred to me before.

The curiosity started when I was looking at the FIG SCREEN editor.

The first notable concept is that BLOCKS are not the same as SCREENS. Notably, in FIG, BLOCKS don't have a standard size. SCREENs are 1K, but a BLOCK, and their associated BUFFERS, can be 128, 256, 1K, etc.

Next, BLOCKS, which load in to BUFFERS, are not, necessarily, sequential in memory. If you load 1 BLOCK and then 2 BLOCK, there's no guarantee that those 2 BLOCKS will load in to BUFFERS that are next to each other.

This is most obvious in the LIST word, which inevitably calls (LINE) to get each individual line of the screen. Each line offset needs to find which BUFFER the BLOCK is in, and then offset in to them individually to get the actual lines for printing.

Coming from modern systems, the relationship between BLOCKS and SCREENS, notably not being sequential, is not intuitive.

But the most striking area where this raises its head, is during LOAD.

LOAD sets the BLK (from the SCREEN #), and, inevitably calls INTERPRET.

INTERPRET simply takes a memory buffer and interprets it. In itself, it has no awareness of BLOCKS or SCREENS or anything.

But, when you load a SCREEN, a SCREEN will be scattered across several BUFFERS. LOAD simply loads up the first BLOCK of the screen, and calls INTERPRET. INTERPRET simply parses the block of memory it's passed. By default, the FIG BLOCK/BUFFER size is 128. So, how does INTERPRET know to load in the next BLOCK? Especially when the BLOCKS may well not be sequential in memory?

It turns out that INTERPRET doesn't.

There's some chicanery involved.

Within the FIG model there's a word called "X". X is an immediate word, and it's job is to do just that -- advance to the next BLOCK in the SCREEN.

But if you look at the code, it's not actually invoked anywhere. LOAD doesn't know about, INTERPRET doesn't know about it.

The trickery is that the words name is not actually X, but the byte 0. The name of the word is '\0' in C parlance.

And, somehow, at the end of each BUFFER, there's a zero byte that parser finds during INTERPRET to move along to the next BLOCK in the SCREEN.

I haven't yet figured out where/how that zero byte is placed. But that's the magic on how it works.

F83 punts on this issue completely, and made it's BLOCKs the same size as SCREENs, 1K. So it doesn't do anything other than pass the 1K BLOCK to INTERPRET and let fly.

But it's an interesting bit of plumbing about what's going on in the FIG model.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 16, 2017 7:07 pm 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
whartung wrote:
Within the FIG model there's a word called "X". X is an immediate word, and it's job is to do just that -- advance to the next BLOCK in the SCREEN.

But if you look at the code, it's not actually invoked anywhere. LOAD doesn't know about, INTERPRET doesn't know about it.

The trickery is that the words name is not actually X, but the byte 0. The name of the word is '\0' in C parlance.

And, somehow, at the end of each BUFFER, there's a zero byte that parser finds during INTERPRET to move along to the next BLOCK in the SCREEN.

I haven't yet figured out where/how that zero byte is placed. But that's the magic on how it works.

IIRC, it's produced as result of calling WORD on an empty input buffer.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 16, 2017 9:21 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
whartung wrote:
But if you look at the code, it's not actually invoked anywhere.
nyef wrote:
IIRC, it's produced as result of calling WORD on an empty input buffer.
That's right. The terminal buffer and each of the disk buffers has the mystery word appended to it as a terminator. Thus, interpreting the contents of a buffer guarantees that the mystery word will eventually execute --and that's how it's intended to be invoked. (BTW, because the mystery word is unprintable the FIG glossary refers to it as X, and I'll do the same.)

It's an odd approach, but it works. What's odd is how the interpreter doesn't know how large the buffer is, and contains no code to detect reaching the end! It's just a matter of letting loose and allowing things to sort themselves out. X is at the end of the buffer, and it does what needs to be done when the buffer end is reached! Simple.


Slightly OT: did you notice how X contains the sequence R> DROP ? :shock: An unusual bit of flow control, that. It allows an escape from the otherwise inescapable BEGIN ... AGAIN construct in INTERPRET.

( more on that, based on notes penciled in my old FIG-Forth manual: )

QUIT is the outer loop, which includes a call to INTERPRET.
INTERPRET is also a loop -- a BEGIN ... AGAIN, as noted. It includes a call to -FIND which calls WORD, and eventually the PFA of X is returned to the loop. The loop will execute X.
X is a colon definition, so it commences by nesting and concludes by un-nesting. Normally an un-nest returns you to your caller, but among other things X has done an R> DROP, which means the un-nest returns us to the caller's caller, QUIT.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 26, 2018 4:43 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
Dr Jefyll wrote:
whartung wrote:
But if you look at the code, it's not actually invoked anywhere.
nyef wrote:
IIRC, it's produced as result of calling WORD on an empty input buffer.
That's right. The terminal buffer and each of the disk buffers has the mystery word appended to it as a terminator. Thus, interpreting the contents of a buffer guarantees that the mystery word will eventually execute --and that's how it's intended to be invoked. (BTW, because the mystery word is unprintable the FIG glossary refers to it as X, and I'll do the same.)

It's an odd approach, but it works. What's odd is how the interpreter doesn't know how large the buffer is, and contains no code to detect reaching the end! It's just a matter of letting loose and allowing things to sort themselves out. X is at the end of the buffer, and it does what needs to be done when the buffer end is reached! Simple.


Slightly OT: did you notice how X contains the sequence R> DROP ? :shock: An unusual bit of flow control, that. It allows an escape from the otherwise inescapable BEGIN ... AGAIN construct in INTERPRET.

( more on that, based on notes penciled in my old FIG-Forth manual: )

QUIT is the outer loop, which includes a call to INTERPRET.
INTERPRET is also a loop -- a BEGIN ... AGAIN, as noted. It includes a call to -FIND which calls WORD, and eventually the PFA of X is returned to the loop. The loop will execute X.
X is a colon definition, so it commences by nesting and concludes by un-nesting. Normally an un-nest returns you to your caller, but among other things X has done an R> DROP, which means the un-nest returns us to the caller's caller, QUIT.

The Forth I wrote for the Commodore 64 uses a similar technique. It mostly conforms to the Forth-83 standard. The only multitasking support is for background tasks and not multiple users, so some of the variables the standard specifies as user variables are regular variables.
Nothing is appended to the blocks or the text buffer. On my system, when word returns text it returns the count and any characters with a blank appended to the end so an empty buffer returns a count and a space character. This nameless character is found in the Forth vocabulary as a code definition with no body. It's code field points to the body of EXIT.
Sorry about replying so late. There are so many interesting threads for me to still go through!

Cheers,
Jim


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 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: