Sept 2007, Udo Munk posted this about BASIC-E:

Newsgroups: comp.os.cpm
Date: Fri, 21 Sep 2007 21:17:32 +0200
Subject: BASIC-E

On CPMUG disk volumes 29 & 30 you'll find the sources for Gordon
Eubanks
BASIC-E compiler from 1976, which was modified later by Gary Kildall.

There are no instructions about how to build compiler and runtime from
the
sources and the precompiled binaries are for crap. I've created
submit
scripts to rebuild the compiler and runtime from the sources using my
ISIS tool disks. I also added a bunch of BASIC programs from the
CPMUG
volumes to play with.

A harddisk image with sources, executables and examples is available
at:
http://www.unix4fun.org/z80pack/

Enjoy,
Udo Munk
--

I had a follow up discussion with him on understanding the Basic-E
further, and am posting it here in case anyone is interested.


> Hi Udo,
>
> Your post on Basic-E piqued my interest to learn about ISIS, PLM,
> and BASIC-E...but I do not have a Unix system. I do have DOS,
> though, and am IMSAI running CP/M. So I located CPMUG vols 29+30 and
> unARKed them ok, as well as a DOS PLM compiler w/ ISIS emulator.
>
> Would you be so kind and willing as to email me the submit scripts
> you came up with to recompile BASIC.COM and RUN.COM? js@cimmeri.com
>
> Thanks very much,
> ~ J


No UNIX system required, just anything that runs CP/M 2.2 will do.
I use UNIX systems to emulate a Z80 system with enough I/O
hardware, so that it can run all the old DRI programs. I don't
have any of the old 8080/Z80 hardware anymore and an emulation is
good enough to run all the old programs.

Here are the submit scripts I used to build the programs from source
on my emulated CP/M system:

--- start basic1.sub ---
pip d:=i:bascom.lit
fixeof d:bascom.lit
pip d:=i:basic.plm
fixeof d:basic.plm
pip d:=i:baspar.plm
fixeof d:baspar.plm
pip d:=i:bassyn.plm
fixeof d:bassyn.plm
isx
:f1lm80 :f3:basic.plm
era :f3:basic.lst
era :f3:basic.plm
:f1lm80 :f3:baspar.plm
era :f3:baspar.lst
era :f3:baspar.plm
:f1lm80 :f3:bassyn.plm
era :f3:bassyn.lst
era :f3:bassyn.plm
:f0:link :f3:basic.obj,:f3:baspar.obj,:f3:bassyn.obj,:f1lm80.lib
to :f3:basic.mod
:f0:locate :f3:basic.mod code(0100H) stacksize(100)
:f0:cpm
objcpm d:basic
era d:*.obj
era d:basic.mod
era d:basic
era d:basic.sym
era d:basic.lin
era d:bascom.lit
--- end basic1.sub ---

--- start basic2.sub ---
xsub
d:
a:ddt basic.com
a100
jmp 1514
..
a29d
jmp 5
..
a2a9
jmp 5
..
g0
save 48 basic.com
a:
--- end basic2.sub ---

--- start run1.sub ---
pip d:f1.src=i:fpint.src
pip d:f2.src=i:fppkg.src
pip d:f3.src=i:tran.src
pip d:f4.src=i:fpconv.src
pip d:f5.src=i:fpdata.src
pip d:b.plm=i:build.plm
fixeof d:b.plm
pip d:r.plm=i:run.plm
fixeof d:r.plm
isx
:f0:asm80 :f3:f1.src
era :f3:f1.lst
era :f3:f1.src
:f0:asm80 :f3:f2.src
era :f3:f2.lst
era :f3:f2.src
:f0:asm80 :f3:f3.src
era :f3:f3.lst
era :f3:f3.src
:f0:asm80 :f3:f4.src
era :f3:f4.lst
era :f3:f4.src
:f0:asm80 :f3:f5.src
era :f3:f5.lst
era :f3:f5.src
:f1lm80 :f3:b.plm
era :f3:b.lst
era :f3:b.plm
:f1lm80 :f3:r.plm
era :f3:r.lst
era :f3:r.plm
:f0:link :f3:f1.obj,:f3:f2.obj,:f3:f3.obj,:f3:f4.obj,:f3:f5 .obj,:f3:r.obj,:f3:b.obj,:f1lm80.lib
to :f3:run.mod
:f0:locate :f3:run.mod code(0100H) stacksize(0400H)
:f0:cpm
objcpm d:run
era d:*.obj
era d:run.mod
era d:run
era d:run.sym
era d:run.lin
--- end run1.sub ---

--- start run2.sub ---
xsub
d:
a:ddt run.com
a100
jmp 2855
jmp 0baf
..
s106
00
32
..
g0
save 49 run.com
a:
--- end run2.sub ---

=======================================

>> I had first tried to use "MyZ80" w/ one of your hard disk archive .dsk
>> files "basice.dsk.
>> I could get a directory, but if I for instance TYPEd out one of the
>> files, it contained the wrong data. Looked like a sector interleave
>> problem. So I located a DOS ISIS emu and the original CPMUG files.


The size of the MyZ80 hard disk drives is 8MB, while I use 4MB - 1
track
drives. Probably the skew (sector interleave) is different too, so the
disks can't be exchanged.

=======================================

>>> >:f0:cpm
>>> >objcpm d:basic


>> *What does "OBJCPM" do exactly?


The ISIS PL/M development tools will build programs to be run under
ISIS
and the excutables have a header. objcmp converts the located binary
into
a .com file, that can be excuted under CP/M.

=======================================

>>> >--- start basic2.sub ---
>>> >xsub
>>> >d:
>>> >a:ddt basic.com
>>> >a100
>>> >jmp 1514
>>> >.
>>> >a29d
>>> >jmp 5
>>> >.
>>> >a2a9
>>> >jmp 5
>>> >.
>>> >g0
>>> >save 48 basic.com
>>> >a:
>>> >--- end basic2.sub ---


>> *I thought these to be your cleverest modifications, and I have no idea
>> how you figured them out. But how come they are necessary? Is it
>> because ISIS produces programs only to run on itself, and these mods are
>> required to convert from the ISIS environment to the CPM one?


This software was written in 1975 and relocatable object files for the
8080
weren't invented yet. Assemblers and compilers could read a single
source file
and build an Intel hex file. No externals, no modules, no nothing. So
for
non trivial programs, like this BASIC compiler/runtime, one would
write
separate programs, locate them at different addresses and patch entry
points to the other model with a debugger afterwards. This might sound
bad,
but it's not that bad as one might think. Look at basic.plm e.g.:

MON1: PROCEDURE(F,A);
DECLARE F BYTE, A ADDRESS;
/* PATCHED WITH JMP 0005 */
L: GO TO L;
END MON1;

Either the compiler used at that time couldn't do a GO TO
,
or Eubanks
just didn't know that a GO TO 5 would be possible too. So he used an
endless
loop which is easy to locate, and later patched it with JMP 5. If you
carfully
study the sources, you can figure it out.

Of couse this could be done different with the ISIS PL/M compiler, it
has
externals, it produces relocatable objects which can be linked
together and
all that. I just left the sources as they are, so that people nowadays
will be able to learn how to program such stuff without a linker ;-)

>> Ok, now I finally understand about those JMP 5 statements! But, what
>> explains your *a100, jmp 1514 *modification?


DECLARE JMPTOMAIN (3) BYTE DATA(0C3H,0,0); /* FILLED WITH DDT */

This is the first statement in basic.plm at 0100H, a 8080 jmp
instruction and the address of the module needs to be patched
in with ddt, because the compiler used didn't support external
entries in other modules.

>> *ok, I understand now... this declare statement is just making room for
>> your jump to the main loop of code actually residing in BASPAR.PLM.


Correct. All the other patch work in the submit scripts is similiar
and the places to patch are commented in the sources. With help of
a symbol table from the ISIS locator and ddt it is easy to find the
values that needs to be patched.

Udo Munk

=======================================