                       A PATCH OF A PATCH

                        by Nate Salsbury
                     610 Madam Moore's Lane
                New Bern, North Carolina  25860


        In the October, 1981 edition of '80 Microcomputing', an
article by Arne Rhode (Pilevej 31, 7600 Struer, Denmark)
outlined a program to transfer EDTASM-Plus (by Microsoft) from
its Model I cassette version to a Model I disk environment.
You could then load in your cassette source programs and store
them to and retrieve them from disk.  Also, new source could be
saved/retrieved from disk.  I had (then) recently moved from a
cassette Model I to a 2-disk Model III and was VERY anxious to
salvage my miles of tapes and months of typing source text.  I
blithely followed Arne's excellent instructions on how to
proceed.
        After successfully getting my Model I (cassette) EA+ on
to my Model III disk, I happily started to 'salvage' my first
Model I tape.  All went smoothly until the LAST BYTE and then
the keyboard locked up and the screen jittered around with some
miscellaneous garbage on it!  After some excellent hints from
Jack Decker and Bruce Hansen, I finally traced the source of my
problem and evolved this Patch of a Patch (lines 2000 to 2560
of this listing).  The difficulty came about because of the
different cassette routines in the Model III ROM - in
particular 235H (read a byte) and 1F8H (turn off cassette).  A
brief review of my findings and 'fix' follow.
        After EA+ finishes its initialization, it jumps to a
routine starting at 44CCH.  The first four lines here read:

44CCH   LD      SP,4380H
44CFH   CALL    01F8H           ;Turn off cassette
44D2H   LD      BC,44CCH
44D5H   PUSH    BC

        This reveals two points: (1) The 'final' RET address on
the stack is 44CCH and (2) the first action after getting there
is to 'turn off the cassette' - in other words, this is always
the first thing EA+ does when it recycles to 44CCH to await
your next command.  I was finally led to tracing out the 01F8H
routine in ROM.
        At 01F8H there is a jump to 300CH and from there a jump
to 31C0H where the routine really starts.  The first two
instructions seem to create most of the problem:

31C0H   LD      A,(4213H)       ;Normally with TRSDOS => 04H
31C3H   OUT     (0E0),A

followed by some routine housekeeping and, finally, at 31CFH: 
31CFH   EI                      ;Enable interrupts
31D0H   RET

         To this day, I'm not sure WHY that OUT (0E0H),A at
31C3H caused my problem (along with the EI at 31CFH).  However,
those two WERE the cause so I fixed them.  I also found that
EA+ also used the byte at 4213H (which distressed BASIC) so I
had to work out a "time sharing" arrangement.
        I will not describe any aspect of Arne Rhode's original
patch since this was covered thoroughly in the referenced "80
Microcomputing" article.  The reader is advised to review that
text.  It will cover this listing through line 1840 (I have
made several modest changes to fit my EA+ version 1.07.  More
on that later.  Also, my line numbers differ from the article
but the instructions are the same).
        My patch accomplishes two main purposes: (1) Save the
byte at 4213H under EA+ and give it back to BASIC at the
appropriate times and (2) DISable interrupts after every call
to the 1F8H routine.  Along the way, I added a third item which
was to return to the EA+ '*' prompt after using BREAK to stop a
cassette load (rather than return to BASIC).  Please note that
my references to EA+ addresses refer to my version, 1.07.  If
you have a different version, the addresses you use may vary
slightly but they SHOULD be close to those I cite here (e.g.
note the difference in my ORG 6486H and Arne's article which
ORGs at 646CH).
        When EDTASM starts to Load a source tape, we get the
READY CASSETTE prompt.  In version 1.07 this is accomplished by
a CALL 4408H instruction.  To find your equivalent, disassemble
the Command Jump table (in version 1.07 this lies between 4659H
and 469AH).  Find the ASCII 'L' and then disassemble EA+ at the
address pointed at by the two bytes immediately following the
'L'.  In Version 1.07 that was 4D0EH.  Here I found the
following code:

4D0EH   CALL    4FB1H           ;Of no concern here
4D11H   LD      E,0D3H          ;Identifying byte at the start
                                ;  of an EDTASM source file
4D13H   CALL    4FFEH           ;Finds the start of your
source
                                ;  file

At 4FFEH I found:

4FFEH   CALL    4408H

Disassembly of the 4408H routine showed that THIS was the
routine which puts READY CASSETTE on the screen.  Since this is
just before we fire up the cassette, I used TASMON to search
EA+ and Z-BUG for similar calls and discovered them at 4FFEH
(as noted) and also at 4FD4H.  At these two spots I replaced
4408H with the address of my CASSON label (see line 2000).
There, I call the routine to print READY CASSETTE, set the
cassette speed to 'L', change the BREAK vector to EDTASM's warm
start, and replace the byte in register E (0D3H - the first
byte of a source tape which was in E when EA+ gets to CASSON).
Then, it's back to EA+ for continuation of source tape
loading.
        Since I wanted to fiddle with the "cassette off"
routine at 1F8H, I also searched EA+ and Z-BUG for CALL 1F8H
and found it (in version 1.07) at 44CFH, 4D1FH, 650DH and 71C6H
(the last two are in Z-BUG).  I replaced the CALL 1F8H at each
location with a CALL to my CASOFF address (line 2260).  Here, I
save the byte at 4213H which 'belongs' to EA+, and replace it
with the 04H byte which is normally found at that address by
the ROM routine.  Then, after a CALL 1F8H to turn off the
cassette, I immediately DISable the interrupts again, restore
the usual BREAK vector and get back to EA+ for whatever.
        This patch allowed me to salvage all those Model I
source tapes and get them on to my disk.  Let me hasten to warn
any reader that I found that SOMETIMES, the 'Find a String'
routine of EA+ would NOT work properly.  I cannot guarantee
that everything else is OK because shortly after doing this, I
became interested in other work and, eventually, got the Model
III disk version of EA+ and discontinued the project.  However,
for my purposes, the major task of salvage had been
accomplished.  I was subsequently able to transfer these files
over to my 'new' EA+ and that's what I started out to do.
        Several comments are appropriate here regarding this
patch.  Of necessity I had to add it at the end of Arne Rhode's
program so that source texts would not overwrite the patch.
This, in turn, required a modification to his EQU for BFSTAD
(at line 140 of his listing in the original article.  It is
line 470 in this listing).  The value you want there is the
location shown in line 2520 of this listing PLUS 0E80H - the
amount of the offset from 4380H to 5200H (Note: Arne suggests
saving everything from 4000H up - if you follow that path you
will have to add 1200H instead of 0E80H).  Since different
versions of EA+ apparently differ in length, you'll have to
experiment to determine where to locate your version of my
patch.
        A final note on Arne Rhode's article - I found it
necessary to insert line 1630 XOR A (to clear the carry flag).
Because of differences in my version of EA+, I started the
routine shown in his lines 1200-1260 at 7330H.  My lines 1790 -
1820 calculate the length of the program to be moved and then
relocates it to its normal position.  Since EA+ clobbers DOS, I
saw no point in saving RAM from 4000H to 437FH.  This has two
benefits: (1) The transferred source text (when you save to
disk) can be located lower in RAM, thus allowing longer
assemblies and (2) Less disk space is used.  With this
background, my TRANSFER address of the LOAD module of my source
text is 7330H + (5200H - 4380H) = 81B0H (see lines 1390 -
1420).
        I also had to change EA+ at 4389H and 438FH where it
CALLs 0215H.  I changed these to 'CALL 0212H' and that was the
final touch.  Since my interest was to salvage my old cassette
source tapes (but NOT to create new ones) I never explored my
revised setup's ability to write source text to tape (since it
could now store it on disk).  Also, I did not do Stand Alone
Z-BUG because TASMON does all the same things and much more.
However, the procedure would be similar once you locate Z-BUG's
command jump table.  In my version of Stand Alone Z-BUG , this
is located from 4FEBH to 501AH with the "L" command located at
500FH.
        One last note: EA+ replaces the RST 20, 28 and 30
instructions with its own routines.  Don't try to use Z-BUG on
programs that use any of these three RST instructions - either
directly or via ROM routines - not unless you enjoy reading
your "XYZ DOS READY" message lots of times!
        I wish to thank Jack Decker and Bruce Hansen for their
extensive time with me on the telephone as I bumbled about
trying to unravel this mystery.  This article could not have
been written without their comments and suggestions which
finally pointed me to the solution.  My other silent
co-contributor was my monitor, TASMON.  It even allowed me to
single-step the ROM routines!
 