trunk/src/mame/machine/stvprot.c
| r21765 | r21766 | |
| 830 | 830 | machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x4fffff0, 0x4ffffff, FUNC(astrass_prot_r), FUNC(astrass_prot_w)); |
| 831 | 831 | } |
| 832 | 832 | |
| 833 | | /************************** |
| 834 | | * |
| 835 | | * Decathlete |
| 836 | | * |
| 837 | | **************************/ |
| 838 | | |
| 839 | | /* Decathlete seems to be a variation on this ... not understood */ |
| 840 | | static UINT32 decathlt_protregs[4]; |
| 841 | | static UINT32 decathlt_lastcount = 0; |
| 842 | | static UINT32 decathlt_part; |
| 843 | | static UINT32 decathlt_prot_uploadmode=0; |
| 844 | | static UINT32 decathlt_prot_uploadoffset=0; |
| 845 | | static UINT16 decathlt_prottable1[24]; |
| 846 | | static UINT16 decathlt_prottable2[128]; |
| 847 | | |
| 848 | | static READ32_HANDLER( decathlt_prot_r ) |
| 849 | | { |
| 850 | | // the offsets written to the protection device definitely only refer to 2 of the roms |
| 851 | | // it's a fair assumption to say that only those 2 are connected to the protection device |
| 852 | | UINT8 *ROM = (UINT8 *)space.machine().root_device().memregion("abus")->base()+0x1000000; |
| 853 | | |
| 854 | | if (offset==2) |
| 855 | | { |
| 856 | | UINT32 retvalue; |
| 857 | | |
| 858 | | retvalue = ROM[(decathlt_protregs[0]*2)-2]; decathlt_protregs[0]++; |
| 859 | | retvalue <<= 8; |
| 860 | | retvalue |= ROM[(decathlt_protregs[0]*2)+1-2]; |
| 861 | | retvalue <<= 8; |
| 862 | | retvalue |= ROM[(decathlt_protregs[0]*2)-2]; decathlt_protregs[0]++; |
| 863 | | retvalue <<= 8; |
| 864 | | retvalue |= ROM[(decathlt_protregs[0]*2)+1-2]; |
| 865 | | |
| 866 | | |
| 867 | | decathlt_lastcount++; |
| 868 | | logerror("blah_r %08x\n", retvalue); |
| 869 | | return retvalue; |
| 870 | | } |
| 871 | | else |
| 872 | | { |
| 873 | | logerror("%06x Decathlete prot R offset %04x mask %08x regs %08x, %08x, %08x, %08x\n",space.device().safe_pc(), offset, mem_mask, decathlt_protregs[0], decathlt_protregs[1], decathlt_protregs[2], decathlt_protregs[3]); |
| 874 | | } |
| 875 | | |
| 876 | | return decathlt_protregs[offset]; |
| 877 | | } |
| 878 | | |
| 879 | | |
| 880 | | void write_prot_data(UINT32 data, UINT32 mem_mask, int offset, int which) |
| 881 | | { |
| 882 | | decathlt_protregs[offset] = (data&mem_mask)|(decathlt_protregs[offset]&~mem_mask); |
| 883 | | // decathlt_protregs[0] = 0x0c00000/4; |
| 884 | | |
| 885 | | if (offset==0) // seems to set a (scrambled?) source address |
| 886 | | { |
| 887 | | decathlt_part ^=1; |
| 888 | | |
| 889 | | //if (decathlt_part==0) logerror("%d, last read count was %06x\n",which, decathlt_lastcount*4); |
| 890 | | decathlt_lastcount = 0; |
| 891 | | if (decathlt_part==1) logerror("%d Decathlete prot W offset %04x data %08x, %08x, >>> regs %08x <<<<, %08x, %08x, %08x\n",which, offset, data, decathlt_protregs[0], decathlt_protregs[0]*4, decathlt_protregs[1], decathlt_protregs[2], decathlt_protregs[3]); |
| 892 | | } |
| 893 | | |
| 894 | | if (offset==1) // uploads 2 tables... |
| 895 | | { |
| 896 | | if (mem_mask==0xffff0000) |
| 897 | | { |
| 898 | | if (data == 0x80000000) |
| 899 | | { |
| 900 | | // logerror("changed to upload mode 1\n"); |
| 901 | | decathlt_prot_uploadmode = 1; |
| 902 | | decathlt_prot_uploadoffset = 0; |
| 903 | | } |
| 904 | | else if (data == 0x80800000) |
| 905 | | { |
| 906 | | // logerror("changed to upload mode 2\n"); |
| 907 | | decathlt_prot_uploadmode = 2; |
| 908 | | decathlt_prot_uploadoffset = 0; |
| 909 | | } |
| 910 | | else |
| 911 | | { |
| 912 | | // logerror("unknown upload mode\n"); |
| 913 | | decathlt_prot_uploadmode = 2; |
| 914 | | decathlt_prot_uploadoffset = 0; |
| 915 | | } |
| 916 | | |
| 917 | | // logerror("ARGH! %08x %08x\n",mem_mask,data); |
| 918 | | } |
| 919 | | else if (mem_mask==0x0000ffff) |
| 920 | | { |
| 921 | | if (decathlt_prot_uploadmode==1) |
| 922 | | { |
| 923 | | if (decathlt_prot_uploadoffset>=24) |
| 924 | | { |
| 925 | | // logerror("upload mode 1 error, too big\n"); |
| 926 | | return; |
| 927 | | } |
| 928 | | |
| 929 | | //logerror("uploading table 1 %04x %04x\n",decathlt_prot_uploadoffset, data&0xffff); |
| 930 | | decathlt_prottable1[decathlt_prot_uploadoffset]=data&0xffff; |
| 931 | | decathlt_prot_uploadoffset++; |
| 932 | | |
| 933 | | { |
| 934 | | /* 0x18 (24) values in this table, rom data is 0x1800000 long, maybe it has |
| 935 | | something to do with that? or 24-address bits? |
| 936 | | |
| 937 | | uploaded values appear to be 12-bit, some are repeated |
| 938 | | */ |
| 939 | | |
| 940 | | { |
| 941 | | FILE* fp; |
| 942 | | if (which==1) fp = fopen("table1x","wb"); |
| 943 | | else fp = fopen("table1","wb"); |
| 944 | | |
| 945 | | { |
| 946 | | fwrite(&decathlt_prottable1,24,2,fp); |
| 947 | | } |
| 948 | | fclose(fp); |
| 949 | | } |
| 950 | | } |
| 951 | | |
| 952 | | } |
| 953 | | else if (decathlt_prot_uploadmode==2) |
| 954 | | { |
| 955 | | if (decathlt_prot_uploadoffset>=128) |
| 956 | | { |
| 957 | | //logerror("upload mode 2 error, too big\n"); |
| 958 | | return; |
| 959 | | } |
| 960 | | |
| 961 | | //logerror("uploading table 2 %04x %04x\n",decathlt_prot_uploadoffset, data&0xffff); |
| 962 | | decathlt_prottable2[decathlt_prot_uploadoffset]=data&0xffff; |
| 963 | | decathlt_prot_uploadoffset++; |
| 964 | | |
| 965 | | { |
| 966 | | /* the table uploaded here is a 256 byte table with 256 unique values, remaps something? */ |
| 967 | | |
| 968 | | { |
| 969 | | FILE* fp; |
| 970 | | if (which==1) fp = fopen("table2x","wb"); |
| 971 | | else fp = fopen("table2","wb"); |
| 972 | | |
| 973 | | { |
| 974 | | fwrite(&decathlt_prottable2,128,2,fp); |
| 975 | | } |
| 976 | | fclose(fp); |
| 977 | | } |
| 978 | | } |
| 979 | | } |
| 980 | | else |
| 981 | | { |
| 982 | | // logerror("unknown upload mode!\n"); |
| 983 | | } |
| 984 | | } |
| 985 | | } |
| 986 | | |
| 987 | | if (offset>1) |
| 988 | | { |
| 989 | | // logerror("higher offset write\n"); |
| 990 | | } |
| 991 | | |
| 992 | | } |
| 993 | | |
| 994 | | static WRITE32_HANDLER( decathlt_prot1_w ) |
| 995 | | { |
| 996 | | write_prot_data(data,mem_mask, offset, 0); |
| 997 | | |
| 998 | | } |
| 999 | | |
| 1000 | | static WRITE32_HANDLER( decathlt_prot2_w ) |
| 1001 | | { |
| 1002 | | write_prot_data(data,mem_mask, offset, 1); |
| 1003 | | |
| 1004 | | |
| 1005 | | } |
| 1006 | | |
| 1007 | | void install_decathlt_protection(running_machine &machine) |
| 1008 | | { |
| 1009 | | /* It uploads 2 tables here, then performs what looks like a number of transfers, setting |
| 1010 | | a source address of some kind (scrambled?) and then making many reads from a single address */ |
| 1011 | | memset(decathlt_protregs, 0, sizeof(decathlt_protregs)); |
| 1012 | | decathlt_lastcount = 0; |
| 1013 | | decathlt_prot_uploadmode = 0; |
| 1014 | | decathlt_prot_uploadoffset = 0; |
| 1015 | | decathlt_part = 1; |
| 1016 | | machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x37FFFF0, 0x37FFFFF, FUNC(decathlt_prot_r), FUNC(decathlt_prot1_w)); |
| 1017 | | /* It accesses the device at this address too, with different tables, for the game textures, should it just act like a mirror, or a secondary device? */ |
| 1018 | | machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x27FFFF0, 0x27FFFFF, FUNC(decathlt_prot_r), FUNC(decathlt_prot2_w)); |
| 1019 | | } |
| 1020 | | |
| 1021 | 833 | void stv_register_protection_savestates(running_machine &machine) |
| 1022 | 834 | { |
| 1023 | 835 | state_save_register_global_array(machine, a_bus); |
trunk/src/mame/machine/decathlt.c
| r0 | r21766 | |
| 1 | /* The Decathlete 'protection' seems to be some kind of Huffman style compression on the graphics, |
| 2 | the game uploads 2 dictionary tables (for different areas of the ROM) as well as an additional |
| 3 | table with each one. The secondary table doesn't initially appear to be the data needed to |
| 4 | build the trees required for decompression */ |
| 5 | |
| 6 | #include "emu.h" |
| 7 | #include "stvprot.h" |
| 8 | #include "includes/stv.h" |
| 9 | |
| 10 | /************************** |
| 11 | * |
| 12 | * Decathlete |
| 13 | * |
| 14 | **************************/ |
| 15 | |
| 16 | |
| 17 | static UINT32 decathlt_protregs[4]; |
| 18 | static UINT32 decathlt_lastcount = 0; |
| 19 | static UINT32 decathlt_part; |
| 20 | static UINT32 decathlt_prot_uploadmode=0; |
| 21 | static UINT32 decathlt_prot_uploadoffset=0; |
| 22 | static UINT16 decathlt_prottable1[24]; |
| 23 | static UINT16 decathlt_prottable2[128]; |
| 24 | |
| 25 | static READ32_HANDLER( decathlt_prot_r ) |
| 26 | { |
| 27 | // the offsets written to the protection device definitely only refer to 2 of the roms |
| 28 | // it's a fair assumption to say that only those 2 are connected to the protection device |
| 29 | UINT8 *ROM = (UINT8 *)space.machine().root_device().memregion("abus")->base()+0x1000000; |
| 30 | UINT32 *fake0 = (UINT32*)space.machine().root_device().memregion( "fake0" )->base(); |
| 31 | |
| 32 | if (offset==2) |
| 33 | { |
| 34 | UINT32 retvalue = 0xffff; |
| 35 | |
| 36 | switch (decathlt_protregs[0]) |
| 37 | { |
| 38 | default: |
| 39 | retvalue = ROM[(decathlt_protregs[0]*2)-2]; |
| 40 | retvalue <<= 8; |
| 41 | retvalue |= ROM[((decathlt_protregs[0]+1)*2)+1-2]; |
| 42 | retvalue <<= 8; |
| 43 | retvalue |= ROM[((decathlt_protregs[0]+1)*2)-2]; |
| 44 | retvalue <<= 8; |
| 45 | retvalue |= ROM[((decathlt_protregs[0]+2)*2)+1-2]; |
| 46 | decathlt_lastcount++; |
| 47 | logerror("read addr %08x, blah_r %08x - read count count %08x\n", decathlt_protregs[0], retvalue, decathlt_lastcount*4); |
| 48 | decathlt_protregs[0]+=2; |
| 49 | return retvalue; |
| 50 | |
| 51 | case 0x03228e4: |
| 52 | if (fake0) retvalue = fake0[(((0x20080/4)+decathlt_lastcount))]; |
| 53 | decathlt_lastcount++; |
| 54 | return retvalue; |
| 55 | |
| 56 | case 0x00a9f3a: |
| 57 | if (fake0) retvalue = fake0[(((0x00000/4)+decathlt_lastcount))]; |
| 58 | decathlt_lastcount++; |
| 59 | return retvalue; |
| 60 | |
| 61 | case 0x0213ab4: |
| 62 | if (fake0) retvalue = fake0[(((0x40000/4)+decathlt_lastcount))]; |
| 63 | decathlt_lastcount++; |
| 64 | return retvalue; |
| 65 | |
| 66 | case 0x01efaf0: |
| 67 | if (fake0) retvalue = fake0[(((0x60000/4)+decathlt_lastcount))]; |
| 68 | decathlt_lastcount++; |
| 69 | return retvalue; |
| 70 | |
| 71 | case 0x033f16c: |
| 72 | case 0x038929c: |
| 73 | |
| 74 | |
| 75 | |
| 76 | case 0x00de05a: |
| 77 | case 0x0334258: |
| 78 | case 0x019fb82: |
| 79 | case 0x033dbf6: |
| 80 | case 0x0011ac6: |
| 81 | case 0x00060dc: |
| 82 | case 0x0000002: |
| 83 | case 0x0008c90: |
| 84 | case 0x035cdc8: |
| 85 | case 0x0327960: |
| 86 | case 0x0329b8c: |
| 87 | case 0x00d6e92: |
| 88 | case 0x000081e: |
| 89 | case 0x00035d6: |
| 90 | case 0x00089a6: |
| 91 | case 0x03315f4: |
| 92 | case 0x0023fe0: |
| 93 | case 0x001e290: |
| 94 | case 0x0026e86: |
| 95 | case 0x0012494: |
| 96 | case 0x001b35a: |
| 97 | case 0x0018424: |
| 98 | |
| 99 | return retvalue; |
| 100 | } |
| 101 | |
| 102 | |
| 103 | } |
| 104 | else |
| 105 | { |
| 106 | logerror("%06x Decathlete prot R offset %04x mask %08x regs %08x, %08x, %08x, %08x\n",space.device().safe_pc(), offset, mem_mask, decathlt_protregs[0], decathlt_protregs[1], decathlt_protregs[2], decathlt_protregs[3]); |
| 107 | } |
| 108 | |
| 109 | return decathlt_protregs[offset]; |
| 110 | } |
| 111 | |
| 112 | |
| 113 | void write_prot_data(UINT32 data, UINT32 mem_mask, int offset, int which) |
| 114 | { |
| 115 | decathlt_protregs[offset] = (data&mem_mask)|(decathlt_protregs[offset]&~mem_mask); |
| 116 | // decathlt_protregs[0] = 0x0c00000/4; |
| 117 | |
| 118 | if (offset==0) // seems to set a (scrambled?) source address |
| 119 | { |
| 120 | decathlt_part ^=1; |
| 121 | |
| 122 | //if (decathlt_part==0) logerror("%d, last read count was %06x\n",which, decathlt_lastcount*4); |
| 123 | decathlt_lastcount = 0; |
| 124 | if (decathlt_part==1) logerror("%d Decathlete prot W offset %04x data %08x, %08x, >>> regs %08x <<<<, %08x, %08x, %08x\n",which, offset, data, decathlt_protregs[0], decathlt_protregs[0]*4, decathlt_protregs[1], decathlt_protregs[2], decathlt_protregs[3]); |
| 125 | } |
| 126 | |
| 127 | if (offset==1) // uploads 2 tables... |
| 128 | { |
| 129 | if (mem_mask==0xffff0000) |
| 130 | { |
| 131 | if (data == 0x80000000) |
| 132 | { |
| 133 | // logerror("changed to upload mode 1\n"); |
| 134 | decathlt_prot_uploadmode = 1; |
| 135 | decathlt_prot_uploadoffset = 0; |
| 136 | } |
| 137 | else if (data == 0x80800000) |
| 138 | { |
| 139 | // logerror("changed to upload mode 2\n"); |
| 140 | decathlt_prot_uploadmode = 2; |
| 141 | decathlt_prot_uploadoffset = 0; |
| 142 | } |
| 143 | else |
| 144 | { |
| 145 | // logerror("unknown upload mode\n"); |
| 146 | decathlt_prot_uploadmode = 2; |
| 147 | decathlt_prot_uploadoffset = 0; |
| 148 | } |
| 149 | |
| 150 | // logerror("ARGH! %08x %08x\n",mem_mask,data); |
| 151 | } |
| 152 | else if (mem_mask==0x0000ffff) |
| 153 | { |
| 154 | if (decathlt_prot_uploadmode==1) |
| 155 | { |
| 156 | if (decathlt_prot_uploadoffset>=24) |
| 157 | { |
| 158 | // logerror("upload mode 1 error, too big\n"); |
| 159 | return; |
| 160 | } |
| 161 | |
| 162 | //logerror("uploading table 1 %04x %04x\n",decathlt_prot_uploadoffset, data&0xffff); |
| 163 | decathlt_prottable1[decathlt_prot_uploadoffset]=data&0xffff; |
| 164 | decathlt_prot_uploadoffset++; |
| 165 | |
| 166 | { |
| 167 | /* 0x18 (24) values in this table, rom data is 0x1800000 long, maybe it has |
| 168 | something to do with that? or 24-address bits? |
| 169 | |
| 170 | uploaded values appear to be 12-bit, some are repeated |
| 171 | */ |
| 172 | |
| 173 | { |
| 174 | FILE* fp; |
| 175 | if (which==1) fp = fopen("table1x","wb"); |
| 176 | else fp = fopen("table1","wb"); |
| 177 | |
| 178 | { |
| 179 | fwrite(&decathlt_prottable1,24,2,fp); |
| 180 | } |
| 181 | fclose(fp); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | } |
| 186 | else if (decathlt_prot_uploadmode==2) |
| 187 | { |
| 188 | if (decathlt_prot_uploadoffset>=128) |
| 189 | { |
| 190 | //logerror("upload mode 2 error, too big\n"); |
| 191 | return; |
| 192 | } |
| 193 | |
| 194 | //logerror("uploading table 2 %04x %04x\n",decathlt_prot_uploadoffset, data&0xffff); |
| 195 | decathlt_prottable2[decathlt_prot_uploadoffset]=data&0xffff; |
| 196 | decathlt_prot_uploadoffset++; |
| 197 | |
| 198 | { |
| 199 | /* the table uploaded here is a 256 byte table with 256 unique values, remaps something? */ |
| 200 | |
| 201 | { |
| 202 | FILE* fp; |
| 203 | if (which==1) fp = fopen("table2x","wb"); |
| 204 | else fp = fopen("table2","wb"); |
| 205 | |
| 206 | { |
| 207 | fwrite(&decathlt_prottable2,128,2,fp); |
| 208 | } |
| 209 | fclose(fp); |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | else |
| 214 | { |
| 215 | // logerror("unknown upload mode!\n"); |
| 216 | } |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | if (offset>1) |
| 221 | { |
| 222 | // logerror("higher offset write\n"); |
| 223 | } |
| 224 | |
| 225 | } |
| 226 | |
| 227 | static WRITE32_HANDLER( decathlt_prot1_w ) |
| 228 | { |
| 229 | write_prot_data(data,mem_mask, offset, 0); |
| 230 | |
| 231 | } |
| 232 | |
| 233 | static WRITE32_HANDLER( decathlt_prot2_w ) |
| 234 | { |
| 235 | write_prot_data(data,mem_mask, offset, 1); |
| 236 | |
| 237 | |
| 238 | } |
| 239 | |
| 240 | void install_decathlt_protection(running_machine &machine) |
| 241 | { |
| 242 | /* It uploads 2 tables here, then performs what looks like a number of transfers, setting |
| 243 | a source address of some kind (scrambled?) and then making many reads from a single address */ |
| 244 | memset(decathlt_protregs, 0, sizeof(decathlt_protregs)); |
| 245 | decathlt_lastcount = 0; |
| 246 | decathlt_prot_uploadmode = 0; |
| 247 | decathlt_prot_uploadoffset = 0; |
| 248 | decathlt_part = 1; |
| 249 | machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x37FFFF0, 0x37FFFFF, FUNC(decathlt_prot_r), FUNC(decathlt_prot1_w)); |
| 250 | /* It accesses the device at this address too, with different tables, for the game textures, should it just act like a mirror, or a secondary device? */ |
| 251 | machine.device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x27FFFF0, 0x27FFFFF, FUNC(decathlt_prot_r), FUNC(decathlt_prot2_w)); |
| 252 | } |
| 253 | |