Author Topic: [Request] Myth hw details  (Read 2777 times)

0 Members and 1 Guest are viewing this topic.

Offline mic_

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 632
[Request] Myth hw details
« on: April 12, 2010, 04:05:57 PM »
The menu code contains a bunch of dummy reads like this one:

Code: [Select]
         LDA    #$E0      ; SET BANK   ;1 1 1 0
         STA.L  MYTH_GBAC_LIO
         LDA.L  $FC2A00  ; FE15XX     ;05

The values that are read from these addresses are not used for anything. Do the reads serve any purpose? Is is part of some kind of unlocking sequence? Could Dr Neo or someone else with knowledge about the Myth hardware elaborate on this?

I'm also wondering what the functions of the following Myth I/O registers are:
$C017
$C01F
$C040
« Last Edit: April 12, 2010, 04:12:04 PM by mic_ »

Offline ChillyWilly

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1751
  • Just a coding machine.
Re: [Request] Myth hw details
« Reply #1 on: April 12, 2010, 04:45:58 PM »
The GBA/NDS flash cards use a sequences as commands to do things. Look at the neo2.s code in the MD menu and you'll see those commands. Basically, you set the bank register for the upper bits of the command, then do a dummy read with the lower bits. The two combine to form the whole dummy address used to do an operation. Put several specific dummy operations together and you do things like activate the ID mode to read the ID of the flash card, or get the RTC, or set some control registers that switch between the menu flash, game flash, etc. The operations will be exactly the same as on the MD menu as the flash cards are the same. The difference is only doing the dummy read itself - you set the SNES Myth bank register and read from the space in SNES memory where the cart space exists.

Let's take a look at an example - from the neo2.s file in the MD menu, you find this for selecting the game flash:

Code: [Select]
| do a Neo Flash ASIC command
| entry: d0 = Neo Flash ASIC command
|        a1 = hardware base (0xA10000)
_neo_asic_cmd:
        move.l  d0,-(sp)
        /* do unlocking sequence */
        move.l  #0x00FFD200,d0
        bsr.b   _neo_asic_op
        move.l  #0x00001500,d0
        bsr.b   _neo_asic_op
        move.l  #0x0001D200,d0
        bsr.b   _neo_asic_op
        move.l  #0x00021500,d0
        bsr.b   _neo_asic_op
        move.l  #0x00FE1500,d0
        bsr.b   _neo_asic_op
        /* do ASIC command */
        move.l  (sp)+,d0
|       bsr.b   _neo_asic_op
|       moveq   #0,d0
        /* fall into _neo_asic_op for last operation */

| do a Neo Flash ASIC operation
| entry: d0 = Neo Flash ASIC operation
|             b23-16 = addr, b15-b0 = value
|        a1 = hardware base (0xA10000)
| exit:  d0 = result (usually dummy read)
_neo_asic_op:
        move.l  d0,d1
        rol.l   #8,d1
        andi.w  #0x000F,d1              /* keep b27-24 */
        move.w  d1,GBAC_HIO(a1)         /* set high bank select reg (holds flash space A27-A24) */
        rol.l   #8,d1
        andi.w  #0x00F8,d1              /* keep b23-19, b18-16 = 0 */
        move.w  d1,GBAC_LIO(a1)         /* set low bank select reg (holds flash space A23-A16) */
        andi.l  #0x0007FFFF,d0          /* b23-19 = 0, keep b18-b0 */
        add.l   d0,d0                   /* 68000 A19-A1 = b18-b0 */
        movea.l d0,a0
        move.w  (a0),d0                 /* access the flash space to do the operation */
        rts

| select Neo Flash Game Flash ROM
| allows you to access the game flash via flash space
| entry: a1 = hardware base (0xA10000)
_neo_select_game:
        move.w  #0x0000,OPTION_IO(a1)   /* set mode 0 */

        move.l  #0x00370203,d0
        bsr     _neo_asic_cmd           /* set cr = select game flash */
        cmpi.b  #0,gCardType
        bne.b   1f
        move.l  #0x00DAAE44,d0          /* set iosr = enable game flash for newest cards */
        bra.b   3f
1:
        cmpi.b  #1,gCardType
        bne.b   2f
        move.l  #0x00DA8E44,d0          /* set iosr = enable game flash for new cards */
        bra.b   3f
2:
        cmpi.b  #2,gCardType
        bne.b   4f
        move.l  #0x00DA0E44,d0          /* set iosr = enable game flash for old cards */
3:
        bsr     _neo_asic_cmd           /* set iosr = enable game flash */
4:
        move.l  #0x00EE0630,d0
        bsr     _neo_asic_cmd           /* set cr1 = enable extended address bus */
        move.w  #0xFFFF,EXTM_ON(a1)     /* enable extended address bus */
        move.w  #0x0000,PRAM_BIO(a1)    /* set psram to bank 0 */
        move.w  #0x00F0,PRAM_ZIO(a1)    /* psram bank size = 2MB */
        move.w  #0x0006,WE_IO(a1)       /* map bank 7, write enable myth psram */
        move.w  #0x0007,OPTION_IO(a1)   /* set mode 7 (copy mode) */
        rts

The unlocking sequence is the dummy read done by _neo_asic_cmd before it does the command passed in d0. So passing 0x00370203 to _neo_asic command does this sequence of dummy reads:

0x00FFD200
0x00001500
0x0001D200
0x00021500
0x00FE1500
0x00370203

The first five are a generic unlocking sequence, while the last is the actual command you wish to do. In this case, setting the control register in the flash to 0x0203, which enables the game flash. You'll notice after that, the IOSR is set to a specific value depending on the type of flash recorded in the menu flash. The final neo asic command set the CR1 to allow the Myth to address more flash. Then finally a few registers in the Myth itself are set. You'll have to get Dr.neo to comment on the SNES Myth registers, but the dummy reads can all be figured out from the MD menu as shown.

Offline mic_

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 632
Re: [Request] Myth hw details
« Reply #2 on: April 17, 2010, 06:27:10 PM »
I was looking at some pinout here: http://www.caitsith2.com/snes/flashcart/cart-chip-pinouts.html#cart

And according to neviksti there's a /RESET signal at pin 26. I don't know if pulling it low would trigger the entire system to reset, but I would guess so, given that the PowerPak seems to be able to reset the SNES. Does the FPGA currently have a function for doing a reset this way? If so, what value(s) do I need to write to which address(es)? If not, is this something that could be added?