]> git.sur5r.net Git - cc65/blob - libsrc/common/getcpu.s
Merge pull request #602 from blackystardust/master
[cc65] / libsrc / common / getcpu.s
1 ;
2 ; Ullrich von Bassewitz, 02.04.1999
3 ;
4 ; unsigned char getcpu (void);
5 ;
6
7         .export         _getcpu
8
9 ; ---------------------------------------------------------------------------
10 ; Subroutine to detect an 816. Returns
11 ;
12 ;   - carry clear and 0 in A for a NMOS 6502 CPU
13 ;   - carry set and 1 in A for a 65C02
14 ;   - carry set and 2 in A for a 65816
15 ;   - carry set and 3 in A for a 4510
16 ;   - carry set and 4 in A for a 65SC02
17 ;   - carry set and 5 in A for a 65CE02
18 ;   - carry set and 6 in A for a HuC6280
19 ;   - carry clear and 7 in A for a 2a03/2a07
20 ;
21 ; This function uses a $1A opcode which is a INA on the 816 and ignored
22 ; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions
23 ; of the 6502, but all of them interpret unknown opcodes as NOP so this is
24 ; just what we want.
25
26 .p816                           ; Enable 65816 instructions
27
28 _getcpu:
29         lda     #0
30         inc     a               ; .byte $1A ; nop on nmos, inc on every cmos
31         cmp     #1
32         bcc     @L8
33
34 ; This is at least a 65C02, check for a 65CE02/4510
35
36         .byte   $42,$EA         ; neg on 65CE02/4510, nop #$EA on 65C02, wdm $EA on 65816
37         cmp     #1
38         beq     @L6
39
40 ; This is at least a 65CE02, check for 4510
41
42         lda     #5              ; CPU_65CE02 constant
43         .byte   $5C             ; map on 4510, aug on 65CE02 (acts like 4 byte nop)
44         lda     #3              ; CPU_4510 constant
45         nop
46         bne     @L9
47
48 ; 6502 type of cpu, check for a 2a03/2a07
49 @L8:
50         sed                     ; set decimal mode, no decimal mode on the 2a03/2a07
51         lda     #9
52         clc
53         adc     #1              ; $01+$09 = $10 on 6502, $01+$09 = $0A on 2a03/2a07
54         cld
55         cmp     #10
56         bne     @L5
57         lda     #0              ; CPU_6502 constant
58         beq     @L9
59 @L5:
60         lda     #7              ; CPU_2A0x constant
61         bne     @L9
62
63 ; 65C02 cpu type, check for HuC6280
64 @L4:    ldx     #6              ; CPU_HUC6280 constant
65         .byte   $22,$EA         ; sax nop on HuC6280 (A=$06, X=$01), nop #$EA on 65C02 (A=$01, X=$06)
66         bne     @L9
67
68 ; Check for 65816/65802
69 @L6:    xba                     ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02)
70         dec     a               ; .byte $3A, A=$00
71         xba                     ; .byte $EB, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02
72         inc     a               ; .byte $1A, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02
73         cmp     #2
74         beq     @L9
75
76 ; check for 65SC02
77
78         ldy     $F7
79         ldx     #0
80         stx     $F7
81         .byte   $F7,$F7         ; nop nop on 65SC02, smb7 $F7 on 65C02
82         ldx     $F7
83         sty     $F7
84         cpx     #$00
85         bne     @L4
86         lda     #4              ; CPU_65SC02 constant
87
88 @L9:    ldx     #0              ; Load high byte of word
89         rts
90