Jump to content
IGNORED

What if? Designing "Geneve 2020". Cool 3D views!


FarmerPotato

Recommended Posts

Please note that I twice corrected my last post. The figForth vocabulary concept is a bit daunting to decipher—especially, when there are errors in the otherwise very good explanation in Mitch Derrick and Linda Baker’s FORTH Encyclopedia!

 

...lee

  • Like 3
Link to comment
Share on other sites

4 hours ago, Lee Stewart said:

Please note that I twice corrected my last post. The figForth vocabulary concept is a bit daunting to decipher—especially, when there are errors in the otherwise very good explanation in Mitch Derrick and Linda Baker’s FORTH Encyclopedia!

 

...lee

I am with you 100%

I am pretty sure I burned some brain cells that I will never get back trying to understand the ANS Wordlists stuff. 

 

  • Like 2
Link to comment
Share on other sites

5 hours ago, FarmerPotato said:

I'm confused by the dictionary pointers because I learned ANS dialect for VOCABULARY. 

 

I haven't sat down to learn how it used to work. 
 

I saw that FORTI relied on  VOCABULARY.   Between VOICE: and FINIS you have note compiling words A AA B BB ... FF GG , which otherwise would be hex constants.  So I wrote that in ANS once and tested it on ... MeCrisp Forth. 
 

 

I just looked at copy of DPANS94, the doc with the 94 standard and found the search order section.

I had never looked at that before.  I was referencing the Forth Standard 2012 web site. 

 

Yes dictionary pointers of any specific nature are not in the standard because they are "implementation specific".

The standard defines what should happen but not too much about how you would do it. :)

 

Is this the code you studied? 

It has CURRENT and "SET-CONTEXT" so yes the variable CONTEXT is not exposed in the standard anymore.

I might have a doc somewhere that describes the FIG vocabulary system.

I am not a fan anymore because its hard to set any arbitrary search order without peaking behind the curtain, so I implemented ALSO ONLY  PREVIOUS   and ORDER to see the order while programming.

Spoiler
A.16.6.2.0715 ALSO
Here is an implementation of ALSO/ONLY in terms of the primitive search-order word set.

WORDLIST CONSTANT ROOT   ROOT SET-CURRENT

: DO-VOCABULARY  ( -- ) \ Implementation factor
    DOES>  @ >R           (  ) ( R: widnew )
     GET-ORDER  SWAP DROP ( wid1 ... widn-1 n )
     R> SWAP SET-ORDER
;

: DISCARD  ( x1 .. xu u - ) \ Implementation factor
   0 ?DO DROP LOOP          \ DROP u+1 stack items
;

CREATE FORTH  FORTH-WORDLIST , DO-VOCABULARY

: VOCABULARY  ( name -- )  WORDLIST CREATE ,  DO-VOCABULARY ;

: ALSO  ( -- )  GET-ORDER  OVER SWAP 1+ SET-ORDER ;

: PREVIOUS  ( --  )  GET-ORDER  SWAP DROP 1- SET-ORDER ;

: DEFINITIONS  ( -- )  GET-ORDER  OVER SET-CURRENT DISCARD ;

: ONLY ( -- )  ROOT ROOT  2 SET-ORDER ;

\ Forth-83 version; just removes ONLY
: SEAL  ( -- )  GET-ORDER 1- SET-ORDER DROP ;

\ F83 and F-PC version; leaves only CONTEXT
: SEAL  ( -- )  GET-ORDER OVER 1 SET-ORDER DISCARD ;
The preceding definition of ONLY in terms of a ROOT word list follows F83 usage, 
and assumes that the default search order just includes ROOT and FORTH. 
A more portable definition of FORTH and ONLY, without the assumptions, is:

<omit the  ... WORDLIST CONSTANT ROOT ... line>

CREATE FORTH GET-ORDER OVER , DISCARD DO-VOCABULARY

: ONLY  ( -- )  -1 SET-ORDER ;
Here is a simple implementation of GET-ORDER and SET-ORDER, including a corresponding definition of FIND. 
The implementations of WORDLIST, SEARCH-WORDLIST, GET-CURRENT and SET-CURRENT depend on system details 
and are not given here.

16 CONSTANT #VOCS

VARIABLE #ORDER

CREATE CONTEXT  #VOCS CELLS ALLOT

: GET-ORDER  ( -- wid1 .. widn n )
    #ORDER @ 0 ?DO
      #ORDER @  I - 1- CELLS CONTEXT + @
    LOOP
    #ORDER @
;

: SET-ORDER  ( wid1 .. widn n -- )
    DUP -1 = IF
      DROP  <push system default word lists and n>
    THEN
    DUP #ORDER !
    0 ?DO  I CELLS CONTEXT + ! LOOP
;

: FIND  ( c-addr -- c-addr 0 | w 1 | w -1 )
    0                     ( c-addr 0 )
    #ORDER @ 0 ?DO
      OVER COUNT          ( c-addr 0 c-addr' u )
      I CELLS CONTEXT + @ ( c-addr 0 c-addr' u wid)
      SEARCH-WORDLIST     ( c-addr 0; 0 | w 1 | w -1 )
      ?DUP IF             ( c-addr 0; w 1 | w -1 )
        2SWAP 2DROP LEAVE ( w 1 | w -1 )
      THEN                ( c-addr 0 )
    LOOP                  ( c-addr 0 | w 1 | w -1 )
;

 

 

You can compare that to the code I fought with for about a week or two before the penny dropped for me. :)

CAMEL99-ITC/LIB.ITC/WORDLISTS.FTH at master · bfox9900/CAMEL99-ITC · GitHub

 

Happy to answer any questions. 

 

 

  • Like 3
Link to comment
Share on other sites

15 hours ago, FarmerPotato said:

I'm confused by the dictionary pointers because I learned ANS dialect for VOCABULARY. 

 

I haven't sat down to learn how it used to work. 
 

I saw that FORTI relied on  VOCABULARY.   Between VOICE: and FINIS you have note compiling words A AA B BB ... FF GG , which otherwise would be hex constants.  So I wrote that in ANS once and tested it on ... MeCrisp Forth. 

 

I don’t know the structure of ANS vocabulary words, but vocabulary words in TI Forth and fbForth (somewhat different from fig-Forth) have the following structure:

  • Link Field                                          <---points to previous word in dictionary
  • Name Field                                        <---name of this vocabulary
  • Code Field                                          <---pointer to executable part of VOCABULARY
  • Parameter Field                                <---starts with the following fields
    • Vocabulary Link Field         <---points to last-defined word in this vocabulary
    • Pseudo-Name Field              <---needed to satisfy -FIND
      • “name” is a space (ignored by -FIND
      • pointed to by link field of first word defined in this vocabulary
    • Chronological Link Field     <---points to Chronological Link Field of last-defined vocabulary

All vocabulary words (including those in the kernel) must be defined in RAM because the Vocabulary Link Field is changed with every new word defined in any vocabulary.

 

...lee

  • Like 3
Link to comment
Share on other sites

25 minutes ago, Lee Stewart said:

 

I don’t know the structure of ANS vocabulary words, but vocabulary words in TI Forth and fbForth (somewhat different from fig-Forth) have the following structure:

  • Link Field                                          <---points to previous word in dictionary
  • Name Field                                        <---name of this vocabulary
  • Code Field                                          <---pointer to executable part of VOCABULARY
  • Parameter Field                                <---starts with the following fields
    • Vocabulary Link Field         <---points to last-defined word in this vocabulary
    • Pseudo-Name Field              <---needed to satisfy -FIND
      • “name” is a space (ignored by -FIND
      • pointed to by link field of first word defined in this vocabulary
    • Chronological Link Field     <---points to Chronological Link Field of last-defined vocabulary

All vocabulary words (including those in the kernel) must be defined in RAM because the Vocabulary Link Field is changed with every new word defined in any vocabulary.

 

...lee

The nice thing about FIG was it prescribed "how" to make a Forth system. This allowed thousands of people to grasp it and make it.

 

The ANS committee had to walk this crazy line of not offending Forth Inc, or MPE or anybody's "common practice" at that time, while still writing some kind of useful standard.

So they punted on all internal details. It was also a time when native code Forth was becoming the norm for professional systems so everything internal was also in flux. 

 

For better or worse we got a standard. Like most committee generated things it didn't satisfy anybody 100% but fulfilled the lesser goal of being approved by a majority.

I supposed that's the blessing and the curse of democracy. :) 

 

 

 

  • Like 3
Link to comment
Share on other sites

I found some of my mistakes in Forth last night. 
 

First one was ALLOT does an overflow check by comparing DP+Size to the param stack guard.  Oops, I moved the param stack to low mem. So always fails. It tries to print an ERROR which doesn't go so well. 

Second was I redefined some important USER vars. Cleaned that up. 

 

Third was EMPTY-BUFFERS.  $FIRST and $LIMIT didn't point anywhere to screen buffers.  Must have left that detail for later and forgot.  So ERASE tries 0 0 0 FILL which corner case is an infinite loop... file a bug report.  I should look through Lee's list of bugs in TI Forth. 

 There was also a bug in ZBLK where BLK wasn't 0. Which means to LOAD that screen. Went off into RDISK which does nothing good yet. 

 

I thought it was an infinite loop, but it was just ZBLK scanning all the block buffers before RDISK. 
 

With trace on, that scan is  very slow.  Worse, my trace still looks something like this: 

: FIRST DOUSER $FIRST U $U  @ + ;S

@ ;S
LIMIT DOUSER $LIMIT U $U  @ + ;S

@ ;S

U- 0< ;S

 

Before I added : for code field DOCOL, it was gobbledygook. 
 


Finally, I've still got a return stack under flow. COLD executes QUIT (yay!) which clears the return stack 

 

RP0 RP! CR LIT -6 SYSTEM

 

at this point I see R is about to underflow. And it does.  The next IP is 0. Whose code field is the console startup code...



SYSTEM enters  my assembly code. The bug has got to be under my SYSTEM call to my $cr. It causes the underflow. 

 

 

But Trace exercises my assembly routines pretty well: $emit $cr $scrol. All working fine so far. Forth word EMIT goes through SYSTEM just fine.
 

Maybe I rewrite CR as LIT 0D EMIT ... that ought to work.

  • Like 4
Link to comment
Share on other sites

On 9/19/2024 at 4:12 PM, FarmerPotato said:

The bug has got to be under my SYSTEM call to my $cr. It causes the underflow. 

Fixed: return stack balanced. 

Fixed: debug readout, instead of using $TIB as a scratch buffer, was trashing the dictionary TIB. 
 

 

I put a breakpoint on write to START-$TASK0.


 

Next bug: bad stuff happens to VDP RAM after KSCAN. I took care not to disturb any PAD used by GPL. KSCAN preserves GPLWS R11 around its BL @SCAN. Just my WS is at 8300, is that too much?

 

Going to arrange my assembly calls into Tiny Terminal Emulator:
 

 

$tty   equ  $
       bl  @$cls
       bl  @$cinit  serial console 
$tty10 bl  @$qkey   scan for new key
       jne $tty20 
       bl  @$cout   serial out
       bl  @$emit0  local echo
$tty20 bl  @$cin    check serial in
       jne $tty30
       bl  @$emit0  print to screen
$tty30 bl  @$qbrk
       jne $tty10
       jmp $forth


 

Then, test other BIOS routines for: circular character buffer (serial input.. but not interrupt on 4A.)  

 

Test line editor. 
 

Test opening sequence, which worked ok on Build 1 wire wrap:
 

WOULD YOU LIKE TO PLAY A GAME? Y/N

You are standing in an open field west of a white house, with a boarded front door. There is a small mailbox here.  

 

  • Like 4
Link to comment
Share on other sites

On 9/23/2024 at 11:53 AM, FarmerPotato said:

 

 

$tty   equ  $
       bl  @$cls
       bl  @$cinit  serial console 
$tty10 bl  @$qkey   scan for new key
       jne $tty20 
       bl  @$cout   serial out
       bl  @$emit0  local echo
$tty20 bl  @$cin    check serial in
       jne $tty30
       bl  @$emit0  print to screen
$tty30 bl  @$qbrk
       jne $tty10
       jmp $forth

 

If you wrapped this code up as Forth CODE words, they would know how to "Call themselves". ;) 

: ?ECHO     CI IF  BL EMIT0 ENDIF ;

: TTY    
       CLS 
       CINIT            \ serial console 
       BEGIN   
           QKEY         \  scan for new key
       WHILE            \ jne $tty20 
           COUT         \ serial out
           EMIT0        \ local echo
       REPEAT        
      ?ECHO
      ?BRK               \ qbrk
      UNTIL              \ jne $tty10

;                        \ jmp $forth

 

  • Like 2
Link to comment
Share on other sites

2 hours ago, TheBF said:

If you wrapped this code up as Forth CODE words, they would know how to "Call themselves".

I will, but I was debugging the implementations reached by the SYSTEM word, which is called by ?KEY, EMIT, CLS . The system table is easily switchable, one for VDP, one for serial console.  
 

I haven't yet worked out how I will move compiled Forth into the assembler source for the ROM.  

 

What I can do is put the SCREENS in ROM.  It can be LOADed at runtime. I want the assembler words especially. 
 

This is where Chuck's "Blocks are virtual memory" shines.  I've got 256K of Flash ROM to play with. Didn't make any provision for writing to it in-system. The SD card is a better bet. 

 

 

  • Like 2
Link to comment
Share on other sites

2 hours ago, FarmerPotato said:

I will, but I was debugging the implementations reached by the SYSTEM word, which is called by ?KEY, EMIT, CLS . The system table is easily switchable, one for VDP, one for serial console.  

 

 

2 hours ago, FarmerPotato said:

I haven't yet worked out how I will move compiled Forth into the assembler source for the ROM.  

Not sure I understand what you mean here. 

If you mean writing Forth source in Assembler then it's a bunch of data statements.

A macro assembler makes building the word headers easier but you don't need macros to do it. 

 

And if you mean how to ROM a Forth image, then you need to be able to compile Forth at the origin of the ROM and make a boot word that updates RAM stuff, moves DP to RAM and runs ABORT. 

 

Typically one does that with a Forth cross compiler, which is a hell of trick with a Fig Forth system but it can be done.

I would volunteer my cross-compiler, but it would put you on a learning curve that you probably don't want. 

 

It is possible to use SAMS as 64K segment and compile into any origin in that space. 

My DOS cross compiler uses a DOS segment for that purpose. By setting the virtual "ORG" I can make an image that is loadable at any address I need in a 64K space. 

 

 

2 hours ago, FarmerPotato said:

 

What I can do is put the SCREENS in ROM.  It can be LOADed at runtime. I want the assembler words especially. 
This is where Chuck's "Blocks are virtual memory" shines.  I've got 256K of Flash ROM to play with. Didn't make any provision for writing to it in-system. The SD card is a better bet. 

Indeed this is a pretty convenient idea. 

Open firmware stores source code and  compiles on demand, but the source code is tokenized as bytes, so it takes very little space. 

  • Like 1
Link to comment
Share on other sites

13 hours ago, TheBF said:

Indeed this is a pretty convenient idea. 

Open firmware stores source code and  compiles on demand, but the source code is tokenized as bytes, so it takes very little space

I was inspired by Open Firmware (OF) !  I will do power-up configuration with LOAD screens.  I also like the OF device tree.   No need yet for compiled or byte-code.  Anyway, the spirit of this machine is:  the owner can easily modify whatever they like on the boot screens.  

 

Screens come from Flash ROM.  Suppose that some of these compile the DSR routines.   That means:  installing a proper  GPL or MDOS DSR ROM, probably from 9900 Object Code!  And making a device tree.   Out of the box, it must support the SD card slot, the console RS232/2, & anything else.  Later comes expansion cards.  NuBus cards have a "personality" ROM.   

 

 

Like you said, to build a ROM in-system, the origin address is important, so I need to copy ROM to RAM and compile to RAM.  The kernel is now from 0000-21FE so it's got to continue the dictionary in the 2nd page of 8K.  Probably smart to never modify the first page. 

 

Only catch is, the memory-mapper is not ready to use at power-up.  So it can't boot from anywhere but the first 32K of ROM.

 

Better idea: never mind the memory-mapper.  I gotta have user dictionary CURRENT in RAM anyhow, say at >A000.  So customization involves:

 

  1. Compile SCREENs with DSRs and desired vocabulary, to the user dictionary
  2. BSAVE the user dictionary to some screens in Flash ROM.  
  3. In non-volatile RAM (currently 8K) write a boot command like "DECIMAL 64 BLOAD".
  4. Next power-up, BOOT reads FRAM and does the BLOAD of the user dictionary back into RAM at >A000.  

 

 

 

 

Link to comment
Share on other sites

13 hours ago, TheBF said:

It is possible to use SAMS as 64K segment and compile into any origin in that space. 

My DOS cross compiler uses a DOS segment for that purpose. By setting the virtual "ORG" I can make an image that is loadable at any address I need in a 64K space

Aha, that gives me this idea:

Because there are separate maps for Supervisor and User, the User page can be used as a 0-origin segment.

 

So:

  1. Initialize memory mapping
  2. Copy the ROM to some free RAM pages.
  3. Initialize User map with those RAM pages, starting at address 0.
  4. In the User copy, make UVARS CURRENT point to the first free address.
  5. Branch to user code to do the compiling.
  6. Return to supervisor (through a word like SUPER)
  7. BSAVE the RAM to Flash ROM.

 

Not interested in hardening the security!   Do whatever you like, its your computer.  

 

  • Like 1
Link to comment
Share on other sites

13 hours ago, TheBF said:

Didn't make any provision for writing to it in-system

Duh, I thought you had to keep the Chip Enable asserted while you send the programming commands.  Nope,  its just normal write byte cycles.  I just have to be not running any code from it.  

Link to comment
Share on other sites

Example configuration for always booting into GeneveOS:

 

HEX 40 BLOAD   ( get extended user dictionary )
BOOT" SD1.SYSTEM/SYS" ( go get the SYSTEM/SYS file )

 

alternately, perhaps direct to GPL:

HEX 40 BLOAD   ( get extended user dictionary )
GPL" SD1.GPL/ROMS"

 

or just plain old:

3 LOAD
ok

 

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, FarmerPotato said:

I was inspired by Open Firmware (OF) !  I will do power-up configuration with LOAD screens.  I also like the OF device tree.   No need yet for compiled or byte-code.  

Anyway, the spirit of this machine is:  the owner can easily modify whatever they like on the boot screens.  

 

Screens come from Flash ROM.  Suppose that some of these compile the DSR routines.  

That means:  installing a proper  GPL or MDOS DSR ROM, probably from 9900 Object Code!  

 

If you want Forth code to load 9900 object code, you have free access to this stuff. 

CAMEL99-ITC/UTILS/LINKER at master · bfox9900/CAMEL99-ITC · GitHub

 

It's not FIG Forth but it would not be to hard to port over. 

It's not optimized in anyway and uses a big case statement but it's a start.

From what I can tell it's about 5x slower to load an object file than the TI loader. Not great.

  • Like 1
Link to comment
Share on other sites

2 hours ago, TheBF said:

If you want Forth code to load 9900 object code, you have free access to this stuff. 

CAMEL99-ITC/UTILS/LINKER at master · bfox9900/CAMEL99-ITC · GitHub

 

It's not FIG Forth but it would not be to hard to port over. 

It's not optimized in anyway and uses a big case statement but it's a start.

From what I can tell it's about 5x slower to load an object file than the TI loader. Not great.

I know, I requested if you could write it :)  

 

I wonder if the Forth version takes up less space than the E/A loader?  
 

I'll probably drop in the E/A loader--for which we have the source code. 

The ancestor was the sophisticated 990 Link Editor (Colin supplied the manual for it!)  Dunno if that survives. 


In future, I'd like to implement its  (unsupported by E/A) tags PSEG and DSEG. 

 

Also I see TI used to concatenate multiple object files to make a library.  
 

Then the loader would skip the parts that weren't needed by a REF.  I think that implies the DEFs had to be at the beginning.
 

 I noticed this in the disks for Microprocessor Pascal, which is on Dave Pitts' 990 emulator website. 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...