I, as others before me, have been working on porting EhBASIC, by the late Lee Davison, to the Apple II. It's actually extremely easy to get it up and running in a minimalist fashion.
What I have wanted (since childhood) is an easy to use/hack BASIC that I have the source code for, that is aware of things like MouseText, the ProDOS MLI, the Pascal 1.1 slot protocol, and other amenities. I wanted I/O to be a first-class citizen in the language, not a somewhat dirty hack that relied on the I/O hooks and literally PRINT
ing commands to the operating system.
For those of us for whom it was our first programming language, we still love Applesoft. That being said, Apple's biggest updates to Applesoft since 1978 were support for lower-case entry and allowing the delete key on newer keyboards to be used as a backspace. There was pretty much nothing else that changed despite the evolving capabilities of the Apple II machines.
Startup screen. |
Some useful commands. |
Woz's signature. Credit. |
In short, my design criteria for a “new traditional” BASIC for the Apple II were:
PRINT CHR$(4);“OPEN MYFILE”
INPUT
command, don't display ?
if the programmer supplied a prompt).I don't quite have the skills to program a full BASIC interpreter, so EhBASIC was a natural fit for expansion due to its generous non-commercial license, well-commented and easy to understand source code, and ease of expansion.
The loader code is complete and features the following:
EHSTARTUP
, but uses the well-defined method of accepting a startup program through a program launcher.SAVE
continue to work even if all the buffers are used.SAVE “<filename>”
saves a program. Uses type $F8 (User 8) with aux type $EBA0.LOAD “<filename>”
loads a saved program.RUN “<filename>”
loads a saved program and executes it.PREFIX [“<new prefix>”]
displays or sets the prefix.ONLINE
lists the online volumes.CAT [“<path>”]
gives a simple directory catalog.RENAME “<old filename>”,“<new filename>”
DELETE “<filename>”
BYE
quits back to ProDOS.P8CALL <num>,<addr>
makes arbitrary ProDOS calls.P2B$()
and B2P$()
help with P8CALLP2B$(<addr|string>[,<mask>[,<rshift>])
- converts a Pascal string (length followed by bytes) to a BASIC string. Length is determined by the first value at addr, ANDed with <mask> and right-shifted by <rshift> bits.B2P$(<string>[,<lshift>[,<or>])
- converts a BASIC string to a Pascal string embedded within a BASIC string. The value used for the length byte is the length of the source string, left-shifted by <lshift> bits, and ORed with <or>.PR#
/IN#
work.PR#3!
).CALL -151
, line feeds are added after each CR (Pascal I/O separates CR/LF functionality). CHR$(192)
INVERSE
and NORMAL
behave as expected. FLASH
is the same as INVERSE
as flashing text is not supported with the alternate character set.HOME
clears the text screen.SCREEN
command:CLS
clears the current active screen.TEXT
, GR
, HGR
, and HGR2
all behave as Applesoft.HGR0
display full screen page 1. HGR1
same as HGR
, HGR3
mixed page 2.COLOR=
, PLOT
, HLIN
, and VLIN
behave as Applesoft.PLOT
can accept any amount of pixels in one command. E.g. plot 0,0,0,1,0,2,1,0,2,0
plots 5 pixels.HLIN
and VLIN
can take a comma instead of AT
. HCOLOR=
and HPLOT
behave as Applesoft.HPLOT
can take a comma instead of TO
.PDL()
and BTN()
work for game I/O.ERRNO(n)
function where n=0 for line number of error, n=1 for BASIC error #, n=2 for Pascal I/O error #, n=3 for ProDOS error #.GLOBAL(n)
returns the Nth address of the EhBASIC global page.BEEP [<pitch>,<duration>]
beeps the speaker. If the args are omitted, it produces the system bell.TRY
statement:TRY <statement> [THEN <success-clause>] [ELSE <fail-clause>]
ERRNO(1)
is populated per the below table.TRY
… THEN
sometimes doesn't work well with PRINT
, INPUT
, and statements that don't evaluate expression arguments because they do not expect to be followed by THEN
TRY PRINT “FOO” THEN PRINT “BAZ” ELSE PRINT “BAR”
will print “FOOBAR
” and ERRNO(1)
will reflect a syntax error.TRY
… ELSE
, TRY
with no clauses, or wrap in a subroutine (e.g. TRY GOSUB 1000 THEN
…).IF
inside TRY
, that may cause unexpected behavior, especially if there is an ELSE clause. If necessary, a solution is to wrap the conditional in a subroutine.TRY GOTO <n>
doesn't work. TRY GOSUB <n>
does. ERRNO(1) Values |
|
---|---|
# | Error |
0 | Success |
1 | NEXT without FOR |
2 | Syntax |
3 | RETURN without GOSUB |
4 | Out of Data |
5 | Function Call |
6 | Overflow |
7 | Out of Memory |
8 | Undefined Statement |
9 | Array Bounds |
10 | Double Dimensioned Array |
11 | Divide by Zero |
12 | Illegal Direct |
13 | Type Mismatch |
14 | String Too Long |
15 | String Too Complex |
16 | Continue Error |
17 | Undefined Function |
18 | LOOP without DO |
19 | Undefined Variable |
20 | Undimensioned Array |
21 | Unimplemented function |
22 | Illegal Argument |
23 | I/O Error |
24 | No Device Connected |
25 | ProDOS Error (ERRNO(3) contains ProDOS error number) |
26 | File Type Mismatch |
PR#
and IN#
to files.OPEN
, CLOSE
, WRITE
(binary file I/O), READ#
(read file like a DATA statement), READ()
(binary file I/O), SEEK
, TELL()
, FLUSH
, PRINT#
(text file I/O), INPUT#
(text file I/O), EOF() - Operations on files. Slots will be able to be opened like files for some operations.CREATE
, LOCK
, UNLOCK
, and CHTYPE
for files.SAVE
and LOAD
untokenized files option. E.g. SAVE “MYPROGRAM” AS LIST
.POP
– dunno why EhBASIC does not have this.ERROR <n>
– cause error on purpose.SCRN()
and HSCRN()
for seeing what pixel is displayed on the graphics screens.PREFIX$()
function for returning the current prefix. On GS/OS this should return the numbered prefixes as well.EDIT <n>
that will pre-fill the input buffer with that line and let you edit it.Many optimizations of my initial implementations of functionality are needed!
Not covered by the above:
INPUT
with a supplied prompt does not display ?
prompt.ON ERROR GOTO
and RESUME
TRY
above.No source code yet, sorry. I do have a mirror of the repository I started with located here.. Importantly, you should read the README and the EhBASIC manual.
Warning: I will be adding more tokens, and this will cause you problems as certain tokens need to be in certain positions. Don't do anything serious with these preview releases.
Files:
ca. 02/12/2018 12:00 PST
TRY
.TRY
…ELSE
now supported.Gzip-compressed .po file Derived from EhBASIC.
ShrinkIt archive Derived from EhBASIC.
In a low-level fashion, until I implement a better way:
10 a$=""+" ":REM the + is so EhBASIC won't store the string in program space 20 POKE SADD(a$),1:REM otherwise these pokes do bad things 30 DOKE SADD(a$)+1,$300:REM we'll use $300 as a buffer 40 P8CALL $c7,SADD(a$):REM call ProDOS GET_PREFIX 50 pf$=B2P$($300):REM convert result 60 PRINT "The prefix is ";pf$
10 a$=""+" " 20 POKE SADD(a$),2:REM 2 params 30 POKE SADD(a$)+1,$60:REM unit # 40 DOKE SADD(a$)+2,$300:REM buffer (16 bytes) 50 P8CALL $c5,SADD(a$):REM ON_LINE 60 v$=B2P$($300,$f):REM convert string, only need lower 4 bits for length 70 PRINT "Volume in slot 6, drive 1 is ";v$
10 HGR:HCOLOR=3:READ A,B:FOR I=1 TO 9:READ X,Y:HPLOT A,B TO X,Y:A=X:B=Y:NEXT I 15 READ A,B:FOR I=1 TO 16:READ X,Y:HPLOT A,B TO X,Y:A=X:B=Y:NEXT I 20 DATA 75,50,69,57,76,62,71,88,53,118,87,71,130,31,76,111,116,66,143,44,132,82, 123,83,108,95,104,104,112,107,130,94,133,80,154 25 DATA 73,146,89,158,88,162,94,139,141,122,160,119,156,139,126,194,85,232,64
I forgot where I found this. If I find out, I will credit it here.
1 GR:COLOR=1:O=5:P=35:Y=2:FOR I=1 TO 4:READ X,Z:HLIN X+O,Z+O AT Y:HLIN P-Z,P-X AT Y:Y=Y+1:NEXT I 2 FOR I=1 TO 30:READ X:HLIN X+O,P-X AT Y:Y=Y+1:NEXT I:COLOR=15:HLIN 9,12 AT 5:VLIN 4,7 AT 10:HLIN 24,26 AT 5:VLIN 4,6 AT 25 32 DATA 5,11,4,12,3,13,2,13,2,1,1,1,1,0,0,0,0,1,1,1,1,2,2,2,3,4,5,5,6,6,7,8,9,10,11,12,13,14,15,16,17,18
Don't remember where this one came from, either.
10 HGR:HCOLOR=3:LX=0:LY=80:FOR I=0 TO 279:A=SIN(I/8)*70+80:PRINT I,A:HPLOT I,A TO LX,LY:LX=I:LY=A:NEXT
My own variant of Brian's Theme.
100 GET a:HGR0 105 oc=c 110 X=INT(RND(0)*280):Y=INT(RND(0)*192) 115 c=INT(RND(0)*7)+1 120 IF c=oc THEN 110 125 HCOLOR=c 130 s=INT(RND(0)*4)+3 140 FOR i=0 TO 279 STEP s:HPLOT i,0 TO X,Y TO 279-i,191 145 NEXT 150 FOR i=0 TO 191 STEP s:HPLOT 0,191-i TO X,Y TO 279,i 155 NEXT 170 GET a 180 IF a=0 THEN GOTO 105 190 TEXT:HOME