Last active
September 20, 2025 04:10
-
-
Save JamesNewton/432dc2f45ae0c239b2d9fcbfe411c9f8 to your computer and use it in GitHub Desktop.
RET FORTH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;1000 years ago, when I was 17, I wrote a FORTH for the Z80 on a Trash 80. | |
| ;It was unique for the time, because it used the machine language RET as NEXT for asm words. | |
| ;e.g. the machine stack pointed NOT at the data stack or return stack but instead | |
| ; at the list of word addresses being executed aka the thread. | |
| ;That meant that asm words could be strung together even faster than a standard asm program | |
| ;because there was no asm CALL the RET was both the return from the current asm word AND | |
| ;the call to the next one. | |
| ;The address of the data and return stacks were kept elsewhere... | |
| ;one of the other registers or a memory location (I don't remember, code is long lost). | |
| ;I think it was IX and IY. | |
| ;Every non-asm word started with an asm call to a routine that saved SP to the return stack pointer, | |
| ;set the SP to the value on the stack, and then did a RET. If I remember, that's called THREAD? | |
| ;Then last thread address was to an asm word that pulled the return stack TOS back into SP and RET. | |
| ;I seem to remember that is called NEXT. So for asm words, NEXT is RET and for higher level words, | |
| ;NEXT was a few asm instructions. | |
| ; | |
| ;Advantages: /screaming/ fast low level words, not much slower high level words. | |
| ; | |
| ;Disadvantages: | |
| ;- low level words couldn't really use the stack, because they would overwrite a thread. | |
| ; Of course, you could save and restore SP... | |
| ; but I seem to remember doing most manipulation of the stack with other registers. | |
| ; e.g. LD (IX+0),B; LD (IX+1),C; INC IX; INC IX; Or maybe it was DEC, I don't remember. | |
| ; | |
| ;- NO INTERRUPTS during asm words! LOL. Can't save PC to TOS because it would over write a thread. | |
| ; I got around that somewhat by adding an EI (enable interrupts) in the NEXT code while the SP was | |
| ; pointed at the return stack, doing a NOP and then DI. LOOP also had that in it because it was asm. | |
| ; Just for the fun of it, I put this together from the original hello world at: | |
| ; https://8bitworkshop.com/v3.12.0/?platform=zx&file=hello.asm# | |
| ; https://gist.github.com/JamesNewton/432dc2f45ae0c239b2d9fcbfe411c9f8#file-hello-asm | |
| CHAN_OPEN equ 5633 | |
| PRINT equ 8252 | |
| org 0x5ccb | |
| call thread | |
| ;ld a, 2 ; 3E 02 | |
| ;call CHAN_OPEN ; CD 01 16 | |
| ;ld de, text ; 11 0E 7F | |
| ;ld bc, textend-text ; 01 0E 00 | |
| ;call PRINT ; C3 3C 20 | |
| loop | |
| jmp loop | |
| ;words. Better examples would be dup and all that rot | |
| op1 | |
| ld a, 2 | |
| ret | |
| LOAD_BCDE | |
| pop bc | |
| pop de | |
| ret | |
| LOAD_DATA | |
| pop bc | |
| PUSH_BC | |
| inc ix | |
| inc ix | |
| ld (ix+0),b | |
| ld (ix+1),c | |
| ret | |
| DUP | |
| ld b,(ix+0) | |
| ld c,(ix+1) | |
| jmp PUSH_BC | |
| DROP | |
| dec ix | |
| dec ix | |
| ret | |
| PLUS | |
| ld b,(ix-2) | |
| ld c,(ix-1) | |
| ld h,(ix+0) | |
| ld l,(ix+1) | |
| add hl,bc | |
| ld (ix-2),h | |
| ld (ix-1),l | |
| jmp DROP | |
| ;the thread | |
| thread | |
| ld ix,data | |
| ld (return),sp ;save the stack | |
| ld sp,start ;stack is now start | |
| ret ;ret runs the words | |
| start | |
| dw LOAD_DATA | |
| dw 1 | |
| dw LOAD_DATA | |
| dw 2 | |
| dw PLUS | |
| dw op1 ;a word is just the address of the asm | |
| dw CHAN_OPEN ;which can be anything that doesn't push or pop | |
| dw LOAD_BCDE | |
| dw textend-text | |
| dw text | |
| dw PRINT | |
| dw stop | |
| stop | |
| ld sp,(return) | |
| ret | |
| data | |
| defb ' ' | |
| return | |
| defb ' ' | |
| text defb 'Hello, world!' ; 48 65 6C 6C 6F 2C 20 57 | |
| ; 6F 72 6C 64 21 | |
| defb 13 ; 0D | |
| textend | |
| org 0xff57 | |
| defb 00h |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment