Mac OS 9 Lives
Classic Mac OS Software => Hacking the System, Mac OS 9.3, and Beyond ! => Topic started by: likanen on June 11, 2017, 10:34:50 PM
-
Hello to this active forum! I've been actively following the hacking of Mac OS 9 to new horizons and beyond. While my question is not directly related to Mac OS 9 but X I hope to get some feedback from active developers as all the old school people I've reached over the emails do no longer possess the required information in their brain (or were too lazy to dig deep).
I'm looking into a way to enable G3 L2 (Sonnet Crescendo in my case) accelerator on TAM (an Alchemy based old world Mac).
First thing that I haven't found is to understand how the accelerator works. My assumptions are that at standard CPU uses some of the L2 cache commands to setup the accelerator G3 CPU into correct state (in case of Sonnet which does not require a boot to enable the G3, the others Vimage, PowerLogix, etc. require a boot to enable the G3) and make the original CPU to do busy loop etc.
Assuming this is right, I have the following questions:
- MPC750 starts execution from certain address, which I assume to be the same as ROM address of Open Firmware, should Old World OF work with G3?
- How to decompile the existing Sonnet extension, I have access to MacNosy but it can not open Ptch resource type used by the extension to load whatever patch to start G3?
- Finally assuming a proper bootstrap code can be figured out, this code should be implemented as a part of Apple's BootX code, right? This can't be done at OF level I assume.
Let me know what you think. In the end my primary goal is to have TAM to be seen as an AirTunes end point to stream Spotify etc. to it.
Thanks and congratulations for everyone for such a great forum!
Harri
-
The accelerator probably fits into a special connector on the motherboard. The main CPU is either physically replaced by the accelerator (if the CPU is on a card and replaced by the accelerator card) or overridden by the accelerator somehow (perhaps by permanently activating the bus request signal). The accelerator's cpu should be compatible enough for Open Firmware to run directly on it. The Sonnet Extension is not loaded until much later in the boot process. It probably sets up the caches for normal operation (assuming that the caches were not activated previously).
Just activating the caches without notifying the operating system would be a disaster. Address Space areas mapped to the PCI bus and other devices should probably have cache disabled. If they use DMA, some parts of main memory should also not be cached. If the accelerator cache is sufficiently different from the normal cache to require a custom driver, there should be some integration with the operating system to ensure that caching can be controlled.
For whether OSX can be run on it, I quote the TAM wikipedia page
Based on a PowerPC 603e processor, the TAM cannot run Mac OS X natively, but with the addition of a G3 or G4 aftermarket upgrade and the use of XPostFacto 4.0 software the TAM could run several versions of OS X, with some limitations.
Attempting to install Mac OS X otherwise can "brick" the TAM, and is ill-advised.
Apparently OSX thinks that it can't run on a TAM when it has a G3 upgrade but actually can. It just needs the boot checks to be overridden.
I was mostly relying on my intuition in this post, so there is no guarantee that any of this is reliable. Any corrections would be welcome. I have a 7300 with a 400 MHz G3 card in it so I am interested in reverse-engineering the extension. Here is my version of the extension. It may or may not be the same as yours.
-
Hi Daniel,
The accelerator used by TAM and 6400 is a product of clever engineering where an existing L2 cache module is replaced with an accelerator. If you don’t run Mac OS with the extension it uses the regular 603e instead. In that way it is different from some of the other accelerator cards. PM 7300 has a spesific expansion slot CPU cards.
Running Mac OS X on TAM works fine although very slowly regardless what Internet says. AFAIR (it has been 10 years ago I tried it the last time) bricking is caused by a few different symptoms and are fixable:
An earlier version of XFP did not turn on the backlight so the screen appeared to be black. This can be fixed within OF but TAM defaults to modem port so you’d need another machine. OF can’t be used on the built in display.
And if you really got it messed up, unplugging all power for 10 mins or so gets it back running.
-
So the replacement G3 is started up while the system is running? That is interesting. Could you attach the extension to your next message? I won't be able to read it but others might be able to. Also, could you run NKLogReader on the machine with the extension installed and send us the log?
Assuming that the extension actually swaps out the processor, it probably uses the RESET supervisor mode trick to take over control. It then probably initializes the G3 and sets the program counter to the return address of the function after messing around with various operating system structures to make everything work. As you said, the original cpu is probably put into an endless loop.
If OSX has no idea how to use the accelerator, it is probably faster to just have the L2 cache.
-
Yes, Sonnet was only L2 G3 accelerator to do it without double booting. There was a lot of other manufacturers as well: http://www.zone6400.com/L2G3_spec_comparison.html
http://lowendmac.com/ppc/g3-l2.shtml
I would assume getting dual booting version to work would be a lot easier but I don't have access to such an accelerator and Sonnets are the most commonly seen in eBay.
My grand idea is to modify BootX (Apple) from XPostFacto (https://github.com/OpenDarwin-CVS/XPostFacto) to do the dual boot to have the accelerator visible in Mac OS X.
AFAIR Running OS X with L2 cache inserted was still awfully slow. I doubt it would be able to run Tiger even though it can be made to work with 603/604:
https://forums.macrumors.com/threads/os-x-tiger-on-a-603-604-cpu.1908276/
Then I could run Airfoil Speakers to have TAM as a remote speakers for Spotify :)
You were able to get the accelerator enabled on Linux:
http://lists.fixstars.com/yellowdog-general/July00/0169.html
Drivers:
http://www.zone6400.com/downloads/Crescendo142_143_144_145.hqx
The latest drivers v3.1 which I used on my decompiling efforts can be found here:
http://forums.system7today.com/viewtopic.php?t=860
Just FYI, the comm slot ii card can be enabled on Mac OS X:
http://baumstark.titaniummatrix.com/BEWARE./C600_Ethernet.html (in German)
About NKLogReader, I don't currently have access to my TAM (it is packed away in the middle of house improvement work), and the CD-ROM drive is flakey so I have only Mac 7.6.3 currently on it.
-
Hmmh... got somehow to look into the Ptch resources (apparently one needs put '>' character before the resource name in MacNosy).
The main resources are (again, I have limited knowledge of how extensions work, so please feel free to correct me if I'm wrong) INIT which is executed by the OS and Ptch which contains the accelerator specific data. DRVR resources seems to implement some sort of default functions, which I assume to be irrelevant. The other resources are texts, icons and picts.
13 resource types, data index = 100
Type INIT att indx length
ID 128 10 0 D4
Type DRVR att indx length
ID 128 50 D8 1CA8 .Accel_604_Sonnet_Crescendo
Type Ptch att indx length
ID 128 10 1D84 2220 Main
ID 129 50 3FA8 3A8
ID 130 50 4354 18E0
ID 131 50 5C38 C8
ID 132 50 5D04 1C
The main INIT resource is:
0: QUAL INIT128 ; b# =1 s#1 =proc1
0: 4E56 0000 'NV..' INIT128 LINK A6,#0
4: 48E7 3C20 'H.< ' MOVEM.L D2-D5/A2,-(A7)
8: 7A00 'z.' MOVEQ #0,D5
A: 41FA 00BC 10000C8 lab_1 LEA data1,A0 ; len= 12
E: 2005 ' .' MOVE.L D5,D0
10: E588 '..' LSL.L #2,D0
12: 2230 0800 '"0..' MOVE.L 0(A0,D0.L),D1
16: 676E 1000086 BEQ.S lab_7
18: 558F 'U.' SUBQ.L #2,A7
1A: 2F01 '/.' PUSH.L D1
1C: A80D '..' _Count1Resources ; (theType:ResType):INTEGER
1E: 381F '8.' POP D4
20: 4243 'BC' CLR D3
22: 605A 100007E BRA.S lab_6
24: 598F 'Y.' lab_2 SUBQ.L #4,A7
26: 41FA 00A0 10000C8 LEA data1,A0 ; len= 12
2A: 2005 ' .' MOVE.L D5,D0
2C: E588 '..' LSL.L #2,D0
2E: 2F30 0800 '/0..' PUSH.L 0(A0,D0.L)
32: 3003 '0.' MOVE D3,D0
34: 5240 'R@' ADDQ #1,D0
36: 3F00 '?.' PUSH D0
38: A80E '..' _Get1IxResource ; (theType:ResType; index:INTEGER):Handle
3A: 245F '$_' POP.L A2
3C: 2252 '"R' MOVEA.L (A2),A1
3E: 0C91 534E 4E54 '..SNNT' CMPI.L #'SNNT',(A1)
44: 662E 1000074 BNE.S lab_5
46: 204A ' J' MOVEA.L A2,A0
48: A04A '.J' _HNoPurge ; (A0/h:Handle)
4A: 204A ' J' MOVEA.L A2,A0
4C: A025 '.%' _GetHandleSize ; (A0/h:Handle):D0\Size
4E: 2400 '$.' MOVE.L D0,D2
50: 2252 '"R' MOVEA.L (A2),A1
52: 2011 ' .' MOVE.L (A1),D0
54: E68A '..' LSR.L #3,D2
56: 6018 1000070 BRA.S lab_4
58: D0A9 0004 '....' lab_3 ADD.L 4(A1),D0
5C: 0A80 1234 5678 '...4Vx' EORI.L #$12345678,D0
62: 22C0 '".' MOVE.L D0,(A1)+
64: D0A9 0004 '....' ADD.L 4(A1),D0
68: 0A80 1234 5678 '...4Vx' EORI.L #$12345678,D0
6E: 22C0 '".' MOVE.L D0,(A1)+
70: 51CA FFE6 1000058 lab_4 DBRA D2,lab_3
74: 204A ' J' lab_5 MOVEA.L A2,A0
76: A02A '.*' _HUnLock ; (A0/h:Handle)
78: 204A ' J' MOVEA.L A2,A0
7A: A029 '.)' _HLock ; (A0/h:Handle)
7C: 5243 'RC' ADDQ #1,D3
7E: B644 '.D' lab_6 CMP.W D4,D3
80: 65A2 1000024 BLO lab_2
82: 5285 'R.' ADDQ.L #1,D5
84: 6084 100000A BRA lab_1
86: 598F 'Y.' lab_7 SUBQ.L #4,A7
88: 2F3C 5074 6368 '/<Ptch' PUSH.L #'Ptch'
8E: 3F3C 0080 '?<..' PUSH #$80
92: A81F '..' _Get1Resource ; (theType:ResType; ID:INTEGER):Handle
94: 245F '$_' POP.L A2
96: 204A ' J' MOVEA.L A2,A0
98: A029 '.)' _HLock ; (A0/h:Handle)
9A: 303C A09F '0<..' MOVE #$A09F,D0 ; Power
9E: A346 '.F' _GetTrapAddress newOS; (D0/trapNum:Word):A0\ProcPtr
A0: 2F08 '/.' PUSH.L A0
A2: 303C A198 '0<..' MOVE #$A198,D0 ; HWPriv
A6: A346 '.F' _GetTrapAddress newOS; (D0/trapNum:Word):A0\ProcPtr
A8: B1DF '..' CMPA.L (A7)+,A0
AA: 6704 10000B0 BEQ.S lab_8
AC: 7001 'p.' MOVEQ #1,D0
AE: A098 '..' _HWPriv
B0: 2012 ' .' lab_8 MOVE.L (A2),D0
B2: A055 '.U' _StripAddress ; (D0/theAddress:HLongInt):D0\HLongInt
B4: 2040 ' @' MOVEA.L D0,A0
B6: 4E90 'N.' JSR (A0)
B8: 204A ' J' MOVEA.L A2,A0
BA: A02A '.*' _HUnLock ; (A0/h:Handle)
BC: 2F0A '/.' PUSH.L A2
BE: A9A3 '..' _ReleaseResource ; (theResource:Handle)
C0: 4CDF 043C 'L..<' MOVEM.L (A7)+,D2-D5/A2
C4: 4E5E 'N^' UNLK A6
C6: 4E75 'Nu' RTS
;-refs - INIT128
C8: 'PtchDRVR....' data1 DC.W $5074,$6368,$4452,$5652,0,0
I would assume it to determine if an accelerator is present, based on the found accelerator load the correct patch into memory and then execute that(?). So to further understand what the code does, all the memory writes (Ptch 128 and 131) should be decompiled as well.
Ptch 129, 130 and 132 are already executable code:
0: QUAL Ptch129 ; b# =1 s#1 =proc1
0: 534E 'SN' Ptch129 SUBQ #1,A6
2: 4E54 050C 'NT..' LINK A4,#$50C
6: E105 '..' ASL.B #8,D5
8: data1 EQU *-1
8: 17E1 B6FD 1000007 MOVE.B -(A1),data1(A3.W*8)
C• F1DD '..' ILL*
0: QUAL Ptch130 ; b# =1 s#1 =proc1
0: 534E 'SN' Ptch130 SUBQ #1,A6
2: 4E54 050C 'NT..' LINK A4,#$50C
6: E105 '..' ASL.B #8,D5
8: data1 EQU *-1
8: 17E1 B6FD 1000007 MOVE.B -(A1),data1(A3.W*8)
C• F1DD '..' ILL*
0: QUAL Ptch132 ; b# =1 s#1 =proc1
param2 VEQU 8
param1 VEQU 16
0: VEND
0: 6004 1000006 Ptch132 BRA.S lab_1
;-refs - Ptch132
2: '....' data1 DC.W 0,0
6: 4E56 FFFC 'NV..' lab_1 LINK A6,#-4
A: 206E 0008 2000008 MOVEA.L param2(A6),A0
E: 20BA FFF2 1000002 MOVE.L data1,(A0)
12: 426E 0010 2000010 CLR param1(A6)
16: 4E5E 'N^' UNLK A6
18: 4E74 0008 'Nt..' RTD #8
-
Ptch 128 and 131 for completeness sake
0: 'SNNT..[T.|Ip.s.d' data1 DC.W $534E,$4E54,$914,$5B54,$C7C,$4970,$773,$8A64
10: '.+.......Y..3...' DC.W $E2B,$A9B0,$DEB,$A9C0,$E559,$A9B3,$33F7,$1E17
20: 'q...G.t..s...<..' DC.W $71C4,$B6A0,$478A,$74A0,$9873,$D592,$123C,$B5AD
30: '.#..7[...s...9..' DC.W $223,$880B,$375B,$B806,$9873,$D592,$1239,$B5AD
40: '.&.....>9..t..]^' DC.W $226,$8913,$19E9,$8D3E,$39F7,$B574,$FC8E,$5D5E
50: '.zc, p.t.D...x).' DC.W $DB7A,$632C,$2070,$374,$C944,$1004,$1078,$29FD
60: '..uCqp...j48o.u.' DC.W $EDE0,$7543,$7170,$2D0,$EE6A,$3438,$6FAA,$751C
70: '..X.}.I......m4.' DC.W $C084,$58B0,$7DE7,$4904,$7F81,$31C,$E46D,$3480
80: 'o.u......Y0,F..&' DC.W $6FAA,$7518,$AEED,$871C,$EF59,$302C,$46D7,$AF26
90: 'x...0...\....yF@' DC.W $78C8,$B3E7,$30DF,$D497,$5CCD,$14D4,$E479,$4640
A0: 'o.u |.3.c.V..p/.' DC.W $6FAA,$7520,$7CC3,$33F4,$63F0,$56EA,$F670,$2FE6
B0: '.I.V..l"........' DC.W $1249,$F556,$FCC1,$6C22,$FD16,$D0EE,$E8B6,$A6
C0: 'z.u..U.uF....-.@' DC.W $7AEF,$75E7,$9755,$8975,$46F1,$2E9A,$C2D,$DE40
D0: '.Z.N..&.....b0U.' DC.W $D25A,$A84E,$91AE,$268C,$8206,$E6F8,$6230,$55F8
E0: '.Z.....L..=..7..' DC.W $B25A,$A994,$19F5,$7F4C,$E9E0,$3D14,$1237,$EE8C
F0: '2l>.<c.....;6..+' DC.W $326C,$3EF4,$3C63,$9CAC,$1E7,$B63B,$36F0,$9F2B
100: '.Z....W...U.....' DC.W $EF5A,$A882,$E499,$5719,$F51C,$55FB,$16D3,$18BE
110: '.........m.xZ..T' DC.W $E2AC,$CADD,$EB2,$1E89,$AA6D,$578,$5A88,$FB54
120: '.?..2h>.<c..[..x' DC.W $113F,$EE8C,$3268,$3EF4,$3C63,$9CAC,$5BE7,$578
130: 'Z..y.:.b..V..4U.' DC.W $5A8C,$BB79,$D13A,$E662,$B509,$568F,$B34,$55E2
140: '..IH.z.....T...}' DC.W $FC8E,$4948,$DD7A,$1AA,$AFCF,$D054,$14DB,$BF7D
150: '#?..rv.5ZD.7;...' DC.W $233F,$BBEC,$7276,$FB35,$5A44,$A437,$3BCF,$FE15
160: '..e:.p..T.k8..x.' DC.W $3B3,$653A,$CD70,$EE8A,$54D0,$6B38,$EB83,$78F8
170: '[email protected].;.fk' DC.W $1F44,$A190,$533,$7640,$141C,$361C,$3BCC,$666B
180: '.s.........r..Q.' DC.W $C673,$E8BB,$EB01,$D5BE,$2BE,$472,$90B5,$512E
190: 'A.2...&.Z:El..W.' DC.W $41D3,$32FD,$11B4,$260F,$5A3A,$456C,$E499,$571A
1A0: '[email protected]..' DC.W $FE03,$1840,$E1C0,$CADD,$F46,$1E89,$AA6D,$51C
1B0: '..>4.......}&...' DC.W $84D7,$3E34,$E10,$18E2,$E284,$B77D,$2690,$9DEC
1C0: '@+}..BIH..W....A' DC.W $402B,$7DE5,$F042,$4948,$E499,$5719,$FE03,$1841
1D0: '.....r..y..7..TM' DC.W $E1EC,$CADD,$F72,$1E89,$7903,$CB37,$C1E0,$544D
1E0: '..W..W......1...' DC.W $EDD9,$5795,$1157,$17C1,$CA09,$1FAD,$31F3,$B61C
1F0: '6.....&%,.E.....' DC.W $36D2,$A1FA,$A6F2,$2625,$2CFA,$458A,$FE10,$18DE
200: '...}%...A=r6.4..' DC.W $E80A,$BB7D,$2512,$91EC,$413D,$7236,$D234,$9CC1
210: '.z.}N..#...i....' DC.W $EC7A,$BF7D,$4EBD,$E523,$E2ED,$E69,$1D89,$18B1
220: '..Hy..)7Xl.^..?z' DC.W $FFC1,$4879,$B5E1,$2937,$586C,$D95E,$E7D5,$3F7A
230: 'T.fh....2d>.<c..' DC.W $54FD,$6668,$AB0B,$EE8C,$3264,$3EF4,$3C63,$A78A
240: '.H..rCo.....\\..' DC.W $9F48,$D0AD,$7243,$6F1F,$AEF3,$CD82,$5C5C,$1F00
250: 'Bq*.........]./P' DC.W $4271,$2A08,$2E11,$D986,$5AC,$CDC4,$5DB6,$2F50
260: '.i.....}g....b..' DC.W $8669,$E994,$18CB,$BF7D,$67B2,$E07,$8D62,$FE
270: 'G..........}....' DC.W $4797,$202,$9880,$D994,$FBB,$B47D,$1EF8,$215
280: '..e:.p..T.k8..x.' DC.W $3B3,$653A,$CD70,$EE8A,$54D0,$6B38,$EB83,$78F8
290: '.D...:x...Go ..=' DC.W $1F44,$A190,$1E3A,$78D8,$B9D9,$476F,$20FE,$893D
2A0: '*......H4.3f..Q.' DC.W $2AC5,$1114,$AEF3,$CE48,$34B4,$3366,$E5DC,$51BA
2B0: '2~....V1...m..v.' DC.W $327E,$D202,$1214,$5631,$1208,$96D,$91AF,$762E
2C0: 'M...-Gx..'.},.Q.' DC.W $4DB2,$D5ED,$2D47,$789F,$D327,$B37D,$2CF0,$51F9
2D0: '...W.QAc.13f....' DC.W $EDCB,$B957,$1D51,$4163,$1031,$3366,$F8A,$FB15
2E0: '..Z..|KP.3:8....' DC.W $E04,$5A13,$C7C,$4B50,$DF33,$3A38,$E803,$1EB0
2F0: '0..9..t.;..Tn3B]' DC.W $30C6,$9E39,$212,$7405,$3B8E,$BE54,$6E33,$425D
300: '..1yq,...s..u4..' DC.W $A38A,$3179,$712C,$F3F8,$EC73,$E7C6,$7534,$B4F8
310: '...9..1yq2.hF7..' DC.W $B7B4,$A839,$A388,$3179,$7132,$CF68,$4637,$8B0
320: '..-.p...[....a.G' DC.W $BAC5,$2DAF,$7011,$C918,$5B95,$1718,$B861,$B947
330: '.X.b+s1.......%.' DC.W $CF58,$462,$2B73,$3180,$C888,4,$1118,$2500
340: 'PTVr.4VZ"#w+.!U.' DC.W $5054,$5672,$E34,$565A,$2223,$772B,$9B21,$55F8
350: '........<......)' DC.W $1213,$F38D,$11F7,$CC8F,$3CE7,$ABDD,$10D8,$1629
360: 'h.7b.U.iG.z.T.G.' DC.W $680B,$3762,$9755,$8869,$47ED,$7A88,$548C,$4716
370: 'C2..3j._...=.d.7' DC.W $4332,$D5E3,$336A,$85F,$11B5,$F73D,$1F64,$837
380: 'D.X..{.v....1L.2' DC.W $44F3,$5800,$EB7B,$1D76,$B99B,$B704,$314C,$D232
390: '...8...}Z-Gt..y.' DC.W $CCA5,$438,$140B,$FD7D,$5A2D,$4774,$1199,$797F
3A0: '..L.......w&L.Q.' DC.W $141F,$4C80,$E3A0,$8B88,$91AF,$7726,$4C9A,$51C2
3B0: 'L.U(.?.R.q.V..6.' DC.W $4C8B,$5528,$33F,$1B52,$E371,$856,$DFFB,$3680
3C0: '..w:..U.L...3j._' DC.W $B086,$773A,$E18F,$55CC,$4CA0,$D5E3,$336A,$85F
3D0: '...=.d.7<.7r.3.^' DC.W $11B5,$F73D,$1F64,$837,$3CF4,$3772,$EC33,$5E
3E0: '..r|..o.&*p... .' DC.W $DDDA,$727C,$C015,$6F80,$262A,$708C,$DBB7,$20C5
3F0: ' c=..r.....x..8.' DC.W $2063,$3DF1,$E372,$9CAE,$2EEF,$EE78,$AFD6,$3880
400: '.A3...C........?' DC.W $9241,$33A8,$8216,$43B4,$E1AB,$A98C,$B2F5,$103F
410: 'l.O9-_N..q...;.b' DC.W $6C0A,$4F39,$2D5F,$4ECA,$E371,$D7A4,$163B,$462
420: '..Vh3t.~..`.t.v.' DC.W $130D,$5668,$3374,$1E7E,$C8AC,$6096,$7415,$761A
430: '..S...M.:.....O9' DC.W $859E,$53A8,$EED4,$4DC2,$3A80,$E8EF,$14D1,$4F39
440: '-_N..qX..`...3U.' DC.W $2D5F,$4EFE,$E371,$589E,$1260,$D40A,$1233,$55F8
450: '...*..w&L..._...' DC.W $1210,$82A,$91AF,$7726,$4C9A,$D5ED,$5FFA,$AA1D
460: '........z.B.....' DC.W $F8A,$FBD5,$C3A4,$16B7,$7A1B,$42E7,$F7EC,$4D8
470: '........V.......' DC.W $4F4,$BEB4,$CCE2,$C999,$56E0,$C6AD,$16E4,$C9B7
480: '....V........<..' DC.W $C3F1,$D2F4,$56E4,$B5F7,$FAA1,$BF9E,$EE3C,$D3AA
490: '....?......."B..' DC.W $BFDD,$B3B2,$3FCC,$AEA7,$B59F,$E108,$2242,$A884
4A0: '.|OD.s>8#.y<....' DC.W $C7C,$4F44,$F173,$3E38,$230D,$793C,$E8F1,$5D4
4B0: '....z.v[.U6)J..V' DC.W $DCA5,$F30C,$7AFD,$765B,$9355,$3629,$4AF2,$2E56
4C0: '.-....U..:...TL.' DC.W $C2D,$DDFC,$F7D8,$55C6,$F73A,$FFBA,$354,$4CBF
4D0: '+(.A.?.h.p....).' DC.W $2B28,$D941,$33F,$1E68,$E370,$F692,$F1E9,$290C
4E0: 'G?O...Y&+>'...V.' DC.W $473F,$4FAA,$E7D5,$5926,$2B3E,$271E,$11D2,$5617
4F0: '..Vq+*V>...P..W.' DC.W $F4A2,$5671,$2B2A,$563E,$11EE,$A850,$E499,$577F
500: 'y2nd....6.....V.' DC.W $7932,$6E64,$A61D,$B61C,$36CA,$BE01,$F91F,$561C
510: '.m.do.t.....A.n6' DC.W $DB6D,$8964,$6FAA,$74F4,$8887,$CBB3,$4111,$6E36
520: 'gt9...v..VS.A...' DC.W $6774,$3983,$B48B,$762E,$CB56,$53D9,$41E0,$D3D1
530: './...W.8..s.....' DC.W $BA2F,$910C,$FA57,$EF38,$11F8,$73E4,$F1B8,$40E
540: '.+.v.....'.G@)..' DC.W $B22B,$FE76,$81D3,$E2A7,$DE27,$CB47,$4029,$816
550: '....P...5.....6.' DC.W $C9FC,$2E0F,$500F,$BFB9,$35EF,$B614,$EFFD,$3694
560: '..z.!fG...E..4*.' DC.W $EEE7,$7A90,$2166,$4712,$CFF8,$45E2,$1234,$2A10
570: './&8.^.7;..%+ W.' DC.W $132F,$2638,$125E,$9F37,$3BC4,$125,$2B20,$5714
580: '...0......W.y2nb' DC.W $11E0,$A730,$11EB,$A994,$E499,$5781,$7932,$6E62
590: '...!.{...+0.`...' DC.W $CEDA,$1F21,$DC7B,$1CCA,$BE2B,$30CA,$60F4,$F6DF
5A0: '.......~........' DC.W $E9D4,$E617,$11E2,$A87E,$11EB,$A994,$11EB,$AA84
5B0: '..Wyy2nf...I.{xF' DC.W $E499,$5779,$7932,$6E66,$CEDA,$1F49,$DC7B,$7846
5C0: '.|...-........ .' DC.W $977C,$EED4,$142D,$D59C,$EBAD,$D5A8,$EDD4,$20D6
5D0: '.5..*%........U.' DC.W $1335,$BCE6,$2A25,$931E,$DAA7,$B16,$EBD2,$55FA
5E0: '3j.|.Ew".DU..@U.' DC.W $336A,$887C,$1245,$7722,$CC44,$55E2,$1340,$55EE
5F0: '..V..<U.aI...a5.' DC.W $ECBC,$56CA,$133C,$5504,$6149,$4D2,$DE61,$351E
600: 'o.v.|.3.....w.W.' DC.W $6FAA,$7604,$7CED,$33F0,$8B8,$A894,$77E1,$57D6
610: '.....5.oE~9...*.' DC.W $B508,$FEFF,$8535,$D16F,$457E,$3908,$EEDA,$2A10
620: '..$0xb.0..%2w...' DC.W $BBF7,$2430,$7862,$F430,$88BA,$2532,$770A,$98E0
630: '.5..E~H...U..0[.' DC.W $8535,$D19E,$457E,$48CE,$EDD4,$55E2,$1330,$5B10
640: '..H.@l6<.\.3[^..' DC.W $ECB0,$48F8,$406C,$363C,$BF5C,$333,$5B5E,$187
650: '..%a3...........' DC.W $F48E,$2561,$331A,$AD89,$A1D2,$D59E,$ECC9,$D5A8
660: '.....@ ..5..*)..' DC.W $EDC7,$D5A8,$EE40,$20D6,$1335,$BCE6,$2A29,$92C8
670: '.\...|......./..' DC.W $F5C,$DFC,$977C,$EED4,$13AB,$D59C,$EC2F,$D5A8
680: '.. ..5..*%...z.<' DC.W $EDD4,$20D6,$1335,$BCE6,$2A25,$85EA,$E67A,$F03C
690: '....u.s*}..d.C..' DC.W $8A6,$A894,$75B5,$732A,$7DA1,$F864,$ED43,$E5D4
6A0: '9ZB...s"...d.?..' DC.W $395A,$4286,$C6C5,$7322,$EEC3,$F864,$ED3F,$E5B6
6B0: '9VBt..7t8VHx4/W.' DC.W $3956,$4274,$C6C1,$3774,$3856,$4878,$342F,$5794
6C0: ').r...1.k@e..+B#' DC.W $2988,$721A,$86BA,$3116,$6B40,$6580,$C22B,$4223
6D0: '4J......s.$.....' DC.W $344A,$F3AE,$C41A,$9C0,$7313,$24F0,$8E5,$CFC8
6E0: '.........]......' DC.W $EDEF,$D09F,$2D2,$E2BC,$FB5D,$CC9,$F3E7,$A8B5
6F0: '...........,..?.' DC.W $F1EB,$DAB0,$FEF1,$C0CE,$19F2,$F12C,$B217,$3F00
700: 'n.........:.J...' DC.W $6E02,$B19F,$10ED,$909,$A10D,$3A0D,$4A15,$A6A0
710: '................' DC.W $F3EF,$F19F,$7D9,$B3A5,$1E9,$EFC9,$FF1,$CBCB
720: '.......I.....!.p' DC.W $B0C5,$B0C9,$EDC7,$D049,$A0F,$DB91,$1A21,$E470
730: '..Vh.LWsi.U...$.' DC.W $1AE,$5668,$EE4C,$5773,$69F4,$5581,$CE08,$2405
740: 'A...zR..0.m.....' DC.W $4105,$A21D,$7A52,$B3E7,$30BF,$6D8A,$1A7F,$ACBD
750: 'B ...O.+5.t.O...' DC.W $4220,$18D0,$AF4F,$BF2B,$35E7,$74D3,$4FD2,$D9FC
760: '.-...>...tL...V.' DC.W $C2D,$E3AE,$DD3E,$FF16,$374,$4CBF,$11DC,$5604
770: '.a..K..I....t.$.' DC.W $1461,$DDDE,$4BEF,$F749,$B21F,$D300,$74BC,$2482
780: '.@..;NVj..6p...S' DC.W $AB40,$1D10,$3B4E,$566A,$E8CE,$3670,$128E,$53
790: '...M"2..E;.x.*.q' DC.W $118D,$F04D,$2232,$ACF8,$453B,$1078,$AB2A,$EA71
7A0: 'u!.....+.2N.5R.8' DC.W $7521,$95C7,$FB1E,$62B,$A232,$4E0D,$3552,$2E38
7B0: '..~.`,.....b....' DC.W $EAD0,$7EF3,$602C,$DE3,$AC99,$F662,$E86,$A984
7C0: 'E.T..tS..46yN4.w' DC.W $45F3,$54FC,$B574,$53F9,$34,$3679,$4E34,$BC77
7D0: '.|.6...,.q.ur..y' DC.W $37C,$C536,$C5ED,$D2C,$D171,$2E75,$72F0,$1E79
7E0: '.1.w.1.|D./4....' DC.W $B31,$B677,$AA31,$D97C,$448E,$2F34,$E7B0,$F6F7
7F0: '......x#..'m....' DC.W $8A9,$9D98,$CDF3,$7823,$EB02,$276D,$8BCC,$1105
800: '...T:.fK.2N.X..:' DC.W $83B3,$EF54,$3AEA,$664B,$A232,$4E0D,$58B2,$93A
810: '.3.q...q../X.e>P' DC.W $F033,$1271,$4AC,$1A71,$1D8B,$2F58,$E565,$3E50
820: 'O.voN"Q-k..K....' DC.W $4F11,$766F,$4E22,$512D,$6B19,$EA4B,$1217,$D500
830: 't$^..3g...._....' DC.W $7424,$5E91,$FA33,$671D,$ECEB,$1A5F,$F8A,$FBF5
840: '..Z..|OP.s>8/../' DC.W $E04,$5A13,$C7C,$4F50,$E973,$3E38,$2FF6,$F2F
850: '.....*$..b.+1...' DC.W $FAB7,$B8DB,$152A,$24F2,$BC62,$BF2B,$31AA,$D319
860: '...>k..r.4......' DC.W $CCA1,$33E,$6BD5,$D072,$9A34,$1616,$EBBA,$D5E3
870: '3f.c..W..\k...k.' DC.W $3366,$863,$1EED,$5784,$BF5C,$6B04,$131C,$6B08
880: 'r5!|..2...X.....' DC.W $7235,$217C,$C3C0,$3284,$EC19,$58AE,$F1A8,$1CE6
890: 't..|..F.R...c.u.' DC.W $74A3,$F27C,$AB94,$46B7,$5297,$BE3,$63F8,$75D5
8A0: 'M....-...{w...Go' DC.W $4DE9,$E3FC,$C2D,$DDB1,$EB7B,$77F8,$B9D9,$476F
8B0: '/cA...1.Y"..iY).' DC.W $2F63,$41A5,$F19B,$31EE,$5922,$83E6,$6959,$29B7
8C0: '.]....xW..(Y...K' DC.W $9C5D,$FE15,$BB3,$7857,$B8C,$2859,$1099,$F54B
8D0: 'A...|...A^t...y.' DC.W $41D7,$E5F7,$7CB7,$928A,$415E,$7404,$F90C,$79C4
8E0: '..Goa.E.|...Y.x.' DC.W $B9D9,$476F,$6118,$45F7,$7CC8,$83C2,$5987,$78F0
8F0: ').n..4E.........' DC.W $29F4,$6E16,$8634,$45E8,$EDD7,$E00A,$B30C,$C8F7
900: '.N....%\..8...w.' DC.W $9C4E,$FE15,$3B3,$255C,$1BB,$3884,$C78D,$770C
910: '4.Q.,..<..g^..$.' DC.W $34AC,$51B8,$2C1A,$843C,$1088,$675E,$EDAD,$240E
920: '..s.........'4V<' DC.W $12C7,$73D6,$EBC5,$B5BA,$1383,$D5E8,$2734,$563C
930: '..Vv..c... .'XVZ' DC.W $F21C,$5676,$DCAE,$630E,$120E,$20F4,$2758,$565A
940: '..fP....3^.0.Fys' DC.W $DCAA,$6650,$ECA1,$E00A,$335E,$1030,$246,$7973
950: ').y.........s-.7' DC.W $29DA,$7981,$11EB,$A984,$11EB,$AA80,$732D,$437
960: '..T)......A..q..' DC.W $B0B2,$5429,$11EB,$A984,$141F,$4108,$DB71,$5C0
970: '@.,....63e.T7.0n' DC.W $4009,$2C12,$82A4,$1136,$3365,$EF54,$37F6,$306E
980: '..B~..zbL...s=..' DC.W $E80A,$427E,$91AF,$7A62,$4C96,$D0AD,$733D,$CFB3
990: '....#;q..'.G@(..' DC.W $8CBA,$D0BC,$233B,$7115,$DE27,$CB47,$4028,$C9D0
9A0: '.o+.>g7:........' DC.W $9E6F,$2B1C,$3E67,$373A,$83A8,$C502,$95DC,$C2FE
9B0: '.Q...P.*r>b#;..I' DC.W $8F51,$C502,$250,$8D2A,$723E,$6223,$3BF7,$B949
9C0: '.HT.....1.6 G..&' DC.W $DF48,$5494,$E5B9,$A890,$3106,$3620,$4703,$B226
9D0: 'wh..1.....8O..<-' DC.W $7768,$B3E7,$31D3,$8490,$1CEC,$384F,$4C7,$3C2D
9E0: 'Q..5.p..1....T2.' DC.W $511F,$A835,$8970,$B3E7,$31CF,$D4A9,$CA54,$32CA
9F0: '.LR.y4V..?.Q.(.W' DC.W $134C,$52F9,$7934,$56CF,$F53F,$E551,$A28,$A757
A00: 'T.d.A..H...g..W.' DC.W $54B4,$64A3,$41B1,$E848,$122E,$767,$13A2,$57D4
A10: '..VX.4T...U..&W.' DC.W $10E0,$5658,$1234,$54A4,$1206,$55F8,$1326,$57AC
A20: '.Pt.`....n49o.v.' DC.W $1150,$74AE,$6086,$1DF,$DE6E,$3439,$6FAA,$760C
A30: '.....Z.V.b4..P..' DC.W $8287,$1AF0,$DD5A,$B56,$EB62,$34CA,$1350,$13F8
A40: 'u4.$.%5..].V.~:.' DC.W $7534,$1724,$FD25,$351C,$9D5D,$1656,$EB7E,$3ACA
A50: '.HG.u.X...G.u."0' DC.W $1348,$47FB,$751C,$58F5,$AB0C,$47FA,$7514,$2230
A60: ';...n2.^..1j^...' DC.W $3B94,$BF18,$6E32,$EF5E,$3B4,$316A,$5E0E,$7FE7
A70: '...w.(G.u04w...Y' DC.W $2FD,$AA77,$AB28,$47F9,$7530,$3477,$AC11,$C059
A80: 'q..7...t@*....s.' DC.W $7111,$E137,$D21A,$A774,$402A,$E80D,$2F0,$73BB
A90: ';J.......$s.;V..' DC.W $3B4A,$BED8,$AFF0,$7F95,$324,$73BA,$3B56,$BEDD
AA0: 'n2. ..1T.}.L..1\' DC.W $6E32,$EF20,$682,$3154,$1D7D,$EF4C,$686,$315C
AB0: '...T..1d...\..1l' DC.W $1D81,$EF54,$687,$3164,$1D80,$EF5C,$3B7,$316C
AC0: '...d..1t...l....' DC.W $1CB0,$EF64,$3B6,$3174,$1C97,$EF6C,$606,$A894
AD0: '{.W..55....V....' DC.W $7BB3,$57C8,$F635,$35AC,$9CFD,$1056,$EC0D,$FFE7
AE0: '......y...o.=..+' DC.W $A5C7,$C0FF,$ABF0,$79E4,$4F5,$6FBD,$3DA5,$C12B
AF0: '..y......1.r....' DC.W $ABF7,$79F0,$4F2,$7FFE,$FD31,$D672,$9C91,$FAFB
B00: '..Ju}4V`.45..4.k' DC.W $118E,$4A75,$7D34,$5660,$F134,$35DE,$F034,$66B
B10: '..x...[...N9./'S' DC.W $E3DA,$7887,$E95,$5B88,$FDC5,$4E39,$C02F,$2753
B20: '.....hK..A.-."W.' DC.W $F03,$F08D,$CF68,$4B03,$1341,$8B2D,$F22,$57FF
B30: '.j....f...W..dJ.' DC.W $CF6A,$13D3,$10A5,$66A8,$F204,$57FE,$CF64,$4A92
B40: '..M..bk2S.......' DC.W $EE0D,$4DC1,$1362,$6B32,$53D6,$A9B2,$FD8D,$A9B0
B50: '#........+...+..' DC.W $2311,$A9CC,$DEB,$A9CA,$E2B,$A9BA,$112B,$A9C8
B60: 'p.g.LX. ....O.U.' DC.W $70B7,$6786,$4C58,$20,$1FBB,$9F01,$4FB2,$55FA
B70: '%.....S.J..A.D..' DC.W $25C3,$406,$9BEE,$53DE,$4A85,$1841,$A444,$DC1A
B80: '.B.... ...*.....' DC.W $1342,$D592,$121E,$20CA,$11FD,$2A08,$1213,$D5A3
B90: ',...|.fK.B.[.+.B' DC.W $2CF5,$13BD,$7C9D,$664B,$CA42,$F05B,$C2B,$EA42
BA0: 'P.0?..B$6J......' DC.W $5005,$303F,$91EE,$4224,$364A,$F3AE,$C3C1,$B6C2
BB0: '\e......:%...$..' DC.W $5C65,$BFDD,$E411,$CDE7,$3A25,$D3F1,$1524,$CFF1
BC0: '.......I..'/..?.' DC.W $F1EC,$CEE9,$9ACB,$D049,$A14,$272F,$FA04,$3FD6
BD0: '........L....j4.' DC.W $B2A3,$C502,$95DC,$D2FE,$4CFC,$2D0,$EE6A,$3410
BE0: 'o.t..[...6;.....' DC.W $6FAA,$74F4,$805B,$DB01,$8536,$3BC1,$CDED,$A4F4
BF0: '..U.,.fm2.y..s.;' DC.W $BD1F,$55B0,$2C09,$666D,$329A,$7981,$C473,$33B
C00: '....8......x..#z' DC.W $D5F1,$DFB9,$3803,$C308,$ACC3,$978,$F205,$237A
C10: '...5v..'.IWfk&u8' DC.W $8988,$FE35,$762E,$227,$EE49,$5766,$6B26,$7538
C20: '.....jF.o.t.....' DC.W $FCF2,$14E2,$E16A,$461E,$6FAA,$74F4,$8287,$DCC
C30: '..CXC......t.tS.' DC.W $FE1A,$4358,$43E0,$E100,$CCB8,$9E74,$BB74,$53F9
C40: '..1S..........s.' DC.W $D2B7,$3153,$86F8,$1218,$CF5,$5E2,$C1C0,$7395
C50: './...6.MBx.{.,.0' DC.W $1D2F,$E5C1,$E736,$CD4D,$4278,$8A7B,$F32C,$1930
C60: '..........R>...6' DC.W $CF5,$5E2,$E9DB,$F2DD,$D990,$523E,$8988,$FE36
C70: '....^".3.]..0...' DC.W $8616,$D1CC,$5E22,$A533,$815D,$B3E7,$30BF,$BECB
C80: 'Q. ...U.*.&d...`' DC.W $51AC,$20FA,$F29F,$55EA,$2AA3,$2664,$BAA4,$E660
C90: '...;#..A..{$.?..' DC.W $CC89,$1A3B,$23B4,$A41,$F0BC,$7B24,$B3F,$D5F7
CA0: '=...O#...]7..:.M' DC.W $3D0B,$D0CC,$4F23,$8F3,$815D,$3716,$163A,$CD4D
CB0: 'Bx.7.....:......' DC.W $4278,$8A37,$DE5,$603,$A23A,$B6AB,$EDB9,$808E
CC0: 'K...........z.}.' DC.W $4B7F,$1200,$E8F1,$5D4,$DC93,$F394,$7AEF,$7DA3
CD0: '.........lL...V.' DC.W $B099,$8E9,$F2AC,$98BA,$36C,$4CBF,$11D4,$5604
CE0: '._.$.k.w...v.IVl' DC.W $165F,$8624,$8E6B,$B677,$8186,$E676,$749,$566C
CF0: '..5.G....f.6.N..' DC.W $CC8,$3506,$4704,$12C2,$DC66,$8936,$F94E,$F3DD
D00: '.a.C<.'.........' DC.W $161,$CF43,$3C8C,$27D8,$F8A,$FBF5,$E04,$803
D10: '..yV.1.....}"x.)' DC.W $EEE8,$7956,$E331,$E994,$1817,$B37D,$2278,$729
D20: '.se8.\D...%.M..e' DC.W $E373,$6538,$175C,$4480,$C9E5,$25AF,$4DF5,$A365
D30: '.b.v.eIn...x..[.' DC.W $C962,$F276,$8265,$496E,$93AA,$1C78,$159C,$5BC0
D40: '..'.+O...L...s..' DC.W $C3C1,$27AF,$2B4F,$D318,$84C,$80D,$E173,$1395
D50: '_....B.).).f...X' DC.W $5FA9,$DA7,$AE42,$C629,$D29,$D766,$DA0F,$D158
D60: '!h.+.se6.\D...%.' DC.W $2168,$62B,$E373,$6536,$175C,$4480,$C9E7,$25AF
D70: 'M..e.b.v.eIn...z' DC.W $4DF3,$A365,$C962,$F276,$8265,$496E,$93AA,$1C7A
D80: '..k...G.U....,^.' DC.W $199C,$6BBE,$BFDD,$47AF,$55B3,$C6DA,$22C,$5EB6
D90: '.t...s&^....H..o' DC.W $D574,$411,$373,$265E,$1CE8,$BDFA,$4813,$A16F
DA0: '.*..#a.A..P?.QD.' DC.W $F72A,$4E7,$2361,$FD41,$CCE0,$503F,$1D51,$44E6
DB0: '...NP.+...6*/..5' DC.W $E7B1,$A4E,$50CD,$2BA0,$BB04,$362A,$2FEC,$9635
DC0: '..B.......1P..^5' DC.W $317,$42F6,$F581,$ECF3,$DD4,$3150,$F7C1,$5E35
DD0: '......\..|L...5.' DC.W $81A,$F3AE,$E04,$5CCB,$C7C,$4C08,$AE7,$35FA
DE0: '.....Awd........' DC.W $FE0,$A7FA,$1E41,$7764,$D3F8,$86AC,$AEDB,$1786
DF0: '........3.......' DC.W $FEE9,$D39C,$EC11,$E28E,$3397,$97AC,$CAEF,$C5BA
E00: '.i....0..;......' DC.W $1169,$D39C,$EC0A,$30B2,$33B,$F4AA,$FEE7,$D39C
E10: '..0..3........0.' DC.W $EBF8,$30B2,$333,$F4AA,$FEE1,$D39C,$EC06,$30B2
E20: '3tB.0.".......X.' DC.W $3374,$4210,$30F6,$22AA,$FE0,$A8BA,$EE19,$58F4
E30: '.mt.C_......[...' DC.W $F26D,$74A0,$435F,$86AC,$AEDB,$1483,$5BA4,$7FAC
E40: '.......f.{{.L..,' DC.W $B607,$BEAD,$11F8,$F766,$1A7B,$7BD6,$4CEC,$A2C
E50: '.43..z.b...{..%S' DC.W $134,$33AE,$CD7A,$C062,$CEE2,$37B,$EC03,$2553
E60: '..D9`.^Y&."=..'W' DC.W $888B,$4439,$60C1,$5E59,$26F1,$223D,$DFEF,$2757
E70: '[email protected].' DC.W $33D7,$E894,$FD90,$9340,$F4D3,$5944,$EE4C,$4300
E80: 'h.P..&*."Y$:;..v' DC.W $68FE,$50D4,$AB26,$2A10,$2259,$243A,$3BCB,$BC76
E90: '[email protected]..' DC.W $B859,$3740,$5AF,$58F4,$9234,$55DA,$8A6F,$8DE2
EA0: '.0}.7."$...}.tU.' DC.W $B730,$7DEC,$37F4,$2224,$209,$F27D,$C074,$55AF
EB0: 'O.0n.2.8..8vC.sD' DC.W $4FF5,$306E,$432,$E38,$8C05,$3876,$43A9,$7344
EC0: '..q<...~nt.fk..)' DC.W $BE15,$713C,$9004,$F87E,$6E74,$F066,$6B8E,$429
ED0: 'B..9d1.fk.Z&.T'8' DC.W $428B,$E239,$6431,$F466,$6BB6,$5A26,$AC54,$2738
EE0: 'n [email protected].' DC.W $6E20,$BD76,$BA59,$3740,$5AF,$58F4,$9234,$55DA
EF0: '.p.../}.7."$...}' DC.W $8A70,$8DE2,$B72F,$7DEC,$37F4,$2224,$209,$F27D
F00: '.tU.O.0n.2.8..8v' DC.W $C074,$55AF,$4FF5,$306E,$432,$E38,$8C05,$3876
F10: 'C.s,..q$...~nt.e' DC.W $43A9,$732C,$BE15,$7124,$9004,$F87E,$6E74,$F065
F20: 'k..*B..9d1.ek.Z'' DC.W $6B8E,$42A,$428B,$E239,$6431,$F465,$6BB6,$5A27
F30: '.['8n"..s.A...*.' DC.W $AC5B,$2738,$6E22,$D14,$730B,$41E4,$14F8,$2A0E
F40: '..%<.S.z.,.r...D' DC.W $8CE6,$253C,$B953,$CA7A,$E2C,$CA72,$C9EF,$F44
F50: '.r><.*h0...0...D' DC.W $1072,$3E3C,$B12A,$6830,$B5A1,$B30,$C8FB,$544
F60: '0....M.Q.6..$..8' DC.W $3082,$1801,$F04D,$1351,$ED36,$E48A,$24AD,$438
F70: '...Q&i2[*43...^.' DC.W $91F9,$F351,$2669,$325B,$2A34,$33C5,$B21A,$5EC4
F80: 'r2).......V.O...' DC.W $7232,$29BF,$FF8,$1EB2,$13F9,$561C,$4F95,$AAF6
F90: ' Ei..tU./....4nN' DC.W $2045,$6905,$C074,$55AE,$2F9C,$EAAD,$DE34,$6E4E
FA0: '*.. ......V.....' DC.W $2ACA,$F620,$DCB0,$B61E,$EE19,$561A,$DA98,$D07
FB0: 'S.O. Ei..tU./...' DC.W $53A4,$4FCB,$2045,$6915,$C074,$55AE,$2F9C,$EAAD
FC0: '.G.V.l..,.`..m..' DC.W $1E47,$E56,$B56C,$B60E,$2CEB,$60F7,$9C6D,$D5FA
FD0: 'S.O. Ei..tU./...' DC.W $5394,$4FCB,$2045,$6915,$C074,$55AE,$2F9C,$EAAD
FE0: '.G.V.l...2U....L' DC.W $1E47,$E56,$B56C,$B602,$EE32,$55EA,$122E,$174C
FF0: '....$..8...Q&i"i' DC.W $93FE,$E48A,$24C1,$438,$91F9,$F351,$2669,$2269
1000: '*m.....}r>).....' DC.W $2A6D,$EE8E,$B1C0,$187D,$723E,$29CD,$1216,$1EB8
1010: '$DV...Vz..a.....' DC.W $2444,$561E,$EEB4,$567A,$DACC,$6110,$122E,$1F12
1020: '%ZVz..a7.6)..6..' DC.W $255A,$567A,$DAC8,$6137,$1236,$29CD,$1236,$1F08
1030: '".Vj.JWl%4Ut..Vj' DC.W $2214,$566A,$E24A,$576C,$2534,$5574,$EE1E,$566A
1040: '..q.....5NV\..p.' DC.W $DAD0,$7104,$1216,$2EFE,$354E,$565C,$EAB6,$70FE
1050: '....5FVL..p.....' DC.W $1218,$2EF6,$3546,$564C,$EABE,$70F6,$11F8,$2EEE
1060: '5>V<..p.....56V,' DC.W $353E,$563C,$EAA6,$70EE,$11F8,$2EE6,$3536,$562C
1070: '..p.....PGa....5' DC.W $EAAE,$70E6,$11D8,$2EDE,$5047,$610B,$CFEC,$F735
1080: '(2.v(1.o.44F.4\.' DC.W $2832,$BE76,$2831,$66F,$F034,$3446,$A634,$5CC6
1090: '6p....'O...C..3.' DC.W $3670,$81BC,$C3EF,$274F,$1AAF,$F043,$E118,$33BF
10A0: 'R6...Sd(.....5..' DC.W $5236,$F3B6,$2E53,$6428,$8DC1,$1E00,$1235,$A303
10B0: '4/P..0....V0..3G' DC.W $342F,$50FC,$EC30,$A304,$1EB6,$5630,$E119,$3347
10C0: '2..RD n...nQ.0..' DC.W $3287,$AE52,$4420,$6E90,$BA1F,$6E51,$F030,$A706
10D0: '..~y......nQ.0..' DC.W $C2B4,$7E79,$7FF3,$88D0,$EDEF,$6E51,$F030,$A706
10E0: '....i..../.4r).x' DC.W $C2B4,$10F9,$69B3,$1ABC,$EA2F,$F534,$7229,$A678
10F0: '...{..6u..yx..?x' DC.W $C417,$7B,$DEAF,$3675,$3B4,$7978,$F507,$3F78
1100: '...W....s~.3k...' DC.W $2D5,$1D57,$888B,$10E,$737E,$C33,$6B8F,$14F3
1110: '.P+.K&....+.K&.[' DC.W $F50,$2BA8,$4B26,$FCA9,$D511,$2BA8,$4B26,$FA5B
1120: 'n..G?I.d+./.....' DC.W $6EAC,$CB47,$3F49,$664,$2BE8,$2F8E,$E9D0,$18
1130: '.,...+..h.......' DC.W $E22C,$6DA,$EF2B,$CE9F,$68F7,$F0C,$AE04,$1D04
1140: 'v.....&8.*.8Y..(' DC.W $7603,$ADEF,$BBD4,$2638,$2A,$F438,$59ED,$C028
1150: '....JT....9.....' DC.W $CACA,$BDDC,$4A54,$E204,$F6FA,$390C,$AFC5,$9C5
1160: 'Sc...*.L..$^....' DC.W $5363,$EB13,$FF2A,$CF4C,$D5C5,$245E,$F7F4,$9F7
1170: 'E....#......A...' DC.W $45F8,$BAB2,$523,$C3E9,$C6EA,$B5F7,$41AF,$FB03
1180: '..-T....A.....6$' DC.W $B7F4,$2D54,$F7F3,$F3E7,$41F3,$B1E3,$B3F4,$3624
1190: '[email protected],.8' DC.W $F7F4,$401C,$EFEA,$138,$F3DB,$138,$532C,$FE38
11A0: '...R..5NB5W8..K8' DC.W $D7A6,$952,$FCF4,$354E,$4235,$5738,$BDB1,$4B38
11B0: '..@...;.....W6..' DC.W $EB18,$401D,$1B0A,$3B19,$EDF4,$BDA,$5736,$BD94
11C0: '.....K........K.' DC.W $11DA,$F0E4,$FF4B,$9ED,$B3,$9A0,$161E,$4BEB
11D0: '.N.8....?....%..' DC.W $164E,$EA38,$C2A6,$C8F9,$3FF8,$B6B8,$C25,$C0F9
11E0: '...6Z........%..' DC.W $C3F1,$DA36,$5AE5,$CF5,$1B3,$4B0,$525,$2F3
11F0: '....Y...........' DC.W $C9F1,$16F4,$59B5,$D9B1,$FA2E,$CBB7,$BDE8,$CAA7
1200: 'V....8..........' DC.W $56AF,$5A8,$E38,$15F2,$E8,$B7F0,$BDF,$3A7
1210: '.......!..9%..J2' DC.W $BDD,$17E4,$C0D9,$21,$150A,$3925,$EFF4,$4A32
1220: '_8.8....$.......' DC.W $5F38,$FD38,$E2F8,$B3F9,$2404,$CE11,$B3B0,$D311
1230: 'D........8......' DC.W $44F4,$DE6,$C4F3,$F4E6,$1238,$CAE9,$15E9,$CDF4
1240: 'Y...........F;E.' DC.W $59B5,$D9B1,$FA2E,$CBB7,$BDAB,$F6F4,$463B,$45F5
1250: '..M..V.N..4)/...' DC.W $6A5,$4D05,$C156,$D94E,$FCCF,$3429,$2FEE,$17E8
1260: '....T7.8....$...' DC.W $F3F4,$2F7,$5437,$1438,$E314,$B8F9,$240A,$CE11
1270: '....8.... .'^..)' DC.W $B3B0,$D30F,$38F4,$DE8,$D120,$C27,$5EE9,$729
1280: '..U.!5........9.' DC.W $E8AB,$55DA,$2135,$5E5,$B1DC,$FE1B,$F00A,$391B
1290: '..<2\5H8....K...' DC.W $F8F4,$3C32,$5C35,$4838,$C6B3,$FF9,$4BF3,$A6D3
12A0: '.4........9...@%' DC.W $134,$DFCF,$9DC,$F9D8,$C30A,$391B,$F8F4,$4025
12B0: '..L%..<8)W..$...' DC.W $5F4,$4C25,$F4,$3C38,$2957,$F4F9,$240A,$CE11
12C0: '...N..28..B8....' DC.W $B613,$AA4E,$FCCF,$3238,$FBE6,$4238,$7DB,$FDED
12D0: '6.....]'..K8.@..' DC.W $36F4,$11D4,$B5F4,$5D27,$F7F2,$4B38,$1240,$5F9
12E0: '$......N..@/).]!' DC.W $2404,$CE11,$B613,$F84E,$FCCF,$402F,$29EE,$5D21
12F0: '...$....B4......' DC.W $F1F3,$F824,$AF3,$9EF8,$4234,$DFCF,$9DC,$F1F5
1300: '.K........K.....' DC.W $FC4B,$9ED,$B3,$98C,$171E,$4BDF,$FD09,$F4F6
1310: '....["98...8....' DC.W $B8E3,$F1EA,$5B22,$3938,$CDB,$638,$ED9E,$B1F7
1320: '........[....V.N' DC.W $F1F3,$BAA7,$121F,$C4AF,$5BA0,$50D,$BC56,$D94E
1330: '..48...8)E..$...' DC.W $FCCF,$3438,$DEE,$F38,$2945,$ACF9,$2404,$CE11
1340: '...N...8..6.$.9.' DC.W $C0B0,$C74E,$AE5,$F538,$18E2,$361B,$24F4,$391B
1350: '..G2....74......' DC.W $EFF4,$4732,$18F3,$DC0A,$3734,$DFC9,$9DC,$F7F5
1360: '........A....:..' DC.W 9,$F4F6,$B7EA,$B89F,$41D4,$DAA9,$C23A,$B6B7
1370: '?...............' DC.W $3FA5,$F3,$AFF4,$F7,$1F3,$BAA7,$121F,$C4AF
1380: '[....V.N..38...8' DC.W $5BA0,$50D,$BC56,$DA4E,$FCCF,$3338,$DEE,$C38
1390: ')E..$......N...8' DC.W $2945,$ABF9,$2404,$CE11,$C0B0,$C44E,$AE5,$9B38
13A0: '..+.%.9...G2....' DC.W $18E2,$2B1B,$25F4,$391B,$EEF4,$4732,$18F3,$DC0A
13B0: '74.......j....F(' DC.W $3734,$DFC9,$9DC,$B1AB,$F86A,$5E2,$B7C4,$4628
13C0: '..8..<..Y..(....' DC.W $E9E4,$3815,$23C,$F21B,$59F3,$CC28,$E9AB,$18
13D0: '..C./........,..' DC.W $E1F4,$43E7,$2FF4,$1DA2,$3E4,$EEF,$22C,$11F6
13E0: '.......I.x)/..;.' DC.W $9DCB,$B2C0,$EC9F,$D049,$E78,$292F,$F304,$3BE4
13F0: '.2$...%-.n.lj.TR' DC.W $1232,$2411,$132E,$252D,$1D6E,$F06C,$6AF1,$5452
1400: '.Z.zq..>D./9..T.' DC.W $F55A,$A67A,$71D1,$1E3E,$44E8,$2F39,$1BC8,$5496
1410: '/H?o....(.......' DC.W $2F48,$3F6F,$14FC,$9FE8,$2899,$AA86,$F790,$A9AE
1420: '-...q...D...L.RR' DC.W $2D0E,$A9B2,$71EB,$1EB4,$44EA,$B40A,$4C0F,$5252
1430: '....../.N4V4..V:' DC.W $E11B,$C602,$FFC0,$2FFC,$4E34,$5634,$93B4,$563A
1440: 'R4V4..V...U..JWf' DC.W $5234,$5634,$8D9D,$56D6,$E9E2,$55F6,$EE4A,$5766
1450: 'j..0...0,..,./p;' DC.W $6AE0,$130,$BF06,$230,$2C08,$E02C,$52F,$703B
1460: '=m.w.0.B.....a6.' DC.W $3D6D,$C077,$9030,$1042,$D09,$4D2,$DE61,$3616
1470: 'o.t.|.3.....u.W.' DC.W $6FAA,$74FC,$7CED,$33F0,$8B7,$A98C,$75E2,$5788
1480: '.....E..q.D<.o..' DC.W $B31A,$A806,$E045,$9706,$71F5,$443C,$B86F,$1DC
1490: 'c....y....j.}...' DC.W $63F1,$7E4,$E579,$A3A8,$D6DB,$6A8B,$7D8C,$CCD0
14A0: 'zo..r;3.w.F..u6.' DC.W $7A6F,$FAD1,$723B,$3318,$77C5,$467F,$8D75,$367F
14B0: 'r.I...iy..?'....' DC.W $7282,$4981,$8D80,$6979,$FBFF,$3F27,$AEFC,$7F5
14C0: '............r2..' DC.W $EF,$860F,$17EC,$BC01,$8AC3,$C9B4,$7232,$B6BC
14D0: '[email protected]...' DC.W $8DC5,$C9B7,$2D35,$4039,$FB6A,$7338,$4CD5,$9C4
14E0: '.....E..r.D<.1..' DC.W $BB1A,$A6E2,$E045,$9706,$72F5,$443C,$C631,$AD9C
14F0: '#,...`4L....&...' DC.W $232C,$BCE6,$C660,$344C,$EDDD,$EC8F,$2618,$DB9
1500: '&...9....3J....$' DC.W $26CC,$C4F8,$39F2,$A9F8,$B033,$4AF6,$DCF3,$C724
1510: '.......C7....0..' DC.W $E2F3,$1EDD,$8EB4,$D143,$37B4,$9FC,$FA30,$C516
1520: '...."B2*R4Vt....' DC.W $EDE2,$DEBE,$2242,$322A,$5234,$5674,$B10A,$8714
1530: '..U."U.,..2.(.bJ' DC.W $9AA7,$550A,$2255,$22C,$F019,$321C,$28CB,$624A
1540: '.n....~7..tw....' DC.W $C96E,$EA90,$80B2,$7E37,$E5B3,$7477,$86B2,$18B8
1550: '.i..-R.u.f.p..2*' DC.W $B69,$D1F7,$2D52,$A675,$FB66,$C870,$F9BF,$322A
1560: 'R4Vt1..._.....fr' DC.W $5234,$5674,$31F0,$A9A2,$5F05,$A9BC,$F91F,$6672
1570: '.....'.........8' DC.W $EDE8,$95E8,$1227,$F5AC,$EDE5,$9ACA,$EDF7,$F938
1580: '...7a.,..(/..js8' DC.W $12D3,$AF37,$61B6,$2CED,$BD28,$2F80,$FB6A,$7338
1590: 'L.....#.....F/4w' DC.W $4CD5,$C80,$FBA8,$2304,$AF96,$14F9,$462F,$3477
15A0: '.....h'8[.R...{.' DC.W $86B2,$18B8,$B68,$2738,$5B19,$52F9,$1586,$7BF8
15B0: '..>|[email protected]&.' DC.W $C5B8,$3E7C,$815A,$A99F,$80EB,$5640,$E77A,$2614
15C0: '"U.,..2.(.bJ.n..' DC.W $2255,$22C,$F019,$321C,$28CB,$624A,$C96E,$EA90
15D0: '..~7..tw.....j4.' DC.W $80B2,$7E37,$E5B3,$7477,$86B2,$18B8,$B6A,$34EC
15E0: '"@2*R4Vt1..._...' DC.W $2240,$322A,$5234,$5674,$31F0,$A9A2,$5F05,$A9BC
15F0: '..fr.....'......' DC.W $F91F,$6672,$EDE8,$95E8,$1227,$F5AC,$EDE5,$9ACA
1600: '..<4Zxz.rSfzD...' DC.W $EDF8,$3C34,$5A78,$7A98,$7253,$667A,$44DF,$DF0A
1610: '-R......-S......' DC.W $2D52,$D16,$AED3,$DF0A,$2D53,$C4D6,$AECC,$B401
1620: 'Za.io.Z.h.D{..2'' DC.W $5A61,$FF69,$6FB2,$5ADE,$681F,$447B,$EDC0,$3227
1630: '...D......$....:' DC.W $12ED,$FF44,$11D0,$2E1A,$ECB4,$240A,$D2C2,$2E3A
1640: '.p.riR.+...u.f.p' DC.W $8070,$1372,$6952,$E02B,$838D,$A675,$FB66,$C870
1650: '..2&.fk..Ll4/YV.' DC.W $6FF,$3226,$B066,$6B10,$124C,$6C34,$2F59,$5698
1660: '.rfL.T;...'.....' DC.W $B072,$664C,$1254,$3B0E,$EDD6,$2716,$EDE9,$DD0B
1670: '/.PG....R+....kU' DC.W $2F95,$5047,$E8D8,$A9A0,$522B,$A9B4,$EC07,$6B55
1680: '[....n7f]...E...' DC.W $5B95,$E6F7,$C06E,$3766,$5D06,$A9B8,$4518,$A9B0
1690: '2.kR..<4Zhz.rS.K' DC.W $3206,$6B52,$1D85,$3C34,$5A68,$7A88,$7253,$F4B
16A0: '..........j.@...' DC.W $11F6,$16D8,$A2A3,$D8AE,$E2DB,$6AC8,$4015,$1E11
16B0: 'q.....p....5.H.7' DC.W $71D6,$89E8,$EDE3,$70CD,$10C5,$535,$EB48,$F37
16C0: '.B...>.o.+.G...8' DC.W $BB42,$1D18,$F93E,$156F,$902B,$A047,$17AD,$1C38
16D0: '.6.w.D.x...sb4fo' DC.W $E636,$E677,$1244,$D678,$C5B8,$E73,$6234,$666F
16E0: '..Z62..F.......3' DC.W $1AB4,$5A36,$32D9,$CD46,$80EB,$A9A2,$E4C1,$1433
16F0: '.;.0.4U..O..E.V.' DC.W $FE3B,$BC30,$E34,$55B6,$9C4F,$B9,$4502,$5689
1700: 'kCydU1Ji..JJC..L' DC.W $6B43,$7964,$5531,$4A69,$12BE,$4A4A,$43B3,$CD4C
1710: '=.....`..Zr..#N.' DC.W $3DB7,$FEEA,$4BC,$60E8,$105A,$72FC,$FB23,$4EDE
1720: '...._...........' DC.W $E4E8,$CEDD,$5F12,$A20D,$F8A,$FB15,$E04,$803
1730: '.}ix.e....S_..2.' DC.W $C7D,$6978,$E965,$15D6,$FDA4,$535F,$615,$32C9
1740: ';.D.<.*..R...a$o' DC.W $3BFF,$44CE,$3CF7,$2A06,$D752,$97A6,$AB61,$246F
1750: '#L.8.....D....YP' DC.W $234C,$8938,$E0B3,$16A0,$1244,$1091,$B1F0,$5950
1760: '[email protected].....&G.*k' DC.W $71D8,$4057,$B26A,$D61A,$B490,$DA26,$47BD,$2A6B
1770: '.3Vd..=`(..j...x' DC.W $C133,$5664,$888,$3D60,$28E8,$CC6A,$B18F,$D678
1780: '.c.x...x]......<' DC.W $1263,$D678,$12B7,$C578,$5D12,$E684,$F8B,$1B3C
1790: '[email protected]$o' DC.W $DE3,$1604,$B3BE,$F036,$4052,$97A6,$AB61,$246F
17A0: 'j4W.vT.<;..x....' DC.W $6A34,$57F5,$7654,$13C,$3B9B,$DD78,$C38F,$14D0
17B0: '.>.(./.(.....6..' DC.W $123E,$D228,$122F,$D228,$1217,$D3F7,$1236,$1091
17C0: '..o..........0f{' DC.W $B1F0,$6F7F,$1215,$F802,$D1D6,$807,$B230,$667B
17D0: 'C.y..|f}..y..|f}' DC.W $43FC,$7983,$A7C,$667D,$F58B,$7983,$A7C,$667D
17E0: '..y..|f}..y.`...' DC.W $F58B,$7983,$A7C,$667D,$F58B,$7983,$60A4,$C8D2
17F0: 'q.q.... .*..y...' DC.W $71E4,$71FF,$8CA7,$CC20,$E2A,$EDF3,$79AD,$A3B2
1800: '......$e..Y...X.' DC.W $C38F,$12AF,$14D3,$2465,$CA87,$59C8,$CDF5,$5819
1810: '.n...!..#...,...' DC.W $9C6E,$E7D6,$521,$C81E,$23F2,$403,$2C02,$101F
1820: '..g.......2.<...' DC.W $D3F2,$671D,$E0B2,$2E80,$1BB9,$3210,$3CF7,$7FD8
1830: '.4.KP.Vs..Vl..V\' DC.W $9934,$7F4B,$509B,$5673,$DF4,$566C,$DF4,$565C
-
continued...
1840: '.+U..M..+3U..D.F' DC.W $102B,$55F2,$D44D,$F5A4,$2B33,$55CA,$1044,$B746
1850: '9.4....t"7..."..' DC.W $39CD,$34A4,$C3C2,$F674,$2237,$1809,$EA22,$807
1860: ';....n..."..;...' DC.W $3BEB,$A982,$D06E,$180F,$EA22,$807,$3BEB,$A982
1870: '.n..."..;....n..' DC.W $D06E,$180F,$EA22,$807,$3BEB,$A982,$D06E,$180F
1880: '."..;...`...q.q.' DC.W $EA22,$807,$3BEB,$A982,$60A4,$C8D6,$71E4,$71FF
1890: '... .*..y.......' DC.W $8CA7,$CC20,$E2A,$EDF3,$79AD,$A3B2,$C3B1,$12AF
18A0: '..$e..Y...X..p..' DC.W $14E9,$2465,$CA87,$59C8,$CDF5,$5819,$9C70,$E7D6
18B0: '....#...,.....g.' DC.W $51F,$C81E,$23F2,$403,$2C02,$101F,$D3F2,$671D
18C0: '......2.<....4.K' DC.W $E0B2,$2E80,$1BB9,$3210,$3CF7,$7FD8,$9934,$7F4B
18D0: 'P.Vs..Vl..V\.+U.' DC.W $509B,$5673,$DF4,$566C,$DF4,$565C,$102B,$55F2
18E0: '.M..+3U..D..9.*|' DC.W $D44D,$F5A4,$2B33,$55CA,$1044,$BA1E,$39CD,$2A7C
18F0: '...t"7^Q.1N.C..@' DC.W $C3C2,$F674,$2237,$5E51,$E231,$4E0F,$43FC,$A940
1900: '.n..,B....N.C..@' DC.W $D06E,$1811,$2C42,$FE0,$C3C3,$4E0F,$43FC,$A940
1910: '.n..,B....N.C..@' DC.W $D06E,$1811,$2C42,$FE0,$C3C3,$4E0F,$43FC,$A940
1920: '.n..,B....N.C..@' DC.W $D06E,$1811,$2C42,$FE0,$C3C3,$4E0F,$43FC,$A940
1930: '`...q.q.... .*..' DC.W $60A4,$C8D8,$71E4,$71FF,$8CA7,$CC20,$E2A,$EDF3
1940: 'y.........$e..Y.' DC.W $79AD,$A3B2,$C3AD,$12AF,$14F5,$2465,$CA87,$59C8
1950: '..X..J......#...' DC.W $CDF5,$5819,$964A,$E7D6,$6FD,$C81E,$23F2,$403
1960: ',.....g.......2.' DC.W $2C02,$101F,$D3F2,$671D,$E0B2,$2E80,$1BB9,$3210
1970: '<....4.KP.Vs..Vl' DC.W $3CF7,$7FD8,$9934,$7F4B,$509B,$5673,$DF4,$566C
1980: '..V\.+U..M..+3U.' DC.W $DF4,$565C,$102B,$55F2,$D44D,$F5A4,$2B33,$55CA
1990: '.D.R9.4....y.%&u' DC.W $1044,$B752,$39CD,$34A6,$C3C3,$679,$1A25,$2675
19A0: ';....n..."..;...' DC.W $3BEB,$A982,$D06E,$180F,$EA22,$807,$3BEB,$A982
19B0: '.n..."..;....n..' DC.W $D06E,$180F,$EA22,$807,$3BEB,$A982,$D06E,$180F
19C0: '."..;...`...q.q.' DC.W $EA22,$807,$3BEB,$A982,$60A4,$C8D6,$71E4,$71FF
19D0: '... .*..y.......' DC.W $8CA7,$CC20,$E2A,$EDF3,$79AD,$A3B2,$C39D,$12AF
19E0: '.8'...X......7..' DC.W $D138,$27D5,$CDF5,$5819,$9C18,$E7D6,$537,$C81E
19F0: '\L...}I@.%7F..1F' DC.W $5C4C,$803,$C7D,$4940,$D125,$3746,$882,$3146
1A00: 'H....'.....O|fv]' DC.W $48ED,$1210,$227,$E91F,$E3D7,$84F,$7C66,$765D
1A10: '.tYY.T.Q.#.G..'h' DC.W $CB74,$5959,$CB54,$C751,$1223,$D947,$CCA,$2768
1A20: '4.W.Z...e(.G.r..' DC.W $3406,$57B6,$5A97,$18E1,$6528,$CB47,$1572,$C099
1A30: '<....7....p@{O..' DC.W $3C84,$DDFB,$E737,$F58A,$EE00,$7040,$7B4F,$1404
1A40: '....U....\U.).6.' DC.W $D0A4,$D2E3,$55C4,$C9D,$AE5C,$55B0,$29B8,$361E
1A50: '..Y...I...0\..+8' DC.W $11FC,$59FA,$F1E0,$49F0,$7F8E,$305C,$ECD0,$2B38
1A60: '.8.7..'o|ft]....' DC.W $338,$B237,$D3CB,$276F,$7C66,$745D,$CBD3,$ED18
1A70: '....,. .....2 ..' DC.W $D5C7,$C5EC,$2CDB,$2013,$C41B,$C0AA,$3220,$86DE
1A80: '....C.....Aw.u.Q' DC.W $1D16,$99D5,$4396,$CFD6,$DC88,$4177,$375,$D051
1A90: '.".G..G3s.U...I.' DC.W $1222,$D947,$CE6,$4733,$731B,$55E5,$9D13,$4906
1AA0: '.3.J........C..:' DC.W $E333,$F84A,$13EE,$9EDB,$B9D4,$8CD5,$43AA,$BE3A
1AB0: 'L.1:..'n|ft]....' DC.W $4C01,$313A,$D3CB,$276E,$7C66,$745D,$CAE3,$ED18
1AC0: '.i.#x.v].../.3zB' DC.W $C669,$FD23,$78FC,$765D,$CB16,$892F,$D633,$7A42
1AD0: '..'p4.T.W.4.CX..' DC.W $FE1A,$2770,$3406,$540C,$5711,$340C,$4358,$A510
1AE0: '}.....,.!....8%.' DC.W $7DF8,$CBCE,$EBE9,$2CCC,$21BF,$E5B7,$EE38,$25D4
1AF0: '.........L......' DC.W $1DA,$14D0,$FAC1,$B1B2,$F04C,$E0A2,$4E2,$AFEF
1B00: '.../..7.....0F..' DC.W $BBA4,$FA2F,$DCC,$370A,$F502,$C6E4,$3046,$E8B2
1B10: '..........F...K.' DC.W $9A0,$CFAF,$C3E3,$F5F1,$FFD3,$4612,$EFFD,$4BC7
1B20: '.0|.P....._.8...' DC.W $EB30,$7C0C,$50D5,$A984,$E80A,$5F84,$388D,$A088
1B30: 'q.."D$..#e...4S.' DC.W $71EB,$1E22,$4424,$B5A9,$2365,$B6E3,$C134,$530E
1B40: '..........A..EW.' DC.W $1EBD,$DBC0,$AFA,$80FC,$18F2,$41BE,$E645,$579E
1B50: '.._*.LV*.4S.....' DC.W $1FB4,$5F2A,$F04C,$562A,$C134,$530C,$1EBD,$DBC0
1B60: '.......j..v8..D@' DC.W $AF8,$8106,$1A99,$EF6A,$E91C,$7638,$11F2,$4440
1B70: '.K$X......g...".' DC.W $B4B,$2458,$9A19,$A8AC,$CCB3,$678C,$AE08,$2200
1B80: '..cx.......L.LV&' DC.W $8F2,$6378,$1AF5,$F4B0,$1AC9,$EF4C,$4C,$5626
1B90: '.<.0.3.<..W2..O.' DC.W $1F3C,$A030,$1233,$AA3C,$E719,$5732,$E6AE,$4FF6
1BA0: '..../'W*...."...' DC.W $12EC,$A2F0,$2F27,$572A,$AF98,$17E5,$22EC,$10DF
1BB0: '..MDF.dN..T.$...' DC.W $EFE2,$4D44,$4602,$644E,$8310,$540B,$24D3,$8F13
1BC0: '..S...]x..4.....' DC.W $BFAC,$530C,$1EBD,$5D78,$AF9,$3480,$11F0,$84E8
1BD0: '.Ic...O/(...q.}p' DC.W $F49,$6301,$19B4,$4F2F,$289A,$9FB6,$71DA,$7D70
1BE0: 'EKMG.3.@S^Zi.|J.' DC.W $454B,$4D47,$1B33,$F640,$535E,$5A69,$C7C,$4A9A
1BF0: '*M...YWF5l.`..Q.' DC.W $2A4D,$8A1C,$D359,$5746,$356C,$A960,$F0D0,$51DA
1C00: '..Pd+HU...&t;o.~' DC.W $E9A9,$5064,$2B48,$55FC,$D8B4,$2674,$3B6F,$E67E
1C10: '..VR..VR=......$' DC.W $1208,$5652,$E898,$5652,$3D18,$138C,$BD85,$D824
1C20: '.......... .....' DC.W $138F,$D598,$120B,$D59C,$ECDC,$20D6,$1314,$D5A3
1C30: '...EiHRd=8...)..' DC.W $BAD5,$1045,$6948,$5264,$3D38,$1D92,$E329,$D598
1C40: '.'.... .........' DC.W $1227,$D59C,$ECF8,$20D6,$1312,$D5A3,$BAD6,$F4D1
1C50: 'D{...o.G.r..<...' DC.W $447B,$B9A7,$F6F,$CB47,$1572,$BC99,$3C84,$F9E9
1C60: '.dVX.....q.I.e.P' DC.W $C364,$5658,$1214,$180E,$EC71,$D049,$E65,$C650
1C70: '.....!Y7..:(.1.J' DC.W $98FF,$1D18,$CA21,$5937,$AC2E,$3A28,$1231,$F84A
1C80: '.S.x.4.8r....}..' DC.W $ED53,$D578,$1334,$1238,$728C,$84AC,$D17D,$F7BD
1C90: '........KP.!....' DC.W $121B,$D5E7,$F1CC,$D5F3,$4B50,$D921,$1808,$F3D0
1CA0: '....{.v.._6..;V>' DC.W $C9AD,$E102,$7B0A,$761C,$8B5F,$3600,$113B,$563E
1CB0: 'A.dF.6d.......Vm' DC.W $4182,$6446,$A236,$648B,$1AE5,$95B6,$1AB4,$566D
1CC0: '0.w4.2U...4.....' DC.W $30F4,$7734,$A232,$55C4,$120E,$34DC,$121E,$13F0
1CD0: '. $...5...$.#tV:' DC.W $1220,$24D1,$11F6,$35C3,$1215,$24DE,$2374,$563A
1CE0: '*..F..W`..Vn. o.' DC.W $2A99,$A946,$F0AB,$5760,$EBF2,$566E,$C20,$6F04
1CF0: '....b0.4.2U...,.' DC.W $11B0,$1D00,$6230,$7F34,$A232,$55C4,$120E,$2CDC
1D00: '..vJ=*Yb+Zy...W.' DC.W $121E,$764A,$3D2A,$5962,$2B5A,$79C4,$11DF,$57AC
1D10: '..V$...2q.'V...*' DC.W $11D4,$5624,$11E0,$A932,$71B4,$2756,$AFF,$42A
1D20: '.Z4....RD)....K.' DC.W $905A,$3400,$19F6,$FC52,$4429,$FEF6,$FDEA,$4BFE
1D30: '..Y/.}6...Vl.dVX' DC.W $F8B,$592F,$F7D,$3615,$CF5,$566C,$C364,$5658
1D40: '.....q.I.e......' DC.W $1214,$180E,$EC71,$D049,$E65,$EE91,$D0AE,$1516
1D50: '.lU.".6$..VdPMd<' DC.W $146C,$55BA,$2212,$3624,$EFF4,$5664,$504D,$643C
1D60: '..8...G.........' DC.W $81FB,$38FC,$ED0C,$47D6,$EDF3,$90D6,$12F4,$94FD
1D70: '.....El...)...4(' DC.W $1FFA,$180F,$8F45,$6C11,$19DC,$290F,$1316,$3428
1D80: '.(.. ...Q9d6[.S.' DC.W $1228,$9411,$2001,$C617,$5139,$6436,$5BD1,$530A
1D90: '0N.....4..WP..7n' DC.W $304E,$D61E,$1D18,$AA34,$F4AB,$5750,$88FD,$376E
1DA0: 'B......G.r..<...' DC.W $4218,$B9A7,$10BF,$CB47,$1572,$BC99,$3C84,$C210
1DB0: '.;......).....Vg' DC.W $DB3B,$D69B,$DBB9,$CCBE,$29AE,$15B6,$E0F4,$5667
1DC0: 'l8r*.0...r.../v2' DC.W $6C38,$722A,$FC30,$D2A6,$CB72,$B5DD,$132F,$7632
1DD0: '6.V.=,VPx.6pm8..' DC.W $360F,$561C,$3D2C,$5650,$7887,$3670,$6D38,$1782
1DE0: '.........%....0.' DC.W $ABDF,$D386,$119D,$E282,$B225,$A800,$F9D9,$3096
1DF0: '..,.Q.V...V.0.V.' DC.W $8A1B,$2CFA,$51A6,$561A,$EF83,$5604,$3085,$569A
1E00: '.bV...v}.jL...6.' DC.W $F762,$5612,$E8BA,$767D,$126A,$4CFB,$11B0,$36C8
1E10: '....S.V...U...W.' DC.W $11E5,$1D00,$53CD,$56D6,$F982,$55DC,$8C4,$570C
1E20: '.<T..4U.%4V2..Vj' DC.W $F03C,$54DD,$1234,$55F9,$2534,$5632,$1718,$566A
1E30: '.t.?3[t...#.^..`' DC.W $1174,$F63F,$335B,$74A1,$AB2E,$23D0,$5EE5,$1A60
1E40: '.b]V..C..<=..l.^' DC.W $F62,$5D56,$EEC1,$430D,$E33C,$3DF3,$1E6C,$CA5E
1E50: 'j..:Y..(.D....0.' DC.W $6AD9,$AA3A,$590C,$2E28,$9144,$FC6,$DCC4,$30D0
1E60: '.~Vl..r.8"T...).' DC.W $1F7E,$566C,$6E1,$721B,$3822,$54A9,$E91F,$2908
1E70: '..dg6b....+.=95y' DC.W $EC9C,$6467,$3662,$F3ED,$EDD1,$2B05,$3D39,$3579
1E80: '.u$j.,Wdq.Ay."..' DC.W $E75,$246A,$E12C,$5764,$71EC,$4179,$D722,$4C7
1E90: '......p'..P..K..' DC.W $88D,$3C8,$CCA,$7027,$FCC,$5008,$144B,$F819
1EA0: '&......S#.%w..P.' DC.W $261B,$CDCD,$ADE5,$CA53,$23A4,$2577,$A9A,$5008
1EB0: '.K..&.....%..:..' DC.W $144B,$F819,$261B,$CDCD,$7E6,$258B,$A03A,$F50A
1EC0: '..5...#...B.m...' DC.W $1216,$35B6,$1212,$23F1,$FCAC,$42B7,$6DC5,$1809
1ED0: '......Z..r..\D..' DC.W $DD3,$C998,$B384,$5A87,$FE72,$1989,$5C44,$C998
1EE0: '..)@...D.,.b.4M.' DC.W $DD4,$2940,$C3CA,$F644,$122C,$1062,$1234,$4DC3
1EF0: 'J.Vp.Y.E,.u.K...' DC.W $4A9B,$5670,$C959,$F445,$2C0A,$75C3,$4BC1,$C708
1F00: 'e.......Q...=.V.' DC.W $65EB,$8196,$12A7,$E289,$511A,$8917,$3DE1,$56F8
1F10: '.....J'...6.....' DC.W $2ED5,$17E5,$8A4A,$27FB,$12E7,$3610,$E80E,$1FB5
1F20: '...h.....,)tS.B.' DC.W $11D8,$8168,$121B,$BCCB,$F22C,$2974,$53CE,$42E6
1F30: '..V..?....."*...' DC.W $FD1,$56B0,$1E3F,$F5E2,$E894,$B622,$2A84,$17A6
1F40: 'J.....(..!5`Q...' DC.W $4AFB,$D62E,$FA01,$289A,$8A21,$3560,$51B8,$A7D8
1F50: '].W\.L...WW...f:' DC.W $5DE1,$575C,$C04C,$A8F2,$CD57,$5700,$F0B0,$663A
1F60: '...L.+(r6......L' DC.W $1212,$2E4C,$122B,$2872,$362E,$120A,$EE16,$E24C
1F70: '<c..0..|.bFt..Vx' DC.W $3C63,$DFB8,$30A8,$D67C,$F62,$4674,$C3BF,$5678
1F80: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
1F90: '.4Vx.4Vx\b....v.' DC.W $1234,$5678,$1234,$5678,$5C62,$A988,$13D6,$7610
1FA0: '...X..%i.4...1~\' DC.W $A912,$F858,$71E,$2569,$1234,$C21B,$1231,$7E5C
1FB0: '?eBd..Vt.^{)..M.' DC.W $3F65,$4264,$1208,$5674,$C05E,$7B29,$EDC8,$4DCD
1FC0: '.D|.2PV.<;t..8.4' DC.W $1244,$7C1A,$3250,$568E,$3C3B,$7410,$9F38,$1434
1FD0: '\n.M.\.I..'W..X.' DC.W $5C6E,$154D,$F45C,$F849,$DFDC,$2757,$8FB2,$5899
1FE0: '...o.........a'O' DC.W $D810,$E66F,$F2E2,$E3C9,$181,$9798,$AB61,$274F
1FF0: '..&.2A.f...N.,V*' DC.W $1212,$26FB,$3241,$F666,$120B,$B64E,$22C,$562A
2000: '..V2=lV....j....' DC.W $1AC,$5632,$3D6C,$5614,$DCC5,$186A,$E39B,$7AC
2010: '\.Vb.xVB.;.a=..e' DC.W $5C99,$5662,$8E78,$5642,$F33B,$F661,$3D8B,$B665
2020: '..V`.+.1<....[D.' DC.W $DD85,$5660,$F32B,$231,$3C85,$1FD8,$B15B,$4408
2030: 'F..]kp.v.,....E.' DC.W $4616,$15D,$6B70,$CF76,$A2C,$18EE,$B99F,$459F
2040: '.ZD. K.ZT..>.2M.' DC.W $B15A,$4408,$204B,$EC5A,$54D1,$A63E,$B32,$4DF8
2050: '.....Y..$U.i....' DC.W $FCE2,$D3E0,$D359,$F490,$2455,$A369,$CDA5,$81FA
2060: '....-.VQ....\bZ.' DC.W $F5AA,$FF6,$2DE0,$5651,$1117,$E9F7,$5C62,$5AE6
2070: '.$gH..$.#LV\....' DC.W $E424,$6748,$F1EB,$24F2,$234C,$565C,$E0C0,$1CCA
2080: '.!..Q..T.rVTA..N' DC.W $1221,$E6BA,$51D3,$EF54,$EE72,$5654,$41B4,$F64E
2090: '....pAkjr...0Z..' DC.W $E3C4,$988,$7041,$6B6A,$721F,$DAE6,$305A,$B899
20A0: ':.%.._U..7....3.' DC.W $3A86,$2588,$C35F,$55E8,$1237,$F3F0,$BBD2,$33C0
20B0: '...I.....4Vx.4Vx' DC.W $988C,$F849,$C1E5,$7A8,$1234,$5678,$1234,$5678
20C0: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
20D0: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
20E0: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
20F0: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2100: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2110: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2120: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2130: '.4RV_d.*....=..$' DC.W $1234,$5256,$5F64,$22A,$C8C9,$C70C,$3DE6,$1524
2140: '..Vx.4Vx.4Vx.4Vx' DC.W $C214,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2150: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2160: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2170: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2180: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
2190: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
21A0: '.4Vx`[email protected]:...m' DC.W $1234,$5678,$6034,$4640,$9EA5,$2D3A,$DA2,$EB6D
21B0: '?40k.4.7....PN.M' DC.W $3F34,$306B,$D34,$E337,$A02E,$F8CC,$504E,$CA4D
21C0: '.h.~XF......f.$V' DC.W $AB68,$C57E,$5846,$EE0A,$B5EC,$EEB7,$66F8,$2456
21D0: '......D@[email protected]} ..' DC.W $717,$D5A1,$B3A7,$4440,$1040,$378,$7D20,$D3E6
21E0: '.(W....;Q.....W"' DC.W $328,$57E6,$B1ED,$D73B,$519C,$88E1,$EF82,$5722
21F0: '..VQp..|r..I....' DC.W $2ED3,$5651,$700C,$197C,$7206,$1949,$11FD,$D8CD
2200: '......f..s$..?..' DC.W $8CC4,$7D5,$937F,$66D2,$CD73,$24E4,$B23F,$197F
2210: 'r..I....wP..'...' DC.W $7205,$1949,$11FD,$D8CD,$7750,$EF00,$2709,$909
0: 'SNNT....R.VJqwVx' data1 DC.W $534E,$4E54,$1EE6,$802,$5289,$564A,$7177,$5678
10: '.4Vxr4V:R.V6q.Vx' DC.W $1234,$5678,$7234,$563A,$52BD,$5636,$71AB,$5678
20: '.4Vx.4Vx.4Vx.4Vx' DC.W $1234,$5678,$1234,$5678,$1234,$5678,$1234,$5678
30: '.4Vx......-.P.S.' DC.W $1234,$5678,$E6CC,$1E9F,$DDBC,$2D19,$501A,$53CC
40: '..0<2$....7P....' DC.W $F86,$303C,$3224,$1390,$F204,$3750,$EDA7,$D6B9
50: 't..&.D..Y.G..f.v' DC.W $74C9,$C726,$AC44,$CB2E,$59D0,$47C3,$E766,$E976
60: '...K....1......y' DC.W $D8A,$D74B,$EFE2,$8D98,$31D4,$E606,$C7DE,$BB79
70: '....~......T.N.B' DC.W $F496,$381,$7EAD,$8BE7,$11CB,$B654,$C74E,$B042
80: '..U^;.Q..oTm....' DC.W $EF9,$555E,$3BAB,$5107,$D6F,$546D,$F494,$A9EE
90: '-....^UQ.f....Uz' DC.W $2D06,$1711,$C5E,$5551,$E766,$E9AA,$FA2,$557A
A0: '........1......z' DC.W $FDC,$D3A5,$EFE2,$8D98,$31D4,$E606,$C7DE,$BB7A
B0: '....~......T..Z.' DC.W $F496,$380,$7EAD,$8BE7,$11CB,$B654,$F5EB,$5AE7
C0: '........' DC.W $80C,$160A,$B4A4,$E9F9
-
Very interesting. I honestly can understand almost none of it. I am not all that good at reverse-engineering assembly (yet).
Swapping out which CPU is in use might actually be easier than double-booting (assuming that we can figure out how to swap the cpu). We would have to modify BootX to perform a few checks early on in the process. If it detects the right conditions, it will do the crazy CPU swap thing. The rest of BootX would then continue on, unaware that the CPU was swapped out from under its feet.
We have not made proper introductions. Welcome. I am the most recent crazy tech person. While I am often wrong, I try to be wrong in interesting and insightful ways :)
-
Nice to meet you,
I'm happy to discuss these things as it is very boring trying to do it on your own. As said I did exchange emails with Ryan Rempel (guy who wrote XPostFacto) and some former Sonnet engineer but they were busy with other things. I do write day-to-day embedded code, iPhone and Android stuff and even have done some NewtonScript in early 2000. One thing I'm not familiar with is how Mac OS 9 works as it is very different from modern day OS and the guys investigating how to expand the memory limit is very interesting and insightful read.
Alas, I haven't done assembly since university (some 18 years ago) and definitely we didn't do m68k or PPC asm. I do understand the basics how a CPU work, which helps with assembly reading but I'd assume there are much more proficient guys around here. But reading assembly is very much brute-force method of understanding how it works. Better and sometimes faster is to create an assumption how it should work, find evidence in the decompiled code that it supports your assumptions limiting the amount of code to be understood to a minimum.
E.g. if the G3 accelerator is somehow commanded using L2 cache commands https://cdn.preterhuman.net/texts/computing/apple_hardware_devnotes/PowerMac%205400.pdf in the decompiled code there should be some references to signals (pg. 63 in the PDF). E.g. L2_PRSNT I would assume is the first check. Does the L2 module exist at all? Then one would read something known to determine if it is a real L2 cache or an accelerator.
Now, I don't know how L2_PRSNT signal is checked in assembly, so I don't yet know what to look for in the decompiled code
-
Based on http://dec8.info/Apple/Designing_Cards_and_Drivers_for_the_Macintosh_Family_2ed_May90.pdf page number 386
ROM traps control the enabling, disabling, and flushing of the cache card. These functions are called using a selector from the HWPriv (A098) trap. See Table 18-2.
Table 18-2 Cache control trap
Function | Selector |
EnableExtCache | 4 |
DisableExtCache | 5 |
FlushExtCache | 6 |
See INIT line AE. The code sends selector 1 which is undefined. Also it calls GetTrapAddress which should not be used with PPC, go figure. Anyways the INIT code will load Ptch 128 (lines 88-92) and start executing it at B6 and in between does something with cache and power management.
I need to figure how I could load the Ptch 128 (and 131) as decompiled code with MacNosy. Those interested there is an article how to use it at http://basalgangster.macgui.com/RetroMacComputing/The_Long_View/Entries/2010/4/24_MacNosy.html
-
Turning Ptch 128 into code was as simple as pressing c on review. It doesn't do the work perfectly (assuming ILL*, PPC_emul instructions are something that it has been misidentified) but it seems that Ptch 128 more or less prepares Mac OS to the new environment (i.e. running on G3) as many of the toolbox instructions called are related to setting up Mac OS again.
I never saw any references to the other Ptch. It also seems weird that the original CPU does all the Mac OS rewiring but it does call JMP (A0) after loading the patch in the init code.
If my findings are correct and not naive enabling the G3 accelerator should be as simple as sending 1 to HWPriv trap. The Power trap is also invoked but I haven't figured that one out what it actually does.
The next step would be to see from the ROM what does HWPriv actually do along with Power.
If anyone knows please let me know! Thanks.
-
How is the HWPriv trap called? (Sorry, can't check myself, at uni.) If it's one of those 68k traps that get mapped to a PowerPC trap instruction, it might be completely implemented in the NanoKernel. This'd be good, because I have already disassembled a lot of that code.
Nice project, by the way! Mind sharing your MacNosy tips as you go? I'm keen to give it a try.
Is the ptch resource the only code that supports this card?
-
Thanks, to me the whole extension looks like pure 68k code. I've looked at Vimage's extension and that is in mixed mode. I put the relevant part of HWPriv call below but it is a A-trap. Prior to calling that however the address for A09F trap is looked up and compared to the HWPriv address. And if they are equal the HWPriv is executed. Regardless if HWPriv is executed the patch is jumped to.
9A: 303C A09F '0<..' MOVE #$A09F,D0 ; Power
9E: A346 '.F' _GetTrapAddress newOS; (D0/trapNum:Word):A0\ProcPtr
A0: 2F08 '/.' PUSH.L A0
A2: 303C A198 '0<..' MOVE #$A198,D0 ; HWPriv
A6: A346 '.F' _GetTrapAddress newOS; (D0/trapNum:Word):A0\ProcPtr
A8: B1DF '..' CMPA.L (A7)+,A0
AA: 6704 10000B0 BEQ.S lab_8
AC: 7001 'p.' MOVEQ #1,D0
AE: A098 '..' _HWPriv
The further I think about it and read some other sources like http://www.zone6400.com/text_files/SonnetClocking_with_resedit.txt which explains how to modify the extension to overclock the accelerator. The interesting part of this is that the modification is done to PREF resource and I've been looking to find any reference to it from elsewhere in the extension without much of luck.
They claim (http://www.zone6400.com/Sonnet_Clocker.html) that this modification works regardless of the type of accelerator as long as it is manufactured by Sonnet. So it is possible that HWPriv vs. Power address comparison is just a check for a certain type of accelerator which is then triggered with that trap call.
I also looked at the decompiled code for earlier version (1.2.4) of the extension which shouldn't support the L2 accelerator but with a glance the INIT seemed to do the same things and there was similar amount of Ptch resources.
After understanding what HWPriv does internally, it would be wise to run the accelerator on a real computer and see with a debugger what it does (or where you enable to log that with NKLog?)
-
Maybe the accelerator has a rom in it that is run by triggering HWPriv? Maybe the rom loads the pref file and the other ptch? That seems to be the most likely course of action that they took given what we know. It would also be super annoying for running it in BootX because we might have to emulate parts of OS 9 to get it to work.
-
Your finding is aligned with http://www.zone6400.com/Sonnet_Clocker.html
Hi it´s me again from germany,
here are the reasons why the overclocker could not run. unlike the 6400/6500 Mainboard, the 4400 needs no extra programming for the bus. That means a L2 G3 Card for the 4400 does not need the custom chipset that is needed for compatiblity with the 6400/6500. The bus ratio for the 4400 is hard wired and not changeable. The Sonnet clocker works fine with 6400/6500s because it can patch the custom chipset (the cards firmware) by software. You can double check this by starting a 4400 with L2 G3 Card with ext. off. This results in starting with the G3! (only the cache is disabled). Starting the 6400/6500 with L2 G3 and extension off results in starting with the base 603e cpu.
Yours
J.R.
As a background later revisions of Sonnet L2 G3 accelerator were compatible with both 4400 and 6400/6500 (http://www.zone6400.com/Sonnet.html):
Dear Reviewer,
I'd like to update you on new developments with the Crescendo G3 L2/PCI upgrade card that you are reviewing.
1. All three cards are now also compatible with the Power Mac 4400, and the Star Max clones.
2. The low-end 240Mhz speed is sold out. We have replaced it with a 250Mhz card, at the same low price of $399.
Not only does our card now run in more models, but it's just the one card for all the compatible models. Also, we offer a faster speed for our low-end card, but have kept the price at $399.
Thank you. - Joy Hsu
How does comparing A09F and A098 trap addresses reveal you that if you have an accelerator or not?
What if it does reveal you if the code is ran within an accelerator or not? If they are equal the code is running in an accelerator no need to turn the accelerator on. In both cases the execution is continued from Ptch 128.
If the HWPriv turns on the cache i.e. the accelerator, how does it know where to continue with the execution?
Could it be possible for HWPriv trap never release the bus, i.e. leaving the original CPU waiting for bus release from the 'cache' and the accelerator then would boot up 'normally' while the user is waiting with the screen from original CPU visible? Once the accelerator is in the Sonnet extension it would take control of the computer by doing ADB reset and video sync etc. which I can see happening in Ptch 128.
This would sort of explain this user comment about overclocking the accelerator http://www.zone6400.com/Sonnet_Clocker.html:
This what it looks like
Sonnet's extension loads right away and in a blink of an eye the G3/G4 profiler over writes it , a very short wait (a lot shorter than before) and all the rest of the extensions come on. G3/G4 profiler reports Back side Cache disabled but Gauge pro reports a 512 enabled. I noticed there is no more poping sound from my speakers when sonnets extension loads up. The PCI timing extension doesn't show up at the bottom of my screen at boot up but its on
He refers there is wait time on loading the extension (you are waiting because G3 is loading everything from scratch?). I can be totally wrong with this one as well.
If this is indeed what would be going on, could we test this with some boot time trickery? Having a counter in somewhere which would tell us how many times the code has been executed?
-
If the accelerator has a rom, some of it is probably run long before the extension is. Maybe all L2 caches are supposed to have roms which are run automatically early in the boot process. Perhaps the initial rom code patches those two traps in a way that leaves some sort of signature in their addresses? Just having them point close together might be enough to indicate that there is an accelerator. When the HWPriv routine is called by the main cpu, it sets some sort of trigger in the accelerator and locks the main cpu in an endless loop. It might have to save some of its registers and other data in a well known location first. When the accelerator "wakes up", it reads those values to get the necessesary state information and loads the other patch using the resource manager.
-
If that would happen it would need to happen during OF. Two CPUs can’t really(?) access the same devices / RAM at the same time. You are correct there that G3 can be initialized meanwhile. Also the accelerator wouldn’t know where to look for the extension if it is loaded by the main CPU. Finally the Ptch 128 is excited regardless what the trap address comparison result is. It only affects should HWPriv be called.
The main Ptch I assume loads Sonnet logo under the Mac OS logo regardless if there is accelerator or not. You can see this by installing the extension on sheepsaver.
-
The pre-extension loading part of the L2 rom is almost certainly run by the main cpu. Think of it as an option rom. When run, it replaces HWPriv with custom code that manages the processor swap.
The accelerator could totally find the extension if it is set up correctly. The HWPriv stuff will copy all relevant information to a data structure. It will either insert the address of this data structure in one of the registers on the G3 or put the data structure at a certain location relative to the program counter it initializes the G3 to start up at. Once it loads that data, it can do everything the main cpu can.
On a slightly off-topic note I have few questions for ELN or NanoPico:
How advanced is the Multiprocessing setup for the NanoKernel? Does it require all processors to be identical? Can there be two or more different models of cpu in a system? Can you dynamically add and remove cpus from the system? Also, what is the level of compatibility between PowerPC processors? Supervisor registers seem to vary but I can't notice any Userspace differences between models (aside from AltiVec). Is there any particular technical reason why the later versions of OS 9 have to run on G3 or better processors? There doesn't seem to be one.
-
Okay, I tried couple of things to just verify some of the very basic assumptions:
AA: 6704 10000B0 BEQ.S lab_8
I replaced with
AA: 6604 10000B0 BNE.S lab_8
This effectively switched around the behaviour that HWPriv is called or not. On sheep shaver it didn't have any effect. No crash, nothing. I shall eventually try it on TAM to see if it will disable the accelerator.
B6: 4E90 'N.' JSR (A0)
I replaced with
B6: 4E71 'N.' NOP
This eliminated the execution of Ptch 128. As expected no Sonnet banner underneath the Mac OS start up window. Additionally, no icon for the Sonnet extension either.
-
I went and got my TAM. After some burning CDs and failing, I was able to download everything I needed with Netscape 3.0 (remember my TAM has stock installed 7.6.1 so it didn't have browser installed by the OS. Luckily the install CD contained Internet Connection Kit as an extra). Time to start testing.
Changing HWPriv execution condition didn't enable / disable the accelerator. It did very little indeed. Replacing JSR with NOP did the same as with sheep shaver, and I ended up with 603ev. Conclusion is that Ptch 128 contains the code to the magic.
After some more fighting with Netscape (could not download it directly from macintosh repository site but had to put it on my MacBook and share from there) I managed to download and install MacsBug on TAM. While executing cmd-power on random I realised I can replace the HWPriv command with A9FF (Debugger trap). Following the code execution with and without the accelerator installed (so the address cmp was true everytime, regardless if the accelerator was installed or not) I kept going with MacsBug.
After the jump to A0 i.e. the Ptch 128 code, I was greeted with loads of code that does not exist in the Ptch 128 or any other Ptch resource (I tried searching for hex strings I was able to see in the MacsBug) and to exclude the accelerator somehow replacing the code, I ended up into the same code without the accelerator installed.
Going with stepping over (cmd-T) and stepping into (cmd-S) whenever MacsBug said the code will branch the code pretty much ended up into the same place regardless of the presence of the accelerator. This place called VInstall (http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/Processes/Processes-77.html) and the MacsBug crashed.
That was pretty much the experience today. Learned how to use MacsBug but also ended up into a dead end as I currently don't know what code the INIT is executing after JSR (A0) so I can't go and put another debugger trap to get past the VInstall code.
Frustrating...
-
Frustration leads to anger and anger leads to... well trying again.
Looking at what the INIT does prior to loading Ptch 128 it indeed crawls through all Ptch and DRVR resources and will do an exclusive or (EORI) with hex long 12345678 and replace the original if the resource begins with word SNNT in hex.
Oh well, why oh why... It doesn't prevent anyone especially that you need provide your decryption logic in the same extension in 'plain' code.
Time to understand fully the decryption, decrypt the Ptch and replace the resources with decrypted code so I can hack it with ResEdit :D
Btw. While I was googling around I stumbled upon this http://vintageapple.org/macbooks/pdf/Debugging_Macintosh_Software_with_MacsBug_1991.pdf. It gave me more advanced instructions how debug certain extension (around pg 323-340). Might help some other newbies like me.
-
Played around with MacsBug some more and used the cool commands in the book above. If I trace it from INIT 31 breakpoint as described in the book, the code flow never(?) goes into the decryption part.
If I replace D5 = 5 assignment at the beginning of the INIT with debugger trap I can enter the code and execute the assignment from MacsBug. However tracing this will lead to Ptch 128 execution where the patch is not decrypted and it fails to move past the first illegal instruction.
I also tried XORring manually some of the first longs in the patch resource with 12345678 but didn’t get the same results which I can see when running it with the debugger.
I also tried the atb OpenResFile @@sp... command explained in the book but that only catches when desktop is loaded and the CODE resource is executed.
I was able try both INIT 31 breakpoint and debugger trap at the beginning of INIT and it was catched at the INIT 31 first. Then I had to leave.
-
Insanity kept me going back.
Trying to find the correct jump/branch from where to find the beginning of Sonnet extension INIT was a nightmare. I did however use the old HWPriv location debugger trap to dump the memory from A0 to a file (using log filename; dm a0 8000; log) before the subroutine to Patch 128 and behold I now have the decrypt code.
While it still is in text form, I can see the code makes sense and equals the code that is being executed.
Ptch 128 as shown by MacNosy (only couple of lines):
0: 'SNNT..[T.|Ip.s.d' data1 DC.W $534E,$4E54,$914,$5B54,$C7C,$4970,$773,$8A64
10: '.+.......Y..3...' DC.W $E2B,$A9B0,$DEB,$A9C0,$E559,$A9B3,$33F7,$1E17
20: 'q...G.t..s...<..' DC.W $71C4,$B6A0,$478A,$74A0,$9873,$D592,$123C,$B5AD
30: '.#..7[...s...9..' DC.W $223,$880B,$375B,$B806,$9873,$D592,$1239,$B5AD
Ptch 128 from a memory dump (the same lines):
0039F030 4E56 FFBC 48E7 1F38 426E FFD0 42AE FFD8 NVˇºHÁ•8Bnˇ–BÆˇÿ
0039F040 42AE FFC0 3C3C FFFF 7E00 486E FFDC A976 BÆˇ¿<<ˇˇ~•Hnˇ‹©v
0039F050 554F 486E FFE3 4878 0007 A85D 101F 6610 UOHnˇ„Hx••®]••f•
0039F060 554F 486E FFE3 4878 0004 A85D 101F 6708 UOHnˇ„Hx••®]••g•
Do you guys use / know another disassembler than MacNosy? One which I could use the text file as an input and on a modern Mac?
-
There is a tool included with MPW called DumpCode, which disassembles 68k code. It will very likely run on a modern Mac using ksherlock's mpw runtime.
-
On a side note, if you run the computer with the accelerator installed but without the extension, the accelerator does not get hot at all... so I guess there is something that kicks the accelerator up and running in the extension.
-
My TAM has been in pieces for some time (CD-ROM drive is broken, and I have hard time to find a replacement). However, I managed to dump the 'decrypted' code from memory (never got into understanding how it worked in as MacsBug wasn't able to catch it properly or I lacked the skill).
Here you go: https://pastebin.com/raw/Dr5nNmHB
As far as I know, one should be able to replace the existing Ptch128 with the decoded one and the code should still work (as the loader code checks if the Ptch128 is encoded). I don't know how to easily write the memory dump into a resource fork with a modern Mac.
If somebody has an idea, I'll happily give it a try.
-
Ended up copy-pasting it to ResEdit :)
Decompiled stuff: https://pastebin.com/raw/PNrA9Eks
-
Cool. I still can't read assembly all that well, but I can sort of follow what it is doing by looking at the various traps. Most of them seem reasonable for accelerator code to call.
Does the decrypted code actually work in place of the regular Patches?
-
It does, at least in sheepshaver (I.e. no acceleration but the banner loads). The code above is only a piece of it as it seems that MacNosy splits it per procedure. Something you can see from it memory dump already is that there is ShowINIT code (responsible for showing the banner?) and some Open Firmware script (boot /APPL,ROM).
-
Actually the banner is shown by proc11 (if you use Nosy to disassemble). Using resedit one can disable the animation from the main Ptch128 304: 4EBA 1204 and change these two to NOPs (4E71). The banner animation disappears.
The proc11 of Ptch128 is here: https://pastebin.com/raw/55FfwNgY
-
After some tedious trial and error with sheepshaver, it seems that the following lines in proc11 are responsible for selecting the correct PICT resource:
167C: 3F04 '?.' PUSH D4
167E: A9BC '..' _GetPicture ; (picID:INTEGER):PicHandle
The PICT resource is important as it shows Crescendo G3 on TAM, Crescendo G4 on sheepshaver. If one can deduct how D4 is built, one finds the logic for determining which upgrade is installed.
The value of D4 should be 136 (or 130 for different size) and banner for Crescendo G3 is 134 (or 128). If I could reduce 2 from D4 it should load different banner.
Only rows I find that modify the value in D4 are
156C: 383C 0080 '8<..' MOVE #$80,D4
157A: 5444 'TD' ADDQ #2,D4
158C: 5444 'TD' lal_2 ADDQ #2,D4
15B2: 5244 'RD' ADDQ #1,D4
15BA: 5C44 '\D' ADDQ #6,D4
1612: 5244 'RD' ADDQ #1,D4
Let's iterate these lines and see if can change the banner. As said earlier NOP (4E71) is quite good replacement for all http://68k.hax.com/ADDQ (http://68k.hax.com/ADDQ)
-
And so it is. Line
157A: 5444 'TD' ADDQ #2,D4
when changed to NOP, changes the banner to Crescendo G3. This line is guarded by:
1574: 0C40 010C '.@..' CMPI #$10C,D0
1578: 6514 100158E BLO.S lal_3
If D0 is lower than 10C it would skip adding 2 to D4. Okay, we are getting closer, but what is in D0 and how did it get there?
150E: 48E7 1F38 'H..8' MOVEM.L D3-D7/A2-A4,-(A7)
1570: 302A 000E '0*..' MOVE 14(A2),D0
If I understand asm right, A2 value is copied from D3, where D3 comes from should be looked from the main procedure of Ptch 128. Then D3 is replaced with the value at 12 indices advanced from the memory location pointed by A2 (i.e. the original D3). OR then I don't understand assembler right.
-
It appears that the MOVEM is saving a bunch of registers on the stack. Maybe. I am not all that familiar with 68k assembly.
Right below the MOVEM is:
1512: 246E 0008 2000008 MOVEA.L param2(A6),A2
So A2 is some parameter passed in from the calling function. That address is some kind of data structure that contains info about the cpu?
-
Yep, that MOVEM is pushing multiple registers to the stack, probably at the start of a function call. So then, what's calling the function?
-
Thanks Daniel, I missed that line (ha, that's what happens when you do this kind of stuff after long day at work and 2 hour IKEA visit).
param2 VEQU 8
so the value we are looking for from the calling code (https://pastebin.com/raw/PNrA9Eks (https://pastebin.com/raw/PNrA9Eks)) is the first thing that was pushed right?
300: 3F06 '?.' PUSH D6
302: 2F0B '/.' PUSH.L A3
304: 4EBA 1204 100150A JSR proc11
IF it is D6 then it is written in
14: 3C3C FFFF '<<..' MOVE #$FFFF,D6
48: 4EBA 0A72 1000ABC lab_2 JSR proc7
4C: 3800 '8.' MOVE D0,D4
4E: 3C04 '<.' MOVE D4,D6
I don't know if proc7 (https://pastebin.com/raw/xQmM5FZu (https://pastebin.com/raw/xQmM5FZu)) has anything to do with the value of D0. However it (lab_2) is executed if
32: 486E FFE3 200FFE3 PEA vab_10(A6)
36: 4878 0004 'Hx..' PEA 4
3A: A85D '.]' _BitTst ; (bytePtr:Ptr; bitNum:LongInt):BOOLEAN
3C: 101F '..' POP.B D0
3E: 6708 1000048 BEQ.S lab_2
IF it is A3 then
8: 426E FFD0 200FFD0 CLR vab_6(A6)
22E: 486E FFD0 200FFD0 PEA vab_6(A6)
232: 4EBA 0708 100093C JSR proc6
236: 584F 'XO' ADDQ #4,A7
24A: 302E FFD0 200FFD0 MOVE vab_6(A6),D0
24E: 48C0 'H.' EXT.L D0
250: 4680 'F.' NOT.L D0
252: E580 '..' ASL.L #2,D0
254: 2030 0800 ' 0..' MOVE.L 0(A0,D0.L),D0
258: 2D40 FFD4 200FFD4 MOVE.L D0,vab_7(A6)
25C: 2040 ' @' MOVEA.L D0,A0
25E: 2050 ' P' MOVEA.L (A0),A0
260: 2668 0014 '&h..' MOVEA.L 20(A0),A3
Proc6 is here (https://pastebin.com/raw/jseXCtr1 (https://pastebin.com/raw/jseXCtr1)).