Jump to content
IGNORED

Bouncing Babies cartridge version


retroclouds

Recommended Posts

This thread describes my progress on turning Bouncing Babies into a cartridge ROM image.

Warning: Only runs with 32K memory expansion RAM.

 

This ZIP file contains the ROM image and source code

baby_cart_conversion.zip

 

 

 

Windows tools used for doing the conversion

 

* classic99 (and its great debugger)

* HxD hex editor

* winasm99 (cross-assembler from Cory Bur included with the win994a emulator)

* PERL

 

 

The following reference material was used for doing the conversion

 

* Graphics Programming Language (GPL manual, see Development Resources thread)

* TMS9900 Assembler auf dem TI-99/4A (great assembler manual written in german)

 

Others

* Spectra2 alpha, my own assembler library for writing games

 

 

Here we go:

 

1. I copied the #EA5 files (BABY5 and BABY6) in my classic99 DSK1 directory and started classic99.

2. Started the Editor/Assembler cartridge in classic99 and also opened the classic99 debugger window.

3. Selected #EA5 (RUN PROGRAM FILE) and entered DSK1.BABY5

4. The game started and while it was running I inspected high memory from >A000->FFFF

Noticed that the first instruction starts at >CFDE.

5. Reset emulator and set breakpoint at >CFDE, then repeated step 3

6. The debugger halts execution at >CFDE, that's before the game does something.

I press the "Dump RAM" button in the emulator and confirm the dialog requesting if I do want a dump.

7. A 64 kilobyte file MEMDUMP.bin is written in the classic99 directory, that's the one I'm looking for.

8. Started HxD hex editor and opened MEMDUMP.bin, I looked for the memory range >CFDE->FFFF.

9. I split this memory range and dumped it from HxD in the binary files "baby_0000_to_17FF.bin" and "baby_1800_to_3021.bin"

They are pretty much a dump of the game split in two files.

10. Time to do some perl now, I recalled I had a short PERL script I used for turning bytes into assembly language data statements.

With the PERL script I created "baby_0000_to_17FF.a99" and "baby_1800_to_3021.a99"

11. It's obvious that the game won't fit in a 8K ROM image, we'll need 2 banks so we'll be switching banks.

Time to start notepad++ and do some hacking. I don't want to start from scratch so I used SPECTRA2 for doing things like

memory setup, setting VDP registers, doing the bank switching, etc.

12. For each bank I create a new project in winasm99, called "baby_bank0.apf" and "baby_bank1.apf"

13. Ready to roll, assemble both projects and important, select option for creating binary files "baby_bank0.bin" and "baby_bank1.bin"

14. Ready to run our newly created bank-switched ROM image, reset classic99 after adding the below to your classic99.ini

 

[usercart2]
name=Bouncing Babies
rom0=C|6000|2000|D:\projekte\baby_cart_conversion\baby_bank0.bin
rom1=X|6000|2000|D:\projekte\baby_cart_conversion\baby_bank1.bin

 

 

 

Here's the extract for the code in bank0

 

***************************************************************
* Cartridge header
********@*****@*********************@**************************
       AORG  >6000
GRMHDR  BYTE  >AA,1,1,0,0,0
       DATA  PROG
       BYTE  0,0,0,0,0,0,0,0
PROG    DATA  0
       DATA  KERNEL
       BYTE  15
       TEXT  'BOUNCING BABIES'
*//////////////////////////////////////////////////////////////
*                    KERNEL MEMORY SETUP
*//////////////////////////////////////////////////////////////
* KERNEL ..:
***************************************************************
*  KERNEL - Spectra2 Kernel memory setup
***************************************************************
*  B  @KERNEL
********@*****@*********************@**************************
KERNEL  LIMI  0                     ; Turn off interrupts
       LWPI  WS1                   ; Activate workspace 1
       LI    TMP0,VM1              ; Graphics mode 1
       BL    @LOADVR               ; Load shadow registers
       LI    STACK,BASE1           ; Set data stack to base
       MOV   @JPCODE,@SWBANK       ; Bank switching trampoline code
       MOV   @JPCODE+2,@SWBANK+2   ; Bank switching trampoline code
       B     @MAIN        
********@*****@*********************@**************************
* VDP graphics mode 1 - See table definitions
VM1     BYTE  >00,>E0,>00,>0E,>01,>06,>00,>F3,32,>00    ; Graphic mode 1
JPCODE  DATA  >04D4,>0455           ; CLR *R4 and B *R5
* :..

MAIN    BL    @PUTVR                ; Put shadow registers
       BL    @FILMEM               ; Clear memory A000-FFFF
       DATA  >A000,>00,>FFFF->A000     
       BL    @CPYM
       DATA  BABY0,>CFDE,>17FF     ; Copy part 1 to HIMEM >CFDE
       LI    TMP0,BANK1
       LI    TMP1,>6070            ; Jump to copy code in bank 1
       B     @SWBANK   
       ....
BABY0   COPY "D:\Projekte\baby_cart_conversion\baby_0000_to_17FF.a99"
       END

 

 

 

And this is the code for the second bank:

 

***************************************************************
* Cartridge header
********@*****@*********************@**************************
       AORG  >6000
GRMHDR  BYTE  >AA,1,1,0,0,0
       DATA  PROG
       BYTE  0,0,0,0,0,0,0,0
PROG    DATA  0
       DATA  KERNEL
       BYTE  15
       TEXT  'BOUNCING BABIES'                
*//////////////////////////////////////////////////////////////
*                    KERNEL MEMORY SETUP
*//////////////////////////////////////////////////////////////
* KERNEL ..:
***************************************************************
*  KERNEL - Spectra2 Kernel memory setup
***************************************************************
*  B  @KERNEL
********@*****@*********************@**************************
KERNEL  LIMI  0                     ; Turn off interrupts
       LWPI  WS1                   ; Activate workspace 1
       LI    STACK,BASE1           ; Set data stack to base
       MOV   @JPCODE,@SWBANK       ; Bank switching trampoline code
       MOV   @JPCODE+2,@SWBANK+2   ; Bank switching trampoline code
       B     @MAIN        
********@*****@*********************@**************************
JPCODE  DATA  >04D4,>0455           ; CLR *R4 and B *R5
GPLWS   BYTE  >13,>F5,>09,>F0,>00,>A0,>43,>81
       BYTE  >CF,>DE,>02,>70,>06,>64,>4F,>F3
       BYTE  >00,>00,>00,>1E,>38,>00,>06,>1C
       BYTE  >00,>00,>98,>00,>01,>08,>8C,>02 
********@*****@*********************@**************************
MAIN    LI    TMP0,BANK0
       LI    TMP1,>6024            ; Start of code
       B     @SWBANK   
       BL    @CPYM
       DATA  BABY1,>E7DE,>17FF     ; Copy part 2 to HIMEM >E7DE        
       BL    @CPYM
       DATA  GPLWS,>83E0,30        ; Setup GPL Workspace as in Editor Assembler
       MOV   @GPLWS+30,@>83FE      ; 32 would have overwritten return stack
       B     @>CFDE                ; Start game in HIMEM
       ...
BABY1   COPY "D:\Projekte\baby_cart_conversion\baby_1800_to_3021.a99"
       END

 

 

I didn't include the SPECTRA code in the above snippets as it might distract from what we are trying to explain here ;)

 

Basically you don't know which bank will be selected when the TI-99/4A is powered up, that is the reason both banks include a

cartridge header. If the second bank is selected first, all it does is a bank-switch to the first bank.

 

This is what happens:

 

BANK 1

=====

1. If we start in BANK1 by coincidence, then all we do is setup workspace & stack and copy bank-switch trampoline code into scratch-pad memory.

2. We use the trampoline code in scratch-pad memory to select BANK0 and jump to the KERNEL subroutine there.

 

BANK 0

=====

1. This kernel actually only does a basic scratch-pad memory setup (workspace, bank-switch trampoline code, etc.) and sets VDP shadow registers the same way as in Editor/Assembler, when done it jumps to MAIN

2. In MAIN, we set the hardware VDP registers based on the values in the VDP shadow registers

3. Clear high memory >A000 to >FFF by filling it with >00

4. Copy >17FF bytes from game code in BANK0 to high memory >CFDE

5. We use the trampoline code in scratch-pad memory to select BANK1 and jump to >6070 (MAIN)

 

BANK 1

=====

1. We copy the remaining >17FF bytes from game code in BANK1 to high memory >E7DE

2. Almost done now, we only need to set the GPL workspace in scratch-pad memory the same was as if we would be using the Editor/Assembler module. So copy 32 bytes to >83E0

3. Ready to go, jump to start of game in high memory: B @>CFDE

 

 

 

Below is the PERL script I used for turning the raw bytes into assembly data statements.

It's nothing fancy just a quick hack.

 

#!/usr/bin/perl
  use Data::Dumper;
  our @rom   = ();
  our $size  = 0;
  
  
  readdump('baby_1800_to_3021.bin');
  #datadump('780','800');
  datadump('0','17FF');
  exit;

  sub readdump {
      my $fname = shift;
      
      if (-e "$fname") {
         my $image = "";
         open(ROMH, "$fname") or die("Could not open \"$fname\"\n");
         binmode ROMH;
         $size = read(ROMH, $image, 16384);
         @rom  = unpack("C*", $image);
         close(ROMH);
      } else { die("no ROM!"); }
   }
  
  
  sub datadump {
     my $start = hex shift;
     my $end   = hex shift;
     my $nl    = 0;
     my $cm    = '';
     for (my $l=$start; $l<=$end; $l+=2) {
         if ($nl == 0) {
            print "        DATA ";
            $cm = sprintf("   ; >%X - >%X\n", $l, $l+7);
         }
         printf("%s>%02X%02X",$nl > 0 ? ',' : '',$rom[$l],$rom[$l+1]);
         if ($nl == 3) { 
            printf($cm); $nl = 0;
         } else {
            $nl++;
         }                          
     }
  }

Link to comment
Share on other sites

I didn't have time to test it out on other emulators (MESS) nor did I try it on the real deal yet.

 

You should be able to run this image when using a GRAM kracker device.

 

Also if both ROM images are concatened as a single binary image and burned on a 16K EPROM

it should work with the newer boards from Jon (keeping my fingers crossed) :D

Link to comment
Share on other sites

Retroclouds, that is great instructions. I had no idea how to do that and you make it so clear. Thank you.

 

When you talk about putting both files in 1 file for a 16k eprom, do you just attach the 2nd file to the end of the first?

 

John

 

Thanks. Yes, you just add the 2nd file to the end of the first.

If you are on windows you can do that by typing: copy /B baby_bank0.bin+baby_bank1.bin baby.bin

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...