Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!microsoft!brianw From: brianw@microsoft.UUCP (Brian Willoughby) Newsgroups: comp.sys.apple Subject: Re: 65C02 Summary: A quick test for 6502 vs 65C02 Message-ID: <765@microsoft.UUCP> Date: 28 Feb 89 00:57:23 GMT References: <8902221021.AA05592@crash.cts.com> Organization: Microsoft Corp., Redmond WA Lines: 42 In article <8902221021.AA05592@crash.cts.com>, delton@pro-carolina.cts.com (System Administrator) writes: > What's the shortest way (code size wise) to test for a 65C02 in software > (disregarding reading ROM ID bytes since the ROM's and CPU's don't > necessarily go together). Mainly I need to differentiate between the 6502 and > 65C02. > > It could be done by setting up an address crossing a bank boundary or by > trapping the BRK vector and using an illegal opcode but both of these seem a > bit messy. Anyone know a quicker/easier method? I don't have the code in front of me, but my test for the 65C02 involved the fix to the indirect JMP ($xxFF) instruction. The 6502 is supposed to get the low byte of the address from $xxFF and the high byte from $(xx+1)00 (i.e. the first byte of the next 256 byte page in memory), the error in the 6502 is that the internal logic didn't increment the upper byte when fetching the indirect address, and the upper byte of the destination is fetched from $xx00. At first I was unsure whether it was valid to assume all 6502's had this error. But I changed my mind when I found an old pre-//e program which used this 'bug' to prevent the uninitiated from easily disassembling their code. It turns out that this game was the only program which wouldn't run on my 65C02 enhanced II+. The algorithm: The trick is to have two routines which start at addresses exactly $0100 bytes apart. Thus the low byte of the starting address of each routine is the same. Store this low byte of the address at $xxFF (i.e. any address ending with $FF). Then store the upper byte of the '65C02 detected' code at the first address of the next page ($(xx+1)00 or $xxFF + 1). Store the upper byte of the '6502 detected' code at the first address of the same page ($xx00 or $xxFF - 255). Then execute JMP ($xxFF), (you pick a page value for 'xx'). A 6502 will jump to '6502 deteced' and a 65C02 processor will jump to '65C02 detected'. If you would like to test for 65C802, then you can put the detection code in the 65C02 routine after you are certain that you are on at least a 65C02 machine. The 65C02 turns all unimplemented instructions into NOP, so a 65C802 test can only be performed with a 65C02 or higher. I think I will go home and get the 65C802 detect code if anyone is interested. Brian Willoughby microsoft!brianw #include /* My comments here bear no relation to my work at MicroSoft */