Re: 6809 / 6702 puzzle

From: Rhialto <rhialto_at_falu.nl>
Date: Sun, 8 Apr 2012 17:58:49 +0200
Message-ID: <20120408155849.GA940@falu.nl>
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 list
Received on 2012-04-08 16:00:08

Archive generated by hypermail 2.2.0.