6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Jul 04, 2024 5:29 pm

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Is it still alive?
PostPosted: Thu Dec 04, 2008 1:15 am 
Offline

Joined: Sat Aug 30, 2008 11:12 pm
Posts: 34
Location: Kent, UK
The last version of 6502 EhBASIC on Lee's website is 2.09, dated 2005. Is the project still under development? Any plans? Has the website moved?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 04, 2008 7:03 am 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
I think that it's simply "mature technology."


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 05, 2008 1:49 pm 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
DaveK wrote:
The last version of 6502 EhBASIC on Lee's website is 2.09, dated 2005. Is the project still under development? Any plans? Has the website moved?

No, nothing's moved. That is the current version.

kc5tja wrote:
I think that it's simply "mature technology."

That's pretty much the case. I only started EhBASIC because I wanted some high level language that I could easily port to any target hardware and be able to use it interactively, so I wouldn't be left wondering if it was my new hardware or my new assembly language code that was broken.

EhBASIC as it is has gone quite a way beyond that goal. Features I'd always wanted from a BASIC such as the ability to easily use hex and binary in the code and for input and output were added. Commands were added that made coding for hardware easier as were commands that made writing code itself easier.

Version 2.xx came with the lessons learned in coding a Motorola 68K version from scratch and, while it looks outwardly very similar to 1.xx versions, internally it changed quite a bit and became a fair bit quicker. 2.09 is the last completed version and while it can probably be improved it works better than I ever expected when I started sometime in the last millenium.

I do plan a similar but expanded version for the 65816 but not having an assembler/simulator like Michal Kowalski's simulator for the 6502 and having all of my 65816 hardware in storage, along with a lot of other things, until I finally sell this place and move has precluded any real progress on that to date.

If there's any undocumented feature that needs addressing I'm always up for that, EhBASIC isn't abandoned, it's just .. resting.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 05, 2008 3:21 pm 
Offline

Joined: Sat Aug 30, 2008 11:12 pm
Posts: 34
Location: Kent, UK
How would I go about adding keywords? I've implemented some stuff for a graphical LCD and would like to go from CALL PLOT,x,y to PLOT x,y.

Longer variable names would be nice but probably difficult to change.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Dec 06, 2008 6:58 am 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
How to add a new command to EhBASIC.

As this is a primary command, it can start a statement, first insert a new entry into the list of primary command tokens. It doesn't particularly matter where in the list.

E.g.
Code:
TK_DOKE           = TK_POKE+1       ; DOKE token
TK_CALL           = TK_DOKE+1       ; CALL token
TK_DO             = TK_CALL+1       ; DO token
TK_LOOP           = TK_DO+1         ; LOOP token

.. becomes ..

Code:
TK_DOKE           = TK_POKE+1       ; DOKE token
TK_CALL           = TK_DOKE+1       ; CALL token
TK_PLOT           = TK_CALL+1       ; PLOT token      new command entry
TK_DO             = TK_PLOT+1       ; DO token        modified entry
TK_LOOP           = TK_DO+1         ; LOOP token

Next put a corresponding new entry in the command vector table that starts at LAB_CTBL. This must be in the same relative location as the token value.

E.g.
Code:
      .word LAB_POKE-1        ; POKE
      .word LAB_DOKE-1        ; DOKE
      .word LAB_CALL-1        ; CALL
      .word LAB_DO-1          ; DO

.. becomes ..

Code:
      .word LAB_POKE-1        ; POKE
      .word LAB_DOKE-1        ; DOKE
      .word LAB_PLOT-1        ; PLOT      new command
      .word LAB_CALL-1        ; CALL
      .word LAB_DO-1          ; DO

Now add an entry in the keyword tables.

E.g.
Code:
LBB_PI
      .byte "I",TK_PI          ; PI
LBB_POKE
      .byte "OKE",TK_POKE      ; POKE

.. becomes ..

Code:
LBB_PI
      .byte "I",TK_PI          ; PI
LBB_PLOT
      .byte "LOT",TK_PLOT      ; PLOT     new command keyword
LBB_POKE
      .byte "OKE",TK_POKE      ; POKE

In this case there are already keywords that start with "P" so it's just a case of adding this one entry but if you were adding a keyword that starts with a so far unused letter then you also need to add entries in the first character table at TAB_1STC and in the character pointers table at TAB_CHRT and make a new character table for your entry.

Next you need to add an entry in the LIST decode table, this again must be in the same relative location as the token value.

E.g.
Code:
      .byte 4,'P'
      .word LBB_POKE          ; POKE
      .byte 4,'D'
      .word LBB_DOKE          ; DOKE
      .byte 4,'C'
      .word LBB_CALL          ; CALL
      .byte 2,'D'
      .word LBB_DO            ; DO

.. becomes ..

Code:
      .byte 4,'P'
      .word LBB_POKE          ; POKE
      .byte 4,'D'
      .word LBB_DOKE          ; DOKE
      .byte 4,'P'             ;           new keyword length and first character
      .word LBB_PLOT          ; PLOT      new keyword pointer
      .byte 4,'C'
      .word LBB_CALL          ; CALL
      .byte 2,'D'
      .word LBB_DO            ; DO

The last thing to add is the code for the new command which should be the same as the code you used for the CALL version but without the first scan for the comma. So instead of say using LAB_SCGB, scan for "," and get byte, you could use LAB_GTBY, get byte parameter, to get the X value.

.. and that should do it.

Quote:
Longer variable names would be nice but probably difficult to change.

Not that difficult but wastefull of space and speed, unless you want variable length names and then it does get more awkward. The first two significant characters give you over 3000 different variables of each type and you can append any number of other characters of your choice as long as you avoid keywords.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Dec 06, 2008 3:30 pm 
Offline

Joined: Sat Aug 30, 2008 11:12 pm
Posts: 34
Location: Kent, UK
Thanks for your help. I will try this today.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Dec 06, 2008 7:01 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
The earliest Forth systems represented word names using the first three characters plus a length byte. This allowed a single 32-bit compare instruction to isolate the overwhelming majority of words when performing a dictionary lookup.

Maybe the same technique would apply for BASIC variable names as well. For example, you could have two variables PLOT (pointer to the graphics plot routine) and PLOTLINE (pointer to some line drawing code). Both variables would start with the PLO prefix, but they'd be further disambiguated by the length byte (4 in the former case, 8 in the latter).

A collision occurs only when you share both a common prefix and length. Hence, A=PLOXXXXX and A=PLOTLINE both assign the same value to A.

Yes, this is a very crude form of hashing the variable name. :)

Just an idea though.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Dec 06, 2008 7:15 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
leeeeee wrote:
The first two significant characters give you over 3000 different variables of each type and you can append any number of other characters of your choice as long as you avoid keywords.

Lee.


Actually, precisely because EhBASIC lacks any kind of abstraction mechanisms whatsoever, and all variables are global, the names you assign to a variable become increasingly important as their quantity increases. Two-character variable names suffice for simple routines only.

Thankfully, if you're crafty with arrays, you can make yourself a stack, and implement your own support for abstraction. It's wordy to do, but it works -- I had to do it for many a VisualBasic application before VB learned proper abstraction constructs.

The technique applies to multiple data types too:

Code:
10 DIM S$(10),I(10)
20 SP=10:IP=10
30 SP=SP-1:S$(SP)="HELLO WORLD"
40 GOSUB 100:REM SP=10, I=9 AT THIS POINT
50 PRINT "THE LENGTH OF THE STRING IS:";I(IP)
60 IP=IP+1:END
100 IP=IP-1:I(IP)=LEN(S$(SP)):SP=SP+1:RETURN

Example,

Code:
10 DIM I(30):REM a simple stack of integers (effectively infinite depth)
11 IP=29:REM Integer stack pointer
...
999 REM A trivial addition example
1000 I(IP+1)=I(IP+1)+I(IP):IP=IP+1:RETURN
1999 REM ( a b c -- z -z ) compute the quadratic formula
2000 T = (-(I(IP+1)) + sqrt((I(IP+1))**2 - 4*(I(IP+2))*(I(IP)))) / 2*(I(IP+2))
2010 I(IP+2)=T:I(IP+1)=-T:IP=IP+1:RETURN


The code is ugly and wordy, like I said. However, it also allows for proper recursion, if your stack is deep enough. Here's how you might call the quadratic routine, for example:

Code:
100 IP=IP-3
110 I(IP+2)=(a)
120 I(IP+1)=(b)
130 I(IP)=(c)
140 GOSUB 2000
150 REM I(IP) contains -z, I(IP+1) contains +z


Remember to update IP as you produce or consume values off the stack!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Dec 06, 2008 7:28 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
I also wanted to add:

The technique can be applied to multiple data types as well.
Code:
10 DIM S$(100),I(100):REM THE STACKS
20 SP=100:IP=100:REM THE STACK POINTERS

30 REM FIND THE LENGTH OF A STRING.
40 SP=SP-1:S$(SP)="HELLO WORLD!"
50 GOSUB 1000
60 PRINT "THE LENGTH OF THE STRING IS: ";I(IP)
70 IP=IP+1
80 END

1000 REM JUST TO PROVE IT CAN BE DONE, WE FIND
1001 REM THE LENGTH OF THE STRING THE HARD WAY:
1002 REM RECURSIVELY!
1003 REM THIS IMPLEMENTS THE FOLLOWING EQUATIONS:
1004 REM LEN "" = 0
1005 REM LEN S = 1+(LEN (TAIL S))
1010 IF S$(SP)="" THEN IP=IP-1:I(IP)=0:SP=SP+1:RETURN
1020 SP=SP-1:S$(SP)=MID$(S$(SP+1),1):GOSUB 1000
1030 I(IP)=I(IP)+1:RETURN


Obviously, you'll want to use LEN() to compute the length of a string. I'm merely illustrating that using stacks like this in BASIC prove powerful enough to compute arbitrary lambda expressions.

Remember, the original version of Smalltalk was written in BASIC!


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

All times are UTC


Who is online

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