]> git.sur5r.net Git - cc65/commitdiff
Merge pull request #348 from SvOlli/release
authorOliver Schmidt <ol.sc@web.de>
Tue, 20 Sep 2016 14:19:45 +0000 (16:19 +0200)
committerGitHub <noreply@github.com>
Tue, 20 Sep 2016 14:19:45 +0000 (16:19 +0200)
ca65: added .P4510 and .IFP4510 pseudo commands

18 files changed:
doc/ca65.sgml
include/6502.h
libsrc/common/getcpu.s
src/ca65/condasm.c
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/token.h
test/Makefile
test/assembler/4510-cpudetect.ref [new file with mode: 0644]
test/assembler/6502-cpudetect.ref [new file with mode: 0644]
test/assembler/6502x-cpudetect.ref [new file with mode: 0644]
test/assembler/65816-cpudetect.ref [new file with mode: 0644]
test/assembler/65c02-cpudetect.ref [new file with mode: 0644]
test/assembler/65sc02-cpudetect.ref [new file with mode: 0644]
test/assembler/Makefile
test/assembler/README
test/assembler/cpudetect.s [new file with mode: 0644]
test/assembler/huc6280-cpudetect.ref [new file with mode: 0644]

index 6ce5ecef68e20732d43868c7db295149a8f0d657..3e1b11df367703018e370f35d30194c4db7193f3 100644 (file)
@@ -424,8 +424,10 @@ The assembler accepts
       <tt><ref id=".PSC02" name=".PSC02"></tt> command was given).
 <item>all valid 65C02 mnemonics when in 65C02 mode (after the
       <tt><ref id=".PC02" name=".PC02"></tt> command was given).
-<item>all valid 65618 mnemonics when in 65816 mode (after the
+<item>all valid 65816 mnemonics when in 65816 mode (after the
       <tt><ref id=".P816" name=".P816"></tt> command was given).
+<item>all valid 4510 mnemonics when in 4510 mode (after the
+      <tt><ref id=".P4510" name=".P4510"></tt> command was given).
 </itemize>
 
 
@@ -3103,6 +3105,12 @@ Here's a list of all control commands and a description, what they do:
   (see <tt><ref id=".P02" name=".P02"></tt> command).
 
 
+<sect1><tt>.IFP4510</tt><label id=".IFP4510"><p>
+
+  Conditional assembly: Check if the assembler is currently in 4510 mode
+  (see <tt><ref id=".P4510" name=".P4510"></tt> command).
+
+
 <sect1><tt>.IFP816</tt><label id=".IFP816"><p>
 
   Conditional assembly: Check if the assembler is currently in 65816 mode
@@ -3494,7 +3502,18 @@ Here's a list of all control commands and a description, what they do:
   <tt><ref id="option--cpu" name="--cpu"></tt> command line option.
 
   See: <tt><ref id=".PC02" name=".PC02"></tt>, <tt><ref id=".PSC02"
-  name=".PSC02"></tt> and <tt><ref id=".P816" name=".P816"></tt>
+  name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and
+  <tt><ref id=".P4510" name=".P4510"></tt>
+
+
+<sect1><tt>.P4510</tt><label id=".P4510"><p>
+
+  Enable the 4510 instruction set. This is a superset of the 65C02 and
+  6502 instruction sets.
+
+  See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02"
+  name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt> and
+  <tt><ref id=".P816" name=".P816"></tt>
 
 
 <sect1><tt>.P816</tt><label id=".P816"><p>
@@ -3503,7 +3522,8 @@ Here's a list of all control commands and a description, what they do:
   6502 instruction sets.
 
   See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02"
-  name=".PSC02"></tt> and <tt><ref id=".PC02" name=".PC02"></tt>
+  name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt> and
+  <tt><ref id=".P4510" name=".P4510"></tt>
 
 
 <sect1><tt>.PAGELEN, .PAGELENGTH</tt><label id=".PAGELENGTH"><p>
@@ -3531,7 +3551,8 @@ Here's a list of all control commands and a description, what they do:
   6502 and 65SC02 instructions.
 
   See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02"
-  name=".PSC02"></tt> and <tt><ref id=".P816" name=".P816"></tt>
+  name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and
+  <ref id=".P4510" name=".P4510">4510</tt>
 
 
 <sect1><tt>.POPCPU</tt><label id=".POPCPU"><p>
@@ -3604,7 +3625,8 @@ Here's a list of all control commands and a description, what they do:
   6502 instructions.
 
   See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PC02"
-  name=".PC02"></tt> and <tt><ref id=".P816" name=".P816"></tt>
+  name=".PC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and
+  <tt><ref id=".P4510" name=".P4510"></tt>
 
 
 <sect1><tt>.PUSHCPU</tt><label id=".PUSHCPU"><p>
@@ -3796,7 +3818,7 @@ Here's a list of all control commands and a description, what they do:
   Switch the CPU instruction set. The command is followed by a string that
   specifies the CPU. Possible values are those that can also be supplied to
   the <tt><ref id="option--cpu" name="--cpu"></tt> command line option,
-  namely: 6502, 6502X, 65SC02, 65C02, 65816 and HuC6280.
+  namely: 6502, 6502X, 65SC02, 65C02, 65816, 4510 and HuC6280.
 
   See: <tt><ref id=".CPU" name=".CPU"></tt>,
        <tt><ref id=".IFP02" name=".IFP02"></tt>,
@@ -3805,6 +3827,7 @@ Here's a list of all control commands and a description, what they do:
        <tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
        <tt><ref id=".P02" name=".P02"></tt>,
        <tt><ref id=".P816" name=".P816"></tt>,
+       <tt><ref id=".P4510" name=".P4510"></tt>,
        <tt><ref id=".PC02" name=".PC02"></tt>,
        <tt><ref id=".PSC02" name=".PSC02"></tt>
 
@@ -4501,6 +4524,7 @@ each supported CPU a constant similar to
     CPU_65816
     CPU_SWEET16
     CPU_HUC6280
+    CPU_4510
 </verb></tscreen>
 
 is defined. These constants may be used to determine the exact type of the
@@ -4514,6 +4538,7 @@ another constant is defined:
     CPU_ISET_65816
     CPU_ISET_SWEET16
     CPU_ISET_HUC6280
+    CPU_ISET_4510
 </verb></tscreen>
 
 The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may
index 6c104c83af512858cc0e3cdfb6a9ec77ff9ebc8b..31398e5c10da1774467124f7ed3daaa1a628f897 100644 (file)
@@ -50,6 +50,7 @@ typedef unsigned size_t;
 #define CPU_6502        0
 #define CPU_65C02       1
 #define CPU_65816       2
+#define CPU_4510        3
 
 unsigned char getcpu (void);
 /* Detect the CPU the program is running on */
index b7954f52f065c69396e758b356c6237fae334c13..1e60a5d39710d633498d37af518f24b3d96a09c3 100644 (file)
@@ -12,6 +12,7 @@
 ;   - carry clear and 0 in A for a NMOS 6502 CPU
 ;   - carry set and 1 in A for some CMOS 6502 CPU
 ;   - carry set and 2 in A for a 65816
+;   - carry set and 3 in A for a 4510
 ;
 ; This function uses a $1A opcode which is a INA on the 816 and ignored
 ; (interpreted as a NOP) on a NMOS 6502. There are several CMOS versions
 
 _getcpu:
         lda     #0
-        inc     a               ; .byte $1A
+        inc     a               ; .byte $1A ; nop on nmos, inc on every cmos
         cmp     #1
         bcc     @L9
 
-; This is at least a 65C02, check for a 65816
+; This is at least a 65C02, check for a 4510
+
+        .byte   $42,$ea         ; neg on 4510, nop #$ea on 65c02, wdm $ea on 65816
+        cmp     #1
+        bne     @L8
+
+; check for 65816; after 4510, because $eb there is row (rotate word)
 
         xba                     ; .byte $eb, put $01 in B accu
         dec     a               ; .byte $3a, A=$00 if 65C02
         xba                     ; .byte $eb, get $01 back if 65816
         inc     a               ; .byte $1a, make $01/$02
+        .byte $2c               ; bit instruction to skip next command
+@L8:    lda     #3              ; CPU_4510 constant
 @L9:    ldx     #0              ; Load high byte of word
         rts
 
index 24cbae69680b5b7ff9f126de0d4acb42a9132fb2..b8bda4c7d836cedd0e21d9efbbe735a13d2f1eda 100644 (file)
@@ -386,6 +386,16 @@ void DoConditionals (void)
                 CalcOverallIfCond ();
                 break;
 
+            case TOK_IFP4510:
+                D = AllocIf (".IFP4510", 1);
+                NextTok ();
+                if (IfCond) {
+                    SetIfCond (D, GetCPU() == CPU_4510);
+                }
+                ExpectSep ();
+                CalcOverallIfCond ();
+                break;
+
             case TOK_IFP816:
                 D = AllocIf (".IFP816", 1);
                 NextTok ();
@@ -457,6 +467,7 @@ int CheckConditionals (void)
         case TOK_IFNDEF:
         case TOK_IFNREF:
         case TOK_IFP02:
+        case TOK_IFP4510:
         case TOK_IFP816:
         case TOK_IFPC02:
         case TOK_IFPSC02:
index 250ceecc9ee96486e66326c60d31f85f52894119..b44c28dd87d5cf9adbb501a7f4b2e05673629e57 100644 (file)
@@ -1530,6 +1530,14 @@ static void DoP816 (void)
 
 
 
+static void DoP4510 (void)
+/* Switch to 4510 CPU */
+{
+    SetCPU (CPU_4510);
+}
+
+
+
 static void DoPageLength (void)
 /* Set the page length for the listing */
 {
@@ -2033,6 +2041,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccKeepToken,      DoConditionals  },      /* .IFNDEF */
     { ccKeepToken,      DoConditionals  },      /* .IFNREF */
     { ccKeepToken,      DoConditionals  },      /* .IFP02 */
+    { ccKeepToken,      DoConditionals  },      /* .IFP4510 */
     { ccKeepToken,      DoConditionals  },      /* .IFP816 */
     { ccKeepToken,      DoConditionals  },      /* .IFPC02 */
     { ccKeepToken,      DoConditionals  },      /* .IFPSC02 */
@@ -2063,6 +2072,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,           DoOrg           },
     { ccNone,           DoOut           },
     { ccNone,           DoP02           },
+    { ccNone,           DoP4510         },
     { ccNone,           DoP816          },
     { ccNone,           DoPageLength    },
     { ccNone,           DoUnexpected    },      /* .PARAMCOUNT */
index 994f95fba86c2b2b7a39707da4ebc10d81b3c71d..e186b19a79149f9f03f37c1e0ff7e94fd5e5cb4b 100644 (file)
@@ -216,6 +216,7 @@ struct DotKeyword {
     { ".IFNDEF",        TOK_IFNDEF              },
     { ".IFNREF",        TOK_IFNREF              },
     { ".IFP02",         TOK_IFP02               },
+    { ".IFP4510",       TOK_IFP4510             },
     { ".IFP816",        TOK_IFP816              },
     { ".IFPC02",        TOK_IFPC02              },
     { ".IFPSC02",       TOK_IFPSC02             },
@@ -251,6 +252,7 @@ struct DotKeyword {
     { ".ORG",           TOK_ORG                 },
     { ".OUT",           TOK_OUT                 },
     { ".P02",           TOK_P02                 },
+    { ".P4510",         TOK_P4510               },
     { ".P816",          TOK_P816                },
     { ".PAGELEN",       TOK_PAGELENGTH          },
     { ".PAGELENGTH",    TOK_PAGELENGTH          },
index 93dfaa0920180c62c269b496ea21a3565541a06c..8998cc162dd6d283b60578076cf47d290f424be0 100644 (file)
@@ -193,6 +193,7 @@ typedef enum token_t {
     TOK_IFNDEF,
     TOK_IFNREF,
     TOK_IFP02,
+    TOK_IFP4510,
     TOK_IFP816,
     TOK_IFPC02,
     TOK_IFPSC02,
@@ -223,6 +224,7 @@ typedef enum token_t {
     TOK_ORG,
     TOK_OUT,
     TOK_P02,
+    TOK_P4510,
     TOK_P816,
     TOK_PAGELENGTH,
     TOK_PARAMCOUNT,
index 2fd252d2a1b4dd5f1949a5ac3aa8aaa99193a5f1..7f95e43798c049bf88157fca25bb70b70c6507aa 100644 (file)
@@ -47,7 +47,6 @@ continue: $(WORKDIR)/bdiff$(EXE)
        @$(MAKE) -C misc all
 
 mostlyclean:
-       @$(MAKE) -C assembler clean
        @$(MAKE) -C val clean
        @$(MAKE) -C ref clean
        @$(MAKE) -C err clean
diff --git a/test/assembler/4510-cpudetect.ref b/test/assembler/4510-cpudetect.ref
new file mode 100644 (file)
index 0000000..515557c
Binary files /dev/null and b/test/assembler/4510-cpudetect.ref differ
diff --git a/test/assembler/6502-cpudetect.ref b/test/assembler/6502-cpudetect.ref
new file mode 100644 (file)
index 0000000..9b0aeb1
Binary files /dev/null and b/test/assembler/6502-cpudetect.ref differ
diff --git a/test/assembler/6502x-cpudetect.ref b/test/assembler/6502x-cpudetect.ref
new file mode 100644 (file)
index 0000000..3434ecb
Binary files /dev/null and b/test/assembler/6502x-cpudetect.ref differ
diff --git a/test/assembler/65816-cpudetect.ref b/test/assembler/65816-cpudetect.ref
new file mode 100644 (file)
index 0000000..4f6e767
Binary files /dev/null and b/test/assembler/65816-cpudetect.ref differ
diff --git a/test/assembler/65c02-cpudetect.ref b/test/assembler/65c02-cpudetect.ref
new file mode 100644 (file)
index 0000000..9f790d5
Binary files /dev/null and b/test/assembler/65c02-cpudetect.ref differ
diff --git a/test/assembler/65sc02-cpudetect.ref b/test/assembler/65sc02-cpudetect.ref
new file mode 100644 (file)
index 0000000..4e11bd7
Binary files /dev/null and b/test/assembler/65sc02-cpudetect.ref differ
index 47f403469b64242dc4899d911858421941e16c22..5d38847f51454de5e3061498412024ffec99c2f5 100644 (file)
@@ -2,29 +2,44 @@
 # makefile for the assembler regression tests
 
 BINDIR = ../../bin
-#WORKDIR := ../../testwrk
-WORKDIR := .
+WORKDIR := ../../testwrk
 
-TARGETS  = 6502 6502x 65sc02 65c02
-#TARGETS += 65816
-TARGETS += 4510
-TARGETS += huc6280
-#TARGETS += m740
+BASE_TARGETS  = 6502 6502x 65sc02 65c02
+BASE_TARGETS += 4510 huc6280
 
-all: $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS)))
-       @#
+OPCODE_TARGETS = $(BASE_TARGETS)
+CPUDETECT_TARGETS = $(BASE_TARGETS)
 
-.PHONY: all clean $(addprefix $(WORKDIR)/, $(addsuffix -opcodes.bin, $(TARGETS)))
+CPUDETECT_TARGETS += 65816
 
-clean:
-       rm -f *.o *.bin *.lst
+# default target defined later
+all:
 
-define build
+# generate opcode targets and expand target list
+define opcode
+OPCODE_TARGETLIST += $$(WORKDIR)/$(1)-opcodes.bin
 $$(WORKDIR)/$(1)-opcodes.bin: $(1)-opcodes.s
        @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-opcodes.lst --obj-path $$(WORKDIR) -o $$@ $$<
        @diff -q $(1)-opcodes.ref $$@ || (cat $$(WORKDIR)/$(1)-opcodes.lst ; exit 1)
-       @echo ca65 --cpu $(1) ok
+       @echo ca65 --cpu $(1) opcodes ok
+       @rm -f $(1)-opcodes.o #workaround for #168
+endef
+$(foreach target,$(OPCODE_TARGETS),$(eval $(call opcode,$(target))))
+
+# generate cpudetect targets and expand target list
+define cpudetect
+CPUDETECT_TARGETLIST += $$(WORKDIR)/$(1)-cpudetect.bin
+$$(WORKDIR)/$(1)-cpudetect.bin: cpudetect.s
+       @$$(BINDIR)/cl65 --cpu $(1) -t none -l $$(WORKDIR)/$(1)-cpudetect.lst --obj-path $$(WORKDIR) -o $$@ $$<
+       @diff -q $(1)-cpudetect.ref $$@ || (cat $$(WORKDIR)/$(1)-cpudetect.lst ; exit 1)
+       @echo ca65 --cpu $(1) cpudetect ok
+       @rm -f cpudetect.o #workaround for #168
 endef
+$(foreach target,$(CPUDETECT_TARGETS),$(eval $(call cpudetect,$(target))))
+
+# now that all targets have been generated, get to the manual ones
+all: $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST)
+       @#
 
-$(foreach target,$(TARGETS),$(eval $(call build,$(target))))
+.PHONY: all $(OPCODE_TARGETLIST) $(CPUDETECT_TARGETLIST)
 
index 697c2444938ce3ee8e9c0423a2ec918341837d5f..a2b1e9a41c98ff3071238c939a47284a30bd27b8 100644 (file)
@@ -2,6 +2,9 @@
 Assembler Testcases
 ===================
 
+Opcode Tests:
+-------------
+
 These testcases are inspired by the ones now removed from test/assembler.
 The main purpose is to have each possible opcode generated at least once,
 either by an assembly instruction or a ".byte"-placeholder. Typically
@@ -23,7 +26,23 @@ The testcases for 6502, 6502x, 65sc02, 65c02, 4510, and huc6280 have been
 put together by Sven Oliver ("SvOlli") Moll, as well as a template for the
 m740 instructions set.
 
-Still to do is to find a way to implement a testcase for the 65816
+Still to do is to find a way to implement an opcode testcase for the 65816
 processor, since it's capable of executing instructions with an 8-bit and
 a 16-bit operator alike, only distinguished by one processor flag.
 
+
+CPU detect Tests
+----------------
+
+These tests all assemble the same file "cpudetect.s" which contains several
+conditionals for several CPUs, only using every option known to the "--cpu"
+commandline switch of ca65/cl65.
+
+
+Reference (".ref") Files
+------------------------
+
+A hint on creating these files: when running the test, it will fail due to
+the missing ".ref" file. Review the output of the ".lst" very pedantic, then
+copy the ".bin" to the ".ref" file.
+
diff --git a/test/assembler/cpudetect.s b/test/assembler/cpudetect.s
new file mode 100644 (file)
index 0000000..adad7c1
--- /dev/null
@@ -0,0 +1,66 @@
+
+.macpack cpu
+
+; step 1: try to assemble an instruction that's exclusive to this set
+;         (when possible)
+
+.ifp02
+   lda #$ea
+.endif
+
+.ifpsc02
+   jmp ($1234,x)
+.endif
+
+.ifpc02
+   rmb0 $12
+.endif
+
+.ifp816
+   xba
+.endif
+
+.ifp4510
+   taz
+.endif
+
+
+; step 2: check for bitwise compatibility of instructions sets
+;         (made verbose for better reading with hexdump/hd(1))
+
+.if (.cpu .bitand CPU_ISET_NONE)
+   .byte 0,"CPU_ISET_NONE"
+.endif
+
+.if (.cpu .bitand CPU_ISET_6502)
+   .byte 0,"CPU_ISET_6502"
+.endif
+
+.if (.cpu .bitand CPU_ISET_6502X)
+   .byte 0,"CPU_ISET_6502X"
+.endif
+
+.if (.cpu .bitand CPU_ISET_65SC02)
+   .byte 0,"CPU_ISET_65SC02"
+.endif
+
+.if (.cpu .bitand CPU_ISET_65C02)
+   .byte 0,"CPU_ISET_65C02"
+.endif
+
+.if (.cpu .bitand CPU_ISET_65816)
+   .byte 0,"CPU_ISET_65816"
+.endif
+
+.if (.cpu .bitand CPU_ISET_SWEET16)
+   .byte 0,"CPU_ISET_SWEET16"
+.endif
+
+.if (.cpu .bitand CPU_ISET_HUC6280)
+   .byte 0,"CPU_ISET_HUC6280"
+.endif
+
+.if (.cpu .bitand CPU_ISET_4510)
+   .byte 0,"CPU_ISET_4510"
+.endif
+
diff --git a/test/assembler/huc6280-cpudetect.ref b/test/assembler/huc6280-cpudetect.ref
new file mode 100644 (file)
index 0000000..646e0f4
Binary files /dev/null and b/test/assembler/huc6280-cpudetect.ref differ