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