7.6.1.1790 LOAD BLOCK

( i * x u -- j * x )

Save the current input-source specification. Store u in BLK (thus making block u the input source and setting the input buffer to encompass its contents), set >IN to zero, and interpret. When the parse area is exhausted, restore the prior input source specification. Other stack effects are due to the words LOADed.

An ambiguous condition exists if u is zero or is not a valid block number.

See:

ContributeContributions

mcondronavatar of mcondron [106] Getting the block contentsRequest for clarification2019-08-10 00:37:10

This word is surely intended to actually transfer the contents of the specified block from the mass storage device to a buffer, but this behavior is not described. From reading the description, it gives the impression that LOAD is meant to be run after a block has been transferred from mass storage. Is that the case? It's not what I get from reading historical documents on this -- it seems LOAD is meant to initiate a transfer of data.

Maybe what's intended is something like: "Save the current input source specification. Read block u from mass storage in the manner described in BLOCK. Make the block buffer where block u was saved be the input source. Set >IN to zero and interpret, then restore the prior input source specification."

mcondronavatar of mcondron

I found the answer to what I needed to know in Appendix C of Forth Programmer's Handbook.

AntonErtlavatar of AntonErtl

Could you give a summary of the answer you found?

My take on your question is that block u might already be in a buffer before the LOAD. In that case, LOAD does not transfer the block from mass storage, only interpret what is already in the buffer. However, if the block is not in a buffer already, LOAD loads it into a buffer first.

mcondronavatar of mcondron

Sure...on page 249 of "Forth Programmer's Handbook" (Conklin and Rather) it says basically that LOAD causes interpretation from the current input source to be suspended and then input comes from the specified block until it's reached the end. Nowhere does it mention affecting any block buffer. Seems like LIST should work the same way with respect to block buffers.

mcondronavatar of mcondron

But now I'm not so sure I've got this right, or that I'm reading that Appendix C correctly. From the description of LOAD here, it really seems to implicitly assume that the data from the "mass storage device" (for me it's an I2C EEPROM actually) is transferred to a block buffer. That does make life easier. I think it should be clarified with an explicit description of whether the block buffers are affected, because it can potentially invalidate previously generated pointers to block buffers. Granted, it's kind of a far-out scenario, but if LOAD or LIST potentially overwrite block buffers, then addresses that may have been obtained before from BLOCK may no longer point to the right data.

AntonErtlavatar of AntonErtl

Yes, given section 7.2, it is clear that LOAD loads into a block buffer. This can invalidate the address returned by an earlier BLOCK or BUFFER, but that is not mentioned for LOAD (nor LIST nor THRU) in 7.3.2. It should.

HowerdOakfordavatar of HowerdOakford

The committee considered this and decided to write a proposal along the lines of : add the comment "XXXX may call BLOCK or BUFFER and so may invalidate a currently used BUFFER", for "XXXX" = LOAD, THRU and LIST, to each of their respective definitions.

Reply New Version

JimPetersonavatar of JimPeterson [280] Possible Test CaseSuggested Testcase2023-02-11 16:39:10

Maybe this?:

\ \ \ \ WARNING!  This could corrupt your "mass storage" accessible through BLOCK:
: GL1 
  1 BLOCK 1024 BLANK
  S" 1 2 3" 1 BLOCK SWAP CMOVE
  UPDATE
;

: GL2  1 LOAD + ;

T{ GL1    ->       }T ( TEST LOAD IN INTERP. STATE )
T{ 1 LOAD -> 1 2 3 }T

T{ GL2    -> 1 5   }T ( TEST LOAD IN EXECUTE STATE )
Reply New Version