1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - flashram.c                                              *
3  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4  *   Copyright (C) 2002 Hacktarux                                          *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21 
22 #include "flashram.h"
23 #include "pi_controller.h"
24 
25 #include "../api/m64p_types.h"
26 #include "../api/callbacks.h"
27 #include "../memory/memory.h"
28 #include "../ri/ri_controller.h"
29 
30 #include <string.h>
31 
init_flashram(struct flashram * flashram,void * user_data,void (* save)(void *),uint8_t * data)32 void init_flashram(struct flashram* flashram,
33       void* user_data,
34       void (*save)(void*),
35       uint8_t* data)
36 {
37    flashram->user_data = user_data;
38    flashram->save = save;
39    flashram->data = data;
40 }
41 
flashram_command(struct pi_controller * pi,uint32_t command)42 static void flashram_command(struct pi_controller *pi, uint32_t command)
43 {
44    unsigned int i;
45    struct flashram *flashram = &pi->flashram;
46    uint8_t *dram             = (uint8_t*)pi->ri->rdram.dram;
47 
48    switch (command & 0xff000000)
49    {
50       case 0x4b000000:
51          flashram->erase_offset = (command & 0xffff) * 128;
52          break;
53       case 0x78000000:
54          flashram->mode = FLASHRAM_MODE_ERASE;
55          flashram->status = 0x1111800800c20000LL;
56          break;
57       case 0xa5000000:
58          flashram->erase_offset = (command & 0xffff) * 128;
59          flashram->status = 0x1111800400c20000LL;
60          break;
61       case 0xb4000000:
62          flashram->mode = FLASHRAM_MODE_WRITE;
63          break;
64       case 0xd2000000:  // execute
65          switch (flashram->mode)
66          {
67             case FLASHRAM_MODE_NOPES:
68             case FLASHRAM_MODE_READ:
69                break;
70             case FLASHRAM_MODE_ERASE:
71                {
72                   for (i=flashram->erase_offset; i<(flashram->erase_offset+128); ++i)
73                      flashram->data[i^S8] = 0xff;
74                   flashram_save(flashram);
75                }
76                break;
77             case FLASHRAM_MODE_WRITE:
78                {
79                   for(i = 0; i < 128; ++i)
80                      flashram->data[(flashram->erase_offset+i)^S8]= dram[(flashram->write_pointer+i)^S8];
81                   flashram_save(flashram);
82                }
83                break;
84             case FLASHRAM_MODE_STATUS:
85                break;
86             default:
87                DebugMessage(M64MSG_WARNING, "unknown flashram command with mode:%x", (int)flashram->mode);
88                break;
89          }
90          flashram->mode = FLASHRAM_MODE_NOPES;
91          break;
92       case 0xe1000000:
93          flashram->mode = FLASHRAM_MODE_STATUS;
94          flashram->status = 0x1111800100c20000LL;
95          break;
96       case 0xf0000000:
97          flashram->mode = FLASHRAM_MODE_READ;
98          flashram->status = 0x11118004f0000000LL;
99          break;
100       default:
101          DebugMessage(M64MSG_WARNING, "unknown flashram command: %x", (int)command);
102          break;
103    }
104 }
105 
poweron_flashram(struct flashram * flashram)106 void poweron_flashram(struct flashram* flashram)
107 {
108    flashram->mode          = FLASHRAM_MODE_NOPES;
109    flashram->status        = 0;
110    flashram->erase_offset  = 0;
111    flashram->write_pointer = 0;
112 }
113 
flashram_save(struct flashram * flashram)114 void flashram_save(struct flashram* flashram)
115 {
116    flashram->save(flashram->user_data);
117 }
118 
format_flashram(uint8_t * flash)119 void format_flashram(uint8_t* flash)
120 {
121    memset(flash, 0xff, FLASHRAM_SIZE);
122 }
123 
read_flashram_status(void * opaque,uint32_t address,uint32_t * value)124 int read_flashram_status(void* opaque, uint32_t address, uint32_t* value)
125 {
126    struct pi_controller* pi = (struct pi_controller*)opaque;
127 
128    if ((pi->use_flashram == -1) || ((address & 0xffff) != 0))
129    {
130       DebugMessage(M64MSG_ERROR, "unknown read in read_flashram_status()");
131       return -1;
132    }
133    pi->use_flashram = 1;
134    *value = pi->flashram.status >> 32;
135    return 0;
136 }
137 
write_flashram_command(void * opaque,uint32_t address,uint32_t value,uint32_t mask)138 int write_flashram_command(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
139 {
140    struct pi_controller* pi = (struct pi_controller*)opaque;
141 
142    if ((pi->use_flashram == -1) || ((address & 0xffff) != 0))
143    {
144       DebugMessage(M64MSG_ERROR, "unknown write in write_flashram_command()");
145       return -1;
146    }
147    pi->use_flashram = 1;
148    flashram_command(pi, value & mask);
149    return 0;
150 }
151 
dma_read_flashram(struct pi_controller * pi)152 void dma_read_flashram(struct pi_controller *pi)
153 {
154    unsigned int dram_addr, cart_addr;
155    unsigned int i, length;
156    struct flashram* flashram = &pi->flashram;
157    uint32_t *dram            = pi->ri->rdram.dram;
158    uint8_t *mem              = flashram->data;
159 
160    switch (flashram->mode)
161    {
162       case FLASHRAM_MODE_STATUS:
163          dram[pi->regs[PI_DRAM_ADDR_REG]/4]   = (uint32_t)(flashram->status >> 32);
164          dram[pi->regs[PI_DRAM_ADDR_REG]/4+1] = (uint32_t)(flashram->status);
165          break;
166       case FLASHRAM_MODE_READ:
167          length = (pi->regs[PI_WR_LEN_REG] & 0xffffff) + 1;
168          dram_addr = pi->regs[PI_DRAM_ADDR_REG];
169          cart_addr = ((pi->regs[PI_CART_ADDR_REG]-0x08000000)&0xffff)*2;
170 
171          for (i = 0; i < length; ++i)
172             ((uint8_t*)dram)[(dram_addr+i)^S8] = mem[(cart_addr+i)^S8];
173          break;
174       default:
175          DebugMessage(M64MSG_WARNING, "unknown dma_read_flashram: %x", flashram->mode);
176          break;
177    }
178 }
179 
dma_write_flashram(struct pi_controller * pi)180 void dma_write_flashram(struct pi_controller *pi)
181 {
182    struct flashram *flashram = &pi->flashram;
183 
184    switch (flashram->mode)
185    {
186       case FLASHRAM_MODE_WRITE:
187          flashram->write_pointer = pi->regs[PI_DRAM_ADDR_REG];
188          break;
189       default:
190          DebugMessage(M64MSG_ERROR, "unknown dma_write_flashram: %x", flashram->mode);
191          break;
192    }
193 }
194