OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [Open8 Tools/] [open8_src/] [open8_link/] [compute.c] - Blame information for rev 224

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 178 jshamlet
 
2
#include <ctype.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
 
7
#include "defines.h"
8
#include "memory.h"
9
#include "compute.h"
10
 
11
 
12
extern unsigned char *rom;
13
extern int romsize, sms_checksum, gb_checksum, gb_complement_check, snes_checksum;
14
extern int snes_rom_mode;
15
 
16
 
17
int compute_checksums(void) {
18
 
19
  if (sms_checksum != 0)
20
    compute_sms_checksum();
21
  if (gb_complement_check != 0)
22
    compute_gb_complement_check();
23
  if (gb_checksum != 0)
24
    compute_gb_checksum();
25
  if (snes_checksum != 0)
26
    compute_snes_checksum();
27
 
28
  return SUCCEEDED;
29
}
30
 
31
 
32
int compute_gb_complement_check(void) {
33
 
34
  unsigned int i, x;
35
 
36
 
37
  if (romsize < 0x8000) {
38
    fprintf(stderr, "COMPUTE_GB_COMPLEMENT_CHECK: GB complement check computing requires a ROM of at least 32KB.\n");
39
    return FAILED;
40
  }
41
 
42
  i = 0;
43
  for (x = 0x134; x <= 0x14C; x++)
44
    i += rom[x];
45
  i += 25;
46
  mem_insert(0x14D, 0 - (i & 0xFF));
47
 
48
  return SUCCEEDED;
49
}
50
 
51
 
52
int compute_gb_checksum(void) {
53
 
54
  unsigned int i, x;
55
 
56
 
57
  if (romsize < 0x8000) {
58
    fprintf(stderr, "COMPUTE_GB_CHECKSUM: GB checksum computing requires a ROM of at least 32KB.\n");
59
    return FAILED;
60
  }
61
 
62
  i = 0;
63
  for (x = 0; x < 0x14E; x++)
64
    i += rom[x];
65
  for (x = 0x150; x < romsize; x++)
66
    i += rom[x];
67
 
68
  mem_insert(0x14E, (i >> 8) & 0xFF);
69
  mem_insert(0x14F, i & 0xFF);
70
 
71
  return SUCCEEDED;
72
}
73
 
74
 
75
int compute_snes_checksum(void) {
76
 
77
  unsigned int i, x, n, m, l, o;
78
 
79
 
80
  if (snes_rom_mode == SNES_ROM_MODE_LOROM) {
81
    if (romsize < 0x8000) {
82
      fprintf(stderr, "COMPUTE_SNES_CHECKSUM: SNES checksum computing for a LoROM image requires a ROM of at least 32KB.\n");
83
      return FAILED;
84
    }
85
  }
86
  else {
87
    if (romsize < 0x10000) {
88
      fprintf(stderr, "COMPUTE_SNES_CHECKSUM: SNES checksum computing for a HiROM image requires a ROM of at least 64KB.\n");
89
      return FAILED;
90
    }
91
  }
92
 
93
  /* n = data inside 4mbit blocks, m = data outside that */
94
  if (romsize < 512*1024) {
95
    n = romsize;
96
    m = 0;
97
  }
98
  else {
99
    n = (romsize/(512*1024))*512*1024;
100
    m = romsize - n;
101
  }
102
 
103
  /* sum all the bytes inside the 4mbit blocks */
104
  x = 0;
105
  for (i = 0; i < n; i++) {
106
    if (snes_rom_mode == SNES_ROM_MODE_LOROM) {
107
      /* skip the checksum bytes */
108
      if (!(i == 0x7FDC || i == 0x7FDD || i == 0x7FDE || i == 0x7FDF))
109
        x += rom[i];
110
    }
111
    else {
112
      /* skip the checksum bytes */
113
      if (!(i == 0xFFDC || i == 0xFFDD || i == 0xFFDE || i == 0xFFDF))
114
        x += rom[i];
115
    }
116
  }
117
 
118
  /* add to that the data outside the 4mbit blocks, ringbuffer style repeating
119
     the remaining block until the the final part reaches 4mbits */
120
  for (o = 0, l = i; i < romsize; i++, o++)
121
    x += rom[(o % m) + l];
122
 
123
  /* 2*255 is for the checksum and its complement bytes, which we skipped earlier */
124
  x += 2*255;
125
 
126
  /* compute the inverse checksum */
127
  l = (x & 0xFFFF) ^ 0xFFFF;
128
 
129
  /* insert the checksum bytes */
130
  if (snes_rom_mode == SNES_ROM_MODE_LOROM) {
131
    mem_insert(0x7FDC, l & 0xFF);
132
    mem_insert(0x7FDD, (l >> 8) & 0xFF);
133
    mem_insert(0x7FDE, x & 0xFF);
134
    mem_insert(0x7FDF, (x >> 8) & 0xFF);
135
  }
136
  else {
137
    mem_insert(0xFFDC, l & 0xFF);
138
    mem_insert(0xFFDD, (l >> 8) & 0xFF);
139
    mem_insert(0xFFDE, x & 0xFF);
140
    mem_insert(0xFFDF, (x >> 8) & 0xFF);
141
  }
142
 
143
  return SUCCEEDED;
144
}
145
 
146
 
147
int compute_sms_checksum(void) {
148
 
149
  unsigned int i, x;
150
 
151
 
152
  if (romsize < 0x8000) {
153
    fprintf(stderr, "COMPUTE_SMS_CHECKSUM: SMS/GG checksum computing requires a ROM of at least 32KBs.\n");
154
    return SUCCEEDED;
155
  }
156
 
157
  /* add together 32KB minus SMS/GG header */
158
  i = 0;
159
  for (x = 0; x < 0x7FF0; x++)
160
    i += rom[x];
161
 
162
  mem_insert(0x7FFA, i & 0xFF);
163
  mem_insert(0x7FFB, (i >> 8) & 0xFF);
164
 
165
  /* 32KB checksum and SMS export */
166
  mem_insert(0x7FFF, 0x4C);
167
 
168
  return SUCCEEDED;
169
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.