Jump to content
IGNORED

Harmony and 7800 detection


Omegamatrix

Recommended Posts

I just checked the "stall" (as we call it) code and unfortunately I have to correct myself again. Yes, there are a few bytes at the end free, but those are required to preserve some variables for the menu which "stalls" when selecting a new page too.

 

We could overwrite those variables when loading a game or we could use different RAM code when loading a game (so we don't need those variables anymore). Option one won't help much, since we cannot reuse the existing checks at $D0 and for the 2nd option there isn't enough space in ROM.

 

I suggest that there are two 7800 auto detect signatures used. The original 7800 one and another one which is based on the RAM kernel. There we have to find a way to change a bit or so without changing the functionality. And this byte and another one should be used for the 7800 detection when loaded from Harmony.

Link to comment
Share on other sites

I just checked the "stall" (as we call it) code and unfortunately I have to correct myself again. Yes, there are a few bytes at the end free, but those are required to preserve some variables for the menu which "stalls" when selecting a new page too.

 

We could overwrite those variables when loading a game or we could use different RAM code when loading a game (so we don't need those variables anymore). Option one won't help much, since we cannot reuse the existing checks at $D0 and for the 2nd option there isn't enough space in ROM.

 

I suggest that there are two 7800 auto detect signatures used. The original 7800 one and another one which is based on the RAM kernel. There we have to find a way to change a bit or so without changing the functionality. And this byte and another one should be used for the 7800 detection when loaded from Harmony.

 

 

 

If I'm understanding you right, then something like this?

 

START:
   sei
   ldx    $D0                   ; initial test for 7800 (using old algorithym)
   cpx    #$2C
   bne    .testForHarmony
   ldx    $D1
   cpx    #$A9
   bne    .testForHarmony
   beq    .startClearLoop       ; always branch, 7800 detected and the carry is set too

.testForHarmony:
   ldx    byteA
   cpx    #HARMONY_BYTE_A       ; - this doesn't tell you if it's a 7800... it's just tested for extra confirmation of a Harmony cart. It'll be the same
   bne    .not7800              ;   value for the harmony whether it's a 7800 or not. However, it is a more uncommon value overall (i.e. not #$FF or #$00)
   ldx    byteB                 ; - this byte changes to indicate a 7800 has has been detected!! It is also an uncommon value
   cpx    #HARMONY_BYTE_B
   beq    .startClearLoop       ; 7800 detected, and the carry has been set automatically
.not7800:
   clc                          ; 2600 detected, clear the future flag

   .byte $2C                    ; BIT opcode, skip 2 bytes
RESET:
   lsr    consoleType           ; move previous 2600/7800 detection into carry

.startClearLoop:
   cld
   ldx    #0
   txa
.loopClear:
   dex
   txs
   pha
   bne    .loopClear
   rol    consoleType           ; move 7800 detection into bit 0

 

 

I also got rid of the illegal NOP (bit won't trigger anything bad in this case!) Even though the illegal NOP worked fine for me on a couple of real 7800's, I kept thinking about maybe it's not a good thing to use until it gets locked into 2600 mode. I was also quite pleased to find out that I don't have to set the carry. If the compare instruction is true for an equal, the carry is always set.

 

 

Also does anyone else find it annoying that the forum software is not defaulted to black text for code boxes? I guess it is hunting for key-words like a text editor, but for comments it is just plain awful to read.

Link to comment
Share on other sites

Okay, I'm a bit slow. You can save a few bytes by checking a value that both the Harmony and 7800 have in common first like Batari suggested.

 

 

START:
   sei
   ldx    $B8                   ; this byte is the same value on both the 7800 and Harmony
   cpx    #$85
   bne    .not7800
   ldx    $D1                   ; this byte is unqiue to a 7800
   cpx    #$A9
   bne    .testForHarmony
   bcs    .startClearLoop       ; always branch, 7800 detected and the carry is set too

.testForHarmony:
   ldx    specificRamInTIA      ; - this byte changes to indicate a 7800 has has been detected!! It is also an uncommon value
   cpx    #HARMONY_7800_FLAG
   beq    .startClearLoop       ; 7800 detected, and the carry has been set automatically
.not7800:
   clc                          ; 2600 detected, clear the future flag

   .byte $2C                    ; BIT opcode, skip 2 bytes
RESET:
   lsr    consoleType           ; move previous 2600/7800 detection into carry

.startClearLoop:
   cld
   ldx    #0
   txa
.loopClear:
   dex
   txs
   pha
   bne    .loopClear
   rol    consoleType           ; move 7800 detection into bit 0

 

 

This code seems a lot more economical now.

Link to comment
Share on other sites

A couple of things: I think the code I posted earlier is the "test" version, as it appears to exit with a console switch and not the BIT $1FF4 on the actual version.

 

Here is the correct code:

 1C 16 3F 1F  07 03 16 04  3C 7E 5F 3F  03 05 00 00
3C 7E FB B0  F2 20 00 00  3C 78 F4 F0  F0 D0 60 00
3C 7E FF FF  FF FF 7E 3C  B5 80 85 5B  B5 A0 85 5C
CA 85 42 85  42 10 F1 4A  85 41 A2 80  A9 9E E8 E8
87 BB A9 98  87 A9 A0 F6  98 E9 7D 69  03 D0 05 2C
F4 1F 50 20  2A 0A 85 42  85 40 88 D0  EB A0 06 84
41 A9 0A 85  46 49 B8 85  47 E0 9E D0  04 46 DE 85
E2 BA D0 B4  18 6C FC FF  85 5B 86 60  86 61 88 A9

 

Second thing is I don't think we need to change any code.

 

The normal stall code looks something like this:

 bit $1ff4
 bvc exit

...
exit:
 clc
 JMP ($FFFC)

We pull D6 low to pull out of the stall and that causes the bit instruction to set V=0 and pull out of the stall. Maybe we pull D7 low for 2600 and high for 7800, and change the stall code for loading a game to this:

 bit $1ff4
 bvc exit

...
exit:
 clc
 bpl is_2600
 lda #$2c
 sta $d0
 lda #$a9
 sta $d1
is_2600:
 JMP ($FFFC)

This will require pre-detecting the 7800 in the boot code, free RAM in Harmony, and 10 bytes for 2 values or 6 bytes for one value when loading a game - there appear to be 8 bytes free. It might work with one but not sure about two.

Edited by batari
Link to comment
Share on other sites

Two possibilities jump out to me for clearing the carry, and storing to 2 locations all within 7 bytes. There are many more possibilities, but none very good. These aren't great either, but better than getting #$04, etc...

 

 

    LDA    #0C
   STA    $C2
   ASL         ; carry clear, #$18
   STA    $C8
   
   
   LDA    #$12
   STA    $BB
   ASL         ; carry clear, #$24
   STA    $BF
   
   
;and you still have $B8 (#$85), and $CD (#$D0) the same between Harmony and 7800

 

 

Of course you could clear the carry, load once and store in two locations within 7 bytes. Lots of duplicate values in the code including ($24, $85, $8D, $A9, $CB, $D0).

 

 

Or you could rely on $B8 or $CD for one of the bytes, and just load one extra in and clear the carry. I'm waiting to see if Thomas can work some magic though, and not free up 2 bytes but 12!! :P I'll keep trying here to see if there is something I can work for $D0 and $D1 too.

 

 

 

Edit: I forgot the branch. Still need bytes!!

 

 

Double Edit: If the stack pointer is at $FF you could use PLA to get #$A9 and save a byte. Then you just need one more byte.

Link to comment
Share on other sites

You still need the branch of course, but the carry needs to be cleared whether a 2600 or 7800 is detected.

 

Anyway, I just noticed that $D0/$D1 contain $F4/$1F which is the operand containing address we check to pull out of the stall. We don't really have to use $1FF4 - we chose that value since it was unlikely to come up randomly during the weird stuff the 2600 did during startup. $1F2C would work just fine and save a byte.

 

Therefore, we can do this:

 bit $1f2c
 bvc exit
...

exit:
 clc
 bpl is_2600
 lda #$a9
 sta $d1
is_2600
 JMP ($FFFC)

Edited by batari
Link to comment
Share on other sites

Alright then! If everything works then it's problem solved on multiple levels. All the old hacks will now work without modification, and there is still is a couple of bytes free if stuff needs to shift around in the future.

 

 

Anyhow I'll wait and try it out whenever it's ready. Too late for me tonight though. I wanted to say thank you to you Batari and Thomas for putting time and effort into this. I think it'll be well worth it. :)

Link to comment
Share on other sites

You still need the branch of course, but the carry needs to be cleared whether a 2600 or 7800 is detected.

 

Anyway, I just noticed that $D0/$D1 contain $F4/$1F which is the operand containing address we check to pull out of the stall. We don't really have to use $1FF4 - we chose that value since it was unlikely to come up randomly during the weird stuff the 2600 did during startup. $1F2C would work just fine and save a byte.

 

Therefore, we can do this:

 bit $1f2c
 bvc exit
...

exit:
 clc
 bpl is_2600
 lda #$a9
 sta $d1
is_2600
 JMP ($FFFC)

No space for that. Sorry.

Link to comment
Share on other sites

You still need the branch of course, but the carry needs to be cleared whether a 2600 or 7800 is detected.

 

Anyway, I just noticed that $D0/$D1 contain $F4/$1F which is the operand containing address we check to pull out of the stall. We don't really have to use $1FF4 - we chose that value since it was unlikely to come up randomly during the weird stuff the 2600 did during startup. $1F2C would work just fine and save a byte.

 

Therefore, we can do this:

 bit $1f2c
 bvc exit
...

exit:
 clc
 bpl is_2600
 lda #$a9
 sta $d1
is_2600
 JMP ($FFFC)

No space for that. Sorry.

When you say there's no space, what are you referring to? This would be needed only when loading a game, so maybe the last 8 bytes of RIOT RAM aren't needed.

Link to comment
Share on other sites

No space for that. Sorry.

When you say there's no space, what are you referring to? This would be needed only when loading a game, so maybe the last 8 bytes of RIOT RAM aren't needed.

It's 7 bytes in NTSC and 5 bytes in PAL BIOS.

If we have to, we can change $D0/$D1 to $2C/$58, and we could do this (carry is always set upon entry)

  bit $582c
 bvc exit
...

exit:
 bpl is_2600
 rol $d1
is_2600
 clc
 JMP ($FFFC)

That's just 4 extra bytes.

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

Would there be any difficulty with using some of the ARM's RAM to hold code to set up the RIOT RAM the way programs are going to expect it?

You mean, after stalling, the PC would switch to ARM RAM, there we overwrite the 128 bytes ZP RAM and then switch to the game?

 

Not sure if that's possible.

Link to comment
Share on other sites

  • 3 months later...
  • 1 month later...

Hi guys,

 

Just giving this a friendly three month bump. I hope at some point there will time to make this happen. :)

 

 

Hi,

 

I`ve been considering buying a harmony cartridge for the past months.

I would like to know if it work in the 7800 to play 7800 games and 5200 and 2600 games.

 

Does it work ?

 

It will play 2600 games on a 7800. If the proto Harmony 2 comes out it will play 2600 and 7800 games on a 7800.

 

Mitch

Link to comment
Share on other sites

  • 1 month later...

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