comparison nor.c @ 1519:1f745318f10a

Made the NOR flash emulation a bit more flexible, but not yet flexible enough to properly support the flash chip in the MegaWiFi cart
author Michael Pavone <pavone@retrodev.com>
date Wed, 31 Jan 2018 22:05:10 -0800
parents d94855080529
children
comparison
equal deleted inserted replaced
1518:713b504dc577 1519:1f745318f10a
1 #include "genesis.h" 1 #include "genesis.h"
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <string.h> 3 #include <string.h>
4 #include "util.h"
4 5
5 enum { 6 enum {
6 NOR_NORMAL, 7 NOR_NORMAL,
7 NOR_PRODUCTID, 8 NOR_PRODUCTID,
8 NOR_BOOTBLOCK 9 NOR_BOOTBLOCK
29 state->last_write_cycle = 0xFFFFFFFF; 30 state->last_write_cycle = 0xFFFFFFFF;
30 state->mode = NOR_NORMAL; 31 state->mode = NOR_NORMAL;
31 state->cmd_state = NOR_CMD_IDLE; 32 state->cmd_state = NOR_CMD_IDLE;
32 state->alt_cmd = 0; 33 state->alt_cmd = 0;
33 state->bus_flags = bus_flags; 34 state->bus_flags = bus_flags;
34 } 35 state->cmd_address1 = 0x5555;
35 36 state->cmd_address2 = 0x2AAA;
36 void nor_run(nor_state *state, uint32_t cycle) 37 }
38
39 void nor_run(nor_state *state, m68k_context *m68k, uint32_t cycle)
37 { 40 {
38 if (state->last_write_cycle == 0xFFFFFFFF) { 41 if (state->last_write_cycle == 0xFFFFFFFF) {
39 return; 42 return;
40 } 43 }
41 if (cycle - state->last_write_cycle >= NOR_WRITE_PAUSE) { 44 if (cycle - state->last_write_cycle >= NOR_WRITE_PAUSE) {
42 state->last_write_cycle = 0xFFFFFFFF; 45 state->last_write_cycle = 0xFFFFFFFF;
43 for (uint32_t i = 0; i < state->page_size; i++) { 46 for (uint32_t i = 0; i < state->page_size; i++) {
44 state->buffer[state->current_page + i] = state->page_buffer[i]; 47 state->buffer[state->current_page + i] = state->page_buffer[i];
45 } 48 }
46 memset(state->page_buffer, 0xFF, state->page_size); 49 memset(state->page_buffer, 0xFF, state->page_size);
50 if (state->bus_flags == RAM_FLAG_BOTH) {
51 //TODO: add base address of NOR device to start and end addresses
52 m68k_invalidate_code_range(m68k, state->current_page, state->current_page + state->page_size);
53 }
47 } 54 }
48 } 55 }
49 56
50 uint8_t nor_flash_read_b(uint32_t address, void *vcontext) 57 uint8_t nor_flash_read_b(uint32_t address, void *vcontext)
51 { 58 {
60 } 67 }
61 if (state->bus_flags != RAM_FLAG_BOTH) { 68 if (state->bus_flags != RAM_FLAG_BOTH) {
62 address = address >> 1; 69 address = address >> 1;
63 } 70 }
64 71
65 nor_run(state, m68k->current_cycle); 72 nor_run(state, m68k, m68k->current_cycle);
66 switch (state->mode) 73 switch (state->mode)
67 { 74 {
68 case NOR_NORMAL: 75 case NOR_NORMAL:
76 if (state->bus_flags == RAM_FLAG_BOTH) {
77 address ^= 1;
78 }
69 return state->buffer[address & (state->size-1)]; 79 return state->buffer[address & (state->size-1)];
70 break; 80 break;
71 case NOR_PRODUCTID: 81 case NOR_PRODUCTID:
72 switch (address & (state->size - 1)) 82 switch (address & (state->size - 1))
73 { 83 {
78 case 2: 88 case 2:
79 //TODO: Implement boot block protection 89 //TODO: Implement boot block protection
80 return 0xFE; 90 return 0xFE;
81 default: 91 default:
82 return 0xFE; 92 return 0xFE;
83 } 93 } //HERE
84 break; 94 break;
85 case NOR_BOOTBLOCK: 95 case NOR_BOOTBLOCK:
86 break; 96 break;
87 } 97 }
88 return 0xFF; 98 return 0xFF;
100 switch(state->mode) 110 switch(state->mode)
101 { 111 {
102 case NOR_NORMAL: 112 case NOR_NORMAL:
103 if (state->last_write_cycle != 0xFFFFFFFF) { 113 if (state->last_write_cycle != 0xFFFFFFFF) {
104 state->current_page = address & (state->size - 1) & ~(state->page_size - 1); 114 state->current_page = address & (state->size - 1) & ~(state->page_size - 1);
115 }
116 if (state->bus_flags == RAM_FLAG_BOTH) {
117 address ^= 1;
105 } 118 }
106 state->page_buffer[address & (state->page_size - 1)] = value; 119 state->page_buffer[address & (state->page_size - 1)] = value;
107 break; 120 break;
108 case NOR_PRODUCTID: 121 case NOR_PRODUCTID:
109 break; 122 break;
127 } 140 }
128 if (state->bus_flags != RAM_FLAG_BOTH) { 141 if (state->bus_flags != RAM_FLAG_BOTH) {
129 address = address >> 1; 142 address = address >> 1;
130 } 143 }
131 144
132 nor_run(state, m68k->current_cycle); 145 nor_run(state, m68k, m68k->current_cycle);
133 switch (state->cmd_state) 146 switch (state->cmd_state)
134 { 147 {
135 case NOR_CMD_IDLE: 148 case NOR_CMD_IDLE:
136 if (value == 0xAA && (address & (state->size - 1)) == 0x5555) { 149 if (value == 0xAA && (address & (state->size - 1)) == state->cmd_address1) {
137 state->cmd_state = NOR_CMD_AA; 150 state->cmd_state = NOR_CMD_AA;
138 } else { 151 } else {
139 nor_write_byte(state, address, value, m68k->current_cycle); 152 nor_write_byte(state, address, value, m68k->current_cycle);
140 state->cmd_state = NOR_CMD_IDLE; 153 state->cmd_state = NOR_CMD_IDLE;
141 } 154 }
142 break; 155 break;
143 case NOR_CMD_AA: 156 case NOR_CMD_AA:
144 if (value == 0x55 && (address & (state->size - 1)) == 0x2AAA) { 157 if (value == 0x55 && (address & (state->size - 1)) == state->cmd_address2) {
145 state->cmd_state = NOR_CMD_55; 158 state->cmd_state = NOR_CMD_55;
146 } else { 159 } else {
147 nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle); 160 nor_write_byte(state, state->cmd_address1, 0xAA, m68k->current_cycle);
148 nor_write_byte(state, address, value, m68k->current_cycle); 161 nor_write_byte(state, address, value, m68k->current_cycle);
149 state->cmd_state = NOR_CMD_IDLE; 162 state->cmd_state = NOR_CMD_IDLE;
150 } 163 }
151 break; 164 break;
152 case NOR_CMD_55: 165 case NOR_CMD_55:
153 if ((address & (state->size - 1)) == 0x5555) { 166 if ((address & (state->size - 1)) == state->cmd_address1) {
154 if (state->alt_cmd) { 167 if (state->alt_cmd) {
155 switch(value) 168 switch(value)
156 { 169 {
157 case 0x10: 170 case 0x10:
158 puts("UNIMPLEMENTED: NOR flash erase"); 171 puts("UNIMPLEMENTED: NOR flash erase");
185 default: 198 default:
186 printf("Unrecognized unshifted NOR flash command %X\n", value); 199 printf("Unrecognized unshifted NOR flash command %X\n", value);
187 } 200 }
188 } 201 }
189 } else { 202 } else {
190 nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle); 203 nor_write_byte(state, state->cmd_address1, 0xAA, m68k->current_cycle);
191 nor_write_byte(state, 0x2AAA, 0x55, m68k->current_cycle); 204 nor_write_byte(state, state->cmd_address2, 0x55, m68k->current_cycle);
192 nor_write_byte(state, address, value, m68k->current_cycle); 205 nor_write_byte(state, address, value, m68k->current_cycle);
193 } 206 }
194 state->cmd_state = NOR_CMD_IDLE; 207 state->cmd_state = NOR_CMD_IDLE;
195 break; 208 break;
196 } 209 }