From a4a24280f26ddb3e319678db7a531320df7125fe Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 30 Jun 2025 20:50:30 +0200 Subject: [PATCH 01/11] Do only check .c and .h files. --- .github/checks/sorted.sh | 4 ++-- .github/checks/sorted_codeopt.sh | 4 ++-- .github/checks/sorted_opcodes.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh index b5451a21f..e15c04475 100755 --- a/.github/checks/sorted.sh +++ b/.github/checks/sorted.sh @@ -33,7 +33,7 @@ function checkarray_quoted_name } -for N in `grep -rl "BEGIN SORTED.SH" "$CHECK_DIR"`; do - checkarray_quoted_name $N +find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do + grep -q "BEGIN SORTED.SH" "$N" && checkarray_quoted_name "$N" done exit 0 diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index cfca028dd..370bbfc9f 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -64,6 +64,6 @@ function checkarray find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do - grep -q "BEGIN DECL SORTED_CODEOPT.SH" "$N" && checkarray $N + grep -q "BEGIN DECL SORTED_CODEOPT.SH" "$N" && checkarray "$N" done -exit 0 +exit 0 diff --git a/.github/checks/sorted_opcodes.sh b/.github/checks/sorted_opcodes.sh index 34156bde6..8f8764c6a 100755 --- a/.github/checks/sorted_opcodes.sh +++ b/.github/checks/sorted_opcodes.sh @@ -34,7 +34,7 @@ function checkarray_quoted_name rm -rf .a.tmp } -for N in `grep -rl "BEGIN SORTED_OPCODES.SH" "$CHECK_DIR"`; do - checkarray_quoted_name $N +find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do + grep -q "BEGIN SORTED_OPCODES.SH" "$N" && checkarray_quoted_name "$N" done exit 0 From d4e57278c6f9ce681dc8c263616157226c76cd2f Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 30 Jun 2025 21:37:43 +0200 Subject: [PATCH 02/11] Add a new .cap pseudo function to the assembler that allows to check for certain capabilities of the CPU or target system. --- doc/ca65.sgml | 54 +++++++++++ src/ca65/expr.c | 76 ++++++++++++++-- src/ca65/pseudo.c | 4 +- src/ca65/scanner.c | 2 + src/ca65/token.h | 1 + src/common/capability.c | 90 +++++++++++++++++++ src/common/capability.h | 78 ++++++++++++++++ src/common/cpu.c | 82 +++++++++++++++++ src/common/cpu.h | 8 ++ test/asm/listing/110-capabilities.s | 39 ++++++++ test/asm/listing/control/110-capabilities.err | 0 .../asm/listing/ref/110-capabilities.err2-ref | 6 ++ 12 files changed, 434 insertions(+), 6 deletions(-) create mode 100644 src/common/capability.c create mode 100644 src/common/capability.h create mode 100644 test/asm/listing/110-capabilities.s create mode 100644 test/asm/listing/control/110-capabilities.err create mode 100644 test/asm/listing/ref/110-capabilities.err2-ref diff --git a/doc/ca65.sgml b/doc/ca65.sgml index b7e8539af..552309ff9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1423,6 +1423,10 @@ writable. + See also: + + + .ISIZE Reading this pseudo variable will return the current size of the Index @@ -1594,6 +1598,56 @@ either a string or an expression value. +.CAP, .CAPABILITY + + Builtin function. The function allows to check for capabilities of the + currently selected CPU or target system. It must be called with a comma + separated list of identifiers and returns non zero if all of the given + capabilities are available. Otherwise it returns zero. + + Existing capabilities are: + + + + CPU_HAS_BRA8 + Checks for the availability of a short (8 bit) branch. + + CPU_HAS_INA + Checks for the availability of accu inc/dec instructions. + + CPU_HAS_PUSHXY + Checks for the capability to push and pop the X and Y registers. + + CPU_HAS_ZPIND + Checks for the availability of the "zeropage indirect" addressing mode. + + CPU_HAS_STZ + Checks for the availability of the "store zero" instruction. + + + + Case is ignored when checking the identifiers. The + .if .cap(CPU_HAS_BRA, CPU_HAS_PUSHXY) + phx + bra L1 + .else + txa + pha + jmp L1 + .endif + + + See also: + + + .CONCAT Builtin string function. The function allows to concatenate a list of string diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 5dcf5ca71..42b1a369b 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -37,6 +37,7 @@ #include /* common */ +#include "capability.h" #include "check.h" #include "cpu.h" #include "exprdefs.h" @@ -405,6 +406,66 @@ static ExprNode* FuncBlank (void) +static ExprNode* FuncCapability (void) +/* Handle the .CAPABILITY builtin function */ +{ + int Result = 1; + + /* What follows is a comma separated list of identifiers. An empty list is + ** not allowed. + */ + while (1) { + + const char* Name; + capability_t Cap; + + /* We must have an identifier */ + if (CurTok.Tok != TOK_IDENT) { + Error ("Arguments to .CAPABILITY must be identifiers"); + /* Skip tokens until closing paren or end of line */ + while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) { + NextTok (); + } + return GenLiteral0 (); + } + + /* Search for the capability that matches this identifier. Ignore case + ** on the specified capabilities. + */ + UpcaseSVal (); + SB_Terminate (&CurTok.SVal); + Name = SB_GetConstBuf (&CurTok.SVal); + Cap = FindCapability (Name); + + /* Check if the capability is supported */ + if (Cap == CAP_INVALID) { + Error ("Not a valid capability name: %s", Name); + Result = 0; + } else { + /* The pseudo function result is the logical AND of all capabilities + ** given. + */ + if (!CPUHasCap (Cap)) { + Result = 0; + } + } + + /* Skip the capability name */ + NextTok (); + + /* Handle end of list or next capability */ + if (CurTok.Tok != TOK_COMMA) { + break; + } + NextTok (); + } + + /* Done */ + return GenLiteralExpr (Result); +} + + + static ExprNode* FuncConst (void) /* Handle the .CONST builtin function */ { @@ -484,9 +545,10 @@ static ExprNode* FuncIsMnemonic (void) if (FindMacro (&CurTok.SVal) == 0) { Instr = FindInstruction (&CurTok.SVal); } - } - else { - /* Macros and symbols may NOT use the names of instructions, so just check for the instruction */ + } else { + /* Macros and symbols may NOT use the names of instructions, so + ** just check for the instruction. + */ Instr = FindInstruction (&CurTok.SVal); } } @@ -532,7 +594,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) token_t Term = GetTokListTerm (TOK_COMMA); while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -570,7 +632,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) Node = Root; while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -1129,6 +1191,10 @@ static ExprNode* Factor (void) N = Function (FuncBlank); break; + case TOK_CAP: + N = Function (FuncCapability); + break; + case TOK_CONST: N = Function (FuncConst); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index e6e10df2c..301129583 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -2114,7 +2114,8 @@ struct CtrlDesc { }; /* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR - and .XOR do NOT go into this table */ +** and .XOR do NOT go into this table. +*/ #define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0])) static CtrlDesc CtrlCmdTab [] = { { ccNone, DoA16 }, /* .A16 */ @@ -2132,6 +2133,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .BLANK */ { ccNone, DoBss }, /* .BSS */ { ccNone, DoByte }, /* .BYT, .BYTE */ + { ccNone, DoUnexpected }, /* .CAP */ { ccNone, DoCase }, /* .CASE */ { ccNone, DoCharMap }, /* .CHARMAP */ { ccNone, DoCode }, /* .CODE */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f3892d32e..a2a72a149 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -158,6 +158,8 @@ struct DotKeyword { { ".BSS", TOK_BSS }, { ".BYT", TOK_BYTE }, { ".BYTE", TOK_BYTE }, + { ".CAP", TOK_CAP }, + { ".CAPABILITY", TOK_CAP }, { ".CASE", TOK_CASE }, { ".CHARMAP", TOK_CHARMAP }, { ".CODE", TOK_CODE }, diff --git a/src/ca65/token.h b/src/ca65/token.h index e2b223880..b40534d79 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -137,6 +137,7 @@ typedef enum token_t { TOK_BLANK, TOK_BSS, TOK_BYTE, + TOK_CAP, TOK_CASE, TOK_CHARMAP, TOK_CODE, diff --git a/src/common/capability.c b/src/common/capability.c new file mode 100644 index 000000000..f66205e7c --- /dev/null +++ b/src/common/capability.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* capability.c */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include + +/* ca65 */ +#include "capability.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* List of dot keywords with the corresponding ids. */ +/* CAUTION: table must be sorted for bsearch. */ +struct Capability { + const char* Key; + capability_t Cap; +} Capabilities [] = { +/* BEGIN SORTED.SH */ + { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, + { "CPU_HAS_INA", CAP_CPU_HAS_INA }, + { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, + { "CPU_HAS_STZ", CAP_CPU_HAS_STZ }, + { "CPU_HAS_ZPIND", CAP_CPU_HAS_ZPIND }, +/* END SORTED.SH */ +}; +#define CAP_TABLE_SIZE (sizeof (Capabilities) / sizeof (Capabilities [0])) + + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static int CmpCapability (const void* K1, const void* K2) +/* Compare function for the capability search */ +{ + return strcmp (((struct Capability*)K1)->Key, ((struct Capability*)K2)->Key); +} + + + +capability_t FindCapability (const char* Name) +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ +{ + const struct Capability K = { Name, 0 }; + const struct Capability* C = bsearch (&K, Capabilities, CAP_TABLE_SIZE, + sizeof (Capabilities [0]), + CmpCapability); + return (C == 0)? CAP_INVALID : C->Cap; +} diff --git a/src/common/capability.h b/src/common/capability.h new file mode 100644 index 000000000..011e2164f --- /dev/null +++ b/src/common/capability.h @@ -0,0 +1,78 @@ +/*****************************************************************************/ +/* */ +/* capability.h */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef CAPABILITY_H +#define CAPABILITY_H + + + +/* common */ +#include "strbuf.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Numeric codes for capabilities */ +enum capability_t { + CAP_INVALID = -1, + CAP_CPU_HAS_BRA8 = 0, /* CPU has a BRA 8-bit instruction */ + CAP_CPU_HAS_INA = 1, /* CPU has DEA/INA */ + CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ + CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ + CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ +}; +typedef enum capability_t capability_t; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +capability_t FindCapability (const char* Name); +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ + + + +/* End of capability.h */ + +#endif diff --git a/src/common/cpu.c b/src/common/cpu.c index 252283211..cdc8e52cc 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -33,6 +33,8 @@ +#include + /* common */ #include "addrsize.h" #include "check.h" @@ -90,6 +92,77 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; +/* Defines for capabilities. Currently the entries are uint32_ts but the table +** is deliberately hidden from the outside so it can be extended to 64 bit or +** even more. +*/ +#define CAP_NONE UINT32_C (0) +#define CAP_6502 UINT32_C (0) +#define CAP_6502X UINT32_C (0) +#define CAP_6502DTV UINT32_C (0) +#define CAP_65SC02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65816 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 UINT32_C (0) +#define CAP_HUC6280 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_M740 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA)) +#define CAP_4510 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_45GS02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_W65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_65CE02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + +/* Table containing one capability entry per CPU */ +static const uint64_t CPUCaps[CPU_COUNT] = { + CAP_NONE, /* CPU_NONE */ + CAP_6502, /* CPU_6502 */ + CAP_6502X, /* CPU_6502X */ + CAP_6502DTV, /* CPU_6502DTV */ + CAP_65SC02, /* CPU_65SC02 */ + CAP_65C02, /* CPU_65C02 */ + CAP_65816, /* CPU_65816 */ + CAP_SWEET16, /* CPU_SWEET16 */ + CAP_HUC6280, /* CPU_HUC6280 */ + CAP_M740, /* CPU_M740 */ + CAP_4510, /* CPU_4510 */ + CAP_45GS02, /* CPU_45GS02 */ + CAP_W65C02, /* CPU_W65C02 */ + CAP_65CE02, /* CPU_65CE02 */ +}; + /*****************************************************************************/ @@ -148,3 +221,12 @@ cpu_t FindCPU (const char* Name) /* Not found */ return CPU_UNKNOWN; } + + + +int CPUHasCap (capability_t Cap) +/* Check if the current CPU has the given capability */ +{ + PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); + return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; +} diff --git a/src/common/cpu.h b/src/common/cpu.h index 4202ed573..0a7c853ac 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -38,6 +38,11 @@ +/* common */ +#include "capability.h" + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -107,6 +112,9 @@ cpu_t FindCPU (const char* Name); ** the given name is no valid target. */ +int CPUHasCap (capability_t Cap); +/* Check if the current CPU has the given capability */ + /* End of cpu.h */ diff --git a/test/asm/listing/110-capabilities.s b/test/asm/listing/110-capabilities.s new file mode 100644 index 000000000..e3e306ca7 --- /dev/null +++ b/test/asm/listing/110-capabilities.s @@ -0,0 +1,39 @@ + +; Error: Arguments to .CAPABILITY must be identifiers +.if .cap() +.endif + +; Error: Arguments to .CAPABILITY must be identifiers +; Error: ')' expected +.if .cap( +.endif + +; Error: Not a valid capability name: CPU_HAS_BR +.if .cap(cpu_has_br) +.endif + +; Error: ')' expected +; Error: Unexpected trailing garbage characters +.if .cap(cpu_has_bra8 cpu_has_bra8) +.endif + +; Ok +.if .cap(cpu_has_bra8, CPU_HAS_PUSHXY, CPU_HAS_STZ, CPU_HAS_INA) +.endif + +.setcpu "65SC02" +.if !.cap(cpu_has_bra8) +.error "Assembler says 65SC02 has no 8 bit bra" +.endif +.if !.cap(cpu_has_PUSHXY) +.error "Assembler says 65SC02 has no phx" +.endif +.if !.cap(cpu_has_STZ) +.error "Assembler says 65SC02 has no stz" +.endif +.if !.cap(cpu_has_INA) +.error "Assembler says 65SC02 has no ina" +.endif + + + diff --git a/test/asm/listing/control/110-capabilities.err b/test/asm/listing/control/110-capabilities.err new file mode 100644 index 000000000..e69de29bb diff --git a/test/asm/listing/ref/110-capabilities.err2-ref b/test/asm/listing/ref/110-capabilities.err2-ref new file mode 100644 index 000000000..e00e60e17 --- /dev/null +++ b/test/asm/listing/ref/110-capabilities.err2-ref @@ -0,0 +1,6 @@ +110-capabilities.s:3: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: ')' expected +110-capabilities.s:12: Error: Not a valid capability name: CPU_HAS_BR +110-capabilities.s:17: Error: ')' expected +110-capabilities.s:17: Error: Unexpected trailing garbage characters From f333b300f1c542b952580420259f6d79db7977f1 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:16:33 +0200 Subject: [PATCH 03/11] Added the CPU_HAS_BITIMM capability. --- doc/ca65.sgml | 3 ++ src/common/capability.c | 1 + src/common/capability.h | 1 + src/common/cpu.c | 81 ++++++++++++++++++++++------------------- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 552309ff9..cfe73a2f0 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1609,6 +1609,9 @@ either a string or an expression value. + CPU_HAS_BITIMM + Checks for the availability of the "bit #imm" instruction. + CPU_HAS_BRA8 Checks for the availability of a short (8 bit) branch. diff --git a/src/common/capability.c b/src/common/capability.c index f66205e7c..19c3ed838 100644 --- a/src/common/capability.c +++ b/src/common/capability.c @@ -50,6 +50,7 @@ struct Capability { capability_t Cap; } Capabilities [] = { /* BEGIN SORTED.SH */ + { "CPU_HAS_BITIMM", CAP_CPU_HAS_BITIMM }, { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, { "CPU_HAS_INA", CAP_CPU_HAS_INA }, { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, diff --git a/src/common/capability.h b/src/common/capability.h index 011e2164f..b0332c72e 100644 --- a/src/common/capability.h +++ b/src/common/capability.h @@ -54,6 +54,7 @@ enum capability_t { CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ + CAP_CPU_HAS_BITIMM = 5, /* CPU has "bit #imm" instruction */ }; typedef enum capability_t capability_t; diff --git a/src/common/cpu.c b/src/common/cpu.c index cdc8e52cc..d8c0dbd37 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -96,54 +96,59 @@ const unsigned CPUIsets[CPU_COUNT] = { ** is deliberately hidden from the outside so it can be extended to 64 bit or ** even more. */ +#define CAP_BIT(Cap) (UINT32_C (1) << (Cap)) #define CAP_NONE UINT32_C (0) -#define CAP_6502 UINT32_C (0) -#define CAP_6502X UINT32_C (0) -#define CAP_6502DTV UINT32_C (0) +#define CAP_6502 CAP_NONE +#define CAP_6502X CAP_NONE +#define CAP_6502DTV CAP_NONE #define CAP_65SC02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65816 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) -#define CAP_SWEET16 UINT32_C (0) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 CAP_NONE #define CAP_HUC6280 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_M740 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA)) #define CAP_4510 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_45GS02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_W65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_65CE02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ static const uint64_t CPUCaps[CPU_COUNT] = { From c72126e68fc879229b677baf6443ed242b0262f7 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:25:32 +0200 Subject: [PATCH 04/11] Changed most of the library sources to use .CAP instead of .CPU. --- libsrc/cbm/clock.s | 3 +- libsrc/common/_directerrno.s | 4 +- libsrc/common/_heapblocksize.s | 3 +- libsrc/common/_mappederrno.s | 3 +- libsrc/common/_printf.s | 11 ++--- libsrc/common/_time_t_to_tm.s | 4 +- libsrc/common/asctime.s | 6 +-- libsrc/common/atexit.s | 10 ++-- libsrc/common/fgetc.s | 4 +- libsrc/common/fgets.s | 8 ++-- libsrc/common/fread.s | 15 +++--- libsrc/common/fwrite.s | 6 +-- libsrc/common/ltoa.s | 4 +- libsrc/common/strcat.s | 3 +- libsrc/common/strchr.s | 3 +- libsrc/common/strdup.s | 4 +- libsrc/common/strncat.s | 83 +++++++++++++++++----------------- libsrc/conio/cputs.s | 5 +- libsrc/conio/scrsize.s | 4 +- libsrc/conio/vcprintf.s | 3 +- libsrc/runtime/add.s | 4 +- libsrc/runtime/and.s | 4 +- libsrc/runtime/condes.s | 2 - libsrc/runtime/incax1.s | 3 +- libsrc/runtime/incsp2.s | 4 +- libsrc/runtime/ladd.s | 4 +- libsrc/runtime/laddeq.s | 4 +- libsrc/runtime/land.s | 6 +-- libsrc/runtime/ldau0sp.s | 4 +- libsrc/runtime/leave.s | 4 +- libsrc/runtime/lmod.s | 4 +- libsrc/runtime/lmul.s | 6 +-- libsrc/runtime/lor.s | 6 +-- libsrc/runtime/lpop.s | 4 +- libsrc/runtime/lpush.s | 6 +-- libsrc/runtime/lrsub.s | 6 +-- libsrc/runtime/lsub.s | 6 +-- libsrc/runtime/lsubeq.s | 4 +- libsrc/runtime/ludiv.s | 6 +-- libsrc/runtime/lumod.s | 4 +- libsrc/runtime/lxor.s | 6 +-- libsrc/runtime/or.s | 4 +- libsrc/runtime/popa.s | 4 +- libsrc/runtime/popptr1.s | 4 +- libsrc/runtime/popsreg.s | 4 +- libsrc/runtime/pusha.s | 2 - libsrc/runtime/pushax.s | 4 +- libsrc/runtime/pushb.s | 4 +- libsrc/runtime/rsub.s | 4 +- libsrc/runtime/shl.s | 4 +- libsrc/runtime/staxspi.s | 4 +- libsrc/runtime/stkchk.s | 3 +- libsrc/runtime/sub.s | 4 +- libsrc/runtime/swap.s | 4 +- libsrc/runtime/tosint.s | 4 +- libsrc/runtime/toslong.s | 6 +-- libsrc/runtime/umul8x16r24.s | 4 +- libsrc/runtime/xor.s | 4 +- libsrc/tgi/tgi_settextstyle.s | 4 +- 59 files changed, 122 insertions(+), 232 deletions(-) diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index 90e4263a8..91fde6f58 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -9,14 +9,13 @@ .importzp sreg .include "cbm.inc" - .macpack cpu .proc _clock ; Some accelerator adaptors have CMOS ICs. -.if (.cpu & ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg + 1 .else lda #$00 ; Byte 3 always is zero diff --git a/libsrc/common/_directerrno.s b/libsrc/common/_directerrno.s index 20060bdd7..74e2f89cd 100644 --- a/libsrc/common/_directerrno.s +++ b/libsrc/common/_directerrno.s @@ -7,8 +7,6 @@ .include "errno.inc" - .macpack cpu - ; ---------------------------------------------------------------------------- ; int __fastcall__ __directerrno (unsigned char code); ; /* Set errno to a specific error code, clear __oserror, and return -1. Used @@ -18,7 +16,7 @@ ___directerrno: jsr ___seterrno ; Set errno (returns with .A = 0) sta ___oserror ; Clear ___oserror -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 diff --git a/libsrc/common/_heapblocksize.s b/libsrc/common/_heapblocksize.s index e9b0cdad9..774056032 100644 --- a/libsrc/common/_heapblocksize.s +++ b/libsrc/common/_heapblocksize.s @@ -12,7 +12,6 @@ .include "_heap.inc" .macpack generic - .macpack cpu ;----------------------------------------------------------------------------- ; Code @@ -39,7 +38,7 @@ ___heapblocksize: ldy #usedblock::size+1 lda (ptr2),y tax -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr2) .else dey diff --git a/libsrc/common/_mappederrno.s b/libsrc/common/_mappederrno.s index 83565b723..4ea3174b6 100644 --- a/libsrc/common/_mappederrno.s +++ b/libsrc/common/_mappederrno.s @@ -8,7 +8,6 @@ .include "errno.inc" .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; int __fastcall__ __mappederrno (unsigned char code); @@ -24,7 +23,7 @@ ___mappederrno: bze ok ; Branch if no jsr ___osmaperrno ; Map OS error into errno code jsr ___seterrno ; Save in errno (returns with .A = 0) -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 if error diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index 40ab0bc64..335485cc6 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -13,7 +13,6 @@ .import _strlower, _strlen .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; We will store variables into the register bank in the zeropage. Define @@ -38,7 +37,7 @@ FCount = ptr2 GetFormatChar: ldy #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (Format) .else lda (Format),y @@ -115,7 +114,7 @@ GetIntArg: lda (ArgList),y tax dey - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (ArgList) .else lda (ArgList),y @@ -274,7 +273,7 @@ Save: lda regbank,y ; Initialize the output counter in the output descriptor to zero lda #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (OutData) ldy #$01 sta (OutData),y @@ -353,7 +352,7 @@ MainLoop: sta (c_sp),y dey lda FCount - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (c_sp) .else sta (c_sp),y @@ -570,7 +569,7 @@ CheckCount: jsr GetIntArg sta ptr1 stx ptr1+1 ; Get user supplied pointer - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (OutData) ; Low byte of OutData->ccount sta (ptr1) ldy #1 diff --git a/libsrc/common/_time_t_to_tm.s b/libsrc/common/_time_t_to_tm.s index 9bcf84184..21e662384 100644 --- a/libsrc/common/_time_t_to_tm.s +++ b/libsrc/common/_time_t_to_tm.s @@ -16,8 +16,6 @@ .include "time.inc" - .macpack cpu - __time_t_to_tm: ; Divide number of seconds since epoch, in ptr1:sreg, ; by 86400 to get the number of days since epoch, and @@ -80,7 +78,7 @@ __time_t_to_tm: ; Zero the two high bytes of the divisor and the high byte ; of the dividend. - .if .cpu .bitand CPU_ISET_65SC02 + .if .cap(CPU_HAS_STZ) stz ptr4 stz ptr4+1 stz sreg+1 diff --git a/libsrc/common/asctime.s b/libsrc/common/asctime.s index efcf34b41..b56371594 100644 --- a/libsrc/common/asctime.s +++ b/libsrc/common/asctime.s @@ -9,8 +9,6 @@ .importzp ptr1 .include "time.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Special values @@ -24,7 +22,7 @@ MAX_BUF_LEN = 38 _asctime: ; Backup timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) pha phx .else @@ -48,7 +46,7 @@ _asctime: jsr pushax ; Restore timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) plx pla .else diff --git a/libsrc/common/atexit.s b/libsrc/common/atexit.s index 47a1dfd4d..ccbc2e69f 100644 --- a/libsrc/common/atexit.s +++ b/libsrc/common/atexit.s @@ -10,8 +10,6 @@ .include "errno.inc" - .macpack cpu - ; --------------------------------------------------------------------------- .proc _atexit @@ -41,7 +39,7 @@ jsr ___seterrno ldx #$FF ; Return -1 txa - rts +Exit: rts .endproc @@ -54,7 +52,7 @@ .proc doatexit ldy exitfunc_index ; Get index - beq @L9 ; Jump if done + beq _atexit::Exit ; Jump if done dey lda exitfunc_table,y tax @@ -62,14 +60,12 @@ lda exitfunc_table,y sty exitfunc_index jsr callax ; Call the function -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra doatexit .else jmp doatexit ; Next one .endif -@L9: rts - .endproc diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s index 34d4df3aa..6d08f69a3 100644 --- a/libsrc/common/fgetc.s +++ b/libsrc/common/fgetc.s @@ -12,8 +12,6 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - _fgetc: sta ptr1 stx ptr1+1 @@ -22,7 +20,7 @@ _fgetc: jsr checkferror bne ret_eof - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FPUSHBACK ; Check for pushed back char beq do_read .else diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index c25664f19..fde3a78a9 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -14,12 +14,10 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - terminate_ptr: lda #$00 tax - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else tay @@ -41,7 +39,7 @@ _fgets: sta buf stx buf+1 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_STZ) stz didread .else lda #$00 ; We have read nothing yet @@ -79,7 +77,7 @@ read_loop: ldy #$01 sty didread ; We read at least one char - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else dey diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index be06c2a62..beb9e707e 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -20,7 +20,6 @@ .include "_file.inc" .macpack generic - .macpack cpu ; ------------------------------------------------------------------------ ; Code @@ -48,7 +47,7 @@ ldy #_FILE::f_flags lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN ; Is the file open? .else and #_FOPEN ; Is the file open? @@ -57,7 +56,7 @@ ; Check if the stream is in an error state - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FERROR .else lda (file),y ; get file->f_flags again @@ -74,17 +73,15 @@ ; Remember if we have a pushed back character and reset the flag. -@L2: .if (.cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .cap(CPU_HAS_BITIMM) ldx #$00 bit #_FPUSHBACK + beq @L3 .else tax ; X = 0 lda (file),y and #_FPUSHBACK - .endif beq @L3 - - .if (.not .cpu .bitand ::CPU_ISET_65SC02) lda (file),y .endif and #<~_FPUSHBACK @@ -135,7 +132,7 @@ ; Copy the buffer pointer into ptr1, and increment the pointer value passed ; to read() by one, so read() starts to store data at buf+1. - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (c_sp) sta ptr1 add #1 @@ -159,7 +156,7 @@ ldy #_FILE::f_pushback lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr1) ; *buf = file->f_pushback; .else ldy #0 diff --git a/libsrc/common/fwrite.s b/libsrc/common/fwrite.s index e7151da95..6f631b816 100644 --- a/libsrc/common/fwrite.s +++ b/libsrc/common/fwrite.s @@ -16,8 +16,6 @@ .include "errno.inc" .include "_file.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Code @@ -34,7 +32,7 @@ ldy #_FILE::f_flags lda (ptr1),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN .else and #_FOPEN ; Is the file open? @@ -50,7 +48,7 @@ ; Check if the stream is in an error state -@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .not .cap(CPU_HAS_BITIMM) lda (ptr1),y ; get file->f_flags again .endif and #_FERROR diff --git a/libsrc/common/ltoa.s b/libsrc/common/ltoa.s index 78e43e23f..7c31d471f 100644 --- a/libsrc/common/ltoa.s +++ b/libsrc/common/ltoa.s @@ -10,8 +10,6 @@ .import __hextab, __longminstr .importzp sreg, ptr1, ptr2, ptr3, tmp1 - .macpack cpu - .code ; @@ -64,7 +62,7 @@ L2: txa ; get high byte bpl ultoa lda #'-' -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) .else ldy #0 diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index f9cd94633..963b037b9 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -8,7 +8,6 @@ .export _strcat .import popax .importzp ptr1, ptr2, tmp3 - .macpack cpu _strcat: sta ptr1 ; Save src @@ -16,7 +15,7 @@ _strcat: jsr popax ; Get dest sta tmp3 ; Remember for function return tay -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr2 .else lda #0 diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 206b5160e..ac7f5397a 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -8,14 +8,13 @@ .export _strchr .import popax .importzp ptr1, tmp1 - .macpack cpu _strchr: sta tmp1 ; Save c jsr popax ; get s tay ; low byte of pointer to y stx ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1 .else lda #0 diff --git a/libsrc/common/strdup.s b/libsrc/common/strdup.s index 94f2cd338..4cf643614 100644 --- a/libsrc/common/strdup.s +++ b/libsrc/common/strdup.s @@ -12,8 +12,6 @@ .import _strlen_ptr4, _malloc, _memcpy, pushax .export _strdup - .macpack cpu - _strdup: ; Get length (and store source in ptr4) sta ptr4 @@ -22,7 +20,7 @@ _strdup: jsr _strlen_ptr4 ; strlen may increment ; Add null byte for terminator -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) inc a .else clc diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index 75572db7c..e4e321591 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -8,64 +8,63 @@ .export _strncat .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1, tmp2 -.macpack cpu _strncat: - inx - stx tmp2 - tax - inx - stx tmp1 ; save count with each byte incremented separately + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately - jsr popptr1 ; get src + jsr popptr1 ; get src - jsr popax ; get dest - sta ptr3 ; remember for function return - stx ptr3+1 - stx ptr2+1 - tay ; low byte as offset in Y -.if (.cpu .bitand ::CPU_ISET_65SC02) - stz ptr2 + jsr popax ; get dest + sta ptr3 ; remember for function return + stx ptr3+1 + stx ptr2+1 + tay ; low byte as offset in Y +.if .cap(CPU_HAS_STZ) + stz ptr2 .else - ldx #0 - stx ptr2 ; destination on page boundary + ldx #0 + stx ptr2 ; destination on page boundary .endif ; find end of dest -L1: lda (ptr2),y - beq L2 - iny - bne L1 - inc ptr2+1 - bne L1 +L1: lda (ptr2),y + beq L2 + iny + bne L1 + inc ptr2+1 + bne L1 ; end found, apply offset to dest ptr and reset y -L2: sty ptr2 +L2: sty ptr2 ; copy src. We've put the ones complement of the count into the counter, so ; we'll increment the counter on top of the loop -L3: ldy #0 - ldx tmp1 ; low counter byte +L3: ldy #0 + ldx tmp1 ; low counter byte -L4: dex - bne L5 - dec tmp2 - beq L6 ; jump if done -L5: lda (ptr1),y - sta (ptr2),y - beq L7 - iny - bne L4 - inc ptr1+1 - inc ptr2+1 - bne L4 +L4: dex + bne L5 + dec tmp2 + beq L6 ; jump if done +L5: lda (ptr1),y + sta (ptr2),y + beq L7 + iny + bne L4 + inc ptr1+1 + inc ptr2+1 + bne L4 ; done, set the trailing zero and return pointer to dest -L6: lda #0 - sta (ptr2),y -L7: lda ptr3 - ldx ptr3+1 - rts +L6: lda #0 + sta (ptr2),y +L7: lda ptr3 + ldx ptr3+1 + rts diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index b822fddee..d6024c0e5 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -8,13 +8,12 @@ .export _cputsxy, _cputs .import gotoxy, _cputc .importzp ptr1, tmp1 - .macpack cpu _cputsxy: sta ptr1 ; Save s for later stx ptr1+1 jsr gotoxy ; Set cursor, pop x and y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra L0 ; Same as cputs... .else jmp L0 ; Same as cputs... @@ -24,7 +23,7 @@ _cputs: sta ptr1 ; Save s stx ptr1+1 L0: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; (5) .else ldy #0 ; (2) diff --git a/libsrc/conio/scrsize.s b/libsrc/conio/scrsize.s index 834c14820..fc1691b87 100644 --- a/libsrc/conio/scrsize.s +++ b/libsrc/conio/scrsize.s @@ -10,8 +10,6 @@ .import screensize .importzp ptr1, ptr2 - .macpack cpu - .proc _screensize sta ptr2 ; Store the y pointer @@ -20,7 +18,7 @@ jsr screensize ; Get screensize into X/Y tya ; Get Y size into A -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) txa sta (ptr1) diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index c6371f00e..aa7b6aa07 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -10,7 +10,6 @@ .importzp c_sp, ptr1, ptr2, ptr3, tmp1 .macpack generic - .macpack cpu .data @@ -74,7 +73,7 @@ out: jsr popax ; count ; Loop outputting characters -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND, CPU_HAS_BRA8) @L1: dec outdesc+6 beq @L4 diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index 85ddd0f25..b841f829d 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -11,14 +11,12 @@ .export tosadda0, tosaddax .importzp c_sp, tmp1 - .macpack cpu - tosadda0: ldx #0 tosaddax: clc ; (2) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; (7) tay ; (9) diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 8411660ab..303d4e010 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -8,12 +8,10 @@ .import addysp1 .importzp c_sp, ptr4 - .macpack cpu - tosanda0: ldx #$00 tosandax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index a99b713f5..fc187040e 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -18,8 +18,6 @@ .import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__ .import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__ - .macpack cpu - ; -------------------------------------------------------------------------- ; Initialize library modules diff --git a/libsrc/runtime/incax1.s b/libsrc/runtime/incax1.s index 19c1d0c60..bff94b019 100644 --- a/libsrc/runtime/incax1.s +++ b/libsrc/runtime/incax1.s @@ -7,11 +7,10 @@ .export incax1 .macpack generic - .macpack cpu .proc incax1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; 65C02 version bne @L9 .else diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index c3260c19d..395ea52cb 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -7,8 +7,6 @@ .export popax, incsp2 .importzp c_sp - .macpack cpu - ; Pop a/x from stack. This function will run directly into incsp2 .proc popax @@ -16,7 +14,7 @@ ldy #1 lda (c_sp),y ; get hi byte tax ; into x -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 6c187f32d..6991e4a7e 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - ; EAX = TOS + EAX tosadd0ax: @@ -19,7 +17,7 @@ tosadd0ax: tosaddeax: clc -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/laddeq.s b/libsrc/runtime/laddeq.s index 57bec0629..e5afac9cc 100644 --- a/libsrc/runtime/laddeq.s +++ b/libsrc/runtime/laddeq.s @@ -11,8 +11,6 @@ .export laddeq1, laddeqa, laddeq .importzp sreg, ptr1, tmp1 - .macpack cpu - laddeq1: lda #$01 @@ -24,7 +22,7 @@ laddeqa: laddeq: sty ptr1+1 ; Store high byte of address clc -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (ptr1) sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 400fede3b..2ad4ae4d7 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosand0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosand0ax: .endif tosandeax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index a808f6f84..5fbde5b62 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -7,8 +7,6 @@ .export ldau00sp, ldau0ysp .importzp c_sp, ptr1 - .macpack cpu - ldau00sp: ldy #1 ldau0ysp: @@ -18,7 +16,7 @@ ldau0ysp: lda (c_sp),y sta ptr1 ldx #0 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 408fdd159..afb069b1c 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -14,8 +14,6 @@ .import addysp .importzp c_sp - .macpack cpu - leave00: lda #0 leave0: ldx #0 @@ -28,7 +26,7 @@ leavey0: leavey: jsr addysp ; drop stack frame -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) leave: tay ; save A a sec lda (c_sp) ; that's the pushed arg size diff --git a/libsrc/runtime/lmod.s b/libsrc/runtime/lmod.s index b8e796dea..1cff216f3 100644 --- a/libsrc/runtime/lmod.s +++ b/libsrc/runtime/lmod.s @@ -11,10 +11,8 @@ .import poplsargs, udiv32, negeax .importzp sreg, ptr1, ptr2, tmp1, tmp3, tmp4 - .macpack cpu - tosmod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index a68c3e5c1..7124d6abd 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -9,11 +9,9 @@ .import addysp1 .importzp c_sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 - .macpack cpu - tosmul0ax: tosumul0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosmuleax: tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index 888a0c611..fa87aa63d 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosor0ax: .endif tosoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index 9690aff24..81dde42d3 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -9,8 +9,6 @@ .import incsp4 .importzp c_sp, sreg - .macpack cpu - popeax: ldy #3 lda (c_sp),y sta sreg+1 @@ -20,7 +18,7 @@ popeax: ldy #3 dey lda (c_sp),y tax -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index ec2c865af..fbc37b78c 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -12,13 +12,11 @@ .import decsp4 .importzp c_sp, sreg - .macpack cpu - pushl0: lda #0 tax push0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -39,7 +37,7 @@ pusheax: txa sta (c_sp),y pla -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) .else dey diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 456d8d8d5..b88d44f1a 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -12,10 +12,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosrsub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosrsub0ax: tosrsubeax: sec -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 17b225404..f0d34cd5b 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -11,10 +11,8 @@ .import addysp1 .importzp c_sp, sreg - .macpack cpu - tossub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tossub0ax: tossubeax: sec eor #$FF -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/lsubeq.s b/libsrc/runtime/lsubeq.s index b16ab18e1..d2d4ede7f 100644 --- a/libsrc/runtime/lsubeq.s +++ b/libsrc/runtime/lsubeq.s @@ -11,8 +11,6 @@ .export lsubeq1, lsubeqa, lsubeq .importzp sreg, ptr1 - .macpack cpu - lsubeq1: lda #$01 @@ -25,7 +23,7 @@ lsubeq: sty ptr1+1 ; Store high byte of address sec eor #$FF - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) adc (ptr1) ; Subtract byte 0 sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index b47207222..53651c789 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 - .macpack cpu - tosudiv0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -38,7 +36,7 @@ getlop: sta ptr3 ; Put right operand in place lda sreg+1 sta ptr4+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lumod.s b/libsrc/runtime/lumod.s index eb6176b35..a43c6d287 100644 --- a/libsrc/runtime/lumod.s +++ b/libsrc/runtime/lumod.s @@ -9,10 +9,8 @@ .import getlop, udiv32 .importzp sreg, tmp3, tmp4, ptr2 - .macpack cpu - tosumod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index 6d9f7db3a..abf341e63 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosxor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosxor0ax: .endif tosxoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 04389be5f..09aa93e79 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosora0: ldx #$00 tosorax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index c1700071d..bc490312e 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -7,11 +7,9 @@ .export popa .importzp c_sp - .macpack cpu - .proc popa -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 ; (2) diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 45043dd27..90dca5e22 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, ptr1 - .macpack cpu - .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else lda (c_sp),y ; get lo byte diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index c7f667246..0f6e5701d 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, sreg - .macpack cpu - popsreg: pha ; save A ldy #1 lda (c_sp),y ; get hi byte sta sreg+1 ; store it -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 399423077..6c715afb7 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -7,8 +7,6 @@ .export pusha0sp, pushaysp, pusha .importzp c_sp - .macpack cpu - ; Beware: The optimizer knows about this function! pusha0sp: diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index f77a9bcc3..5177f77b5 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -7,8 +7,6 @@ .export push0, pusha0, pushax .importzp c_sp - .macpack cpu - push0: lda #0 pusha0: ldx #0 @@ -31,7 +29,7 @@ pusha0: ldx #0 sta (c_sp),y ; (27) pla ; (31) dey ; (33) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; (37) .else sta (c_sp),y ; (38) diff --git a/libsrc/runtime/pushb.s b/libsrc/runtime/pushb.s index 7507ff21a..02d91b156 100644 --- a/libsrc/runtime/pushb.s +++ b/libsrc/runtime/pushb.s @@ -8,8 +8,6 @@ .import pushax .importzp ptr1 - .macpack cpu - pushbidx: sty ptr1 clc @@ -19,7 +17,7 @@ pushbidx: pushb: sta ptr1 stx ptr1+1 ldx #0 ; Load index/high byte -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index bacb3c7fc..1eedee53e 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -9,8 +9,6 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - ; ; AX = AX - TOS ; @@ -19,7 +17,7 @@ tosrsuba0: ldx #0 tosrsubax: sec -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/shl.s b/libsrc/runtime/shl.s index c1a4b6ef8..1f11eb5c0 100644 --- a/libsrc/runtime/shl.s +++ b/libsrc/runtime/shl.s @@ -15,8 +15,6 @@ .import popax .importzp tmp1 - .macpack cpu - tosshlax: tosaslax: sta tmp1 ; Save shift count @@ -55,7 +53,7 @@ L2: pla ; Shift count is exactly 8 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) L3: plx ; Low byte from stack into X rts ; A is already zero .else diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index aefed428f..e1542881f 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -9,8 +9,6 @@ .import incsp2 .importzp c_sp, tmp1, ptr1 - .macpack cpu - .proc staxspidx sty tmp1 ; Save Y @@ -18,7 +16,7 @@ ldy #1 lda (c_sp),y sta ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index a7ca39f21..f6ab28ea6 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -21,7 +21,6 @@ ; Use macros for better readability .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- @@ -39,7 +38,7 @@ lda c_sp+1 sta initialsp+1 sbc #>__STACKSIZE__ -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; Add 256 bytes safety area .else add #1 ; Add 256 bytes safety area diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index 58ffb4c91..7129e2147 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp - .macpack cpu - ; AX = TOS - AX tossuba0: @@ -17,7 +15,7 @@ tossuba0: tossubax: sec eor #$FF -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index 3796b0a97..72adaa90b 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -8,8 +8,6 @@ .export swapstk .importzp c_sp, ptr4 - .macpack cpu - swapstk: sta ptr4 stx ptr4+1 @@ -18,7 +16,7 @@ swapstk: tax lda ptr4+1 sta (c_sp),y -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) tay lda ptr4 diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index 2aaa19ccc..e879fe11f 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from long to int by cutting of the high 16bit .proc tosint pha -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index cf8eff031..c8b34d8b0 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -8,8 +8,6 @@ .import decsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from int to long tosulong: @@ -17,7 +15,7 @@ tosulong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else @@ -43,7 +41,7 @@ toslong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else diff --git a/libsrc/runtime/umul8x16r24.s b/libsrc/runtime/umul8x16r24.s index 54d730558..115a3e1a4 100644 --- a/libsrc/runtime/umul8x16r24.s +++ b/libsrc/runtime/umul8x16r24.s @@ -9,8 +9,6 @@ .include "zeropage.inc" - .macpack cpu - ;--------------------------------------------------------------------------- ; 8x16 => 24 unsigned multiplication routine. Because the overhead for a ; 8x16 => 16 unsigned multiplication routine is small, we will tag it with @@ -31,7 +29,7 @@ umul8x16r16: umul8x16r24m: umul8x16r16m: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1+1 stz sreg .else diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index 15394413c..1236b2c37 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosxora0: ldx #$00 tosxorax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ldy #1 .else diff --git a/libsrc/tgi/tgi_settextstyle.s b/libsrc/tgi/tgi_settextstyle.s index b62d6904c..bb924c048 100644 --- a/libsrc/tgi/tgi_settextstyle.s +++ b/libsrc/tgi/tgi_settextstyle.s @@ -9,8 +9,6 @@ .import umul8x16r24 .import popa, popax - .macpack cpu - ;----------------------------------------------------------------------------- ; void __fastcall__ tgi_settextstyle (unsigned width, unsigned height, ; unsigned char dir, unsigned char font); @@ -82,7 +80,7 @@ process_onedim: ; Disallowing characters larger than 256 pixels, we just drop the high byte ; and remember the low 16 bit as size in 8.8 format. -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) phy ; Save Y jsr umul8x16r24 ply ; Restore Y From 59e7158512043a18966ca68531a18ba67791afdb Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:29:42 +0200 Subject: [PATCH 05/11] Make the CPU_xxx constants from cpu.mac internal to the assembler and replace cpu.mac by a file that just emits a warning when used. --- asminc/cpu.mac | 42 ++---------- doc/ca65.sgml | 134 ++++++++++++++++++------------------- libsrc/apple2/cputc.s | 2 - libsrc/apple2/lseek.s | 1 - libsrc/apple2/ser/a2.ssc.s | 1 - libsrc/common/strlen.s | 1 - libsrc/sim6502/exehdr.s | 2 - src/ca65/main.c | 50 ++++++++++++++ 8 files changed, 119 insertions(+), 114 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 15b16bad5..092519173 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -1,38 +1,4 @@ -; CPU bitmask constants (make sure this matches src/common/cpu.h) - -CPU_ISET_NONE = $0001 -CPU_ISET_6502 = $0002 -CPU_ISET_6502X = $0004 -CPU_ISET_6502DTV = $0008 -CPU_ISET_65SC02 = $0010 -CPU_ISET_65C02 = $0020 ; Rockwell extensions -CPU_ISET_65816 = $0040 -CPU_ISET_SWEET16 = $0080 -CPU_ISET_HUC6280 = $0100 -CPU_ISET_M740 = $0200 -CPU_ISET_4510 = $0400 -CPU_ISET_45GS02 = $0800 -CPU_ISET_W65C02 = $1000 ; WDC extensions -CPU_ISET_65CE02 = $2000 ; CSG extensions - -; CPU capabilities -; make sure to only combine the instruction sets that are 100% compatible -CPU_NONE = CPU_ISET_NONE -CPU_6502 = CPU_ISET_6502 -CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502 -CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502 -CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502 -CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 - -; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect -; addressing was replaced with zp-indirect,z-indexed in 652SCE02 - -CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 -CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 -CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510 -CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 -CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02 - -CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_SWEET16 = CPU_ISET_SWEET16 +; This file is no longer needed as the symbols that were defined here are now +; internal symbols generated by the assembler. It is kept to avoid breaking +; old sources. +.warning "'.macpack cpu' is no longer required" diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cfe73a2f0..0f996ff64 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1401,16 +1401,76 @@ writable. Reading this pseudo variable will give a constant integer value that tells which CPU is currently enabled. It can also tell which instruction set the CPU is able to translate. The value read from the pseudo variable - should be further examined by using one of the constants defined by the - "cpu" macro package (see /). + should be further examined by using one of the following constants: - It may be used to replace the .IFPxx pseudo instructions or to construct - even more complex expressions. + + CPU_6502 + CPU_65SC02 + CPU_65C02 + CPU_65816 + CPU_SWEET16 + CPU_HUC6280 + CPU_4510 + CPU_45GS02 + CPU_6502DTV + CPU_M740 + + +Above constants may be used to determine the exact type of the currently +enabled CPU. In addition to that, for each CPU instruction set, another +constant is defined: + + + CPU_ISET_6502 + CPU_ISET_65SC02 + CPU_ISET_65C02 + CPU_ISET_65816 + CPU_ISET_SWEET16 + CPU_ISET_HUC6280 + CPU_ISET_4510 + CPU_ISET_45GS02 + CPU_ISET_6502DTV + CPU_ISET_M740 + + + + + - .macpack cpu .if (.cpu .bitand CPU_ISET_65816) phx phy @@ -1422,7 +1482,6 @@ writable. .endif - See also: @@ -5042,69 +5101,6 @@ This macro package defines a macro named .MACPACK cpu - -This macro package does not define any macros but constants used to examine -the value read from the / pseudo variable. For -each supported CPU a constant similar to - - - CPU_6502 - CPU_65SC02 - CPU_65C02 - CPU_65816 - CPU_SWEET16 - CPU_HUC6280 - CPU_4510 - CPU_45GS02 - CPU_6502DTV - CPU_M740 - - -is defined. These constants may be used to determine the exact type of the -currently enabled CPU. In addition to that, for each CPU instruction set, -another constant is defined: - - - CPU_ISET_6502 - CPU_ISET_65SC02 - CPU_ISET_65C02 - CPU_ISET_65816 - CPU_ISET_SWEET16 - CPU_ISET_HUC6280 - CPU_ISET_4510 - CPU_ISET_45GS02 - CPU_ISET_6502DTV - CPU_ISET_M740 - - -The value read from the / pseudo variable may -be checked with / to determine if the -currently enabled CPU supports a specific instruction set. For example the -65C02 supports all instructions of the 65SC02 CPU, so it has the - - .if (.cpu .bitand CPU_ISET_65SC02) - lda (c_sp) - .else - ldy #$00 - lda (c_sp),y - .endif - - -it is possible to determine if the - - - lda (c_sp) - - -instruction is supported, which is the case for the 65SC02, 65C02 and 65816 -CPUs (the latter two are upwards compatible to the 65SC02). - -see section and following. - .MACPACK module This macro package defines a macro named Date: Tue, 1 Jul 2025 08:34:38 +0200 Subject: [PATCH 06/11] Add an additional hook (currently unused) for target specific capabilities. --- src/ca65/expr.c | 3 ++- src/common/target.c | 10 ++++++++++ src/common/target.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 42b1a369b..33984610d 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -61,6 +61,7 @@ #include "studyexpr.h" #include "symbol.h" #include "symtab.h" +#include "target.h" #include "toklist.h" #include "ulabel.h" #include "macro.h" @@ -445,7 +446,7 @@ static ExprNode* FuncCapability (void) /* The pseudo function result is the logical AND of all capabilities ** given. */ - if (!CPUHasCap (Cap)) { + if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) { Result = 0; } } diff --git a/src/common/target.c b/src/common/target.c index a12f69bf9..bb67ddf9a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -37,6 +37,7 @@ #include /* common */ +#include "attrib.h" #include "chartype.h" #include "check.h" #include "target.h" @@ -302,3 +303,12 @@ const char* GetTargetName (target_t Target) /* Return the array entry */ return GetTargetProperties (Target)->Name; } + + + +int TargetHasCap (capability_t Cap attribute((unused))) +/* Check if the current target has the given capability */ +{ + /* Currently unused */ + return 0; +} diff --git a/src/common/target.h b/src/common/target.h index c5c8455a0..1dfa66ac7 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -39,6 +39,7 @@ /* common */ +#include "capability.h" #include "cpu.h" @@ -131,6 +132,9 @@ const TargetProperties* GetTargetProperties (target_t Target); const char* GetTargetName (target_t Target); /* Return the name of a target */ +int TargetHasCap (capability_t Cap); +/* Check if the current target has the given capability */ + /* End of target.h */ From 8d3112e24f93053bf8cd92ca5aa54d2f55339821 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:47:16 +0200 Subject: [PATCH 07/11] Small code simplification. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index d8c0dbd37..2f239d99d 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -233,5 +233,5 @@ int CPUHasCap (capability_t Cap) /* Check if the current CPU has the given capability */ { PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); - return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; + return (CPUCaps[CPU] & CAP_BIT (Cap)) != 0; } From c162f6a28636cd9cb04f5812532e53f87922b5f5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:21:18 +0200 Subject: [PATCH 08/11] Warning fix. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2f239d99d..7988cb4c1 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -151,7 +151,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ -static const uint64_t CPUCaps[CPU_COUNT] = { +static const uint32_t CPUCaps[CPU_COUNT] = { CAP_NONE, /* CPU_NONE */ CAP_6502, /* CPU_6502 */ CAP_6502X, /* CPU_6502X */ From 37414199c7f511eeee21a23bc0c1d184871fe92b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:33:38 +0200 Subject: [PATCH 09/11] Hopefully fix windows build files. --- src/common.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.vcxproj b/src/common.vcxproj index 6098c98a0..251ea3aeb 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -80,6 +80,7 @@ + @@ -133,6 +134,7 @@ + @@ -171,4 +173,4 @@ - \ No newline at end of file + From 60ec9045fce2c30aa4a24e46c59daaaccfab283a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:02:15 +0200 Subject: [PATCH 10/11] Use CPUIsets from cpu.c instead of recreating the CPU_xxx constants. --- src/ca65/main.c | 36 ++++++++++++++---------------------- src/common/cpu.c | 16 ++++++++++++++-- src/common/cpu.h | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fb0907df3..e9b36ee5d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -213,28 +213,20 @@ static void DefineCpuSymbols (void) /* Additional ones from cpu.mac. Not sure how useful they are after the ** changes from #2751. */ - NewSymbol ("CPU_NONE", CPU_ISET_NONE); - NewSymbol ("CPU_6502", CPU_ISET_6502); - NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); - NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); - NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); - NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | - CPU_ISET_65C02); - - /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the - ** zp-indirect addressing was replaced with zp-indirect,z-indexed in - ** 652SCE02 - */ - NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02); - NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02 | CPU_ISET_4510); - NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); - NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]); + NewSymbol ("CPU_6502", CPUIsets[CPU_6502]); + NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]); + NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]); + NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]); + NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]); + NewSymbol ("CPU_65816", CPUIsets[CPU_65816]); + NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]); + NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]); + NewSymbol ("CPU_M740", CPUIsets[CPU_M740]); + NewSymbol ("CPU_4510", CPUIsets[CPU_4510]); + NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]); + NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]); + NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]); } diff --git a/src/common/cpu.c b/src/common/cpu.c index 7988cb4c1..8e9ff827a 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -74,21 +74,33 @@ const char* CPUNames[CPU_COUNT] = { * NOTE: make sure to only combine the instruction sets that are 100% compatible */ const unsigned CPUIsets[CPU_COUNT] = { + /* CPU_NONE */ CPU_ISET_NONE, + /* CPU_6502 */ CPU_ISET_6502, + /* CPU_6502X */ CPU_ISET_6502X | CPU_ISET_6502, + /* CPU_6502DTV */ CPU_ISET_6502DTV | CPU_ISET_6502, + /* CPU_65SC02 */ CPU_ISET_65SC02 | CPU_ISET_6502, + /* CPU_65C02 */ CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* 65816 has wai/stp and NO bit manipulation */ + /* CPU_65816. 65816 has wai/stp and NO bit manipulation. */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* CPU_SWEET16 */ CPU_ISET_SWEET16, + /* CPU_HUC6280 */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_M740 */ CPU_ISET_M740 | CPU_ISET_6502, - /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* CPU_4510. 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + /* CPU_45GS02 */ CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, + /* CPU_W65C02 */ CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_65CE02 */ CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 0a7c853ac..bc6260371 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -69,7 +69,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ +/* CPU instruction sets */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From 070276a1a3baa9fbfca42555b306e0d9caac8436 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:19:19 +0200 Subject: [PATCH 11/11] Add a better description for CPU_HAS_ZPIND and CPU_HAS_STZ. --- doc/ca65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0f996ff64..63a1be7e9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1681,10 +1681,12 @@ either a string or an expression value. Checks for the capability to push and pop the X and Y registers. CPU_HAS_ZPIND - Checks for the availability of the "zeropage indirect" addressing mode. + Checks for the availability of the "zeropage indirect" addressing mode as it + is implemented in the 65SC02 CPU. CPU_HAS_STZ - Checks for the availability of the "store zero" instruction. + Checks for the availability of the "store zero" instruction as it is + implemented in the 65SC02 CPU.
Reading this pseudo variable will return the current size of the Index @@ -1594,6 +1598,56 @@ either a string or an expression value. +.CAP, .CAPABILITY + + Builtin function. The function allows to check for capabilities of the + currently selected CPU or target system. It must be called with a comma + separated list of identifiers and returns non zero if all of the given + capabilities are available. Otherwise it returns zero. + + Existing capabilities are: + + + + CPU_HAS_BRA8 + Checks for the availability of a short (8 bit) branch. + + CPU_HAS_INA + Checks for the availability of accu inc/dec instructions. + + CPU_HAS_PUSHXY + Checks for the capability to push and pop the X and Y registers. + + CPU_HAS_ZPIND + Checks for the availability of the "zeropage indirect" addressing mode. + + CPU_HAS_STZ + Checks for the availability of the "store zero" instruction. + + + + Case is ignored when checking the identifiers. The + .if .cap(CPU_HAS_BRA, CPU_HAS_PUSHXY) + phx + bra L1 + .else + txa + pha + jmp L1 + .endif + + + See also: + + + .CONCAT Builtin string function. The function allows to concatenate a list of string diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 5dcf5ca71..42b1a369b 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -37,6 +37,7 @@ #include /* common */ +#include "capability.h" #include "check.h" #include "cpu.h" #include "exprdefs.h" @@ -405,6 +406,66 @@ static ExprNode* FuncBlank (void) +static ExprNode* FuncCapability (void) +/* Handle the .CAPABILITY builtin function */ +{ + int Result = 1; + + /* What follows is a comma separated list of identifiers. An empty list is + ** not allowed. + */ + while (1) { + + const char* Name; + capability_t Cap; + + /* We must have an identifier */ + if (CurTok.Tok != TOK_IDENT) { + Error ("Arguments to .CAPABILITY must be identifiers"); + /* Skip tokens until closing paren or end of line */ + while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) { + NextTok (); + } + return GenLiteral0 (); + } + + /* Search for the capability that matches this identifier. Ignore case + ** on the specified capabilities. + */ + UpcaseSVal (); + SB_Terminate (&CurTok.SVal); + Name = SB_GetConstBuf (&CurTok.SVal); + Cap = FindCapability (Name); + + /* Check if the capability is supported */ + if (Cap == CAP_INVALID) { + Error ("Not a valid capability name: %s", Name); + Result = 0; + } else { + /* The pseudo function result is the logical AND of all capabilities + ** given. + */ + if (!CPUHasCap (Cap)) { + Result = 0; + } + } + + /* Skip the capability name */ + NextTok (); + + /* Handle end of list or next capability */ + if (CurTok.Tok != TOK_COMMA) { + break; + } + NextTok (); + } + + /* Done */ + return GenLiteralExpr (Result); +} + + + static ExprNode* FuncConst (void) /* Handle the .CONST builtin function */ { @@ -484,9 +545,10 @@ static ExprNode* FuncIsMnemonic (void) if (FindMacro (&CurTok.SVal) == 0) { Instr = FindInstruction (&CurTok.SVal); } - } - else { - /* Macros and symbols may NOT use the names of instructions, so just check for the instruction */ + } else { + /* Macros and symbols may NOT use the names of instructions, so + ** just check for the instruction. + */ Instr = FindInstruction (&CurTok.SVal); } } @@ -532,7 +594,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) token_t Term = GetTokListTerm (TOK_COMMA); while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -570,7 +632,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) Node = Root; while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -1129,6 +1191,10 @@ static ExprNode* Factor (void) N = Function (FuncBlank); break; + case TOK_CAP: + N = Function (FuncCapability); + break; + case TOK_CONST: N = Function (FuncConst); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index e6e10df2c..301129583 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -2114,7 +2114,8 @@ struct CtrlDesc { }; /* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR - and .XOR do NOT go into this table */ +** and .XOR do NOT go into this table. +*/ #define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0])) static CtrlDesc CtrlCmdTab [] = { { ccNone, DoA16 }, /* .A16 */ @@ -2132,6 +2133,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .BLANK */ { ccNone, DoBss }, /* .BSS */ { ccNone, DoByte }, /* .BYT, .BYTE */ + { ccNone, DoUnexpected }, /* .CAP */ { ccNone, DoCase }, /* .CASE */ { ccNone, DoCharMap }, /* .CHARMAP */ { ccNone, DoCode }, /* .CODE */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f3892d32e..a2a72a149 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -158,6 +158,8 @@ struct DotKeyword { { ".BSS", TOK_BSS }, { ".BYT", TOK_BYTE }, { ".BYTE", TOK_BYTE }, + { ".CAP", TOK_CAP }, + { ".CAPABILITY", TOK_CAP }, { ".CASE", TOK_CASE }, { ".CHARMAP", TOK_CHARMAP }, { ".CODE", TOK_CODE }, diff --git a/src/ca65/token.h b/src/ca65/token.h index e2b223880..b40534d79 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -137,6 +137,7 @@ typedef enum token_t { TOK_BLANK, TOK_BSS, TOK_BYTE, + TOK_CAP, TOK_CASE, TOK_CHARMAP, TOK_CODE, diff --git a/src/common/capability.c b/src/common/capability.c new file mode 100644 index 000000000..f66205e7c --- /dev/null +++ b/src/common/capability.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* capability.c */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include + +/* ca65 */ +#include "capability.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* List of dot keywords with the corresponding ids. */ +/* CAUTION: table must be sorted for bsearch. */ +struct Capability { + const char* Key; + capability_t Cap; +} Capabilities [] = { +/* BEGIN SORTED.SH */ + { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, + { "CPU_HAS_INA", CAP_CPU_HAS_INA }, + { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, + { "CPU_HAS_STZ", CAP_CPU_HAS_STZ }, + { "CPU_HAS_ZPIND", CAP_CPU_HAS_ZPIND }, +/* END SORTED.SH */ +}; +#define CAP_TABLE_SIZE (sizeof (Capabilities) / sizeof (Capabilities [0])) + + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static int CmpCapability (const void* K1, const void* K2) +/* Compare function for the capability search */ +{ + return strcmp (((struct Capability*)K1)->Key, ((struct Capability*)K2)->Key); +} + + + +capability_t FindCapability (const char* Name) +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ +{ + const struct Capability K = { Name, 0 }; + const struct Capability* C = bsearch (&K, Capabilities, CAP_TABLE_SIZE, + sizeof (Capabilities [0]), + CmpCapability); + return (C == 0)? CAP_INVALID : C->Cap; +} diff --git a/src/common/capability.h b/src/common/capability.h new file mode 100644 index 000000000..011e2164f --- /dev/null +++ b/src/common/capability.h @@ -0,0 +1,78 @@ +/*****************************************************************************/ +/* */ +/* capability.h */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef CAPABILITY_H +#define CAPABILITY_H + + + +/* common */ +#include "strbuf.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Numeric codes for capabilities */ +enum capability_t { + CAP_INVALID = -1, + CAP_CPU_HAS_BRA8 = 0, /* CPU has a BRA 8-bit instruction */ + CAP_CPU_HAS_INA = 1, /* CPU has DEA/INA */ + CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ + CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ + CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ +}; +typedef enum capability_t capability_t; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +capability_t FindCapability (const char* Name); +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ + + + +/* End of capability.h */ + +#endif diff --git a/src/common/cpu.c b/src/common/cpu.c index 252283211..cdc8e52cc 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -33,6 +33,8 @@ +#include + /* common */ #include "addrsize.h" #include "check.h" @@ -90,6 +92,77 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; +/* Defines for capabilities. Currently the entries are uint32_ts but the table +** is deliberately hidden from the outside so it can be extended to 64 bit or +** even more. +*/ +#define CAP_NONE UINT32_C (0) +#define CAP_6502 UINT32_C (0) +#define CAP_6502X UINT32_C (0) +#define CAP_6502DTV UINT32_C (0) +#define CAP_65SC02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65816 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 UINT32_C (0) +#define CAP_HUC6280 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_M740 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA)) +#define CAP_4510 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_45GS02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_W65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_65CE02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + +/* Table containing one capability entry per CPU */ +static const uint64_t CPUCaps[CPU_COUNT] = { + CAP_NONE, /* CPU_NONE */ + CAP_6502, /* CPU_6502 */ + CAP_6502X, /* CPU_6502X */ + CAP_6502DTV, /* CPU_6502DTV */ + CAP_65SC02, /* CPU_65SC02 */ + CAP_65C02, /* CPU_65C02 */ + CAP_65816, /* CPU_65816 */ + CAP_SWEET16, /* CPU_SWEET16 */ + CAP_HUC6280, /* CPU_HUC6280 */ + CAP_M740, /* CPU_M740 */ + CAP_4510, /* CPU_4510 */ + CAP_45GS02, /* CPU_45GS02 */ + CAP_W65C02, /* CPU_W65C02 */ + CAP_65CE02, /* CPU_65CE02 */ +}; + /*****************************************************************************/ @@ -148,3 +221,12 @@ cpu_t FindCPU (const char* Name) /* Not found */ return CPU_UNKNOWN; } + + + +int CPUHasCap (capability_t Cap) +/* Check if the current CPU has the given capability */ +{ + PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); + return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; +} diff --git a/src/common/cpu.h b/src/common/cpu.h index 4202ed573..0a7c853ac 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -38,6 +38,11 @@ +/* common */ +#include "capability.h" + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -107,6 +112,9 @@ cpu_t FindCPU (const char* Name); ** the given name is no valid target. */ +int CPUHasCap (capability_t Cap); +/* Check if the current CPU has the given capability */ + /* End of cpu.h */ diff --git a/test/asm/listing/110-capabilities.s b/test/asm/listing/110-capabilities.s new file mode 100644 index 000000000..e3e306ca7 --- /dev/null +++ b/test/asm/listing/110-capabilities.s @@ -0,0 +1,39 @@ + +; Error: Arguments to .CAPABILITY must be identifiers +.if .cap() +.endif + +; Error: Arguments to .CAPABILITY must be identifiers +; Error: ')' expected +.if .cap( +.endif + +; Error: Not a valid capability name: CPU_HAS_BR +.if .cap(cpu_has_br) +.endif + +; Error: ')' expected +; Error: Unexpected trailing garbage characters +.if .cap(cpu_has_bra8 cpu_has_bra8) +.endif + +; Ok +.if .cap(cpu_has_bra8, CPU_HAS_PUSHXY, CPU_HAS_STZ, CPU_HAS_INA) +.endif + +.setcpu "65SC02" +.if !.cap(cpu_has_bra8) +.error "Assembler says 65SC02 has no 8 bit bra" +.endif +.if !.cap(cpu_has_PUSHXY) +.error "Assembler says 65SC02 has no phx" +.endif +.if !.cap(cpu_has_STZ) +.error "Assembler says 65SC02 has no stz" +.endif +.if !.cap(cpu_has_INA) +.error "Assembler says 65SC02 has no ina" +.endif + + + diff --git a/test/asm/listing/control/110-capabilities.err b/test/asm/listing/control/110-capabilities.err new file mode 100644 index 000000000..e69de29bb diff --git a/test/asm/listing/ref/110-capabilities.err2-ref b/test/asm/listing/ref/110-capabilities.err2-ref new file mode 100644 index 000000000..e00e60e17 --- /dev/null +++ b/test/asm/listing/ref/110-capabilities.err2-ref @@ -0,0 +1,6 @@ +110-capabilities.s:3: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: ')' expected +110-capabilities.s:12: Error: Not a valid capability name: CPU_HAS_BR +110-capabilities.s:17: Error: ')' expected +110-capabilities.s:17: Error: Unexpected trailing garbage characters From f333b300f1c542b952580420259f6d79db7977f1 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:16:33 +0200 Subject: [PATCH 03/11] Added the CPU_HAS_BITIMM capability. --- doc/ca65.sgml | 3 ++ src/common/capability.c | 1 + src/common/capability.h | 1 + src/common/cpu.c | 81 ++++++++++++++++++++++------------------- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 552309ff9..cfe73a2f0 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1609,6 +1609,9 @@ either a string or an expression value. + CPU_HAS_BITIMM + Checks for the availability of the "bit #imm" instruction. + CPU_HAS_BRA8 Checks for the availability of a short (8 bit) branch. diff --git a/src/common/capability.c b/src/common/capability.c index f66205e7c..19c3ed838 100644 --- a/src/common/capability.c +++ b/src/common/capability.c @@ -50,6 +50,7 @@ struct Capability { capability_t Cap; } Capabilities [] = { /* BEGIN SORTED.SH */ + { "CPU_HAS_BITIMM", CAP_CPU_HAS_BITIMM }, { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, { "CPU_HAS_INA", CAP_CPU_HAS_INA }, { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, diff --git a/src/common/capability.h b/src/common/capability.h index 011e2164f..b0332c72e 100644 --- a/src/common/capability.h +++ b/src/common/capability.h @@ -54,6 +54,7 @@ enum capability_t { CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ + CAP_CPU_HAS_BITIMM = 5, /* CPU has "bit #imm" instruction */ }; typedef enum capability_t capability_t; diff --git a/src/common/cpu.c b/src/common/cpu.c index cdc8e52cc..d8c0dbd37 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -96,54 +96,59 @@ const unsigned CPUIsets[CPU_COUNT] = { ** is deliberately hidden from the outside so it can be extended to 64 bit or ** even more. */ +#define CAP_BIT(Cap) (UINT32_C (1) << (Cap)) #define CAP_NONE UINT32_C (0) -#define CAP_6502 UINT32_C (0) -#define CAP_6502X UINT32_C (0) -#define CAP_6502DTV UINT32_C (0) +#define CAP_6502 CAP_NONE +#define CAP_6502X CAP_NONE +#define CAP_6502DTV CAP_NONE #define CAP_65SC02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65816 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) -#define CAP_SWEET16 UINT32_C (0) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 CAP_NONE #define CAP_HUC6280 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_M740 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA)) #define CAP_4510 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_45GS02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_W65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_65CE02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ static const uint64_t CPUCaps[CPU_COUNT] = { From c72126e68fc879229b677baf6443ed242b0262f7 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:25:32 +0200 Subject: [PATCH 04/11] Changed most of the library sources to use .CAP instead of .CPU. --- libsrc/cbm/clock.s | 3 +- libsrc/common/_directerrno.s | 4 +- libsrc/common/_heapblocksize.s | 3 +- libsrc/common/_mappederrno.s | 3 +- libsrc/common/_printf.s | 11 ++--- libsrc/common/_time_t_to_tm.s | 4 +- libsrc/common/asctime.s | 6 +-- libsrc/common/atexit.s | 10 ++-- libsrc/common/fgetc.s | 4 +- libsrc/common/fgets.s | 8 ++-- libsrc/common/fread.s | 15 +++--- libsrc/common/fwrite.s | 6 +-- libsrc/common/ltoa.s | 4 +- libsrc/common/strcat.s | 3 +- libsrc/common/strchr.s | 3 +- libsrc/common/strdup.s | 4 +- libsrc/common/strncat.s | 83 +++++++++++++++++----------------- libsrc/conio/cputs.s | 5 +- libsrc/conio/scrsize.s | 4 +- libsrc/conio/vcprintf.s | 3 +- libsrc/runtime/add.s | 4 +- libsrc/runtime/and.s | 4 +- libsrc/runtime/condes.s | 2 - libsrc/runtime/incax1.s | 3 +- libsrc/runtime/incsp2.s | 4 +- libsrc/runtime/ladd.s | 4 +- libsrc/runtime/laddeq.s | 4 +- libsrc/runtime/land.s | 6 +-- libsrc/runtime/ldau0sp.s | 4 +- libsrc/runtime/leave.s | 4 +- libsrc/runtime/lmod.s | 4 +- libsrc/runtime/lmul.s | 6 +-- libsrc/runtime/lor.s | 6 +-- libsrc/runtime/lpop.s | 4 +- libsrc/runtime/lpush.s | 6 +-- libsrc/runtime/lrsub.s | 6 +-- libsrc/runtime/lsub.s | 6 +-- libsrc/runtime/lsubeq.s | 4 +- libsrc/runtime/ludiv.s | 6 +-- libsrc/runtime/lumod.s | 4 +- libsrc/runtime/lxor.s | 6 +-- libsrc/runtime/or.s | 4 +- libsrc/runtime/popa.s | 4 +- libsrc/runtime/popptr1.s | 4 +- libsrc/runtime/popsreg.s | 4 +- libsrc/runtime/pusha.s | 2 - libsrc/runtime/pushax.s | 4 +- libsrc/runtime/pushb.s | 4 +- libsrc/runtime/rsub.s | 4 +- libsrc/runtime/shl.s | 4 +- libsrc/runtime/staxspi.s | 4 +- libsrc/runtime/stkchk.s | 3 +- libsrc/runtime/sub.s | 4 +- libsrc/runtime/swap.s | 4 +- libsrc/runtime/tosint.s | 4 +- libsrc/runtime/toslong.s | 6 +-- libsrc/runtime/umul8x16r24.s | 4 +- libsrc/runtime/xor.s | 4 +- libsrc/tgi/tgi_settextstyle.s | 4 +- 59 files changed, 122 insertions(+), 232 deletions(-) diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index 90e4263a8..91fde6f58 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -9,14 +9,13 @@ .importzp sreg .include "cbm.inc" - .macpack cpu .proc _clock ; Some accelerator adaptors have CMOS ICs. -.if (.cpu & ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg + 1 .else lda #$00 ; Byte 3 always is zero diff --git a/libsrc/common/_directerrno.s b/libsrc/common/_directerrno.s index 20060bdd7..74e2f89cd 100644 --- a/libsrc/common/_directerrno.s +++ b/libsrc/common/_directerrno.s @@ -7,8 +7,6 @@ .include "errno.inc" - .macpack cpu - ; ---------------------------------------------------------------------------- ; int __fastcall__ __directerrno (unsigned char code); ; /* Set errno to a specific error code, clear __oserror, and return -1. Used @@ -18,7 +16,7 @@ ___directerrno: jsr ___seterrno ; Set errno (returns with .A = 0) sta ___oserror ; Clear ___oserror -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 diff --git a/libsrc/common/_heapblocksize.s b/libsrc/common/_heapblocksize.s index e9b0cdad9..774056032 100644 --- a/libsrc/common/_heapblocksize.s +++ b/libsrc/common/_heapblocksize.s @@ -12,7 +12,6 @@ .include "_heap.inc" .macpack generic - .macpack cpu ;----------------------------------------------------------------------------- ; Code @@ -39,7 +38,7 @@ ___heapblocksize: ldy #usedblock::size+1 lda (ptr2),y tax -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr2) .else dey diff --git a/libsrc/common/_mappederrno.s b/libsrc/common/_mappederrno.s index 83565b723..4ea3174b6 100644 --- a/libsrc/common/_mappederrno.s +++ b/libsrc/common/_mappederrno.s @@ -8,7 +8,6 @@ .include "errno.inc" .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; int __fastcall__ __mappederrno (unsigned char code); @@ -24,7 +23,7 @@ ___mappederrno: bze ok ; Branch if no jsr ___osmaperrno ; Map OS error into errno code jsr ___seterrno ; Save in errno (returns with .A = 0) -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 if error diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index 40ab0bc64..335485cc6 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -13,7 +13,6 @@ .import _strlower, _strlen .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; We will store variables into the register bank in the zeropage. Define @@ -38,7 +37,7 @@ FCount = ptr2 GetFormatChar: ldy #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (Format) .else lda (Format),y @@ -115,7 +114,7 @@ GetIntArg: lda (ArgList),y tax dey - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (ArgList) .else lda (ArgList),y @@ -274,7 +273,7 @@ Save: lda regbank,y ; Initialize the output counter in the output descriptor to zero lda #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (OutData) ldy #$01 sta (OutData),y @@ -353,7 +352,7 @@ MainLoop: sta (c_sp),y dey lda FCount - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (c_sp) .else sta (c_sp),y @@ -570,7 +569,7 @@ CheckCount: jsr GetIntArg sta ptr1 stx ptr1+1 ; Get user supplied pointer - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (OutData) ; Low byte of OutData->ccount sta (ptr1) ldy #1 diff --git a/libsrc/common/_time_t_to_tm.s b/libsrc/common/_time_t_to_tm.s index 9bcf84184..21e662384 100644 --- a/libsrc/common/_time_t_to_tm.s +++ b/libsrc/common/_time_t_to_tm.s @@ -16,8 +16,6 @@ .include "time.inc" - .macpack cpu - __time_t_to_tm: ; Divide number of seconds since epoch, in ptr1:sreg, ; by 86400 to get the number of days since epoch, and @@ -80,7 +78,7 @@ __time_t_to_tm: ; Zero the two high bytes of the divisor and the high byte ; of the dividend. - .if .cpu .bitand CPU_ISET_65SC02 + .if .cap(CPU_HAS_STZ) stz ptr4 stz ptr4+1 stz sreg+1 diff --git a/libsrc/common/asctime.s b/libsrc/common/asctime.s index efcf34b41..b56371594 100644 --- a/libsrc/common/asctime.s +++ b/libsrc/common/asctime.s @@ -9,8 +9,6 @@ .importzp ptr1 .include "time.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Special values @@ -24,7 +22,7 @@ MAX_BUF_LEN = 38 _asctime: ; Backup timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) pha phx .else @@ -48,7 +46,7 @@ _asctime: jsr pushax ; Restore timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) plx pla .else diff --git a/libsrc/common/atexit.s b/libsrc/common/atexit.s index 47a1dfd4d..ccbc2e69f 100644 --- a/libsrc/common/atexit.s +++ b/libsrc/common/atexit.s @@ -10,8 +10,6 @@ .include "errno.inc" - .macpack cpu - ; --------------------------------------------------------------------------- .proc _atexit @@ -41,7 +39,7 @@ jsr ___seterrno ldx #$FF ; Return -1 txa - rts +Exit: rts .endproc @@ -54,7 +52,7 @@ .proc doatexit ldy exitfunc_index ; Get index - beq @L9 ; Jump if done + beq _atexit::Exit ; Jump if done dey lda exitfunc_table,y tax @@ -62,14 +60,12 @@ lda exitfunc_table,y sty exitfunc_index jsr callax ; Call the function -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra doatexit .else jmp doatexit ; Next one .endif -@L9: rts - .endproc diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s index 34d4df3aa..6d08f69a3 100644 --- a/libsrc/common/fgetc.s +++ b/libsrc/common/fgetc.s @@ -12,8 +12,6 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - _fgetc: sta ptr1 stx ptr1+1 @@ -22,7 +20,7 @@ _fgetc: jsr checkferror bne ret_eof - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FPUSHBACK ; Check for pushed back char beq do_read .else diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index c25664f19..fde3a78a9 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -14,12 +14,10 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - terminate_ptr: lda #$00 tax - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else tay @@ -41,7 +39,7 @@ _fgets: sta buf stx buf+1 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_STZ) stz didread .else lda #$00 ; We have read nothing yet @@ -79,7 +77,7 @@ read_loop: ldy #$01 sty didread ; We read at least one char - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else dey diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index be06c2a62..beb9e707e 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -20,7 +20,6 @@ .include "_file.inc" .macpack generic - .macpack cpu ; ------------------------------------------------------------------------ ; Code @@ -48,7 +47,7 @@ ldy #_FILE::f_flags lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN ; Is the file open? .else and #_FOPEN ; Is the file open? @@ -57,7 +56,7 @@ ; Check if the stream is in an error state - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FERROR .else lda (file),y ; get file->f_flags again @@ -74,17 +73,15 @@ ; Remember if we have a pushed back character and reset the flag. -@L2: .if (.cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .cap(CPU_HAS_BITIMM) ldx #$00 bit #_FPUSHBACK + beq @L3 .else tax ; X = 0 lda (file),y and #_FPUSHBACK - .endif beq @L3 - - .if (.not .cpu .bitand ::CPU_ISET_65SC02) lda (file),y .endif and #<~_FPUSHBACK @@ -135,7 +132,7 @@ ; Copy the buffer pointer into ptr1, and increment the pointer value passed ; to read() by one, so read() starts to store data at buf+1. - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (c_sp) sta ptr1 add #1 @@ -159,7 +156,7 @@ ldy #_FILE::f_pushback lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr1) ; *buf = file->f_pushback; .else ldy #0 diff --git a/libsrc/common/fwrite.s b/libsrc/common/fwrite.s index e7151da95..6f631b816 100644 --- a/libsrc/common/fwrite.s +++ b/libsrc/common/fwrite.s @@ -16,8 +16,6 @@ .include "errno.inc" .include "_file.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Code @@ -34,7 +32,7 @@ ldy #_FILE::f_flags lda (ptr1),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN .else and #_FOPEN ; Is the file open? @@ -50,7 +48,7 @@ ; Check if the stream is in an error state -@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .not .cap(CPU_HAS_BITIMM) lda (ptr1),y ; get file->f_flags again .endif and #_FERROR diff --git a/libsrc/common/ltoa.s b/libsrc/common/ltoa.s index 78e43e23f..7c31d471f 100644 --- a/libsrc/common/ltoa.s +++ b/libsrc/common/ltoa.s @@ -10,8 +10,6 @@ .import __hextab, __longminstr .importzp sreg, ptr1, ptr2, ptr3, tmp1 - .macpack cpu - .code ; @@ -64,7 +62,7 @@ L2: txa ; get high byte bpl ultoa lda #'-' -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) .else ldy #0 diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index f9cd94633..963b037b9 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -8,7 +8,6 @@ .export _strcat .import popax .importzp ptr1, ptr2, tmp3 - .macpack cpu _strcat: sta ptr1 ; Save src @@ -16,7 +15,7 @@ _strcat: jsr popax ; Get dest sta tmp3 ; Remember for function return tay -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr2 .else lda #0 diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 206b5160e..ac7f5397a 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -8,14 +8,13 @@ .export _strchr .import popax .importzp ptr1, tmp1 - .macpack cpu _strchr: sta tmp1 ; Save c jsr popax ; get s tay ; low byte of pointer to y stx ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1 .else lda #0 diff --git a/libsrc/common/strdup.s b/libsrc/common/strdup.s index 94f2cd338..4cf643614 100644 --- a/libsrc/common/strdup.s +++ b/libsrc/common/strdup.s @@ -12,8 +12,6 @@ .import _strlen_ptr4, _malloc, _memcpy, pushax .export _strdup - .macpack cpu - _strdup: ; Get length (and store source in ptr4) sta ptr4 @@ -22,7 +20,7 @@ _strdup: jsr _strlen_ptr4 ; strlen may increment ; Add null byte for terminator -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) inc a .else clc diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index 75572db7c..e4e321591 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -8,64 +8,63 @@ .export _strncat .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1, tmp2 -.macpack cpu _strncat: - inx - stx tmp2 - tax - inx - stx tmp1 ; save count with each byte incremented separately + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately - jsr popptr1 ; get src + jsr popptr1 ; get src - jsr popax ; get dest - sta ptr3 ; remember for function return - stx ptr3+1 - stx ptr2+1 - tay ; low byte as offset in Y -.if (.cpu .bitand ::CPU_ISET_65SC02) - stz ptr2 + jsr popax ; get dest + sta ptr3 ; remember for function return + stx ptr3+1 + stx ptr2+1 + tay ; low byte as offset in Y +.if .cap(CPU_HAS_STZ) + stz ptr2 .else - ldx #0 - stx ptr2 ; destination on page boundary + ldx #0 + stx ptr2 ; destination on page boundary .endif ; find end of dest -L1: lda (ptr2),y - beq L2 - iny - bne L1 - inc ptr2+1 - bne L1 +L1: lda (ptr2),y + beq L2 + iny + bne L1 + inc ptr2+1 + bne L1 ; end found, apply offset to dest ptr and reset y -L2: sty ptr2 +L2: sty ptr2 ; copy src. We've put the ones complement of the count into the counter, so ; we'll increment the counter on top of the loop -L3: ldy #0 - ldx tmp1 ; low counter byte +L3: ldy #0 + ldx tmp1 ; low counter byte -L4: dex - bne L5 - dec tmp2 - beq L6 ; jump if done -L5: lda (ptr1),y - sta (ptr2),y - beq L7 - iny - bne L4 - inc ptr1+1 - inc ptr2+1 - bne L4 +L4: dex + bne L5 + dec tmp2 + beq L6 ; jump if done +L5: lda (ptr1),y + sta (ptr2),y + beq L7 + iny + bne L4 + inc ptr1+1 + inc ptr2+1 + bne L4 ; done, set the trailing zero and return pointer to dest -L6: lda #0 - sta (ptr2),y -L7: lda ptr3 - ldx ptr3+1 - rts +L6: lda #0 + sta (ptr2),y +L7: lda ptr3 + ldx ptr3+1 + rts diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index b822fddee..d6024c0e5 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -8,13 +8,12 @@ .export _cputsxy, _cputs .import gotoxy, _cputc .importzp ptr1, tmp1 - .macpack cpu _cputsxy: sta ptr1 ; Save s for later stx ptr1+1 jsr gotoxy ; Set cursor, pop x and y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra L0 ; Same as cputs... .else jmp L0 ; Same as cputs... @@ -24,7 +23,7 @@ _cputs: sta ptr1 ; Save s stx ptr1+1 L0: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; (5) .else ldy #0 ; (2) diff --git a/libsrc/conio/scrsize.s b/libsrc/conio/scrsize.s index 834c14820..fc1691b87 100644 --- a/libsrc/conio/scrsize.s +++ b/libsrc/conio/scrsize.s @@ -10,8 +10,6 @@ .import screensize .importzp ptr1, ptr2 - .macpack cpu - .proc _screensize sta ptr2 ; Store the y pointer @@ -20,7 +18,7 @@ jsr screensize ; Get screensize into X/Y tya ; Get Y size into A -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) txa sta (ptr1) diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index c6371f00e..aa7b6aa07 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -10,7 +10,6 @@ .importzp c_sp, ptr1, ptr2, ptr3, tmp1 .macpack generic - .macpack cpu .data @@ -74,7 +73,7 @@ out: jsr popax ; count ; Loop outputting characters -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND, CPU_HAS_BRA8) @L1: dec outdesc+6 beq @L4 diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index 85ddd0f25..b841f829d 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -11,14 +11,12 @@ .export tosadda0, tosaddax .importzp c_sp, tmp1 - .macpack cpu - tosadda0: ldx #0 tosaddax: clc ; (2) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; (7) tay ; (9) diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 8411660ab..303d4e010 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -8,12 +8,10 @@ .import addysp1 .importzp c_sp, ptr4 - .macpack cpu - tosanda0: ldx #$00 tosandax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index a99b713f5..fc187040e 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -18,8 +18,6 @@ .import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__ .import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__ - .macpack cpu - ; -------------------------------------------------------------------------- ; Initialize library modules diff --git a/libsrc/runtime/incax1.s b/libsrc/runtime/incax1.s index 19c1d0c60..bff94b019 100644 --- a/libsrc/runtime/incax1.s +++ b/libsrc/runtime/incax1.s @@ -7,11 +7,10 @@ .export incax1 .macpack generic - .macpack cpu .proc incax1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; 65C02 version bne @L9 .else diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index c3260c19d..395ea52cb 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -7,8 +7,6 @@ .export popax, incsp2 .importzp c_sp - .macpack cpu - ; Pop a/x from stack. This function will run directly into incsp2 .proc popax @@ -16,7 +14,7 @@ ldy #1 lda (c_sp),y ; get hi byte tax ; into x -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 6c187f32d..6991e4a7e 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - ; EAX = TOS + EAX tosadd0ax: @@ -19,7 +17,7 @@ tosadd0ax: tosaddeax: clc -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/laddeq.s b/libsrc/runtime/laddeq.s index 57bec0629..e5afac9cc 100644 --- a/libsrc/runtime/laddeq.s +++ b/libsrc/runtime/laddeq.s @@ -11,8 +11,6 @@ .export laddeq1, laddeqa, laddeq .importzp sreg, ptr1, tmp1 - .macpack cpu - laddeq1: lda #$01 @@ -24,7 +22,7 @@ laddeqa: laddeq: sty ptr1+1 ; Store high byte of address clc -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (ptr1) sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 400fede3b..2ad4ae4d7 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosand0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosand0ax: .endif tosandeax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index a808f6f84..5fbde5b62 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -7,8 +7,6 @@ .export ldau00sp, ldau0ysp .importzp c_sp, ptr1 - .macpack cpu - ldau00sp: ldy #1 ldau0ysp: @@ -18,7 +16,7 @@ ldau0ysp: lda (c_sp),y sta ptr1 ldx #0 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 408fdd159..afb069b1c 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -14,8 +14,6 @@ .import addysp .importzp c_sp - .macpack cpu - leave00: lda #0 leave0: ldx #0 @@ -28,7 +26,7 @@ leavey0: leavey: jsr addysp ; drop stack frame -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) leave: tay ; save A a sec lda (c_sp) ; that's the pushed arg size diff --git a/libsrc/runtime/lmod.s b/libsrc/runtime/lmod.s index b8e796dea..1cff216f3 100644 --- a/libsrc/runtime/lmod.s +++ b/libsrc/runtime/lmod.s @@ -11,10 +11,8 @@ .import poplsargs, udiv32, negeax .importzp sreg, ptr1, ptr2, tmp1, tmp3, tmp4 - .macpack cpu - tosmod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index a68c3e5c1..7124d6abd 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -9,11 +9,9 @@ .import addysp1 .importzp c_sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 - .macpack cpu - tosmul0ax: tosumul0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosmuleax: tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index 888a0c611..fa87aa63d 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosor0ax: .endif tosoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index 9690aff24..81dde42d3 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -9,8 +9,6 @@ .import incsp4 .importzp c_sp, sreg - .macpack cpu - popeax: ldy #3 lda (c_sp),y sta sreg+1 @@ -20,7 +18,7 @@ popeax: ldy #3 dey lda (c_sp),y tax -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index ec2c865af..fbc37b78c 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -12,13 +12,11 @@ .import decsp4 .importzp c_sp, sreg - .macpack cpu - pushl0: lda #0 tax push0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -39,7 +37,7 @@ pusheax: txa sta (c_sp),y pla -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) .else dey diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 456d8d8d5..b88d44f1a 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -12,10 +12,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosrsub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosrsub0ax: tosrsubeax: sec -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 17b225404..f0d34cd5b 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -11,10 +11,8 @@ .import addysp1 .importzp c_sp, sreg - .macpack cpu - tossub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tossub0ax: tossubeax: sec eor #$FF -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/lsubeq.s b/libsrc/runtime/lsubeq.s index b16ab18e1..d2d4ede7f 100644 --- a/libsrc/runtime/lsubeq.s +++ b/libsrc/runtime/lsubeq.s @@ -11,8 +11,6 @@ .export lsubeq1, lsubeqa, lsubeq .importzp sreg, ptr1 - .macpack cpu - lsubeq1: lda #$01 @@ -25,7 +23,7 @@ lsubeq: sty ptr1+1 ; Store high byte of address sec eor #$FF - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) adc (ptr1) ; Subtract byte 0 sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index b47207222..53651c789 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 - .macpack cpu - tosudiv0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -38,7 +36,7 @@ getlop: sta ptr3 ; Put right operand in place lda sreg+1 sta ptr4+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lumod.s b/libsrc/runtime/lumod.s index eb6176b35..a43c6d287 100644 --- a/libsrc/runtime/lumod.s +++ b/libsrc/runtime/lumod.s @@ -9,10 +9,8 @@ .import getlop, udiv32 .importzp sreg, tmp3, tmp4, ptr2 - .macpack cpu - tosumod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index 6d9f7db3a..abf341e63 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosxor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosxor0ax: .endif tosxoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 04389be5f..09aa93e79 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosora0: ldx #$00 tosorax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index c1700071d..bc490312e 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -7,11 +7,9 @@ .export popa .importzp c_sp - .macpack cpu - .proc popa -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 ; (2) diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 45043dd27..90dca5e22 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, ptr1 - .macpack cpu - .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else lda (c_sp),y ; get lo byte diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index c7f667246..0f6e5701d 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, sreg - .macpack cpu - popsreg: pha ; save A ldy #1 lda (c_sp),y ; get hi byte sta sreg+1 ; store it -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 399423077..6c715afb7 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -7,8 +7,6 @@ .export pusha0sp, pushaysp, pusha .importzp c_sp - .macpack cpu - ; Beware: The optimizer knows about this function! pusha0sp: diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index f77a9bcc3..5177f77b5 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -7,8 +7,6 @@ .export push0, pusha0, pushax .importzp c_sp - .macpack cpu - push0: lda #0 pusha0: ldx #0 @@ -31,7 +29,7 @@ pusha0: ldx #0 sta (c_sp),y ; (27) pla ; (31) dey ; (33) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; (37) .else sta (c_sp),y ; (38) diff --git a/libsrc/runtime/pushb.s b/libsrc/runtime/pushb.s index 7507ff21a..02d91b156 100644 --- a/libsrc/runtime/pushb.s +++ b/libsrc/runtime/pushb.s @@ -8,8 +8,6 @@ .import pushax .importzp ptr1 - .macpack cpu - pushbidx: sty ptr1 clc @@ -19,7 +17,7 @@ pushbidx: pushb: sta ptr1 stx ptr1+1 ldx #0 ; Load index/high byte -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index bacb3c7fc..1eedee53e 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -9,8 +9,6 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - ; ; AX = AX - TOS ; @@ -19,7 +17,7 @@ tosrsuba0: ldx #0 tosrsubax: sec -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/shl.s b/libsrc/runtime/shl.s index c1a4b6ef8..1f11eb5c0 100644 --- a/libsrc/runtime/shl.s +++ b/libsrc/runtime/shl.s @@ -15,8 +15,6 @@ .import popax .importzp tmp1 - .macpack cpu - tosshlax: tosaslax: sta tmp1 ; Save shift count @@ -55,7 +53,7 @@ L2: pla ; Shift count is exactly 8 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) L3: plx ; Low byte from stack into X rts ; A is already zero .else diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index aefed428f..e1542881f 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -9,8 +9,6 @@ .import incsp2 .importzp c_sp, tmp1, ptr1 - .macpack cpu - .proc staxspidx sty tmp1 ; Save Y @@ -18,7 +16,7 @@ ldy #1 lda (c_sp),y sta ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index a7ca39f21..f6ab28ea6 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -21,7 +21,6 @@ ; Use macros for better readability .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- @@ -39,7 +38,7 @@ lda c_sp+1 sta initialsp+1 sbc #>__STACKSIZE__ -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; Add 256 bytes safety area .else add #1 ; Add 256 bytes safety area diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index 58ffb4c91..7129e2147 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp - .macpack cpu - ; AX = TOS - AX tossuba0: @@ -17,7 +15,7 @@ tossuba0: tossubax: sec eor #$FF -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index 3796b0a97..72adaa90b 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -8,8 +8,6 @@ .export swapstk .importzp c_sp, ptr4 - .macpack cpu - swapstk: sta ptr4 stx ptr4+1 @@ -18,7 +16,7 @@ swapstk: tax lda ptr4+1 sta (c_sp),y -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) tay lda ptr4 diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index 2aaa19ccc..e879fe11f 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from long to int by cutting of the high 16bit .proc tosint pha -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index cf8eff031..c8b34d8b0 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -8,8 +8,6 @@ .import decsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from int to long tosulong: @@ -17,7 +15,7 @@ tosulong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else @@ -43,7 +41,7 @@ toslong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else diff --git a/libsrc/runtime/umul8x16r24.s b/libsrc/runtime/umul8x16r24.s index 54d730558..115a3e1a4 100644 --- a/libsrc/runtime/umul8x16r24.s +++ b/libsrc/runtime/umul8x16r24.s @@ -9,8 +9,6 @@ .include "zeropage.inc" - .macpack cpu - ;--------------------------------------------------------------------------- ; 8x16 => 24 unsigned multiplication routine. Because the overhead for a ; 8x16 => 16 unsigned multiplication routine is small, we will tag it with @@ -31,7 +29,7 @@ umul8x16r16: umul8x16r24m: umul8x16r16m: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1+1 stz sreg .else diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index 15394413c..1236b2c37 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosxora0: ldx #$00 tosxorax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ldy #1 .else diff --git a/libsrc/tgi/tgi_settextstyle.s b/libsrc/tgi/tgi_settextstyle.s index b62d6904c..bb924c048 100644 --- a/libsrc/tgi/tgi_settextstyle.s +++ b/libsrc/tgi/tgi_settextstyle.s @@ -9,8 +9,6 @@ .import umul8x16r24 .import popa, popax - .macpack cpu - ;----------------------------------------------------------------------------- ; void __fastcall__ tgi_settextstyle (unsigned width, unsigned height, ; unsigned char dir, unsigned char font); @@ -82,7 +80,7 @@ process_onedim: ; Disallowing characters larger than 256 pixels, we just drop the high byte ; and remember the low 16 bit as size in 8.8 format. -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) phy ; Save Y jsr umul8x16r24 ply ; Restore Y From 59e7158512043a18966ca68531a18ba67791afdb Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:29:42 +0200 Subject: [PATCH 05/11] Make the CPU_xxx constants from cpu.mac internal to the assembler and replace cpu.mac by a file that just emits a warning when used. --- asminc/cpu.mac | 42 ++---------- doc/ca65.sgml | 134 ++++++++++++++++++------------------- libsrc/apple2/cputc.s | 2 - libsrc/apple2/lseek.s | 1 - libsrc/apple2/ser/a2.ssc.s | 1 - libsrc/common/strlen.s | 1 - libsrc/sim6502/exehdr.s | 2 - src/ca65/main.c | 50 ++++++++++++++ 8 files changed, 119 insertions(+), 114 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 15b16bad5..092519173 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -1,38 +1,4 @@ -; CPU bitmask constants (make sure this matches src/common/cpu.h) - -CPU_ISET_NONE = $0001 -CPU_ISET_6502 = $0002 -CPU_ISET_6502X = $0004 -CPU_ISET_6502DTV = $0008 -CPU_ISET_65SC02 = $0010 -CPU_ISET_65C02 = $0020 ; Rockwell extensions -CPU_ISET_65816 = $0040 -CPU_ISET_SWEET16 = $0080 -CPU_ISET_HUC6280 = $0100 -CPU_ISET_M740 = $0200 -CPU_ISET_4510 = $0400 -CPU_ISET_45GS02 = $0800 -CPU_ISET_W65C02 = $1000 ; WDC extensions -CPU_ISET_65CE02 = $2000 ; CSG extensions - -; CPU capabilities -; make sure to only combine the instruction sets that are 100% compatible -CPU_NONE = CPU_ISET_NONE -CPU_6502 = CPU_ISET_6502 -CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502 -CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502 -CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502 -CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 - -; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect -; addressing was replaced with zp-indirect,z-indexed in 652SCE02 - -CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 -CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 -CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510 -CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 -CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02 - -CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_SWEET16 = CPU_ISET_SWEET16 +; This file is no longer needed as the symbols that were defined here are now +; internal symbols generated by the assembler. It is kept to avoid breaking +; old sources. +.warning "'.macpack cpu' is no longer required" diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cfe73a2f0..0f996ff64 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1401,16 +1401,76 @@ writable. Reading this pseudo variable will give a constant integer value that tells which CPU is currently enabled. It can also tell which instruction set the CPU is able to translate. The value read from the pseudo variable - should be further examined by using one of the constants defined by the - "cpu" macro package (see /). + should be further examined by using one of the following constants: - It may be used to replace the .IFPxx pseudo instructions or to construct - even more complex expressions. + + CPU_6502 + CPU_65SC02 + CPU_65C02 + CPU_65816 + CPU_SWEET16 + CPU_HUC6280 + CPU_4510 + CPU_45GS02 + CPU_6502DTV + CPU_M740 + + +Above constants may be used to determine the exact type of the currently +enabled CPU. In addition to that, for each CPU instruction set, another +constant is defined: + + + CPU_ISET_6502 + CPU_ISET_65SC02 + CPU_ISET_65C02 + CPU_ISET_65816 + CPU_ISET_SWEET16 + CPU_ISET_HUC6280 + CPU_ISET_4510 + CPU_ISET_45GS02 + CPU_ISET_6502DTV + CPU_ISET_M740 + + + + + - .macpack cpu .if (.cpu .bitand CPU_ISET_65816) phx phy @@ -1422,7 +1482,6 @@ writable. .endif - See also: @@ -5042,69 +5101,6 @@ This macro package defines a macro named .MACPACK cpu - -This macro package does not define any macros but constants used to examine -the value read from the / pseudo variable. For -each supported CPU a constant similar to - - - CPU_6502 - CPU_65SC02 - CPU_65C02 - CPU_65816 - CPU_SWEET16 - CPU_HUC6280 - CPU_4510 - CPU_45GS02 - CPU_6502DTV - CPU_M740 - - -is defined. These constants may be used to determine the exact type of the -currently enabled CPU. In addition to that, for each CPU instruction set, -another constant is defined: - - - CPU_ISET_6502 - CPU_ISET_65SC02 - CPU_ISET_65C02 - CPU_ISET_65816 - CPU_ISET_SWEET16 - CPU_ISET_HUC6280 - CPU_ISET_4510 - CPU_ISET_45GS02 - CPU_ISET_6502DTV - CPU_ISET_M740 - - -The value read from the / pseudo variable may -be checked with / to determine if the -currently enabled CPU supports a specific instruction set. For example the -65C02 supports all instructions of the 65SC02 CPU, so it has the - - .if (.cpu .bitand CPU_ISET_65SC02) - lda (c_sp) - .else - ldy #$00 - lda (c_sp),y - .endif - - -it is possible to determine if the - - - lda (c_sp) - - -instruction is supported, which is the case for the 65SC02, 65C02 and 65816 -CPUs (the latter two are upwards compatible to the 65SC02). - -see section and following. - .MACPACK module This macro package defines a macro named Date: Tue, 1 Jul 2025 08:34:38 +0200 Subject: [PATCH 06/11] Add an additional hook (currently unused) for target specific capabilities. --- src/ca65/expr.c | 3 ++- src/common/target.c | 10 ++++++++++ src/common/target.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 42b1a369b..33984610d 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -61,6 +61,7 @@ #include "studyexpr.h" #include "symbol.h" #include "symtab.h" +#include "target.h" #include "toklist.h" #include "ulabel.h" #include "macro.h" @@ -445,7 +446,7 @@ static ExprNode* FuncCapability (void) /* The pseudo function result is the logical AND of all capabilities ** given. */ - if (!CPUHasCap (Cap)) { + if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) { Result = 0; } } diff --git a/src/common/target.c b/src/common/target.c index a12f69bf9..bb67ddf9a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -37,6 +37,7 @@ #include /* common */ +#include "attrib.h" #include "chartype.h" #include "check.h" #include "target.h" @@ -302,3 +303,12 @@ const char* GetTargetName (target_t Target) /* Return the array entry */ return GetTargetProperties (Target)->Name; } + + + +int TargetHasCap (capability_t Cap attribute((unused))) +/* Check if the current target has the given capability */ +{ + /* Currently unused */ + return 0; +} diff --git a/src/common/target.h b/src/common/target.h index c5c8455a0..1dfa66ac7 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -39,6 +39,7 @@ /* common */ +#include "capability.h" #include "cpu.h" @@ -131,6 +132,9 @@ const TargetProperties* GetTargetProperties (target_t Target); const char* GetTargetName (target_t Target); /* Return the name of a target */ +int TargetHasCap (capability_t Cap); +/* Check if the current target has the given capability */ + /* End of target.h */ From 8d3112e24f93053bf8cd92ca5aa54d2f55339821 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:47:16 +0200 Subject: [PATCH 07/11] Small code simplification. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index d8c0dbd37..2f239d99d 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -233,5 +233,5 @@ int CPUHasCap (capability_t Cap) /* Check if the current CPU has the given capability */ { PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); - return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; + return (CPUCaps[CPU] & CAP_BIT (Cap)) != 0; } From c162f6a28636cd9cb04f5812532e53f87922b5f5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:21:18 +0200 Subject: [PATCH 08/11] Warning fix. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2f239d99d..7988cb4c1 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -151,7 +151,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ -static const uint64_t CPUCaps[CPU_COUNT] = { +static const uint32_t CPUCaps[CPU_COUNT] = { CAP_NONE, /* CPU_NONE */ CAP_6502, /* CPU_6502 */ CAP_6502X, /* CPU_6502X */ From 37414199c7f511eeee21a23bc0c1d184871fe92b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:33:38 +0200 Subject: [PATCH 09/11] Hopefully fix windows build files. --- src/common.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.vcxproj b/src/common.vcxproj index 6098c98a0..251ea3aeb 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -80,6 +80,7 @@ + @@ -133,6 +134,7 @@ + @@ -171,4 +173,4 @@ - \ No newline at end of file + From 60ec9045fce2c30aa4a24e46c59daaaccfab283a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:02:15 +0200 Subject: [PATCH 10/11] Use CPUIsets from cpu.c instead of recreating the CPU_xxx constants. --- src/ca65/main.c | 36 ++++++++++++++---------------------- src/common/cpu.c | 16 ++++++++++++++-- src/common/cpu.h | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fb0907df3..e9b36ee5d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -213,28 +213,20 @@ static void DefineCpuSymbols (void) /* Additional ones from cpu.mac. Not sure how useful they are after the ** changes from #2751. */ - NewSymbol ("CPU_NONE", CPU_ISET_NONE); - NewSymbol ("CPU_6502", CPU_ISET_6502); - NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); - NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); - NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); - NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | - CPU_ISET_65C02); - - /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the - ** zp-indirect addressing was replaced with zp-indirect,z-indexed in - ** 652SCE02 - */ - NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02); - NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02 | CPU_ISET_4510); - NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); - NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]); + NewSymbol ("CPU_6502", CPUIsets[CPU_6502]); + NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]); + NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]); + NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]); + NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]); + NewSymbol ("CPU_65816", CPUIsets[CPU_65816]); + NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]); + NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]); + NewSymbol ("CPU_M740", CPUIsets[CPU_M740]); + NewSymbol ("CPU_4510", CPUIsets[CPU_4510]); + NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]); + NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]); + NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]); } diff --git a/src/common/cpu.c b/src/common/cpu.c index 7988cb4c1..8e9ff827a 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -74,21 +74,33 @@ const char* CPUNames[CPU_COUNT] = { * NOTE: make sure to only combine the instruction sets that are 100% compatible */ const unsigned CPUIsets[CPU_COUNT] = { + /* CPU_NONE */ CPU_ISET_NONE, + /* CPU_6502 */ CPU_ISET_6502, + /* CPU_6502X */ CPU_ISET_6502X | CPU_ISET_6502, + /* CPU_6502DTV */ CPU_ISET_6502DTV | CPU_ISET_6502, + /* CPU_65SC02 */ CPU_ISET_65SC02 | CPU_ISET_6502, + /* CPU_65C02 */ CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* 65816 has wai/stp and NO bit manipulation */ + /* CPU_65816. 65816 has wai/stp and NO bit manipulation. */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* CPU_SWEET16 */ CPU_ISET_SWEET16, + /* CPU_HUC6280 */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_M740 */ CPU_ISET_M740 | CPU_ISET_6502, - /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* CPU_4510. 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + /* CPU_45GS02 */ CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, + /* CPU_W65C02 */ CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_65CE02 */ CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 0a7c853ac..bc6260371 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -69,7 +69,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ +/* CPU instruction sets */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From 070276a1a3baa9fbfca42555b306e0d9caac8436 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:19:19 +0200 Subject: [PATCH 11/11] Add a better description for CPU_HAS_ZPIND and CPU_HAS_STZ. --- doc/ca65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0f996ff64..63a1be7e9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1681,10 +1681,12 @@ either a string or an expression value. Checks for the capability to push and pop the X and Y registers. CPU_HAS_ZPIND - Checks for the availability of the "zeropage indirect" addressing mode. + Checks for the availability of the "zeropage indirect" addressing mode as it + is implemented in the 65SC02 CPU. CPU_HAS_STZ - Checks for the availability of the "store zero" instruction. + Checks for the availability of the "store zero" instruction as it is + implemented in the 65SC02 CPU.
+ + Builtin function. The function allows to check for capabilities of the + currently selected CPU or target system. It must be called with a comma + separated list of identifiers and returns non zero if all of the given + capabilities are available. Otherwise it returns zero. + + Existing capabilities are: + + + + CPU_HAS_BRA8 + Checks for the availability of a short (8 bit) branch. + + CPU_HAS_INA + Checks for the availability of accu inc/dec instructions. + + CPU_HAS_PUSHXY + Checks for the capability to push and pop the X and Y registers. + + CPU_HAS_ZPIND + Checks for the availability of the "zeropage indirect" addressing mode. + + CPU_HAS_STZ + Checks for the availability of the "store zero" instruction. + + + + Case is ignored when checking the identifiers. The + .if .cap(CPU_HAS_BRA, CPU_HAS_PUSHXY) + phx + bra L1 + .else + txa + pha + jmp L1 + .endif + + + See also: + + + .CONCAT Builtin string function. The function allows to concatenate a list of string diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 5dcf5ca71..42b1a369b 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -37,6 +37,7 @@ #include /* common */ +#include "capability.h" #include "check.h" #include "cpu.h" #include "exprdefs.h" @@ -405,6 +406,66 @@ static ExprNode* FuncBlank (void) +static ExprNode* FuncCapability (void) +/* Handle the .CAPABILITY builtin function */ +{ + int Result = 1; + + /* What follows is a comma separated list of identifiers. An empty list is + ** not allowed. + */ + while (1) { + + const char* Name; + capability_t Cap; + + /* We must have an identifier */ + if (CurTok.Tok != TOK_IDENT) { + Error ("Arguments to .CAPABILITY must be identifiers"); + /* Skip tokens until closing paren or end of line */ + while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) { + NextTok (); + } + return GenLiteral0 (); + } + + /* Search for the capability that matches this identifier. Ignore case + ** on the specified capabilities. + */ + UpcaseSVal (); + SB_Terminate (&CurTok.SVal); + Name = SB_GetConstBuf (&CurTok.SVal); + Cap = FindCapability (Name); + + /* Check if the capability is supported */ + if (Cap == CAP_INVALID) { + Error ("Not a valid capability name: %s", Name); + Result = 0; + } else { + /* The pseudo function result is the logical AND of all capabilities + ** given. + */ + if (!CPUHasCap (Cap)) { + Result = 0; + } + } + + /* Skip the capability name */ + NextTok (); + + /* Handle end of list or next capability */ + if (CurTok.Tok != TOK_COMMA) { + break; + } + NextTok (); + } + + /* Done */ + return GenLiteralExpr (Result); +} + + + static ExprNode* FuncConst (void) /* Handle the .CONST builtin function */ { @@ -484,9 +545,10 @@ static ExprNode* FuncIsMnemonic (void) if (FindMacro (&CurTok.SVal) == 0) { Instr = FindInstruction (&CurTok.SVal); } - } - else { - /* Macros and symbols may NOT use the names of instructions, so just check for the instruction */ + } else { + /* Macros and symbols may NOT use the names of instructions, so + ** just check for the instruction. + */ Instr = FindInstruction (&CurTok.SVal); } } @@ -532,7 +594,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) token_t Term = GetTokListTerm (TOK_COMMA); while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -570,7 +632,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) Node = Root; while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -1129,6 +1191,10 @@ static ExprNode* Factor (void) N = Function (FuncBlank); break; + case TOK_CAP: + N = Function (FuncCapability); + break; + case TOK_CONST: N = Function (FuncConst); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index e6e10df2c..301129583 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -2114,7 +2114,8 @@ struct CtrlDesc { }; /* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR - and .XOR do NOT go into this table */ +** and .XOR do NOT go into this table. +*/ #define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0])) static CtrlDesc CtrlCmdTab [] = { { ccNone, DoA16 }, /* .A16 */ @@ -2132,6 +2133,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .BLANK */ { ccNone, DoBss }, /* .BSS */ { ccNone, DoByte }, /* .BYT, .BYTE */ + { ccNone, DoUnexpected }, /* .CAP */ { ccNone, DoCase }, /* .CASE */ { ccNone, DoCharMap }, /* .CHARMAP */ { ccNone, DoCode }, /* .CODE */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f3892d32e..a2a72a149 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -158,6 +158,8 @@ struct DotKeyword { { ".BSS", TOK_BSS }, { ".BYT", TOK_BYTE }, { ".BYTE", TOK_BYTE }, + { ".CAP", TOK_CAP }, + { ".CAPABILITY", TOK_CAP }, { ".CASE", TOK_CASE }, { ".CHARMAP", TOK_CHARMAP }, { ".CODE", TOK_CODE }, diff --git a/src/ca65/token.h b/src/ca65/token.h index e2b223880..b40534d79 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -137,6 +137,7 @@ typedef enum token_t { TOK_BLANK, TOK_BSS, TOK_BYTE, + TOK_CAP, TOK_CASE, TOK_CHARMAP, TOK_CODE, diff --git a/src/common/capability.c b/src/common/capability.c new file mode 100644 index 000000000..f66205e7c --- /dev/null +++ b/src/common/capability.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* capability.c */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include + +/* ca65 */ +#include "capability.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* List of dot keywords with the corresponding ids. */ +/* CAUTION: table must be sorted for bsearch. */ +struct Capability { + const char* Key; + capability_t Cap; +} Capabilities [] = { +/* BEGIN SORTED.SH */ + { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, + { "CPU_HAS_INA", CAP_CPU_HAS_INA }, + { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, + { "CPU_HAS_STZ", CAP_CPU_HAS_STZ }, + { "CPU_HAS_ZPIND", CAP_CPU_HAS_ZPIND }, +/* END SORTED.SH */ +}; +#define CAP_TABLE_SIZE (sizeof (Capabilities) / sizeof (Capabilities [0])) + + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static int CmpCapability (const void* K1, const void* K2) +/* Compare function for the capability search */ +{ + return strcmp (((struct Capability*)K1)->Key, ((struct Capability*)K2)->Key); +} + + + +capability_t FindCapability (const char* Name) +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ +{ + const struct Capability K = { Name, 0 }; + const struct Capability* C = bsearch (&K, Capabilities, CAP_TABLE_SIZE, + sizeof (Capabilities [0]), + CmpCapability); + return (C == 0)? CAP_INVALID : C->Cap; +} diff --git a/src/common/capability.h b/src/common/capability.h new file mode 100644 index 000000000..011e2164f --- /dev/null +++ b/src/common/capability.h @@ -0,0 +1,78 @@ +/*****************************************************************************/ +/* */ +/* capability.h */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef CAPABILITY_H +#define CAPABILITY_H + + + +/* common */ +#include "strbuf.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Numeric codes for capabilities */ +enum capability_t { + CAP_INVALID = -1, + CAP_CPU_HAS_BRA8 = 0, /* CPU has a BRA 8-bit instruction */ + CAP_CPU_HAS_INA = 1, /* CPU has DEA/INA */ + CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ + CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ + CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ +}; +typedef enum capability_t capability_t; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +capability_t FindCapability (const char* Name); +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ + + + +/* End of capability.h */ + +#endif diff --git a/src/common/cpu.c b/src/common/cpu.c index 252283211..cdc8e52cc 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -33,6 +33,8 @@ +#include + /* common */ #include "addrsize.h" #include "check.h" @@ -90,6 +92,77 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; +/* Defines for capabilities. Currently the entries are uint32_ts but the table +** is deliberately hidden from the outside so it can be extended to 64 bit or +** even more. +*/ +#define CAP_NONE UINT32_C (0) +#define CAP_6502 UINT32_C (0) +#define CAP_6502X UINT32_C (0) +#define CAP_6502DTV UINT32_C (0) +#define CAP_65SC02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65816 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 UINT32_C (0) +#define CAP_HUC6280 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_M740 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA)) +#define CAP_4510 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_45GS02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_W65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_65CE02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + +/* Table containing one capability entry per CPU */ +static const uint64_t CPUCaps[CPU_COUNT] = { + CAP_NONE, /* CPU_NONE */ + CAP_6502, /* CPU_6502 */ + CAP_6502X, /* CPU_6502X */ + CAP_6502DTV, /* CPU_6502DTV */ + CAP_65SC02, /* CPU_65SC02 */ + CAP_65C02, /* CPU_65C02 */ + CAP_65816, /* CPU_65816 */ + CAP_SWEET16, /* CPU_SWEET16 */ + CAP_HUC6280, /* CPU_HUC6280 */ + CAP_M740, /* CPU_M740 */ + CAP_4510, /* CPU_4510 */ + CAP_45GS02, /* CPU_45GS02 */ + CAP_W65C02, /* CPU_W65C02 */ + CAP_65CE02, /* CPU_65CE02 */ +}; + /*****************************************************************************/ @@ -148,3 +221,12 @@ cpu_t FindCPU (const char* Name) /* Not found */ return CPU_UNKNOWN; } + + + +int CPUHasCap (capability_t Cap) +/* Check if the current CPU has the given capability */ +{ + PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); + return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; +} diff --git a/src/common/cpu.h b/src/common/cpu.h index 4202ed573..0a7c853ac 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -38,6 +38,11 @@ +/* common */ +#include "capability.h" + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -107,6 +112,9 @@ cpu_t FindCPU (const char* Name); ** the given name is no valid target. */ +int CPUHasCap (capability_t Cap); +/* Check if the current CPU has the given capability */ + /* End of cpu.h */ diff --git a/test/asm/listing/110-capabilities.s b/test/asm/listing/110-capabilities.s new file mode 100644 index 000000000..e3e306ca7 --- /dev/null +++ b/test/asm/listing/110-capabilities.s @@ -0,0 +1,39 @@ + +; Error: Arguments to .CAPABILITY must be identifiers +.if .cap() +.endif + +; Error: Arguments to .CAPABILITY must be identifiers +; Error: ')' expected +.if .cap( +.endif + +; Error: Not a valid capability name: CPU_HAS_BR +.if .cap(cpu_has_br) +.endif + +; Error: ')' expected +; Error: Unexpected trailing garbage characters +.if .cap(cpu_has_bra8 cpu_has_bra8) +.endif + +; Ok +.if .cap(cpu_has_bra8, CPU_HAS_PUSHXY, CPU_HAS_STZ, CPU_HAS_INA) +.endif + +.setcpu "65SC02" +.if !.cap(cpu_has_bra8) +.error "Assembler says 65SC02 has no 8 bit bra" +.endif +.if !.cap(cpu_has_PUSHXY) +.error "Assembler says 65SC02 has no phx" +.endif +.if !.cap(cpu_has_STZ) +.error "Assembler says 65SC02 has no stz" +.endif +.if !.cap(cpu_has_INA) +.error "Assembler says 65SC02 has no ina" +.endif + + + diff --git a/test/asm/listing/control/110-capabilities.err b/test/asm/listing/control/110-capabilities.err new file mode 100644 index 000000000..e69de29bb diff --git a/test/asm/listing/ref/110-capabilities.err2-ref b/test/asm/listing/ref/110-capabilities.err2-ref new file mode 100644 index 000000000..e00e60e17 --- /dev/null +++ b/test/asm/listing/ref/110-capabilities.err2-ref @@ -0,0 +1,6 @@ +110-capabilities.s:3: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: ')' expected +110-capabilities.s:12: Error: Not a valid capability name: CPU_HAS_BR +110-capabilities.s:17: Error: ')' expected +110-capabilities.s:17: Error: Unexpected trailing garbage characters From f333b300f1c542b952580420259f6d79db7977f1 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:16:33 +0200 Subject: [PATCH 03/11] Added the CPU_HAS_BITIMM capability. --- doc/ca65.sgml | 3 ++ src/common/capability.c | 1 + src/common/capability.h | 1 + src/common/cpu.c | 81 ++++++++++++++++++++++------------------- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 552309ff9..cfe73a2f0 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1609,6 +1609,9 @@ either a string or an expression value. + CPU_HAS_BITIMM + Checks for the availability of the "bit #imm" instruction. + CPU_HAS_BRA8 Checks for the availability of a short (8 bit) branch. diff --git a/src/common/capability.c b/src/common/capability.c index f66205e7c..19c3ed838 100644 --- a/src/common/capability.c +++ b/src/common/capability.c @@ -50,6 +50,7 @@ struct Capability { capability_t Cap; } Capabilities [] = { /* BEGIN SORTED.SH */ + { "CPU_HAS_BITIMM", CAP_CPU_HAS_BITIMM }, { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, { "CPU_HAS_INA", CAP_CPU_HAS_INA }, { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, diff --git a/src/common/capability.h b/src/common/capability.h index 011e2164f..b0332c72e 100644 --- a/src/common/capability.h +++ b/src/common/capability.h @@ -54,6 +54,7 @@ enum capability_t { CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ + CAP_CPU_HAS_BITIMM = 5, /* CPU has "bit #imm" instruction */ }; typedef enum capability_t capability_t; diff --git a/src/common/cpu.c b/src/common/cpu.c index cdc8e52cc..d8c0dbd37 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -96,54 +96,59 @@ const unsigned CPUIsets[CPU_COUNT] = { ** is deliberately hidden from the outside so it can be extended to 64 bit or ** even more. */ +#define CAP_BIT(Cap) (UINT32_C (1) << (Cap)) #define CAP_NONE UINT32_C (0) -#define CAP_6502 UINT32_C (0) -#define CAP_6502X UINT32_C (0) -#define CAP_6502DTV UINT32_C (0) +#define CAP_6502 CAP_NONE +#define CAP_6502X CAP_NONE +#define CAP_6502DTV CAP_NONE #define CAP_65SC02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65816 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) -#define CAP_SWEET16 UINT32_C (0) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 CAP_NONE #define CAP_HUC6280 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_M740 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA)) #define CAP_4510 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_45GS02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_W65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_65CE02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ static const uint64_t CPUCaps[CPU_COUNT] = { From c72126e68fc879229b677baf6443ed242b0262f7 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:25:32 +0200 Subject: [PATCH 04/11] Changed most of the library sources to use .CAP instead of .CPU. --- libsrc/cbm/clock.s | 3 +- libsrc/common/_directerrno.s | 4 +- libsrc/common/_heapblocksize.s | 3 +- libsrc/common/_mappederrno.s | 3 +- libsrc/common/_printf.s | 11 ++--- libsrc/common/_time_t_to_tm.s | 4 +- libsrc/common/asctime.s | 6 +-- libsrc/common/atexit.s | 10 ++-- libsrc/common/fgetc.s | 4 +- libsrc/common/fgets.s | 8 ++-- libsrc/common/fread.s | 15 +++--- libsrc/common/fwrite.s | 6 +-- libsrc/common/ltoa.s | 4 +- libsrc/common/strcat.s | 3 +- libsrc/common/strchr.s | 3 +- libsrc/common/strdup.s | 4 +- libsrc/common/strncat.s | 83 +++++++++++++++++----------------- libsrc/conio/cputs.s | 5 +- libsrc/conio/scrsize.s | 4 +- libsrc/conio/vcprintf.s | 3 +- libsrc/runtime/add.s | 4 +- libsrc/runtime/and.s | 4 +- libsrc/runtime/condes.s | 2 - libsrc/runtime/incax1.s | 3 +- libsrc/runtime/incsp2.s | 4 +- libsrc/runtime/ladd.s | 4 +- libsrc/runtime/laddeq.s | 4 +- libsrc/runtime/land.s | 6 +-- libsrc/runtime/ldau0sp.s | 4 +- libsrc/runtime/leave.s | 4 +- libsrc/runtime/lmod.s | 4 +- libsrc/runtime/lmul.s | 6 +-- libsrc/runtime/lor.s | 6 +-- libsrc/runtime/lpop.s | 4 +- libsrc/runtime/lpush.s | 6 +-- libsrc/runtime/lrsub.s | 6 +-- libsrc/runtime/lsub.s | 6 +-- libsrc/runtime/lsubeq.s | 4 +- libsrc/runtime/ludiv.s | 6 +-- libsrc/runtime/lumod.s | 4 +- libsrc/runtime/lxor.s | 6 +-- libsrc/runtime/or.s | 4 +- libsrc/runtime/popa.s | 4 +- libsrc/runtime/popptr1.s | 4 +- libsrc/runtime/popsreg.s | 4 +- libsrc/runtime/pusha.s | 2 - libsrc/runtime/pushax.s | 4 +- libsrc/runtime/pushb.s | 4 +- libsrc/runtime/rsub.s | 4 +- libsrc/runtime/shl.s | 4 +- libsrc/runtime/staxspi.s | 4 +- libsrc/runtime/stkchk.s | 3 +- libsrc/runtime/sub.s | 4 +- libsrc/runtime/swap.s | 4 +- libsrc/runtime/tosint.s | 4 +- libsrc/runtime/toslong.s | 6 +-- libsrc/runtime/umul8x16r24.s | 4 +- libsrc/runtime/xor.s | 4 +- libsrc/tgi/tgi_settextstyle.s | 4 +- 59 files changed, 122 insertions(+), 232 deletions(-) diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index 90e4263a8..91fde6f58 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -9,14 +9,13 @@ .importzp sreg .include "cbm.inc" - .macpack cpu .proc _clock ; Some accelerator adaptors have CMOS ICs. -.if (.cpu & ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg + 1 .else lda #$00 ; Byte 3 always is zero diff --git a/libsrc/common/_directerrno.s b/libsrc/common/_directerrno.s index 20060bdd7..74e2f89cd 100644 --- a/libsrc/common/_directerrno.s +++ b/libsrc/common/_directerrno.s @@ -7,8 +7,6 @@ .include "errno.inc" - .macpack cpu - ; ---------------------------------------------------------------------------- ; int __fastcall__ __directerrno (unsigned char code); ; /* Set errno to a specific error code, clear __oserror, and return -1. Used @@ -18,7 +16,7 @@ ___directerrno: jsr ___seterrno ; Set errno (returns with .A = 0) sta ___oserror ; Clear ___oserror -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 diff --git a/libsrc/common/_heapblocksize.s b/libsrc/common/_heapblocksize.s index e9b0cdad9..774056032 100644 --- a/libsrc/common/_heapblocksize.s +++ b/libsrc/common/_heapblocksize.s @@ -12,7 +12,6 @@ .include "_heap.inc" .macpack generic - .macpack cpu ;----------------------------------------------------------------------------- ; Code @@ -39,7 +38,7 @@ ___heapblocksize: ldy #usedblock::size+1 lda (ptr2),y tax -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr2) .else dey diff --git a/libsrc/common/_mappederrno.s b/libsrc/common/_mappederrno.s index 83565b723..4ea3174b6 100644 --- a/libsrc/common/_mappederrno.s +++ b/libsrc/common/_mappederrno.s @@ -8,7 +8,6 @@ .include "errno.inc" .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; int __fastcall__ __mappederrno (unsigned char code); @@ -24,7 +23,7 @@ ___mappederrno: bze ok ; Branch if no jsr ___osmaperrno ; Map OS error into errno code jsr ___seterrno ; Save in errno (returns with .A = 0) -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 if error diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index 40ab0bc64..335485cc6 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -13,7 +13,6 @@ .import _strlower, _strlen .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; We will store variables into the register bank in the zeropage. Define @@ -38,7 +37,7 @@ FCount = ptr2 GetFormatChar: ldy #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (Format) .else lda (Format),y @@ -115,7 +114,7 @@ GetIntArg: lda (ArgList),y tax dey - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (ArgList) .else lda (ArgList),y @@ -274,7 +273,7 @@ Save: lda regbank,y ; Initialize the output counter in the output descriptor to zero lda #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (OutData) ldy #$01 sta (OutData),y @@ -353,7 +352,7 @@ MainLoop: sta (c_sp),y dey lda FCount - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (c_sp) .else sta (c_sp),y @@ -570,7 +569,7 @@ CheckCount: jsr GetIntArg sta ptr1 stx ptr1+1 ; Get user supplied pointer - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (OutData) ; Low byte of OutData->ccount sta (ptr1) ldy #1 diff --git a/libsrc/common/_time_t_to_tm.s b/libsrc/common/_time_t_to_tm.s index 9bcf84184..21e662384 100644 --- a/libsrc/common/_time_t_to_tm.s +++ b/libsrc/common/_time_t_to_tm.s @@ -16,8 +16,6 @@ .include "time.inc" - .macpack cpu - __time_t_to_tm: ; Divide number of seconds since epoch, in ptr1:sreg, ; by 86400 to get the number of days since epoch, and @@ -80,7 +78,7 @@ __time_t_to_tm: ; Zero the two high bytes of the divisor and the high byte ; of the dividend. - .if .cpu .bitand CPU_ISET_65SC02 + .if .cap(CPU_HAS_STZ) stz ptr4 stz ptr4+1 stz sreg+1 diff --git a/libsrc/common/asctime.s b/libsrc/common/asctime.s index efcf34b41..b56371594 100644 --- a/libsrc/common/asctime.s +++ b/libsrc/common/asctime.s @@ -9,8 +9,6 @@ .importzp ptr1 .include "time.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Special values @@ -24,7 +22,7 @@ MAX_BUF_LEN = 38 _asctime: ; Backup timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) pha phx .else @@ -48,7 +46,7 @@ _asctime: jsr pushax ; Restore timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) plx pla .else diff --git a/libsrc/common/atexit.s b/libsrc/common/atexit.s index 47a1dfd4d..ccbc2e69f 100644 --- a/libsrc/common/atexit.s +++ b/libsrc/common/atexit.s @@ -10,8 +10,6 @@ .include "errno.inc" - .macpack cpu - ; --------------------------------------------------------------------------- .proc _atexit @@ -41,7 +39,7 @@ jsr ___seterrno ldx #$FF ; Return -1 txa - rts +Exit: rts .endproc @@ -54,7 +52,7 @@ .proc doatexit ldy exitfunc_index ; Get index - beq @L9 ; Jump if done + beq _atexit::Exit ; Jump if done dey lda exitfunc_table,y tax @@ -62,14 +60,12 @@ lda exitfunc_table,y sty exitfunc_index jsr callax ; Call the function -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra doatexit .else jmp doatexit ; Next one .endif -@L9: rts - .endproc diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s index 34d4df3aa..6d08f69a3 100644 --- a/libsrc/common/fgetc.s +++ b/libsrc/common/fgetc.s @@ -12,8 +12,6 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - _fgetc: sta ptr1 stx ptr1+1 @@ -22,7 +20,7 @@ _fgetc: jsr checkferror bne ret_eof - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FPUSHBACK ; Check for pushed back char beq do_read .else diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index c25664f19..fde3a78a9 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -14,12 +14,10 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - terminate_ptr: lda #$00 tax - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else tay @@ -41,7 +39,7 @@ _fgets: sta buf stx buf+1 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_STZ) stz didread .else lda #$00 ; We have read nothing yet @@ -79,7 +77,7 @@ read_loop: ldy #$01 sty didread ; We read at least one char - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else dey diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index be06c2a62..beb9e707e 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -20,7 +20,6 @@ .include "_file.inc" .macpack generic - .macpack cpu ; ------------------------------------------------------------------------ ; Code @@ -48,7 +47,7 @@ ldy #_FILE::f_flags lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN ; Is the file open? .else and #_FOPEN ; Is the file open? @@ -57,7 +56,7 @@ ; Check if the stream is in an error state - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FERROR .else lda (file),y ; get file->f_flags again @@ -74,17 +73,15 @@ ; Remember if we have a pushed back character and reset the flag. -@L2: .if (.cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .cap(CPU_HAS_BITIMM) ldx #$00 bit #_FPUSHBACK + beq @L3 .else tax ; X = 0 lda (file),y and #_FPUSHBACK - .endif beq @L3 - - .if (.not .cpu .bitand ::CPU_ISET_65SC02) lda (file),y .endif and #<~_FPUSHBACK @@ -135,7 +132,7 @@ ; Copy the buffer pointer into ptr1, and increment the pointer value passed ; to read() by one, so read() starts to store data at buf+1. - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (c_sp) sta ptr1 add #1 @@ -159,7 +156,7 @@ ldy #_FILE::f_pushback lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr1) ; *buf = file->f_pushback; .else ldy #0 diff --git a/libsrc/common/fwrite.s b/libsrc/common/fwrite.s index e7151da95..6f631b816 100644 --- a/libsrc/common/fwrite.s +++ b/libsrc/common/fwrite.s @@ -16,8 +16,6 @@ .include "errno.inc" .include "_file.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Code @@ -34,7 +32,7 @@ ldy #_FILE::f_flags lda (ptr1),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN .else and #_FOPEN ; Is the file open? @@ -50,7 +48,7 @@ ; Check if the stream is in an error state -@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .not .cap(CPU_HAS_BITIMM) lda (ptr1),y ; get file->f_flags again .endif and #_FERROR diff --git a/libsrc/common/ltoa.s b/libsrc/common/ltoa.s index 78e43e23f..7c31d471f 100644 --- a/libsrc/common/ltoa.s +++ b/libsrc/common/ltoa.s @@ -10,8 +10,6 @@ .import __hextab, __longminstr .importzp sreg, ptr1, ptr2, ptr3, tmp1 - .macpack cpu - .code ; @@ -64,7 +62,7 @@ L2: txa ; get high byte bpl ultoa lda #'-' -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) .else ldy #0 diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index f9cd94633..963b037b9 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -8,7 +8,6 @@ .export _strcat .import popax .importzp ptr1, ptr2, tmp3 - .macpack cpu _strcat: sta ptr1 ; Save src @@ -16,7 +15,7 @@ _strcat: jsr popax ; Get dest sta tmp3 ; Remember for function return tay -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr2 .else lda #0 diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 206b5160e..ac7f5397a 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -8,14 +8,13 @@ .export _strchr .import popax .importzp ptr1, tmp1 - .macpack cpu _strchr: sta tmp1 ; Save c jsr popax ; get s tay ; low byte of pointer to y stx ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1 .else lda #0 diff --git a/libsrc/common/strdup.s b/libsrc/common/strdup.s index 94f2cd338..4cf643614 100644 --- a/libsrc/common/strdup.s +++ b/libsrc/common/strdup.s @@ -12,8 +12,6 @@ .import _strlen_ptr4, _malloc, _memcpy, pushax .export _strdup - .macpack cpu - _strdup: ; Get length (and store source in ptr4) sta ptr4 @@ -22,7 +20,7 @@ _strdup: jsr _strlen_ptr4 ; strlen may increment ; Add null byte for terminator -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) inc a .else clc diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index 75572db7c..e4e321591 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -8,64 +8,63 @@ .export _strncat .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1, tmp2 -.macpack cpu _strncat: - inx - stx tmp2 - tax - inx - stx tmp1 ; save count with each byte incremented separately + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately - jsr popptr1 ; get src + jsr popptr1 ; get src - jsr popax ; get dest - sta ptr3 ; remember for function return - stx ptr3+1 - stx ptr2+1 - tay ; low byte as offset in Y -.if (.cpu .bitand ::CPU_ISET_65SC02) - stz ptr2 + jsr popax ; get dest + sta ptr3 ; remember for function return + stx ptr3+1 + stx ptr2+1 + tay ; low byte as offset in Y +.if .cap(CPU_HAS_STZ) + stz ptr2 .else - ldx #0 - stx ptr2 ; destination on page boundary + ldx #0 + stx ptr2 ; destination on page boundary .endif ; find end of dest -L1: lda (ptr2),y - beq L2 - iny - bne L1 - inc ptr2+1 - bne L1 +L1: lda (ptr2),y + beq L2 + iny + bne L1 + inc ptr2+1 + bne L1 ; end found, apply offset to dest ptr and reset y -L2: sty ptr2 +L2: sty ptr2 ; copy src. We've put the ones complement of the count into the counter, so ; we'll increment the counter on top of the loop -L3: ldy #0 - ldx tmp1 ; low counter byte +L3: ldy #0 + ldx tmp1 ; low counter byte -L4: dex - bne L5 - dec tmp2 - beq L6 ; jump if done -L5: lda (ptr1),y - sta (ptr2),y - beq L7 - iny - bne L4 - inc ptr1+1 - inc ptr2+1 - bne L4 +L4: dex + bne L5 + dec tmp2 + beq L6 ; jump if done +L5: lda (ptr1),y + sta (ptr2),y + beq L7 + iny + bne L4 + inc ptr1+1 + inc ptr2+1 + bne L4 ; done, set the trailing zero and return pointer to dest -L6: lda #0 - sta (ptr2),y -L7: lda ptr3 - ldx ptr3+1 - rts +L6: lda #0 + sta (ptr2),y +L7: lda ptr3 + ldx ptr3+1 + rts diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index b822fddee..d6024c0e5 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -8,13 +8,12 @@ .export _cputsxy, _cputs .import gotoxy, _cputc .importzp ptr1, tmp1 - .macpack cpu _cputsxy: sta ptr1 ; Save s for later stx ptr1+1 jsr gotoxy ; Set cursor, pop x and y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra L0 ; Same as cputs... .else jmp L0 ; Same as cputs... @@ -24,7 +23,7 @@ _cputs: sta ptr1 ; Save s stx ptr1+1 L0: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; (5) .else ldy #0 ; (2) diff --git a/libsrc/conio/scrsize.s b/libsrc/conio/scrsize.s index 834c14820..fc1691b87 100644 --- a/libsrc/conio/scrsize.s +++ b/libsrc/conio/scrsize.s @@ -10,8 +10,6 @@ .import screensize .importzp ptr1, ptr2 - .macpack cpu - .proc _screensize sta ptr2 ; Store the y pointer @@ -20,7 +18,7 @@ jsr screensize ; Get screensize into X/Y tya ; Get Y size into A -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) txa sta (ptr1) diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index c6371f00e..aa7b6aa07 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -10,7 +10,6 @@ .importzp c_sp, ptr1, ptr2, ptr3, tmp1 .macpack generic - .macpack cpu .data @@ -74,7 +73,7 @@ out: jsr popax ; count ; Loop outputting characters -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND, CPU_HAS_BRA8) @L1: dec outdesc+6 beq @L4 diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index 85ddd0f25..b841f829d 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -11,14 +11,12 @@ .export tosadda0, tosaddax .importzp c_sp, tmp1 - .macpack cpu - tosadda0: ldx #0 tosaddax: clc ; (2) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; (7) tay ; (9) diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 8411660ab..303d4e010 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -8,12 +8,10 @@ .import addysp1 .importzp c_sp, ptr4 - .macpack cpu - tosanda0: ldx #$00 tosandax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index a99b713f5..fc187040e 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -18,8 +18,6 @@ .import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__ .import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__ - .macpack cpu - ; -------------------------------------------------------------------------- ; Initialize library modules diff --git a/libsrc/runtime/incax1.s b/libsrc/runtime/incax1.s index 19c1d0c60..bff94b019 100644 --- a/libsrc/runtime/incax1.s +++ b/libsrc/runtime/incax1.s @@ -7,11 +7,10 @@ .export incax1 .macpack generic - .macpack cpu .proc incax1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; 65C02 version bne @L9 .else diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index c3260c19d..395ea52cb 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -7,8 +7,6 @@ .export popax, incsp2 .importzp c_sp - .macpack cpu - ; Pop a/x from stack. This function will run directly into incsp2 .proc popax @@ -16,7 +14,7 @@ ldy #1 lda (c_sp),y ; get hi byte tax ; into x -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 6c187f32d..6991e4a7e 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - ; EAX = TOS + EAX tosadd0ax: @@ -19,7 +17,7 @@ tosadd0ax: tosaddeax: clc -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/laddeq.s b/libsrc/runtime/laddeq.s index 57bec0629..e5afac9cc 100644 --- a/libsrc/runtime/laddeq.s +++ b/libsrc/runtime/laddeq.s @@ -11,8 +11,6 @@ .export laddeq1, laddeqa, laddeq .importzp sreg, ptr1, tmp1 - .macpack cpu - laddeq1: lda #$01 @@ -24,7 +22,7 @@ laddeqa: laddeq: sty ptr1+1 ; Store high byte of address clc -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (ptr1) sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 400fede3b..2ad4ae4d7 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosand0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosand0ax: .endif tosandeax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index a808f6f84..5fbde5b62 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -7,8 +7,6 @@ .export ldau00sp, ldau0ysp .importzp c_sp, ptr1 - .macpack cpu - ldau00sp: ldy #1 ldau0ysp: @@ -18,7 +16,7 @@ ldau0ysp: lda (c_sp),y sta ptr1 ldx #0 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 408fdd159..afb069b1c 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -14,8 +14,6 @@ .import addysp .importzp c_sp - .macpack cpu - leave00: lda #0 leave0: ldx #0 @@ -28,7 +26,7 @@ leavey0: leavey: jsr addysp ; drop stack frame -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) leave: tay ; save A a sec lda (c_sp) ; that's the pushed arg size diff --git a/libsrc/runtime/lmod.s b/libsrc/runtime/lmod.s index b8e796dea..1cff216f3 100644 --- a/libsrc/runtime/lmod.s +++ b/libsrc/runtime/lmod.s @@ -11,10 +11,8 @@ .import poplsargs, udiv32, negeax .importzp sreg, ptr1, ptr2, tmp1, tmp3, tmp4 - .macpack cpu - tosmod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index a68c3e5c1..7124d6abd 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -9,11 +9,9 @@ .import addysp1 .importzp c_sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 - .macpack cpu - tosmul0ax: tosumul0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosmuleax: tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index 888a0c611..fa87aa63d 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosor0ax: .endif tosoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index 9690aff24..81dde42d3 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -9,8 +9,6 @@ .import incsp4 .importzp c_sp, sreg - .macpack cpu - popeax: ldy #3 lda (c_sp),y sta sreg+1 @@ -20,7 +18,7 @@ popeax: ldy #3 dey lda (c_sp),y tax -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index ec2c865af..fbc37b78c 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -12,13 +12,11 @@ .import decsp4 .importzp c_sp, sreg - .macpack cpu - pushl0: lda #0 tax push0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -39,7 +37,7 @@ pusheax: txa sta (c_sp),y pla -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) .else dey diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 456d8d8d5..b88d44f1a 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -12,10 +12,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosrsub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosrsub0ax: tosrsubeax: sec -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 17b225404..f0d34cd5b 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -11,10 +11,8 @@ .import addysp1 .importzp c_sp, sreg - .macpack cpu - tossub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tossub0ax: tossubeax: sec eor #$FF -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/lsubeq.s b/libsrc/runtime/lsubeq.s index b16ab18e1..d2d4ede7f 100644 --- a/libsrc/runtime/lsubeq.s +++ b/libsrc/runtime/lsubeq.s @@ -11,8 +11,6 @@ .export lsubeq1, lsubeqa, lsubeq .importzp sreg, ptr1 - .macpack cpu - lsubeq1: lda #$01 @@ -25,7 +23,7 @@ lsubeq: sty ptr1+1 ; Store high byte of address sec eor #$FF - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) adc (ptr1) ; Subtract byte 0 sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index b47207222..53651c789 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 - .macpack cpu - tosudiv0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -38,7 +36,7 @@ getlop: sta ptr3 ; Put right operand in place lda sreg+1 sta ptr4+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lumod.s b/libsrc/runtime/lumod.s index eb6176b35..a43c6d287 100644 --- a/libsrc/runtime/lumod.s +++ b/libsrc/runtime/lumod.s @@ -9,10 +9,8 @@ .import getlop, udiv32 .importzp sreg, tmp3, tmp4, ptr2 - .macpack cpu - tosumod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index 6d9f7db3a..abf341e63 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosxor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosxor0ax: .endif tosxoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 04389be5f..09aa93e79 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosora0: ldx #$00 tosorax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index c1700071d..bc490312e 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -7,11 +7,9 @@ .export popa .importzp c_sp - .macpack cpu - .proc popa -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 ; (2) diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 45043dd27..90dca5e22 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, ptr1 - .macpack cpu - .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else lda (c_sp),y ; get lo byte diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index c7f667246..0f6e5701d 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, sreg - .macpack cpu - popsreg: pha ; save A ldy #1 lda (c_sp),y ; get hi byte sta sreg+1 ; store it -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 399423077..6c715afb7 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -7,8 +7,6 @@ .export pusha0sp, pushaysp, pusha .importzp c_sp - .macpack cpu - ; Beware: The optimizer knows about this function! pusha0sp: diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index f77a9bcc3..5177f77b5 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -7,8 +7,6 @@ .export push0, pusha0, pushax .importzp c_sp - .macpack cpu - push0: lda #0 pusha0: ldx #0 @@ -31,7 +29,7 @@ pusha0: ldx #0 sta (c_sp),y ; (27) pla ; (31) dey ; (33) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; (37) .else sta (c_sp),y ; (38) diff --git a/libsrc/runtime/pushb.s b/libsrc/runtime/pushb.s index 7507ff21a..02d91b156 100644 --- a/libsrc/runtime/pushb.s +++ b/libsrc/runtime/pushb.s @@ -8,8 +8,6 @@ .import pushax .importzp ptr1 - .macpack cpu - pushbidx: sty ptr1 clc @@ -19,7 +17,7 @@ pushbidx: pushb: sta ptr1 stx ptr1+1 ldx #0 ; Load index/high byte -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index bacb3c7fc..1eedee53e 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -9,8 +9,6 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - ; ; AX = AX - TOS ; @@ -19,7 +17,7 @@ tosrsuba0: ldx #0 tosrsubax: sec -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/shl.s b/libsrc/runtime/shl.s index c1a4b6ef8..1f11eb5c0 100644 --- a/libsrc/runtime/shl.s +++ b/libsrc/runtime/shl.s @@ -15,8 +15,6 @@ .import popax .importzp tmp1 - .macpack cpu - tosshlax: tosaslax: sta tmp1 ; Save shift count @@ -55,7 +53,7 @@ L2: pla ; Shift count is exactly 8 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) L3: plx ; Low byte from stack into X rts ; A is already zero .else diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index aefed428f..e1542881f 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -9,8 +9,6 @@ .import incsp2 .importzp c_sp, tmp1, ptr1 - .macpack cpu - .proc staxspidx sty tmp1 ; Save Y @@ -18,7 +16,7 @@ ldy #1 lda (c_sp),y sta ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index a7ca39f21..f6ab28ea6 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -21,7 +21,6 @@ ; Use macros for better readability .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- @@ -39,7 +38,7 @@ lda c_sp+1 sta initialsp+1 sbc #>__STACKSIZE__ -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; Add 256 bytes safety area .else add #1 ; Add 256 bytes safety area diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index 58ffb4c91..7129e2147 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp - .macpack cpu - ; AX = TOS - AX tossuba0: @@ -17,7 +15,7 @@ tossuba0: tossubax: sec eor #$FF -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index 3796b0a97..72adaa90b 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -8,8 +8,6 @@ .export swapstk .importzp c_sp, ptr4 - .macpack cpu - swapstk: sta ptr4 stx ptr4+1 @@ -18,7 +16,7 @@ swapstk: tax lda ptr4+1 sta (c_sp),y -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) tay lda ptr4 diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index 2aaa19ccc..e879fe11f 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from long to int by cutting of the high 16bit .proc tosint pha -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index cf8eff031..c8b34d8b0 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -8,8 +8,6 @@ .import decsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from int to long tosulong: @@ -17,7 +15,7 @@ tosulong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else @@ -43,7 +41,7 @@ toslong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else diff --git a/libsrc/runtime/umul8x16r24.s b/libsrc/runtime/umul8x16r24.s index 54d730558..115a3e1a4 100644 --- a/libsrc/runtime/umul8x16r24.s +++ b/libsrc/runtime/umul8x16r24.s @@ -9,8 +9,6 @@ .include "zeropage.inc" - .macpack cpu - ;--------------------------------------------------------------------------- ; 8x16 => 24 unsigned multiplication routine. Because the overhead for a ; 8x16 => 16 unsigned multiplication routine is small, we will tag it with @@ -31,7 +29,7 @@ umul8x16r16: umul8x16r24m: umul8x16r16m: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1+1 stz sreg .else diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index 15394413c..1236b2c37 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosxora0: ldx #$00 tosxorax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ldy #1 .else diff --git a/libsrc/tgi/tgi_settextstyle.s b/libsrc/tgi/tgi_settextstyle.s index b62d6904c..bb924c048 100644 --- a/libsrc/tgi/tgi_settextstyle.s +++ b/libsrc/tgi/tgi_settextstyle.s @@ -9,8 +9,6 @@ .import umul8x16r24 .import popa, popax - .macpack cpu - ;----------------------------------------------------------------------------- ; void __fastcall__ tgi_settextstyle (unsigned width, unsigned height, ; unsigned char dir, unsigned char font); @@ -82,7 +80,7 @@ process_onedim: ; Disallowing characters larger than 256 pixels, we just drop the high byte ; and remember the low 16 bit as size in 8.8 format. -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) phy ; Save Y jsr umul8x16r24 ply ; Restore Y From 59e7158512043a18966ca68531a18ba67791afdb Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:29:42 +0200 Subject: [PATCH 05/11] Make the CPU_xxx constants from cpu.mac internal to the assembler and replace cpu.mac by a file that just emits a warning when used. --- asminc/cpu.mac | 42 ++---------- doc/ca65.sgml | 134 ++++++++++++++++++------------------- libsrc/apple2/cputc.s | 2 - libsrc/apple2/lseek.s | 1 - libsrc/apple2/ser/a2.ssc.s | 1 - libsrc/common/strlen.s | 1 - libsrc/sim6502/exehdr.s | 2 - src/ca65/main.c | 50 ++++++++++++++ 8 files changed, 119 insertions(+), 114 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 15b16bad5..092519173 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -1,38 +1,4 @@ -; CPU bitmask constants (make sure this matches src/common/cpu.h) - -CPU_ISET_NONE = $0001 -CPU_ISET_6502 = $0002 -CPU_ISET_6502X = $0004 -CPU_ISET_6502DTV = $0008 -CPU_ISET_65SC02 = $0010 -CPU_ISET_65C02 = $0020 ; Rockwell extensions -CPU_ISET_65816 = $0040 -CPU_ISET_SWEET16 = $0080 -CPU_ISET_HUC6280 = $0100 -CPU_ISET_M740 = $0200 -CPU_ISET_4510 = $0400 -CPU_ISET_45GS02 = $0800 -CPU_ISET_W65C02 = $1000 ; WDC extensions -CPU_ISET_65CE02 = $2000 ; CSG extensions - -; CPU capabilities -; make sure to only combine the instruction sets that are 100% compatible -CPU_NONE = CPU_ISET_NONE -CPU_6502 = CPU_ISET_6502 -CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502 -CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502 -CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502 -CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 - -; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect -; addressing was replaced with zp-indirect,z-indexed in 652SCE02 - -CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 -CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 -CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510 -CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 -CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02 - -CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_SWEET16 = CPU_ISET_SWEET16 +; This file is no longer needed as the symbols that were defined here are now +; internal symbols generated by the assembler. It is kept to avoid breaking +; old sources. +.warning "'.macpack cpu' is no longer required" diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cfe73a2f0..0f996ff64 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1401,16 +1401,76 @@ writable. Reading this pseudo variable will give a constant integer value that tells which CPU is currently enabled. It can also tell which instruction set the CPU is able to translate. The value read from the pseudo variable - should be further examined by using one of the constants defined by the - "cpu" macro package (see /). + should be further examined by using one of the following constants: - It may be used to replace the .IFPxx pseudo instructions or to construct - even more complex expressions. + + CPU_6502 + CPU_65SC02 + CPU_65C02 + CPU_65816 + CPU_SWEET16 + CPU_HUC6280 + CPU_4510 + CPU_45GS02 + CPU_6502DTV + CPU_M740 + + +Above constants may be used to determine the exact type of the currently +enabled CPU. In addition to that, for each CPU instruction set, another +constant is defined: + + + CPU_ISET_6502 + CPU_ISET_65SC02 + CPU_ISET_65C02 + CPU_ISET_65816 + CPU_ISET_SWEET16 + CPU_ISET_HUC6280 + CPU_ISET_4510 + CPU_ISET_45GS02 + CPU_ISET_6502DTV + CPU_ISET_M740 + + + + + - .macpack cpu .if (.cpu .bitand CPU_ISET_65816) phx phy @@ -1422,7 +1482,6 @@ writable. .endif - See also: @@ -5042,69 +5101,6 @@ This macro package defines a macro named .MACPACK cpu - -This macro package does not define any macros but constants used to examine -the value read from the / pseudo variable. For -each supported CPU a constant similar to - - - CPU_6502 - CPU_65SC02 - CPU_65C02 - CPU_65816 - CPU_SWEET16 - CPU_HUC6280 - CPU_4510 - CPU_45GS02 - CPU_6502DTV - CPU_M740 - - -is defined. These constants may be used to determine the exact type of the -currently enabled CPU. In addition to that, for each CPU instruction set, -another constant is defined: - - - CPU_ISET_6502 - CPU_ISET_65SC02 - CPU_ISET_65C02 - CPU_ISET_65816 - CPU_ISET_SWEET16 - CPU_ISET_HUC6280 - CPU_ISET_4510 - CPU_ISET_45GS02 - CPU_ISET_6502DTV - CPU_ISET_M740 - - -The value read from the / pseudo variable may -be checked with / to determine if the -currently enabled CPU supports a specific instruction set. For example the -65C02 supports all instructions of the 65SC02 CPU, so it has the - - .if (.cpu .bitand CPU_ISET_65SC02) - lda (c_sp) - .else - ldy #$00 - lda (c_sp),y - .endif - - -it is possible to determine if the - - - lda (c_sp) - - -instruction is supported, which is the case for the 65SC02, 65C02 and 65816 -CPUs (the latter two are upwards compatible to the 65SC02). - -see section and following. - .MACPACK module This macro package defines a macro named Date: Tue, 1 Jul 2025 08:34:38 +0200 Subject: [PATCH 06/11] Add an additional hook (currently unused) for target specific capabilities. --- src/ca65/expr.c | 3 ++- src/common/target.c | 10 ++++++++++ src/common/target.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 42b1a369b..33984610d 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -61,6 +61,7 @@ #include "studyexpr.h" #include "symbol.h" #include "symtab.h" +#include "target.h" #include "toklist.h" #include "ulabel.h" #include "macro.h" @@ -445,7 +446,7 @@ static ExprNode* FuncCapability (void) /* The pseudo function result is the logical AND of all capabilities ** given. */ - if (!CPUHasCap (Cap)) { + if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) { Result = 0; } } diff --git a/src/common/target.c b/src/common/target.c index a12f69bf9..bb67ddf9a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -37,6 +37,7 @@ #include /* common */ +#include "attrib.h" #include "chartype.h" #include "check.h" #include "target.h" @@ -302,3 +303,12 @@ const char* GetTargetName (target_t Target) /* Return the array entry */ return GetTargetProperties (Target)->Name; } + + + +int TargetHasCap (capability_t Cap attribute((unused))) +/* Check if the current target has the given capability */ +{ + /* Currently unused */ + return 0; +} diff --git a/src/common/target.h b/src/common/target.h index c5c8455a0..1dfa66ac7 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -39,6 +39,7 @@ /* common */ +#include "capability.h" #include "cpu.h" @@ -131,6 +132,9 @@ const TargetProperties* GetTargetProperties (target_t Target); const char* GetTargetName (target_t Target); /* Return the name of a target */ +int TargetHasCap (capability_t Cap); +/* Check if the current target has the given capability */ + /* End of target.h */ From 8d3112e24f93053bf8cd92ca5aa54d2f55339821 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:47:16 +0200 Subject: [PATCH 07/11] Small code simplification. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index d8c0dbd37..2f239d99d 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -233,5 +233,5 @@ int CPUHasCap (capability_t Cap) /* Check if the current CPU has the given capability */ { PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); - return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; + return (CPUCaps[CPU] & CAP_BIT (Cap)) != 0; } From c162f6a28636cd9cb04f5812532e53f87922b5f5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:21:18 +0200 Subject: [PATCH 08/11] Warning fix. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2f239d99d..7988cb4c1 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -151,7 +151,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ -static const uint64_t CPUCaps[CPU_COUNT] = { +static const uint32_t CPUCaps[CPU_COUNT] = { CAP_NONE, /* CPU_NONE */ CAP_6502, /* CPU_6502 */ CAP_6502X, /* CPU_6502X */ From 37414199c7f511eeee21a23bc0c1d184871fe92b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:33:38 +0200 Subject: [PATCH 09/11] Hopefully fix windows build files. --- src/common.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.vcxproj b/src/common.vcxproj index 6098c98a0..251ea3aeb 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -80,6 +80,7 @@ + @@ -133,6 +134,7 @@ + @@ -171,4 +173,4 @@ - \ No newline at end of file + From 60ec9045fce2c30aa4a24e46c59daaaccfab283a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:02:15 +0200 Subject: [PATCH 10/11] Use CPUIsets from cpu.c instead of recreating the CPU_xxx constants. --- src/ca65/main.c | 36 ++++++++++++++---------------------- src/common/cpu.c | 16 ++++++++++++++-- src/common/cpu.h | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fb0907df3..e9b36ee5d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -213,28 +213,20 @@ static void DefineCpuSymbols (void) /* Additional ones from cpu.mac. Not sure how useful they are after the ** changes from #2751. */ - NewSymbol ("CPU_NONE", CPU_ISET_NONE); - NewSymbol ("CPU_6502", CPU_ISET_6502); - NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); - NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); - NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); - NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | - CPU_ISET_65C02); - - /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the - ** zp-indirect addressing was replaced with zp-indirect,z-indexed in - ** 652SCE02 - */ - NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02); - NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02 | CPU_ISET_4510); - NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); - NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]); + NewSymbol ("CPU_6502", CPUIsets[CPU_6502]); + NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]); + NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]); + NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]); + NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]); + NewSymbol ("CPU_65816", CPUIsets[CPU_65816]); + NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]); + NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]); + NewSymbol ("CPU_M740", CPUIsets[CPU_M740]); + NewSymbol ("CPU_4510", CPUIsets[CPU_4510]); + NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]); + NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]); + NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]); } diff --git a/src/common/cpu.c b/src/common/cpu.c index 7988cb4c1..8e9ff827a 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -74,21 +74,33 @@ const char* CPUNames[CPU_COUNT] = { * NOTE: make sure to only combine the instruction sets that are 100% compatible */ const unsigned CPUIsets[CPU_COUNT] = { + /* CPU_NONE */ CPU_ISET_NONE, + /* CPU_6502 */ CPU_ISET_6502, + /* CPU_6502X */ CPU_ISET_6502X | CPU_ISET_6502, + /* CPU_6502DTV */ CPU_ISET_6502DTV | CPU_ISET_6502, + /* CPU_65SC02 */ CPU_ISET_65SC02 | CPU_ISET_6502, + /* CPU_65C02 */ CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* 65816 has wai/stp and NO bit manipulation */ + /* CPU_65816. 65816 has wai/stp and NO bit manipulation. */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* CPU_SWEET16 */ CPU_ISET_SWEET16, + /* CPU_HUC6280 */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_M740 */ CPU_ISET_M740 | CPU_ISET_6502, - /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* CPU_4510. 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + /* CPU_45GS02 */ CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, + /* CPU_W65C02 */ CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_65CE02 */ CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 0a7c853ac..bc6260371 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -69,7 +69,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ +/* CPU instruction sets */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From 070276a1a3baa9fbfca42555b306e0d9caac8436 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:19:19 +0200 Subject: [PATCH 11/11] Add a better description for CPU_HAS_ZPIND and CPU_HAS_STZ. --- doc/ca65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0f996ff64..63a1be7e9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1681,10 +1681,12 @@ either a string or an expression value. Checks for the capability to push and pop the X and Y registers. CPU_HAS_ZPIND - Checks for the availability of the "zeropage indirect" addressing mode. + Checks for the availability of the "zeropage indirect" addressing mode as it + is implemented in the 65SC02 CPU. CPU_HAS_STZ - Checks for the availability of the "store zero" instruction. + Checks for the availability of the "store zero" instruction as it is + implemented in the 65SC02 CPU.
Builtin string function. The function allows to concatenate a list of string diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 5dcf5ca71..42b1a369b 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -37,6 +37,7 @@ #include /* common */ +#include "capability.h" #include "check.h" #include "cpu.h" #include "exprdefs.h" @@ -405,6 +406,66 @@ static ExprNode* FuncBlank (void) +static ExprNode* FuncCapability (void) +/* Handle the .CAPABILITY builtin function */ +{ + int Result = 1; + + /* What follows is a comma separated list of identifiers. An empty list is + ** not allowed. + */ + while (1) { + + const char* Name; + capability_t Cap; + + /* We must have an identifier */ + if (CurTok.Tok != TOK_IDENT) { + Error ("Arguments to .CAPABILITY must be identifiers"); + /* Skip tokens until closing paren or end of line */ + while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) { + NextTok (); + } + return GenLiteral0 (); + } + + /* Search for the capability that matches this identifier. Ignore case + ** on the specified capabilities. + */ + UpcaseSVal (); + SB_Terminate (&CurTok.SVal); + Name = SB_GetConstBuf (&CurTok.SVal); + Cap = FindCapability (Name); + + /* Check if the capability is supported */ + if (Cap == CAP_INVALID) { + Error ("Not a valid capability name: %s", Name); + Result = 0; + } else { + /* The pseudo function result is the logical AND of all capabilities + ** given. + */ + if (!CPUHasCap (Cap)) { + Result = 0; + } + } + + /* Skip the capability name */ + NextTok (); + + /* Handle end of list or next capability */ + if (CurTok.Tok != TOK_COMMA) { + break; + } + NextTok (); + } + + /* Done */ + return GenLiteralExpr (Result); +} + + + static ExprNode* FuncConst (void) /* Handle the .CONST builtin function */ { @@ -484,9 +545,10 @@ static ExprNode* FuncIsMnemonic (void) if (FindMacro (&CurTok.SVal) == 0) { Instr = FindInstruction (&CurTok.SVal); } - } - else { - /* Macros and symbols may NOT use the names of instructions, so just check for the instruction */ + } else { + /* Macros and symbols may NOT use the names of instructions, so + ** just check for the instruction. + */ Instr = FindInstruction (&CurTok.SVal); } } @@ -532,7 +594,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) token_t Term = GetTokListTerm (TOK_COMMA); while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -570,7 +632,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) Node = Root; while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -1129,6 +1191,10 @@ static ExprNode* Factor (void) N = Function (FuncBlank); break; + case TOK_CAP: + N = Function (FuncCapability); + break; + case TOK_CONST: N = Function (FuncConst); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index e6e10df2c..301129583 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -2114,7 +2114,8 @@ struct CtrlDesc { }; /* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR - and .XOR do NOT go into this table */ +** and .XOR do NOT go into this table. +*/ #define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0])) static CtrlDesc CtrlCmdTab [] = { { ccNone, DoA16 }, /* .A16 */ @@ -2132,6 +2133,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .BLANK */ { ccNone, DoBss }, /* .BSS */ { ccNone, DoByte }, /* .BYT, .BYTE */ + { ccNone, DoUnexpected }, /* .CAP */ { ccNone, DoCase }, /* .CASE */ { ccNone, DoCharMap }, /* .CHARMAP */ { ccNone, DoCode }, /* .CODE */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f3892d32e..a2a72a149 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -158,6 +158,8 @@ struct DotKeyword { { ".BSS", TOK_BSS }, { ".BYT", TOK_BYTE }, { ".BYTE", TOK_BYTE }, + { ".CAP", TOK_CAP }, + { ".CAPABILITY", TOK_CAP }, { ".CASE", TOK_CASE }, { ".CHARMAP", TOK_CHARMAP }, { ".CODE", TOK_CODE }, diff --git a/src/ca65/token.h b/src/ca65/token.h index e2b223880..b40534d79 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -137,6 +137,7 @@ typedef enum token_t { TOK_BLANK, TOK_BSS, TOK_BYTE, + TOK_CAP, TOK_CASE, TOK_CHARMAP, TOK_CODE, diff --git a/src/common/capability.c b/src/common/capability.c new file mode 100644 index 000000000..f66205e7c --- /dev/null +++ b/src/common/capability.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* capability.c */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include + +/* ca65 */ +#include "capability.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* List of dot keywords with the corresponding ids. */ +/* CAUTION: table must be sorted for bsearch. */ +struct Capability { + const char* Key; + capability_t Cap; +} Capabilities [] = { +/* BEGIN SORTED.SH */ + { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, + { "CPU_HAS_INA", CAP_CPU_HAS_INA }, + { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, + { "CPU_HAS_STZ", CAP_CPU_HAS_STZ }, + { "CPU_HAS_ZPIND", CAP_CPU_HAS_ZPIND }, +/* END SORTED.SH */ +}; +#define CAP_TABLE_SIZE (sizeof (Capabilities) / sizeof (Capabilities [0])) + + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static int CmpCapability (const void* K1, const void* K2) +/* Compare function for the capability search */ +{ + return strcmp (((struct Capability*)K1)->Key, ((struct Capability*)K2)->Key); +} + + + +capability_t FindCapability (const char* Name) +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ +{ + const struct Capability K = { Name, 0 }; + const struct Capability* C = bsearch (&K, Capabilities, CAP_TABLE_SIZE, + sizeof (Capabilities [0]), + CmpCapability); + return (C == 0)? CAP_INVALID : C->Cap; +} diff --git a/src/common/capability.h b/src/common/capability.h new file mode 100644 index 000000000..011e2164f --- /dev/null +++ b/src/common/capability.h @@ -0,0 +1,78 @@ +/*****************************************************************************/ +/* */ +/* capability.h */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef CAPABILITY_H +#define CAPABILITY_H + + + +/* common */ +#include "strbuf.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Numeric codes for capabilities */ +enum capability_t { + CAP_INVALID = -1, + CAP_CPU_HAS_BRA8 = 0, /* CPU has a BRA 8-bit instruction */ + CAP_CPU_HAS_INA = 1, /* CPU has DEA/INA */ + CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ + CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ + CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ +}; +typedef enum capability_t capability_t; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +capability_t FindCapability (const char* Name); +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ + + + +/* End of capability.h */ + +#endif diff --git a/src/common/cpu.c b/src/common/cpu.c index 252283211..cdc8e52cc 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -33,6 +33,8 @@ +#include + /* common */ #include "addrsize.h" #include "check.h" @@ -90,6 +92,77 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; +/* Defines for capabilities. Currently the entries are uint32_ts but the table +** is deliberately hidden from the outside so it can be extended to 64 bit or +** even more. +*/ +#define CAP_NONE UINT32_C (0) +#define CAP_6502 UINT32_C (0) +#define CAP_6502X UINT32_C (0) +#define CAP_6502DTV UINT32_C (0) +#define CAP_65SC02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65816 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 UINT32_C (0) +#define CAP_HUC6280 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_M740 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA)) +#define CAP_4510 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_45GS02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_W65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_65CE02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + +/* Table containing one capability entry per CPU */ +static const uint64_t CPUCaps[CPU_COUNT] = { + CAP_NONE, /* CPU_NONE */ + CAP_6502, /* CPU_6502 */ + CAP_6502X, /* CPU_6502X */ + CAP_6502DTV, /* CPU_6502DTV */ + CAP_65SC02, /* CPU_65SC02 */ + CAP_65C02, /* CPU_65C02 */ + CAP_65816, /* CPU_65816 */ + CAP_SWEET16, /* CPU_SWEET16 */ + CAP_HUC6280, /* CPU_HUC6280 */ + CAP_M740, /* CPU_M740 */ + CAP_4510, /* CPU_4510 */ + CAP_45GS02, /* CPU_45GS02 */ + CAP_W65C02, /* CPU_W65C02 */ + CAP_65CE02, /* CPU_65CE02 */ +}; + /*****************************************************************************/ @@ -148,3 +221,12 @@ cpu_t FindCPU (const char* Name) /* Not found */ return CPU_UNKNOWN; } + + + +int CPUHasCap (capability_t Cap) +/* Check if the current CPU has the given capability */ +{ + PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); + return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; +} diff --git a/src/common/cpu.h b/src/common/cpu.h index 4202ed573..0a7c853ac 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -38,6 +38,11 @@ +/* common */ +#include "capability.h" + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -107,6 +112,9 @@ cpu_t FindCPU (const char* Name); ** the given name is no valid target. */ +int CPUHasCap (capability_t Cap); +/* Check if the current CPU has the given capability */ + /* End of cpu.h */ diff --git a/test/asm/listing/110-capabilities.s b/test/asm/listing/110-capabilities.s new file mode 100644 index 000000000..e3e306ca7 --- /dev/null +++ b/test/asm/listing/110-capabilities.s @@ -0,0 +1,39 @@ + +; Error: Arguments to .CAPABILITY must be identifiers +.if .cap() +.endif + +; Error: Arguments to .CAPABILITY must be identifiers +; Error: ')' expected +.if .cap( +.endif + +; Error: Not a valid capability name: CPU_HAS_BR +.if .cap(cpu_has_br) +.endif + +; Error: ')' expected +; Error: Unexpected trailing garbage characters +.if .cap(cpu_has_bra8 cpu_has_bra8) +.endif + +; Ok +.if .cap(cpu_has_bra8, CPU_HAS_PUSHXY, CPU_HAS_STZ, CPU_HAS_INA) +.endif + +.setcpu "65SC02" +.if !.cap(cpu_has_bra8) +.error "Assembler says 65SC02 has no 8 bit bra" +.endif +.if !.cap(cpu_has_PUSHXY) +.error "Assembler says 65SC02 has no phx" +.endif +.if !.cap(cpu_has_STZ) +.error "Assembler says 65SC02 has no stz" +.endif +.if !.cap(cpu_has_INA) +.error "Assembler says 65SC02 has no ina" +.endif + + + diff --git a/test/asm/listing/control/110-capabilities.err b/test/asm/listing/control/110-capabilities.err new file mode 100644 index 000000000..e69de29bb diff --git a/test/asm/listing/ref/110-capabilities.err2-ref b/test/asm/listing/ref/110-capabilities.err2-ref new file mode 100644 index 000000000..e00e60e17 --- /dev/null +++ b/test/asm/listing/ref/110-capabilities.err2-ref @@ -0,0 +1,6 @@ +110-capabilities.s:3: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: ')' expected +110-capabilities.s:12: Error: Not a valid capability name: CPU_HAS_BR +110-capabilities.s:17: Error: ')' expected +110-capabilities.s:17: Error: Unexpected trailing garbage characters From f333b300f1c542b952580420259f6d79db7977f1 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:16:33 +0200 Subject: [PATCH 03/11] Added the CPU_HAS_BITIMM capability. --- doc/ca65.sgml | 3 ++ src/common/capability.c | 1 + src/common/capability.h | 1 + src/common/cpu.c | 81 ++++++++++++++++++++++------------------- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 552309ff9..cfe73a2f0 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1609,6 +1609,9 @@ either a string or an expression value. + CPU_HAS_BITIMM + Checks for the availability of the "bit #imm" instruction. + CPU_HAS_BRA8 Checks for the availability of a short (8 bit) branch. diff --git a/src/common/capability.c b/src/common/capability.c index f66205e7c..19c3ed838 100644 --- a/src/common/capability.c +++ b/src/common/capability.c @@ -50,6 +50,7 @@ struct Capability { capability_t Cap; } Capabilities [] = { /* BEGIN SORTED.SH */ + { "CPU_HAS_BITIMM", CAP_CPU_HAS_BITIMM }, { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, { "CPU_HAS_INA", CAP_CPU_HAS_INA }, { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, diff --git a/src/common/capability.h b/src/common/capability.h index 011e2164f..b0332c72e 100644 --- a/src/common/capability.h +++ b/src/common/capability.h @@ -54,6 +54,7 @@ enum capability_t { CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ + CAP_CPU_HAS_BITIMM = 5, /* CPU has "bit #imm" instruction */ }; typedef enum capability_t capability_t; diff --git a/src/common/cpu.c b/src/common/cpu.c index cdc8e52cc..d8c0dbd37 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -96,54 +96,59 @@ const unsigned CPUIsets[CPU_COUNT] = { ** is deliberately hidden from the outside so it can be extended to 64 bit or ** even more. */ +#define CAP_BIT(Cap) (UINT32_C (1) << (Cap)) #define CAP_NONE UINT32_C (0) -#define CAP_6502 UINT32_C (0) -#define CAP_6502X UINT32_C (0) -#define CAP_6502DTV UINT32_C (0) +#define CAP_6502 CAP_NONE +#define CAP_6502X CAP_NONE +#define CAP_6502DTV CAP_NONE #define CAP_65SC02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65816 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) -#define CAP_SWEET16 UINT32_C (0) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 CAP_NONE #define CAP_HUC6280 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_M740 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA)) #define CAP_4510 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_45GS02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_W65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_65CE02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ static const uint64_t CPUCaps[CPU_COUNT] = { From c72126e68fc879229b677baf6443ed242b0262f7 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:25:32 +0200 Subject: [PATCH 04/11] Changed most of the library sources to use .CAP instead of .CPU. --- libsrc/cbm/clock.s | 3 +- libsrc/common/_directerrno.s | 4 +- libsrc/common/_heapblocksize.s | 3 +- libsrc/common/_mappederrno.s | 3 +- libsrc/common/_printf.s | 11 ++--- libsrc/common/_time_t_to_tm.s | 4 +- libsrc/common/asctime.s | 6 +-- libsrc/common/atexit.s | 10 ++-- libsrc/common/fgetc.s | 4 +- libsrc/common/fgets.s | 8 ++-- libsrc/common/fread.s | 15 +++--- libsrc/common/fwrite.s | 6 +-- libsrc/common/ltoa.s | 4 +- libsrc/common/strcat.s | 3 +- libsrc/common/strchr.s | 3 +- libsrc/common/strdup.s | 4 +- libsrc/common/strncat.s | 83 +++++++++++++++++----------------- libsrc/conio/cputs.s | 5 +- libsrc/conio/scrsize.s | 4 +- libsrc/conio/vcprintf.s | 3 +- libsrc/runtime/add.s | 4 +- libsrc/runtime/and.s | 4 +- libsrc/runtime/condes.s | 2 - libsrc/runtime/incax1.s | 3 +- libsrc/runtime/incsp2.s | 4 +- libsrc/runtime/ladd.s | 4 +- libsrc/runtime/laddeq.s | 4 +- libsrc/runtime/land.s | 6 +-- libsrc/runtime/ldau0sp.s | 4 +- libsrc/runtime/leave.s | 4 +- libsrc/runtime/lmod.s | 4 +- libsrc/runtime/lmul.s | 6 +-- libsrc/runtime/lor.s | 6 +-- libsrc/runtime/lpop.s | 4 +- libsrc/runtime/lpush.s | 6 +-- libsrc/runtime/lrsub.s | 6 +-- libsrc/runtime/lsub.s | 6 +-- libsrc/runtime/lsubeq.s | 4 +- libsrc/runtime/ludiv.s | 6 +-- libsrc/runtime/lumod.s | 4 +- libsrc/runtime/lxor.s | 6 +-- libsrc/runtime/or.s | 4 +- libsrc/runtime/popa.s | 4 +- libsrc/runtime/popptr1.s | 4 +- libsrc/runtime/popsreg.s | 4 +- libsrc/runtime/pusha.s | 2 - libsrc/runtime/pushax.s | 4 +- libsrc/runtime/pushb.s | 4 +- libsrc/runtime/rsub.s | 4 +- libsrc/runtime/shl.s | 4 +- libsrc/runtime/staxspi.s | 4 +- libsrc/runtime/stkchk.s | 3 +- libsrc/runtime/sub.s | 4 +- libsrc/runtime/swap.s | 4 +- libsrc/runtime/tosint.s | 4 +- libsrc/runtime/toslong.s | 6 +-- libsrc/runtime/umul8x16r24.s | 4 +- libsrc/runtime/xor.s | 4 +- libsrc/tgi/tgi_settextstyle.s | 4 +- 59 files changed, 122 insertions(+), 232 deletions(-) diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index 90e4263a8..91fde6f58 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -9,14 +9,13 @@ .importzp sreg .include "cbm.inc" - .macpack cpu .proc _clock ; Some accelerator adaptors have CMOS ICs. -.if (.cpu & ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg + 1 .else lda #$00 ; Byte 3 always is zero diff --git a/libsrc/common/_directerrno.s b/libsrc/common/_directerrno.s index 20060bdd7..74e2f89cd 100644 --- a/libsrc/common/_directerrno.s +++ b/libsrc/common/_directerrno.s @@ -7,8 +7,6 @@ .include "errno.inc" - .macpack cpu - ; ---------------------------------------------------------------------------- ; int __fastcall__ __directerrno (unsigned char code); ; /* Set errno to a specific error code, clear __oserror, and return -1. Used @@ -18,7 +16,7 @@ ___directerrno: jsr ___seterrno ; Set errno (returns with .A = 0) sta ___oserror ; Clear ___oserror -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 diff --git a/libsrc/common/_heapblocksize.s b/libsrc/common/_heapblocksize.s index e9b0cdad9..774056032 100644 --- a/libsrc/common/_heapblocksize.s +++ b/libsrc/common/_heapblocksize.s @@ -12,7 +12,6 @@ .include "_heap.inc" .macpack generic - .macpack cpu ;----------------------------------------------------------------------------- ; Code @@ -39,7 +38,7 @@ ___heapblocksize: ldy #usedblock::size+1 lda (ptr2),y tax -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr2) .else dey diff --git a/libsrc/common/_mappederrno.s b/libsrc/common/_mappederrno.s index 83565b723..4ea3174b6 100644 --- a/libsrc/common/_mappederrno.s +++ b/libsrc/common/_mappederrno.s @@ -8,7 +8,6 @@ .include "errno.inc" .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; int __fastcall__ __mappederrno (unsigned char code); @@ -24,7 +23,7 @@ ___mappederrno: bze ok ; Branch if no jsr ___osmaperrno ; Map OS error into errno code jsr ___seterrno ; Save in errno (returns with .A = 0) -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 if error diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index 40ab0bc64..335485cc6 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -13,7 +13,6 @@ .import _strlower, _strlen .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; We will store variables into the register bank in the zeropage. Define @@ -38,7 +37,7 @@ FCount = ptr2 GetFormatChar: ldy #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (Format) .else lda (Format),y @@ -115,7 +114,7 @@ GetIntArg: lda (ArgList),y tax dey - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (ArgList) .else lda (ArgList),y @@ -274,7 +273,7 @@ Save: lda regbank,y ; Initialize the output counter in the output descriptor to zero lda #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (OutData) ldy #$01 sta (OutData),y @@ -353,7 +352,7 @@ MainLoop: sta (c_sp),y dey lda FCount - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (c_sp) .else sta (c_sp),y @@ -570,7 +569,7 @@ CheckCount: jsr GetIntArg sta ptr1 stx ptr1+1 ; Get user supplied pointer - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (OutData) ; Low byte of OutData->ccount sta (ptr1) ldy #1 diff --git a/libsrc/common/_time_t_to_tm.s b/libsrc/common/_time_t_to_tm.s index 9bcf84184..21e662384 100644 --- a/libsrc/common/_time_t_to_tm.s +++ b/libsrc/common/_time_t_to_tm.s @@ -16,8 +16,6 @@ .include "time.inc" - .macpack cpu - __time_t_to_tm: ; Divide number of seconds since epoch, in ptr1:sreg, ; by 86400 to get the number of days since epoch, and @@ -80,7 +78,7 @@ __time_t_to_tm: ; Zero the two high bytes of the divisor and the high byte ; of the dividend. - .if .cpu .bitand CPU_ISET_65SC02 + .if .cap(CPU_HAS_STZ) stz ptr4 stz ptr4+1 stz sreg+1 diff --git a/libsrc/common/asctime.s b/libsrc/common/asctime.s index efcf34b41..b56371594 100644 --- a/libsrc/common/asctime.s +++ b/libsrc/common/asctime.s @@ -9,8 +9,6 @@ .importzp ptr1 .include "time.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Special values @@ -24,7 +22,7 @@ MAX_BUF_LEN = 38 _asctime: ; Backup timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) pha phx .else @@ -48,7 +46,7 @@ _asctime: jsr pushax ; Restore timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) plx pla .else diff --git a/libsrc/common/atexit.s b/libsrc/common/atexit.s index 47a1dfd4d..ccbc2e69f 100644 --- a/libsrc/common/atexit.s +++ b/libsrc/common/atexit.s @@ -10,8 +10,6 @@ .include "errno.inc" - .macpack cpu - ; --------------------------------------------------------------------------- .proc _atexit @@ -41,7 +39,7 @@ jsr ___seterrno ldx #$FF ; Return -1 txa - rts +Exit: rts .endproc @@ -54,7 +52,7 @@ .proc doatexit ldy exitfunc_index ; Get index - beq @L9 ; Jump if done + beq _atexit::Exit ; Jump if done dey lda exitfunc_table,y tax @@ -62,14 +60,12 @@ lda exitfunc_table,y sty exitfunc_index jsr callax ; Call the function -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra doatexit .else jmp doatexit ; Next one .endif -@L9: rts - .endproc diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s index 34d4df3aa..6d08f69a3 100644 --- a/libsrc/common/fgetc.s +++ b/libsrc/common/fgetc.s @@ -12,8 +12,6 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - _fgetc: sta ptr1 stx ptr1+1 @@ -22,7 +20,7 @@ _fgetc: jsr checkferror bne ret_eof - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FPUSHBACK ; Check for pushed back char beq do_read .else diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index c25664f19..fde3a78a9 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -14,12 +14,10 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - terminate_ptr: lda #$00 tax - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else tay @@ -41,7 +39,7 @@ _fgets: sta buf stx buf+1 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_STZ) stz didread .else lda #$00 ; We have read nothing yet @@ -79,7 +77,7 @@ read_loop: ldy #$01 sty didread ; We read at least one char - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else dey diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index be06c2a62..beb9e707e 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -20,7 +20,6 @@ .include "_file.inc" .macpack generic - .macpack cpu ; ------------------------------------------------------------------------ ; Code @@ -48,7 +47,7 @@ ldy #_FILE::f_flags lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN ; Is the file open? .else and #_FOPEN ; Is the file open? @@ -57,7 +56,7 @@ ; Check if the stream is in an error state - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FERROR .else lda (file),y ; get file->f_flags again @@ -74,17 +73,15 @@ ; Remember if we have a pushed back character and reset the flag. -@L2: .if (.cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .cap(CPU_HAS_BITIMM) ldx #$00 bit #_FPUSHBACK + beq @L3 .else tax ; X = 0 lda (file),y and #_FPUSHBACK - .endif beq @L3 - - .if (.not .cpu .bitand ::CPU_ISET_65SC02) lda (file),y .endif and #<~_FPUSHBACK @@ -135,7 +132,7 @@ ; Copy the buffer pointer into ptr1, and increment the pointer value passed ; to read() by one, so read() starts to store data at buf+1. - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (c_sp) sta ptr1 add #1 @@ -159,7 +156,7 @@ ldy #_FILE::f_pushback lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr1) ; *buf = file->f_pushback; .else ldy #0 diff --git a/libsrc/common/fwrite.s b/libsrc/common/fwrite.s index e7151da95..6f631b816 100644 --- a/libsrc/common/fwrite.s +++ b/libsrc/common/fwrite.s @@ -16,8 +16,6 @@ .include "errno.inc" .include "_file.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Code @@ -34,7 +32,7 @@ ldy #_FILE::f_flags lda (ptr1),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN .else and #_FOPEN ; Is the file open? @@ -50,7 +48,7 @@ ; Check if the stream is in an error state -@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .not .cap(CPU_HAS_BITIMM) lda (ptr1),y ; get file->f_flags again .endif and #_FERROR diff --git a/libsrc/common/ltoa.s b/libsrc/common/ltoa.s index 78e43e23f..7c31d471f 100644 --- a/libsrc/common/ltoa.s +++ b/libsrc/common/ltoa.s @@ -10,8 +10,6 @@ .import __hextab, __longminstr .importzp sreg, ptr1, ptr2, ptr3, tmp1 - .macpack cpu - .code ; @@ -64,7 +62,7 @@ L2: txa ; get high byte bpl ultoa lda #'-' -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) .else ldy #0 diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index f9cd94633..963b037b9 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -8,7 +8,6 @@ .export _strcat .import popax .importzp ptr1, ptr2, tmp3 - .macpack cpu _strcat: sta ptr1 ; Save src @@ -16,7 +15,7 @@ _strcat: jsr popax ; Get dest sta tmp3 ; Remember for function return tay -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr2 .else lda #0 diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 206b5160e..ac7f5397a 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -8,14 +8,13 @@ .export _strchr .import popax .importzp ptr1, tmp1 - .macpack cpu _strchr: sta tmp1 ; Save c jsr popax ; get s tay ; low byte of pointer to y stx ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1 .else lda #0 diff --git a/libsrc/common/strdup.s b/libsrc/common/strdup.s index 94f2cd338..4cf643614 100644 --- a/libsrc/common/strdup.s +++ b/libsrc/common/strdup.s @@ -12,8 +12,6 @@ .import _strlen_ptr4, _malloc, _memcpy, pushax .export _strdup - .macpack cpu - _strdup: ; Get length (and store source in ptr4) sta ptr4 @@ -22,7 +20,7 @@ _strdup: jsr _strlen_ptr4 ; strlen may increment ; Add null byte for terminator -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) inc a .else clc diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index 75572db7c..e4e321591 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -8,64 +8,63 @@ .export _strncat .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1, tmp2 -.macpack cpu _strncat: - inx - stx tmp2 - tax - inx - stx tmp1 ; save count with each byte incremented separately + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately - jsr popptr1 ; get src + jsr popptr1 ; get src - jsr popax ; get dest - sta ptr3 ; remember for function return - stx ptr3+1 - stx ptr2+1 - tay ; low byte as offset in Y -.if (.cpu .bitand ::CPU_ISET_65SC02) - stz ptr2 + jsr popax ; get dest + sta ptr3 ; remember for function return + stx ptr3+1 + stx ptr2+1 + tay ; low byte as offset in Y +.if .cap(CPU_HAS_STZ) + stz ptr2 .else - ldx #0 - stx ptr2 ; destination on page boundary + ldx #0 + stx ptr2 ; destination on page boundary .endif ; find end of dest -L1: lda (ptr2),y - beq L2 - iny - bne L1 - inc ptr2+1 - bne L1 +L1: lda (ptr2),y + beq L2 + iny + bne L1 + inc ptr2+1 + bne L1 ; end found, apply offset to dest ptr and reset y -L2: sty ptr2 +L2: sty ptr2 ; copy src. We've put the ones complement of the count into the counter, so ; we'll increment the counter on top of the loop -L3: ldy #0 - ldx tmp1 ; low counter byte +L3: ldy #0 + ldx tmp1 ; low counter byte -L4: dex - bne L5 - dec tmp2 - beq L6 ; jump if done -L5: lda (ptr1),y - sta (ptr2),y - beq L7 - iny - bne L4 - inc ptr1+1 - inc ptr2+1 - bne L4 +L4: dex + bne L5 + dec tmp2 + beq L6 ; jump if done +L5: lda (ptr1),y + sta (ptr2),y + beq L7 + iny + bne L4 + inc ptr1+1 + inc ptr2+1 + bne L4 ; done, set the trailing zero and return pointer to dest -L6: lda #0 - sta (ptr2),y -L7: lda ptr3 - ldx ptr3+1 - rts +L6: lda #0 + sta (ptr2),y +L7: lda ptr3 + ldx ptr3+1 + rts diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index b822fddee..d6024c0e5 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -8,13 +8,12 @@ .export _cputsxy, _cputs .import gotoxy, _cputc .importzp ptr1, tmp1 - .macpack cpu _cputsxy: sta ptr1 ; Save s for later stx ptr1+1 jsr gotoxy ; Set cursor, pop x and y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra L0 ; Same as cputs... .else jmp L0 ; Same as cputs... @@ -24,7 +23,7 @@ _cputs: sta ptr1 ; Save s stx ptr1+1 L0: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; (5) .else ldy #0 ; (2) diff --git a/libsrc/conio/scrsize.s b/libsrc/conio/scrsize.s index 834c14820..fc1691b87 100644 --- a/libsrc/conio/scrsize.s +++ b/libsrc/conio/scrsize.s @@ -10,8 +10,6 @@ .import screensize .importzp ptr1, ptr2 - .macpack cpu - .proc _screensize sta ptr2 ; Store the y pointer @@ -20,7 +18,7 @@ jsr screensize ; Get screensize into X/Y tya ; Get Y size into A -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) txa sta (ptr1) diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index c6371f00e..aa7b6aa07 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -10,7 +10,6 @@ .importzp c_sp, ptr1, ptr2, ptr3, tmp1 .macpack generic - .macpack cpu .data @@ -74,7 +73,7 @@ out: jsr popax ; count ; Loop outputting characters -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND, CPU_HAS_BRA8) @L1: dec outdesc+6 beq @L4 diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index 85ddd0f25..b841f829d 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -11,14 +11,12 @@ .export tosadda0, tosaddax .importzp c_sp, tmp1 - .macpack cpu - tosadda0: ldx #0 tosaddax: clc ; (2) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; (7) tay ; (9) diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 8411660ab..303d4e010 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -8,12 +8,10 @@ .import addysp1 .importzp c_sp, ptr4 - .macpack cpu - tosanda0: ldx #$00 tosandax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index a99b713f5..fc187040e 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -18,8 +18,6 @@ .import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__ .import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__ - .macpack cpu - ; -------------------------------------------------------------------------- ; Initialize library modules diff --git a/libsrc/runtime/incax1.s b/libsrc/runtime/incax1.s index 19c1d0c60..bff94b019 100644 --- a/libsrc/runtime/incax1.s +++ b/libsrc/runtime/incax1.s @@ -7,11 +7,10 @@ .export incax1 .macpack generic - .macpack cpu .proc incax1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; 65C02 version bne @L9 .else diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index c3260c19d..395ea52cb 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -7,8 +7,6 @@ .export popax, incsp2 .importzp c_sp - .macpack cpu - ; Pop a/x from stack. This function will run directly into incsp2 .proc popax @@ -16,7 +14,7 @@ ldy #1 lda (c_sp),y ; get hi byte tax ; into x -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 6c187f32d..6991e4a7e 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - ; EAX = TOS + EAX tosadd0ax: @@ -19,7 +17,7 @@ tosadd0ax: tosaddeax: clc -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/laddeq.s b/libsrc/runtime/laddeq.s index 57bec0629..e5afac9cc 100644 --- a/libsrc/runtime/laddeq.s +++ b/libsrc/runtime/laddeq.s @@ -11,8 +11,6 @@ .export laddeq1, laddeqa, laddeq .importzp sreg, ptr1, tmp1 - .macpack cpu - laddeq1: lda #$01 @@ -24,7 +22,7 @@ laddeqa: laddeq: sty ptr1+1 ; Store high byte of address clc -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (ptr1) sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 400fede3b..2ad4ae4d7 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosand0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosand0ax: .endif tosandeax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index a808f6f84..5fbde5b62 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -7,8 +7,6 @@ .export ldau00sp, ldau0ysp .importzp c_sp, ptr1 - .macpack cpu - ldau00sp: ldy #1 ldau0ysp: @@ -18,7 +16,7 @@ ldau0ysp: lda (c_sp),y sta ptr1 ldx #0 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 408fdd159..afb069b1c 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -14,8 +14,6 @@ .import addysp .importzp c_sp - .macpack cpu - leave00: lda #0 leave0: ldx #0 @@ -28,7 +26,7 @@ leavey0: leavey: jsr addysp ; drop stack frame -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) leave: tay ; save A a sec lda (c_sp) ; that's the pushed arg size diff --git a/libsrc/runtime/lmod.s b/libsrc/runtime/lmod.s index b8e796dea..1cff216f3 100644 --- a/libsrc/runtime/lmod.s +++ b/libsrc/runtime/lmod.s @@ -11,10 +11,8 @@ .import poplsargs, udiv32, negeax .importzp sreg, ptr1, ptr2, tmp1, tmp3, tmp4 - .macpack cpu - tosmod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index a68c3e5c1..7124d6abd 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -9,11 +9,9 @@ .import addysp1 .importzp c_sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 - .macpack cpu - tosmul0ax: tosumul0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosmuleax: tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index 888a0c611..fa87aa63d 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosor0ax: .endif tosoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index 9690aff24..81dde42d3 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -9,8 +9,6 @@ .import incsp4 .importzp c_sp, sreg - .macpack cpu - popeax: ldy #3 lda (c_sp),y sta sreg+1 @@ -20,7 +18,7 @@ popeax: ldy #3 dey lda (c_sp),y tax -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index ec2c865af..fbc37b78c 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -12,13 +12,11 @@ .import decsp4 .importzp c_sp, sreg - .macpack cpu - pushl0: lda #0 tax push0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -39,7 +37,7 @@ pusheax: txa sta (c_sp),y pla -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) .else dey diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 456d8d8d5..b88d44f1a 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -12,10 +12,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosrsub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosrsub0ax: tosrsubeax: sec -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 17b225404..f0d34cd5b 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -11,10 +11,8 @@ .import addysp1 .importzp c_sp, sreg - .macpack cpu - tossub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tossub0ax: tossubeax: sec eor #$FF -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/lsubeq.s b/libsrc/runtime/lsubeq.s index b16ab18e1..d2d4ede7f 100644 --- a/libsrc/runtime/lsubeq.s +++ b/libsrc/runtime/lsubeq.s @@ -11,8 +11,6 @@ .export lsubeq1, lsubeqa, lsubeq .importzp sreg, ptr1 - .macpack cpu - lsubeq1: lda #$01 @@ -25,7 +23,7 @@ lsubeq: sty ptr1+1 ; Store high byte of address sec eor #$FF - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) adc (ptr1) ; Subtract byte 0 sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index b47207222..53651c789 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 - .macpack cpu - tosudiv0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -38,7 +36,7 @@ getlop: sta ptr3 ; Put right operand in place lda sreg+1 sta ptr4+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lumod.s b/libsrc/runtime/lumod.s index eb6176b35..a43c6d287 100644 --- a/libsrc/runtime/lumod.s +++ b/libsrc/runtime/lumod.s @@ -9,10 +9,8 @@ .import getlop, udiv32 .importzp sreg, tmp3, tmp4, ptr2 - .macpack cpu - tosumod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index 6d9f7db3a..abf341e63 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosxor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosxor0ax: .endif tosxoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 04389be5f..09aa93e79 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosora0: ldx #$00 tosorax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index c1700071d..bc490312e 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -7,11 +7,9 @@ .export popa .importzp c_sp - .macpack cpu - .proc popa -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 ; (2) diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 45043dd27..90dca5e22 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, ptr1 - .macpack cpu - .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else lda (c_sp),y ; get lo byte diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index c7f667246..0f6e5701d 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, sreg - .macpack cpu - popsreg: pha ; save A ldy #1 lda (c_sp),y ; get hi byte sta sreg+1 ; store it -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 399423077..6c715afb7 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -7,8 +7,6 @@ .export pusha0sp, pushaysp, pusha .importzp c_sp - .macpack cpu - ; Beware: The optimizer knows about this function! pusha0sp: diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index f77a9bcc3..5177f77b5 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -7,8 +7,6 @@ .export push0, pusha0, pushax .importzp c_sp - .macpack cpu - push0: lda #0 pusha0: ldx #0 @@ -31,7 +29,7 @@ pusha0: ldx #0 sta (c_sp),y ; (27) pla ; (31) dey ; (33) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; (37) .else sta (c_sp),y ; (38) diff --git a/libsrc/runtime/pushb.s b/libsrc/runtime/pushb.s index 7507ff21a..02d91b156 100644 --- a/libsrc/runtime/pushb.s +++ b/libsrc/runtime/pushb.s @@ -8,8 +8,6 @@ .import pushax .importzp ptr1 - .macpack cpu - pushbidx: sty ptr1 clc @@ -19,7 +17,7 @@ pushbidx: pushb: sta ptr1 stx ptr1+1 ldx #0 ; Load index/high byte -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index bacb3c7fc..1eedee53e 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -9,8 +9,6 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - ; ; AX = AX - TOS ; @@ -19,7 +17,7 @@ tosrsuba0: ldx #0 tosrsubax: sec -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/shl.s b/libsrc/runtime/shl.s index c1a4b6ef8..1f11eb5c0 100644 --- a/libsrc/runtime/shl.s +++ b/libsrc/runtime/shl.s @@ -15,8 +15,6 @@ .import popax .importzp tmp1 - .macpack cpu - tosshlax: tosaslax: sta tmp1 ; Save shift count @@ -55,7 +53,7 @@ L2: pla ; Shift count is exactly 8 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) L3: plx ; Low byte from stack into X rts ; A is already zero .else diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index aefed428f..e1542881f 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -9,8 +9,6 @@ .import incsp2 .importzp c_sp, tmp1, ptr1 - .macpack cpu - .proc staxspidx sty tmp1 ; Save Y @@ -18,7 +16,7 @@ ldy #1 lda (c_sp),y sta ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index a7ca39f21..f6ab28ea6 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -21,7 +21,6 @@ ; Use macros for better readability .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- @@ -39,7 +38,7 @@ lda c_sp+1 sta initialsp+1 sbc #>__STACKSIZE__ -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; Add 256 bytes safety area .else add #1 ; Add 256 bytes safety area diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index 58ffb4c91..7129e2147 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp - .macpack cpu - ; AX = TOS - AX tossuba0: @@ -17,7 +15,7 @@ tossuba0: tossubax: sec eor #$FF -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index 3796b0a97..72adaa90b 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -8,8 +8,6 @@ .export swapstk .importzp c_sp, ptr4 - .macpack cpu - swapstk: sta ptr4 stx ptr4+1 @@ -18,7 +16,7 @@ swapstk: tax lda ptr4+1 sta (c_sp),y -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) tay lda ptr4 diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index 2aaa19ccc..e879fe11f 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from long to int by cutting of the high 16bit .proc tosint pha -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index cf8eff031..c8b34d8b0 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -8,8 +8,6 @@ .import decsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from int to long tosulong: @@ -17,7 +15,7 @@ tosulong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else @@ -43,7 +41,7 @@ toslong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else diff --git a/libsrc/runtime/umul8x16r24.s b/libsrc/runtime/umul8x16r24.s index 54d730558..115a3e1a4 100644 --- a/libsrc/runtime/umul8x16r24.s +++ b/libsrc/runtime/umul8x16r24.s @@ -9,8 +9,6 @@ .include "zeropage.inc" - .macpack cpu - ;--------------------------------------------------------------------------- ; 8x16 => 24 unsigned multiplication routine. Because the overhead for a ; 8x16 => 16 unsigned multiplication routine is small, we will tag it with @@ -31,7 +29,7 @@ umul8x16r16: umul8x16r24m: umul8x16r16m: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1+1 stz sreg .else diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index 15394413c..1236b2c37 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosxora0: ldx #$00 tosxorax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ldy #1 .else diff --git a/libsrc/tgi/tgi_settextstyle.s b/libsrc/tgi/tgi_settextstyle.s index b62d6904c..bb924c048 100644 --- a/libsrc/tgi/tgi_settextstyle.s +++ b/libsrc/tgi/tgi_settextstyle.s @@ -9,8 +9,6 @@ .import umul8x16r24 .import popa, popax - .macpack cpu - ;----------------------------------------------------------------------------- ; void __fastcall__ tgi_settextstyle (unsigned width, unsigned height, ; unsigned char dir, unsigned char font); @@ -82,7 +80,7 @@ process_onedim: ; Disallowing characters larger than 256 pixels, we just drop the high byte ; and remember the low 16 bit as size in 8.8 format. -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) phy ; Save Y jsr umul8x16r24 ply ; Restore Y From 59e7158512043a18966ca68531a18ba67791afdb Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:29:42 +0200 Subject: [PATCH 05/11] Make the CPU_xxx constants from cpu.mac internal to the assembler and replace cpu.mac by a file that just emits a warning when used. --- asminc/cpu.mac | 42 ++---------- doc/ca65.sgml | 134 ++++++++++++++++++------------------- libsrc/apple2/cputc.s | 2 - libsrc/apple2/lseek.s | 1 - libsrc/apple2/ser/a2.ssc.s | 1 - libsrc/common/strlen.s | 1 - libsrc/sim6502/exehdr.s | 2 - src/ca65/main.c | 50 ++++++++++++++ 8 files changed, 119 insertions(+), 114 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 15b16bad5..092519173 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -1,38 +1,4 @@ -; CPU bitmask constants (make sure this matches src/common/cpu.h) - -CPU_ISET_NONE = $0001 -CPU_ISET_6502 = $0002 -CPU_ISET_6502X = $0004 -CPU_ISET_6502DTV = $0008 -CPU_ISET_65SC02 = $0010 -CPU_ISET_65C02 = $0020 ; Rockwell extensions -CPU_ISET_65816 = $0040 -CPU_ISET_SWEET16 = $0080 -CPU_ISET_HUC6280 = $0100 -CPU_ISET_M740 = $0200 -CPU_ISET_4510 = $0400 -CPU_ISET_45GS02 = $0800 -CPU_ISET_W65C02 = $1000 ; WDC extensions -CPU_ISET_65CE02 = $2000 ; CSG extensions - -; CPU capabilities -; make sure to only combine the instruction sets that are 100% compatible -CPU_NONE = CPU_ISET_NONE -CPU_6502 = CPU_ISET_6502 -CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502 -CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502 -CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502 -CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 - -; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect -; addressing was replaced with zp-indirect,z-indexed in 652SCE02 - -CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 -CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 -CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510 -CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 -CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02 - -CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_SWEET16 = CPU_ISET_SWEET16 +; This file is no longer needed as the symbols that were defined here are now +; internal symbols generated by the assembler. It is kept to avoid breaking +; old sources. +.warning "'.macpack cpu' is no longer required" diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cfe73a2f0..0f996ff64 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1401,16 +1401,76 @@ writable. Reading this pseudo variable will give a constant integer value that tells which CPU is currently enabled. It can also tell which instruction set the CPU is able to translate. The value read from the pseudo variable - should be further examined by using one of the constants defined by the - "cpu" macro package (see /). + should be further examined by using one of the following constants: - It may be used to replace the .IFPxx pseudo instructions or to construct - even more complex expressions. + + CPU_6502 + CPU_65SC02 + CPU_65C02 + CPU_65816 + CPU_SWEET16 + CPU_HUC6280 + CPU_4510 + CPU_45GS02 + CPU_6502DTV + CPU_M740 + + +Above constants may be used to determine the exact type of the currently +enabled CPU. In addition to that, for each CPU instruction set, another +constant is defined: + + + CPU_ISET_6502 + CPU_ISET_65SC02 + CPU_ISET_65C02 + CPU_ISET_65816 + CPU_ISET_SWEET16 + CPU_ISET_HUC6280 + CPU_ISET_4510 + CPU_ISET_45GS02 + CPU_ISET_6502DTV + CPU_ISET_M740 + + + + + - .macpack cpu .if (.cpu .bitand CPU_ISET_65816) phx phy @@ -1422,7 +1482,6 @@ writable. .endif - See also: @@ -5042,69 +5101,6 @@ This macro package defines a macro named .MACPACK cpu - -This macro package does not define any macros but constants used to examine -the value read from the / pseudo variable. For -each supported CPU a constant similar to - - - CPU_6502 - CPU_65SC02 - CPU_65C02 - CPU_65816 - CPU_SWEET16 - CPU_HUC6280 - CPU_4510 - CPU_45GS02 - CPU_6502DTV - CPU_M740 - - -is defined. These constants may be used to determine the exact type of the -currently enabled CPU. In addition to that, for each CPU instruction set, -another constant is defined: - - - CPU_ISET_6502 - CPU_ISET_65SC02 - CPU_ISET_65C02 - CPU_ISET_65816 - CPU_ISET_SWEET16 - CPU_ISET_HUC6280 - CPU_ISET_4510 - CPU_ISET_45GS02 - CPU_ISET_6502DTV - CPU_ISET_M740 - - -The value read from the / pseudo variable may -be checked with / to determine if the -currently enabled CPU supports a specific instruction set. For example the -65C02 supports all instructions of the 65SC02 CPU, so it has the - - .if (.cpu .bitand CPU_ISET_65SC02) - lda (c_sp) - .else - ldy #$00 - lda (c_sp),y - .endif - - -it is possible to determine if the - - - lda (c_sp) - - -instruction is supported, which is the case for the 65SC02, 65C02 and 65816 -CPUs (the latter two are upwards compatible to the 65SC02). - -see section and following. - .MACPACK module This macro package defines a macro named Date: Tue, 1 Jul 2025 08:34:38 +0200 Subject: [PATCH 06/11] Add an additional hook (currently unused) for target specific capabilities. --- src/ca65/expr.c | 3 ++- src/common/target.c | 10 ++++++++++ src/common/target.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 42b1a369b..33984610d 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -61,6 +61,7 @@ #include "studyexpr.h" #include "symbol.h" #include "symtab.h" +#include "target.h" #include "toklist.h" #include "ulabel.h" #include "macro.h" @@ -445,7 +446,7 @@ static ExprNode* FuncCapability (void) /* The pseudo function result is the logical AND of all capabilities ** given. */ - if (!CPUHasCap (Cap)) { + if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) { Result = 0; } } diff --git a/src/common/target.c b/src/common/target.c index a12f69bf9..bb67ddf9a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -37,6 +37,7 @@ #include /* common */ +#include "attrib.h" #include "chartype.h" #include "check.h" #include "target.h" @@ -302,3 +303,12 @@ const char* GetTargetName (target_t Target) /* Return the array entry */ return GetTargetProperties (Target)->Name; } + + + +int TargetHasCap (capability_t Cap attribute((unused))) +/* Check if the current target has the given capability */ +{ + /* Currently unused */ + return 0; +} diff --git a/src/common/target.h b/src/common/target.h index c5c8455a0..1dfa66ac7 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -39,6 +39,7 @@ /* common */ +#include "capability.h" #include "cpu.h" @@ -131,6 +132,9 @@ const TargetProperties* GetTargetProperties (target_t Target); const char* GetTargetName (target_t Target); /* Return the name of a target */ +int TargetHasCap (capability_t Cap); +/* Check if the current target has the given capability */ + /* End of target.h */ From 8d3112e24f93053bf8cd92ca5aa54d2f55339821 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:47:16 +0200 Subject: [PATCH 07/11] Small code simplification. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index d8c0dbd37..2f239d99d 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -233,5 +233,5 @@ int CPUHasCap (capability_t Cap) /* Check if the current CPU has the given capability */ { PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); - return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; + return (CPUCaps[CPU] & CAP_BIT (Cap)) != 0; } From c162f6a28636cd9cb04f5812532e53f87922b5f5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:21:18 +0200 Subject: [PATCH 08/11] Warning fix. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2f239d99d..7988cb4c1 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -151,7 +151,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ -static const uint64_t CPUCaps[CPU_COUNT] = { +static const uint32_t CPUCaps[CPU_COUNT] = { CAP_NONE, /* CPU_NONE */ CAP_6502, /* CPU_6502 */ CAP_6502X, /* CPU_6502X */ From 37414199c7f511eeee21a23bc0c1d184871fe92b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:33:38 +0200 Subject: [PATCH 09/11] Hopefully fix windows build files. --- src/common.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.vcxproj b/src/common.vcxproj index 6098c98a0..251ea3aeb 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -80,6 +80,7 @@ + @@ -133,6 +134,7 @@ + @@ -171,4 +173,4 @@ - \ No newline at end of file + From 60ec9045fce2c30aa4a24e46c59daaaccfab283a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:02:15 +0200 Subject: [PATCH 10/11] Use CPUIsets from cpu.c instead of recreating the CPU_xxx constants. --- src/ca65/main.c | 36 ++++++++++++++---------------------- src/common/cpu.c | 16 ++++++++++++++-- src/common/cpu.h | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fb0907df3..e9b36ee5d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -213,28 +213,20 @@ static void DefineCpuSymbols (void) /* Additional ones from cpu.mac. Not sure how useful they are after the ** changes from #2751. */ - NewSymbol ("CPU_NONE", CPU_ISET_NONE); - NewSymbol ("CPU_6502", CPU_ISET_6502); - NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); - NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); - NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); - NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | - CPU_ISET_65C02); - - /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the - ** zp-indirect addressing was replaced with zp-indirect,z-indexed in - ** 652SCE02 - */ - NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02); - NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02 | CPU_ISET_4510); - NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); - NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]); + NewSymbol ("CPU_6502", CPUIsets[CPU_6502]); + NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]); + NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]); + NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]); + NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]); + NewSymbol ("CPU_65816", CPUIsets[CPU_65816]); + NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]); + NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]); + NewSymbol ("CPU_M740", CPUIsets[CPU_M740]); + NewSymbol ("CPU_4510", CPUIsets[CPU_4510]); + NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]); + NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]); + NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]); } diff --git a/src/common/cpu.c b/src/common/cpu.c index 7988cb4c1..8e9ff827a 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -74,21 +74,33 @@ const char* CPUNames[CPU_COUNT] = { * NOTE: make sure to only combine the instruction sets that are 100% compatible */ const unsigned CPUIsets[CPU_COUNT] = { + /* CPU_NONE */ CPU_ISET_NONE, + /* CPU_6502 */ CPU_ISET_6502, + /* CPU_6502X */ CPU_ISET_6502X | CPU_ISET_6502, + /* CPU_6502DTV */ CPU_ISET_6502DTV | CPU_ISET_6502, + /* CPU_65SC02 */ CPU_ISET_65SC02 | CPU_ISET_6502, + /* CPU_65C02 */ CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* 65816 has wai/stp and NO bit manipulation */ + /* CPU_65816. 65816 has wai/stp and NO bit manipulation. */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* CPU_SWEET16 */ CPU_ISET_SWEET16, + /* CPU_HUC6280 */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_M740 */ CPU_ISET_M740 | CPU_ISET_6502, - /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* CPU_4510. 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + /* CPU_45GS02 */ CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, + /* CPU_W65C02 */ CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_65CE02 */ CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 0a7c853ac..bc6260371 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -69,7 +69,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ +/* CPU instruction sets */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From 070276a1a3baa9fbfca42555b306e0d9caac8436 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:19:19 +0200 Subject: [PATCH 11/11] Add a better description for CPU_HAS_ZPIND and CPU_HAS_STZ. --- doc/ca65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0f996ff64..63a1be7e9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1681,10 +1681,12 @@ either a string or an expression value. Checks for the capability to push and pop the X and Y registers. CPU_HAS_ZPIND - Checks for the availability of the "zeropage indirect" addressing mode. + Checks for the availability of the "zeropage indirect" addressing mode as it + is implemented in the 65SC02 CPU. CPU_HAS_STZ - Checks for the availability of the "store zero" instruction. + Checks for the availability of the "store zero" instruction as it is + implemented in the 65SC02 CPU.
- -This macro package does not define any macros but constants used to examine -the value read from the / pseudo variable. For -each supported CPU a constant similar to - - - CPU_6502 - CPU_65SC02 - CPU_65C02 - CPU_65816 - CPU_SWEET16 - CPU_HUC6280 - CPU_4510 - CPU_45GS02 - CPU_6502DTV - CPU_M740 - - -is defined. These constants may be used to determine the exact type of the -currently enabled CPU. In addition to that, for each CPU instruction set, -another constant is defined: - - - CPU_ISET_6502 - CPU_ISET_65SC02 - CPU_ISET_65C02 - CPU_ISET_65816 - CPU_ISET_SWEET16 - CPU_ISET_HUC6280 - CPU_ISET_4510 - CPU_ISET_45GS02 - CPU_ISET_6502DTV - CPU_ISET_M740 - - -The value read from the / pseudo variable may -be checked with / to determine if the -currently enabled CPU supports a specific instruction set. For example the -65C02 supports all instructions of the 65SC02 CPU, so it has the - - .if (.cpu .bitand CPU_ISET_65SC02) - lda (c_sp) - .else - ldy #$00 - lda (c_sp),y - .endif - - -it is possible to determine if the - - - lda (c_sp) - - -instruction is supported, which is the case for the 65SC02, 65C02 and 65816 -CPUs (the latter two are upwards compatible to the 65SC02). - -see section and following. - .MACPACK module This macro package defines a macro named Date: Tue, 1 Jul 2025 08:34:38 +0200 Subject: [PATCH 06/11] Add an additional hook (currently unused) for target specific capabilities. --- src/ca65/expr.c | 3 ++- src/common/target.c | 10 ++++++++++ src/common/target.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 42b1a369b..33984610d 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -61,6 +61,7 @@ #include "studyexpr.h" #include "symbol.h" #include "symtab.h" +#include "target.h" #include "toklist.h" #include "ulabel.h" #include "macro.h" @@ -445,7 +446,7 @@ static ExprNode* FuncCapability (void) /* The pseudo function result is the logical AND of all capabilities ** given. */ - if (!CPUHasCap (Cap)) { + if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) { Result = 0; } } diff --git a/src/common/target.c b/src/common/target.c index a12f69bf9..bb67ddf9a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -37,6 +37,7 @@ #include /* common */ +#include "attrib.h" #include "chartype.h" #include "check.h" #include "target.h" @@ -302,3 +303,12 @@ const char* GetTargetName (target_t Target) /* Return the array entry */ return GetTargetProperties (Target)->Name; } + + + +int TargetHasCap (capability_t Cap attribute((unused))) +/* Check if the current target has the given capability */ +{ + /* Currently unused */ + return 0; +} diff --git a/src/common/target.h b/src/common/target.h index c5c8455a0..1dfa66ac7 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -39,6 +39,7 @@ /* common */ +#include "capability.h" #include "cpu.h" @@ -131,6 +132,9 @@ const TargetProperties* GetTargetProperties (target_t Target); const char* GetTargetName (target_t Target); /* Return the name of a target */ +int TargetHasCap (capability_t Cap); +/* Check if the current target has the given capability */ + /* End of target.h */ From 8d3112e24f93053bf8cd92ca5aa54d2f55339821 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:47:16 +0200 Subject: [PATCH 07/11] Small code simplification. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index d8c0dbd37..2f239d99d 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -233,5 +233,5 @@ int CPUHasCap (capability_t Cap) /* Check if the current CPU has the given capability */ { PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); - return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; + return (CPUCaps[CPU] & CAP_BIT (Cap)) != 0; } From c162f6a28636cd9cb04f5812532e53f87922b5f5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:21:18 +0200 Subject: [PATCH 08/11] Warning fix. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2f239d99d..7988cb4c1 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -151,7 +151,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ -static const uint64_t CPUCaps[CPU_COUNT] = { +static const uint32_t CPUCaps[CPU_COUNT] = { CAP_NONE, /* CPU_NONE */ CAP_6502, /* CPU_6502 */ CAP_6502X, /* CPU_6502X */ From 37414199c7f511eeee21a23bc0c1d184871fe92b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:33:38 +0200 Subject: [PATCH 09/11] Hopefully fix windows build files. --- src/common.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.vcxproj b/src/common.vcxproj index 6098c98a0..251ea3aeb 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -80,6 +80,7 @@ + @@ -133,6 +134,7 @@ + @@ -171,4 +173,4 @@ - \ No newline at end of file + From 60ec9045fce2c30aa4a24e46c59daaaccfab283a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:02:15 +0200 Subject: [PATCH 10/11] Use CPUIsets from cpu.c instead of recreating the CPU_xxx constants. --- src/ca65/main.c | 36 ++++++++++++++---------------------- src/common/cpu.c | 16 ++++++++++++++-- src/common/cpu.h | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fb0907df3..e9b36ee5d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -213,28 +213,20 @@ static void DefineCpuSymbols (void) /* Additional ones from cpu.mac. Not sure how useful they are after the ** changes from #2751. */ - NewSymbol ("CPU_NONE", CPU_ISET_NONE); - NewSymbol ("CPU_6502", CPU_ISET_6502); - NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); - NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); - NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); - NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | - CPU_ISET_65C02); - - /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the - ** zp-indirect addressing was replaced with zp-indirect,z-indexed in - ** 652SCE02 - */ - NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02); - NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02 | CPU_ISET_4510); - NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); - NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]); + NewSymbol ("CPU_6502", CPUIsets[CPU_6502]); + NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]); + NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]); + NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]); + NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]); + NewSymbol ("CPU_65816", CPUIsets[CPU_65816]); + NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]); + NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]); + NewSymbol ("CPU_M740", CPUIsets[CPU_M740]); + NewSymbol ("CPU_4510", CPUIsets[CPU_4510]); + NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]); + NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]); + NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]); } diff --git a/src/common/cpu.c b/src/common/cpu.c index 7988cb4c1..8e9ff827a 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -74,21 +74,33 @@ const char* CPUNames[CPU_COUNT] = { * NOTE: make sure to only combine the instruction sets that are 100% compatible */ const unsigned CPUIsets[CPU_COUNT] = { + /* CPU_NONE */ CPU_ISET_NONE, + /* CPU_6502 */ CPU_ISET_6502, + /* CPU_6502X */ CPU_ISET_6502X | CPU_ISET_6502, + /* CPU_6502DTV */ CPU_ISET_6502DTV | CPU_ISET_6502, + /* CPU_65SC02 */ CPU_ISET_65SC02 | CPU_ISET_6502, + /* CPU_65C02 */ CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* 65816 has wai/stp and NO bit manipulation */ + /* CPU_65816. 65816 has wai/stp and NO bit manipulation. */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* CPU_SWEET16 */ CPU_ISET_SWEET16, + /* CPU_HUC6280 */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_M740 */ CPU_ISET_M740 | CPU_ISET_6502, - /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* CPU_4510. 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + /* CPU_45GS02 */ CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, + /* CPU_W65C02 */ CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_65CE02 */ CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 0a7c853ac..bc6260371 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -69,7 +69,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ +/* CPU instruction sets */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From 070276a1a3baa9fbfca42555b306e0d9caac8436 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:19:19 +0200 Subject: [PATCH 11/11] Add a better description for CPU_HAS_ZPIND and CPU_HAS_STZ. --- doc/ca65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0f996ff64..63a1be7e9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1681,10 +1681,12 @@ either a string or an expression value. Checks for the capability to push and pop the X and Y registers. CPU_HAS_ZPIND - Checks for the availability of the "zeropage indirect" addressing mode. + Checks for the availability of the "zeropage indirect" addressing mode as it + is implemented in the 65SC02 CPU. CPU_HAS_STZ - Checks for the availability of the "store zero" instruction. + Checks for the availability of the "store zero" instruction as it is + implemented in the 65SC02 CPU.
This macro package defines a macro named Date: Tue, 1 Jul 2025 08:34:38 +0200 Subject: [PATCH 06/11] Add an additional hook (currently unused) for target specific capabilities. --- src/ca65/expr.c | 3 ++- src/common/target.c | 10 ++++++++++ src/common/target.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 42b1a369b..33984610d 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -61,6 +61,7 @@ #include "studyexpr.h" #include "symbol.h" #include "symtab.h" +#include "target.h" #include "toklist.h" #include "ulabel.h" #include "macro.h" @@ -445,7 +446,7 @@ static ExprNode* FuncCapability (void) /* The pseudo function result is the logical AND of all capabilities ** given. */ - if (!CPUHasCap (Cap)) { + if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) { Result = 0; } } diff --git a/src/common/target.c b/src/common/target.c index a12f69bf9..bb67ddf9a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -37,6 +37,7 @@ #include /* common */ +#include "attrib.h" #include "chartype.h" #include "check.h" #include "target.h" @@ -302,3 +303,12 @@ const char* GetTargetName (target_t Target) /* Return the array entry */ return GetTargetProperties (Target)->Name; } + + + +int TargetHasCap (capability_t Cap attribute((unused))) +/* Check if the current target has the given capability */ +{ + /* Currently unused */ + return 0; +} diff --git a/src/common/target.h b/src/common/target.h index c5c8455a0..1dfa66ac7 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -39,6 +39,7 @@ /* common */ +#include "capability.h" #include "cpu.h" @@ -131,6 +132,9 @@ const TargetProperties* GetTargetProperties (target_t Target); const char* GetTargetName (target_t Target); /* Return the name of a target */ +int TargetHasCap (capability_t Cap); +/* Check if the current target has the given capability */ + /* End of target.h */ From 8d3112e24f93053bf8cd92ca5aa54d2f55339821 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:47:16 +0200 Subject: [PATCH 07/11] Small code simplification. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index d8c0dbd37..2f239d99d 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -233,5 +233,5 @@ int CPUHasCap (capability_t Cap) /* Check if the current CPU has the given capability */ { PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); - return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; + return (CPUCaps[CPU] & CAP_BIT (Cap)) != 0; } From c162f6a28636cd9cb04f5812532e53f87922b5f5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:21:18 +0200 Subject: [PATCH 08/11] Warning fix. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2f239d99d..7988cb4c1 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -151,7 +151,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ -static const uint64_t CPUCaps[CPU_COUNT] = { +static const uint32_t CPUCaps[CPU_COUNT] = { CAP_NONE, /* CPU_NONE */ CAP_6502, /* CPU_6502 */ CAP_6502X, /* CPU_6502X */ From 37414199c7f511eeee21a23bc0c1d184871fe92b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:33:38 +0200 Subject: [PATCH 09/11] Hopefully fix windows build files. --- src/common.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.vcxproj b/src/common.vcxproj index 6098c98a0..251ea3aeb 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -80,6 +80,7 @@ + @@ -133,6 +134,7 @@ + @@ -171,4 +173,4 @@ - \ No newline at end of file + From 60ec9045fce2c30aa4a24e46c59daaaccfab283a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:02:15 +0200 Subject: [PATCH 10/11] Use CPUIsets from cpu.c instead of recreating the CPU_xxx constants. --- src/ca65/main.c | 36 ++++++++++++++---------------------- src/common/cpu.c | 16 ++++++++++++++-- src/common/cpu.h | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fb0907df3..e9b36ee5d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -213,28 +213,20 @@ static void DefineCpuSymbols (void) /* Additional ones from cpu.mac. Not sure how useful they are after the ** changes from #2751. */ - NewSymbol ("CPU_NONE", CPU_ISET_NONE); - NewSymbol ("CPU_6502", CPU_ISET_6502); - NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); - NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); - NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); - NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | - CPU_ISET_65C02); - - /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the - ** zp-indirect addressing was replaced with zp-indirect,z-indexed in - ** 652SCE02 - */ - NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02); - NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02 | CPU_ISET_4510); - NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); - NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]); + NewSymbol ("CPU_6502", CPUIsets[CPU_6502]); + NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]); + NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]); + NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]); + NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]); + NewSymbol ("CPU_65816", CPUIsets[CPU_65816]); + NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]); + NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]); + NewSymbol ("CPU_M740", CPUIsets[CPU_M740]); + NewSymbol ("CPU_4510", CPUIsets[CPU_4510]); + NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]); + NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]); + NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]); } diff --git a/src/common/cpu.c b/src/common/cpu.c index 7988cb4c1..8e9ff827a 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -74,21 +74,33 @@ const char* CPUNames[CPU_COUNT] = { * NOTE: make sure to only combine the instruction sets that are 100% compatible */ const unsigned CPUIsets[CPU_COUNT] = { + /* CPU_NONE */ CPU_ISET_NONE, + /* CPU_6502 */ CPU_ISET_6502, + /* CPU_6502X */ CPU_ISET_6502X | CPU_ISET_6502, + /* CPU_6502DTV */ CPU_ISET_6502DTV | CPU_ISET_6502, + /* CPU_65SC02 */ CPU_ISET_65SC02 | CPU_ISET_6502, + /* CPU_65C02 */ CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* 65816 has wai/stp and NO bit manipulation */ + /* CPU_65816. 65816 has wai/stp and NO bit manipulation. */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* CPU_SWEET16 */ CPU_ISET_SWEET16, + /* CPU_HUC6280 */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_M740 */ CPU_ISET_M740 | CPU_ISET_6502, - /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* CPU_4510. 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + /* CPU_45GS02 */ CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, + /* CPU_W65C02 */ CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_65CE02 */ CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 0a7c853ac..bc6260371 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -69,7 +69,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ +/* CPU instruction sets */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From 070276a1a3baa9fbfca42555b306e0d9caac8436 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:19:19 +0200 Subject: [PATCH 11/11] Add a better description for CPU_HAS_ZPIND and CPU_HAS_STZ. --- doc/ca65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0f996ff64..63a1be7e9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1681,10 +1681,12 @@ either a string or an expression value. Checks for the capability to push and pop the X and Y registers. CPU_HAS_ZPIND - Checks for the availability of the "zeropage indirect" addressing mode. + Checks for the availability of the "zeropage indirect" addressing mode as it + is implemented in the 65SC02 CPU. CPU_HAS_STZ - Checks for the availability of the "store zero" instruction. + Checks for the availability of the "store zero" instruction as it is + implemented in the 65SC02 CPU.