+
+ Conditional assembly: Check if the assembler is currently in 6502DTV mode
+ (see command).
+
+
.IFPSC02
Conditional assembly: Check if the assembler is currently in 65SC02 mode
@@ -3585,6 +3593,14 @@ Here's a list of all control commands and a description, what they do:
+.PDTV
+
+ Enable the 6502DTV instruction set. This is a superset of the 6502
+ instruction set.
+
+ See:
+
+
.POPCPU
Pop the last CPU setting from the stack, and activate it.
@@ -3848,10 +3864,11 @@ 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 command line option,
- namely: 6502, 6502X, 65SC02, 65C02, 65816, 4510 and HuC6280.
+ namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510 and HuC6280.
See: ,
,
+ ,
,
,
,
@@ -4586,6 +4603,7 @@ each supported CPU a constant similar to
CPU_SWEET16
CPU_HUC6280
CPU_4510
+ CPU_6502DTV
is defined. These constants may be used to determine the exact type of the
@@ -4600,6 +4618,7 @@ another constant is defined:
CPU_ISET_SWEET16
CPU_ISET_HUC6280
CPU_ISET_4510
+ CPU_ISET_6502DTV
The value read from the / pseudo variable may
diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c
index b8bda4c7d..6198f4017 100644
--- a/src/ca65/condasm.c
+++ b/src/ca65/condasm.c
@@ -416,6 +416,16 @@ void DoConditionals (void)
CalcOverallIfCond ();
break;
+ case TOK_IFPDTV:
+ D = AllocIf (".IFPDTV", 1);
+ NextTok ();
+ if (IfCond) {
+ SetIfCond (D, GetCPU() == CPU_6502DTV);
+ }
+ ExpectSep ();
+ CalcOverallIfCond ();
+ break;
+
case TOK_IFPSC02:
D = AllocIf (".IFPSC02", 1);
NextTok ();
@@ -470,6 +480,7 @@ int CheckConditionals (void)
case TOK_IFP4510:
case TOK_IFP816:
case TOK_IFPC02:
+ case TOK_IFPDTV:
case TOK_IFPSC02:
case TOK_IFREF:
DoConditionals ();
diff --git a/src/ca65/instr.c b/src/ca65/instr.c
index c5e3b7fef..faeff2026 100644
--- a/src/ca65/instr.c
+++ b/src/ca65/instr.c
@@ -367,7 +367,7 @@ static const struct {
{ "RRA", 0x000A26C, 0x63, 0, PutAll }, /* X */
{ "RTI", 0x0000001, 0x40, 0, PutAll },
{ "RTS", 0x0000001, 0x60, 0, PutAll },
- { "SAC", 0x0800000, 0x32, 0, PutAll }, /* DTV */
+ { "SAC", 0x0800000, 0x32, 1, PutAll }, /* DTV */
{ "SBC", 0x080A26C, 0xe0, 0, PutAll },
{ "SEC", 0x0000001, 0x38, 0, PutAll },
{ "SED", 0x0000001, 0xf8, 0, PutAll },
@@ -375,7 +375,7 @@ static const struct {
{ "SHA", 0x0002200, 0x93, 1, PutAll }, /* X */
{ "SHX", 0x0000200, 0x9e, 1, PutAll }, /* X */
{ "SHY", 0x0000040, 0x9c, 1, PutAll }, /* X */
- { "SIR", 0x0800000, 0x32, 0, PutAll }, /* DTV */
+ { "SIR", 0x0800000, 0x42, 1, PutAll }, /* DTV */
{ "STA", 0x000A26C, 0x80, 0, PutAll },
{ "STX", 0x000010c, 0x82, 1, PutAll },
{ "STY", 0x000002c, 0x80, 1, PutAll },
diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c
index 5b2ef0573..26d01cbf1 100644
--- a/src/ca65/pseudo.c
+++ b/src/ca65/pseudo.c
@@ -1552,6 +1552,14 @@ static void DoP4510 (void)
+static void DoPDTV (void)
+/* Switch to C64DTV CPU */
+{
+ SetCPU (CPU_6502DTV);
+}
+
+
+
static void DoPageLength (void)
/* Set the page length for the listing */
{
@@ -2058,6 +2066,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
{ ccKeepToken, DoConditionals }, /* .IFP816 */
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
+ { ccKeepToken, DoConditionals }, /* .IFPDTV */
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
{ ccKeepToken, DoConditionals }, /* .IFREF */
{ ccNone, DoImport },
@@ -2091,6 +2100,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoPageLength },
{ ccNone, DoUnexpected }, /* .PARAMCOUNT */
{ ccNone, DoPC02 },
+ { ccNone, DoPDTV },
{ ccNone, DoPopCPU },
{ ccNone, DoPopSeg },
{ ccNone, DoProc },
diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c
index 361a817c1..fb9905809 100644
--- a/src/ca65/scanner.c
+++ b/src/ca65/scanner.c
@@ -219,6 +219,7 @@ struct DotKeyword {
{ ".IFP4510", TOK_IFP4510 },
{ ".IFP816", TOK_IFP816 },
{ ".IFPC02", TOK_IFPC02 },
+ { ".IFPDTV", TOK_IFPDTV },
{ ".IFPSC02", TOK_IFPSC02 },
{ ".IFREF", TOK_IFREF },
{ ".IMPORT", TOK_IMPORT },
@@ -258,6 +259,7 @@ struct DotKeyword {
{ ".PAGELENGTH", TOK_PAGELENGTH },
{ ".PARAMCOUNT", TOK_PARAMCOUNT },
{ ".PC02", TOK_PC02 },
+ { ".PDTV", TOK_PDTV },
{ ".POPCPU", TOK_POPCPU },
{ ".POPSEG", TOK_POPSEG },
{ ".PROC", TOK_PROC },
diff --git a/src/ca65/token.h b/src/ca65/token.h
index 8998cc162..ab36028fd 100644
--- a/src/ca65/token.h
+++ b/src/ca65/token.h
@@ -196,6 +196,7 @@ typedef enum token_t {
TOK_IFP4510,
TOK_IFP816,
TOK_IFPC02,
+ TOK_IFPDTV,
TOK_IFPSC02,
TOK_IFREF,
TOK_IMPORT,
@@ -229,6 +230,7 @@ typedef enum token_t {
TOK_PAGELENGTH,
TOK_PARAMCOUNT,
TOK_PC02,
+ TOK_PDTV,
TOK_POPCPU,
TOK_POPSEG,
TOK_PROC,
diff --git a/src/common/cpu.c b/src/common/cpu.c
index 16578543b..b55a5ab00 100644
--- a/src/common/cpu.c
+++ b/src/common/cpu.c
@@ -70,7 +70,7 @@ const unsigned CPUIsets[CPU_COUNT] = {
CPU_ISET_NONE,
CPU_ISET_6502,
CPU_ISET_6502 | CPU_ISET_6502X,
- CPU_ISET_6502 | CPU_ISET_6502X | CPU_ISET_6502DTV,
+ CPU_ISET_6502 | CPU_ISET_6502DTV,
CPU_ISET_6502 | CPU_ISET_65SC02,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_65816,
diff --git a/src/common/cpu.h b/src/common/cpu.h
index 706b4544e..2e75feaaf 100644
--- a/src/common/cpu.h
+++ b/src/common/cpu.h
@@ -50,7 +50,7 @@ typedef enum {
CPU_NONE, /* No CPU - for assembler */
CPU_6502,
CPU_6502X, /* "Extended", that is: with illegal opcodes */
- CPU_6502DTV, /* CPU_6502X + C64DTV extra opcodes */
+ CPU_6502DTV, /* CPU_6502 + DTV extra and illegal opcodes */
CPU_65SC02,
CPU_65C02,
CPU_65816,
diff --git a/src/da65/opc6502dtv.c b/src/da65/opc6502dtv.c
index 15b860c4e..fe83ad598 100644
--- a/src/da65/opc6502dtv.c
+++ b/src/da65/opc6502dtv.c
@@ -115,7 +115,7 @@ const OpcDesc OpcTable_6502DTV[256] = {
{ "rla", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3f */
{ "rti", 1, flNone, OH_Rts }, /* $40 */
{ "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */
- { "sir", 1, flNone, OH_Implicit }, /* $42 */
+ { "sir", 2, flNone, OH_Immediate }, /* $42 */
{ "", 1, flIllegal, OH_Illegal, }, /* $43 */
{ "nop", 2, flUseLabel, OH_Direct }, /* $44 */
{ "eor", 2, flUseLabel, OH_Direct }, /* $45 */
diff --git a/test/asm/6502dtv-cpudetect.ref b/test/asm/6502dtv-cpudetect.ref
new file mode 100644
index 000000000..77a865eb4
Binary files /dev/null and b/test/asm/6502dtv-cpudetect.ref differ
diff --git a/test/asm/6502dtv-opcodes.ref b/test/asm/6502dtv-opcodes.ref
new file mode 100644
index 000000000..408d89be2
Binary files /dev/null and b/test/asm/6502dtv-opcodes.ref differ
diff --git a/test/asm/6502dtv-opcodes.s b/test/asm/6502dtv-opcodes.s
new file mode 100644
index 000000000..f2446cbe0
--- /dev/null
+++ b/test/asm/6502dtv-opcodes.s
@@ -0,0 +1,258 @@
+.setcpu "6502DTV"
+
+ brk
+ ora ($12,x)
+ .byte $02
+ .byte $03
+ nop $12
+ ora $12
+ asl $12
+ .byte $07
+ php
+ ora #$12
+ asl a
+ anc #$12
+ nop $3456
+ ora $3456
+ asl $3456
+ .byte $0f
+ bpl *+122
+ ora ($12),y
+ bra *+122
+ .byte $13
+ nop $12,x
+ ora $12,x
+ asl $12,x
+ .byte $17
+ clc
+ ora $3456,y
+ .byte $1a ; nop
+ .byte $1b
+ nop $3456,x
+ ora $3456,x
+ asl $3456,x
+ .byte $1f
+ jsr $3456
+ and ($12,x)
+ .byte $22
+ rla ($12,x)
+ bit $12
+ and $12
+ rol $12
+ rla $12
+ plp
+ and #$12
+ rol a
+ .byte $2b,$12 ; anc #$12
+ bit $3456
+ and $3456
+ rol $3456
+ rla $3456
+ bmi *+122
+ and ($12),y
+ sac #$12
+ rla ($12),y
+ .byte $34,$12 ; nop $12,x
+ and $12,x
+ rol $12,x
+ rla $12,x
+ sec
+ and $3456,y
+ .byte $3a ; nop
+ rla $3456,y
+ .byte $3c,$56,$34 ; nop $3456,x
+ and $3456,x
+ rol $3456,x
+ rla $3456,x
+ rti
+ eor ($12,x)
+ sir #$12
+ .byte $43
+ .byte $44,$12 ; nop $12
+ eor $12
+ lsr $12
+ .byte $47
+ pha
+ eor #$12
+ lsr a
+ alr #$12
+ jmp $3456
+ eor $3456
+ lsr $3456
+ .byte $4f
+ bvc *+122
+ eor ($12),y
+ .byte $52
+ .byte $53
+ .byte $54,$12 ; nop $12,x
+ eor $12,x
+ lsr $12,x
+ .byte $57
+ cli
+ eor $3456,y
+ .byte $5a ; nop
+ .byte $5b
+ .byte $5c,$56,$34 ; nop $3456,x
+ eor $3456,x
+ lsr $3456,x
+ .byte $5f
+ rts
+ adc ($12,x)
+ .byte $62
+ rra ($12,x)
+ .byte $64,$12 ; nop $12
+ adc $12
+ ror $12
+ rra $12
+ pla
+ adc #$12
+ ror a
+ arr #$12
+ jmp ($3456)
+ adc $3456
+ ror $3456
+ rra $3456
+ bvs *+122
+ adc ($12),y
+ .byte $72
+ rra ($12),y
+ .byte $74,$12 ; nop $12,x
+ adc $12,x
+ ror $12,x
+ rra $12,x
+ sei
+ adc $3456,y
+ .byte $7a ; nop
+ rra $3456,y
+ .byte $7c,$56,$34 ; nop $3456,x
+ adc $3456,x
+ ror $3456,x
+ rra $3456,x
+ nop #$12
+ sta ($12,x)
+ .byte $82,$12 ; nop #$12
+ .byte $83
+ sty $12
+ sta $12
+ stx $12
+ .byte $87
+ dey
+ .byte $89,$12 ; nop #$12
+ txa
+ .byte $8b
+ sty $3456
+ sta $3456
+ stx $3456
+ .byte $8f
+ bcc *+122
+ sta ($12),y
+ .byte $92
+ .byte $93
+ sty $12,x
+ sta $12,x
+ stx $12,y
+ .byte $97
+ tya
+ sta $3456,y
+ txs
+ .byte $9b
+ shy $3456,x
+ sta $3456,x
+ shx $3456,y
+ .byte $9f
+ ldy #$12
+ lda ($12,x)
+ ldx #$12
+ lax ($12,x)
+ ldy $12
+ lda $12
+ ldx $12
+ lax $12
+ tay
+ lda #$12
+ tax
+ lax #$12
+ ldy $3456
+ lda $3456
+ ldx $3456
+ lax $3456
+ bcs *+122
+ lda ($12),y
+ .byte $b2
+ lax ($12),y
+ ldy $12,x
+ lda $12,x
+ ldx $12,y
+ lax $12,y
+ clv
+ lda $3456,y
+ tsx
+ las $3456,y
+ ldy $3456,x
+ lda $3456,x
+ ldx $3456,y
+ lax $3456,y
+ cpy #$12
+ cmp ($12,x)
+ .byte $c2,$12 ; nop #$12
+ .byte $c3
+ cpy $12
+ cmp $12
+ dec $12
+ .byte $c7
+ iny
+ cmp #$12
+ dex
+ axs #$12
+ cpy $3456
+ cmp $3456
+ dec $3456
+ .byte $cf
+ bne *+122
+ cmp ($12),y
+ .byte $d2
+ .byte $d3
+ .byte $d4,$12 ; nop $12,x
+ cmp $12,x
+ dec $12,x
+ .byte $d7
+ cld
+ cmp $3456,y
+ .byte $da ; nop
+ .byte $db
+ .byte $dc,$56,$34 ; nop $3456,x
+ cmp $3456,x
+ dec $3456,x
+ .byte $df
+ cpx #$12
+ sbc ($12,x)
+ .byte $e2,$12 ; nop #$12
+ .byte $e3
+ cpx $12
+ sbc $12
+ inc $12
+ .byte $e7
+ inx
+ sbc #$12
+ nop
+ .byte $eb,$12 ; sbc #$12
+ cpx $3456
+ sbc $3456
+ inc $3456
+ .byte $ef
+ beq *+122
+ sbc ($12),y
+ .byte $f2
+ .byte $f3
+ .byte $f4,$12 ; nop $12,x
+ sbc $12,x
+ inc $12,x
+ .byte $f7
+ sed
+ sbc $3456,y
+ .byte $fa ; nop
+ .byte $fb
+ .byte $fc,$56,$34 ; nop $3456,x
+ sbc $3456,x
+ inc $3456,x
+ .byte $ff
diff --git a/test/asm/cpudetect.s b/test/asm/cpudetect.s
index adad7c1dc..7b2363b7f 100644
--- a/test/asm/cpudetect.s
+++ b/test/asm/cpudetect.s
@@ -24,6 +24,10 @@
taz
.endif
+.ifpdtv
+ sac #$00
+.endif
+
; step 2: check for bitwise compatibility of instructions sets
; (made verbose for better reading with hexdump/hd(1))
@@ -64,3 +68,7 @@
.byte 0,"CPU_ISET_4510"
.endif
+.if (.cpu .bitand CPU_ISET_6502DTV)
+ .byte 0,"CPU_ISET_6502DTV"
+.endif
+
diff --git a/test/asm/readme.txt b/test/asm/readme.txt
index 0bbadeab9..1d135c895 100644
--- a/test/asm/readme.txt
+++ b/test/asm/readme.txt
@@ -23,7 +23,7 @@ leftover dummy opcode parameters with something more recognizable.
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.
+m740 instructions set. Later 6502dtv support was also added.
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