Jump to content
IGNORED

Possible to detect emulator from the code?


e1will

Recommended Posts

Is there a way for the code to detect whether it's being run under an emulator vs. on an actual 2600?

 

I realize this may be either a desirable development feature or an undesirable emulator bug to be squashed depending on how you look at it, but I'm just curious if there is currently a way to tell.

 

--Will

Link to comment
Share on other sites

Is there a way for the code to detect whether it's being run under an emulator vs. on an actual 2600?

 

I realize this may be either a desirable development feature or an undesirable emulator bug to be squashed depending on how you look at it, but I'm just curious if there is currently a way to tell.

 

--Will

 

As you said, the only way would be to find an emulator "bug" something that wasn't emulated properly that the CPU can detect. Even if you found this on one emulator it's unlikely that it would be the same on all emulators.

 

Dan

Link to comment
Share on other sites

If you want copy protection you need to prevent the BIN from being released in the first place. Once you have a BIN all you need to do is find the copy protection routine and hack it out.

 

In theory you could create a new banking scheme that emulators don't support, which would work as long as Stella isn't updated to support it.

 

Chimera native games were going to be hard to emulate just because Stella would have had to add an ARM emulator side by side with the VCS. So just the amount of work that would require would probably prevent it from happening anytime soon.

Link to comment
Share on other sites

If you want copy protection you need to prevent the BIN from being released in the first place.

 

Nah, I'm not interested in copy protection... I was mainly thinking of it in terms of the "pause" vs "color/BW" switch functionality. Since emulators generally include a pause function already, I thought I could use that switch as a "pause function" on a real 2600 and use it to display an alternate color palette in the emulator.

 

--Will

Link to comment
Share on other sites

Is there a way for the code to detect whether it's being run under an emulator vs. on an actual 2600?

 

I realize this may be either a desirable development feature or an undesirable emulator bug to be squashed depending on how you look at it, but I'm just curious if there is currently a way to tell.

 

--Will

There was a ROM released some time ago that exploited a bug in emulators. It printed 'EMU' if run on such an emulator, and '2600' if run on the real system. It actually does print '2600' when run in Stella, since the emulation was fixed. The other 2600 emulators still print 'EMU'. I don't know where to get the ROM right now, but it was originally mentioned on the Stella mailing list.

 

In any event, I would suggest not depending on emulator-specific things. Personally, if I ever find such a bug (and I do consider it a bug, since the emulator should be exactly the same as the real thing), I will try to fix it ASAP. I think you should always aim for full compatibility with the real thing, with the emulator helping you to achieve that goal (and being fixed if it doesn't match real hardware).

Link to comment
Share on other sites

Chimera native games were going to be hard to emulate just because Stella would have had to add an ARM emulator side by side with the VCS. So just the amount of work that would require would probably prevent it from happening anytime soon.

That depends. Any scheme that can be defined by a functional description can be emulated without actually running the underlying ARM code.

 

For the Harmony, I plan to provide specifications for any new schemes I create so they can be emulated without necessarily needing a full ARM emulation core. This will work except in cases where a programmer decides to use the user code stub for arbitrary ARM code.

Link to comment
Share on other sites

I remember a while back they were developing a standard for C-64 emulators that would allow an emulator to identify itself, and distinguish itself both from the real hardware and other emulators, using a certain phrase in memory that was otherwise read-only.

 

Does the Atari 2600 have any spare read-only bits that could be used for that purpose? Somebody would have to create the standard, and the emu devs would then have to adhere to the standard, of course, but it's a thought.

Edited by skunkworx
Link to comment
Share on other sites

I remember a while back they were developing a standard for C-64 emulators that would allow an emulator to identify itself, and distinguish itself both from the real hardware and other emulators, using a certain phrase in memory that was otherwise read-only.

 

Does the Atari 2600 have any spare read-only bits that could be used for that purpose? Somebody would have to create the standard, and the emu devs would then have to adhere to the standard, of course, but it's a thought.

 

I seem to recall a similar feature with an Apple ][ emulator I was using a few years back...

 

I know there are plenty of unused read-only locations, but that doesn't mean that existing cartridges aren't depending on a certain behavior when reading them (either by design or by accident) that using them for "what environment am I running on" info might break.

 

It's an interesting question what sort of locations COULD theoretically be used for that purpose without breaking anything... any address returning an indeterminate value might already be used by existing programs as a quasi-random number, and any address that always returned the same value might be relied on as well (again, either by design or accidentally).

 

(Then I guess there's the third category of hardware-dependent values... I was reading elsewhere that LDA $07 would return "$x7" on a 2600 but "$x0" on a 7800.)

 

--Will

Link to comment
Share on other sites

(Then I guess there's the third category of hardware-dependent values... I was reading elsewhere that LDA $07 would return "$x7" on a 2600 but "$x0" on a 7800.)

That is not reliable. Different EPROMs and different cartridge hardware (such as CC, CC2, Kroko) may produce different values on undriven bits even on the same console. If you release a binary, you have no way of knowing what sort of hardware the user will try.

Link to comment
Share on other sites

If you want copy protection you need to prevent the BIN from being released in the first place.

 

Nah, I'm not interested in copy protection... I was mainly thinking of it in terms of the "pause" vs "color/BW" switch functionality. Since emulators generally include a pause function already, I thought I could use that switch as a "pause function" on a real 2600 and use it to display an alternate color palette in the emulator.

 

--Will

 

Have it do both ;)

There are ways to increase the number of switch functions. For example, use a difficulty switch to choose between altering the palette in one position, and pause status in the other. Toggling the B&W switch then completes the function. All this would "cost" is one bit to hold each of the modes' flip status, and the B&W switch's flip status. Add an additional bit if you want 7800 console autodetection (so it's switch toggles mode options correctly). That comes to a total of 1 nybble of ram you'd burn.

When the B&W switch isn't being messed with, you can keep the difficulty switches assigned as player handicaps (their original intent). This "costs" nothing, because SWCHB holds them.

Link to comment
Share on other sites

Try this...you can have each of the 4 difficulty switch positions hold a seperate function that can be toggled on and off using the B&W switch (on either console). Never checked it, but it should work.

 

;7800 autodetection requires a special power-up sequence...

;execute on power-up ONLY.  Ram is overwritten, so 7800 detection would fail later
CONSOLE7800 = %00000100 ; I just used one of the remaining bits
START:
      cld                            ;2 Clear decimal mode
      sei                            ;2 and set the interrupt status
      lda    #$00                    ;2 clear A
      tay                            ;2 Console type = 2600
      ldx    $D0                     ;3 Check $D0
      cpx    #$2C                    ;2 Does it contain value $2C?
      bne    Not_7800                ;2 If not, branch (keep 2600 mode)
      ldx    $D1                     ;3 Check $D1
      cpx    #$A9                    ;2 Does it contain value $A9?
      bne    Not_7800                ;2 If not, branch (keep 2600 mode)
      ldy    #CONSOLE7800            ;2 Otherwise, store the bit
Not_7800:
;now, clear out all ram
      tax                            ;2 clear the X counter
Init_Ram_loop:
      dex                            ;2 count down 1
      txs                            ;2 give to the stack pointer
      pha                            ;3 ...and push #$00 into ram
      bne    Init_Ram_loop           ;2 branch 255 more times
;ram initialization done
      lda    SWCHB                   ;4
      and    #$08                    ;2
      sta    console                 ;3 save current B&W switch status to bit 4
      tya                            ;3 Save the console type...
      ora    console                 ;3  ...by merging into the same ram
      sta    console                 ;3

 

 

 

 

;During your game, check the status of the B&W switch...optimally on every frame
      lda    SWCHB                   ;4 load current switches for B&W status
      tax                            ;2 keep uncorrupted in an index register
      eor    console                 ;3 compare against previous value...
      and    #$08                    ;2 (mask out all other bits)
      beq    No_Switch_Change        ;2 branch if the same (branch to end)
      lda    console                 ;2 Is it playing on a 7800?
      and    #CONSOLE7800            ;2
      beq    Atari2600               ;2 Branch if not
;console type is 7800...skip B&W switch bounceback...
      txa                            ;2 first, get back current...
      and    #$08                    ;2 keep only Color/B&W
      beq    Switch_bounce           ;2 Skip if B&W
Atari2600:
      txa                            ;2 Fetch the difficulty switch positions (all 4)
      rol                            ;2 move to bits 0 and 1...
      rol                            ;2
      rol                            ;2
      and    #$03                    ;2  ...and mask out all others
      tax                            ;2 give to the index register
      lda    Flip_Table,x            ;4 load in the bit we want to flip
Switch_bounce:
      eor    console                 ;3  ...in the stored switches
      sta    console                 ;3 ALL DONE!
No_Switch_Change:

 

 

 

 

 

 

 

;Then throw this data table someplace...
Flip_Table: ;example...you can use any bit positions that
           ;don't conflict with the ones used for console
           ;type and current B&W flip status
      .byte %10000000 ; bit to use if both switches are "B"
      .byte %01000000 ; right switch "A", left switch "B"
      .byte %00100000 ; right switch "B", left switch "A"
      .byte %00010000 ; both switches "A"

 

 

Changes to the variable console are only happening when the B&W switch is flipped. You can read those bits later to decide on what to do for each case :) Because the difficulties are ignored by the B&W routine otherwise, you can use their status to provide two other off/on functions.

Link to comment
Share on other sites

Have it do both ;)

 

You're right, of course... To be honest I was just looking for an excuse to play with code that would detect the different environments, and the pause vs "emulator palette" thing seemed like a decent use of that (possibly nonexistent) feature/bug.

 

Speaking of 7800 console detection, I was reading the thread you started about code to handle the 7800 pause vs 2600 TV type switch, and was wondering you could re-post the code for that (if you're willing to share it). (The link you'd posted no longer works.)

 

--Will

 

EDIT: Never mind, I see you just posted it!

Edited by e1will
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...