diff --git a/docs/cputypes/all.txt b/docs/cputypes/all.txt index b9c48ce..4f104e5 100644 --- a/docs/cputypes/all.txt +++ b/docs/cputypes/all.txt @@ -184,10 +184,15 @@ quad mode introduces several new mnemonics: ANDQ/EORQ/ORQ like AND/EOR/ORA ASLQ/LSRQ/ROLQ/RORQ like ASL/LSR/ROL/ROR INQ/DEQ like INC/DEC + BITQ like BIT + ASRQ like ASR The new mnemonics support all the addressing modes of the original - mnemonics with two exceptions: - - there are no 32-bit immediate arguments + mnemonics with these exceptions: + - there is no immediate addressing - indirect-Z-indexed addressing becomes indirect addressing + - all other indexed addressing modes are only really useful + with read-modify-write instructions or LDQ, because otherwise + a part of the 'Q' value will be used as the index. CAUTION: The STQ instruction clobbers the N and Z flags! There is no "real" Q register, instead A/X/Y/Z are combined to form the Q register (A holds lsb, Z holds msb), except for read-modify- @@ -217,4 +222,3 @@ quad and long modes combined result in another addressing mode for The NOP mnemonic is disabled for this instruction set because its opcode is re-used internally as a prefix byte. CAUTION: The !align pseudo opcode still inserts NOPs. - diff --git a/docs/cputypes/cpu m65.txt b/docs/cputypes/cpu m65.txt index 5c49b01..6adb29e 100644 --- a/docs/cputypes/cpu m65.txt +++ b/docs/cputypes/cpu m65.txt @@ -12,6 +12,8 @@ The mnemonics ldq/stq have nine addressing modes in quad mode, and a tenth when combined with long mode. The mnemonics cpq/adcq/sbcq/andq/eorq/orq have eight addressing modes in quad mode, and a ninth when combined with long mode. +The mnemonic bitq has four addressing modes. +The mnemonic asrq has three addressing modes. This mode is entered after a NEG:NEG (42 42) prefix, the following opcode is then taken from this table: @@ -25,20 +27,20 @@ then taken from this table: 1c 1d orq abs16, x 1e aslq abs16, x 1f 20 21 andq (zp, x) 22 23 -24 25 andq zp 26 rolq zp 27 +24 bitq zp 25 andq zp 26 rolq zp 27 28 29 2a rolq 2b -2c 2d andq abs16 2e rolq abs16 2f +2c bitq abs16 2d andq abs16 2e rolq abs16 2f 30 31 andq (zp), y 32 andq (zp) 33 -34 35 andq zp, x 36 rolq zp, x 37 +34 bitq zp, x 35 andq zp, x 36 rolq zp, x 37 38 39 andq abs16, y 3a deq 3b -3c 3d andq abs16, x 3e rolq abs16, x 3f +3c bitq abs16, x 3d andq abs16, x 3e rolq abs16, x 3f -40 41 eorq (zp, x) 42 43 -44 45 eorq zp 46 lsrq zp 47 +40 41 eorq (zp, x) 42 43 asrq +44 asrq zp 45 eorq zp 46 lsrq zp 47 48 49 4a lsrq 4b 4c 4d eorq abs16 4e lsrq abs16 4f 50 51 eorq (zp), y 52 eorq (zp) 53 -54 55 eorq zp, x 56 lsrq zp, x 57 +54 asrq zp, x 55 eorq zp, x 56 lsrq zp, x 57 58 59 eorq abs16, y 5a 5b 5c 5d eorq abs16, x 5e lsrq abs16, x 5f diff --git a/src/mnemo.c b/src/mnemo.c index c253b84..a3f4b88 100644 --- a/src/mnemo.c +++ b/src/mnemo.c @@ -112,13 +112,13 @@ SCB accu_lindz8[] = { 0, 0, 0, 0, 0x12, 0, 0, // mnemotable), the assembler finds out the column to use here. The row // depends on the used addressing mode. A zero entry in these tables means // that the combination of mnemonic and addressing mode is illegal. -// | 6502 | 6502/65c02/65ce02 | 65c02 | 65ce02 | 65816 | NMOS 6502 undocumented opcodes | C64DTV2 | -enum { IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_BIT,IDXcBIT,IDX_STX,IDXeSTX,IDX_STY,IDXeSTY,IDX_DEC,IDXcDEC,IDX_INC,IDXcINC,IDXcTSB,IDXcTRB,IDXcSTZ,IDXeASR,IDXeASW,IDXeCPZ,IDXeLDZ,IDXePHW,IDXeROW,IDXeRTN,IDX16COP,IDX16REP,IDX16SEP,IDX16PEA,IDXuANC,IDXuASR,IDXuARR,IDXuSBX,IDXuNOP,IDXuDOP,IDXuTOP,IDXuLXA,IDXuANE,IDXuLAS,IDXuTAS,IDXuSHX,IDXuSHY,IDX_SAC,IDX_SIR}; -SCB misc_impl[] = { 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0, 0x1a, 0, 0, 0, 0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xea, 0x80, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0}; // implied/accu -SCB misc_imm[] = { 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc2, 0xa3, 0xf4, 0, 0x62, /*2?*/0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0x80, 0, 0xab, 0x8b, 0, 0, 0, 0, 0x32, 0x42}; // #$ff #$ffff -SCS misc_abs[] = { 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0x2c24, 0x2c24, 0x8e86, 0x8e86, 0x8c84, 0x8c84, 0xcec6, 0xcec6, 0xeee6, 0xeee6, 0x0c04, 0x1c14, 0x9c64, 0x44, 0xcb00, 0xdcd4, 0xab00, 0xfc00, 0xeb00, 0, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x0c04, 0x04, 0x0c00, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff $ffff -SCS misc_xabs[] = { 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0xbcb4, 0, 0, 0, 0, 0x3c34, 0, 0, 0x94, 0x8b94, 0xded6, 0xded6, 0xfef6, 0xfef6, 0, 0, 0x9e74, 0x54, 0, 0, 0xbb00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1c14, 0x14, 0x1c00, 0, 0, 0, 0, 0, 0x9c00, 0, 0}; // $ff,x $ffff,x -SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0xbeb6, 0, 0, 0, 0, 0x96, 0x9b96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xbb00, 0x9b00, 0x9e00, 0, 0, 0}; // $ff,y $ffff,y +// | 6502 | 6502/65c02/65ce02/m65 | 65c02 | 65ce02 | 65816 | NMOS 6502 undocumented opcodes | C64DTV2 | +enum { IDX_ASL,IDX_ROL,IDX_LSR,IDX_ROR,IDX_LDY,IDX_LDX,IDX_CPY,IDX_CPX,IDX_BIT,IDXcBIT,IDXmBITQ,IDX_STX,IDXeSTX,IDX_STY,IDXeSTY,IDX_DEC,IDXcDEC,IDX_INC,IDXcINC,IDXcTSB,IDXcTRB,IDXcSTZ,IDXeASR,IDXeASW,IDXeCPZ,IDXeLDZ,IDXePHW,IDXeROW,IDXeRTN,IDX16COP,IDX16REP,IDX16SEP,IDX16PEA,IDXuANC,IDXuASR,IDXuARR,IDXuSBX,IDXuNOP,IDXuDOP,IDXuTOP,IDXuLXA,IDXuANE,IDXuLAS,IDXuTAS,IDXuSHX,IDXuSHY,IDX_SAC,IDX_SIR}; +SCB misc_impl[] = { 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0, 0x1a, 0, 0, 0, 0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xea, 0x80, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0}; // implied/accu +SCB misc_imm[] = { 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc2, 0xa3, 0xf4, 0, 0x62, /*2?*/0, 0xc2, 0xe2, 0, 0x0b, 0x4b, 0x6b, 0xcb, 0x80, 0x80, 0, 0xab, 0x8b, 0, 0, 0, 0, 0x32, 0x42}; // #$ff #$ffff +SCS misc_abs[] = { 0x0e06, 0x2e26, 0x4e46, 0x6e66, 0xaca4, 0xaea6, 0xccc4, 0xece4, 0x2c24, 0x2c24, 0x2c24, 0x8e86, 0x8e86, 0x8c84, 0x8c84, 0xcec6, 0xcec6, 0xeee6, 0xeee6, 0x0c04, 0x1c14, 0x9c64, 0x44, 0xcb00, 0xdcd4, 0xab00, 0xfc00, 0xeb00, 0, 0x02, 0, 0, 0xf400, 0, 0, 0, 0, 0x0c04, 0x04, 0x0c00, 0, 0, 0, 0, 0, 0, 0, 0}; // $ff $ffff +SCS misc_xabs[] = { 0x1e16, 0x3e36, 0x5e56, 0x7e76, 0xbcb4, 0, 0, 0, 0, 0x3c34, 0x3c34, 0, 0, 0x94, 0x8b94, 0xded6, 0xded6, 0xfef6, 0xfef6, 0, 0, 0x9e74, 0x54, 0, 0, 0xbb00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1c14, 0x14, 0x1c00, 0, 0, 0, 0, 0, 0x9c00, 0, 0}; // $ff,x $ffff,x +SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0xbeb6, 0, 0, 0, 0, 0, 0x96, 0x9b96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xbb00, 0x9b00, 0x9e00, 0, 0, 0}; // $ff,y $ffff,y // Code tables for group GROUP_ALLJUMPS: // These tables are needed for finding out the correct code when the mnemonic @@ -485,6 +485,10 @@ static struct ronode mnemos_m65[] = { // ...now ASLQ/LSRQ/ROLQ/RORQ // INC/DEC // ...now INQ/DEQ + // BIT + // ...now BITQ + // ASR + // ...now ASRQ // it works with all addressing modes (beware of index register usage!) // except for immediate addressing and "($ff),z", which becomes "($ff)" // extension 3: @@ -513,6 +517,8 @@ static struct ronode mnemos_m65[] = { PREDEFNODE("rorq", MERGE(GROUP_MISC, IDX_ROR | PREFIX_NEGNEG)), PREDEFNODE("inq", MERGE(GROUP_MISC, IDXcINC | PREFIX_NEGNEG)), PREDEFNODE("deq", MERGE(GROUP_MISC, IDXcDEC | PREFIX_NEGNEG)), + PREDEFNODE("bitq", MERGE(GROUP_MISC, IDXmBITQ | PREFIX_NEGNEG)), + PREDEFNODE("asrq", MERGE(GROUP_MISC, IDXeASR | PREFIX_NEGNEG)), // because the NOP opcode is used as a prefix code, the mnemonic was disabled: PREDEFLAST("nop", MERGE(GROUP_PREFIX, 0xea)), // ^^^^ this marks the last element diff --git a/src/version.h b/src/version.h index acfff7e..b196485 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ #define RELEASE "0.97" // update before release FIXME #define CODENAME "Zem" // update before release -#define CHANGE_DATE "18 Jul" // update before release FIXME +#define CHANGE_DATE "28 Jul" // update before release FIXME #define CHANGE_YEAR "2020" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME diff --git a/testing/cpus/expected-m65.o b/testing/cpus/expected-m65.o index 30630af..5917e0c 100644 Binary files a/testing/cpus/expected-m65.o and b/testing/cpus/expected-m65.o differ diff --git a/testing/cpus/test-m65.a b/testing/cpus/test-m65.a index 8e8a4a3..6ea63a0 100644 --- a/testing/cpus/test-m65.a +++ b/testing/cpus/test-m65.a @@ -28,20 +28,26 @@ M65 = 1 ; make next include skip the NOP mnemonic (re-used as prefix code by M65 orq $1d1e, x ; 1d aslq $1d1e, x ; 1e andq ($01, x) ; 21 + bitq $05 ; 24 andq $05 ; 25 rolq $05 ; 26 rolq ; 2a + bitq $0d0e ; 2c andq $0d0e ; 2d rolq $0d0e ; 2e andq ($11), y ; 31 andq ($12) ; 32 + bitq $15, x ; 34 andq $15, x ; 35 rolq $15, x ; 36 andq $1919, y ; 39 deq ; 3a + bitq $1d1e, x ; 3c andq $1d1e, x ; 3d rolq $1d1e, x ; 3e eorq ($01, x) ; 41 + asrq ; 43 + asrq $05 ; 44 eorq $05 ; 45 lsrq $05 ; 46 lsrq ; 4a @@ -49,6 +55,7 @@ M65 = 1 ; make next include skip the NOP mnemonic (re-used as prefix code by M65 lsrq $0d0e ; 4e eorq ($11), y ; 51 eorq ($12) ; 52 + asrq $15, x ; 54 eorq $15, x ; 55 lsrq $15, x ; 56 eorq $1919, y ; 59