Jump to content
IGNORED

TurboForth V1.2 (Beta)--Evolution & Arcana


Lee Stewart

Recommended Posts

HEX

000E CODE: TEST 02E0 WORKSPACE , C820 A00A ' TEST + , 02E0 0000 ;CODE

DECIMAL

 

Unfortunately that won't work, Lee, as CODE: only permits numeric literals. It should be a relatively trivial mod to change the interpreter to permit it, however. I'll take a look at it!

Link to comment
Share on other sites

I like it! :grin: :thumbsup: Did you get a chance to look at the abortion I posted just above.

 

...lee

 

I did! It is very hacky, but it could have it's uses. I don't like the limitation of CODE: only being able to process numeric literals. Though it's actually a limitation of the interpreter/compiler. I'm going to see if I can change it. It won't take any extra ROM space, and more flexibility can only be a good thing!

 

So, did my diatribe make sense to you? :? It only just about made sense to me!! :twisted:

Link to comment
Share on other sites

Unfortunately that won't work, Lee, as CODE: only permits numeric literals. It should be a relatively trivial mod to change the interpreter to permit it, however. I'll take a look at it!

 

Trust me. I tried it. It works! I would not have posted it otherwise. :P

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Lee and anyone else that is interested ;-)

 

Quiet at work so spent an afternoon hacking. I thought I would have a go at writing an ED/AS option 3 loader for TF. It could have it's uses... Anyway, after reading the tagged object code loader spec in the ED/AS and physically looking at a few object files I managed to work it out.

 

The following loader is able to successfully load the following assembly code (when assembled into an object file, of course!)

 


VBLNK EQU >83D7 ; VERTICAL BLANK COUNTER
VDPR EQU >8800 ; VDP READ REGISTER
VDPW EQU >8C00 ; VDP WRITE REGISTER
VDPA EQU >8C02 ; VDP ADDRESS REGISTER


AORG >A900

 LI R1,'!'*256
START CLR R0
 LI R2,40*24
AGAIN BL @VSBW
 INC R0
 DEC R2
 JNE AGAIN
 AI R1,>0100
 JMP START
VSBW ORI R0,>4000
SWPB R0
MOVB R0,@VDPA
SWPB R0
MOVB R0,@VDPA
MOVB R1,@VDPW
XOR @BIT1,R0
RT
BIT1 DATA >4000
 AORG >FACE
 DATA 1,2,3,4,5,6,7,8,9,10
 DATA 10,9,8,7,6,5,4,3,2,1
 DATA >994A

 END

 

The loader itself is nothing special (seems quite fast though). It only supports the 9 tag (set address) and the B tag (load data). It does not support REF or DEF. It does support AORG.

 

Anyway, using classic99 I ran the loader, and then examined the memory using the debugger, and there was the code! I then set the PC to A900 and voila! The machine code ran just fine! Woohoo!

 

I might have a look at supporting the DEF directive. Any DEF'd code could generate dictionary entries:

 

DEF START

START CLR R0

...

...

 

Would actually create a dictionary entry called START that, when executed, does a branch to that address!

 

I don't know if supporting REF would have much use inside the TF environment... Any code written with the TI assembler for TF would probably want to be AORG'd, and the EA utilities such as VMBR KSCAN et al are no use inside TF - they're not there - and anyway, supporting REF seems complex - resolving REFd entries seems to be walking a big long chain, as far as I can see. Quite clever.

 

Here is the loader code:

 

FORGET LLen

0 VALUE LLen \ line length
0 VALUE LAddr \ address of line in memory
0 VALUE LPos \ current position in line
0 VALUE CAddr \ code load address
FALSE VALUE #3debug

: SetAddress
 1 +TO Lpos
 Laddr Lpos + 4 NUMBER DROP TO CAddr
 #3debug IF CR ." Set load address:" CAddr $. CR THEN
 3 +TO LPos ;

: LoadData
 1 +TO Lpos
 Laddr Lpos + 4 NUMBER DROP DUP CAddr !
 #3debug IF $. ELSE DROP THEN
 2 +TO Caddr 4 +TO LPos ;

: ParseLine
BEGIN
 LAddr Lpos + C@
 CASE
	 ASCII 9 OF SetAddress ENDOF
	 ASCII B OF LoadData ENDOF
	 ASCII : OF 999 TO LPos ENDOF
	 ASCII 7 OF 999 to LPos ENDOF
	 1 +TO LPos
 ENDCASE
Lpos LLen > UNTIL ;

fbuf: objFile

: #3LOAD
 ZEROS @ >R BASE @ >R 16 BASE ! TRUE ZEROS !
 s" DSK2.AL-TEST.OBJ DF80SI" objFile FILE
 objFile #OPEN ABORT" Cant open object file"
 BEGIN objFile #EOF? NOT WHILE
 PAD objFile #GET ABORT" Cant read from file"
 PAD COUNT TO LLen DROP \ set line length
 PAD 1+ TO LAddr		 \ set line address
 0 TO Lpos			 \ 0 line position
 ParseLine
 REPEAT
 objFile #CLOSE
 R> BASE !  R> ZEROS ! ;

#3LOAD

 

And here are the files as text files.

option 3 loader.txt

AL-TEST.txt

 

Enjoy! Quite pleased with this!

 

Mark

Link to comment
Share on other sites

Lee and anyone else that is interested ;-)

...

Enjoy! Quite pleased with this!

 

Mark

 

Wow! :-o Even though I already worked out how to load a binary image produced from an object file, I may switch to this because I won't have to keep track of the size every time I change the ALC!---especially if your loader updates the available-memory-size indicators. Does it?

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Lee and anyone else that is interested ;-)

...

It does not support REF or DEF. It does support AORG.

...

Mark

 

As long as I don't care about the REF/DEF table, i.e., not using DEFed labels in other programs' REFs, I should still be able to use DEFs for program clarity, right?

 

...lee

Link to comment
Share on other sites

You shouldn't be using def for program clarity. DEF is designed to make an entry in the ref/ def table for calling either by call link or by entering a program name into the prompt in editor/ assembler. Excuse the typos. Bloody touch pad rubbish!

 

I'm going to have a look at def though. I can't make head or tail of the editor assembler book so I'll just study a dump of an object file. Should be able to work it out.

 

Ref is of dubious utility in my opinion. What do you think? :ponder:

Link to comment
Share on other sites

You shouldn't be using def for program clarity. DEF is designed to make an entry in the ref/ def table for calling either by call link or by entering a program name into the prompt in editor/ assembler.

...

 

You're right, of course. I guess I should take out the DEFs in the FPLTF code to prevent the DEF garbage at the end of the file. Or, does your loader ignore it?

 

Ref is of dubious utility in my opinion. What do you think? :ponder:

 

I can't think why we would need it in TF. Any AORGed programs written to work in the TF environment can use EQUates I should think.

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Good point about updating the memory pointers. Excellent idea! The solution is to use comma to load the data instead of ! and then the pointers are updated for free.

 

So SetAddress should set H and load data should just comma the data in. I'll do it this evening!

 

Mark

Link to comment
Share on other sites

Good point about updating the memory pointers. Excellent idea! The solution is to use comma to load the data instead of ! and then the pointers are updated for free.

 

So SetAddress should set H and load data should just comma the data in. I'll do it this evening!

 

Mark

 

Cool beans!! :grin:

 

...lee

Link to comment
Share on other sites

Unfortunately that won't work, Lee, as CODE: only permits numeric literals. It should be a relatively trivial mod to change the interpreter to permit it, however. I'll take a look at it!

 

Trust me. I tried it. It works! I would not have posted it otherwise. :P

 

...lee

 

Mark...

 

You didn't respond to this. Did you see it?

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Lee:

It looks like you and Mark have been really busy here. Things are looking good!

I am uploading a file for an expanded version of the words definition. I called it

WORDS+

 

I combined a few things, and I used some of the code you sent me. I'm in the

ballpark....... but I'm not finished yet. The routine reads the TF Word Dictionary.

However, so far I have not corrected the logic (or illogic) which reads passed the end

of the dictionary in memory. This shows up in the last display screen of the running

routine. The TF word EXIT seems to be the last word in the dictionary. I could test for

that and stop the loop at that point. There may be a half dozen other ways to do this.

 

Anyway.... take a look and let me know what you think.

 

 

 

Rod Van Orden

 

WORDS+.zip

Link to comment
Share on other sites

Yeah I saw it I'm just not convinced!

 

Try:

 

9 constant n

Code: test n n n ;code

 

See?

 

What's your point? :P

 

CODE: sees the name of the constant and does nothing because the name is not a number. n just executes, pushing 9 onto the stack. My point is that anything presented to CODE: that is not seen as a literal number is ignored and passed to the interpreter. If you want to put the executed result into the CODE:ed word at that point, you simply comma ( , ) it:

 

CODE: TEST n , n , n , ;CODE

 

When you want to use a literal number in a calculation before compiling the result with comma, you must put it on the stack prior to CODE: and use it in the proper order in the embedded calculation followed by comma. Works like a charm!

 

...lee

Link to comment
Share on other sites

Rod...

 

The logic for stopping when you get to the beginning of the dictionary must check that the first word's previous-word pointer contains a 0, indicating that there are no more words before it. The place in @Willsy's code where that is checked is in words :

 

: words ... begin @ dup @ while ... ;

 

The first @ gets the address of the previous word (the current last word from latest the first time through), which actually contains the address of the word before it, which the second @ gets. This second value will be 0 just after the routine displays the first word in the dictionary. Your code is DUPing the address of latest the first time through, when it should be DUPing the address of the last word with @ before DUP . I would put back the @'s around DUP in words+ as in the code snippet in words above and remove the @ in scr-wrd to maintain the other logic (I think!).

 

...lee

Link to comment
Share on other sites

Oh yes! I wrote it and I don't understand it! I'm so dumb! I guess you could also use [ & ] so you don't have to put stuff on the stack before calling code: ?

 

In looking at your ALC for CODE: , ;CODE , [ , ] and INTERPRET , that won't work because [ and ] change _state but not coding , while CODE: and ;CODE change coding but not _state . I'm actually not sure what's going on inside the coded word definition when the interpreter sees compile mode while it is coding---I had to re-boot TF because something went awry!

 

I think I actually prefer the way TIF handles this, viz., TIF's CODE (sort of equivalent to TF's CODE: but not as smart) just establishes the header for the dictionary entry and nothing else. The programmer must compile each number with comma ( , ) and properly terminate the word with hex 045F , TIF's machine code equivalent of NEXT, (sort of equivalent to TF's ;CODE but not as smart). For further comparison TF uses CODE and NEXT, pretty much as TF uses ASM: and ;ASM ; TIF uses CODE and hex 045F as TF uses CODE: and ;CODE .

 

H-m-m-m, never mind! TF's way is clearer except for the non-coding-number stuff. Perhaps you could implement [ and ] equivalents for coding, say { and } .

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Yeah I saw it I'm just not convinced!

 

Try:

 

9 constant n

Code: test n n n ;code

 

See?

 

What's your point? :P

 

CODE: sees the name of the constant and does nothing because the name is not a number. n just executes, pushing 9 onto the stack. My point is that anything presented to CODE: that is not seen as a literal number is ignored and passed to the interpreter. If you want to put the executed result into the CODE:ed word at that point, you simply comma ( , ) it:

 

CODE: TEST n , n , n , ;CODE

When you want to use a literal number in a calculation before compiling the result with comma, you must put it on the stack prior to CODE: and use it in the proper order in the embedded calculation followed by comma. Works like a charm!

 

...lee

 

Actually, I got this backwards. CODE: is not doing anything after establishing the header and setting an ALC variable (coding). The interpreter is in charge and executes any word it finds before it ever checks to see if it is a number. It does other things after that if the input is not a TF word; but, the last thing but one that the interpreter does before giving up and issuing an error message is to check whether the input item is a number. If it is, it pushes it onto the stack. Only then does it check whether coding is set. If coding is set, the number on the stack is popped off and compiled into the dictionary at HERE .

 

...lee

Edited by Lee Stewart
Link to comment
Share on other sites

Yes, I like the idea of {{ and }} very much!

 

Back to the loader... 'Tis done... It now processes DEF directives, and, furthermore, it creates dictionary entries for them! So, after a loading a routine, you can type it's name to run it!

 

Here's a video!

 

The memory pointers are also updated.

 

Source code attached - I'm about to start work on removing the debug option and putting it in a couple of blocks. Will post when done.

I've also attached the source code that I used as my test platform. I used ASM994A to produce an object file *directly* into Classic99's DSK2 folder. The loader loads this object file and processes it, loading into the correct memory address (as per the AORG directive) and creating a dictionary entry for the DEF'd address. Cool.

 

http://youtu.be/ryaSh-7iyl4

 

AL-TEST.txt

option 3 loader.txt

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...