Jump to content
IGNORED

Making a cartridge questions


jchase1970

Recommended Posts

Ok, 1st if this has been discussed else where I have missed it or not understood it.

 

I used Tursi EA5 to GROM program to turn Bouncing Babies into a GROM file, I was under the impression that a GROM file was what you needed to make a cartridge. Apparently a GROM chip is in a special type of cartridge not the cartridges we can make using a EPROM.

 

So let's leave that there and move forward.

 

I posted for assemble help a while back and Matthew posted this piece,

      DEF  STDHDR

* VDP Memory Map
*
VDPRD  EQU  >8800             * VDP read data
VDPSTA EQU  >8802             * VDP status
VDPWD  EQU  >8C00             * VDP write data
VDPWA  EQU  >8C02             * VDP set read/write address

* Workspace
WRKSP  EQU  >8300             * Workspace
R0LB   EQU  WRKSP+1           * R0 low byte reqd for VDP routines
R1LB   EQU  WRKSP+3           * R1 low byte
R2LB   EQU  WRKSP+5           * R2 low byte
R3LB   EQU  WRKSP+7           * R3 low byte
R4LB   EQU  WRKSP+9           * R4 low byte


**
* Set Up Cartridge
*
* Always mapped to the cartidge address range
      AORG >6000

STDHDR BYTE >AA               * Indicates a standard header
      BYTE >01               * Version number
      BYTE >01               * Number of programs (optional)
      BYTE >00               * Not used
      DATA >0000             * Pointer to power-up list (can't use in cartridge ROM)
      DATA PROG              * Pointer to program list
      DATA >0000             * Pointer to DSR list
      DATA >0000             * Pointer to subprogram list
      DATA >0000             * Pointer to ISR list
PROG   DATA >0000             * No next menu item
      DATA MAIN              * Program start address for this menu item
      BYTE 11                * Length of text for menu screen
      TEXT 'HELLO WORLD'
      EVEN

* Text to display.  This is redundant here since the text above used
* for the menu display could have also been used here, but for
* completness a separate message is reserved.

MSG1   TEXT 'HELLO WORLD!'    * Reserve and initialize the message bytes
MSG1E
      EVEN

*********************************************************************
*
* Main Entry Point
*
*
MAIN   LIMI 0                 * Prevent the console ISR from running
      LWPI WRKSP             * Set the workspace

* No VDP initialization since the console will have set the standard
* Graphics I mode (32x24) and loaded the standard character set.
* If full VDP initialization is necessary, then this code would be
* a lot larger since all the data for a full ASCII set would most
* likely be required.

* Clear the screen by writing a space to every screen position.  In
* VDP RAM the screen in a continous buffer of bytes.  32*24=768 total
* bytes.
      LI   R0,0              * Address in VDP RAM to write to
      LI   R1,>2000          * The byte to write (space)
      LI   R2,768            * Number of bytes to write
      BL   @VSMW             * Write the space multiple times

* Since the VDP is wired to the upper 8-bits of the 9900's data bus,
* the single byte to write must be in the upper byte of the R1
* register, which is why the HEX value is used above since it is
* eaiser to read (>20 HEX is 32 decimal, i.e. ASCII for space)

* To display the message the address of the screen has to be loaded,
* the buffer in CPU RAM designated, and the lenght of the data to
* write (in bytes).
      LI   R0,395            * (12,11) == 12 * 32 + 11 == 395
      LI   R1,MSG1           * Bytes to write
      LI   R2,MSG1E-MSG1     * Length (let the assembler do the math)
      BL   @VMBW             * Write the data

      LIMI 2                 * Enable interrupts to CTRL= works
LOOPZ  JMP  LOOPZ


* These are replacements for the console VDP "functions" that are usually
* called with a BLWP.  These are a bit faster and don't have any fluff.

* VDP Single Byte Write
VSBW   MOVB @R0LB,@VDPWA      * Send low byte of VDP RAM write address
      ORI  R0,>4000          * Set read/write bits 14 and 15 to write (01)
      MOVB R0,@VDPWA         * Send high byte of VDP RAM write address
      MOVB R1,@VDPWD         * Write byte to VDP RAM
      B    *R11

* VDP Single Byte Multiple Write
VSMW   MOVB @R0LB,@VDPWA      * Send low byte of VDP RAM write address
      ORI  R0,>4000          * Set read/write bits 14 and 15 to write (01)
      MOVB R0,@VDPWA         * Send high byte of VDP RAM write address
VSMWLP MOVB R1,@VDPWD         * Write byte to VDP RAM
      DEC  R2                * Byte counter
      JNE  VSMWLP            * Check if done
      B    *R11

* VDP Multiple Byte Write
VMBW   MOVB @R0LB,@VDPWA      * Send low byte of VDP RAM write address
      ORI  R0,>4000          * Set read/write bits 14 and 15 to write (01)
      MOVB R0,@VDPWA         * Send high byte of VDP RAM write address
VMBWLP MOVB *R1+,@VDPWD       * Write byte to VDP RAM
      DEC  R2                * Byte counter
      JNE  VMBWLP            * Check if done
      B    *R11

* VDP Single Byte Read
VSBR   MOVB @R0LB,@VDPWA      * Send low byte of VDP RAM write address
      MOVB R0,@VDPWA         * Send high byte of VDP RAM write address
      MOVB @VDPRD,R1         * Read byte from VDP RAM
      B    *R11

* VDP Multiple Byte Read
VMBR   MOVB @R0LB,@VDPWA      * Send low byte of VDP RAM write address
      MOVB R0,@VDPWA         * Send high byte of VDP RAM write address
VMBRLP MOVB @VDPRD,*R1+       * Read byte from VDP RAM
      DEC  R2                * Byte counter
      JNE  VMBRLP            * Check if finished
      B    *R11

* VDP Write to Register
VWTR   MOVB @R0LB,@VDPWA      * Send low byte (value) to write to VDP register
      ORI  R0,>8000          * Set up a VDP register write operation (10)
      MOVB R0,@VDPWA         * Send high byte (address) of VDP register
      B    *R11

      END

 

It has this cartridge header in it,

**
* Set Up Cartridge
*
* Always mapped to the cartidge address range
      AORG >6000

STDHDR BYTE >AA               * Indicates a standard header
      BYTE >01               * Version number
      BYTE >01               * Number of programs (optional)
      BYTE >00               * Not used
      DATA >0000             * Pointer to power-up list (can't use in cartridge ROM)
      DATA PROG              * Pointer to program list
      DATA >0000             * Pointer to DSR list
      DATA >0000             * Pointer to subprogram list
      DATA >0000             * Pointer to ISR list
PROG   DATA >0000             * No next menu item
      DATA MAIN              * Program start address for this menu item
      BYTE 11                * Length of text for menu screen
      TEXT 'HELLO WORLD'
      EVEN

 

When compiling this with WIN994a assemble with the option 'Produce Cart BIN File' would this output file be something that is able to be put on a cartridge?

 

I'm trying to understand what I need to do to make a cartridge, so if this is not the way to program for a homemade cartridge then maybe someone who has made a cart can walk me though the setup protocol.

 

Thanks, John.

Link to comment
Share on other sites

I guess it will depend on where the compiled game loads in memory, I presume somewhere near >A000 ?

Games directly running from the module space need to start at >6000 and also need their own routines for writing to VDP etc.

 

It'll also depend how much memory space the game takes. You have 8K of memory in the module space, if you need more you have to use multiple banks and do bank switching.

But I suppose the easiest solution by far is to build some assembly wrapper code, that copies the actual game code where it needs to go.

Ofcourse this also means you need 32K memory expansion.

 

  * Cartridge header
  * Wrapper code for copying game code to >A000
  * Your game

Link to comment
Share on other sites

I guess it will depend on where the compiled game loads in memory, I presume somewhere near >A000 ?

Games directly running from the module space need to start at >6000 and also need their own routines for writing to VDP etc.

 

It'll also depend how much memory space the game takes. You have 8K of memory in the module space, if you need more you have to use multiple banks and do bank switching.

But I suppose the easiest solution by far is to build some assembly wrapper code, that copies the actual game code where it needs to go.

Ofcourse this also means you need 32K memory expansion.

 

  * Cartridge header
  * Wrapper code for copying game code to >A000
  * Your game

 

So if your program is to big for a single game then you have to do bank switching.

 

Questions based on 2 banks.

If Bank 0 is >6000 I assume 8k later bank 1 starts at >8000, right?

Can code in bank 1 access code in bank 0, ie do you have your VDP functions in 0 only, bank or copies in all banks?

Code has to be wrote in 8k chunks with ,code headers changing the memory start point, and compiled to separate bin files. A cartridge with a 16k program will have 2 files on it?

 

 

Questions regarding more banks.

Is there a limit to the number of banks used by the computer for a single program.

Can you use the whole 64k cartridge space.

Link to comment
Share on other sites

I'm trying to understand what I need to do to make a cartridge, so if this is not the way to program for a homemade cartridge then maybe someone who has made a cart can walk me though the setup protocol.

 

Thanks, John.

 

With Tursi's tool and probably some other resources out there you could probably make some sort of GROM to work with you game. However, there is no way to make a *real* GROM yet (until Tursi's GROM module is done, or someone else does something similar), and working with GROMs is a real hassle. Also, for an assembly language program, a GROM is only good for storing data that is copied to other parts of the system for use, like graphics and sound which can go to VDP RAM. You could store code in a GROM, but it has to be copied out of the GROM and into system RAM before it can be executed. The only code that can be executed from GROM is GPL.

 

To make a cartridge, your code has to be written to start at a fixed memory location, in this case >6000 because that's where the cartridge ROM is mapped in the 99/4A's memory space. You set a specific location using the AORG (absolute origin) assembly directive. You also need to set up a "header" in your code so the console's menu will display your program and allow it to be selected. Again, this is not something we can change, that's simply how the console it set up.

 

Something to note about ROM based cartridges: Later in the 99/4A's production, TI tried a final time to control the software being developed for the system and changed the console OS to no longer scan for menu headers in cartridge ROMs. It would only scan for GROMs in cartridges, and of course only TI made GROMs. That means that ROM-only cartridges will not work on these later consoles, which are called QI consoles I believe, and are always the beige plastic case (note that not all beige consoles are QI.) Don't let this deter you though, Tursi informed me that these QI consoles are pretty rare, and of course emulators don't have this problem. Also, a ROM cart can be made to work fine with the inclusion of a GROM to present the header to the console menu system. Or, a special menu program (like the one Tursi wrote), will scan and display cartridge ROM headers regardless of the console.

 

Some programming changes you need to be aware of when working on code that will be run from a cartridge ROM are:

 

1. You must have a header, and it must be the first data in the cart, starting at >6000.

 

2. You can not use the assembly directives to set up writable variables like you can when writing a relocatable program. For example:

SCORE DATA >0000
. . .
     INC  @SCORE

That won't work because SCORE is in ROM, which you can't change. I forgot about this and had my memory jogged the hard way when single stepping Classic99 in debug and screaming "why didn't the score just change?!?!?!?!" Stupid emulator enforcing that you can't write to a ROM!!! ;-) You *can* use the DATA, BYTE, and TEXT directives to set up read-only data, just remember that the data will be in the ROM and will use up some of your limited 8K of ROM space.

 

3. The only RAM you have is the 256 bytes of scratch pad and VDP RAM. Your workspace has to be in scratch pad, and if you shut off the console ISR you can use the rest of the scratch pad for your variables. Variables are kind of a pain since the assembler does not support the segment directives, you have to specify the memory addresses for your variables manually. In a relocatable program the assembler would do that for you.

 

4. As already mentioned, the subroutines provided by the E/A or XB cartridge are not available to your program, since those cartridges will obviously not be plugged in (because your cartridge will be.) So you need to set up your own VDP routines, which I have included in my assembly thread and so have many other people. Even if you are not doing a ROM cartridge program, it is my opinion that you should use your own routines for sound, VDP, keyboard, etc., especially when making games. Or use a library like SPECTRA, which Retroclouds developed when he wrote PitFall and it should work with cartridge-based programs without a problem (since PitFall is on a cart.)

 

5. You only have 8K. However, you can make a multi-bank cart and do bank switching which would give you a total of 32K for code and read-only data. Jon Guidry's 64K cart supports four 8K banks, and I'm pretty sure Classic99 supports all four as well. I believe PitFall is a 3-bank game. If you use bank switching, you have to set up your banking management code somewhere outside of the code space that will actually be swapped out. Or, you have to make sure your banking management is always in the same place in every bank, so when you switch banks execution will continue and you can figure out where to jump to after the switch.

 

For a single 8K cartridge ROM, the "code, assembly, test, debug" cycle can actually be very fast if you are using Asm994a and Classic99. This is the setup I currently use until I can get a better assembler. Also note that v3.009 of Asm994a has a bug with the JH instruction. There is an unofficial update to just Asm994a (v3.010) to fix this bug, but I don't know where to get it.

 

I have no idea if the BASIC compiler you are using can produce code that can be put in a cart. You mentioned a final step where the assembler output is fed into another program to make it loadable from BASIC or something. If you leave that step out, and modify the assembly code to work in a ROM, then it will probably work. I have not looked at the BASIC compiler's output though, and it might create code that would be a pain to set up in a fixed address space, i.e. it probably sets up the variables using BYTE and DATA statements, but that is just a guess.

 

I think I posted a skeleton for making a ROM cart, if you can't find anything let me know and I'll post one.

 

Matthew

Link to comment
Share on other sites

So if your program is to big for a single game then you have to do bank switching.

 

Questions based on 2 banks.

If Bank 0 is >6000 I assume 8k later bank 1 starts at >8000, right?

Can code in bank 1 access code in bank 0, ie do you have your VDP functions in 0 only, bank or copies in all banks?

Code has to be wrote in 8k chunks with ,code headers changing the memory start point, and compiled to separate bin files. A cartridge with a 16k program will have 2 files on it?

 

Banks are always at addresses >6000 to >7FFF in the 99/4A's address space. That's why we have to "switch" them. Bank switching is a window into a larger address space. Let's use a 2-bank example:

 

8K == >2000 (hex) == 8192 (decimal)

 

+- EPROM 27128 (16K x 
| >0000 \___ bank 0
| >1FFF /
|-
| >2000 \___ bank 1
| >3FFF /
+-

 

When bank 0 is selected, the EPROM addresses from >0000 to >1FFF will be visible at the 99/4A's cartridge address space of >6000 to >7FFF.

+- BANK 0 SELECTED
| >0000 \___/ >6000 \___ cartridge address space
| >1FFF /   \ >7FFF /
|-
| >2000 \___ bank 1 inactive
| >3FFF /
+-

 

Now, when bank 1 is selected, the EPROM addresses from >2000 to >3FFF will be visible at the cartridge address space of >6000 to >7FFF.

+- BANK 1 SELECTED
| >0000 \___bank 0 inactive
| >1FFF /
|-
| >2000 \___/ >6000 \___ cartridge address space
| >3FFF /   \ >7FFF /
+-

 

You can not access the code or data in another bank until it is "swapped" in to the 99/4A's cartridge address space. That's why banking is tricky. For example, if your banking code is in the ROM itself, say at the top of bank 0 from >0000 to >0010 (16 bytes), then when bank 0 is active that will be 99/4A addresses >6000 to >6010. Now say you have some data in bank 1. So you execute your code at >6000 to bank switch, which brings bank 1 into the address space >6000 to >7FFF, but as far as the 99/4A is concerned you are still accessing memory address >6010, which is now all of a sudden graphic or sound data, or something like that. At this point your program will crash because it starts to *execute* data, or other code at some strange point.

 

One way around this is to set up the bank switching code at the same place in each bank. Then when the switch is made, you need some external data to let you know what you were doing and where to go now that you have switched. You could also keep your bank switching code in scratch pad RAM, which keeps it out of the way when you switch.

 

Bank switching means you have to think about your code and how it can be make into 8K blocks. That does not mean writing smaller segments and compiling them separately (which you still have to do), what that means is that at any given time you program will not have access to all of its parts, and different code will appear at the same addresses depending on what bank is active. For example, I would not recommend bank switching the VDP routines since you will need them a lot, unless you consolidate all of your screen updates or VDP RAM access to a single subroutine in your program.

 

A good use for a second bank would be all the graphics and sound data, map data, etc. That way you would switch in bank 1, load graphics data to the VDP, and switch back to bank 0 to run the program. Sound data could be accesses as needed by switching bank 1 and telling the sound player code (which could also be in bank 1) to play the next note of sound data.

 

I have not done bank switching in practice though, so these methods are just ideas I'm kicking around. Retroclouds did PitFall in a cart with 3 banks I think, so he should have some practical advice.

 

 

Questions regarding more banks.

Is there a limit to the number of banks used by the computer for a single program.

Can you use the whole 64k cartridge space.

 

If you are talking about the 64K boards made by Jon Guidry, they are limited to four 8K banks due to the physical wiring (without hacking.) However, since the bank selection is based on the address bus, and there are 12 effective address lines that can be used in the cartridge port for banking, it is theoretically possible to have 4096 8K banks, which is about 33MB.

 

There is no limit to the number of banks a program can use other than the physical number of banks available. The tricky part is being able to use that much memory in a form where everything is cut up into 8K segments and not requiring access to any more than 8K worth of data or code from that 33MB at any given time.

 

Matthew

Link to comment
Share on other sites

Just throwing stuff out there, trying to get my head around how it all works,

 

ram we have to work with is 256bytes in scratchpad and 16k in VDP

If we use normal graphics mode(32x24) 768 bytes of VDP ram write to the screen.

 

does this then mean we have the rest of the VDP memory for what ever we need it for, 15616 bytes(16354-768)

All this memory is for variables that change, like score, inventory items, etc. Right?

 

The rom is the routines that uses data stored in ram to do something with.

 

so something simple like a score update,

lets say it's in >xxxx and the game set this to >0000 to begin with, does this have to be in the scratchpad or can this be in the spare VDP ram? Scratchpad is close to the cpu so it's faster?

 

the program in rom would

1st load the score into a register

2nd load the amount to add to the score in another register

3rd do a add function on these 2 registers and store the result back in >xxxx

 

 

 

Get me straight so I'm thinking in the right direction,

 

John

Link to comment
Share on other sites

Think about ROM like a book at the library. You can't highlight and make notes in the book... So you make a xerox copy of it and mark away. ROM is an unchangeable "book", but feel free to modify your xerox copies. Just don't LOSE your copies or forget what you were working on. :) You can always re-xerox the copies, but none of the changes you made will be there.... I think you have a good understanding of it.

Link to comment
Share on other sites

Think about ROM like a book at the library. You can't highlight and make notes in the book... So you make a xerox copy of it and mark away. ROM is an unchangeable "book", but feel free to modify your xerox copies. Just don't LOSE your copies or forget what you were working on. :) You can always re-xerox the copies, but none of the changes you made will be there.... I think you have a good understanding of it.

 

 

Yeah, I understand read only and random access. It's more how to work with the 2 from a cartridge that I am trying to figure out. I guess I am doing it right because my C.bin files work when loaded as a cartridge in c99 and win994a. But that is only because I have worked with the sample programs from Matthew and have made them work. I have not made them work because I understand what I am doing. More trial and error then anything. I have 2 compilable basic programs in the works right now and then I want to start from scratch on a cartridge game. I know the whole thing will be a learning experience but I want a basic understanding of the memory locations and accessing before I get started.

Link to comment
Share on other sites

You guys have advanced a bit beyond the bit I wanted to touch on, so let me drag you backwards half a step just to explain my tool. :)

 

My cartridge creation tool creates GROM images for emulation out of EA#5 programs -- but all the GROM code does is copy the program back to RAM and start it. So it's essentially just a loader.

 

I have a version in progress that will do the same for ROM images that will work with Jon's bank-switching EPROM carts, but that has fallen so far down my backlogged task list that it will be a few months before I can get to finishing it.

 

My single-chip GROM solution works now, but I need to get back into it, too, as right now the only way to program the GROM code is when you program the Atmel itself (I want to make it programmable by the TI). This is higher on my list but still backlogged... couple months away. ;)

 

Back to the discussion on moving your program to ROM! :)

Link to comment
Share on other sites

does this then mean we have the rest of the VDP memory for what ever we need it for, 15616 bytes(16354-768)

All this memory is for variables that change, like score, inventory items, etc. Right?

 

Almost. The "name table" has 1 byte for every location, which in graphics mode 1 is 32x24, or 768 bytes. However, you also have the pattern definitions in VDP RAM (VRAM), which consume 8 bytes per character times 256 total characters, which is 8 * 256, or 2048 bytes (2K). You also have the color table (which is very small), the sprite pattern table, which can overlap or be separate from the character patterns, and finally the sprite attribute table.

 

So assuming you are not using sprites, or you are using the same patterns for sprites and characters, you have:

 

1K name table (rounded up)

2K pattern table

32 bytes color table

 

The color table can actually be placed at the end of the name table, within the 1K boundary, so 3K is used and leaves you with 13K of VRAM to use as you see fit.

 

The rom is the routines that uses data stored in ram to do something with.

 

ROM can also store data that does not change, like graphics, sounds, maps, levels, or anything else your program needs to function.

 

so something simple like a score update,

lets say it's in >xxxx and the game set this to >0000 to begin with, does this have to be in the scratchpad or can this be in the spare VDP ram? Scratchpad is close to the cpu so it's faster?

 

the program in rom would

1st load the score into a register

2nd load the amount to add to the score in another register

3rd do a add function on these 2 registers and store the result back in >xxxx

 

Pretty much. You really want to try and only keep data in VRAM that you can read or write in "blocks". Keeping individual variables in VRAM and manipulating them one at a time would be very tedious and slow. With some planning and creative thinking you can usually fit all your variables into the scratch pad, but if you really find you have run out of room, you can use VRAM.

 

For your example, the steps you would need to take would be more like this:

 

set up VDP read address

read score MSB from VRAM into R0 MSB

read score LSB from VRAM into R0 LSB

add value to R0 (the value could be in another register, a read only value from ROM, or some other variable in scratch pad)

set up the VDP write address

write score MSB into VRAM

write score LSB into VRAM

 

Also keep in mind that setting up the VDP read and write addresses are a few instructions each, so you are talking about a *lot* of overhead just to update a single variable. For a variable that changes as much as a score, I would not keep it in VRAM. Now, something like the number of lives remaining, that would be a good candidate for storage in VRAM since you only need to read it after the player is killed (or whatever happens in your game.)

 

Matthew

Link to comment
Share on other sites

But that is only because I have worked with the sample programs from Matthew and have made them work. I have not made them work because I understand what I am doing. More trial and error then anything.

 

That's how it works. When I was learning BASIC, I would type the programs in from books or magazines (back when there were "computer" magazines and they had program listings in them), run them, then start changing things to see what happened. Hacking and reading other people's code is how you will learn most of your programming, you learn the rest by teaching.

 

If you don't understand something, break it down into smaller pieces until you do understand, then start adding things back. I try to keep my code examples short and to the point, especially the "skeleton" programs in my assembly thread. Unfortunately there is just a certain amount of *stuff* you have to include to support an assembly program that displays something on the screen. You have to obtain a critical mass of knowledge to understand it all, and until then you will just be using pieces that do what you need, even though you're not quite sure why.

 

When I was learning assembly, I had no idea what VMBW did, or what the VSBW, VSBR, etc. really were, other than the books I had said you use those instructions to write and read VRAM data. I was unsure what the "workspace" pointer was and I certainly did not understand that the registers were memory based. However, by looking at the examples in various books, and reading the Tombstone City code, I managed to write programs that actually worked. It was not until I rediscovered my TI in about 2001 that I really understood the details of the computer, and even then only when I used it. If I quite coding in assembly for a few weeks, I'm always having to go back and look stuff up again. C'est la vie.

 

Matthew

Link to comment
Share on other sites

ok Matthew,

I was thinking the character patterns would be readable from ROM addresses. But it makes sense that it would be in VDP memory for speed. I am guessing that that 2K for the pattern table are fixed memory positions? or is it a good programming practice thing to always use the same base address for the tables?

 

 

You say the sprite patterns can be separate, so we can have 256 character definitions and another 32 for sprites?

 

Thanks alot for the help, I'll have some nice stuff coming for the TI-community at some point.

 

John

Link to comment
Share on other sites

The character patterns have to be in VRAM so the 9918A (the video chip in the TI) VDP (video display processor) can use the patterns to display them on the screen. The VRAM is "owned" by the VDP, and to gain access to that memory the system has to go "through" the VDP. Of course those patterns have to come from somewhere, so your pattern data is copied from the ROM into the VRAM.

 

The location in VRAM of the various tables are programmable via the VDP's write-only registers. Each table has specific location possibilities, but there are too many to post here. The 9918A datasheet lists all the possible memory location for any given table. But basically the "name" table can be anywhere in VRAM on a 1K boundary. The pattern table, depending on the mode, has a 2K boundary, so 8 possible locations.

 

As for a standard of where the tables are located, I don't think there is one. I set the tables up how I need them.

 

There is a VDP register to designate the location character pattern table, and a separate register to designate the location of the sprite pattern table. Both tables are on 2K boundaries and both can point to the same location or different locations. The sprite pattern table is just as big as the character pattern table, i.e. 8 bytes * 256 characters, or 2K. So, you can have 256 character patterns for "tiles" and another 256 separate patterns for sprites.

 

Matthew

Link to comment
Share on other sites

I did miss one point I should have addressed, until Cory releases an update to Win994A, you can get his patched binary from me at http://harmlesslion.com/temp/WinAsm99.zip

 

Just backup the old EXE and replace it with this one. Cory provided that binary to me directly as a test, so I doubt there's any warranty. ;)

 

Also Classic99 supports up to 128k of bank-switched ROM with Jon's scheme. ;)

Link to comment
Share on other sites

I did miss one point I should have addressed, until Cory releases an update to Win994A, you can get his patched binary from me at http://harmlesslion.com/temp/WinAsm99.zip

 

Just backup the old EXE and replace it with this one. Cory provided that binary to me directly as a test, so I doubt there's any warranty. ;)

 

Also Classic99 supports up to 128k of bank-switched ROM with Jon's scheme. ;)

 

 

 

Great I had looked for 1.010 version of win994a but it doesn't exist. This fixes the JH problem right?

Link to comment
Share on other sites

I did miss one point I should have addressed, until Cory releases an update to Win994A, you can get his patched binary from me at http://harmlesslion.com/temp/WinAsm99.zip

 

Great I had looked for 1.010 version of win994a but it doesn't exist. This fixes the JH problem right?

 

I don't know the version number offhand, but yes, it fixes JH. :)

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