Omega-Race cartridge made to run on 8K ram expansion.

Basic and Machine Language

Moderator: Moderators

tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Omega-Race cartridge made to run on 8K ram expansion.

Post by tlr »

Hi everyone,
I just uncartridged Omega-Race, it will now run on 8Kb ram expansion. (without the cartridge ofcourse) While I was at it I added a fix for centering the screen correctly on both PAL and NTSC.
http://www.kahlin.net/~tlr/vic20/omega-race_8k.prg
Please try it out and report if it works ok. I played it for a while, but you never know.

Technically this involved relocating the code from $A000 to $2000. Although I did this in VICE, I used only HESMON (1.1) + 16Kb mem as tools. It took more effort than I initially expected, most of which was unfortunately due to rusty 6502 knowledge. :?

I'll post more details if anyone is interested how to do it... :)
Tepic
Vic 20 Devotee
Posts: 209
Joined: Wed Mar 24, 2004 10:47 pm

Post by Tepic »

You people are FAR to smart for me.
6502dude
megacart
Posts: 1581
Joined: Wed Dec 01, 2004 9:53 am

Re: Omega-Race cartridge made to run on 8K ram expansion.

Post by 6502dude »

tlr wrote:
I'll post more details if anyone is interested how to do it... :)
Great work!!!

I would be interested in more details.

I don't have much interest in playing the games, but I enjoy technical stuff.
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Omega-Race cartridge made to run on 8K ram expansion.

Post by tlr »

6502dude wrote: Great work!!!

I would be interested in more details.
Thanks!
6502dude wrote:I don't have much interest in playing the games, but I enjoy technical stuff.
Same here. :)


How to relocate Omega-Race, or mostly any other cartridge game for the VIC-20.
by Daniel Kahlin 2005-03-14

Tools:
-----
* vic20 (or emulator)
* HesMon (v1.1, 1982)
* 16Kb memory (could probably do it with 8Kb)
* Resetbutton (could probably do without)

I assume that we already have a cartridge dump of our original
Omega-Race cartridge on disk.


Ok...
First we must decide what we are about to do.
The original cartridge resides at $A000 and runs on a otherwise unexpanded VIC. This means it has code from $A000-$BFFF and possibly has data from
$0000-$03FF + $1000-$2000.

If we have a VIC with an 8Kb mem cartridge it will have additional RAM at $2000-$4000. This is just the size of the cartridge ROM, perfect!

Task: Relocate the Code from $A000 to $2000.


First load the cartridge image from disk to $2000. In HesMon this turned out to be a problem because you cannot override the load address with the 'L' command. I had to write a small basic program to do this.

Now comes the hard part...

Pass 1:
Disassemble by hand from $2000 to $4000 to determine which areas are code, and which are data.
This requires some experience in 6502 machine-language because when the disassembler sees data, it will here and there find something that looks like an instruction and display it. This instruction is not necessarily aligned with the first instruction after the data block ends so it might mask the start of the next code block.

We see an example of this right at the beginning of the code:

Code: Select all

D2000 2018
,2000 09 A0    ORA #$A0
,2002 8D B4 41 STA $41B4
,2005 30 C3    BMI $1FCA
,2007 C2       ???
,2008 CD D8 20 CMP $20D8
,200B 8D FD 20 STA $20FD
,200E 8A       TXA
,200F FF       ???
,2010 20 F9 FD JSR $FDF9  <-- here it starts to look like code.
,2013 A9 1E    LDA #$1E
,2015 8D 88 02 STA $0288
,2018 20 18 E5 JSR $E518

Code: Select all

D2000 2018
,2009 D8       CLD        <-- but this was the start.
,200A 20 8D FD JSR $FD8D
,200D 20 8A FF JSR $FF8A
,2010 20 F9 FD JSR $FDF9
,2013 A9 1E    LDA #$1E
,2015 8D 88 02 STA $0288
,2018 20 18 E5 JSR $E518
In this particular case we know that the data at $2000 is a cartridge header so:

Code: Select all

M2000 200F
:2000 09 A0 8D B4 41 30 C3 C2
:2008 CD D8 20 8D FD 20 8A FF
41 30 C3 C2 CD (A0CBM) is the tag for an autostart cartridge at $A000.
The first word is the reset address 09,A0 = $A009, the next is the NMI address, 8D,B4 = $B48D. Remember to relocate these!

We continue identifying code and data, and will eventually end up with:

Code: Select all

2000 - 2008  Data
2009 - 2373  Code
2374 - 23FF  Data
2400 - 2441  Code
2442 - 2451  Data
2452 - 24E6  Code
24E7 - 2506  Data
2507 - 282A  Code
282B - 284E  Data
284F - 287E  Code
287F - 2886  Data
2887 - 2958  Code
2959 - 2969  Data 
296A - 2AD6  Code
2AD7 - 2AFE  Data
2AFF - 2B92  Code
2B93 - 2B9A  Data
2B9B - 2BE5  Code
2BE6 - 2BF5  Data
2BF6 - 2C16  Code
2C16 - 2C52  Data
2C53 - 2C9F  Code
2CA0 - 2CAC  Data
2CAD - 2D92  Code
2D93 - 2D9C  Data
2D9D - 2E06  Code
2E07 - 2E46  Data
2E47 - 3081  Code
3082 - 30B5  Data
30B6 - 3169  Code 
316A - 3179  Data
317A - 3495  Code
3496 - 3FFF  Data
Absolute addressing mode instructions within the code areas can now be relocated using the 'N' New Locator command in HesMon.
Neat!

Pass 2...

More hard work!

We must find all instructions that directly load or add the MSB of an address.
Based on experience this would be some of these:

Code: Select all

LDA #$A0-BF --> A9 XX
LDX #$A0-BF --> A2 XX
LDY #$A0-BF --> A0 XX
ADC #$A0-BF --> 69 XX 
ORA #$A0-BF --> 09 XX
We do this the hard way...
LDA #:

Code: Select all

H 2000 3FFF A9 A0
21A6  <-- MSB load irq
(A1 none)
H 2000 3FFF A9 A2
2B0F  <-- unaligned
(A3-A4 none)
H 2000 3FFF A9 A5
2BB0  <-- mul?
H 2000 3FFF A9 A6
3407  <-- LSB indirect JSR address.
(A7 none)
H 2000 3FFF A9 A8
340C  <-- MSB indirect JSR address.
H 2000 3FFF A9 A9
33FC  <-- MSB indirect JSR address.
H 2000 3FFF A9 AA
3BA7  <-- data
(AB-BF none)
LDX #:

Code: Select all

(A0 none)
H 2000 3FFF A2 A1
33A5    <-- LSB load
H 2000 3FFF A2 A2
35F9    <-- data
H 2000 3FFF A2 A3
3BA0    <-- data
(A4-A7 none)
H 2000 3FFF A2 A8
3252   <-- LSB load
(A9-B9 none)
H 2000 3FFF A2 BA
35FA   <-- Data
(BB-BF none)
LDY #:

Code: Select all

H 2000 3FFF A0 A0
36CF 36D0 36EE 37A1 37
B7 37B8 37D6 37D9 37EE
 37F1 3800 3801 3807 3
808 3809 380F 3810 381
F 3820 3829 383E 383F 
3840 3846 3847 3848 38
4E 384F 3856 3859 385E  <-- data
(A1 none)
H 2000 3FFF A0 A2
3B9E                    <-- data
(A3-A8 none)
H 2000 3FFF A0 A9
22F7          <-- unaligned
(AA-B3 none)
H 2000 3FFF A0 B4
2410          <-- y offset.
(B5-B6 none)
H 2000 3FFF A0 B7
31FB          <-- MSB $b728 jsr $32cc (copy/render)
(B8-BA none)
H 2000 3FFF A0 BB
31DC         <-- MSB $bb86  jsr $32cc (copy/render)
H 2000 3FFF A0 BC
3213 3234    <-- MSB $bc10  jsr $32cc (copy/render)
             <-- MSB $bc67  jsr $32cc (copy/render) 
H 2000 3FFF A0 BD
3254         <-- MSB $bda8  jsr $32cc (copy/render)
H 2000 3FFF A0 BE
20BD 326E 33A7 <-- MSB $be94  jsr $32cc (copy/render)
               <-- MSB $be0a  jsr $32cc (copy/render)
               <-- MSB $bea1  jsr $32cc (copy/render)
(BF none)
ADC #:

Code: Select all

H 2000 3FFF 69 A0
2ACC   <-- LSB add.
(A1-B3 none)
H 2000 3FFF 69 B4
2BB3   <-- MSB add.
(B5-BF none)
ORA #:

Code: Select all

(A0-AC none)
H 2000 3FFF 09 AD
345E  <-- unaligned
(AE-BC none)
H 2000 3FFF 09 BD
3052  <-- unaligned
(BE-BF none)
Pass 3...
We try to check if there is any references to absolute addresses inside data tables and similar. After examining the code and data hunting for different addresses and similar it seems there are none of these. Hope I didn't miss any!

The relocation:
The 'N' New Locator command is neat, because it parses machine code between two addresses, and adds an offset to all absolute references found accessing a certain area.
N <start> <end> <offset> <areastart> <areaend>

We know what is code and what is data, so:

Code: Select all

N 2009 2373 8000 A000 BFFF
N 2400 2441 8000 A000 BFFF
N 2452 24E6 8000 A000 BFFF
N 2507 282A 8000 A000 BFFF
N 284F 287E 8000 A000 BFFF
N 2887 2958 8000 A000 BFFF
N 296A 2AD6 8000 A000 BFFF
N 2AFF 2B92 8000 A000 BFFF
N 2B9B 2BE5 8000 A000 BFFF
N 2BF6 2C16 8000 A000 BFFF
N 2C53 2C9F 8000 A000 BFFF
N 2CAD 2D92 8000 A000 BFFF
N 2D9D 2E06 8000 A000 BFFF
N 2E47 3081 8000 A000 BFFF
N 30B6 3169 8000 A000 BFFF
N 317A 3495 8000 A000 BFFF
Remember the vectors at the beginning:

Code: Select all

M 2000 
:2000 09 A0 8D B4 41 30 C3 C2 --> :2000 09 20 8D 34 41 30 C3 C2
And our absolute references:

Code: Select all

,20BD A0 BE    LDY #$BE --> A0 3E    LDY #$3E
,21A6 A9 A0    LDA #$A0 --> A9 20    LDA #$20
,2BB3 69 B4    ADC #$B4 --> 69 34    ADC #$34
,31FB A0 B7    LDY #$B7 --> A0 37    LDY #$37
,31DC A0 BB    LDY #$BB --> A0 3B    LDY #$3B
,3213 A0 BC    LDY #$BC --> A0 3C    LDY #$3C
,3234 A0 BC    LDY #$BC --> A0 3C    LDY #$3C
,3254 A0 BD    LDY #$BD --> A0 3D    LDY #$3D
,326E A0 BE    LDY #$BE --> A0 3E    LDY #$3E
,33A7 A0 BE    LDY #$BE --> A0 3E    LDY #$3E
,33FC A9 A9    LDA #$A9 --> A9 29    LDA #$29
,340C A9 A8    LDA #$A8 --> A9 28    LDA #$28
Now save your work!

Code: Select all

S "RELOC" 08 2000 4000
Crack...
Unfortunately it still doesn't run. We forgot to crack the cartridge protection!
This is usually some code that does writes to the cartridge ROM, and checks that the contents doesn't change.
Here you need to hunt for STA $, STX $, STY $ within the cartridge range. Remember that this is now $2000 to $3FFF. I leave this as exercise to the reader.
Result:

Code: Select all

,3166 8D 6D A4 STA $246D --> EA       NOP
,3167                        EA       NOP
,3168                        EA       NOP
The second one is easy to get wrong. It is part of a timing loop. We could just NOP it out, but then something would slow down. (6 * NOP = 12 cycles, 2* STA $ = 8 cycles) We can change it to write at another address instead. $2008 in the cartridge header isn't use anymore.

Code: Select all

,33C5 8D AD A1 STA $21AD --> 8D 08 20 STA $2008
,33C8 8D BD A1 STA $21BD --> 8D 02 20 STA $2008
We need to start the code in an environment that looks a bit like a reset.

Code: Select all

A2000 78       SEI
A2003 4C 09 20 JMP $2009
A2004
Now save...

Code: Select all

S "FINAL" 08 2000 4000
We've done it!

Code: Select all

LOAD"FINAL",8,1
SYS 8192
Hope you enjoy it!
Regards
/Daniel
d0c
Vic 20 Devotee
Posts: 278
Joined: Wed May 03, 2006 5:21 pm

Post by d0c »

will you also do other games?

radar rat race
gorf

etc...
User avatar
Jeff-20
Denial Founder
Posts: 5759
Joined: Wed Dec 31, 1969 6:00 pm

Post by Jeff-20 »

I'm so glad I made this message board.
High Scores, Links, and Jeff's Basic Games page.
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

I think it was more proof of concept than a series of planned conversions. Is there a great demand in converting cartridge games to run with a standard memory expansion? If so, which game(s) are most wanted?
Anders Carlsson

Image Image Image Image Image
d0c
Vic 20 Devotee
Posts: 278
Joined: Wed May 03, 2006 5:21 pm

Post by d0c »

carlsson wrote:I think it was more proof of concept than a series of planned conversions. Is there a great demand in converting cartridge games to run with a standard memory expansion? If so, which game(s) are most wanted?
radar rat race
gorf

:wink:
User avatar
hawk
Vic 20 Afficionado
Posts: 342
Joined: Mon Jun 20, 2005 7:32 pm

Add to a Wiki

Post by hawk »

tlr,

That's an excellent description of the conversion process. Well done!
A valuable contribution to the information pool. :D

Do you have somewhere suitable on your site (or someone elses) where it could be stored as a doc?

Hawk.
User avatar
orion70
VICtalian
Posts: 4341
Joined: Thu Feb 02, 2006 4:45 am
Location: Piacenza, Italy
Occupation: Biologist

Post by orion70 »

I think it was more proof of concept than a series of planned conversions. Is there a great demand in converting cartridge games to run with a standard memory expansion? If so, which game(s) are most wanted?
Of course there is GREAT demand... With those crazy cart prices getting higher and higher :evil:

How about rare carts with excellent gameplay? I'd say, for example, Chopper, Pole Position, and Satellites & Meteorites :shock:

Waiting and hoping,
Alex
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

But doesn't a memory expansion demand just as high cart prices? Perhaps only a few non-switchable ones can be made switchable.

Currently I'm busy with other stuff, but perhaps someone else will give it a try or at a later time. I find nbla's tapes a bit more interesting to fix, since those are games not previously archived (and theoretically much easier to "convert" than fixing all memory accesses from a cartridge image).
Anders Carlsson

Image Image Image Image Image
User avatar
Schlowski
NoMess!
Posts: 892
Joined: Tue Jun 08, 2004 12:20 pm

Post by Schlowski »

But for a memory expansion you only have to pay once as opposed to pay for every cartridge...

Björg
User avatar
nbla000
Salmon Run
Posts: 2582
Joined: Thu Oct 13, 2005 8:58 am
Location: Italy

Post by nbla000 »

My opinion, it's relative simple to find a switchable 16k or more expansion, there are sites too that explains how to made one starting from an original 8/16k expansion very common to found on ebay, using these memory expansions you may load almost all the cartridges released for the Vic-20 stored to a floppy or a tape as rom image, take e look to a my previous thread.
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Post by Boray »

I totally agree!
PRG Starter - a VICE helper / Vic Software (Boray Gammon, SD2IEC music player, Vic Disk Menu, Tribbles, Mega Omega, How Many 8K etc.)
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Add to a Wiki

Post by tlr »

d0c wrote:will you also do other games?

radar rat race
gorf

etc...
It didn't seem to be much demand before your post here, so I haven't thought about it.
Maybe it's someone elses turn to try, you have the tutorial! :)
carlsson wrote:I think it was more proof of concept than a series of planned conversions. Is there a great demand in converting cartridge games to run with a standard memory expansion? If so, which game(s) are most wanted?
It was a proof of concept, but it was real fun doing it! :)
hawk wrote:That's an excellent description of the conversion process. Well done!
A valuable contribution to the information pool. :D

Do you have somewhere suitable on your site (or someone elses) where it could be stored as a doc?
Thanks! :)
It is only stored here currently, but I guess I could but it on my page somewhere.

@all:
I personally think there is a point in converting cartridge games to running on standard 8Kb/16Kb expansion.
People can then just get one of those, and do LOAD/RUN and it will work.

Many of you are collectors that want the original cartridge, and if so you should ofcourse get that.
For the rest of us, I prefer LOAD/RUN.

The real point is ofcourse the fun of converting!
Post Reply