|
|
1.1.1.3 ! root 1: #ifndef UAE_CPUMMU030_H ! 2: #define UAE_CPUMMU030_H 1.1 root 3: 4: #include "mmu_common.h" 5: 1.1.1.2 root 6: extern uae_u64 srp_030, crp_030; 7: extern uae_u32 tt0_030, tt1_030, tc_030; 8: extern uae_u16 mmusr_030; 9: 10: #define MAX_MMU030_ACCESS 10 11: extern uae_u32 mm030_stageb_address; 12: extern int mmu030_idx; 13: extern bool mmu030_retry; 14: extern int mmu030_opcode, mmu030_opcode_stageb; 1.1.1.3 ! root 15: extern int mmu030_fake_prefetch; ! 16: extern uaecptr mmu030_fake_prefetch_addr; 1.1.1.2 root 17: extern uae_u16 mmu030_state[3]; 18: extern uae_u32 mmu030_data_buffer; 19: extern uae_u32 mmu030_disp_store[2]; 20: extern uae_u32 mmu030_fmovem_store[2]; 21: 22: #define MMU030_STATEFLAG1_FMOVEM 0x2000 23: #define MMU030_STATEFLAG1_MOVEM1 0x4000 24: #define MMU030_STATEFLAG1_MOVEM2 0x8000 25: #define MMU030_STATEFLAG1_DISP0 0x0001 26: #define MMU030_STATEFLAG1_DISP1 0x0002 27: 28: struct mmu030_access 29: { 30: bool done; 31: uae_u32 val; 32: }; 33: extern struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS]; 34: 35: uae_u32 REGPARAM3 get_disp_ea_020_mmu030 (uae_u32 base, int idx) REGPARAM; 1.1.1.3 ! root 36: void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc); 1.1.1.2 root 37: 1.1.1.3 ! root 38: bool mmu_op30_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); ! 39: bool mmu_op30_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); ! 40: bool mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); ! 41: bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); 1.1 root 42: 43: uae_u32 mmu_op30_helper_get_fc(uae_u16 next); 44: 45: void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write); 46: uae_u32 mmu030_ptest_table_search(uaecptr extra, uae_u32 fc, bool write, int level); 47: uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level); 48: 49: 50: typedef struct { 51: uae_u32 addr_base; 52: uae_u32 addr_mask; 53: uae_u32 fc_base; 54: uae_u32 fc_mask; 55: } TT_info; 56: 57: TT_info mmu030_decode_tt(uae_u32 TT); 1.1.1.3 ! root 58: bool mmu030_decode_tc(uae_u32 TC); ! 59: bool mmu030_decode_rp(uae_u64 RP); 1.1 root 60: 61: int mmu030_logical_is_in_atc(uaecptr addr, uae_u32 fc, bool write); 62: void mmu030_atc_handle_history_bit(int entry_num); 63: 1.1.1.2 root 64: void mmu030_put_long_atc(uaecptr addr, uae_u32 val, int l, uae_u32 fc); 65: void mmu030_put_word_atc(uaecptr addr, uae_u16 val, int l, uae_u32 fc); 66: void mmu030_put_byte_atc(uaecptr addr, uae_u8 val, int l, uae_u32 fc); 67: uae_u32 mmu030_get_long_atc(uaecptr addr, int l, uae_u32 fc); 68: uae_u16 mmu030_get_word_atc(uaecptr addr, int l, uae_u32 fc); 69: uae_u8 mmu030_get_byte_atc(uaecptr addr, int l, uae_u32 fc); 1.1 root 70: 1.1.1.3 ! root 71: void mmu030_put_atc_generic(uaecptr addr, uae_u32 val, int l, uae_u32 fc, int size, int flags); ! 72: uae_u32 mmu030_get_atc_generic(uaecptr addr, int l, uae_u32 fc, int size, int flags, bool checkwrite); ! 73: 1.1 root 74: void mmu030_flush_atc_fc(uae_u32 fc_base, uae_u32 fc_mask); 75: void mmu030_flush_atc_page(uaecptr logical_addr); 76: void mmu030_flush_atc_page_fc(uaecptr logical_addr, uae_u32 fc_base, uae_u32 fc_mask); 77: void mmu030_flush_atc_all(void); 78: void mmu030_reset(int hardreset); 1.1.1.3 ! root 79: void mmu030_set_funcs(void); 1.1.1.2 root 80: uaecptr mmu030_translate(uaecptr addr, bool super, bool data, bool write); 1.1 root 81: 82: int mmu030_match_ttr(uaecptr addr, uae_u32 fc, bool write); 1.1.1.2 root 83: int mmu030_match_ttr_access(uaecptr addr, uae_u32 fc, bool write); 1.1.1.3 ! root 84: int mmu030_match_lrmw_ttr_access(uaecptr addr, uae_u32 fc); 1.1 root 85: int mmu030_do_match_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc, bool write); 1.1.1.2 root 86: int mmu030_do_match_lrmw_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc); 1.1 root 87: 1.1.1.2 root 88: void mmu030_put_long(uaecptr addr, uae_u32 val, uae_u32 fc); 89: void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc); 90: void mmu030_put_byte(uaecptr addr, uae_u8 val, uae_u32 fc); 91: uae_u32 mmu030_get_long(uaecptr addr, uae_u32 fc); 92: uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc); 93: uae_u8 mmu030_get_byte(uaecptr addr, uae_u32 fc); 1.1.1.3 ! root 94: uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc); ! 95: uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc); 1.1.1.2 root 96: 97: uae_u32 uae_mmu030_get_lrmw(uaecptr addr, int size); 98: void uae_mmu030_put_lrmw(uaecptr addr, uae_u32 val, int size); 99: 1.1.1.3 ! root 100: void mmu030_put_generic(uaecptr addr, uae_u32 val, uae_u32 fc, int size, int accesssize, int flags); 1.1.1.2 root 101: uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int accesssize, int flags); 102: 103: extern uae_u16 REGPARAM3 mmu030_get_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; 104: extern uae_u32 REGPARAM3 mmu030_get_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; 1.1.1.3 ! root 105: extern uae_u32 REGPARAM3 mmu030_get_ilong_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; 1.1.1.2 root 106: extern uae_u16 REGPARAM3 mmu030_get_lrmw_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; 107: extern uae_u32 REGPARAM3 mmu030_get_lrmw_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; 108: extern void REGPARAM3 mmu030_put_word_unaligned(uaecptr addr, uae_u16 val, uae_u32 fc, int flags) REGPARAM; 109: extern void REGPARAM3 mmu030_put_long_unaligned(uaecptr addr, uae_u32 val, uae_u32 fc, int flags) REGPARAM; 1.1 root 110: 111: static ALWAYS_INLINE uae_u32 uae_mmu030_get_ilong(uaecptr addr) 112: { 113: uae_u32 fc = (regs.s ? 4 : 0) | 2; 114: 115: if (unlikely(is_unaligned(addr, 4))) 1.1.1.3 ! root 116: return mmu030_get_ilong_unaligned(addr, fc, 0); ! 117: return mmu030_get_ilong(addr, fc); 1.1 root 118: } 119: static ALWAYS_INLINE uae_u16 uae_mmu030_get_iword(uaecptr addr) 120: { 121: uae_u32 fc = (regs.s ? 4 : 0) | 2; 1.1.1.3 ! root 122: return mmu030_get_iword(addr, fc); 1.1 root 123: } 124: static ALWAYS_INLINE uae_u16 uae_mmu030_get_ibyte(uaecptr addr) 125: { 126: uae_u32 fc = (regs.s ? 4 : 0) | 2; 127: 1.1.1.2 root 128: return mmu030_get_byte(addr, fc); 1.1 root 129: } 130: static ALWAYS_INLINE uae_u32 uae_mmu030_get_long(uaecptr addr) 131: { 132: uae_u32 fc = (regs.s ? 4 : 0) | 1; 133: 134: if (unlikely(is_unaligned(addr, 4))) 1.1.1.2 root 135: return mmu030_get_long_unaligned(addr, fc, 0); 136: return mmu030_get_long(addr, fc); 1.1 root 137: } 138: static ALWAYS_INLINE uae_u16 uae_mmu030_get_word(uaecptr addr) 139: { 140: uae_u32 fc = (regs.s ? 4 : 0) | 1; 141: 142: if (unlikely(is_unaligned(addr, 2))) 1.1.1.2 root 143: return mmu030_get_word_unaligned(addr, fc, 0); 144: return mmu030_get_word(addr, fc); 1.1 root 145: } 146: static ALWAYS_INLINE uae_u8 uae_mmu030_get_byte(uaecptr addr) 147: { 148: uae_u32 fc = (regs.s ? 4 : 0) | 1; 149: 1.1.1.2 root 150: return mmu030_get_byte(addr, fc); 1.1 root 151: } 152: static ALWAYS_INLINE void uae_mmu030_put_long(uaecptr addr, uae_u32 val) 153: { 154: uae_u32 fc = (regs.s ? 4 : 0) | 1; 155: 156: if (unlikely(is_unaligned(addr, 4))) 1.1.1.2 root 157: mmu030_put_long_unaligned(addr, val, fc, 0); 1.1 root 158: else 1.1.1.2 root 159: mmu030_put_long(addr, val, fc); 1.1 root 160: } 161: static ALWAYS_INLINE void uae_mmu030_put_word(uaecptr addr, uae_u16 val) 162: { 163: uae_u32 fc = (regs.s ? 4 : 0) | 1; 164: 165: if (unlikely(is_unaligned(addr, 2))) 1.1.1.2 root 166: mmu030_put_word_unaligned(addr, val, fc, 0); 1.1 root 167: else 1.1.1.2 root 168: mmu030_put_word(addr, val, fc); 1.1 root 169: } 170: static ALWAYS_INLINE void uae_mmu030_put_byte(uaecptr addr, uae_u8 val) 171: { 172: uae_u32 fc = (regs.s ? 4 : 0) | 1; 173: 1.1.1.2 root 174: mmu030_put_byte(addr, val, fc); 1.1 root 175: } 176: 177: static ALWAYS_INLINE uae_u32 sfc030_get_long(uaecptr addr) 178: { 1.1.1.2 root 179: uae_u32 fc = regs.sfc; 180: #if MMUDEBUG > 2 181: write_log(_T("sfc030_get_long: FC = %i\n"),fc); 182: #endif 183: if (unlikely(is_unaligned(addr, 4))) 184: return mmu030_get_long_unaligned(addr, fc, 0); 185: return mmu030_get_long(addr, fc); 1.1 root 186: } 187: 188: static ALWAYS_INLINE uae_u16 sfc030_get_word(uaecptr addr) 189: { 1.1.1.2 root 190: uae_u32 fc = regs.sfc; 191: #if MMUDEBUG > 2 192: write_log(_T("sfc030_get_word: FC = %i\n"),fc); 193: #endif 1.1 root 194: if (unlikely(is_unaligned(addr, 2))) 1.1.1.2 root 195: return mmu030_get_word_unaligned(addr, fc, 0); 196: return mmu030_get_word(addr, fc); 1.1 root 197: } 198: 199: static ALWAYS_INLINE uae_u8 sfc030_get_byte(uaecptr addr) 200: { 1.1.1.2 root 201: uae_u32 fc = regs.sfc; 202: #if MMUDEBUG > 2 203: write_log(_T("sfc030_get_byte: FC = %i\n"),fc); 204: #endif 205: return mmu030_get_byte(addr, fc); 1.1 root 206: } 207: 208: static ALWAYS_INLINE void dfc030_put_long(uaecptr addr, uae_u32 val) 209: { 1.1.1.2 root 210: uae_u32 fc = regs.dfc; 211: #if MMUDEBUG > 2 1.1.1.3 ! root 212: write_log(_T("dfc030_put_long: %08X = %08X FC = %i\n"), addr, val, fc); 1.1.1.2 root 213: #endif 1.1 root 214: if (unlikely(is_unaligned(addr, 4))) 1.1.1.2 root 215: mmu030_put_long_unaligned(addr, val, fc, 0); 1.1 root 216: else 1.1.1.2 root 217: mmu030_put_long(addr, val, fc); 1.1 root 218: } 219: 220: static ALWAYS_INLINE void dfc030_put_word(uaecptr addr, uae_u16 val) 221: { 1.1.1.2 root 222: uae_u32 fc = regs.dfc; 223: #if MMUDEBUG > 2 1.1.1.3 ! root 224: write_log(_T("dfc030_put_word: %08X = %04X FC = %i\n"), addr, val, fc); 1.1.1.2 root 225: #endif 226: if (unlikely(is_unaligned(addr, 2))) 227: mmu030_put_word_unaligned(addr, val, fc, 0); 1.1 root 228: else 1.1.1.2 root 229: mmu030_put_word(addr, val, fc); 1.1 root 230: } 231: 232: static ALWAYS_INLINE void dfc030_put_byte(uaecptr addr, uae_u8 val) 233: { 1.1.1.2 root 234: uae_u32 fc = regs.dfc; 235: #if MMUDEBUG > 2 1.1.1.3 ! root 236: write_log(_T("dfc030_put_byte: %08X = %02X FC = %i\n"), addr, val, fc); 1.1.1.2 root 237: #endif 238: mmu030_put_byte(addr, val, fc); 239: } 240: 241: #define ACCESS_CHECK_PUT \ 242: if (!mmu030_ad[mmu030_idx].done) { \ 243: mmu030_ad[mmu030_idx].val = v; \ 244: } else if (mmu030_ad[mmu030_idx].done) { \ 245: mmu030_idx++; \ 246: return; \ 247: } 248: 249: #define ACCESS_CHECK_GET \ 250: if (mmu030_ad[mmu030_idx].done) { \ 251: v = mmu030_ad[mmu030_idx].val; \ 252: mmu030_idx++; \ 253: return v; \ 254: } 255: 256: #define ACCESS_CHECK_GET_PC(pc) \ 257: if (mmu030_ad[mmu030_idx].done) { \ 258: v = mmu030_ad[mmu030_idx].val; \ 259: mmu030_idx++; \ 260: m68k_incpci (pc); \ 261: return v; \ 262: } 263: 264: #define ACCESS_EXIT_PUT \ 265: mmu030_ad[mmu030_idx].done = true; \ 266: mmu030_idx++; \ 267: mmu030_ad[mmu030_idx].done = false; 268: 269: #define ACCESS_EXIT_GET \ 270: mmu030_ad[mmu030_idx].val = v; \ 271: mmu030_ad[mmu030_idx].done = true; \ 272: mmu030_idx++; \ 273: mmu030_ad[mmu030_idx].done = false; 1.1 root 274: 1.1.1.2 root 275: STATIC_INLINE void put_byte_mmu030_state (uaecptr addr, uae_u32 v) 1.1 root 276: { 1.1.1.2 root 277: ACCESS_CHECK_PUT 1.1 root 278: uae_mmu030_put_byte (addr, v); 1.1.1.2 root 279: ACCESS_EXIT_PUT 1.1 root 280: } 1.1.1.2 root 281: STATIC_INLINE void put_lrmw_byte_mmu030_state (uaecptr addr, uae_u32 v) 282: { 283: ACCESS_CHECK_PUT 284: uae_mmu030_put_lrmw (addr, v, sz_byte); 285: ACCESS_EXIT_PUT 286: } 287: STATIC_INLINE void put_word_mmu030_state (uaecptr addr, uae_u32 v) 1.1 root 288: { 1.1.1.2 root 289: ACCESS_CHECK_PUT 1.1 root 290: uae_mmu030_put_word (addr, v); 1.1.1.2 root 291: ACCESS_EXIT_PUT 1.1 root 292: } 1.1.1.2 root 293: STATIC_INLINE void put_lrmw_word_mmu030_state (uaecptr addr, uae_u32 v) 1.1 root 294: { 1.1.1.2 root 295: ACCESS_CHECK_PUT 296: uae_mmu030_put_lrmw (addr, v, sz_word); 297: ACCESS_EXIT_PUT 298: } 299: STATIC_INLINE void put_long_mmu030_state (uaecptr addr, uae_u32 v) 300: { 301: ACCESS_CHECK_PUT 1.1 root 302: uae_mmu030_put_long (addr, v); 1.1.1.2 root 303: ACCESS_EXIT_PUT 304: } 305: STATIC_INLINE void put_lrmw_long_mmu030_state (uaecptr addr, uae_u32 v) 306: { 307: ACCESS_CHECK_PUT 308: uae_mmu030_put_lrmw (addr, v, sz_long); 309: ACCESS_EXIT_PUT 1.1 root 310: } 1.1.1.2 root 311: 312: STATIC_INLINE uae_u32 get_byte_mmu030_state (uaecptr addr) 313: { 314: uae_u32 v; 315: ACCESS_CHECK_GET 316: v = uae_mmu030_get_byte (addr); 317: ACCESS_EXIT_GET 318: return v; 319: } 320: STATIC_INLINE uae_u32 get_lrmw_byte_mmu030_state (uaecptr addr) 321: { 322: uae_u32 v; 323: ACCESS_CHECK_GET 324: v = uae_mmu030_get_lrmw (addr, sz_byte); 325: ACCESS_EXIT_GET 326: return v; 327: } 328: 329: STATIC_INLINE uae_u32 get_word_mmu030_state (uaecptr addr) 330: { 331: uae_u32 v; 332: ACCESS_CHECK_GET 333: v = uae_mmu030_get_word (addr); 334: ACCESS_EXIT_GET 335: return v; 336: } 337: STATIC_INLINE uae_u32 get_lrmw_word_mmu030_state (uaecptr addr) 338: { 339: uae_u32 v; 340: ACCESS_CHECK_GET 341: v = uae_mmu030_get_lrmw (addr, sz_word); 342: ACCESS_EXIT_GET 343: return v; 344: } 345: STATIC_INLINE uae_u32 get_long_mmu030_state (uaecptr addr) 346: { 347: uae_u32 v; 348: ACCESS_CHECK_GET 349: v = uae_mmu030_get_long (addr); 350: ACCESS_EXIT_GET 351: return v; 352: } 353: STATIC_INLINE uae_u32 get_lrmw_long_mmu030_state (uaecptr addr) 354: { 355: uae_u32 v; 356: ACCESS_CHECK_GET 357: v = uae_mmu030_get_lrmw (addr, sz_long); 358: ACCESS_EXIT_GET 359: return v; 360: } 361: 362: STATIC_INLINE uae_u32 get_ibyte_mmu030_state (int o) 363: { 364: uae_u32 v; 1.1.1.3 ! root 365: uae_u32 addr = m68k_getpci () + o; 1.1.1.2 root 366: ACCESS_CHECK_GET 367: v = uae_mmu030_get_iword (addr); 368: ACCESS_EXIT_GET 369: return v; 370: } 371: STATIC_INLINE uae_u32 get_iword_mmu030_state (int o) 372: { 373: uae_u32 v; 1.1.1.3 ! root 374: uae_u32 addr = m68k_getpci () + o; 1.1.1.2 root 375: ACCESS_CHECK_GET 376: v = uae_mmu030_get_iword (addr); 377: ACCESS_EXIT_GET 378: return v; 379: } 380: STATIC_INLINE uae_u32 get_ilong_mmu030_state (int o) 381: { 382: uae_u32 v; 1.1.1.3 ! root 383: uae_u32 addr = m68k_getpci () + o; 1.1.1.2 root 384: ACCESS_CHECK_GET 385: v = uae_mmu030_get_ilong (addr); 386: ACCESS_EXIT_GET 387: return v; 388: } 389: STATIC_INLINE uae_u32 next_iword_mmu030_state (void) 390: { 391: uae_u32 v; 1.1.1.3 ! root 392: uae_u32 addr = m68k_getpci (); 1.1.1.2 root 393: ACCESS_CHECK_GET_PC(2); 394: v = uae_mmu030_get_iword (addr); 395: m68k_incpci (2); 396: ACCESS_EXIT_GET 397: return v; 398: } 399: STATIC_INLINE uae_u32 next_ilong_mmu030_state (void) 400: { 401: uae_u32 v; 1.1.1.3 ! root 402: uae_u32 addr = m68k_getpci (); 1.1.1.2 root 403: ACCESS_CHECK_GET_PC(4); 404: v = uae_mmu030_get_ilong (addr); 405: m68k_incpci (4); 406: ACCESS_EXIT_GET 407: return v; 408: } 409: 1.1 root 410: STATIC_INLINE uae_u32 get_byte_mmu030 (uaecptr addr) 411: { 1.1.1.2 root 412: return uae_mmu030_get_byte (addr); 1.1 root 413: } 414: STATIC_INLINE uae_u32 get_word_mmu030 (uaecptr addr) 415: { 1.1.1.2 root 416: return uae_mmu030_get_word (addr); 1.1 root 417: } 418: STATIC_INLINE uae_u32 get_long_mmu030 (uaecptr addr) 419: { 1.1.1.2 root 420: return uae_mmu030_get_long (addr); 421: } 422: STATIC_INLINE void put_byte_mmu030 (uaecptr addr, uae_u32 v) 423: { 424: uae_mmu030_put_byte (addr, v); 425: } 426: 427: STATIC_INLINE void put_word_mmu030 (uaecptr addr, uae_u32 v) 428: { 429: uae_mmu030_put_word (addr, v); 1.1 root 430: } 1.1.1.2 root 431: STATIC_INLINE void put_long_mmu030 (uaecptr addr, uae_u32 v) 432: { 433: uae_mmu030_put_long (addr, v); 434: } 435: 1.1 root 436: STATIC_INLINE uae_u32 get_ibyte_mmu030 (int o) 437: { 1.1.1.3 ! root 438: uae_u32 pc = m68k_getpci () + o; 1.1 root 439: return uae_mmu030_get_iword (pc); 440: } 441: STATIC_INLINE uae_u32 get_iword_mmu030 (int o) 442: { 1.1.1.3 ! root 443: uae_u32 pc = m68k_getpci () + o; 1.1 root 444: return uae_mmu030_get_iword (pc); 445: } 446: STATIC_INLINE uae_u32 get_ilong_mmu030 (int o) 447: { 1.1.1.3 ! root 448: uae_u32 pc = m68k_getpci () + o; 1.1 root 449: return uae_mmu030_get_ilong (pc); 450: } 451: STATIC_INLINE uae_u32 next_iword_mmu030 (void) 452: { 1.1.1.2 root 453: uae_u32 v; 1.1.1.3 ! root 454: uae_u32 pc = m68k_getpci (); 1.1.1.2 root 455: v = uae_mmu030_get_iword (pc); 1.1 root 456: m68k_incpci (2); 1.1.1.2 root 457: return v; 1.1 root 458: } 459: STATIC_INLINE uae_u32 next_ilong_mmu030 (void) 460: { 1.1.1.2 root 461: uae_u32 v; 1.1.1.3 ! root 462: uae_u32 pc = m68k_getpci (); 1.1.1.2 root 463: v = uae_mmu030_get_ilong (pc); 1.1 root 464: m68k_incpci (4); 1.1.1.2 root 465: return v; 1.1 root 466: } 467: 468: extern void m68k_do_rts_mmu030 (void); 469: extern void m68k_do_rte_mmu030 (uaecptr a7); 470: extern void flush_mmu030 (uaecptr, int); 471: extern void m68k_do_bsr_mmu030 (uaecptr oldpc, uae_s32 offset); 1.1.1.3 ! root 472: ! 473: #endif /* UAE_CPUMMU030_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.