diff --git a/.Docs/Acosx Words.md b/.Docs/Acosx Words.md
index c770a1d7..f8dfdd1a 100644
--- a/.Docs/Acosx Words.md
+++ b/.Docs/Acosx Words.md
@@ -20,14 +20,14 @@ This document lists all of the **ACOS Words** supported in the A2osX implementat
| DATE$ | *string*=DATE$ | dev | The DATE$ function returns the current date in MM/DD/YY format. The input will be taken from whatever device was configured as a clock. If 00/00/00 is returned, then there is no clock in the system and the date hasn't been set. |
| ECHO | ECHO=*string*
ECHO="" | dev | The ECHO statement is used to set the echo character to be used with the INPUT statement (e.g ECHO="\*"
will mask password entry with asterisks). Once the echo has been set, that character will be sent each time a user types a character when entering text. The ECHO statement in the second syntax (setting to an empty string) will reset the echo function to normal where user input will send the character that is being typed. |
| EDIT | EDIT(*number*) | dev | The EDIT statement is the command used to interface ACOS with its editor. With the different EDIT statements, you can clear the editor, see how much space is free, etc. The following list gives all legal calls:
To setup the FLAG function, you need to first point it to a location in memory (*memloc*), which is typically 'ram' or 'ram2', but you can specify an offset, e.g. FLAG=ram+20
will specify that you're using the 20th byte inside of the 'ram' location.
Once the pointer is set up, you can use the FLAG function just like any variable using the remaining syntax forms outlined for reading/writing flags. |
| FOR | FOR *numvar*=*startvalue* TO *targetvalue* [STEP *number*]
...
NEXT | dev | Creates a loop in program execution that sets a variable *numvar* to initially *startvalue* and increments its value with each iteration and will repeat until that variable reaches *targetvalue*. The STEP keyword is optional, but allows you to specify *number* which overrides the typical +1 increment of the loop, i.e. you can count by 2 by specifying STEP 2
or you can *decrement* by specifying a negative step number. In general, operates much the same way as AppleSoft FOR-NEXT loops, However, you can only have ONE for loop active at a time, i.e. the NEXT command does not allow for a variable, it only operates on the currently active FOR loop. |
| FREE | FREE | dev | Has the same function as the AppleSoft FRE(0) command, in that it returns the amount of free memory. REMY TODO: Does this garbage collect? |
| GET | GET *varstr* | dev | The GET statement is used to get a single keypress from the user. This is a blocking call in that the system will wait until a key is pressed. The key will be returned in *varstr*. Control characters will not be filtered out as they are with INPUT. |
-| GOSUB | GOSUB *label* | dev | Calls subroutine *label* in the program and sets the point in code so that when a RETURN function is encountered, execution will resume after the GOSUB
statement. While behaves the same way as AppleSoft basic, it is worth pointing out that ACOS uses labels as targets instead of line numbers. |
-| GOTO | GOTO *label* | Working | Redirects program execution to continue from *label*. Unlike GOSUB, no record of where the GOTO call occurred. As with GOSUB, it is worth pointing out that ACOS uses labels as targets intead of line number. |
+| GOSUB | GOSUB *label* | impl | Calls subroutine *label* in the program and sets the point in code so that when a RETURN function is encountered, execution will resume after the GOSUB
statement. While behaves the same way as AppleSoft basic, it is worth pointing out that ACOS uses labels as targets instead of line numbers. |
+| GOTO | GOTO *label* | impl | Redirects program execution to continue from *label*. Unlike GOSUB, no record of where the GOTO call occurred. As with GOSUB, it is worth pointing out that ACOS uses labels as targets intead of line number. |
| HOME | HOME | dev | Clears the screen and positions the cursor at the top left. REMY TODO: Does this clear the remote session as well? |
| IF | IF *condition* [THEN] *statement1* [ELSE] *statement2* | dev | Evaluate *condition* and if true (or greater than zero), execute *statement1*. If optional ELSE keyword is specified, then a false condition will execute *statement2*. If ELSE is used, it must appear on the same line as the IF statement, i.e. there is no multi-line if/then/else construct like some other languages. Logical constructs for *condition* supports parenthesis, AND, and OR.
THEN is optional (as it is in AppleSoft BASIC) but if you use THEN, it cannot be followed by a label directly.(use IF arg THEN GOTO label). |
| INFO | *expression*=INFO(*optional*)
INFO(*optional*)=*expression* | dev | INFO can be used as either a statement or as a function. It is really a 'catch-all' of ACOS state value functions in nature in that many values that are more or less unrelated are accessible through it. The following table gives the meanings of all the INFO data.
argument r/w function| @@ -54,7 +54,7 @@ This document lists all of the **ACOS Words** supported in the A2osX implementat | POKE | POKE *address*, *value* | dev | Sets the value of the memory location specified at *address* with *value*. REMY TODO: Does this work in A2osX? Perhaps limit it to $C000-CFFF? | | POP | POP | dev | Removes the last execution address from the stack, i.e. if a PUSH or GOSUB was called which put an execution address on the stack, the POP command can be used to remove it (and render that PUSH or GOSUB 'forgotten'). Works the same as the AppleSoft POP statement with the exception of it also can be used with the ACOS PUSH command. | | POSITION | POSITION #*device,* *record_length,* *record_number* [,*offset*] | dev | The POSITION statement is used to position within a random access file. The *device* argument is the disk device channel number that was used to open the file. The *record_length* argument is the length of each record. The *record_number* argument is the record number to be positioned to. The optional *offset* argument is the offset within the record that is to be positioned to. Note that there is no check to see if files actually conform to *record_length*; it along with the other *record_number* and *offset* arguments simply form a means of providing a calculation for a byte offset in the file as a while. For example,
-------- ---- -----------------
INFO(0) r is there a caller online? (0=no)
INFO(1) r capacity of current message file.
INFO(2) r callers baud rate /300 (1=300)
INFO(3) r/w current number of nulls.
INFO(4) w top screen stats. (1=chat, 2=exec)
INFO(5) r/w executive user online? (1=yes)
INFO(6) r checks bit map for mail/msg bases for room.
POSITION #1, 1000, 3, 50
would result in seeking file device #1 to the 3050'th byte in the file. |
-| PRINT | PRINT [#*device*,] [*expression*] [,*expression*] [;] | dev | Sends/displays text or data to the screen, remote user, or specified device handler. There are a few rules for PRINT:print:print...
statements.print:print...
statements.READY MSG(x):COPY #7
statements. Using REWIND will put the internal pointer back to where it was before the last message operation took place. This is generally used for doing a 're-read' function of sorts. |
| RIGHT$ | *string*=RIGHT$(*source*, *length*) | dev | Returns the last *length* number of characters from the *source*. |
| RND$ | *char*=RND$ | dev | The RND$ function is used to generate random characters. Each time RND$ is accessed a new random character will be returned. Be warned: the random number is generated from timing how long a user takes to enter his input. This is really a pretty random number since it is based on the users typing skill and speed. The only problem is that the random character generator can start repeating patterns after about 15-20 characters have been generated and before another input has taken place. REMY TODO: Is this how your implementation works or are you using an A2osX random generator? |
diff --git a/.Docs/Forth Words.md b/.Docs/Forth Words.md
index e9f43ad1..46930517 100644
--- a/.Docs/Forth Words.md
+++ b/.Docs/Forth Words.md
@@ -41,7 +41,7 @@ This document lists all of the **Forth Words** supported in the A2osX implementa
| 0< | ( n - f ) | Working | True if top number negative |
| 0= | ( n - f ) | Working | True if top number zero |
| . | ( n - ) | Working | Print number |
-| U. | ( u - ) | Working | Print UNSINGED number |
+| U. | ( u - ) | Working | Print UNSIGNED number |
| .R | ( n u - ) | | Print number, right-justified in u column |
| D. | ( d - ) | | Print double-precision number |
| D.R | ( d u - ) | | Print double-precision number in u column |
@@ -67,7 +67,8 @@ This document lists all of the **Forth Words** supported in the A2osX implementa
| DECIMAL | ( - ) | | Set decimal base |
| HEX | ( - ) | | Set hexadecimal base |
| OCTAL | ( - ) | | Set octal base |
-| @ | ( addr - n ) |Working | Replace word address by contents |
+| SP@ | ( - addr ) | Working | Return the address of the top of the stack, just before SP@ was executed |
+| @ | ( addr - n ) | Working | Replace word address by contents |
| ! | ( n addr - ) | Working | Store second word at address on top |
| C@ | ( addr - b ) | Working | Fetch one byte only |
| C! | ( b addr - ) | Working | Store one byte only |
diff --git a/.Floppies/A2OSX.BOOTHD.woz b/.Floppies/A2OSX.BOOTHD.woz
index b253353d..d00c9a1a 100644
Binary files a/.Floppies/A2OSX.BOOTHD.woz and b/.Floppies/A2OSX.BOOTHD.woz differ
diff --git a/.Floppies/A2OSX.BUILD.po b/.Floppies/A2OSX.BUILD.po
index 33ae73a0..4a0206cd 100644
Binary files a/.Floppies/A2OSX.BUILD.po and b/.Floppies/A2OSX.BUILD.po differ
diff --git a/.Floppies/A2OSX.TEST.po b/.Floppies/A2OSX.TEST.po
index 2e6667b4..c856cd86 100644
Binary files a/.Floppies/A2OSX.TEST.po and b/.Floppies/A2OSX.TEST.po differ
diff --git a/BIN/ACOS.S.CORE.txt b/BIN/ACOS.S.CORE.txt
index f26b77e8..47c0be66 100644
--- a/BIN/ACOS.S.CORE.txt
+++ b/BIN/ACOS.S.CORE.txt
@@ -35,6 +35,17 @@ CORE.Init >LDYAI CODESEG
bcs .9
>STA.G hVars
+
+ >LDYAI FWREF
+ >SYSCALL GetMem
+ bcs .9
+
+ >STYA ZPFWRefBufPtr
+ txa
+ >STA.G hFWRefBuf
+
+ lda #0
+ sta (ZPFWRefBufPtr)
clc
.9 rts
@@ -142,7 +153,42 @@ CORE.Compile jsr CORE.GetChar
sec
.99 rts
*--------------------------------------
-CORE.Run lda #$60 RTS
+CORE.FWREF >LDA.G hFWRefBuf
+ >SYSCALL GetMemPtr
+ >STYA ZPInputBufPtr
+ >DEBUG
+.1 lda (ZPInputBufPtr)
+ beq .8
+
+ sta ZPPtr1+1
+
+ jsr CORE.GetNextChar
+ sta ZPPtr1
+
+ jsr CORE.GetNextChar
+
+ jsr CORE.GetLabel
+ bcs .9
+
+ lda ZPADDR
+ sta (ZPPtr1)
+ ldy #1
+ lda ZPADDR+1
+ sta (ZPPtr1),y
+
+ bra .1
+
+.8 clc
+ rts
+
+.9 >PUSHW L.MSG.FWREFERR
+ >PUSHW ZPInputBufPtr
+ >PUSHBI 2
+ >SYSCALL PrintF
+ sec
+ rts
+*--------------------------------------
+CORE.Run lda #$0 RTS
sta (ZPCodeBufPtr)
jsr CORE.Cleanup
@@ -170,7 +216,7 @@ CORE.Run lda #$60 RTS
>PUSHW ZPPtr2
>PUSHBI 2
>SYSCALL PrintF
-* >DEBUG
+
jmp (ZPCodeBufPtr)
*--------------------------------------
CORE.Lookup >STYA ZPPtr1
@@ -241,6 +287,59 @@ CORE.CreateLabel
>SYSCALL SListAddData
.9 rts
*--------------------------------------
+CORE.GetLabel >PUSHB.G hLabels
+ >PUSHW ZPInputBufPtr
+ >SYSCALL SListLookup
+ bcs .9
+
+ >STYA ZPSID
+
+ txa
+ jsr CORE.SkipA
+
+ >PUSHB.G hLabels
+ >PUSHW ZPSID
+ >PUSHWI ZPADDR
+ >PUSHWI 2 2 bytes : ADDR
+ >PUSHWZ From Start
+ >SYSCALL SListGetData
+
+.9 rts
+*--------------------------------------
+CORE.AddFWRef lda ZPCodeBufPtr+1
+
+ jsr CORE.2FWRefBuf
+
+ lda ZPCodeBufPtr
+ jsr CORE.2FWRefBuf
+
+ ldy #$ff
+
+.1 iny
+ lda (ZPInputBufPtr),y
+ beq .8
+
+ jsr CORE.IsIDValid
+ bcs .8
+
+ jsr CORE.2FWRefBuf
+ bra .1
+
+.8 tya
+ jsr CORE.SkipA
+
+ lda #0
+
+ clc
+*--------------------------------------
+CORE.2FWRefBuf sta (ZPFWRefBufPtr)
+ inc ZPFWRefBufPtr
+ bne .8
+
+ inc ZPFWRefBufPtr+1
+
+.8 rts
+*--------------------------------------
CORE.CreateOrGetVar
>LDA.G hVars
jsr CORE.GetAddr
@@ -250,6 +349,8 @@ CORE.CreateOrGetVar
jsr CORE.NewKey
bcs .9
+ stz ZPTYPE
+
jsr CORE.GetChar
cmp #'$'
bne .1
@@ -362,6 +463,10 @@ CORE.IsEndInst cmp #':' CS=TRUE
.8 rts
*---------------------------------------
+CORE.IsIDValid cmp #'.'
+ clc
+ beq CORE.IsLetterRTS
+*---------------------------------------
CORE.IsLetterOrDigit
jsr CORE.IsDigit10
bcc CORE.IsLetterRTS
diff --git a/BIN/ACOS.S.KW.txt b/BIN/ACOS.S.KW.txt
index 0ec04100..83346430 100644
--- a/BIN/ACOS.S.KW.txt
+++ b/BIN/ACOS.S.KW.txt
@@ -12,7 +12,7 @@ KW.COPY
KW.CREATE
KW.ECHO
KW.EDIT
-KW.END
+*KW.END
KW.FILL
KW.FLAG
KW.FOR
@@ -22,38 +22,30 @@ KW.GET
sec
rts
*--------------------------------------
-KW.GOSUB sec
- .HS 90 CLC
+KW.GOSUB lda #$20 JSR abs
+ bra KW.GOTO1
*--------------------------------------
-KW.GOTO clc
- php
-
+KW.GOTO lda #$4C JMP abs
+
+KW.GOTO1 jsr CODE.EmitByte
jsr CORE.GetNextCharNB
bcs .90
- >LDA.G hLabels
- jsr CORE.GetAddr
- bcs .99
-
- plp
-
- lda #$4C JMP abs
+ jsr CORE.GetLabel
bcc .1
- lda #$20 JSR abs
+ jsr CORE.AddFWRef
+ bcs .99
-.1 jsr CODE.EmitByte
- lda ZPADDR
+.1 lda ZPADDR
jsr CODE.EmitByte
lda ZPADDR+1
-
clc
jmp CODE.EmitByte
.90 lda #E.CSYN
-.99 plp
- sec
- rts
+
+.99 rts
*--------------------------------------
KW.HOME
KW.IF
@@ -179,7 +171,10 @@ KW.READY
sec
rts
*--------------------------------------
-KW.RETURN lda #$60 RTS
+KW.RETURN
+* TODO : check context
+
+KW.END lda #$60 RTS
clc
jmp CODE.EmitByte
diff --git a/BIN/ACOS.S.txt b/BIN/ACOS.S.txt
index 9d855c8c..e6ed7998 100644
--- a/BIN/ACOS.S.txt
+++ b/BIN/ACOS.S.txt
@@ -8,6 +8,7 @@ NEW
CODESEG .EQ 4096
CONSTSEG .EQ 1024
DATASEG .EQ 256
+FWREF .EQ 1024
EXP.DEPTH.MAX .EQ 16
*--------------------------------------
.INB inc/macros.i
@@ -36,13 +37,13 @@ hOut .BS 1
ZPCodeBufPtr .BS 2
ZPConstBufPtr .BS 2
ZPDataBufPtr .BS 2
-ArgIndex .BS 1
-bFlag .BS 1
+ZPFWRefBufPtr .BS 2
EXP.ADDR .BS 2
EXP.TYPE .BS 1
EXP.AOPS .BS 1
-*EXP.DEPTH .BS 1
+ArgIndex .BS 1
+bFlag .BS 1
ZS.END .ED
*--------------------------------------
@@ -73,6 +74,7 @@ L.MSG.COMPILING .DA MSG.COMPILING
L.MSG.DEBUG .DA MSG.DEBUG
L.MSG.ERR .DA MSG.ERR
L.MSG.RUN .DA MSG.RUN
+L.MSG.FWREFERR .DA MSG.FWREFERR
L.MSG.STR .DA MSG.STR
L.MSG.INT32 .DA MSG.INT32
*--------------------------------------
@@ -211,6 +213,9 @@ CS.RUN >PUSHW L.MSG.GREETINGS
cmp #MLI.E.EOF
bne .9
+ jsr CORE.FWREF
+ bcs .9
+
jsr CORE.Run
bcc .8
@@ -472,7 +477,8 @@ MSG.ECHOCRLF .AZ "\r\n"
MSG.COMPILING .AZ "Compiling : %s...\r\n"
MSG.DEBUG .AZ "pStack=%H CodePtr=%H\r\n"
MSG.ERR .AZ "-^\r\nLine #%D:"
-MSG.RUN .AZ "Success, Code size = %D Bytes\r\nExecuting...\r\n"
+MSG.RUN .AZ "Success, Code size = %D Bytes\r\nResolving FWRefs...\r\n"
+MSG.FWREFERR .AZ "Unresolved FWRef : %s\r\n"
MSG.STR .AZ "%s"
MSG.INT32 .AZ "%L"
*--------------------------------------
@@ -590,6 +596,7 @@ hConstBuf .BS 1
hDataBuf .BS 1
hLabels .BS 1
hVars .BS 1
+hFWRefBuf .BS 1
DS.END .ED
*--------------------------------------
MAN
diff --git a/BIN/FORTH.S.KW.txt b/BIN/FORTH.S.KW.txt
index aedd4ef4..770a1720 100644
--- a/BIN/FORTH.S.KW.txt
+++ b/BIN/FORTH.S.KW.txt
@@ -682,6 +682,22 @@ KW.. jsr KW.DUP
* clc
+.9 rts
+*--------------------------------------
+KW.U. jsr KW.DUP
+ bcs .9
+
+ ldy #2
+ lda L.FMT.uint16
+ sta (pStack),y
+ iny
+ lda L.FMT.uint16+1
+ sta (pStack),y
+ >PUSHBI 2
+ >SYSCALL PrintF
+
+* clc
+
.9 rts
*--------------------------------------
KW..R
@@ -803,6 +819,16 @@ KW.OCTAL lda #E.SYN
sec
rts
*--------------------------------------
+KW.FETCHSP lda pStack+1
+ ldy pStack
+ bne .1
+
+ inc
+
+.1 >PUSHYA
+ clc
+ rts
+*--------------------------------------
KW.FETCHW lda (pStack)
sta ZPAddrPtr
ldy #1
diff --git a/BIN/FORTH.S.txt b/BIN/FORTH.S.txt
index 12b29def..c17e9167 100644
--- a/BIN/FORTH.S.txt
+++ b/BIN/FORTH.S.txt
@@ -92,6 +92,7 @@ L.MSG.TYPES .DA MSG.CONST
.DA MSG.CODE
L.FMT.Byte .DA FMT.Byte
L.FMT.int16 .DA FMT.int16
+L.FMT.uint16 .DA FMT.uint16
J.ESC .DA CL.BS left arrow
.DA HIS.GetNext
.DA HIS.GetPrev
@@ -132,6 +133,7 @@ J.KEYWORDS.LWR .DA KW.LWR
.DA KW.NEGATIVE
.DA KW.ZERO
.DA KW..
+ .DA KW.U.
.DA KW..R
.DA KW.D.
.DA KW.D.R
@@ -157,6 +159,7 @@ J.KEYWORDS.LWR .DA KW.LWR
.DA KW.DECIMAL
.DA KW.HEX
.DA KW.OCTAL
+ .DA KW.FETCHSP
.DA KW.FETCHW
.DA KW.STOREW
.DA KW.FETCHB
@@ -643,12 +646,22 @@ PrintPrompt >PUSHW L.MSG.PROMPT
>SYSCALL PrintF
rts
*--------------------------------------
-PrintDebugMsg >PUSHW L.MSG.DEBUG
+PrintDebugMsg lda pStack+1
+ ldy pStack
+ bne .1
+
+ inc
+
+.1 pha
+
+ >PUSHW L.MSG.DEBUG
>PUSHW ZPCodePtr
>PUSHW ZPDataPtr
- >PUSHB pStack
+
+ pla
+ >PUSHYA
>PUSHB RP
- >PUSHBI 6
+ >PUSHBI 7
>SYSCALL PrintF
rts
@@ -805,7 +818,7 @@ MSG.USAGE .AS "Usage : FORTH