Jump to content
IGNORED

GPL Development


Davvel

Recommended Posts

As promised, today I am submitting my first tool for the "ATARI AGE" members who would like to have an easier way to compose 3 channel (no noise for now) music sequences for the TI 99/4A using a familiar interface. I opted to use Excel as the input medium as nothing beats the ease of use of Excel to input a lot of data and moving it around as required. Once all the notes are fed in the SCORE sheet, just click on Generate code and you will end up with a GPL program ready to be compiled using XGA99. One can utilise the sound list data bytes for assembly too by deleting the GPL Header and Footer templates in the TEMPLATE sheet in this same Excel.

 

I urge you to look at the Sheet called "DEMO EXPLAINED" to appreciate the power of the tool and how easy it is to create a sound list data block which can be inserted in your games.

 

I have protected some cells of the Excel Sheet to ensure no one overwrites the formulas by accident.

 

Instructions:

1. Feed in Musical Score in the sheet called SCORE (Delete the demo data first by clicking on CLEAR ALL)

2. Click on GENERATE CODE

3. Switch to the OUTPUT sheet

4. Copy the content of the green code cell to notepad++

5. Remove the 2 extra quotation marks that are delimiting the entire code block.

6. Compile using XGA99

7. Enjoy your TI GPL music using Classic 99 (see previous posts in this thread on how to compile and run GPL code)

 

TIMUSICGenerator.zip

Edited by Davvel
  • Like 5
Link to comment
Share on other sites

Ralphb, kindly note that when using XGA99 and you accidentally have a duplicate label it would give you "Too many assembly passes" with no indication to why and where in the code caused this.

 

Is there an easy way to identify the offending label that is causing this? Please remember that as long as the GPL program is small, finding the issue is manageable but when the program grows it may take quite some time to find what is causing the error.

 

Thanks for your support.

 

David

Link to comment
Share on other sites

Ha, that's actually quite a funny bug. It's been fixed on GitHub now, though.

 

Most compilers and assemblers are multi-pass, i.e., they read the source code multiple times before generating code. The reason is quite simple: If you have a forward reference, e.g.,

.

      ...
      JMP  NEXT    <---- where is NEXT?
      ...
NEXT  CLR  R0

.

then you cannot create code for a jump to a location you haven't seen yet.

 

The xas99 assembler is two-pass: The first pass reads the source code to find values for all symbols, and then the second pass generates code, substituting the previously found values for all symbols as it goes along.

 

Interestingly, a two-pass assembler won't do for GPL. GPL has many different addressing modes for RAM, GROM, VDP RAM, and VDP registers. To save space, the language encodes addresses in 1, 2, or 3 bytes, depending on the value of the address. All ROM/RAM addresses are encoded relative to >8300, and the farther away an address is from >8300, the more bytes it takes to encode it.

 

For example, in the instruction ST 1,@>8300, GPL encodes the @>8300 as @>00, but would encode @>8380 as @>0080 and @>9000 as @>0F1000.

 

So if you have code like

.

.ST 1,@ADDR

.

then the compiler needs the second pass before it can generate the code for this instruction. Now look at this program (from the xga99 test suite):

.

S1   ST  1,@CPU1
S2   ST  2,@CPU2
S3   ST  3,@CPU3

EXIT

CPU1 EQU >837F
CPU2 EQU >837F+S2-S1-3
CPU3 EQU >837F+S3-S1-3-3

.

The values of Sx and CPUx depend on each other, and since all CPUx values are just slightly below >8380, their encoding might be 1 or 2 bytes, depending on the size of each Sx instruction above.

 

The first pass defines all symbols, but the second pass will move S2 and S3 as the argument of S1 has changed. Consequently, the values of CPUx will also change. In other words. the code after pass 2 is still "unstable", and thus not correct. So the GPL assembler needs another pass. This time, S3 is moved, as the argument of S2 has changed. Only in the fourth pass do all symbols remain stable, and we're done.

 

xga99 has an upper limit of 32 passes, which is arbitrary, but 32 passes should be enough for anybody.

 

But now back to the label bug: Because of some incorrect duplicate label check, the statement with the duplicate label changed the value of that label symbol twice per pass. xga99 correctly thought that some symbol is still unstable and triggered another pass, until we hit the 32 limit.

 

So when I heard your error description, I knew immediately what went wrong. :)

  • Like 1
Link to comment
Share on other sites

ralphb, Can you kindly indicate what is the expected result of an SRL 0,@>8300 ?

 

Good question. The GPL spec doesn't state what happens for a shift value of 0. But if GPL is like assembly then shifting by 0 actually means shifting by 16 -- which would shift all the bits away.

 

Now GPL is 8-bit only, so it makes only half sense ... Why don't you try SRA 0,@>8300, where the original value of >8300 is >80? If the assembly theory is correct, you should get >FF afterwards.

 

EDIT: I just remembered: In assembly, shifting by 0 means shifting by R0, and if THAT is 0, then you shift by 16. So it only makes quarter sense for GPL now.

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

ralphb, Thanks for your patience to answer my questions. I really appreciate your time.

 

What I was after was a simple first pass check to see if someone typed 2 or more labels which are identical, this would throw an exception example : XGA99 Duplicate Label found "START".

Link to comment
Share on other sites

What I was after was a simple first pass check to see if someone typed 2 or more labels which are identical, this would throw an exception example : XGA99 Duplicate Label found "START".

 

Yes, the latest fix does just that. You can get the file from GitHub via the link above.

  • Like 1
Link to comment
Share on other sites

ralphb, Can you kindly indicate what is the expected result of an SRL 0,@>8300 ?

 

I thought it would be ignored, but in fact it clears the content of >8300.

 

Good question. The GPL spec doesn't state what happens for a shift value of 0. But if GPL is like assembly then shifting by 0 actually means shifting by 16 -- which would shift all the bits away.

 

Now GPL is 8-bit only, so it makes only half sense ... Why don't you try SRA 0,@>8300, where the original value of >8300 is >80? If the assembly theory is correct, you should get >FF afterwards.

 

EDIT: I just remembered: In assembly, shifting by 0 means shifting by R0, and if THAT is 0, then you shift by 16. So it only makes quarter sense for GPL now.

 

After a careful look at the ALC for the GPL SRL and SRA instructions in the GPL Interpreter (Heiner Martin's disassembly listing of the TI-99/4A console ROM), I can say with confidence that the GPL SRL and SRA behave exactly like the ALC SRL and SRA, respectively, except that they are byte operations, of course.

 

For all of the GPL shift instructions, the number to be shifted (destination operand) is first read into R0. For a byte operation, the byte is right-shifted with an ALC "SRA R0,8" to preserve the sign bit before it is copied to R2. For the GPL SRL instruction, after the number of bits to shift is put into the LSB of R0, the MSB of R2 is cleared with an ALC "SB R2,R2" to insure that zeroes are shifted into the LSB from the left.

 

The shift is performed with an ALC "SRL R2,0", which uses the rightmost nybble (four bits) of R0 to get the number of bits to shift right. Any shift > 7 will result in clearing the byte. Shift = 0 will use a shift = 16, as noted by @ralphb, which, of course, also clears the byte. The shifted result is then copied from R2 to the destination byte.

 

The GPL SRA instruction is set up just as for SRL except that the MSB of R2 is not cleared so as to maintain the sign bit already filling the MSB. The shift is performed by an ALC "SRA R2,0". And, yes, "SRA 0,@>8300" should transform >80 into >FF.

 

...lee

  • Like 2
Link to comment
Share on other sites

Well SRL is a byte command, DSRL is a word command.

All commands in GPL that have no D in front are byte commands in GPL. i.e. DSRL or DSRA

So SRL @>8300,0 as there are only 8 bits in a byte I think what happens is it decrements the value from 0 to F and repeats till it reaches 0 again. (Just a guess of the results)

This might explain the results you get. Has anyone tried this with the RYTE DATA GPL Assembler yet?

 

Aso the TI Intern has the commands backwards compared to the TI GPL manual and RYTE DATA GPL Assembler as TI Intern swaps the location and value spots.

i.e. Ti Intern SRL 0,@>8300 while TI GPL Manual shows SRL @>8300,0

 

Also GPL has SRC (Shift Right Circular) or DSRC (Double Shift Right Circular) and there is no SLC or DSLC command. (A very useful command in GPL)

 

Will have to check if the GPL Assembler I use says that 0 is a invalid data for a SRL or SRA or SLL or SLA command, would also have to check D commands for words.

The RYTE DATA GPL Assembler does 16 passes with a value of PF (Passes 16) but is really a endless pass GPL Assembler.

Edited by RXB
Link to comment
Share on other sites

So SRL @>8300,0 as there are only 8 bits in a byte I think what happens is it decrements the value from 0 to F and repeats till it reaches 0 again. (Just a guess of the results)

 

You don't need to guess. In my last post, I explained what the GPL Interpreter actually does: It converts the operation to a TMS9900 ALC (Assembly Language Code) word (double-byte) operation with the shift in R0 and the data to be shifted in R2:

 

SRL R2,0

 

The '0' shift signals the TMS9900 to use the LSN (Least Significant Nybble = 4 bits) of R0 for the actual shift. Regardless of the actual value in R0, the shift will always be limited to 1 – 16, with LSN = 0 signalling a shift of 16. I do not know how the various GPL Assemblers limit what GPL code is emitted; but, the GPL Interpreter will handle a shift of—say, 127—just fine. The LSN of 127 is 15.

 

Aso the TI Intern has the commands backwards compared to the TI GPL manual and RYTE DATA GPL Assembler as TI Intern swaps the location and value spots.

i.e. Ti Intern SRL 0,@>8300 while TI GPL Manual shows SRL @>8300,0

 

Actually, in his description of GPL, Heiner Martin shows source and destination operands in the same order as the TI manual. It is the GROM listings that are backwards, which he explains and so warns the reader on page 80 of his TI99/4A INTERN:

 

The GROM listings have been worked out with the GPL disassembler.
The disassembler chose the source operand and the destination
operand in reverse order from what has been used in the following
explanations to the GPL commands. Please pay attention when
reading the GROM listing.
The disassembler's order likely reflects the actual byte-code of GPL, which has the destination operand first. It was probably easier to write the disassembler this way. Ralph (@ralphb) surely has some insight here.

Also GPL has SRC (Shift Right Circular) or DSRC (Double Shift Right Circular) and there is no SLC or DSLC command. (A very useful command in GPL)

 

Well, there is no SLC in ALC, either. To effect "SLC" in GPL would only require subtracting the desired left shift from 8 and using that value with SRC. Of course, subtracting from 16 would be necessary for DSRC to manage a "DSLC".

 

Interestingly, GPL (per the TI GPL Programmer's Guide) has (D)SLL, but no (D)SLA, whereas ALC has it the other way round, i.e., SLA, but no SLL. It is only in the mind of the programmer that this matters because they are the same operation. The GPL Interpreter converts the emitted code for (D)SLL to the ALC's SLA. Thierry Nouspikel's GPL Assembler allows (D)SLA which emits the same code as for (D)SLL.

 

...lee

  • Like 1
Link to comment
Share on other sites

In case anyone is interested in a text-file ALC listing of the TI-99/4A console ROM, I have extracted it from Heiner Martin's TI99/4A INTERN. Of principal concern for this thread is the GPL Interpreter, which starts near the beginning. The biggest reason I extracted it was to allow me to view it in a side-by-side mode in Notepad++ in an effort to better follow the convoluted branching.

 

One of these days, I may

  • Convert all of the register references from numbers (0 – 15) to R-notation (R0 – R15)
  • Replace hex memory-location labels (every line) with mnemonic labels
  • Remove unreferenced hex memory-location labels
  • Remove the machine code column.

Some folks have probably already done this, especially those who have re-written the console ROM; but, here it is anyway:

 

ConsoleROM_ALC.lst**

 

...lee

 

**Corrected listing (see post #96 below): ConsoleROM_ALC_corr.lst

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

 

Who, besides TI, has re-written the console ROM ? :)

 

I am pretty sure that Winfried Winkler and Tony Knerr both modified the console's GROM0; but, I do not know whether either (or anyone else) modified the ROM. I do know there are a lot of hardwired references in console-ROM to instruction code, the machine code of which just happened to be the value(s) needed. I ran into several when I deconstructed KSCAN. It was one of those things (unwise IMHO) TI did to conserve space. It also makes it very dangerous to attempt a rewrite.

 

Even if it could be successfully rewritten, there is likely third-party (maybe TI, as well) code out there that also does this. Though not ROM, the one example I know about that did something like this with a GROM location is Craig Miller's GSRLNK/DSRLNK routines. He found 2 bytes in the middle of a data block that just happened to be the machine code for the GPL instruction, “XML >27”, which he used in his code to trick the GPL Interpreter into “returning” to his routine in ALC.

 

...lee

  • Like 1
Link to comment
Share on other sites

I did this port of the TI Intern code some time ago, and verified that the CPU code successfully assembles. I also fixed the argument order in the GPL part, but I can't remember if we proved it builds correctly or not...

 

(Edit: updated archive to include Lee's fix from below)

 

tiintern.zip

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

Please be careful with my code if it has been modified to override the built-in GROMs. There are two caveats, which are why I shipped it with that code disabled:

 

1) No address read-back functionality. You need one real GROM somewhere in the system. ;) This is deliberate for now as I wasn't ready to call my address read-back code done, but I have tested code that will ship in MPD.

 

2) If you're just overriding from the cartridge port, /probably/ no worries. I've done it, it works, but I didn't measure current draw to ensure there was no danger of burning anything out (we may need current limiting resistors) and I wanted to verify that I had tested against the internal pull up and pull down resistors before shipping it for that. if you mean to install inside the console and permanently /replace/ the GROMs, please use current limiting resistors, otherwise GRAMKrackers or future AVR-GROM products may end up fighting each other directly on the bus, causing damage.

 

It's all just "be careful about maybes", but better safe than sorry. :)

  • Like 1
Link to comment
Share on other sites

I did this port of the TI Intern code some time ago, and verified that the CPU code successfully assembles. I also fixed the argument order in the GPL part, but I can't remember if we proved it builds correctly or not...

 

attachicon.giftiintern.zip

 

I found an error in Heiner Martin's disassembly listing of the console ROM. The error is on page 62 of TI99/4A INTERN at location >17BC:

 

17BC 835C DATA >83C5 Pointer address VDP

 

Verified from binary dumps (not mine) and my real iron, It should read

 

17BC 835C DATA >835C Pointer address VDP

 

You will note that the machine code (the second hex number) is actually correct; but, because the error is in the ALC, it was propagated into the source code of TI994A_CPU.asm packaged in @Tursi's ZIP file referenced in his quote above. After assembling the corrected ALC and converting the OBJ file to BIN format, it is identical to the ROM binary used by Classic99 and MESS.

 

...lee

  • Like 2
Link to comment
Share on other sites

 

 

After a careful look at the ALC for the GPL SRL and SRA instructions in the GPL Interpreter (Heiner Martin's disassembly listing of the TI-99/4A console ROM), I can say with confidence that the GPL SRL and SRA behave exactly like the ALC SRL and SRA, respectively, except that they are byte operations, of course.

 

For all of the GPL shift instructions, the number to be shifted (destination operand) is first read into R0. For a byte operation, the byte is right-shifted with an ALC "SRA R0,8" to preserve the sign bit before it is copied to R2. For the GPL SRL instruction, after the number of bits to shift is put into the LSB of R0, the MSB of R2 is cleared with an ALC "SB R2,R2" to insure that zeroes are shifted into the LSB from the left.

 

The shift is performed with an ALC "SRL R2,0", which uses the rightmost nybble (four bits) of R0 to get the number of bits to shift right. Any shift > 7 will result in clearing the byte. Shift = 0 will use a shift = 16, as noted by @ralphb, which, of course, also clears the byte. The shifted result is then copied from R2 to the destination byte.

 

The GPL SRA instruction is set up just as for SRL except that the MSB of R2 is not cleared so as to maintain the sign bit already filling the MSB. The shift is performed by an ALC "SRA R2,0". And, yes, "SRA 0,@>8300" should transform >80 into >FF.

 

...lee

Thanks Lee for the exhaustive explanation. It's much more interesting when you know what is going on underneath the hood.

Link to comment
Share on other sites

I found an error in Heiner Martin's disassembly listing of the console ROM. The error is on page 62 of TI99/4A INTERN at location >17BC:

Wow, thanks Lee! I thought I did a binary compare years ago, so I had trusted this. I've updated my local copy (and suggest anyone who downloaded it update theirs ;) ).

Link to comment
Share on other sites

 

I am pretty sure that Winfried Winkler and Tony Knerr both modified the console's GROM0; but, I do not know whether either (or anyone else) modified the ROM. I do know there are a lot of hardwired references in console-ROM to instruction code, the machine code of which just happened to be the value(s) needed. I ran into several when I deconstructed KSCAN. It was one of those things (unwise IMHO) TI did to conserve space. It also makes it very dangerous to attempt a rewrite.

 

Even if it could be successfully rewritten, there is likely third-party (maybe TI, as well) code out there that also does this. Though not ROM, the one example I know about that did something like this with a GROM location is Craig Miller's GSRLNK/DSRLNK routines. He found 2 bytes in the middle of a data block that just happened to be the machine code for the GPL instruction, “XML >27”, which he used in his code to trick the GPL Interpreter into “returning” to his routine in ALC.

 

...lee

I have written several versions of GROM 0, GROM 1 and 2 changing and customizing different things. Many from the MIller Graphics notes on GROMs 0, 1 and 2.

 

Also I came out with RBASIC that added EA Cartridge support to TI Basic without using a EA Cartridge.

 

As far as I know no one else ever did this.

Link to comment
Share on other sites

  • 6 months later...

For all my friends here, first of all sorry for not being around the TI community in the past 5 months but between work and family I had little to no time for my hobbies. Now things settled down a little and I can commit several hours of my time again towards GPL development. I have approx. 90% of my game done. I have also found help in the music department which was killing my initiative to continue, but was lucky enough to find a friend who is composing a suitable music score for me to key in into a soundlist. All looks gelling and I am posting this message as a commitment to the community that by December the game has to be released for all to enjoy.

 

For now all I can reveal is that name of game is "Break Free" - 100% GPL and is dedicated to the TI communities around the world.

  • Like 8
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...