6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 23, 2024 9:44 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Tue Dec 25, 2018 9:58 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
Vorth is token-threaded Forth for the VIC-20, based on the memory mapping ideas behind uxForth.
http://oneweekwonder.blogspot.com/

http://oneweekwonder.blogspot.com/2017/03/uxforth-unexpanded-forth-for-standard.html

http://oneweekwonder.blogspot.com/2016/11/uxforth-unexpanded-forth-for-standard.html

http://oneweekwonder.blogspot.com/2016/11/uxforth-unexpanded-forth-for-standard_6.html

Code:
nextx
    stx stack    ; X is the data stack pointer, stack is a z.p. address at the root of the stack
next   
    iny             ;[2]
iphi = *+2
nexto
    ldx $1700,y     ;[4]
    lda cfahi,x     ;[4]
    pha             ;[3]
    lda cfalo,x     ;[4]
    pha             ;[3]
    rts             ;[6]  = [26 clocks]

alternatively, next could load the stack pointer for 3 clocks:
Code:
    ldx stack       ;[3]
    rts             ;[6]  = [29 clocks]


Crossing page boundaries will be handled by the compiler. For now, development is going to be a metacompiler hosted on PETTIL, because it already has the editor and a running Forth. Vorth is written in PETTIL. Vorth source code is hosted on a PETTIL system, and Vorth object code is a file that loads and runs on unexpanded VIC-20.

In a primitive, the BRK instruction (opcode 00) is `enter`, and token #0 is reserved for `exit`

The return stack is the machine stack.

The data stack is a zero page structure, in this example we would say "the stack is at hex 60" which is the address containing a mirror of the stack pointer. Values on the data stack are 8-bits wide, but addresses are 16-bits wide. Primitives have an affirmative duty to exit with `X` containing the current stack pointer, and also to update the mirror when altering `X`. Since 'Y' contains IP low byte, it should also be respected.


Code:
\ stack dup !
$60 cconstant stack
code dup   ( value -- value value ) 
    stack ,x  lda,
              dex,
    stack ,x  sta,
    next 2-   jmp,
end-code

code !   ( value addr -- ) 
    stack 2+ ,x  lda,
    stack x)     sta,
                 inx,
                 inx,
                 inx,
    next 2-      jmp,
end-code


Last edited by chitselb on Wed Dec 26, 2018 11:50 pm, edited 8 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 25, 2018 10:14 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
The way the Vorth metacompiler will operate is first load the PETTIL screens containing the word `vorth`, then `15 vorth` loads the outermost word (the application) which will be the word invoked by `startup` on the target VIC-20 system.

The metacompiler scans each word, checks to see if it has a token already, and either creates a token on the spot (primitives, variables) or postpones creating a token (secondaries) using a metacompilation stack. Secondaries are recursively compiled and appended to the target dictionary until the outermost definition is complete, and is appended to the very end of the target dictionary.

The metacompiler expects the top line (index line) of each source screen to contain all blank-delimited
words that are defined on that screen. That's how it will locate the code to build into the dictionary only those words that are needed by the outermost word.


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 26, 2018 10:11 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
here's `enter`. It leaves a lot of rubbish on the stack, some of which might be useful, but this is a job for `exit` and anything that happens in between. We'll just leave it all on the return stack.
Code:
    ;    brk
              ;($FFFE) ; --> $E61B
              ;    pha
              ;    txa
              ;    pha
              ;    tya
              ;    pha
              ;    tsx
              ;    lda $0104,x
              ;    and #$10
              ;    beq +
              ;    jmp ($0092)  ; --> enter
              ;+
              ;    jmp ($0090)

              ;0107,x
              ;0106,x RTI hi    ; <-- set IPHI to this page
              ;0105,x RTI lo    ; <-- points to where BRK instruction is +2
              ;0104,x P
              ;0103,x A
              ;0102,x X         ; data stack pointer
              ;0101,x Y         ; IPLO
              ;0100,x           ; <-- next stack entry goes here
                                ; X = stack pointer
                                ; A = #$10
                                ; Y = IPLO
code enter
    ldy $0106,x
    lda iphi
    sta $0106,x
    sty iphi
    ldy $0105,x
    dey
    jmp nexto      ; does not increment `iplo`


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 28, 2018 2:27 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
https://github.com/chitselb/pettil/blob/noobranch/studio/vorth/vorth.a65

2019-01-03 edit: I removed a lot of early draft code, the next message replaces that code.


Last edited by chitselb on Thu Jan 03, 2019 5:59 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 03, 2019 5:56 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
In Vorth, most things are done to conserve space. Here is some working code like that which the Vorth metacompiler will generate. This one makes a little bird fly around on the VIC-20 display. The whole thing, including a BASIC bootstrap and the Vorth inner interpreter with a few primitives, takes up less than 300 bytes of RAM.

Only words that are required by the outermost definition ("the app") are compiled into the target dictionary. First, this little bit of BASIC bootstrap to call Vorth at $100D :
Code:
6502 sys4109

(C:$11f0) m 1000 100f
>C:1000  00 0b 10 66  19 9e 34 31  30 39 00 00  00 a9 00 85   ...f..4109......

(C:$114f) d 100d
.C:100d   .basend:
.C:100d  A9 00       LDA #$00
.C:100f  85 04       STA $04            ; shadow IP, put a zero here...
.C:1011  A9 FF       LDA #$FF
.C:1013  8D 0F 90    STA $900F          ; yellow/light yellow border/background
.C:1016  A9 52       LDA #$52
.C:1018  8D 16 03    STA .BRKVEC
.C:101b  A9 10       LDA #$10           ; `brk` instruction performs `enter`
.C:101d  8D 17 03    STA $0317          ; the rest of `enter` is at $1052
.C:1020   .restart:
.C:1020  6C 93 11    JMP (.userstartup) ; on to the main event!
.C:1023   .delay:
.C:1023  20 F5 10    JSR .docreate      ; variable delay  5 delay !
.C:1026  05
.C:1027   .exit:
.C:1027  68          PLA
.C:1028  A8          TAY                ; IP low byte
.C:1029  68          PLA
.C:102a  68          PLA
.C:102b  68          PLA
.C:102c  68          PLA                ; `enter` left 6 bytes, discard most of it
.C:102d  68          PLA                ; IP high byte
.C:102e   .gotoay:
.C:102e  8D 3A 10    STA .iphi
.C:1031  D0 02       BNE .nextx         ; bra
.C:1033   .spstore:
.C:1033  A2 00       LDX #$00
.C:1035   .nextx:
.C:1035  86 60       STX .STACK
.C:1037   .next:
.C:1037  C8          INY                ;[2]
.C:1038   .nexto:
.C:1038  BE 00 11    LDX $1100,Y        ;[4]
.C:103b  BD B8 11    LDA .cfahi,X       ;[4]
.C:103e  48          PHA                ;[3]
(C:$103f) d
.C:103f  BD 95 11    LDA .cfalo,X       ;[4]
.C:1042  48          PHA                ;[3]
.C:1043  A6 60       LDX .STACK         ;[3]
.C:1045  60          RTS                ;[6 = 29 total clocks]
.C:1046   .bumpip:
.C:1046  C8          INY
.C:1047  D0 03       BNE .bumpip01
.C:1049  EE 3A 10    INC .iphi
.C:104c   .bumpip01:
.C:104c  AD 3A 10    LDA .iphi
.C:104f  85 05       STA $05            ; shadow IP at ($04)
.C:1051  60          RTS

               ;brk
                    ;($FFFE) --> $FF72
                    ;FF72:
                    ;pha           ; VIC-20 ROM stuff
                    ;txa
                    ;pha
                    ;tya
                    ;pha
                    ;tsx
                    ;lda $0104,x
                    ;and #$10
                    ;bne $FF82
                    ;jmp (.BRKVEC)  --> $1052 BRK vector
                    ;FF82:
                    ;jmp ($0314) ; hardware IRQ
.C:1052   .enter:
.C:1052  58          CLI
.C:1053  BC 06 01    LDY $0106,X
.C:1056  AD 3A 10    LDA .iphi
.C:1059  9D 06 01    STA $0106,X
.C:105c  8C 3A 10    STY .iphi
.C:105f  BC 05 01    LDY $0105,X
.C:1062  88          DEY
.C:1063  4C 38 10    JMP .nexto
.C:1066   .qbranch:
.C:1066  20 46 10    JSR .bumpip
.C:1069  E8          INX
.C:106a  B5 60       LDA .STACK,X
.C:106c  D0 06       BNE .branch01
.C:106e  4C 35 10    JMP .nextx
.C:1071   .branch:
.C:1071  20 46 10    JSR .bumpip
.C:1074   .branch01:
.C:1074  98          TYA
.C:1075  18          CLC
.C:1076  71 04       ADC ($04),Y
.C:1078  A8          TAY
.C:1079  4C 35 10    JMP .nextx
.C:107c   .cfetch:
.C:107c  A1 60       LDA (.STACK,X)
.C:107e  95 61       STA $61,X
.C:1080  4C 88 10    JMP .drop
.C:1083   .emit:
.C:1083  B5 60       LDA .STACK,X
.C:1085  20 D2 FF    JSR $FFD2
.C:1088   .drop:
.C:1088  E8          INX
.C:1089  4C 35 10    JMP .nextx
.C:108c   .three:
.C:108c  A9 03       LDA #$03
.C:108e  2C A9 20    BIT $20A9  ; bl:
.C:1091  2C B5 62    BIT $62B5  ; third:
.C:1094  2C B5 61    BIT $61B5  ; over:
.C:1097  2C B5 60    BIT $60B5  ; dup:
.C:109a  CA          DEX
.C:109b  95 60       STA .STACK,X
.C:109d  4C 35 10    JMP .nextx
.C:10a0   .swap:
.C:10a0  B5 60       LDA .STACK,X
.C:10a2  48          PHA
.C:10a3  B5 61       LDA $61,X
.C:10a5  95 60       STA .STACK,X
.C:10a7  68          PLA
.C:10a8  95 61       STA $61,X
.C:10aa  4C 37 10    JMP .next
.C:10ad   .rot:
.C:10ad  B5 60       LDA .STACK,X
.C:10af  48          PHA
.C:10b0  B5 61       LDA $61,X
.C:10b2  48          PHA
.C:10b3  B5 62       LDA $62,X
.C:10b5  95 60       STA .STACK,X
.C:10b7  68          PLA
.C:10b8  95 62       STA $62,X
.C:10ba  68          PLA
.C:10bb  95 61       STA $61,X
.C:10bd  4C 37 10    JMP .next
.C:10c0   .minus:
.C:10c0  B5 61       LDA $61,X
.C:10c2  49 FF       EOR #$FF
.C:10c4  95 61       STA $61,X
.C:10c6  38          SEC
.C:10c7  29 18       AND #$18   ; mplus:
.C:10c9  B5 60       LDA .STACK,X
.C:10cb  75 61       ADC $61,X
.C:10cd  90 02       BCC .mplus01
.C:10cf  F6 62       INC $62,X
.C:10d1   .mplus01:
.C:10d1  95 61       STA $61,X
.C:10d3  E8          INX
.C:10d4  4C 35 10    JMP .nextx
.C:10d7   .or:
.C:10d7  B5 60       LDA .STACK,X
.C:10d9  15 61       ORA $61,X
.C:10db  4C D1 10    JMP .mplus01
.C:10de   .andx:
.C:10de  B5 60       LDA .STACK,X
.C:10e0  35 61       AND $61,X
.C:10e2  4C D1 10    JMP .mplus01
.C:10e5   .xor:
.C:10e5  B5 60       LDA .STACK,X
.C:10e7  55 61       EOR $61,X
.C:10e9  4C D1 10    JMP .mplus01
.C:10ec   .oneplus:
.C:10ec  F6 60       INC .STACK,X
.C:10ee  D0 02       BNE .oneplus01
.C:10f0  F6 61       INC $61,X
.C:10f2   .oneplus01:
.C:10f2  4C 37 10    JMP .next
.C:10f5   .docreate:
.C:10f5  CA          DEX
.C:10f6  CA          DEX
.C:10f7  68          PLA
.C:10f8  95 60       STA .STACK,X
.C:10fa  68          PLA
.C:10fb  95 61       STA $61,X
.C:10fd  86 60       STX .STACK
.C:10ff  4C EC 10    JMP .oneplus
.C:1102   .randu:
.C:1102  38          SEC        ; from Butterfield's "First Book of KIM-1"
.C:1103  AD 23 11    LDA $1123
.C:1106  6D 26 11    ADC $1126
.C:1109  6D 27 11    ADC $1127
.C:110c  8D 22 11    STA .random
.C:110f  A2 04       LDX #$04
.C:1111   .ripl:
.C:1111  BD 22 11    LDA .random,X
.C:1114  9D 23 11    STA $1123,X
.C:1117  CA          DEX
.C:1118  10 F7       BPL .ripl
.C:111a  A6 60       LDX .STACK
.C:111c  CA          DEX
.C:111d  95 60       STA .STACK,X
.C:111f  4C 35 10    JMP .nextx
.C:1122   .random:
.C:1122  9C 9C D8    SHY $D89C,X
.C:1125  D8          CLD
.C:1126  9D E7 20    STA $20E7,X
.C:1129  E1 FF       SBC ($FF,X)
.C:112b  D0 02       BNE .pushz
.C:112d   .notz:
.C:112d  18          CLC
.C:112e  29 38       AND #$38
.C:1130  A9 00       LDA #$00
.C:1132  E9 00       SBC #$00
.C:1134  CA          DEX
.C:1135  95 60       STA .STACK,X
.C:1137  4C 35 10    JMP .nextx
.C:113a   .threedot:
.C:113a  A2 03       LDX #$03   ; emit 3 bytes, coded inline
.C:113c   .threedot01:
.C:113c  20 46 10    JSR .bumpip
.C:113f  B1 04       LDA ($04),Y
.C:1141  20 D2 FF    JSR $FFD2
.C:1144  CA          DEX
.C:1145  D0 F5       BNE .threedot01
.C:1147  4C 37 10    JMP .next
.C:114a   .jiffies:
.C:114a  B5 60       LDA .STACK,X
.C:114c  18          CLC
.C:114d  65 A2       ADC $A2
.C:114f   .jiffies01:
.C:114f  C5 A2       CMP $A2
.C:1151  D0 FC       BNE .jiffies01
.C:1153  4C 88 10    JMP .drop
.C:1156   .compass:
.C:1156  20 F5 10    JSR .docreate
.C:1159  1D 9D 11    ORA $119D,X    ; [rt] [lf] [dn] [up]
.C:115c  91 00       STA ($00),Y        ; : 3<-   ( -- ) 3. [lf] [lf] [lf] ;
.C:115e  1A          NOOP
.C:115f  9D 9D 9D    STA $9D9D,X
.C:1162   ._zz:
.C:1162  00          BRK                ; : zz   ( -- ) delay @ jiffies ;
.C:1163  01 07       ORA ($07,X)
.C:1165  1B 00 1A    SLO $1A00,Y        ; : flap   ( -- ) 3.
.C:1168  D5 D7       CMP $D7,X          ;    [U] [W] [I]
.C:116a  C9 1C       CMP #$1C           ;    3<-
.C:116c  1D 1A C0    ORA $C01A,X        ;    zz  3. [@] [W] [@]
.C:116f  D7 C0       DCP $C0,X
.C:1171  1C 1D 1A    NOOP $1A1D,X       ;    3<- zz  3.
.C:1174  CA          DEX
.C:1175  D7 CB       DCP $CB,X          ;    [J] [W] [K]
.C:1177  1C 1D 1A    NOOP $1A1D,X       ;    3<- zz  3.
(C:$117a) m 1150
>C:1150  a2 d0 fc 4c  88 10 20 f5  10 1d 9d 11  91 00 1a 9d   ...L.. .........
>C:1160  9d 9d 00 01  07 1b 00 1a  d5 d7 c9 1c  1d 1a c0 d7   ................
>C:1170  c0 1c 1d 1a  ca d7 cb 1c  1d 1a c0 d7  c0 1c 1d 1a   ................
                                        ;    [@] [W] [@]  3<- zz 3.
>C:1180  20 20 20 1c  00 1f 16 0a  14 12 07 08  00 1e 1e 20      ............
                                        ;    [sp] [sp] [sp]  3<- ;
                                        ; : flit   ( -- ) compass randu
                                        ;    3 and m+ c@ emit ;
                                        ;118C:
                                        ; : fly   ( -- )
                                        ;    begin
                                        ;        flap flap flit
>C:1190  17 05 fa 8c  11 26 22 32  36 51 65 70  7b 82 87 8b   .....&"26Qep{...
                                        ;        ?terminal
                                        ;    until ;
                                        ; (startup) --> $118C
                                        ;
                                        ; [35 tokens]
                                        ; CFA low bytes
                                        ; CFA high bytes
>C:11a0  8e 91 94 97  9f ac bf c7  d6 dd e4 01  27 2c 2e 39   ............',.9
>C:11b0  49 5c 61 65  55 83 8b 92  10 10 10 10  10 10 10 10   I\aeU...........
>C:11c0  10 10 10 10  10 10 10 10  10 10 10 10  10 10 11 11   ................
>C:11d0  11 11 11 11  11 11 11 11  11 11 11 ff  ff ff ff ff   ................
>C:11e0  ff ff ff ff  ff ff ff ff  ff ff ff ff  ff ff ff ff   ................


Last edited by chitselb on Thu Jan 03, 2019 6:45 am, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 03, 2019 6:04 am 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
Stacks are pretty simple, 8-bits wide with the stack pointer stored in the byte above the stack. It is easy enough to treat two 8-bit cells as an address, since everything is in zero page. This seems like it might work well for a few processes, each with its own private stack, in a multitasking setup. As long as it could be known what the maximum stack depth a process will be, the stacks could be kept out of each others' way.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


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: