1 /*
2 IGS Asic25 + (Asic12, Asic22, or Asic28) emulation
3
4 Used by:
5 Oriental Legends Special (Asic25 + Asic28)
6 The Killing Blade (Asic25 + Asic22)
7 Dragon World 2 (Asic25 + Asic12)
8 Dragon World 3 (Asic25 + Asic22)
9 */
10
11 #include "pgm.h"
12 #include "bitswap.h"
13
14 static const UINT8 source_data[0x22][0xec] =
15 {
16 { 0, }, // Region 0, not used
17 { // region 1, $14c21a
18 0x67, 0x51, 0xf3, 0x19, 0xa0, 0x09, 0xb1, 0x21, 0xb0, 0xee, 0xe3, 0xf6, 0xbe, 0x81, 0x35, 0xe3,
19 0xfb, 0xe6, 0xef, 0xdf, 0x61, 0x01, 0xfa, 0x22, 0x5d, 0x43, 0x01, 0xa5, 0x3b, 0x17, 0xd4, 0x74,
20 0xf0, 0xf4, 0xf3, 0x43, 0xb5, 0x19, 0x04, 0xd5, 0x84, 0xce, 0x87, 0xfe, 0x35, 0x3e, 0xc4, 0x3c,
21 0xc7, 0x85, 0x2a, 0x33, 0x00, 0x86, 0xd0, 0x4d, 0x65, 0x4b, 0xf9, 0xe9, 0xc0, 0xba, 0xaa, 0x77,
22 0x9e, 0x66, 0xf6, 0x0f, 0x4f, 0x3a, 0xb6, 0xf1, 0x64, 0x9a, 0xe9, 0x25, 0x1a, 0x5f, 0x22, 0xa3,
23 0xa2, 0xbf, 0x4b, 0x77, 0x3f, 0x34, 0xc9, 0x6e, 0xdb, 0x12, 0x5c, 0x33, 0xa5, 0x8b, 0x6c, 0xb1,
24 0x74, 0xc8, 0x40, 0x4e, 0x2f, 0xe7, 0x46, 0xae, 0x99, 0xfc, 0xb0, 0x55, 0x54, 0xdf, 0xa7, 0xa1,
25 0x0f, 0x5e, 0x49, 0xcf, 0x56, 0x3c, 0x90, 0x2b, 0xac, 0x65, 0x6e, 0xdb, 0x58, 0x3e, 0xc9, 0x00,
26 0xae, 0x53, 0x4d, 0x92, 0xfa, 0x40, 0xb2, 0x6b, 0x65, 0x4b, 0x90, 0x8a, 0x0c, 0xe2, 0xa5, 0x9a,
27 0xd0, 0x20, 0x29, 0x55, 0xa4, 0x44, 0xac, 0x51, 0x87, 0x54, 0x53, 0x34, 0x24, 0x4b, 0x81, 0x67,
28 0x34, 0x4c, 0x5f, 0x31, 0x4e, 0xf2, 0xf1, 0x19, 0x18, 0x1c, 0x34, 0x38, 0xe1, 0x81, 0x17, 0xcf,
29 0x24, 0xb9, 0x9a, 0xcb, 0x34, 0x51, 0x50, 0x59, 0x44, 0xb1, 0x0b, 0x50, 0x95, 0x6c, 0x48, 0x7e,
30 0x14, 0xa4, 0xc6, 0xd9, 0xd3, 0xa5, 0xd6, 0xd0, 0xc5, 0x97, 0xf0, 0x45, 0xd0, 0x98, 0x51, 0x91,
31 0x9f, 0xa3, 0x43, 0x51, 0x05, 0x90, 0xee, 0xca, 0x7e, 0x5f, 0x72, 0x53, 0xb1, 0xd3, 0xaf, 0x36,
32 0x08, 0x75, 0xb0, 0x9b, 0xe0, 0x0d, 0x43, 0x88, 0xaa, 0x27, 0x44, 0x11
33 },
34 { // region 2, $14c126
35 0xf9, 0x19, 0xf3, 0x09, 0xa0, 0x09, 0xb0, 0x21, 0xb0, 0x22, 0xfd, 0x8e, 0xd3, 0xc8, 0x31, 0x67,
36 0xc0, 0x10, 0x3c, 0xc2, 0x03, 0xf2, 0x6a, 0x0a, 0x54, 0x49, 0xca, 0xb5, 0x4b, 0xe0, 0x94, 0xe8,
37 0x8d, 0xc8, 0x90, 0xee, 0x6b, 0x6f, 0xfa, 0x09, 0x76, 0x84, 0x6f, 0x55, 0xd1, 0x94, 0xca, 0x9c,
38 0xe1, 0x22, 0xc6, 0x02, 0xb5, 0x8c, 0xf9, 0x3a, 0x52, 0x10, 0xf0, 0x22, 0xe4, 0x11, 0x15, 0x73,
39 0x5e, 0x9e, 0xde, 0xc4, 0x5a, 0xbd, 0xa3, 0x89, 0xe7, 0x9b, 0x95, 0x5d, 0x75, 0xf6, 0xc3, 0x9f,
40 0xe4, 0xcf, 0x65, 0x73, 0x90, 0xd0, 0x75, 0x56, 0xfa, 0xcc, 0xe4, 0x3e, 0x9c, 0x41, 0x81, 0x62,
41 0xb1, 0xd3, 0x28, 0xbd, 0x6c, 0xed, 0x60, 0x28, 0x27, 0xee, 0xf2, 0xa1, 0xb4, 0x2c, 0x6c, 0xbb,
42 0x42, 0xd7, 0x1d, 0x62, 0xc0, 0x33, 0x7d, 0xf9, 0xe4, 0x5c, 0xe2, 0x41, 0xa4, 0x1c, 0x98, 0xa1,
43 0x87, 0x95, 0xad, 0x61, 0x56, 0x96, 0x40, 0x08, 0x6b, 0xe2, 0x4b, 0x95, 0x7b, 0x1b, 0xd8, 0x64,
44 0xb3, 0xee, 0x9d, 0x79, 0x69, 0xea, 0x5d, 0xcf, 0x01, 0x91, 0xea, 0x3f, 0x70, 0x29, 0xdc, 0xe0,
45 0x08, 0x20, 0xbf, 0x46, 0x90, 0xa8, 0xfc, 0x29, 0x14, 0xd1, 0x0d, 0x20, 0x79, 0xd2, 0x2c, 0xe9,
46 0x52, 0xa6, 0x8c, 0xbd, 0xa3, 0x3e, 0x88, 0x2d, 0xb8, 0x4e, 0xf2, 0x74, 0x50, 0xcc, 0x12, 0xde,
47 0xd3, 0x5a, 0xa4, 0x7b, 0xa2, 0x8d, 0x91, 0x68, 0x12, 0x0c, 0x9c, 0xb9, 0x6d, 0x26, 0x66, 0x60,
48 0xc3, 0x6d, 0xd0, 0x11, 0x33, 0x05, 0x1d, 0xa8, 0xb6, 0x51, 0xe6, 0xe0, 0x58, 0x61, 0x74, 0x37,
49 0xcc, 0x3a, 0x4d, 0x6a, 0x0a, 0x09, 0x71, 0xe3, 0x7e, 0xa5, 0x3b, 0xe9
50 },
51 { // region 3, $14E5BE
52 0x73, 0x59, 0xf3, 0x09, 0xa0, 0x09, 0xb1, 0x21, 0xb0, 0x55, 0x18, 0x0d, 0xe8, 0x29, 0x2d, 0x04,
53 0x85, 0x39, 0x88, 0xbe, 0x8b, 0xcb, 0xd9, 0x0b, 0x32, 0x36, 0x94, 0xac, 0x74, 0xc3, 0x3b, 0x5d,
54 0x2a, 0x83, 0x46, 0xb3, 0x3a, 0xac, 0xd8, 0x55, 0x68, 0x21, 0x57, 0xab, 0x6e, 0xd1, 0xd0, 0xfc,
55 0xe2, 0xbe, 0x63, 0xd0, 0x6b, 0x79, 0x23, 0x40, 0x58, 0xd4, 0xe7, 0x73, 0x22, 0x67, 0x7f, 0x88,
56 0x05, 0xbd, 0xdf, 0x7a, 0x65, 0x41, 0x90, 0x3a, 0x52, 0x83, 0x28, 0xae, 0xe9, 0x8e, 0x65, 0x82,
57 0x0e, 0xdf, 0x98, 0x88, 0xe1, 0x86, 0x21, 0x3e, 0x1a, 0x87, 0x6d, 0x62, 0x7a, 0xf6, 0xaf, 0x2c,
58 0xd5, 0xc5, 0x10, 0x2d, 0xa9, 0xda, 0x93, 0xa1, 0x9b, 0xc7, 0x35, 0xd4, 0x15, 0x78, 0x18, 0xd5,
59 0x75, 0x6a, 0xd7, 0xdb, 0x12, 0x2a, 0x6a, 0xc8, 0x36, 0x53, 0x57, 0xa6, 0xf0, 0x13, 0x67, 0x43,
60 0x79, 0xf0, 0x0e, 0x49, 0xb1, 0xec, 0xcd, 0xa4, 0x8a, 0x61, 0x06, 0xb9, 0xea, 0x53, 0xf2, 0x47,
61 0x7d, 0xd6, 0xf8, 0x9d, 0x2e, 0xaa, 0x27, 0x35, 0x61, 0xce, 0x9b, 0x63, 0xbc, 0x07, 0x51, 0x5a,
62 0xc2, 0x0d, 0x39, 0x42, 0xd2, 0x5e, 0x21, 0x20, 0x10, 0xa0, 0xe5, 0x08, 0xf7, 0x3d, 0x28, 0x04,
63 0x99, 0x93, 0x97, 0xaf, 0xf9, 0x12, 0xc0, 0x01, 0x2d, 0xea, 0xf3, 0x98, 0x0b, 0x46, 0xc2, 0x26,
64 0x93, 0x10, 0x69, 0x1d, 0x71, 0x8e, 0x33, 0x00, 0x5e, 0x80, 0x2f, 0x47, 0x0a, 0xcc, 0x94, 0x16,
65 0xe7, 0x37, 0x45, 0xd0, 0x61, 0x79, 0x32, 0x86, 0x08, 0x2a, 0x5b, 0x55, 0xfe, 0xee, 0x52, 0x38,
66 0xaa, 0x18, 0xe9, 0x39, 0x1a, 0x1e, 0xb8, 0x26, 0x6b, 0x3d, 0x4b, 0xa9
67 },
68 { // region 4, $14d500
69 0x06, 0x01, 0xf3, 0x39, 0xa0, 0x09, 0xa0, 0x21, 0xb0, 0x6f, 0x32, 0x8b, 0xfd, 0x89, 0x29, 0xa0,
70 0x4a, 0x62, 0xed, 0xa1, 0x2d, 0xa4, 0x49, 0xf2, 0x10, 0x3c, 0x77, 0xa3, 0x84, 0x8d, 0xfa, 0xd1,
71 0xc6, 0x57, 0xe2, 0x78, 0xef, 0xe9, 0xb6, 0xa1, 0x5a, 0xbd, 0x3f, 0x02, 0x0b, 0x28, 0xd6, 0x76,
72 0xfc, 0x5b, 0x19, 0x9f, 0x21, 0x66, 0x4c, 0x2d, 0x45, 0x99, 0xde, 0xab, 0x46, 0xbd, 0xe9, 0x84,
73 0xc4, 0xdc, 0xc7, 0x30, 0x70, 0xdd, 0x64, 0xea, 0xbc, 0x6b, 0xd3, 0xe6, 0x45, 0x3f, 0x07, 0x7e,
74 0x50, 0xef, 0xb2, 0x84, 0x33, 0x3c, 0xcc, 0x3f, 0x39, 0x5b, 0xf5, 0x6d, 0x71, 0xc5, 0xdd, 0xf5,
75 0xf9, 0xd0, 0xf7, 0x9c, 0xe6, 0xc7, 0xad, 0x1b, 0x29, 0xb9, 0x90, 0x08, 0x75, 0xc4, 0xc3, 0xef,
76 0xa8, 0xfc, 0xab, 0x55, 0x7c, 0x21, 0x57, 0x97, 0x87, 0x4a, 0xcb, 0x0c, 0x56, 0x0a, 0x4f, 0xcb,
77 0x52, 0x33, 0x87, 0x31, 0xf3, 0x43, 0x5b, 0x41, 0x90, 0xf8, 0xc0, 0xdd, 0x5a, 0xa4, 0x26, 0x2a,
78 0x60, 0xa5, 0x6d, 0xda, 0xf2, 0x6a, 0xf0, 0xb3, 0xda, 0x25, 0x33, 0x87, 0x22, 0xe4, 0xac, 0xd3,
79 0x96, 0xe0, 0x99, 0x3e, 0xfb, 0x14, 0x45, 0x17, 0x25, 0x56, 0xbe, 0xef, 0x8f, 0x8e, 0x3d, 0x1e,
80 0xc7, 0x99, 0xa2, 0xa1, 0x50, 0xfe, 0xdf, 0xd4, 0xa1, 0x87, 0xf4, 0xd5, 0xde, 0xa6, 0x8c, 0x6d,
81 0x6c, 0xde, 0x47, 0xbe, 0x59, 0x8f, 0xd4, 0x97, 0xc3, 0xf4, 0xda, 0xbb, 0xa6, 0x73, 0xa9, 0xcb,
82 0xf2, 0x01, 0xb9, 0x90, 0x8f, 0xed, 0x60, 0x64, 0x40, 0x1c, 0xb6, 0xc9, 0xa5, 0x7c, 0x17, 0x52,
83 0x6f, 0xdc, 0x6d, 0x08, 0x2a, 0x1a, 0xe6, 0x68, 0x3f, 0xd4, 0x42, 0x69
84 },
85 { // region 5, $14bfb2
86 0x7f, 0x41, 0xf3, 0x39, 0xa0, 0x09, 0xa1, 0x21, 0xb0, 0xa2, 0x4c, 0x23, 0x13, 0xe9, 0x25, 0x3d,
87 0x0f, 0x72, 0x3a, 0x9d, 0xb5, 0x96, 0xd1, 0xda, 0x07, 0x29, 0x41, 0x9a, 0xad, 0x70, 0xba, 0x46,
88 0x63, 0x2b, 0x7f, 0x3d, 0xbe, 0x40, 0xad, 0xd4, 0x4c, 0x73, 0x27, 0x58, 0xa7, 0x65, 0xdc, 0xd6,
89 0xfd, 0xde, 0xb5, 0x6e, 0xd6, 0x6c, 0x75, 0x1a, 0x32, 0x45, 0xd5, 0xe3, 0x6a, 0x14, 0x6d, 0x80,
90 0x84, 0x15, 0xaf, 0xcc, 0x7b, 0x61, 0x51, 0x82, 0x40, 0x53, 0x7f, 0x38, 0xa0, 0xd6, 0x8f, 0x61,
91 0x79, 0x19, 0xe5, 0x99, 0x84, 0xd8, 0x78, 0x27, 0x3f, 0x16, 0x97, 0x78, 0x4f, 0x7b, 0x0c, 0xa6,
92 0x37, 0xdb, 0xc6, 0x0c, 0x24, 0xb4, 0xc7, 0x94, 0x9d, 0x92, 0xd2, 0x3b, 0xd5, 0x11, 0x6f, 0x0a,
93 0xdb, 0x76, 0x66, 0xe7, 0xcd, 0x18, 0x2b, 0x66, 0xd8, 0x41, 0x40, 0x58, 0xa2, 0x01, 0x1e, 0x6d,
94 0x44, 0x75, 0xe7, 0x19, 0x4f, 0xb2, 0xe8, 0xc4, 0x96, 0x77, 0x62, 0x02, 0xc9, 0xdc, 0x59, 0xf3,
95 0x43, 0x8d, 0xc8, 0xfe, 0x9e, 0x2a, 0xba, 0x32, 0x3b, 0x62, 0xe3, 0x92, 0x6e, 0xc2, 0x08, 0x4d,
96 0x51, 0xcd, 0xf9, 0x3a, 0x3e, 0xc9, 0x50, 0x27, 0x21, 0x25, 0x97, 0xd7, 0x0e, 0xf8, 0x39, 0x38,
97 0xf5, 0x86, 0x94, 0x93, 0xbf, 0xeb, 0x18, 0xa8, 0xfc, 0x24, 0xf5, 0xf9, 0x99, 0x20, 0x3d, 0xcd,
98 0x2c, 0x94, 0x25, 0x79, 0x28, 0x77, 0x8f, 0x2f, 0x10, 0x69, 0x86, 0x30, 0x43, 0x01, 0xd7, 0x9a,
99 0x17, 0xe3, 0x47, 0x37, 0xbd, 0x62, 0x75, 0x42, 0x78, 0xf4, 0x2b, 0x57, 0x4c, 0x0a, 0xdb, 0x53,
100 0x4d, 0xa1, 0x0a, 0xd6, 0x3a, 0x16, 0x15, 0xaa, 0x2c, 0x6c, 0x39, 0x42
101 },
102 { // region 6, $14cd82
103 0x12, 0x09, 0xf3, 0x29, 0xa0, 0x09, 0xa0, 0x21, 0xb0, 0xd5, 0x66, 0xa1, 0x28, 0x4a, 0x21, 0xc0,
104 0xd3, 0x9b, 0x86, 0x80, 0x57, 0x6f, 0x41, 0xc2, 0xe4, 0x2f, 0x0b, 0x91, 0xbd, 0x3a, 0x7a, 0xba,
105 0x00, 0xe5, 0x35, 0x02, 0x74, 0x7d, 0x8b, 0x21, 0x57, 0x10, 0x0f, 0xae, 0x44, 0xbb, 0xe2, 0x37,
106 0x18, 0x7b, 0x52, 0x3d, 0x8c, 0x59, 0x9e, 0x20, 0x1f, 0x0a, 0xcc, 0x1c, 0x8e, 0x6a, 0xd7, 0x95,
107 0x2b, 0x34, 0xb0, 0x82, 0x6d, 0xfd, 0x25, 0x33, 0xaa, 0x3b, 0x2b, 0x70, 0x15, 0x87, 0x31, 0x5d,
108 0xbb, 0x29, 0x19, 0x95, 0xd5, 0x8e, 0x24, 0x28, 0x5e, 0xd0, 0x20, 0x83, 0x46, 0x4a, 0x21, 0x70,
109 0x5b, 0xcd, 0xae, 0x7b, 0x61, 0xa1, 0xfa, 0xf4, 0x2b, 0x84, 0x15, 0x6e, 0x36, 0x5d, 0x1b, 0x24,
110 0x0f, 0x09, 0x3a, 0x61, 0x38, 0x0f, 0x18, 0x35, 0x11, 0x38, 0xb4, 0xbd, 0xee, 0xf7, 0xec, 0x0f,
111 0x1d, 0xb7, 0x48, 0x01, 0xaa, 0x09, 0x8f, 0x61, 0xb5, 0x0f, 0x1d, 0x26, 0x39, 0x2e, 0x8c, 0xd6,
112 0x26, 0x5c, 0x3d, 0x23, 0x63, 0xe9, 0x6b, 0x97, 0xb4, 0x9f, 0x7b, 0xb6, 0xba, 0xa0, 0x7c, 0xc6,
113 0x25, 0xa1, 0x73, 0x36, 0x67, 0x7f, 0x74, 0x1e, 0x1d, 0xda, 0x70, 0xbf, 0xa5, 0x63, 0x35, 0x39,
114 0x24, 0x8c, 0x9f, 0x85, 0x16, 0xd8, 0x50, 0x95, 0x71, 0xc0, 0xf6, 0x1e, 0x6d, 0x80, 0xed, 0x15,
115 0xeb, 0x63, 0xe9, 0x1b, 0xf6, 0x78, 0x31, 0xc6, 0x5c, 0xdd, 0x19, 0xbd, 0xdf, 0xa7, 0xec, 0x50,
116 0x22, 0xad, 0xbb, 0xf6, 0xeb, 0xd6, 0xa3, 0x20, 0xc9, 0xe6, 0x9f, 0xcb, 0xf2, 0x97, 0xb9, 0x54,
117 0x12, 0x66, 0xa6, 0xbe, 0x4a, 0x12, 0x43, 0xec, 0x00, 0xea, 0x49, 0x02
118 },
119 { // region 7, $14ce76
120 0xa4, 0x49, 0xf3, 0x29, 0xa0, 0x09, 0xa1, 0x21, 0xb0, 0xef, 0x80, 0x20, 0x3d, 0xaa, 0x36, 0x5d,
121 0x98, 0xc4, 0xd2, 0x63, 0xdf, 0x61, 0xb0, 0xc3, 0xc2, 0x35, 0xd4, 0x88, 0xe6, 0x1d, 0x3a, 0x2f,
122 0x9c, 0xb9, 0xd1, 0xc6, 0x43, 0xba, 0x69, 0x6d, 0x49, 0xac, 0xdd, 0x05, 0xe0, 0xf8, 0xe8, 0x97,
123 0x19, 0x18, 0x08, 0x0c, 0x42, 0x46, 0xc7, 0x0d, 0x25, 0xce, 0xc3, 0x54, 0xb2, 0xd9, 0x42, 0x91,
124 0xea, 0x53, 0x98, 0x38, 0x78, 0x81, 0x12, 0xca, 0x15, 0x23, 0xbd, 0xc1, 0x70, 0x1f, 0xd2, 0x40,
125 0xfd, 0x39, 0x33, 0xaa, 0x27, 0x2b, 0xe8, 0x10, 0x7d, 0xa4, 0xa8, 0x8e, 0x3d, 0x00, 0x4f, 0x3a,
126 0x7f, 0xd8, 0x96, 0xea, 0x9e, 0x8e, 0x15, 0x6e, 0x9f, 0x76, 0x57, 0xba, 0x7d, 0xc2, 0xdf, 0x57,
127 0x42, 0x82, 0xf4, 0xda, 0x89, 0x06, 0x05, 0x04, 0x62, 0x2f, 0x29, 0x23, 0x54, 0xd5, 0xbb, 0x97,
128 0xf5, 0xf9, 0xc1, 0xcf, 0xec, 0x5f, 0x1d, 0xfd, 0xbb, 0xa6, 0xd7, 0x4a, 0xa8, 0x66, 0xbf, 0xb9,
129 0x09, 0x44, 0xb1, 0x60, 0x28, 0xa9, 0x35, 0x16, 0x15, 0xf5, 0x13, 0xc1, 0x07, 0x7e, 0xd7, 0x40,
130 0xdf, 0x8e, 0xd3, 0x32, 0xa9, 0x35, 0x98, 0x15, 0x32, 0xa9, 0x49, 0xc0, 0x24, 0xb4, 0x4a, 0x53,
131 0x6b, 0x79, 0xaa, 0x77, 0x6c, 0xc5, 0x88, 0x69, 0xe5, 0x5d, 0xde, 0x42, 0x28, 0xf9, 0xb7, 0x5c,
132 0xab, 0x19, 0xc7, 0xbc, 0xc5, 0x60, 0xeb, 0x5e, 0xa8, 0x52, 0xc4, 0x32, 0x7c, 0x35, 0x02, 0x06,
133 0x46, 0x77, 0x30, 0xb6, 0x33, 0x4b, 0xb8, 0xfd, 0x02, 0xd8, 0x14, 0x40, 0x99, 0x25, 0x7e, 0x55,
134 0xd6, 0x44, 0x43, 0x8d, 0x73, 0x0e, 0x71, 0x48, 0xd3, 0x82, 0x40, 0xda
135 },
136 { 0, }, // unused region 08
137 { 0, }, // unused region 09
138 { 0, }, // unused region 0a
139 { 0, }, // unused region 0b
140 { 0, }, // unused region 0c
141 { 0, }, // unused region 0d
142 { 0, }, // unused region 0e
143 { 0, }, // unused region 0f
144 { 0, }, // unused region 10
145 { 0, }, // unused region 11
146 { 0, }, // unused region 12
147 { 0, }, // unused region 13
148 { 0, }, // unused region 14
149 { 0, }, // unused region 15
150 { // region 16, $178772
151 0x5e, 0x09, 0xb3, 0x39, 0x60, 0x71, 0x71, 0x53, 0x11, 0xe5, 0x26, 0x34, 0x4c, 0x8c, 0x90, 0xee,
152 0xed, 0xb5, 0x05, 0x95, 0x9e, 0x6b, 0xdd, 0x87, 0x0e, 0x7b, 0xed, 0x33, 0xaf, 0xc2, 0x62, 0x98,
153 0xec, 0xc8, 0x2c, 0x2b, 0x57, 0x3d, 0x00, 0xbd, 0x12, 0xac, 0xba, 0x64, 0x81, 0x99, 0x16, 0x29,
154 0xb4, 0x63, 0xa8, 0xd9, 0xc9, 0x5f, 0xfe, 0x21, 0xbb, 0xbf, 0x9b, 0xd1, 0x7b, 0x93, 0xc4, 0x82,
155 0xef, 0x2b, 0xe8, 0xa6, 0xdc, 0x68, 0x3a, 0xd9, 0xc9, 0x23, 0xc7, 0x7b, 0x98, 0x5b, 0xe1, 0xc7,
156 0xa3, 0xd4, 0x51, 0x0a, 0x86, 0x30, 0x20, 0x51, 0x6e, 0x04, 0x1c, 0xd4, 0xfb, 0xf5, 0x22, 0x8f,
157 0x16, 0x6f, 0xb9, 0x59, 0x30, 0xcf, 0xab, 0x32, 0x1d, 0x6c, 0x84, 0xab, 0x23, 0x90, 0x94, 0xb1,
158 0xe7, 0x4b, 0x6d, 0xc1, 0x84, 0xba, 0x32, 0x68, 0xa3, 0xf2, 0x47, 0x28, 0xe5, 0xcb, 0xbb, 0x47,
159 0x14, 0x2c, 0xad, 0x4d, 0xa1, 0xd7, 0x18, 0x53, 0xf7, 0x6f, 0x05, 0x81, 0x8f, 0xbb, 0x29, 0xdc,
160 0xbd, 0x17, 0x61, 0x92, 0x9b, 0x1d, 0x4e, 0x7a, 0x83, 0x14, 0x9f, 0x7b, 0x7a, 0x6a, 0xe1, 0x27,
161 0x62, 0x52, 0x7e, 0x82, 0x45, 0xda, 0xed, 0xf1, 0x0a, 0x3b, 0x6c, 0x02, 0x5b, 0x6e, 0x45, 0x4e,
162 0xf2, 0x65, 0x87, 0x1d, 0x80, 0xed, 0x6a, 0xc3, 0x77, 0xcb, 0xe8, 0x8d, 0x5a, 0xb8, 0xda, 0x89,
163 0x88, 0x4b, 0x27, 0xd5, 0x57, 0x29, 0x91, 0x86, 0x12, 0xbb, 0xd3, 0x8c, 0xc7, 0x49, 0x84, 0x9c,
164 0x96, 0x59, 0x30, 0x93, 0x92, 0xeb, 0x59, 0x2b, 0x93, 0x5b, 0x5f, 0xf9, 0x67, 0xac, 0x97, 0x8c,
165 0x04, 0xda, 0x1b, 0x65, 0xd7, 0xef, 0x44, 0xca, 0xc4, 0x87, 0x18, 0x2b
166 },
167 { // region 17, $178a36
168 0xd7, 0x49, 0xb3, 0x39, 0x60, 0x71, 0x70, 0x53, 0x11, 0x00, 0x27, 0xb2, 0x61, 0xd3, 0x8c, 0x8b,
169 0xb2, 0xde, 0x6a, 0x78, 0x40, 0x5d, 0x4d, 0x88, 0xeb, 0x81, 0xd0, 0x2a, 0xbf, 0x8c, 0x22, 0x0d,
170 0x89, 0x83, 0xc8, 0xef, 0x0d, 0x7a, 0xf6, 0xf0, 0x1d, 0x49, 0xa2, 0xd3, 0x1e, 0xef, 0x1c, 0xa2,
171 0xce, 0x00, 0x5e, 0xa8, 0x7f, 0x4c, 0x41, 0x27, 0xa8, 0x6b, 0x92, 0x0a, 0xb8, 0x03, 0x2f, 0x7e,
172 0xaf, 0x4a, 0xd0, 0x5c, 0xce, 0xeb, 0x0e, 0x8a, 0x4d, 0x0b, 0x73, 0xb3, 0xf3, 0x0c, 0x83, 0xaa,
173 0xe5, 0xe4, 0x84, 0x06, 0xd7, 0xcc, 0xcb, 0x52, 0x8d, 0xbe, 0xa4, 0xdf, 0xd9, 0xab, 0x50, 0x59,
174 0x53, 0x61, 0xa1, 0xc8, 0x6d, 0xbc, 0xde, 0xab, 0xaa, 0x5e, 0xc6, 0xf7, 0x83, 0xdc, 0x40, 0xcb,
175 0x1b, 0xdd, 0x28, 0x3b, 0xee, 0xb1, 0x1f, 0x37, 0xdb, 0xe9, 0xbb, 0x74, 0x4b, 0xc2, 0x8a, 0xe8,
176 0xec, 0x6e, 0x0e, 0x35, 0xe3, 0x2e, 0xbe, 0xef, 0xfd, 0x07, 0xbf, 0x8c, 0xfe, 0xf3, 0x5c, 0xbf,
177 0x87, 0xe5, 0xbc, 0xcf, 0x60, 0xdc, 0x18, 0xf8, 0xfc, 0x51, 0x50, 0x86, 0xc6, 0x48, 0x3d, 0xb9,
178 0x1d, 0x26, 0xf7, 0x7e, 0x87, 0x90, 0x12, 0xe8, 0x06, 0x0a, 0x45, 0xe9, 0xd9, 0xd8, 0x41, 0x68,
179 0x21, 0x52, 0x92, 0x0f, 0xd6, 0xda, 0xa2, 0x97, 0xeb, 0x68, 0xd0, 0xb1, 0x15, 0x19, 0x8b, 0xd0,
180 0x48, 0x1a, 0xeb, 0x90, 0x3f, 0x2a, 0x33, 0x1e, 0x5e, 0x30, 0x66, 0x01, 0x64, 0xef, 0x99, 0x52,
181 0xba, 0x23, 0xbd, 0x53, 0xc0, 0x60, 0x87, 0x09, 0xcb, 0x4d, 0xd3, 0x87, 0x0e, 0x3a, 0x5c, 0x8d,
182 0xc8, 0xb8, 0xb7, 0x34, 0x01, 0xeb, 0x72, 0x0d, 0xb1, 0x1f, 0x0f, 0xea
183 },
184 { // region 18, $17dac4
185 0x6a, 0x13, 0xb3, 0x09, 0x60, 0x79, 0x61, 0x53, 0x11, 0x33, 0x41, 0x31, 0x76, 0x34, 0x88, 0x0f,
186 0x77, 0x08, 0xb6, 0x74, 0xc8, 0x36, 0xbc, 0x70, 0xe2, 0x87, 0x9a, 0x21, 0xe8, 0x56, 0xe1, 0x9a,
187 0x26, 0x57, 0x7e, 0x9b, 0xdb, 0xb7, 0xd4, 0x3d, 0x0f, 0xfe, 0x8a, 0x2a, 0xba, 0x2d, 0x22, 0x03,
188 0xcf, 0x9c, 0xfa, 0x77, 0x35, 0x39, 0x6a, 0x14, 0xae, 0x30, 0x89, 0x42, 0xdc, 0x59, 0xb2, 0x93,
189 0x6f, 0x82, 0xd1, 0x12, 0xd9, 0x88, 0xfa, 0x3b, 0xb7, 0x0c, 0x1f, 0x05, 0x68, 0xa3, 0x0c, 0xa6,
190 0x0f, 0xf4, 0x9e, 0x1b, 0x29, 0x82, 0x77, 0x3a, 0xac, 0x92, 0x2d, 0x04, 0xd0, 0x61, 0x65, 0x0a,
191 0x77, 0x6c, 0x89, 0x38, 0xaa, 0xa9, 0xf8, 0x0c, 0x1f, 0x37, 0x09, 0x2b, 0xca, 0x29, 0x05, 0xe5,
192 0x4e, 0x57, 0xfb, 0xcd, 0x40, 0xa8, 0x0c, 0x06, 0x2d, 0xe0, 0x30, 0xd9, 0x97, 0xb9, 0x59, 0x8a,
193 0xde, 0xc9, 0x87, 0x1d, 0x3f, 0x84, 0x4c, 0x73, 0x04, 0x85, 0x61, 0xb0, 0x6e, 0x2c, 0x8f, 0xa2,
194 0x6a, 0xcd, 0x31, 0xf3, 0x25, 0x83, 0xe1, 0x5e, 0x5d, 0xa7, 0xe7, 0xaa, 0x13, 0x26, 0xb1, 0x33,
195 0xf0, 0x13, 0x58, 0x7a, 0xb0, 0x46, 0x1d, 0xdf, 0x02, 0xbf, 0x1e, 0xd1, 0x71, 0x43, 0x56, 0x82,
196 0x4f, 0x58, 0x9d, 0x01, 0x2d, 0xc7, 0xda, 0x6b, 0x47, 0x05, 0xd1, 0xd5, 0xe8, 0x92, 0x3c, 0x18,
197 0x21, 0xcf, 0xc9, 0x32, 0x0e, 0x12, 0xed, 0xb5, 0xaa, 0xa4, 0x12, 0x75, 0x01, 0x7d, 0xc7, 0x21,
198 0xde, 0xec, 0x32, 0x13, 0xee, 0xd4, 0x9c, 0xe6, 0x04, 0x3f, 0x48, 0xfb, 0xb4, 0xc7, 0x21, 0x8e,
199 0x8d, 0x7d, 0x54, 0x03, 0x11, 0xe7, 0xb9, 0x4f, 0x85, 0xb6, 0x1f, 0xaa
200 },
201 { // region 19, $178eee
202 0xe3, 0x53, 0xb3, 0x09, 0x60, 0x79, 0x60, 0x53, 0x11, 0x66, 0x5b, 0xc8, 0x8b, 0x94, 0x84, 0xab,
203 0x3c, 0x18, 0x03, 0x57, 0x6a, 0x0f, 0x45, 0x58, 0xc0, 0x74, 0x64, 0x18, 0xf8, 0x39, 0xa1, 0x0f,
204 0xc2, 0x2b, 0x1b, 0x60, 0xaa, 0x0e, 0xb2, 0x89, 0x01, 0x9b, 0x72, 0x80, 0x57, 0x83, 0x28, 0x63,
205 0xe9, 0x39, 0x97, 0x46, 0xea, 0x3f, 0x93, 0x01, 0x9b, 0xf4, 0x80, 0x93, 0x01, 0xaf, 0x1d, 0x8f,
206 0x16, 0xa1, 0xb9, 0xc7, 0xe4, 0x0c, 0xe7, 0xd2, 0x3b, 0xf3, 0xca, 0x3d, 0xc3, 0x54, 0xad, 0x89,
207 0x51, 0x1e, 0xd1, 0x17, 0x7a, 0x1f, 0x23, 0x22, 0xcb, 0x4d, 0xce, 0x0f, 0xae, 0x30, 0x93, 0xd3,
208 0x9b, 0x77, 0x71, 0xa7, 0xe7, 0x96, 0x2c, 0x85, 0xac, 0x29, 0x4b, 0x5e, 0x2b, 0x75, 0xb0, 0x00,
209 0x81, 0xe9, 0xb6, 0x47, 0xaa, 0x9f, 0xdf, 0xd4, 0x7e, 0xd7, 0xa4, 0x3f, 0xe3, 0xb0, 0x41, 0x2c,
210 0xb7, 0x0c, 0xe7, 0xeb, 0x9a, 0xda, 0xd9, 0x10, 0x23, 0x1d, 0x1c, 0xd4, 0xdd, 0x7d, 0xc2, 0x6c,
211 0x4d, 0x9c, 0xa5, 0x18, 0xd0, 0x43, 0xab, 0xdc, 0xbd, 0xe4, 0x7f, 0xb5, 0x5f, 0x04, 0x0d, 0xac,
212 0xab, 0xe6, 0xb8, 0x76, 0xf2, 0x15, 0x41, 0xef, 0x17, 0x8e, 0xf6, 0xb9, 0xef, 0x94, 0x52, 0x83,
213 0x96, 0x45, 0x8f, 0xf2, 0x9c, 0xb4, 0x13, 0x3f, 0xbb, 0xa1, 0xd2, 0xf9, 0xa3, 0xf2, 0x06, 0x78,
214 0xe0, 0x9e, 0xa7, 0xd3, 0xdc, 0x13, 0x8f, 0x4d, 0xf6, 0x19, 0xbd, 0x03, 0x9d, 0x24, 0xdc, 0xd6,
215 0xe9, 0xcf, 0xa6, 0xd2, 0x1d, 0x49, 0xca, 0xc4, 0x55, 0x18, 0xbc, 0x70, 0x5b, 0x55, 0xfe, 0x8f,
216 0x6b, 0x42, 0xf0, 0xd1, 0x21, 0xe3, 0xe7, 0x91, 0x59, 0x4e, 0x16, 0x83
217 },
218 { 0, }, // unused region 1a
219 { 0, }, // unused region 1b
220 { 0, }, // unused region 1c
221 { 0, }, // unused region 1d
222 { 0, }, // unused region 1e
223 { 0, }, // unused region 1f
224 { // region 20, $17a322
225 0xb3, 0x10, 0xf3, 0x0b, 0xe0, 0x71, 0x60, 0x53, 0x11, 0x9a, 0x12, 0x70, 0x1f, 0x1e, 0x81, 0xda,
226 0x9d, 0x1f, 0x4b, 0xd6, 0x71, 0x48, 0x83, 0xe1, 0x04, 0x6c, 0x1b, 0xf1, 0xcd, 0x09, 0xdf, 0x3e,
227 0x0b, 0xaa, 0x95, 0xc1, 0x07, 0xec, 0x0f, 0x54, 0xd0, 0x16, 0xb0, 0xdc, 0x86, 0x7b, 0x52, 0x38,
228 0x3c, 0x68, 0x2b, 0xed, 0xe2, 0xeb, 0xb3, 0xc6, 0x48, 0x24, 0x41, 0x36, 0x17, 0x25, 0x1f, 0xa5,
229 0x22, 0xc6, 0x5c, 0xa6, 0x19, 0xef, 0x17, 0x5c, 0x56, 0x4b, 0x4a, 0x2b, 0x75, 0xab, 0xe6, 0x22,
230 0xd5, 0xc0, 0xd3, 0x46, 0xcc, 0xe4, 0xd4, 0xc4, 0x8c, 0x9a, 0x8a, 0x75, 0x24, 0x73, 0xa4, 0x26,
231 0xca, 0x79, 0xaf, 0xb3, 0x94, 0x2a, 0x15, 0xbe, 0x40, 0x7b, 0x4d, 0xf6, 0xb4, 0xa4, 0x7b, 0xcf,
232 0xce, 0xa0, 0x1d, 0xcb, 0x2f, 0x60, 0x28, 0x63, 0x85, 0x98, 0xd3, 0xd2, 0x45, 0x3f, 0x02, 0x65,
233 0xd7, 0xf4, 0xbc, 0x2a, 0xe7, 0x50, 0xd1, 0x3f, 0x7f, 0xf6, 0x05, 0xb8, 0xe9, 0x39, 0x10, 0x6e,
234 0x68, 0xa8, 0x89, 0x60, 0x00, 0x68, 0xfd, 0x20, 0xc4, 0xdc, 0xef, 0x67, 0x75, 0xfb, 0xbe, 0xfe,
235 0x2b, 0x16, 0xa6, 0x5a, 0x77, 0x0d, 0x0c, 0xe2, 0x2d, 0xd1, 0xe4, 0x11, 0xc9, 0x4b, 0x81, 0x3a,
236 0x0c, 0x24, 0xaa, 0x77, 0x2b, 0x2f, 0x83, 0x23, 0xd1, 0xe9, 0xa7, 0x29, 0x0a, 0xf9, 0x26, 0x9d,
237 0x51, 0xc8, 0x6d, 0x71, 0x9d, 0xce, 0x46, 0x72, 0x26, 0x48, 0x3d, 0x64, 0xe5, 0x67, 0xbb, 0x1a,
238 0xb4, 0x6d, 0x21, 0x11, 0x79, 0x78, 0xc2, 0xd5, 0x11, 0x6a, 0xd2, 0xea, 0x03, 0x4d, 0x92, 0xaf,
239 0x18, 0xd5, 0x07, 0x79, 0xaa, 0xf9, 0x44, 0x93, 0x6f, 0x41, 0x22, 0x0d
240 },
241 { // region 21, $17b3b4
242 0x2d, 0x50, 0xf3, 0x0b, 0xe0, 0x71, 0x61, 0x53, 0x11, 0xb4, 0x2c, 0xee, 0x34, 0x7e, 0x7d, 0x5e,
243 0x62, 0x48, 0x97, 0xd2, 0xf9, 0x3a, 0xf2, 0xc9, 0xfa, 0x59, 0xe4, 0xe8, 0xf6, 0xd2, 0x9f, 0xb2,
244 0xa7, 0x7e, 0x32, 0x86, 0xbc, 0x43, 0xec, 0xa0, 0xc2, 0xcb, 0x98, 0x33, 0x23, 0xd1, 0x58, 0x98,
245 0x56, 0x05, 0xc7, 0xbc, 0x98, 0xd8, 0xdc, 0xb3, 0x35, 0xe8, 0x51, 0x6e, 0x3b, 0x7b, 0x89, 0xba,
246 0xe1, 0xe5, 0x44, 0x5c, 0x24, 0x73, 0x04, 0x0d, 0xd9, 0x33, 0xf5, 0x63, 0xe9, 0x5c, 0x88, 0x05,
247 0x18, 0xd0, 0x07, 0x5b, 0x1e, 0x81, 0x80, 0xac, 0x92, 0x6e, 0x13, 0x80, 0x1b, 0x29, 0xd2, 0xef,
248 0x08, 0x84, 0x97, 0x23, 0xd1, 0x17, 0x2f, 0x38, 0xb4, 0x6d, 0x8f, 0x2a, 0x15, 0xf0, 0x40, 0xe9,
249 0x02, 0x33, 0xd7, 0x5e, 0x99, 0x57, 0x15, 0x32, 0xbd, 0x8f, 0x48, 0x38, 0x91, 0x36, 0xe9, 0x07,
250 0xc9, 0x37, 0x1d, 0x12, 0x2a, 0xbf, 0x5f, 0xdb, 0x85, 0x75, 0xbf, 0xdc, 0x59, 0x8a, 0x43, 0x51,
251 0x4b, 0x77, 0xfd, 0x84, 0xc4, 0x28, 0xc7, 0x85, 0x25, 0x1a, 0x87, 0x8b, 0xc1, 0xd9, 0x1a, 0x78,
252 0xe5, 0x03, 0x20, 0x56, 0xa0, 0xc2, 0x17, 0xf2, 0x29, 0xa0, 0xbd, 0xf8, 0x61, 0x9c, 0x7d, 0x54,
253 0x3a, 0x11, 0xb5, 0x69, 0x9a, 0x1c, 0xbb, 0xf6, 0x2d, 0x86, 0xa8, 0x4d, 0xdd, 0x5a, 0xd6, 0xe4,
254 0x11, 0x7e, 0x4b, 0x13, 0x6c, 0xb6, 0x01, 0x0a, 0x72, 0xbc, 0xe8, 0xf1, 0x82, 0x0e, 0xd0, 0xcf,
255 0xbf, 0x50, 0x95, 0xb7, 0xa7, 0xec, 0xd7, 0xb3, 0x49, 0x5c, 0x47, 0x5f, 0xa9, 0xda, 0x70, 0xb0,
256 0xdc, 0x9a, 0xa3, 0x48, 0xd3, 0xf5, 0x72, 0xd5, 0x43, 0xd8, 0x19, 0xcc
257 }
258 };
259
260 static UINT16 *sharedprotram;
261
262 static UINT32 kb_regs[0x100];
263 static UINT16 kb_prot_hold;
264 static UINT16 kb_prot_hilo;
265 static UINT32 kb_ptr;
266 static UINT8 kb_region;
267 static UINT8 kb_cmd;
268 static UINT8 kb_reg;
269 static UINT8 kb_swap;
270 static UINT8 kb_cmd3;
271 static UINT8 olds_bs;
272 static UINT32 kb_prot_hilo_select;
273 static UINT32 kb_game_id;
274
IGS022_do_dma(UINT16 src,UINT16 dst,UINT16 size,UINT16 mode)275 static void IGS022_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode)
276 {
277 UINT16 param = mode >> 8;
278
279 bprintf (0, _T("src: %4.4x, dst: %4.4x, size: %4.4x, mode: %4.4x\n"), src,dst,size,mode);
280
281 mode &= 0x7; // what are the other bits?
282
283 if ((mode == 0) || (mode == 1) || (mode == 2) || (mode == 3) || (mode == 4))
284 {
285 UINT16 *PROTROM = (UINT16*)PGMProtROM;
286 for (INT32 x = 0; x < size; x++)
287 {
288 UINT16 dat2 = BURN_ENDIAN_SWAP_INT16(PROTROM[src + x]);
289
290 UINT8 extraoffset = param&0xff;
291 UINT8* dectable = PGMProtROM;
292 UINT8 taboff = ((x*2)+extraoffset) & 0xff;
293 UINT16 extraxor = ((dectable[taboff+0]) << 8) | (dectable[taboff+1] << 0);
294
295 dat2 = ((dat2 & 0x00ff)<<8) | ((dat2 & 0xff00)>>8);
296
297 if (mode==4)
298 {
299 extraxor = 0;
300 if ((x & 0x003) == 0x000) extraxor |= 0x0049; // 'I'
301 if ((x & 0x003) == 0x001) extraxor |= 0x0047; // 'G'
302 if ((x & 0x003) == 0x002) extraxor |= 0x0053; // 'S'
303 if ((x & 0x003) == 0x003) extraxor |= 0x0020; // ' '
304 if ((x & 0x300) == 0x000) extraxor |= 0x4900; // 'I'
305 if ((x & 0x300) == 0x100) extraxor |= 0x4700; // 'G'
306 if ((x & 0x300) == 0x200) extraxor |= 0x5300; // 'S'
307 if ((x & 0x300) == 0x300) extraxor |= 0x2000; // ' '
308
309 // extraxor = (extraxor << 8) | (extraxor >> 8); //
310 }
311
312 // mode==0 plain
313 if (mode==3) dat2 ^= extraxor;
314 if (mode==2) dat2 += extraxor;
315 if (mode==1) dat2 -= extraxor;
316
317 if (mode==4)
318 {
319 dat2 -= extraxor;
320 }
321
322 sharedprotram[dst + x] = BURN_ENDIAN_SWAP_INT16(dat2);
323 }
324 }
325 else if (mode == 5)
326 {
327 UINT16 *PROTROM = (UINT16*)PGMProtROM;
328
329 for (INT32 x = 0; x < size; x++)
330 {
331 UINT16 dat2 = BURN_ENDIAN_SWAP_INT16(PROTROM[src + x]);
332
333 sharedprotram[dst + x] = dat2;
334 }
335 }
336 else if (mode == 6)
337 {
338 UINT16 *PROTROM = (UINT16*)PGMProtROM;
339 for (INT32 x = 0; x < size; x++)
340 {
341 UINT16 dat2 = PROTROM[src + x];
342
343 dat2 = ((dat2 & 0xf000) >> 12)|
344 ((dat2 & 0x0f00) >> 4)|
345 ((dat2 & 0x00f0) << 4)|
346 ((dat2 & 0x000f) << 12);
347
348 sharedprotram[dst + x] = dat2;
349 }
350 }
351 }
352
IGS022_reset()353 static void IGS022_reset()
354 {
355 INT32 i;
356 UINT16 *PROTROM = (UINT16*)PGMProtROM;
357 UINT16 tmp;
358
359 // fill ram with A5 patern
360 for (i = 0; i < 0x4000/2; i++)
361 sharedprotram[i] = BURN_ENDIAN_SWAP_INT16(0xa55a);
362
363 // the auto-dma
364 UINT16 src = BURN_ENDIAN_SWAP_INT16(PROTROM[0x100 / 2]);
365 UINT32 dst = BURN_ENDIAN_SWAP_INT16(PROTROM[0x102 / 2]);
366 UINT16 size = BURN_ENDIAN_SWAP_INT16(PROTROM[0x104/ 2]);
367 UINT16 mode = BURN_ENDIAN_SWAP_INT16(PROTROM[0x106 / 2]);
368
369 src = ((src & 0xff00) >> 8) | ((src & 0x00ff) << 8);
370 dst = ((dst & 0xff00) >> 8) | ((dst & 0x00ff) << 8);
371 size = ((size & 0xff00) >> 8) | ((size & 0x00ff) << 8);
372 mode &= 0xff;
373
374 src >>= 1;
375
376 IGS022_do_dma(src,dst,size,mode);
377
378 // there is also a version ID? (or is it some kind of checksum) that is stored in the data rom, and gets copied..
379 // Dragon World 3 checks it
380 tmp = BURN_ENDIAN_SWAP_INT16(PROTROM[0x114/2]);
381 tmp = ((tmp & 0xff00) >> 8) | ((tmp & 0x00ff) << 8);
382 sharedprotram[0x2a2/2] = BURN_ENDIAN_SWAP_INT16(tmp);
383 }
384
IGS022_handle_command()385 static void IGS022_handle_command()
386 {
387 UINT16 cmd = sharedprotram[0x200/2];
388
389 if (cmd == 0x6d) // Store values to asic ram
390 {
391 UINT32 p1 = (sharedprotram[0x298/2] << 16) | sharedprotram[0x29a/2];
392 UINT32 p2 = (sharedprotram[0x29c/2] << 16) | sharedprotram[0x29e/2];
393
394 if ((p2 & 0xffff) == 0x9) // Set value
395 {
396 INT32 reg = (p2 >> 16) & 0xffff;
397
398 if (reg & 0x300) { // 300?? killbld expects 0x200, drgw3 expects 0x100?
399 kb_regs[reg & 0xff] = p1;
400 }
401 }
402
403 if ((p2 & 0xffff) == 0x6) // Add value
404 {
405 INT32 src1 = (p1 >> 16) & 0xff;
406 INT32 src2 = (p1 >> 0) & 0xff;
407 INT32 dst = (p2 >> 16) & 0xff;
408
409 kb_regs[dst] = kb_regs[src2] - kb_regs[src1];
410 }
411
412 if ((p2 & 0xffff) == 0x1) // Add Imm?
413 {
414 INT32 reg = (p2 >> 16) & 0xff;
415 INT32 imm = (p1 >> 0) & 0xffff;
416
417 kb_regs[reg] += imm;
418 }
419
420 if ((p2 & 0xffff) == 0xa) // Get value
421 {
422 INT32 reg = (p1 >> 16) & 0xFF;
423
424 sharedprotram[0x29c/2] = (kb_regs[reg] >> 16) & 0xffff;
425 sharedprotram[0x29e/2] = kb_regs[reg] & 0xffff;
426 }
427
428 sharedprotram[0x202 / 2] = 0x7c; // this mode complete?
429 }
430
431 // Is this actually what this is suppose to do? Complete guess.
432 if (cmd == 0x12) // copy??
433 {
434 sharedprotram[0x28c / 2] = sharedprotram[0x288 / 2];
435 sharedprotram[0x28e / 2] = sharedprotram[0x28a / 2];
436
437 sharedprotram[0x202 / 2] = 0x23; // this mode complete?
438 }
439
440 // what do these do? write the completion byte for now...
441 if (cmd == 0x45) sharedprotram[0x202 / 2] = 0x56;
442 if (cmd == 0x5a) sharedprotram[0x202 / 2] = 0x4b;
443 if (cmd == 0x2d) sharedprotram[0x202 / 2] = 0x3c;
444
445 if (cmd == 0x4f) // memcpy with encryption / scrambling
446 {
447 UINT16 src = sharedprotram[0x290 / 2] >> 1;
448 UINT32 dst = sharedprotram[0x292 / 2];
449 UINT16 size = sharedprotram[0x294 / 2];
450 UINT16 mode = sharedprotram[0x296 / 2];
451
452 IGS022_do_dma(src,dst,size,mode);
453
454 sharedprotram[0x202 / 2] = 0x5e; // this mode complete?
455 }
456 }
457
458 #if 0
459 static UINT32 olds_prot_addr(UINT16 addr)
460 {
461 switch (addr & 0xff)
462 {
463 case 0x0:
464 case 0x5:
465 case 0xa: return 0x402a00 + ((addr >> 8) << 2);
466 case 0x2:
467 case 0x8: return 0x402e00 + ((addr >> 8) << 2);
468 case 0x1: return 0x40307e;
469 case 0x3: return 0x403090;
470 case 0x4: return 0x40309a;
471 case 0x6: return 0x4030a4;
472 case 0x7: return 0x403000;
473 case 0x9: return 0x40306e;
474 case 0xb: return 0x403044;
475 }
476
477 return 0;
478 }
479
480 static UINT32 olds_read_reg(UINT16 addr)
481 {
482 UINT32 protaddr = (olds_prot_addr(addr) - 0x400000) / 2;
483 return sharedprotram[protaddr] << 16 | sharedprotram[protaddr + 1];
484 }
485
486 static void olds_write_reg( UINT16 addr, UINT32 val )
487 {
488 sharedprotram[((olds_prot_addr(addr) - 0x400000) / 2) + 0] = val >> 16;
489 sharedprotram[((olds_prot_addr(addr) - 0x400000) / 2) + 1] = val & 0xffff;
490 }
491
492 static void IGS028_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode)
493 {
494 UINT16 param = mode >> 8;
495 UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000);
496
497 mode &= 0x0f;
498
499 switch (mode & 0x7)
500 {
501 case 0x00: // -= encryption
502 case 0x01: // swap nibbles
503 case 0x02: // ^= encryption
504 case 0x03: // unused?
505 case 0x04: // unused?
506 case 0x05: // swap bytes
507 case 0x06: // += encryption (correct?)
508 case 0x07: // unused?
509 {
510 UINT8 extraoffset = param & 0xff;
511 UINT8 *dectable = (UINT8 *)(PGMProtROM + (0x100 / 2));
512
513 for (INT32 x = 0; x < size; x++)
514 {
515 UINT16 dat2 = PROTROM[src + x];
516
517 int taboff = ((x*2)+extraoffset) & 0xff; // must allow for overflow in instances of odd offsets
518 unsigned short extraxor = ((dectable[taboff + 0]) << 0) | (dectable[taboff + 1] << 8);
519
520 if (mode==0) dat2 -= extraxor;
521 else if (mode==1) dat2 = ((dat2 & 0xf0f0) >> 4)|((dat2 & 0x0f0f) << 4);
522 else if (mode==2) dat2 ^= extraxor;
523 else if (mode==5) dat2 = ((dat2 &0x00ff) << 8) | ((dat2 &0xff00) >> 8);
524 else if (mode==6) dat2 += extraxor;
525 else
526 {
527 UINT16 extraxor2 = 0;
528 if ((x & 0x003) == 0x000) extraxor2 |= 0x0049; // 'I'
529 if ((x & 0x003) == 0x001) extraxor2 |= 0x0047; // 'G'
530 if ((x & 0x003) == 0x002) extraxor2 |= 0x0053; // 'S'
531 if ((x & 0x003) == 0x003) extraxor2 |= 0x0020; // ' '
532 if ((x & 0x300) == 0x000) extraxor2 |= 0x4900; // 'I'
533 if ((x & 0x300) == 0x100) extraxor2 |= 0x4700; // 'G'
534 if ((x & 0x300) == 0x200) extraxor2 |= 0x5300; // 'S'
535 if ((x & 0x300) == 0x300) extraxor2 |= 0x2000; // ' '
536
537 dat2 = 0x4e75; // hack
538 }
539
540 sharedprotram[dst + x] = dat2;
541 }
542 }
543 break;
544 }
545 }
546
547 static void IGS028_handle()
548 {
549 UINT16 cmd = sharedprotram[0x3026 / 2];
550
551 switch (cmd)
552 {
553 case 0x12:
554 {
555 UINT16 mode = sharedprotram[0x303e / 2]; // ?
556 UINT16 src = sharedprotram[0x306a / 2] >> 1; // ?
557 UINT16 dst = sharedprotram[0x3084 / 2] & 0x1fff;
558 UINT16 size = sharedprotram[0x30a2 / 2] & 0x1fff;
559
560 IGS028_do_dma(src, dst, size, mode);
561 }
562 break;
563
564 case 0x64: // incomplete?
565 {
566 UINT16 p1 = sharedprotram[0x3050 / 2];
567 UINT16 p2 = sharedprotram[0x3082 / 2];
568 UINT16 p3 = sharedprotram[0x3054 / 2];
569 UINT16 p4 = sharedprotram[0x3088 / 2];
570
571 if (p2 == 0x02)
572 olds_write_reg(p1, olds_read_reg(p1) + 0x10000);
573
574 switch (p4)
575 {
576 case 0xd:
577 olds_write_reg(p1,olds_read_reg(p3));
578 break;
579 case 0x0:
580 olds_write_reg(p3,(olds_read_reg(p2))^(olds_read_reg(p1)));
581 break;
582 case 0xe:
583 olds_write_reg(p3,olds_read_reg(p3)+0x10000);
584 break;
585 case 0x2:
586 olds_write_reg(p1,(olds_read_reg(p2))+(olds_read_reg(p3)));
587 break;
588 case 0x6:
589 olds_write_reg(p3,(olds_read_reg(p2))&(olds_read_reg(p1)));
590 break;
591 case 0x1:
592 olds_write_reg(p2,olds_read_reg(p1)+0x10000);
593 break;
594 case 0x7:
595 olds_write_reg(p3,olds_read_reg(p1));
596 break;
597 }
598 }
599 break;
600 }
601 }
602 #endif
603
killbld_protection_calculate_hold(INT32 y,INT32 z)604 static void killbld_protection_calculate_hold(INT32 y, INT32 z)
605 {
606 UINT16 old = kb_prot_hold;
607
608 kb_prot_hold = ((old << 1) | (old >> 15));
609
610 kb_prot_hold ^= 0x2bad;
611 kb_prot_hold ^= BIT(z, y);
612 kb_prot_hold ^= BIT(old, 7) << 0;
613 kb_prot_hold ^= BIT(~old, 13) << 4;
614 kb_prot_hold ^= BIT(old, 3) << 11;
615
616 kb_prot_hold ^= (kb_prot_hilo & ~0x0408) << 1;
617 }
618
killbld_protection_calculate_hilo()619 static void killbld_protection_calculate_hilo()
620 {
621 kb_prot_hilo_select++;
622
623 if (kb_prot_hilo_select > 0xeb) {
624 kb_prot_hilo_select = 0;
625 }
626
627 UINT8 source = source_data[kb_region][kb_prot_hilo_select];
628
629 if (kb_prot_hilo_select & 1)
630 {
631 kb_prot_hilo = (kb_prot_hilo & 0x00ff) | (source << 8);
632 }
633 else
634 {
635 kb_prot_hilo = (kb_prot_hilo & 0xff00) | (source << 0);
636 }
637 }
638
killbld_igs025_prot_write(UINT32 address,UINT16 data)639 static void __fastcall killbld_igs025_prot_write(UINT32 address, UINT16 data)
640 {
641 bprintf (0, _T("PRTW: %5.5x %4.4x\n"), address, data);
642
643 if ((address & 0xf0000f) == 0xd00000) {
644 kb_cmd = data;
645 return;
646 }
647
648 switch (kb_cmd)
649 {
650 case 0x00:
651 kb_reg = data;
652 break;
653
654 case 0x01: // drgw3
655 {
656 if (data == 0x0002) { // Execute command
657 IGS022_handle_command();
658 }
659 }
660 break;
661
662 case 0x02: // killbld
663 {
664 if (data == 0x0001) { // Execute command
665 IGS022_handle_command();
666 kb_reg++;
667 }
668 }
669 break;
670
671 case 0x03:
672 kb_swap = data;
673 break;
674
675 case 0x04:
676 // kb_ptr = data; // Suspect. Not good for drgw3
677 break;
678
679 case 0x20:
680 case 0x21:
681 case 0x22:
682 case 0x23:
683 case 0x24:
684 case 0x25:
685 case 0x26:
686 case 0x27:
687 kb_ptr++;
688 killbld_protection_calculate_hold(kb_cmd & 0x0f, data & 0xff);
689 break;
690 }
691 }
692
693 #if 0
694 static void __fastcall olds_igs025_prot_write(UINT32 address, UINT16 data)
695 {
696 bprintf (0, _T("PRTW: %5.5x %4.4x\n"), address, data);
697
698 if (address == 0xdcb400) {
699 kb_cmd = data;
700 return;
701 }
702
703 switch (kb_cmd)
704 {
705 case 0x00:
706 kb_reg = data;
707 break;
708
709 case 0x02:
710 olds_bs = ((data & 0x03) << 6) | ((data & 0x04) << 3) | ((data & 0x08) << 1);
711 break;
712
713 case 0x03:
714 {
715 IGS028_handle();
716 kb_cmd3 = ((data >> 4) + 1) & 0x3;
717 }
718 break;
719
720 case 0x04:
721 kb_ptr = data;
722 break;
723
724 case 0x20:
725 case 0x21:
726 case 0x22:
727 case 0x23:
728 case 0x24:
729 case 0x25:
730 case 0x26:
731 case 0x27:
732 kb_ptr++;
733 killbld_protection_calculate_hold(kb_cmd & 0x0f, data & 0xff);
734 break;
735 }
736 }
737 #endif
738
drgw2_igs025_prot_write(UINT32 address,UINT16 data)739 static void __fastcall drgw2_igs025_prot_write(UINT32 address, UINT16 data)
740 {
741 bprintf (0, _T("PRTW: %5.5x %4.4x\n"), address, data);
742
743 if (address == 0xd80000) {
744 kb_cmd = data;
745 return;
746 }
747
748 switch (kb_cmd)
749 {
750 case 0x20:
751 case 0x21:
752 case 0x22:
753 case 0x23:
754 case 0x24:
755 case 0x25:
756 case 0x26:
757 case 0x27:
758 kb_ptr++;
759 killbld_protection_calculate_hold(kb_cmd & 0x0f, data & 0xff);
760 break;
761 }
762 }
763
igs025_prot_read(UINT32 address)764 static UINT16 __fastcall igs025_prot_read(UINT32 address)
765 {
766 bprintf (0, _T("PRTR: %5.5x\n"), address);
767
768 switch (kb_cmd)
769 {
770 case 0x00:
771 return BITSWAP08((kb_swap + 1) & 0x7f, 0, 1, 2, 3, 4, 5, 6, 7); // drgw3
772
773 case 0x01:
774 return kb_reg & 0x7f;
775
776 case 0x02:
777 return olds_bs | 0x80;
778
779 case 0x03:
780 return kb_cmd3;
781
782 case 0x05:
783 {
784 switch (kb_ptr)
785 {
786 case 1:
787 return 0x3f00 | ((kb_game_id >> 0) & 0xff);
788
789 case 2:
790 return 0x3f00 | ((kb_game_id >> 8) & 0xff);
791
792 case 3:
793 return 0x3f00 | ((kb_game_id >> 16) & 0xff);
794
795 case 4:
796 return 0x3f00 | ((kb_game_id >> 24) & 0xff);
797
798 default: // >= 5
799 return 0x3f00 | BITSWAP08(kb_prot_hold, 5, 2, 9, 7, 10, 13, 12, 15);
800 }
801 }
802
803 case 0x40:
804 killbld_protection_calculate_hilo();
805 return 0;
806 }
807
808 return 0;
809 }
810
common_reset()811 static void common_reset()
812 {
813 kb_region = PgmInput[7];
814
815 kb_prot_hold = 0;
816 kb_prot_hilo = 0;
817 kb_prot_hilo_select = 0;
818 kb_cmd = 0;
819 kb_reg = 0;
820 kb_ptr = 0;
821 kb_swap = 0;
822 olds_bs = 0;
823 kb_cmd3 = 0;
824
825 memset(kb_regs, 0, 0x100 * sizeof(UINT32));
826 }
827
drgw2_reset()828 static void drgw2_reset()
829 {
830 if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2") == 0) kb_region = 6;
831 if (strcmp(BurnDrvGetTextA(DRV_NAME), "dw2v100x") == 0) kb_region = 6;
832 if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2c") == 0) kb_region = 5;
833 if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2j") == 0) kb_region = 1;
834
835 common_reset();
836 }
837
killbld_reset()838 static void killbld_reset()
839 {
840 common_reset();
841
842 kb_game_id = 0x89911400 | kb_region;
843
844 IGS022_reset();
845 }
846
drgw3_reset()847 static void drgw3_reset()
848 {
849 common_reset();
850
851 kb_game_id = 0x00060000 | kb_region;
852
853 IGS022_reset();
854 }
855
CommonScan(INT32 nAction,INT32 *)856 static INT32 CommonScan(INT32 nAction, INT32 *)
857 {
858 struct BurnArea ba;
859
860 if (nAction & ACB_MEMORY_RAM) {
861 ba.Data = PGMUSER0;
862 ba.nLen = 0x0004000;
863 ba.nAddress = 0x400000;
864 ba.szName = "ProtRAM";
865 BurnAcb(&ba);
866
867 ba.Data = (UINT8*)kb_regs;
868 ba.nLen = 0x00100 * sizeof(INT32);
869 ba.nAddress = 0xfffffc00;
870 ba.szName = "Protection Registers";
871 BurnAcb(&ba);
872 }
873
874 if (nAction & ACB_DRIVER_DATA) {
875 SCAN_VAR(kb_prot_hold);
876 SCAN_VAR(kb_prot_hilo);
877 SCAN_VAR(kb_ptr);
878 SCAN_VAR(kb_region);
879 SCAN_VAR(kb_cmd);
880 SCAN_VAR(kb_reg);
881 SCAN_VAR(kb_swap);
882 SCAN_VAR(kb_cmd3);
883 SCAN_VAR(olds_bs);
884 SCAN_VAR(kb_prot_hilo_select);
885 SCAN_VAR(kb_game_id);
886 }
887
888 return 0;
889 }
890
891 #if 0
892 static void olds_reset()
893 {
894 common_reset();
895
896 kb_game_id = 0x00900000 | kb_region;
897
898 sharedprotram[0x1000/2] = 0x4749; // 'IGS.28'
899 sharedprotram[0x1002/2] = 0x2E53;
900 sharedprotram[0x1004/2] = 0x3832;
901
902 sharedprotram[0x3064/2] = 0xB315; // crc?
903 }
904 #endif
905
install_protection_asic25_asic22_killbld()906 void install_protection_asic25_asic22_killbld()
907 {
908 BurnByteswap(PGMProtROM, 0x10000);
909
910 pPgmScanCallback = CommonScan;
911 pPgmResetCallback = killbld_reset;
912
913 sharedprotram = (UINT16*)PGMUSER0;
914
915 SekOpen(0);
916 SekMapMemory(PGMUSER0, 0x300000, 0x303fff, MAP_RAM);
917 SekMapHandler(4, 0xd40000, 0xd40003, MAP_READ | MAP_WRITE);
918 SekSetReadWordHandler(4, igs025_prot_read);
919 SekSetWriteWordHandler(4, killbld_igs025_prot_write);
920 SekClose();
921 }
922
install_protection_asic25_asic22_drgw3()923 void install_protection_asic25_asic22_drgw3()
924 {
925 BurnByteswap(PGMProtROM, 0x10000);
926
927 pPgmScanCallback = CommonScan;
928 pPgmResetCallback = drgw3_reset;
929
930 sharedprotram = (UINT16*)PGMUSER0;
931
932 SekOpen(0);
933 SekMapMemory(PGMUSER0, 0x300000, 0x303fff, MAP_RAM);
934 SekMapHandler(4, 0xda5610, 0xda5613, MAP_READ | MAP_WRITE);
935 SekSetReadWordHandler(4, igs025_prot_read);
936 SekSetWriteWordHandler(4, killbld_igs025_prot_write);
937 SekClose();
938 }
939
install_protection_asic25_asic12_dw2()940 void install_protection_asic25_asic12_dw2()
941 {
942 pPgmScanCallback = CommonScan;
943 pPgmResetCallback = drgw2_reset;
944
945 SekOpen(0);
946 SekMapHandler(4, 0xd80000, 0xd80003, MAP_READ | MAP_WRITE);
947 SekSetReadWordHandler(4, igs025_prot_read);
948 SekSetWriteWordHandler(4, drgw2_igs025_prot_write);
949 SekClose();
950 }
951
952 #if 0
953 void install_protection_asic25_asic28_olds()
954 {
955 pPgmScanCallback = CommonScan;
956 pPgmResetCallback = olds_reset;
957
958 sharedprotram = (UINT16*)PGMUSER0;
959
960 SekOpen(0);
961 SekMapMemory(PGMUSER0, 0x400000, 0x403fff, MAP_RAM);
962 SekMapHandler(4, 0xdcb400, 0xdcb403, MAP_READ | MAP_WRITE);
963 SekSetReadWordHandler(4, igs025_prot_read);
964 SekSetWriteWordHandler(4, olds_igs025_prot_write);
965 SekClose();
966 }
967 #endif
968
969
970
971 static INT32 m_olds_cmd;
972 static INT32 m_olds_reg;
973 static INT32 m_olds_ptr;
974 static UINT16 m_olds_bs;
975 static UINT16 m_olds_cmd3;
976 static UINT16 m_olds_prot_hold;
977 static UINT16 m_olds_prot_hilo;
978 static UINT16 m_olds_prot_hilo_select;
979
olds_prot_addr(UINT16 addr)980 static UINT32 olds_prot_addr(UINT16 addr)
981 {
982 switch (addr & 0xff)
983 {
984 case 0x0:
985 case 0x5:
986 case 0xa: return 0x402a00 + ((addr >> 8) << 2);
987 case 0x2:
988 case 0x8: return 0x402e00 + ((addr >> 8) << 2);
989 case 0x1: return 0x40307e;
990 case 0x3: return 0x403090;
991 case 0x4: return 0x40309a;
992 case 0x6: return 0x4030a4;
993 case 0x7: return 0x403000;
994 case 0x9: return 0x40306e;
995 }
996
997 return 0;
998 }
999
olds_read_reg(UINT16 addr)1000 static UINT32 olds_read_reg(UINT16 addr)
1001 {
1002 UINT32 protaddr = (olds_prot_addr(addr) - 0x400000) / 2;
1003 return sharedprotram[protaddr] << 16 | sharedprotram[protaddr + 1];
1004 }
1005
olds_write_reg(UINT16 addr,UINT32 val)1006 static void olds_write_reg( UINT16 addr, UINT32 val )
1007 {
1008 sharedprotram[(olds_prot_addr(addr) - 0x400000) / 2] = val >> 16;
1009 sharedprotram[(olds_prot_addr(addr) - 0x400000) / 2 + 1] = val & 0xffff;
1010 }
1011
IGS028_do_dma(UINT16 src,UINT16 dst,UINT16 size,UINT16 mode)1012 static void IGS028_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode)
1013 {
1014 UINT16 param = mode >> 8;
1015 UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000);
1016
1017 mode &= 0x0f;
1018
1019 // bprintf (0, _T("SRC: %4.4x, DST: %4.4x, SIZE: %4.4x, PARAM: %2.2x, MODE: %x\n"), src, dst*2, size*2, param, mode);
1020
1021 switch (mode & 0x7)
1022 {
1023 case 0x00: // -= encryption
1024 case 0x01: // swap nibbles
1025 case 0x02: // ^= encryption
1026 case 0x03: // unused?
1027 case 0x04: // unused?
1028 case 0x05: // swap bytes
1029 case 0x06: // += encryption (correct?)
1030 case 0x07: // unused?
1031 {
1032 UINT8 extraoffset = param & 0xff;
1033 UINT8 *dectable = PGMUSER0 + 0x10100;
1034
1035 for (INT32 x = 0; x < size; x++)
1036 {
1037 UINT16 dat2 = PROTROM[src + x];
1038
1039 int taboff = ((x*2)+extraoffset) & 0xff; // must allow for overflow in instances of odd offsets
1040 unsigned short extraxor = ((dectable[taboff + 0]) << 0) | (dectable[taboff + 1] << 8);
1041
1042 if (mode==0) dat2 -= extraxor;
1043 else if (mode==1) dat2 = ((dat2 & 0xf0f0) >> 4)|((dat2 & 0x0f0f) << 4);
1044 else if (mode==2) dat2 ^= extraxor;
1045 else if (mode==5) dat2 = ((dat2 &0x00ff) << 8) | ((dat2 &0xff00) >> 8);
1046 else if (mode==6) dat2 += extraxor;
1047 else
1048 {
1049 UINT16 extraxor2 = 0;
1050 if ((x & 0x003) == 0x000) extraxor2 |= 0x0049; // 'I'
1051 if ((x & 0x003) == 0x001) extraxor2 |= 0x0047; // 'G'
1052 if ((x & 0x003) == 0x002) extraxor2 |= 0x0053; // 'S'
1053 if ((x & 0x003) == 0x003) extraxor2 |= 0x0020; // ' '
1054 if ((x & 0x300) == 0x000) extraxor2 |= 0x4900; // 'I'
1055 if ((x & 0x300) == 0x100) extraxor2 |= 0x4700; // 'G'
1056 if ((x & 0x300) == 0x200) extraxor2 |= 0x5300; // 'S'
1057 if ((x & 0x300) == 0x300) extraxor2 |= 0x2000; // ' '
1058
1059 dat2 = 0x4e75; // hack
1060 }
1061
1062 sharedprotram[dst + x] = dat2;
1063 }
1064 }
1065 break;
1066 }
1067 }
1068
olds_protection_calculate_hold(int y,int z)1069 static void olds_protection_calculate_hold(int y, int z) // calculated in routine $12dbc2 in olds
1070 {
1071 unsigned short old = m_olds_prot_hold;
1072
1073 m_olds_prot_hold = ((old << 1) | (old >> 15));
1074
1075 m_olds_prot_hold ^= 0x2bad;
1076 m_olds_prot_hold ^= BIT(z, y);
1077 m_olds_prot_hold ^= BIT( old, 7) << 0;
1078 m_olds_prot_hold ^= BIT(~old, 13) << 4;
1079 m_olds_prot_hold ^= BIT( old, 3) << 11;
1080
1081 m_olds_prot_hold ^= (m_olds_prot_hilo & ~0x0408) << 1; // $81790c
1082 }
1083
olds_protection_calculate_hilo()1084 static void olds_protection_calculate_hilo() // calculated in routine $12dbc2 in olds
1085 {
1086 UINT8 source;
1087
1088 m_olds_prot_hilo_select++;
1089 if (m_olds_prot_hilo_select > 0xeb) {
1090 m_olds_prot_hilo_select = 0;
1091 }
1092
1093 source = source_data[PgmInput[7]][m_olds_prot_hilo_select];
1094
1095 if (m_olds_prot_hilo_select & 1) // $8178fa
1096 {
1097 m_olds_prot_hilo = (m_olds_prot_hilo & 0x00ff) | (source << 8); // $8178d8
1098 }
1099 else
1100 {
1101 m_olds_prot_hilo = (m_olds_prot_hilo & 0xff00) | (source << 0); // $8178d8
1102 }
1103 }
1104
olds_protection_w(UINT32 offset,UINT16 data)1105 static void __fastcall olds_protection_w(UINT32 offset, UINT16 data)
1106 {
1107 offset &= 2;
1108
1109 if (offset == 0)
1110 {
1111 m_olds_cmd = data;
1112 }
1113 else
1114 {
1115 switch (m_olds_cmd)
1116 {
1117 case 0x00:
1118 m_olds_reg = data;
1119 break;
1120
1121 case 0x02:
1122 m_olds_bs = ((data & 0x03) << 6) | ((data & 0x04) << 3) | ((data & 0x08) << 1);
1123 break;
1124
1125 case 0x03:
1126 {
1127 UINT16 cmd = sharedprotram[0x3026 / 2];
1128
1129 switch (cmd)
1130 {
1131 case 0x12:
1132 {
1133 UINT16 mode = sharedprotram[0x303e / 2]; // ?
1134 UINT16 src = sharedprotram[0x306a / 2] >> 1; // ?
1135 UINT16 dst = sharedprotram[0x3084 / 2] & 0x1fff;
1136 UINT16 size = sharedprotram[0x30a2 / 2] & 0x1fff;
1137
1138 IGS028_do_dma(src, dst, size, mode);
1139 }
1140 break;
1141
1142 case 0x64: // incomplete...
1143 {
1144 UINT16 p1 = sharedprotram[0x3050 / 2];
1145 UINT16 p2 = sharedprotram[0x3082 / 2];
1146 UINT16 p3 = sharedprotram[0x3054 / 2];
1147 UINT16 p4 = sharedprotram[0x3088 / 2];
1148
1149 if (p2 == 0x02)
1150 olds_write_reg(p1, olds_read_reg(p1) + 0x10000);
1151
1152 switch (p4)
1153 {
1154 case 0xd:
1155 olds_write_reg(p1,olds_read_reg(p3));
1156 break;
1157 case 0x0:
1158 olds_write_reg(p3,(olds_read_reg(p2))^(olds_read_reg(p1)));
1159 break;
1160 case 0xe:
1161 olds_write_reg(p3,olds_read_reg(p3)+0x10000);
1162 break;
1163 case 0x2:
1164 olds_write_reg(p1,(olds_read_reg(p2))+(olds_read_reg(p3)));
1165 break;
1166 case 0x6:
1167 olds_write_reg(p3,(olds_read_reg(p2))&(olds_read_reg(p1)));
1168 break;
1169 case 0x1:
1170 olds_write_reg(p2,olds_read_reg(p1)+0x10000);
1171 break;
1172 case 0x7:
1173 olds_write_reg(p3,olds_read_reg(p1));
1174 break;
1175 default:
1176 break;
1177 }
1178 }
1179 }
1180
1181 m_olds_cmd3 = ((data >> 4) + 1) & 0x3;
1182 }
1183 break;
1184
1185 case 0x04:
1186 m_olds_ptr = data;
1187 break;
1188
1189 case 0x20:
1190 case 0x21:
1191 case 0x22:
1192 case 0x23:
1193 case 0x24:
1194 case 0x25:
1195 case 0x26:
1196 case 0x27:
1197 m_olds_ptr++;
1198 olds_protection_calculate_hold(m_olds_cmd & 0x0f, data & 0xff);
1199 break;
1200 }
1201 }
1202 }
1203
olds_protection_r(UINT32 offset)1204 static UINT16 __fastcall olds_protection_r(UINT32 offset)
1205 {
1206 offset &= 2;
1207
1208 if (offset)
1209 {
1210 switch (m_olds_cmd)
1211 {
1212 case 0x01:
1213 return m_olds_reg & 0x7f;
1214
1215 case 0x02:
1216 return m_olds_bs | 0x80;
1217
1218 case 0x03:
1219 return m_olds_cmd3;
1220
1221 case 0x05:
1222 {
1223 switch (m_olds_ptr)
1224 {
1225 case 1: return 0x3f00 | PgmInput[7];
1226
1227 case 2:
1228 return 0x3f00 | 0x00;
1229
1230 case 3:
1231 return 0x3f00 | 0x90;
1232
1233 case 4:
1234 return 0x3f00 | 0x00;
1235
1236 case 5:
1237 default: // >= 5
1238 return 0x3f00 | BITSWAP08(m_olds_prot_hold, 5,2,9,7,10,13,12,15); // $817906
1239 }
1240 }
1241
1242 case 0x40:
1243 olds_protection_calculate_hilo();
1244 return 0; // unused?
1245 }
1246 }
1247
1248 return 0;
1249 }
1250
reset_olds()1251 static void reset_olds()
1252 {
1253 // written by protection device
1254 // there seems to be an auto-dma that writes from $401000-402573?
1255 sharedprotram[0x1000/2] = 0x4749; // 'IGS.28'
1256 sharedprotram[0x1002/2] = 0x2E53;
1257 sharedprotram[0x1004/2] = 0x3832;
1258 sharedprotram[0x3064/2] = 0xB315; // crc or status check?
1259
1260 // Should these be written by command 64??
1261 // sharedprotram[0x2a00/2] = 0x0000; // ?
1262 // sharedprotram[0x2a02/2] = 0x0000; // ?
1263 sharedprotram[0x2a04/2] = 0x0002; // ?
1264 // sharedprotram[0x2a06/2] = 0x0000; // ?
1265 // sharedprotram[0x2ac0/2] = 0x0000; // ?
1266 sharedprotram[0x2ac2/2] = 0x0001; // ?
1267 // sharedprotram[0x2e00/2] = 0x0000; // ?
1268 // sharedprotram[0x2e02/2] = 0x0000; // ?
1269 // sharedprotram[0x2e04/2] = 0x0000; // ?
1270 sharedprotram[0x2e06/2] = 0x0009; // seconds on char. select timer
1271 // sharedprotram[0x2e08/2] = 0x0000; // ?
1272 sharedprotram[0x2e0a/2] = 0x0006; // ?
1273
1274 m_olds_prot_hold = 0;
1275 m_olds_prot_hilo = 0;
1276 m_olds_prot_hilo_select = 0;
1277 m_olds_cmd = 0;
1278 m_olds_reg = 0;
1279 m_olds_ptr = 0;
1280 m_olds_bs = 0;
1281 m_olds_cmd3 = 0;
1282 }
1283
oldsScan(INT32 nAction,INT32 *)1284 static INT32 oldsScan(INT32 nAction, INT32 *)
1285 {
1286 struct BurnArea ba;
1287
1288 if (nAction & ACB_MEMORY_RAM) {
1289 ba.Data = PGMUSER0 + 0x000000;
1290 ba.nLen = 0x0004000;
1291 ba.nAddress = 0x400000;
1292 ba.szName = "ProtRAM";
1293 BurnAcb(&ba);
1294 }
1295
1296 if (nAction & ACB_DRIVER_DATA) {
1297 SCAN_VAR(m_olds_prot_hold);
1298 SCAN_VAR(m_olds_prot_hilo);
1299 SCAN_VAR(m_olds_prot_hilo_select);
1300 SCAN_VAR(m_olds_cmd);
1301 SCAN_VAR(m_olds_reg);
1302 SCAN_VAR(m_olds_ptr);
1303 SCAN_VAR(m_olds_bs);
1304 SCAN_VAR(m_olds_cmd3);
1305 }
1306
1307 return 0;
1308 }
1309
1310 // hack...
olds_mainram_read_word(UINT32 address)1311 static UINT16 __fastcall olds_mainram_read_word(UINT32 address)
1312 {
1313 if (SekGetPC(-1) >= 0x100000 && address != 0x8178d8) SekWriteWord(0x8178f4, SekReadWord(0x8178D8));
1314
1315 return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(PGM68KRAM + (address & 0x1fffe))));
1316 }
1317
olds_mainram_read_byte(UINT32 address)1318 static UINT8 __fastcall olds_mainram_read_byte(UINT32 address)
1319 {
1320 return PGM68KRAM[(address & 0x1ffff)^1];
1321 }
1322
install_protection_asic25_asic28_olds()1323 void install_protection_asic25_asic28_olds()
1324 {
1325 pPgmScanCallback = oldsScan;
1326 pPgmResetCallback = reset_olds;
1327
1328 sharedprotram = (UINT16*)PGMUSER0;
1329
1330 // no protection rom and different offset for olds100a
1331 if (strcmp(BurnDrvGetTextA(DRV_NAME), "olds100a") == 0) {
1332 BurnLoadRom(PGMUSER0 + 0x10000, 15, 1);
1333 } else {
1334 BurnLoadRom(PGMUSER0 + 0x10000, 19, 1);
1335 }
1336
1337 SekOpen(0);
1338
1339 SekMapMemory(PGMUSER0, 0x400000, 0x403fff, MAP_RAM);
1340
1341 SekMapHandler(4, 0xdcb400, 0xdcb403, MAP_READ | MAP_WRITE);
1342 SekSetReadWordHandler(4, olds_protection_r);
1343 SekSetWriteWordHandler(4, olds_protection_w);
1344
1345 SekMapHandler(5, 0x8178f4, 0x8178f5, MAP_ROM);
1346 SekSetReadWordHandler(5, olds_mainram_read_word);
1347 SekSetReadByteHandler(5, olds_mainram_read_byte);
1348
1349 SekClose();
1350 }
1351
1352