Download it here: http://home.comcast.net/~oneelkruns/
Some key points of the language and compiler:
1. Written in Python, will run almost everywhere
2. Comes with a library of over 100 assembly words, including ProDOS
disk support
3. Forth-like, though simpler
4. The compiler can generate 140k disk image files as output allowing
development using emulators
5. Easily modified to work with other 6502 systems
6. Documentation included
7. The compiler only outputs the code it truly needs. No large
runtime module.
I wrote this as a pet project and it seems to be working well enough
to release it for others to play around with. Of course, do let me
know if you find any bugs or if you think you'll use it for something.
Looks interesting!
BTW I had some issues downloading to a windows box so I've converted
the archive from a tar.gz to a .zip file - there's a copy of the zip
file is at http://www.jamtronix.com/files/spl_1.0.zip
Regards
Jonno
Looking forward to playing with this. Thanks.
Cheers,
Mike T
--- Synchronet 3.14a-Win32 NewsLink 1.85
A2Central.com - Your total source for Apple II computing.
When I tried it, the .gz file was downloaded as a .tar.tar file.
Changing the final .tar back to .gz fixed it.
-michael
NadaPong: Network game demo for Apple II computers!
Home page: http://members.aol.com/MJMahon/
"The wastebasket is our most important design
tool--and it's seriously underused."
What's the best way to define new words in assembly? (e.g. if I wanted
to create a DOS 3.3 library)?
Yes, please to create a new library! I hadn't thought of it before,
but it might be nice to make it easier to add new library words in
assembly.
Here's how to do it:
1. Write your new word. Call "pop" to get the top stack item in A
and X (lo/hi). Call "push" to push A,X on the stack. Also useful is
"get_ta" and "get_tb" to put the top stack address into zero page
locations ta,ta+1 and tb,tb+1.
2. In the spl.py source code you need to update the DEPENDENCIES and
LIBRARYMAP dictionaries. They are near the top of the file. Even if
you are new to Python, you'll see how the syntax goes from what's
already there.
3. In DEPENDENCIES you need to put the names of all the routines that
your routine calls, like "pop" and "push", _if_ those routines exist
in a separate .s file. If you put all your routines in the same .s
file, then you can leave this entry set to an empty list ([]).
However, you are most likely going to call "pop" and "push", if
nothing else. The whole point of the dependencies dictionary is to
only copy the assembly code that is actually needed.
4. In LIBRARYMAP you need to set up the mapping between what you call
your new word in SPL, the left-hand value, and what the base file name
is that holds your routine's code on the right-hand side. You'll see
what I mean when you look at the code.
If you do make new library words and feel like sending them to me I'll
update the source on the web page. That might be best to keep
everything in one place. However, I did put the code out there for
any use, so you don't have to send me anything if you don't want to.
If you make the DOS library in SPL itself you can put it in the
include directory, but that might be difficult for DOS 3.3. I started
with the ProDOS interface in SPL and it was taking up too much memory
so I switched to assembly.
And, of course, do let me know if you run into bugs. I'm sure there
are a few.
Ron
It seems that Comcast may not like the .gz extension. I'll put a .zip
up there in place of the .gz file.
Ron
Thanks! I put a copy of the zip file in place of the .gz one on the
website.
Ron
Ron
I don't mind sending things back to get included, but it seems like
adding things in to the main spl.py file might become a maintenance
chore. What about adding compiler directive say "asm" that passes the
included source code straight through to as6502 (similar to the 'data'
directive).
e.g.
asm cout
JSR $FDED
RTS
end
> asm cout
> JSR $FDED
> RTS
> end
why not
> asm cout
> JMP $FDED
> end
?
Save one byte and 6 cycles!
Ok, I'm convinced. I already planned on doing this at one point but
put it off to get the first version out on the web. I'm about to
leave on a business trip, I might have time to hack on it in the
evenings, otherwise I'll get it in there when I get back later next
week or Christmas week.
Ron
Just to be cute...
def cout
areg 0xfded execute
end
Ron
this should go in a file called "beep.s" in the lib directory
###########################################
beep_pitch:
.byte 0
beep_duration:
.byte 0
beep: ;(duration pitch --)
jsr pop
sta beep_pitch
jsr pop
sta beep_duration
beep_main_loop:
lda $c030 ;toggle speaker
beep_delay_between_clicks:
dey
bne beep_not_waited_255_cycles
dec beep_duration
beq beep_done
beep_not_waited_255_cycles:
dex
bne beep_delay_between_clicks
ldx beep_pitch
jmp beep_main_loop
beep_done:
rts
###############################
then open up spl.py, and add "beep" to both DEPENDENCIES (depends on
'pop') and LIBRARYMAP.
finally, here's some sample code (which got my 18mo daughter very
excited):
###############################
org 0x801
def pause #(duration --)
{
1- dup ?0break
}
drop
end
def main
108 128 beep
10 pause
108 128 beep
10 pause
108 85 beep
10 pause
108 85 beep
10 pause
108 76 beep
10 pause
108 76 beep
10 pause
216 85 beep
10 pause
108 96 beep
10 pause
108 96 beep
10 pause
108 102 beep
10 pause
108 102 beep
10 pause
108 114 beep
10 pause
108 114 beep
10 pause
216 128 beep
10 pause
108 85 beep
10 pause
108 85 beep
10 pause
108 96 beep
10 pause
108 96 beep
10 pause
108 102 beep
10 pause
108 102 beep
10 pause
216 114 beep
10 pause
108 85 beep
10 pause
108 85 beep
10 pause
108 96 beep
10 pause
108 96 beep
10 pause
108 102 beep
10 pause
108 102 beep
10 pause
216 114 beep
10 pause
108 128 beep
10 pause
108 128 beep
10 pause
108 85 beep
10 pause
108 85 beep
10 pause
108 76 beep
10 pause
108 76 beep
10 pause
216 85 beep
10 pause
108 96 beep
10 pause
108 96 beep
10 pause
108 102 beep
10 pause
108 102 beep
10 pause
108 114 beep
10 pause
108 114 beep
10 pause
216 128 beep
10 pause
end
###############################
Nice! beep.s will be part of the distribution going forward.
Got back from my work trip but I didn't have time to put asm
statements into SPL. Given the fact that I didn't use a real parser,
it isn't as straightforward as I thought it would be but I have an
idea to try now that I'm on vacation.
I might have some bugs to sort out in SPL and it's output formats. I
tried sending your sample program to a real Apple II first as a text
file (-t a2t) and then as a disk image file which I write back to a
real floppy. When I EXEC the text file I get a SYNTAX ERROR message
and no file is saved on disk. When I transfer the disk image and
write it back to a real floppy the disk is not readable. However, the
disk image file works just fine with the AppleWin emulator. So,
something is a tiny bit off, or my transfer program is messing things
up some how.
Ron
Just as a follow up, the problem was with my serial transfer
settings. The code works perfectly and my younger kids came running
once they heard the familiar tune as well.
A nice addition would be to add support for Michael Mahon's code to
play .wav files. Nice for sound effects should someone want to write
a game of some sort using SPL.
Still thinking about the asm construct. Just need to find some time
to add it in.
Ron
I'm confused. "SPL" is a language, which Ron wrote in another
language called "Python", that outputs 6502 assembler, and that output
is then assembled by the C program, "AS6502"? Not sure what happens
after that.. but is that the gist?
Would someone be so generous as to describe the steps of taking a
sample SPL program from start to actually running on an Apple so it
can be seen how this all works?
Thanks very much,
~ J
This is exactly correct. What happens next is that your output file
is either transferred to a real Apple II and run there as a binary
file or, if you chose a disk image file as output, you can load that
disk image file in any Apple II emulator and run the file there.
> Would someone be so generous as to describe the steps of taking a
> sample SPL program from start to actually running on an Apple so it
> can be seen how this all works?
Sure, no problem.
Say I have a PC running Linux (or Windows). On that PC I download and
unpack the SPL compiler. What I get is basically an executable for
as6502 and a file called spl.py plus a directory called lib with over
100 .s files in it.
Now I want to create a new SPL program to run on the Apple II. I open
a text editor on the PC and enter something like this:
def main
"Hello world!" disp cr
end
and save it to a file called hello.spl. Now I can run the SPL
compiler on this file. This is done from the command line by typing
something like:
python spl.py hello -o hello -t bin
Assuming that Python is installed (almost always true with any
standard Linux distribution, you have to get it and install it
yourself for Windows, see www.python.org. Copy the python.exe file to
some place in your Windows path, I usually use C:\WINDOWS) I now have
two new output files, hello.s and hello.bin. The first is the 6502
assembly code that is the application. It was generated by Python
running the spl.py program. The second is the binary data generated
by assembling hello.s using as6502. The as6502 program was called for
you by the Python program. This explains the lib directory. In there
you will find disp.s and cr.s files. These were simply appended to
the output file generated by spl.py so that the assembler would know
how to implement those words.
Now, we don't have to output only binary data, instead we can create a
disk image file for an emulator which has the binary data on it
already setup so that ProDOS will know it is a binary program. To do
that use a command line like:
python spl.py hello -o hello -t dsk
which will create a hello.dsk file. This is the 140k disk image
file. If loaded into an Apple II emulator, I usually use AppleWin, it
will be seen that there is a single file on the disk, A.OUT. This
file can be run using -A.OUT and we'll see "Hello world!" printed on
the screen.
To get the compiled program to an actual Apple II you can do one of
two things:
1. Send the hello.bin file over to the Apple II as a BIN file. Then
BLOAD hello.bin, A$900 where $900 is the ORG address used when
compiling (the default). Then BSAVE to a new file. This will then be
a file ProDOS can run.
or
2. Compile using the -t a2t option. This will make a text file
(hello.txt) that when transferred to the Apple II and EXEC-ed will
load the binary data into memory and BSAVE it as a binary program.
The second option is probably the easiest.
I hope this helps (?) Please ask is something doesn't make sense, I'm
sure it is just my poor explanation.
Ron
And a third option to get the "hello world" program to a real Apple II
is to use ADTPro to transfer the disk image to an Apple II and save it
as a real disk. I haven't been following this discussion very close
but from you post I take it your program only runs in either Linux or
Windows, so that those of us with Macs are unable to use it?
Dean
I have the impression that a Mac running OSX handles the SPL, Python,
and AS6502 portions fine.
~ J
Ron, makes perfect sense now... I just needed that extra mental
framework since I've not had exposure to Python or AS6502. I think
you should add your email to your manual.. would be a nice "tutorial"
addition.
Thank you very much for your carefully crafted reply.
~ J
A good idea. Thanks. I'll try to get an update on the website soon.
Ron
This is correct. Python runs wonderfully on Macs and the archive
includes (or, rather, should include) a precompiled as6502 for the
Macintosh (Intel Macs only since that's the only Mac I have). Python
runs everywhere, if you can get as6502.c compiled on your platform
then you can run SPL everywhere, too. As I said, as6502.c compiles as-
is on old VMS systems so I suspect it will work on most systems with a
C compiler.
Ron
Ron, I have an IMSAI 8080 with a working C compiler.. Do you know if
there is a CPM version of Python?
Just kidding. ;-)
Since I'm not familiar with Python, I'm curious what made you choose
it to develop "SPL" in instead of something like the C language?
Would be cool to know.
~ J
I can't speak for Ron, but programming in Python is fun. Compared to C it
is a very expressive language, and it is quite easy to read compared to
say, Perl.
--
-- Jerry
I'm with Jerry. Python is fun and simple to learn. Lists are nice,
too, plus automatic garbage collection, etc. The main reason, though,
was time. I knew if I started in C I'd likely as not never finish
because I'm getting too busy with other things, but if I used Python
it wouldn't take long.
My real goal with SPL, besides the fun of implementing it and putting
all the little assembly pieces together, is to write an SPL compiler
in SPL and thereby bootstrap it to run on a real Apple II directly.
Heaven knows when I'll get around to it, the idea for SPL floated
around in my head for several years before I did it, but eventually it
would be fun. I think if I port the assembly code to Merlin that it
wouldn't be too hard, really.
Ron