6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Sep 21, 2024 8:02 pm

All times are UTC




Post new topic Reply to topic  [ 354 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 24  Next
Author Message
PostPosted: Sat Jul 04, 2020 8:29 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
I found out by way of a typo that my zero overhead data stack underflow protection for the Forth words DROP , 2DROP , (DO) , (?DO) and anything that jumps to POP ( DROP ) or POPTWO ( 2DROP ) didn't quite work out. If a code word pops several items off of an empty stack, the error handling can cause problems because WHERE needs a stable stack to work properly and some of the words in WHERE will clip the stack underflow. I meant to type DOPEN which takes no parameters and returns none. It opens the currently selected drive for BLOCK access. I typed OPEN by mistake and it takes five parameters and returns one. This deep of a stack underflow caused problems ( one of my constants used in WHERE got reset to a different value because ! ( store ) stored to the wrong address ). I decided that if my Forth was going to have any data stack underflow protection, instead of clipping the underflow it should ABORT but I needed the stack to be in a good state for the error handling.
Here is the source for ?STACK , the word that aborts when the stack under or overflows.
Code:
HEX
: ?STACK  ( -- )
   DEPTH 0<
   ABORT" STACK EMPTY!"
   SP@ SPLIM @ U<
   ABORT" STACK FULL!" ;
' ?STACK DO.?STACK !

Depth returns a negative one ( TRUE ) if there was an underflow.
My solution to that problem was to redefine DEPTH . DEPTH is a code word so it doesn't access the data stack until it places a result on it. The new DEPTH reports the number of items on the stack as before, so long as the stack hasn't had an underflow. If there is an underflow, DEPTH clears the stack then places a negative one ( TRUE ) on the stack.
Here is the code:
Code:
HEX
CODE DEPTH  ( NX -- NX N )
   TXA,
   ' SP0 >BODY C@ # LDY,
   CLC,  UP )Y SBC,
   .A ROR,  7F # EOR,
   APUSH 0< NOT BRAN,
   UP )Y LDA,  TAX,
   PUSH.TRUE 0< NOT BRAN,
END-CODE

I realize that this code looks a little strange with clearing the carry before a subtraction with the operands reversed and then toggling all the bits but the high bit after the roll to the right, but I needed to be able to branch on positive to APUSH and still fall through if the number of items on the stack was less than zero.
After rewriting DEPTH , the error handling was easy.
Here is the new code for 2DROP .
Code:
HEX
CODE 2DROP ( N1 N2 -- )
   HERE TIS POPTWO
   INX,  INX,
   HERE TIS POP
   INX,  INX,
   NEXT 0< NOT BRAN,
   LABEL RUNG1
   // WILL BE PATCHED
   0 JSR,           // >FORTH
   LABEL DO.?STACK
   0 ,              // ?STACK
END-CODE

The JSR to zero will be patched when (>FORTH) is defined so it is a JSR to (>FORTH). The zero following is a place holder for ?STACK to be patched in.
Here is the disassembly.
Code:
2DROP
  889         INX
  88A         INX
  88B         INX
  88C         INX
  88D  843 ^^ BPL NEXT
  88F  BED    JSR
  892 1F02 ?STACK
  894 FUTURE EXPANSION
B

SEE had a little trouble with this due to the forward JSR. $0BED is the address of the subroutine at (>FORTH) which causes a transition to high level Forth. Since there is an underflow, ?STACK will abort.
Neither (>FORTH) nor do.colon affect or are affected by the data stack. The new DEPTH doesn't pop anything from the data stack. It doesn't push anything on a data stack that had an underflow before fixing the underflow.

(DO) and (?DO) were modified to branch to the address of (>FORTH) JSR, ( JSR (>FORTH) ) if the branch elsewhere falls through.
Code:
HEX
CODE (DO)  ( N1 N2 -- )
   INY,
   IP )Y LDA,  PHA,  DEY,
   IP )Y LDA,  PHA,  CLC,
   3 ,X LDA,  80 # ADC,  PHA,
   3 ,X STA,  2 ,X LDA,  PHA,  SEC,
   0 ,X LDA,  2 ,X SBC,  TAY,
   1 ,X LDA,  3 ,X SBC,  PHA,
   TYA,  PHA,
   INX,  INX,  INX,  INX,
   IP.INC2 0< NOT BRAN,
   LABEL RUNG2
   RUNG1   0< BRAN,
END-CODE

CODE (?DO)
   0 ,X LDA,  2 ,X CMP,
   ' (DO) @ 0= NOT BRAN,
   1 ,X LDA,  3 ,X CMP,
   ' (DO) @ 0= NOT BRAN,
   INX,  INX,  INX,  INX,
   XBRANCH 2+ 0< NOT BRAN,
   RUNG2      0< BRAN,
END-CODE

If (?DO) causes an underflow, it branches to the address labeled RUNG2 and from there branches to the label RUNG1. If (DO) causes a stack underflow, it branches to the address labeled RUNG1. RUNG1 is the address of the transition to high level and the stack check.
Here is a test run to show that the new DEPTH works as expected.
Code:
 OK
CR DEPTH .S >IN OFF
    0
    0     1
    0     1     2
    0     1     2     3
    0     1     2     3     4
    0     1     2     3     4     5
    0     1     2     3     4     5     6
    0     1     2     3     4     5     6     7
    0     1     2     3     4     5     6     7     8
    0     1     2     3     4     5     6     7     8     9
    0     1     2     3     4     5     6     7     8     9    10
    0     1     2     3     4     5     6     7     8     9    10
   11
    0     1     2     3     4     5     6     7     8     9    10
   11    12
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40    41
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40    41    42
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40    41    42    43
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40    41    42    43
   44
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40    41    42    43
   44    45
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40    41    42    43
   44    45    46
    0     1     2     3     4     5     6     7     8     9    10
   11    12    13    14    15    16    17    18    19    20    21
   22    23    24    25    26    27    28    29    30    31    32
   33    34    35    36    37    38    39    40    41    42    43
   44    45    46    47
CR DEPTH .S >IN OFF
            ^^^
STACK FULL!
CODE TEST  OK
INX, INX, >FORTH DEPTH ;  OK
CODE TEST2  OK
INX, INX, INX, INX, >FORTH DEPTH ;  OK
CODE TEST3  OK
INX, INX, INX, INX, INX, INX,  OK
>FORTH DEPTH ;  OK
TEST  OK
.S 65535  OK
TEST2  OK
.S 65535  OK
SP!  OK
TEST2  OK
.S 65535  OK
SP!  OK
TEST3  OK
.S 65535  OK
CONSOLE


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 04, 2020 8:49 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8510
Location: Southern California
That's an interesting idea to use BPL NEXT as a zero-overhead underflow check! :D Do you really get much need for it though? I just have INTERPRETER check for empty stack, which means the check doesn't happen while compiled code is running, only after it comes back to the command line. There has been little need for anything more. I have a few bytes of unused ZP space for protection under the data stack so an underflow of a cell or two won't overwrite anything I need.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 8:10 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
Since the 6510 does not have the branch always ( BRA ) instruction, 2drop would have ended with a jump to NEXT. Replacing the JMP with a branch to NEXT if positive followed by the JSR and two bytes of high level Forth code only adds four bytes to 2DROP. Nothing is added to DROP since it has no body, just a code field that points two bytes into the body of 2DROP.
The jump at the end of (DO) is replaced with two back to back complementary branches for a cost there of one byte. The jump at the end of (?DO) is replaced with two more back to back complementary branches for a cost of another byte. A total of six bytes extra code and no run time penalty when there is no underflow.
Not all words that remove stack items have the underflow test. Words that move parameters from the stack to the scratchpad area N do not test for underflow ( it would have added to the run time of SETUP ).
Do I need underflow protection for only some primitives? Maybe not. Since the interpreter checks the stack immediately after executing a word, the example with the typo would have been resolved with just the improvement to DEPTH .
I hope others will be interested in Fleet Forth, so is the underflow protection worth keeping for only six extra bytes total? Given that not all primitives which remove items from the data stack are protected, I'm not sure.

The underflow protection seemed like a good idea at the time. Now that I think about it and consider that other people may be using Fleet Forth, It ( the underflow protection ) could encourage bad habits since not all primitives are protected and no primitive has overflow protection.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 8:15 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
To my inexperienced eye, the current cost-to-benefit ratio seems to lean in favor of keeping the protection.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 05, 2020 10:06 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
Thank you.
I was wondering if anyone had an opinion, one way or the other, about the FORGET protection for DEFERred words ( resetting a deferred word's vector to -SET if it's vector will be forgotten. It resulted in a kernel that was fifty two bytes larger and adds two more bytes per deferred word.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 07, 2020 12:23 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
The latest version of the Fleet Forth kernel has a new definition for # .
The original high level version had a body that was thirty three bytes. The next version had a transition to assembly and back to high level Forth. It was four bytes smaller.
Code:
HEX
: #  ( D1 -- D2 )
   BASE @ UD/MOD ROT
   >ASSEM
   0 ,X LDA,  0A # CMP,
   CS IF,
      6 # ADC,
   THEN,
   30 # ADC,  0 ,X STA,
   >FORTH
   HOLD ;

The latest version has a transition to assembly but no transition back to high level Forth.
Code:
HEX
: #  ( D1 -- D2 )
   BASE @ UD/MOD ROT
   >ASSEM
   0 ,X LDA,  0A # CMP,
   CS IF,
      6 # ADC,
   THEN,
   30 # ADC,  0 ,X STA,
   SEC,
   ' HLD >BODY C@ # LDY,
   DEX,  DEX,
   UP )Y LDA,  1 # SBC,  UP )Y STA,
   0 ,X STA,  INY,
   UP )Y LDA,  0 # SBC,  UP )Y STA,
   1 ,X STA,
   2 ,X LDA,  0 X) STA,
   POPTWO JMP,  END-CODE

Although the body of this version is bigger, the overall increase in kernel size is only one byte.


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 08, 2020 8:53 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
Since Fleet Forth is an ITC Forth, here is the source for # , HOLD , and C!
Code:
HEX
: #  ( D1 -- D2 )
   BASE @ UD/MOD ROT
   >ASSEM
   0 ,X LDA,  0A # CMP,
   CS IF,
      6 # ADC,
   THEN,
   30 # ADC,  0 ,X STA,
LABEL HOLD.BODY
   SEC,
   ' HLD >BODY C@ # LDY,
   DEX,  DEX,
   UP )Y LDA,  1 # SBC,  UP )Y STA,
   0 ,X STA,  INY,
   UP )Y LDA,  0 # SBC,  UP )Y STA,
   1 ,X STA,
LABEL C!.BODY
   2 ,X LDA,  0 X) STA,
   POPTWO JMP,  END-CODE
CODE HOLD  ( C -- )
   -2 ALLOT HOLD.BODY , END-CODE
CODE C!   ( C ADR -- )
   -2 ALLOT C!.BODY , END-CODE

HOLD has a code field that points into the body of # and C! also has a code field that points into # ( and HOLD ).
I don't know if there is a name for this technique.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 24, 2020 11:32 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
At one time I had considered making some of the primitives in Fleet Forth headerless. Words like LIT , CLIT , (DO) , (?DO) etc.
This is the story of why I decided against that.
Fleet Forth has, in the system loader, a word, WITH-WORDS , that allows performing actions on each word in the CONTEXT vocabulary. Kind of like ANSForth's TRAVERSE-WORDLIST but different. WITH-WORDS works like this:
Code:
: #WORDS  ( -- U )  \ leave the number of words in the CONTEXT vocabulary on the data stack.
   0                \ perform everything before WITH-WORDS only once.
   WITH-WORDS       \ place name field on data stack
   DROP 1+ ;        \ do everything from WITH-WORDS to first EXIT encountered
                    \ for each word in the CONTEXT vocabulary.

After looking at ANSForth's TRAVERSE-WORDLIST, I was thinking that it might be nice to be able to execute something after WITH-WORDS finishes with the vocabulary so #WORDS would display the total number of words in the CONTEXT vocabulary instead of leaving the result on the stack. I suppose I could write this:
Code:
: #WORDS  ( -- U )  \ leave the number of words in the CONTEXT vocabulary on the data stack.
   0                \ perform everything before WITH-WORDS only once.
   WITH-WORDS       \ place name field on data stack
   DROP 1+ ;        \ do everything from WITH-WORDS to first EXIT encountered
                    \ for each word in the CONTEXT vocabulary.

: #WORDS  ( -- )  \ redefine #WORDS
   #WORDS U. ;

I could even give the first #WORDS a different name like (#WORDS) . After reading M.L.Gassanenko's article, I started kicking around the idea of placing the address of part of a colon definition on the return stack. When WITH-WORDS finishes with the vocabulary and exits, it will exit to the address of the threaded code on the return stack:
Code:
: NOW
   COMPILE LIT  >MARK  COMPILE >R ; IMMEDIATE
: LATER
   COMPILE EXIT  >RESOLVE ; IMMEDIATE

: #WORDS  ( -- )
   NOW 0 WITH-WORDS
   DROP 1+
   LATER U. ;

The word NOW can be anywhere before WITH-WORDS:
Code:
: #WORDS  ( -- )
   0 NOW WITH-WORDS
   DROP 1+
   LATER U. ;

#WORD's body looks like this:
Code:
SEE #WORDS
 598A  BD6 0
 598C  829 LIT 599A
 5990 1215 >R
 5992 42DB WITH-WORDS
 5994  89B DROP
 5996 12A1 1+
 5998  963 EXIT
10
 OK
599A :DIS
 599A 1C92 U.
 599C  963 EXIT
4
 OK

I don't know if NOW and LATER will be useful. Maybe this experiment will lead to other interesting ideas. I know I could not have experimented with this if I had made LIT , among others, headerless.
[That color change is easier on the eyes! @Garth. Thanks for the example.]


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 07, 2020 10:08 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890

I made a version of Fleet Forth with TYPE defined as a colon definition to see the difference in speed and size.
The new TYPE is about 20% slower than the old version. Words that use TYPE , such as DUMP and WORDS , are about 5% slower.
The new kernel is 31 bytes smaller and the system as a whole is over 160 bytes smaller. This is due to having fewer DEFERred words that need revectored for printing and logging in the system loader.
WORDS is still fast enough on a one Megahertz C64 (WORDS will display 589 words in 11.9 seconds) that WITH-WORDS still needs to have DONE? in the definition to allow suspending the output. The same goes for DUMP (when displaying more than will fit on the C64 screen).


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 07, 2020 11:00 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
JimBoyd wrote:
I was wondering if anyone had an opinion, one way or the other, about the FORGET protection for DEFERred words ( resetting a deferred word's vector to -SET if it's vector will be forgotten. It resulted in a kernel that was fifty two bytes larger and adds two more bytes per deferred word.

I'm considering removing the FORGET protection for deferred words. The deferred words in the kernel are already protected and I haven't needed the protection for anything else. If someone else needs the protection, the following could be defined:
Code:
VARIABLE DEFER-LINK
DEFER-LINK OFF      // NOT REALLY NEEDED IN FLEET FORTH
: DEFER-TRIM  ( -- )
   DEFER-LINK HERE TRIM
   DEFER-LINK @
   BEGIN
      DUP 2- @ HERE U< 0=
      IF
         ['] -SET OVER 2- !
      THEN
      @ ?DUP 0=
   UNTIL ;

DEFER , FORGET , and EMPTY could be redefined:
Code:
: DEFER  ( -- )
   DEFER
   DEFER-LINK ADD ;
: FORGET  ( -- )
   FORGET
   DEFER-TRIM ;
: EMPTY  ( -- )
   EMPTY
   DEFER-TRIM ;

COLD could be redefined as well, but If the system is saved, the original COLD will be executed upon start-up. The original COLD will execute the original EMPTY. One way around this is to set INITIAL to DEFER-TRIM
Code:
' DEFER-TRIM IS INITIAL

Instead of redefining FORGET and EMPTY , another possibility is to execute DEFER-TRIM from the console after each use of FORGET or EMPTY or after a COLD start.
Maybe instead of doing all this, it would be best to just be careful with deferred words.
Any opinions?


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 23, 2020 9:28 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890

I'm definitely going without the forget protection for DEFERred words except for the kernel DEFERred words. For clarification, when I use the word 'vector', I will be referring to the word that a deferred word is set to execute. For every deferred word in the kernel, there is a default vector that it will be reset to if the current vector is forgotten.
As for warning about exhausting memory, I was including the word FREE in the kernel and using it like this:
Code:
: FREE  ( -- D )
   MRU 0 PAD FF + 0 D- ;

: CREATE  ( -- )
   FREE NIP ABORT" NO MEMORY"
   >IN @ NAME
   DUP C@ 1F OVER
   U< ABORT" NAME TOO LONG"
   0= ABORT" NO NAME"
   \ rest of definition not shown

FREE returns a double number. That number is negative if PAD+$FF is higher than MRU , the beginning of the block buffer control table.

My current version of Fleet Forth does not define FREE in the kernel. It defines ?MEM. ?MEM takes a size as a parameter and returns that same value. ?MEM is sort of transparent except when free memory is exhaused, then it aborts. In this case, free memory is all memory from PAD to MRU, not PAD+$FF to MRU. FREE has been modified ( it's now in the system loader ) to return free memory from PAD to MRU.
Code:
: ?MEM  ( N -- N )
   MRU OVER PAD + U< 0EXIT
   ABORT" NO MEMORY" ;

: ALLOT  ( N -- )
   ?MEM  DP +! ;

: CREATE  ( -- )
   >IN @ NAME
   DUP C@ 1F OVER
   U< ABORT" NAME TOO LONG"
   0= ABORT" NO NAME"
   \ rest of definition not shown for brevity

In the system loader:
Code:
: FREE  ( -- D )
   MRU 0 PAD 0 D- ;

I've also changed the definitions of FBUF and IBUF , the editor buffers from this:
Code:
: FBUF  ( -- ADR )
   PAD 55 + ;
: IBUF  ( -- ADR )
   FBUF [ C/L 1+ ] LITERAL + ;

which seemed to work well enough with the other version of CREATE, to this:
Code:
: FBUF  ( -- ADR )
   [ 55 C/L 2* + 2+ ] LITERAL ?MEM
   DROP  PAD 55 + ;
: IBUF  ( -- ADR )
   FBUF [ C/L 1+ ] LITERAL + ;

to work with ?MEM and avoid overwriting something important.
Although all memory allotting is slower, it doesn't feel noticeably slower. I'll have to run some tests, although ?MEM could be defined as a CODE word to minimize it's impact on performance.
Any opinions on which is the better way to deal with avoiding overwriting the block buffer control table and buffers, or if there were no block buffers, avoiding writing into the section of memory where I/O is mapped at $D000 to $DFFF?
I realize that ?MEM will catch all problems of trying to allot too much memory or even compiling a word that extends beyond the limit of free memory ( if memory is getting low ), but it also has more impact on performance. The first method only slows down CREATE , while the second slows down everything that extends the dictionary.
Any opinions, suggestions, or comments?

[Edit: fixed some typos]


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 01, 2020 12:45 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890

A test of , ( comma ) on both versions showed that when adding 10K cells to the dictionary, the version with ?MEM took almost twice as long.
I also tested the compiling speed of both by by copying some Forth utilities from blocks on disk to blocks in the Ram Expansion Unit. This was to eliminate the disk access speed (or lack thereof) from minimizing the differences.
Both versions compiled the utilities from ram and the version with ?MEM was less than three percent slower while offering better 'out of memory' protection.


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 30, 2020 8:45 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890

barrym95838 wrote:
Have you considered changing your PUSH to PUSHAY?

I've looked over the source for my kernel and I though I saw where PUSHAY would make some things smaller and faster. When I looked on the forum, I found out that PUSHAY pushes the accumulator to the high byte and the Y index register to the low byte. I had it the other way around! I was thinking low byte high byte order and the A for accumulator is before the Y for Y index register. I also called it AYPUSH ( I'd forgotten it was called PUSHAY).
In my ITC Forth, when a code word executes, the Y register is already set to zero. Certain words that return a byte value such as C@ SP@ and RP@ work well if AYPUSH ( or PUSHAY? ) pushes the accumulator as the low byte and Y as the high byte.
Some, like @ might work better ( as in smaller and slightly faster) if the accumulator holds the high byte while others like I ( the DO LOOP index) still needs to push the accumulator to the return stack temporarily.
I suppose it is possible to have both PUSHAY and AYPUSH . With one the high byte is in the accumulator and with the other the low byte is in the accumulator. This gives three possible pairs:
PUSHAY -- push .Y and .A to the data stack. .Y holds the low byte. Which falls through to:
PUTAY -- put .Y and .A on data stack, overwriting TOS.

AYPUSH -- push .A and .Y to the data stack. .A holds the low byte.
AYPUT -- put .A and .Y on the data stack, overwriting TOS.

PUSH -- push top byte of return stack and .A to data stack. .A holds the high byte and the low byte is on the return stack.
PUT -- put top byte of return stack and .A on data stack overwriting TOS.

In the kernel ( which is actually a complete Forth-83 Forth without the assembler and editor) I could use any combination of them but only one pair can fall through to NEXT . Then there is the matter of which to include in the Assembler. Every constant takes up memory.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 02, 2020 11:01 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890
JimBoyd wrote:

Some, like @ might work better ( as in smaller and slightly faster) if the accumulator holds the high byte while others like I ( the DO LOOP index) still needs to push the accumulator to the return stack temporarily.


Oops! I had the word I ( used to get the innermost DO LOOP index) on my mind when I wrote this, as I had been trying to get it to work with AYPUSH ( the version that pushes the accumulator to the low byte of the TOS) without making it any bigger. It can be modified without making it bigger if it can jump to the version of PUSHAY that pushes the accumulator to the high byte.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 02, 2020 11:03 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 890

Although I've been finding ways to improve Fleet Forth, I'm still working on the documentation. Even though the existing documentation is rather sparse, it is a Forth-83 Standard Forth, so it shouldn't be to difficult to work with.
Has anyone found any bugs? Does anyone have any suggestions for improvements? Any constructive criticism other than "Hurry up and get the docs done!" ?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 354 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 24  Next

All times are UTC


Who is online

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