public void handler() {
            /*
             the values vary, but the translation mask is always laid out like this:
	
             0 1 2 3 4 5 6 7 8 9 a b c d e f
             0 A A B B A A B B C C D D C C D D
             1 A A B B A A B B C C D D C C D D
             2 E E F F E E F F G G H H G G H H
             3 E E F F E E F F G G H H G G H H
             4 A A B B A A B B C C D D C C D D
             5 A A B B A A B B C C D D C C D D
             6 E E F F E E F F G G H H G G H H
             7 E E F F E E F F G G H H G G H H
             8 H H G G H H G G F F E E F F E E
             9 H H G G H H G G F F E E F F E E
             a D D C C D D C C B B A A B B A A
             b D D C C D D C C B B A A B B A A
             c H H G G H H G G F F E E F F E E
             d H H G G H H G G F F E E F F E E
             e D D C C D D C C B B A A B B A A
             f D D C C D D C C B B A A B B A A
	
             (e.g. 0xc0 is XORed with H)
             therefore in the following tables we only keep track of A, B, C, D, E, F, G and H.
             */
            char data_xortable[][]
                    = {
                        {0x0a, 0x0a, 0x22, 0x22, 0xaa, 0xaa, 0x82, 0x82}, /* ...............0 */
                        {0xa0, 0xaa, 0x28, 0x22, 0xa0, 0xaa, 0x28, 0x22}, /* ...............1 */};
            char opcode_xortable[][]
                    = {
                        {0x8a, 0x8a, 0x02, 0x02, 0x8a, 0x8a, 0x02, 0x02}, /* .......0...0...0 */
                        {0x80, 0x80, 0x08, 0x08, 0xa8, 0xa8, 0x20, 0x20}, /* .......0...0...1 */
                        {0x8a, 0x8a, 0x02, 0x02, 0x8a, 0x8a, 0x02, 0x02}, /* .......0...1...0 */
                        {0x02, 0x08, 0x2a, 0x20, 0x20, 0x2a, 0x08, 0x02}, /* .......0...1...1 */
                        {0x88, 0x0a, 0x88, 0x0a, 0xaa, 0x28, 0xaa, 0x28}, /* .......1...0...0 */
                        {0x80, 0x80, 0x08, 0x08, 0xa8, 0xa8, 0x20, 0x20}, /* .......1...0...1 */
                        {0x88, 0x0a, 0x88, 0x0a, 0xaa, 0x28, 0xaa, 0x28}, /* .......1...1...0 */
                        {0x02, 0x08, 0x2a, 0x20, 0x20, 0x2a, 0x08, 0x02} /* .......1...1...1 */};
            int A;
            UBytePtr rom = memory_region(REGION_CPU1);
            int diff = memory_region_length(REGION_CPU1) / 2;

            memory_set_opcode_base(0, new UBytePtr(rom, diff));

            for (A = 0x0000; A < 0x8000; A++) {
                int i, j;
                char src;

                src = rom.read(A);

                /* pick the translation table from bit 0 of the address */
                i = A & 1;

                /* pick the offset in the table from bits 1, 3 and 5 of the source data */
                j = ((src >> 1) & 1) + (((src >> 3) & 1) << 1) + (((src >> 5) & 1) << 2);
                /* the bottom half of the translation table is the mirror image of the top */
                if ((src & 0x80) != 0) {
                    j = 7 - j;
                }

                /* decode the ROM data */
                rom.write(A, src ^ data_xortable[i][j]);

                /* now decode the opcodes */
                /* pick the translation table from bits 0, 4, and 8 of the address */
                i = ((A >> 0) & 1) + (((A >> 4) & 1) << 1) + (((A >> 8) & 1) << 2);
                rom.write(A + diff, src ^ opcode_xortable[i][j]);
            }
        }