Jump to content
IGNORED

MiniMemory Loader Bug


senior_falcon

Recommended Posts

Over the past few days I have been working with PixelPedant, trying to use the routines in the "Text to Speech" disk in a compiled program. I found that  CALL INIT and CALL LOAD("DSK3.SPEAK") or CALL LOAD("DSK3.XLAT") will crash XB 2.9 G.E.M., although they load fine in standard XB. For XB 2.9 G.E.M. the crash happens from a write to >7FFE which selects a non-existant rom bank. XB 2.9 G.E.M. uses the MiniMemory loader adapted to the XB environment. Turns out that CALL INIT and CALL LOAD("DSK3.SPEAK") will crash MiniMemory BASIC as well. Below are a few lines of code from the MiniMem loader and below that is a screen from the Classic99 debugger. (This was done from MiniMemory BASIC) The breakpoint is the first time the loader came to >64B4. You can see the loop will continue until R9=0 which overwrites almost the entire ram.

 

A disassembly of the MiniMemory rom and the SPEAK file are included below. Can anyone shed some light as to:

What is it about the SPEAK and XLAT files that causes them to behave differently when loading from XB and MiniMemory?

Is there a fix for this?

 

(edit) I should add that E/A BASIC gives an "ILLEGAL TAG" error message when trying to load SPEAK, so there is yet another behavior. You can look at >8300 with the debugger and see that the pad is trashed by MiniMemory and XB 2.9 G.E.M.  when loading SPEAK. E/A does NOT trash the pad.

MINIMEMROM.txt

SPEAK

 

       MOV  6,9               shift symbol table to remove ref
       S    4,9               number of bytes to shift
       MOV  6,10              source=  undef label)
       AI   10,>0008          dest= next label upwards
       MOV  6,3               source ptr
A64B4  DECT 3
       DECT 10
       MOV  *3,*10            copy 1 word 8 bytes above
       DECT 9
A64BC  JNE  A64B4             more to do
       AI   4,>0008           adjust table bottom ptr
       MOV  4,@>701E          last free address

Classic99debugger.thumb.jpg.c019d970879c9ed8633e9408714f4a36.jpg

Edited by senior_falcon
  • Like 2
Link to comment
Share on other sites

Could be a timing issue:

[2888]               ***********************************************************
[2889]               * SPEAK will actually speak the speech list. It tests the
[2890]               * timing byte to see if it is an >FF. If it is, then the
[2891]               * data following it points to a direct speech data string
[2892]               * in VDP. If it is not, then the data following it points
[2893]               * to a PHROM speech data list. In the first case, this
[2894]               * routine will issue a speak external command to the PHROM
[2895]               * and then feed bytes out to the PHROM as it requests them.
[2896]               * In the second case, the address will be loaded out to the
[2897]               * PHROM, and then a speak command will be issued.
[2898]               ***********************************************************
[2899] B24C 06,B5,D1 SPEAK  CALL SETRW             Set read/write address
[2900] B24F C9,00,02 GB1CE  DCHE @PTLBSL,@PTFBSL   More speech list to go
[2901] B252 72,D9           BS   GB258
[2902] B254 06,B5,C6        CALL WAIT              Yes, wait until previous
[2903]               *                              speech is though
[2904] B257 D6,B0,00        CEQ  >FF,V*PTFBSL      External speech data
       B25A FF
[2905] B25B 72,7F           BS   GB1FE
[2906] B25D BC,79,B0        ST   V*PTFBSL,@TIMER   No, load timer
       B260 00
[2907] B261 82,79           NEG  @TIMER             and neg it to correct
[2908] B263 BD,12,E0        DST  V@1(@PTFBSL),@PTFBPH   Put addr into PTFBPH
       B266 01,00
[2909] B268 A3,00,00        DADD 3,@PTFBSL               and skip to next node
       B26B 03
[2910] B26C D2,79,00 LOOP1  CGE  0,@TIMER          Wait for time delay
[2911] B26F 52,6C           BR   LOOP1
[2912] B271 8E,12           CZ   @PTFBPH           If there is data
[2913] B273 72,7D           BS   GB1FC
[2914] B275 06,B5,6C        CALL LOADAD            Load the addr to PHROM

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0051 
RXB 2022
[2915] B278 BE,C0,00        ST   >50,@PAD(@WRITE)   and issue speak command
       B27B 5A,50
[2916] B27D 52,D6    GB1FC  BR   CONTIN
[2917] B27F 91,00    GB1FE  DINC @PTFBSL           Speak external, skip over >FF
[2918] B281 BD,5E,B0        DST  V*PTFBSL,@PTCBED  Set up pointer to 1st byte
       B284 00
[2919] B285 BD,5E,E0        DST  V@4(@PTCBED),@PTCBED    in external speech data
       B288 04,5E
[2920] B28A 95,00           DINCT @PTFBSL          Skip addr bytes
[2921] B28C BC,62,EF        ST   V@-1(@PTCBED),@LENWST  Get Len of whole string
       B28F FF,FF,5E
[2922] B292 A6,62,03 DIRSPH SUB  3,@LENWST         Minus 3 bytes overhead
[2923]               * All external speech strings start with a >60
[2924] B295 D6,B0,5E        CEQ  >60,V*PTCBED      Bad speech string
       B298 60
[2925] B299 4D,99           BR   ERRBV
[2926] B29B 06,B5,C6        CALL WAIT              Wait for go ahead
[2927] B29E 95,5E           DINCT @PTCBED          Skip spk ext & 1st byte len
[2928] B2A0 BC,60,B0        ST   V*PTCBED,@LENCST  Get len of current string
       B2A3 5E
[2929] B2A4 91,5E           DINC @PTCBED           Skip len byte to 1st real byt
[2930] B2A6 BE,56,10        ST   16,@TEMP2         Do 1st 16 bytes (fill buff)
[2931] B2A9 BE,C0,00        ST   >60,@PAD(@WRITE)  Start Speak External
       B2AC 5A,60
[2932] B2AE BC,C0,00 LOOPR  ST   V*PTCBED,@PAD(@WRITE) Write byte to PHROM
       B2B1 5A,B0,5E
[2933] B2B4 91,5E           DINC @PTCBED           Go to next byte
[2934] B2B6 92,62           DEC  @LENWST           1 less char in whole string
[2935] B2B8 72,D6           BS   CONTIN            Finished whole string?
[2936] B2BA 92,60           DEC  @LENCST           1 less char in curr string
[2937] B2BC 72,92           BS   DIRSPH            Finished current string?
[2938] B2BE 92,56           DEC  @TEMP2            1 less char in this loop
[2939] B2C0 52,AE           BR   LOOPR             Not finished curr loop yet?
[2940] B2C2 BC,69,C0 GB241  ST   @PAD(@READ),@SPKSTS Read status from PHROM
       B2C5 00,58
[2941]                
[2942]               * If the next statement is true, it means that speak was
[2943]               * probably interupted and that it is shot at this point.
[2944]               * Therefore, we are going to quit now.
[2945] B2C7 DA,69,80        CLOG >80,@SPKSTS
[2946] B2CA 72,D6           BS   CONTIN
[2947] B2CC DA,69,40        CLOG >40,@SPKSTS       Loop till buff below half
[2948] B2CF 72,C2           BS   GB241
[2949] B2D1 BE,56,08        ST   8,@TEMP2          Put 8 more bytes to PHROM
[2950] B2D4 52,AE           BR   LOOPR              and go do these
[2951] B2D6 05,B2,4F CONTIN B    GB1CE             We've said it all!!
[2952]               * Now pop all entries off stack that we put on!
[2953] B2D9 0F,78    GB258  XML  VPOP              Free up a temporary string
[2954] B2DB D5,6E,4C        DCEQ @FAC2,@VSPTR
[2955] B2DE 52,D9           BR   GB258
[2956] B2E0 4A,C0           BR   LNKRTN       

 

Link to comment
Share on other sites

CALL SAY and CALL SPGET along with CALL SOUND are the very largest GPL subroutines in XB.

And none of any of them are Assembly so cannot say why but it is a fact.

 

Never spent any time with GPL of the Mini Memory as Basic sucks compared to XB.

The debugger in Mini Memory is great but nothing else ever appealed to me.

Link to comment
Share on other sites

This bug has nothing to do with speech or GPL. The problem is simple:

CALL INIT then CALL LOAD("DSK3.SPEAK") is supposed to load an assembly object code file.

This works in TI Extended BASIC  (the loader is written in GPL)

Gives a "ILLEGAL TAG" error message in E/A BASIC  (loader written in assembly)

Goes into a black hole in cyberspace in MiniMemory BASIC  (loader written in assembly, but obviously not identical to the E/A loader)

What is it about the file that causes it to not work in E/A or MiniMem BASIC?

 

 

Link to comment
Share on other sites

On page 415 of the E/A manual is a list of the object tags in E/A and XB

The only one that matches this behavior is this:

Tag M  Data/Common Seg.   ignored in XB   Issues error in E/A

I'm guessing that is the problem and will experiment some more tonight.

Looks like the fix is simple - just amend the manual to reflect this behavior.

  • Like 4
Link to comment
Share on other sites

I have thought about adding Text to Speech into XB ROMS would name it CALL SPEECH("String to speak")

Of course it would require a buffer to be set up as a temporary file for XB to access and I could place it next

to XB VDP stack so less likely to be involved in Garbage Collection routine and could be closed with 

CALLL SPEECH(#?#)

Link to comment
Share on other sites

Using a hex editor I could look at the first line of SPEAK. Sure enough, the 14th byte is a M which is supposed to stand for Data/common seg. and that is ignored by XB and issues an error in the E/A loader.

The tag for Program ID is an I, and it should be ignored by both the XB and E/A loaders.  I was hoping that changing the M to an I would make the file loadable by both XB and E/A, and hopefully MiniMemory. But it just gives an "unrecognized character" message. Any ideas on how to change the first line so it will load all three ways?

FIRSTLINE.thumb.JPG.e5687e693d36fdee4c90047717fda1fc.JPG

 

In the disassembly of the MiniMemory ROM are these lines with the note that tags K to P branch to crazy locations!

A65F8  BYTE >2D               tag 0
       BYTE >5D,>5C           tag 1+2
       BYTE >6E,>6F           tag 3+4
       BYTE >A3,>A4           tag 5+6
       BYTE >60,>04           tag 7+8
       BYTE >67,>66           tag 9+A
       BYTE >6A,>69           tag B+C
       BYTE >CF,>CF           tag D+E  error 10
       BYTE >03               tag F
       BYTE >CF,>CF           tag G+H  error 10
       BYTE >52               tag I    skip 8 chars
       BYTE >00               tag J    tag in data word
*                             tags K to P branch to crazy locations!
*

 

 

 

Link to comment
Share on other sites

Maybe the trick is not to patch it, but just resave it?

 

According to my notes, SPEAK loads at >24F4 (reserving workspace there), and are >06D4 bytes (ending at >2BC7).

 

Classic99 can save memory as EA#3 uncompressed, which XB loaders are supposed to be too, but in this case only the absolute data tags will be used.

 

This does have the small problem that no memory will be reserved/allocated/marked used when loading... but it's probably easier to patch this one with the much simpler header. This also DOES NOT set up the Ref/Def table, since it's just a memory dump. Guess it depends on the use whether it's useful.

 

In fact, to keep it simple, I saved SPEAK, XLAT and SETUP all in one file here:

 

SPEAK - 24F4 to 2BC7

XLAT - 2BC8 to 33B1

SETUP - 33B2 to 3683

 

Then I saved off the database - this means that SETUP doesn't need to work or be called.

 

I manually added the ref/defs to the end.

 

XLAT -> 2BE8

SPEAK -> 2514

 

There is still the problem of the XB utils... my notes say that these are used:

SPEAK:

ERR (BLWP @>2034) - 25C8

STRREF (BLWP @>2014) - 253E

NUMREF (BLWP @>200C) (twice) - 2556 and 256A

XMLLNK (BLWP @>2018 - DATA >12B8) (twice) - 255A and 256E

- my notes say >1200 is float to int and I wasn't sure about the B8 part, but it clearly wants float to int.

 

XLAT:

ERR (BLWP @>2034) (twice) - 2BFC and 2C3C

STRREF (BLWP @>2014) - 2C16

STRASG (BLWP @>2010) - 2C56

 

So, that's only 10 points that need to be patched up. You could hard-code the changes for the MiniMem or E/A entry points, or change them to proper refs. Might work?

 

Maybe I'm off base, I dunno. Fun to look at for a moment.

 

SPEAKV2.zip

  • Like 3
Link to comment
Share on other sites

To test that SPEAK, XLAT, and ALPHON, were truly relocatable, I readjusted the FIRST/LAST free memory pointers at >2002, >2004, before loading them individually. They seemed to run fine from >D000+.

 

   P.S. NUMREF, seems to be misreferenced on E/A, page 416, >2000 is the XML vector to XB's, DEF TABLE, parser. I believe that NUMREF should be called from >200C.

  • Like 2
Link to comment
Share on other sites

2 hours ago, HOME AUTOMATION said:

P.S. NUMREF, seems to be misreferenced on E/A, page 416, >2000 is the XML vector to XB's, DEF TABLE, parser. I believe that NUMREF should be called from >200C.

 

Yes. That is, indeed, an error in the E/A manual. >200C it is.

 

...lee

  • Like 3
Link to comment
Share on other sites

My first guess from the assembly was that R4 and R6 were garbage. Also XB doesn’t use REF so this should never come up. 

 

If R4 is supposed to be the last free address (that is, start of the ref table) it is garbage >0180. 
 

R6 is supposed to point to the REF to be removed but it’s 0. 

So I guess that that M tag branches to a weird location and R4 and 6 are not valid so it fails. 
 

I would remove the M tag by deleting the M and the 4 hex chars after. At the end of the line, you may have to fix up the 7 tag, checksum, by changing it to 8, ignore checksum. (7 to 8 is what you do when you edit any line.)

 

M is not supposed to be in 4A object files! You can’t assemble a  PSEG or CSEG directive in ASSM1.   You need an assembler like SDSMAC on a 990/12 (or /10 with memory mapping upgrade).

 

Curious, what is the last line of the object file? It should tell the name of the assembler!  I think E/A files say 99/4 A/S or something.

 

Many speech files that I have looked at say SDSMAC, indicating they were produced on a 990. 

 

In 990 o/s DX10 or DNOS,  a program gets 64K of its own address space. This is divided into 3 segments , which can map anywhere in 1 Meg system RAM.  The LMF instruction sets up the address and size of the 3 segments. 

 

One way to use 3 segments is to have:

 

1. PSEG:  Program segment (shared if possible, plus it hangs around in case you run the program again.) (PSEG) Marked read-only but executable. 

    optionally? loadable from object file:

    CSEG:  Common program segment. Relocatable code just like PSEG, but identified by a different label and I think linkable separately from outside.

 

2. DSEG: Data constants, text, etc.  (Not sure if this intended to be read-only? but no-execute. I'm not sure if this is shared.)

 

3. User RAM.  Stack, heap, and so on.  The program might make a SVC call (defined with DXOP as XOP 15) that asks  the OS to extend this RAM boundary (until the 64K is full.) Obviously, allows read and write by the program. 


I’ve never programmed in that environment, so my book-learning could be wrong. 
 

Anyhow that’s where I believe the M would come from. I guess it’s really a no-op on the 4A because code and data are treated the same. 

 
Conceivably, a PSEG might go in a separate address space altogether—Harvard architecture—from which instructions are always fetched, but not data. So PSEG could be 64K, and CSEG + user RAM could have 64K. The 99000 facilitated this. 
 

The 9900 is not Harvard— it’s plain old Von Neumann or MIT architecture, where code and data are treated the same. (You can have self-modifying code or use code as data.. both illegal at Harvard.) 

  • Like 2
Link to comment
Share on other sites

10 hours ago, FarmerPotato said:

I would remove the M tag by deleting the M and the 4 hex chars after. At the end of the line, you may have to fix up the 7 tag, checksum, by changing it to 8, ignore checksum. (7 to 8 is what you do when you edit any line.)

 

M is not supposed to be in 4A object files! You can’t assemble a  PSEG or CSEG directive in ASSM1.  

Thanks for the advice. I tried that a couple different ways - by deleting those 5 characters and by spacing over the characters. Changed 7 to 8 and get I/O error 2 when I try to load.

This was in standard XB, so I didn't even try it in MiniMemory or XB 2.9 G.E.M.

It is odd that those unuseable directives are even mentioned!

The assembler is not identified as far as I can tell. You can look at SPEAK with a hex editor if you are curious.

Edited by senior_falcon
  • Like 1
Link to comment
Share on other sites

23 hours ago, senior_falcon said:

Thanks for the advice. I tried that a couple different ways - by deleting those 5 characters and by spacing over the characters. Changed 7 to 8 and get I/O error 2 when I try to load.

This was in standard XB, so I didn't even try it in MiniMemory or XB 2.9 G.E.M.

It is odd that those unuseable directives are even mentioned!

The assembler is not identified as far as I can tell. You can look at SPEAK with a hex editor if you are curious.

 

I found the syntax for M in the TXDS Link Editor Manual.  TXDS is an operating system for 990/4 or /10 but SDSLNK was probably common to others.

M has 2 arguments.

 

TAG	FIELD1                FIELD2            FIELD3
0 	PSEG length           Program ID (8)    -
M	DSEG length           $DATA             0000
M	Blank CSEG length     $BLANK            0001
M	CSEG Length           Common Name(6)    Common #
M	CBSEG Length          $CBSEG            CBSEG#

Here is the weird tag in the SPEAK object:

M0000$DATA 0000

Did you remove all of that, up to the 7 (checksum tag)? I guess the 7F954F could be replaced with just F (the end of record tag)

 

The last line, after the DEF table, names the TI Link Editor SDSLNK:

SPKL0057      02/24/82  10:34:27    SDSLNK        3.4.0   

 

  • Like 1
Link to comment
Share on other sites

8 hours ago, FarmerPotato said:

Did you remove all of that, up to the 7 (checksum tag)? I guess the 7F954F could be replaced with just F (the end of record tag)

 

Both ways did the trick. I removed up the the checksum tag and changed that to 8 and it works fine. Then I tried taking out everything up to the F and that also worked.

Thank you very much!

  • Like 3
Link to comment
Share on other sites

That should work…

 

The F means end of line. You can delete from M all the way to the end, and have one Final F. As if the M was never there. 
 

Also the 0000 after the M means empty… so I guess SDSLNK is pedantic. 
 

I love finding out these things. It’s like etymology or history, as our 4A world came out of 990 land, a bigger, older place.

 

 I don’t think any other home computer got a heritage like that? The PC purposely broke away from all prior IBM hardware and software. 
 

Imagine if DEC had made a Rainbow home computer? (not just their 8088 DEC Rainbow 100 PC).
 

I’m imagining a LSI-11 CPU in a console. A home version of a DEC PDP-11, much like we got a home 9900, a minicomputer on a chip.

 

 That LSI-11 would have been a fun machine if it’s ecosystem had a derivative of one of the smaller PDP-11 operating systems. All those LISP programmers taking time off to write games for it!
 

My brief experience programming the PDP-11 was a joy even though the tools were primitive. 

 

(ED—Line by line editor—AS the assembler—that was it.)  I edited on the 4A, then uploaded PDP-11 assembly source using Telco into ED!)

 

The PDP-11 (hence LSI-11) machine language, being 16-bit, was sweet and a lot like 9900.  I don’t know what O/S it was (rebranded by Kaman Sciences as KIS) maybe one of the small multi terminal ones like RSX-11? It had system calls for everything, which I saw similar in CP/M and MS-DOS. 
 

I learned its  disk file structures: they were multi level B trees of sector numbers. So a sector could be deleted or inserted in the middle, or file sorted! I disassembled the serial interrupt handler (a ring buffer.) 

 

If DEC had made a LSI-11 home computer, I would have been doing that in front of a TV. 
 

Don’t mention  VMS. It could have run Unix! (It’s source  for Unix v.6 you can read on the web.)
 

OK digression over. this is a text-to-speech thread. 

 

 

 

 

 


 

 

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...