Hi Dave, On Sat 07 Apr 2012 at 11:43:50 +0200, davee.roberts@fsmail.net wrote: > I have also been working on an implementation of the SuperPET for VICE > - and got as far as Rhialto had until yesterday. Finding this site > (and the post) has spurred me on to crack the 6702... Great! The more the merrier! > STA $04,S ; This instruction appears to be missing from the disassembly. Yes, you're right. I hadn't noticed. I mainly worked on a separate disassembly that I made. I'm including it bewlow with some notes. > I assume the disassembly has come from the EDITor - as I get the same > addresses and instruction stream as Rhialto does. That is correct. The disassembly below is from the EDITor too. > If you follow the disassembly through it finishes at: > > 9087: BEQ >$908C ; Equal = Zero = All good! > 9089: JSR >$B003 ; According to the Waterloo ROM disassembly; this entry point is called "suicide" (hmmm). > > I patched the ROM so that it performed a RTS (return from subroutine) > instead of the intended suicide action - and this appeared to get > the editor to work. I tried that too, a bit half-heartedly I admit, and I think that is why it didn't work consistently for me. I did notice that the call to suicide is (by accident, probably) located so that continuing after it just works. But I wasn't sure if the other languages/tools would be like that. > I also noted that the 6702 code was entered via a JSR within the ROM > bankswitch code - so I hacked the 6809 emulator's JSR code to trap > this address (when combined with the bank switch value) to NOT invoke > the subroutine call. I also worked out what I think the register and > flag values should be after a successful 6702 call and set the CPU > state accordingly. I provide my code for your information below: Very nice find! I immediately copied your code into VICE. I did make some additional changes. Since you say that the bankswitch code is always used, that means that you can check on the value of the pc when the JSR is executed, $BC0D, before checking the list of addresses it jumps to (I put in the whole list all at once). That is a cheaper check. And what's more, you only need to put the check in for opcode AD, JSR indexed, since the call is made with a "JSR ,X" instruction. I haven't tried all tools yet, but so far I have had success! I had to put in a small check for false positives though when i tried BASIC. If you RUN your program it calls some routine which happens to be at $9000, one of the other addresses from your list. I check for the 1st byte of code it jumps to (1F 41 from TFR S,X). That seems to be sufficient so far. > This now seems to work!!! I have tried all of the Waterloo languages > and things "seem" to work - with a few exceptions that I am currently > putting down to 6809 emulator issues. I have found no further attempts > to communicate with the 6702 chip. I have used the following > Waterloo software: > > EDIT V1.1 1982 > PASCAL V1.1 1982 > BASIC V1.1 1981 > FORTRAN V1.1 1981 > APL V1.1 1982 > COBOL V1.0 1981 > DEVELOPMENT ASSEMBLER V1.1 1981 > DEVELOPMENT LINKER V1.0 1981 > DEVELOPMENT EDITOR V1.1 1982 Do you know if the V1.0 versions of those are the same, or different? It would be nice to extend the list to both versions of all languages. (They are both on zi > I will now concentrate on the actual routine itself and try and work > out what it actually does. I have looked at it too, and made some notes with my disassembly, but it is all fairly low level. I didn't get to understand what is really happening. Maybe you'll see more! > Dave Diff edited for clarity: 6809.c: @@ -1528,8 +1528,57 @@ /* Miscellaneous Instructions */ +static inline int ignore_dongle_check() +{ + extern int spet_bank; + extern BYTE mem_ram[]; + // Idea from Dave Roberts + + // ****************************** + // *** *** + // *** DER FOR 6702 dongle. *** + // *** *** + // ****************************** + + if (PC != 0xbc0d) { + return 0; + } + + int bank = spet_bank; + BYTE *mem = (mem_ram + 0x10000) + (bank << 12) + (ea & 0x0fff); + if (mem[0] != 0x1F) { // 9852 1F 41 TFR S,X + return 0; + } + + if ( ((ea == 0x9852) && (bank == 0x01)) ||// EDIT 1.1 - WORKS WITH THE PATCH + ((ea == 0x9000) && (bank == 0x05)) ||// PASCAL 1.1 - FAILS AFTER RUN (BUT EDITOR WORKS) (6809 EMULATOR PROBLEM?) + ((ea == 0x93F0) && (bank == 0x05)) ||// BASIC 1.1 - WORKS WITH THE PATCH + ((ea == 0x960C) && (bank == 0x00)) ||// FORTRAN 1.1 - FAILS AFTER RUN (BUT EDITOR WORKS) (6809 EMULATOR PROBLEM?) + ((ea == 0x9F12) && (bank == 0x06)) ||// APL 1.1 - NOT QUITE RIGHT YET? (I DON'T KNOW APL) + ((ea == 0x9240) && (bank == 0x00)) ||// COBOL 1.0 - SORT OF WORKS? (I DON'T KNOW COBOL) + ((ea == 0x9A05) && (bank == 0x05)) ||// DEVELOPMENT (ASSEMBLER) 1.1 - WORKS WITH THE PATCH + ((ea == 0x94B6) && (bank == 0x08)) ||// DEVELOPMENT (LINKER) 1.0 - WORKS WITH THE PATCH + ((ea == 0x9852) && (bank == 0x02)) // DEVELOPMENT (EDITOR) 1.1 - WORKS WITH THE PATCH + ) { + A = 0x00; // register A + B = 0x00; // Register B + Z = 1; // Z (Zero/Equal) flag + C = 0; // C (Carry) flag + OV = 0; // V (overflow) flag + + printf("ignore dongle check: pc=%04x ea=%04x\n", PC, ea); + // Ignore the JSR! + return 1; + } + return 0; + + +} @@ -4320,6 +4369,7 @@ case 0x00ad: /* JSR indexed */ case 0x10ad: /* JSR indexed (UNDOC) */ case 0x11ad: /* JSR indexed (UNDOC) */ indexed(); + if (ignore_dongle_check()) break; jsr(); break; (this all from the editor; in the comments I used a notation of indexed addressing modes like PDP-11 or 68000, not like 6809) dongle check routine; watch out, this one is checksummed! see 9B8E .C:9852 1F 41 TFR S,X X is old stack ptr .C:9854 32 72 LEAS -14,S make space for 14 bytes .C:9856 86 F0 LDA #$F0 calculate efe0 in a complicated manner .C:9858 A7 66 STA 6,S .C:985a 6A 66 DEC 6,S F0 -> EF .C:985c A7 67 STA 7,S .C:985e 68 67 ASL 7,S F0 -> E0 .C:9860 A6 F8 06 LDA [$06,S] load from dongle .C:9863 8A 11 ORA #$11 or with #$11 .C:9865 A7 64 STA 4,S store in 4(sp) and 5(sp) .C:9867 A7 65 STA 5,S .C:9869 C6 40 LDB #$40 big loop: .C:986b 58 ASLB .C:986c E7 61 STB 1,S store #$80 at 1(sp) for 9893; bitmask to go over 8 bits? .C:986e E7 F8 06 STB [$06,S] and in dongle .C:9871 EC 64 LDD 4,S load the 2 copies of data back in A and B .C:9873 3D MUL multiply them to D .C:9874 E7 65 STB 5,S store in lo byte .C:9876 AA 65 ORA 5,S hi | low byte .C:9878 A7 64 STA 4,S store in hi byte .C:987a C8 D7 EORB #$D7 XOR hi byte with #$D7 .C:987c 68 F8 06 ASL [$06,S] .C:987f E8 F8 06 EORB [$06,S] .C:9882 A6 65 LDA 5,S .C:9884 A7 F8 06 STA [$06,S] .C:9887 68 F8 06 ASL [$06,S] .C:988a A6 F8 06 LDA [$06,S] .C:988d A7 E4 STA ,S save for 98a2 .C:988f E7 82 STB ,-X push on free space between 7(sp) and 14(sp) .C:9891 AF 62 STX 2,S store X for 98b4 .C:9893 E6 61 LDB 1,S get back from 986c .C:9895 8D 08 BSR $989F .C:9897 10 80 UNDOC .C:9899 22 00 BHI $989B .C:989b 40 NEGA .C:989c 00 04 NEG <$04 .C:989e A8 10 EORA -16,X .C:989f 10 AE E1 LDY ,S++ 0(sp) is return address: look at data 10 80 22 00 40 00 04 A8 small loop: .C:98a2 AA E4 ORA ,S from 988d .C:98a4 A4 A4 ANDA ,Y AND with data from table .C:98a6 34 02 PSHS A save A for now on stack .C:98a8 A6 80 LDA ,X+ don't want to loop more than once??? only one STB ,-X above. .C:98aa A4 A0 ANDA ,Y+ AND with data from table, and advance pointer .C:98ac A0 E0 SUBA ,S+ subtract saved A; restores stack ptr .C:98ae 26 0A BNE $98BA done .C:98b0 68 61 ASL 1,S shift left B from 9893 and 986c .C:98b2 26 EE BNE $98A2 loop back small loop .C:98b4 AE 62 LDX 2,S X was saved at 9891 .C:98b6 54 LSRB shift bit in mask 2 to the right .C:98b7 54 LSRB .C:98b8 26 B1 BNE $986B loop back big loop .C:98ba 32 6E LEAS 14,S clean up stack .C:98bc 39 RTS return. If D is not 0000 here, caller jumps to suicide. return addr is 9057 in bank 0, see trace: .C:9057 ED E4 STD ,S - A:80 B:40 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF..N..C .C:9059 E6 63 LDB 3,S - A:80 B:40 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF..N..C .C:905b 26 28 BNE $9085 - A:80 B:00 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF...Z.C .C:905d DC 20 LDD <$20 - A:80 B:00 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF...Z.C .C:905f DD 26 STD <$26 - A:0A B:00 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9061 DD 24 STD <$24 - A:0A B:00 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9063 C6 02 LDB #$02 - A:0A B:00 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9065 9E 24 LDX <$24 - A:0A B:02 X:09EB Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9067 E7 84 STB ,X - A:0A B:02 X:0A00 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9069 30 01 LEAX 1,X - A:0A B:02 X:0A00 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:906b 9F 24 STX <$24 - A:0A B:02 X:0A01 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:906d C6 01 LDB #$01 - A:0A B:02 X:0A01 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:906f E7 84 STB ,X - A:0A B:01 X:0A01 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9071 30 01 LEAX 1,X - A:0A B:01 X:0A01 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9073 9F 24 STX <$24 - A:0A B:01 X:0A02 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9075 DC 24 LDD <$24 - A:0A B:01 X:0A02 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9077 DD 28 STD <$28 - A:0A B:02 X:0A02 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9079 C6 02 LDB #$02 - A:0A B:02 X:0A02 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:907b E7 84 STB ,X - A:0A B:02 X:0A02 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:907d 30 01 LEAX 1,X - A:0A B:02 X:0A02 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:907f 9F 24 STX <$24 - A:0A B:02 X:0A03 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9081 C6 01 LDB #$01 - A:0A B:02 X:0A03 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9083 E7 84 STB ,X - A:0A B:01 X:0A03 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9085 EC E4 LDD ,S - A:0A B:01 X:0A03 Y:9057 SP:09ED U:02FF DP:00 EF.....C .C:9087 27 03 BEQ $908C - A:80 B:40 X:0A03 Y:9057 SP:09ED U:02FF DP:00 EF..N..C .C:9089 BD B0 03 JSR $B003 suicide! - A:80 B:40 X:0A03 Y:9057 SP:09ED U:02FF DP:00 EF..N..C make checksum of dongle check routine .C:9b8e 32 7D LEAS -3,S .C:9b90 6F 62 CLR 2,S set sum to 0 .C:9b92 CC 98 52 LDD #$9852 address of dongle check .C:9b95 ED E4 STD ,S store at 0(sp) .C:9b97 AE E4 LDX ,S to X .C:9b99 E6 84 LDB ,X load 1st byte of routine .C:9b9b C1 39 CMPB #$39 is it RTS? .C:9b9d 27 10 BEQ $9BAF exit loop .C:9b9f 4F CLRA .C:9ba0 E6 62 LDB 2,S load checksum .C:9ba2 EB 84 ADDB ,X add byte of routine .C:9ba4 89 00 ADCA #$00 add carry: one's complement sum .C:9ba6 E7 62 STB 2,S store back in stack .C:9ba8 EC E4 LDD ,S get routine ptr back .C:9baa C3 00 01 ADDD #$0001 add 1 .C:9bad 20 E6 BRA $9B95 and do next byte .C:9baf 4F CLRA .C:9bb0 E6 62 LDB 2,S get checksum .C:9bb2 C3 FF 03 ADDD #$FF03 add FF03 .C:9bb5 E7 62 STB 2,S store back .C:9bb7 4F CLRA .C:9bb8 E6 62 LDB 2,S get result .C:9bba 32 63 LEAS 3,S clean up stack .C:9bbc 39 RTS -Olaf. -- ___ Olaf 'Rhialto' Seibert -- There's no point being grown-up if you \X/ rhialto/at/xs4all.nl -- can't be childish sometimes. -The 4th Doctor Message was sent through the cbm-hackers mailing listReceived on 2012-04-08 16:00:08
Archive generated by hypermail 2.2.0.