• R/O
  • SSH
  • HTTPS

oricsdk: Commit


Commit MetaInfo

Revision1574 (tree)
Time2021-10-05 02:37:56
Authordbug

Log Message

6502/65c02/65816 detection code adapted from CC65
(c) Ullrich von Bassewitz, 02.04.1999

Change Summary

Incremental Difference

--- users/dbug/tests/CpuTest/detect.s (nonexistent)
+++ users/dbug/tests/CpuTest/detect.s (revision 1574)
@@ -0,0 +1,181 @@
1+
2+;
3+; Ullrich von Bassewitz, 02.04.1999
4+;
5+; unsigned char getcpu (void);
6+;
7+
8+#include "infos.h"
9+
10+; OSDKXAPARAMS
11+
12+_CurrentCpu .byt CPU_UNKNOWN
13+
14+_DetectCPU
15+.(
16+ ; Start from an unknown version
17+ lda #CPU_UNKNOWN
18+ sta _CurrentCpu
19+
20+ lda #0
21+ inc ; .byte $1A ; nop on nmos, inc on every cmos
22+ cmp #1
23+ bcc isNMOS
24+
25+; Check for 65816/65802
26+ xba ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02)
27+ dec ; .byte $3A, A=$00
28+ xba ; .byte $EB, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02
29+ inc ; .byte $1A, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02
30+ cmp #2
31+ beq is65816
32+
33+isCMOS
34+ lda #CPU_65C02
35+ sta _CurrentCpu
36+ rts
37+
38+is65816
39+ lda #CPU_65C816
40+ sta _CurrentCpu
41+ rts
42+
43+isNMOS
44+ lda #CPU_6502
45+ sta _CurrentCpu
46+ rts
47+.)
48+
49+
50+/*
51+ .include "zeropage.inc"
52+ .export _getcpu
53+
54+
55+; ---------------------------------------------------------------------------
56+; Subroutine to detect an 816. Returns
57+;
58+; - carry clear and 0 in A for a NMOS 6502 CPU
59+; - carry set and 1 in A for a 65C02
60+; - carry set and 2 in A for a 65816
61+; - carry set and 3 in A for a 4510
62+; - carry set and 4 in A for a 65SC02
63+; - carry set and 5 in A for a 65CE02
64+; - carry set and 6 in A for a HuC6280
65+; - carry clear and 7 in A for a 2a03/2a07
66+; - carry set and 8 in A for a 45GS02
67+;
68+; This function uses a $1A opcode which is a INA on the 816 and ignored
69+; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions
70+; of the 6502, but all of them interpret unknown opcodes as NOP so this is
71+; just what we want.
72+
73+.p816 ; Enable 65816 instructions
74+
75+_getcpu:
76+
77+ lda #0
78+ inc a ; .byte $1A ; nop on nmos, inc on every cmos
79+ cmp #1
80+ bcc @IsNMOS
81+
82+; This is at least a 65C02, check for a 65CE02/4510
83+
84+ .byte $42,$EA ; neg on 65CE02/4510, nop #$EA on 65C02, wdm $EA on 65816
85+ cmp #1
86+ beq @HasINCA
87+
88+; This is at least a 65CE02, check for 4510
89+
90+ lda #5 ; CPU_65CE02 constant
91+ ldx #0 ; to make sure MAP doesn't do anything, the upper nybl of X and Z must be clear
92+ .byte $5C ; map on 4510, aug on 65CE02 (acts like 4 byte nop)
93+ lda #3 ; CPU_4510 constant
94+ nop
95+ cmp #5
96+ beq @LoadXAndReturn
97+
98+; It is either a 4510 (C65) or a 45GS02 (MEGA65)
99+
100+ ; 45GS02 supports 32-bit ZP indirect, so use that to check CPU type
101+ ; without requiring a functioning MEGA65 hypervisor.
102+ ; We setup a read of $200xx, then store a different value in $xx
103+ ; and then re-read $200xx to see if it is unchanged.
104+
105+ ; Setup 32-bit pointer to $00020000+tmp1
106+ lda #<$020000+tmp1
107+ sta regsave
108+ lda #>$020000+tmp1
109+ sta regsave+1
110+ sta regsave+3 ; also write to upper byte of pointer to save an extra LDA #$00
111+ lda #^$020000+tmp1
112+ sta regsave+2
113+
114+ ; Prefixing LDA ($nn),Z with a NOP uses 32-bit ZP pointer on 45GS02,
115+ ; but normal 16-bit ZP pointer on 4510
116+ ; (We assume Z=$00, which will be the normal case)
117+ nop ; prefix to tell next instruction to be 32-bit ZP
118+ .byte $b2,regsave ; LDA (regsave),Z
119+ eor #$ff ; change the value
120+ sta tmp1 ; store in $xx
121+ ; now try again to load it: If the same, then 45GS02, as $200xx is unchanged
122+ nop ; prefix to tell next instruction to be 32-bit ZP
123+ .byte $b2,regsave ; LDA (regsave),Z
124+ cmp tmp1 ; does the loaded value match what is in $xx?
125+ bne @Is45GS02 ; $200xx and $xx have different values, so must be a MEGA65 45GS02
126+@Is4510:
127+ lda #3 ; CPU_4510 constant
128+ ldx #0 ; load high byte of word
129+ rts
130+
131+@Is45GS02:
132+ lda #8 ; CPU_45GS02 constant
133+ ldx #0 ; load high byte of word
134+ rts
135+
136+; 6502 type of cpu, check for a 2a03/2a07
137+@IsNMOS:
138+ sed ; set decimal mode, no decimal mode on the 2a03/2a07
139+ lda #9
140+ clc
141+ adc #1 ; $01+$09 = $10 on 6502, $01+$09 = $0A on 2a03/2a07
142+ cld
143+ cmp #$0a
144+ beq @Is2a03
145+ lda #0 ; CPU_6502 constant
146+ beq @LoadXAndReturn
147+@Is2a03:
148+ lda #7 ; CPU_2A0x constant
149+ bne @LoadXAndReturn
150+
151+; 65C02 cpu type, check for HuC6280
152+@CheckHuC6280:
153+ ldx #6 ; CPU_HUC6280 constant
154+ .byte $22,$EA ; sax nop on HuC6280 (A=$06, X=$01), nop #$EA on 65C02 (A=$01, X=$06)
155+ bne @LoadXAndReturn
156+
157+; Check for 65816/65802
158+@HasINCA:
159+ xba ; .byte $EB, put $01 in B accu (nop on 65C02/65SC02)
160+ dec a ; .byte $3A, A=$00
161+ xba ; .byte $EB, A=$01 if 65816/65802 and A=$00 if 65C02/65SC02
162+ inc a ; .byte $1A, A=$02 if 65816/65802 and A=$01 if 65C02/65SC02
163+ cmp #2
164+ beq @LoadXAndReturn
165+
166+; check for 65SC02
167+
168+ ldy $F7
169+ ldx #0
170+ stx $F7
171+ .byte $F7,$F7 ; nop nop on 65SC02, smb7 $F7 on 65C02
172+ ldx $F7
173+ sty $F7
174+ cpx #$00
175+ bne @CheckHuC6280
176+ lda #4 ; CPU_65SC02 constant
177+@LoadXAndReturn:
178+ ldx #0
179+ rts
180+*/
181+
--- users/dbug/tests/CpuTest/infos.h (nonexistent)
+++ users/dbug/tests/CpuTest/infos.h (revision 1574)
@@ -0,0 +1,9 @@
1+
2+
3+
4+#define CPU_UNKNOWN 0
5+#define CPU_6502 1
6+#define CPU_65C02 2
7+#define CPU_65C816 3
8+
9+
--- users/dbug/tests/CpuTest/main.c (nonexistent)
+++ users/dbug/tests/CpuTest/main.c (revision 1574)
@@ -0,0 +1,41 @@
1+//
2+// 6502/65c02/65816 detection code and benchmark
3+//
4+// Detection code adapted from CC65 (c) Ullrich von Bassewitz, 02.04.1999
5+//
6+//
7+
8+#include "infos.h"
9+
10+// Declare the assembly code function
11+void DetectCPU();
12+extern char CurrentCpu;
13+
14+void main()
15+{
16+ cls();
17+ printf("CPU Detected: ");
18+ DetectCPU();
19+ switch (CurrentCpu)
20+ {
21+ default:
22+ case CPU_UNKNOWN: // 0
23+ printf("Unknown CPU");
24+ break;
25+
26+ case CPU_6502: // 1
27+ printf("6502 (NMOS)");
28+ break;
29+
30+ case CPU_65C02: // 2
31+ printf("6502 (CMOS)");
32+ break;
33+
34+ case CPU_65C816: // 3
35+ printf("65C816");
36+ break;
37+ }
38+ printf("\r\n");
39+
40+ printf("Done\r\n");
41+}
--- users/dbug/tests/CpuTest/osdk_build.bat (nonexistent)
+++ users/dbug/tests/CpuTest/osdk_build.bat (revision 1574)
@@ -0,0 +1,35 @@
1+@ECHO OFF
2+
3+
4+::
5+:: Initial check.
6+:: Verify if the SDK is correctly configurated
7+::
8+IF "%OSDK%"=="" GOTO ErCfg
9+
10+
11+::
12+:: Set the build paremeters
13+::
14+CALL osdk_config.bat
15+
16+
17+::
18+:: Launch the compilation of files
19+::
20+CALL %OSDK%\bin\make.bat %OSDKFILE%
21+GOTO End
22+
23+
24+::
25+:: Outputs an error message
26+::
27+:ErCfg
28+ECHO == ERROR ==
29+ECHO The Oric SDK was not configured properly
30+ECHO You should have a OSDK environment variable setted to the location of the SDK
31+IF "%OSDKBRIEF%"=="" PAUSE
32+GOTO End
33+
34+
35+:End
--- users/dbug/tests/CpuTest/osdk_config.bat (nonexistent)
+++ users/dbug/tests/CpuTest/osdk_config.bat (revision 1574)
@@ -0,0 +1,10 @@
1+@ECHO OFF
2+
3+::
4+:: Set the build paremeters
5+::
6+SET OSDKADDR=$500
7+SET OSDKNAME=CPUTEST
8+SET OSDKFILE=main detect
9+SET OSDKXAPARAMS=
10+
--- users/dbug/tests/CpuTest/osdk_execute.bat (nonexistent)
+++ users/dbug/tests/CpuTest/osdk_execute.bat (revision 1574)
@@ -0,0 +1,31 @@
1+@ECHO OFF
2+
3+::
4+:: Initial check.
5+:: Verify if the SDK is correctly configurated,
6+::
7+IF "%OSDK%"=="" GOTO ErCfg
8+
9+::
10+:: Set the build paremeters
11+::
12+CALL osdk_config.bat
13+
14+::
15+:: Run the emulator using the common batch
16+::
17+CALL %OSDK%\bin\execute.bat
18+GOTO End
19+
20+::
21+:: Outputs an error message about configuration
22+::
23+:ErCfg
24+ECHO == ERROR ==
25+ECHO The Oric SDK was not configured properly
26+ECHO You should have a OSDK environment variable setted to the location of the SDK
27+ECHO ===========
28+IF "%OSDKBRIEF%"=="" PAUSE
29+GOTO End
30+
31+:End
--- users/dbug/tests/CpuTest/osdk_showmap.bat (nonexistent)
+++ users/dbug/tests/CpuTest/osdk_showmap.bat (revision 1574)
@@ -0,0 +1,39 @@
1+@ECHO OFF
2+
3+::
4+:: Initial check.
5+:: Verify if the SDK is correctly configurated
6+::
7+IF "%OSDK%"=="" GOTO ErCfg
8+
9+::
10+:: Set the build paremeters
11+::
12+CALL osdk_config.bat
13+
14+::
15+:: Generate the HTML file
16+::
17+%OSDK%\bin\MemMap.exe build\symbols build\map.htm %OSDKNAME% %OSDK%\documentation\documentation.css
18+
19+::
20+:: Display the HTML file
21+::
22+explorer build\map.htm
23+
24+GOTO End
25+
26+
27+::
28+:: Outputs an error message
29+::
30+:ErCfg
31+ECHO == ERROR ==
32+ECHO The Oric SDK was not configured properly
33+ECHO You should have a OSDK environment variable setted to the location of the SDK
34+pause
35+GOTO End
36+
37+
38+:End
39+
Show on old repository browser