Merge pull request #2760 from kugelfuhr/kugelfuhr/fix-2753
Add ".CAPABILITY" to ca65, remove ".MACPACK cpu"
This commit is contained in:
4
.github/checks/sorted.sh
vendored
4
.github/checks/sorted.sh
vendored
@@ -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
|
||||
|
||||
4
.github/checks/sorted_codeopt.sh
vendored
4
.github/checks/sorted_codeopt.sh
vendored
@@ -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
|
||||
|
||||
4
.github/checks/sorted_opcodes.sh
vendored
4
.github/checks/sorted_opcodes.sh
vendored
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
191
doc/ca65.sgml
191
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 <tt/<ref id=".MACPACK" name=".MACPACK">/).
|
||||
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.
|
||||
<tscreen><verb>
|
||||
CPU_6502
|
||||
CPU_65SC02
|
||||
CPU_65C02
|
||||
CPU_65816
|
||||
CPU_SWEET16
|
||||
CPU_HUC6280
|
||||
CPU_4510
|
||||
CPU_45GS02
|
||||
CPU_6502DTV
|
||||
CPU_M740
|
||||
</verb></tscreen>
|
||||
|
||||
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:
|
||||
|
||||
<tscreen><verb>
|
||||
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
|
||||
</verb></tscreen>
|
||||
|
||||
<!-- Sorry but explaining these with the changes from #2751 is too cringy for
|
||||
me - must be done by someone else. The remainder is from the old
|
||||
".macpack cpu" section"
|
||||
|
||||
The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may
|
||||
be checked with <tt/<ref id="operators" name=".BITAND">/ 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
|
||||
<tt/CPU_ISET_65SC02/ bit set in addition to its native <tt/CPU_ISET_65C02/
|
||||
bit. Using
|
||||
|
||||
<tscreen><verb>
|
||||
.if (.cpu .bitand CPU_ISET_65SC02)
|
||||
lda (c_sp)
|
||||
.else
|
||||
ldy #$00
|
||||
lda (c_sp),y
|
||||
.endif
|
||||
</verb></tscreen>
|
||||
|
||||
it is possible to determine if the
|
||||
|
||||
<tscreen><verb>
|
||||
lda (c_sp)
|
||||
</verb></tscreen>
|
||||
|
||||
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 <ref id="6502-mode" name="6502 format"> and following.
|
||||
-->
|
||||
|
||||
<tt/.CPU/ may be used to replace the .IFPxx pseudo instructions or to
|
||||
construct even more complex expressions.
|
||||
|
||||
Example:
|
||||
|
||||
<tscreen><verb>
|
||||
.macpack cpu
|
||||
.if (.cpu .bitand CPU_ISET_65816)
|
||||
phx
|
||||
phy
|
||||
@@ -1422,6 +1482,9 @@ writable.
|
||||
.endif
|
||||
</verb></tscreen>
|
||||
|
||||
See also: <tt><ref id=".CAP" name=".CAP"></tt>
|
||||
|
||||
|
||||
|
||||
<sect1><tt>.ISIZE</tt><label id=".ISIZE"><p>
|
||||
|
||||
@@ -1594,6 +1657,61 @@ either a string or an expression value.
|
||||
|
||||
|
||||
|
||||
<sect1><tt>.CAP, .CAPABILITY</tt><label id=".CAP"><p>
|
||||
|
||||
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:
|
||||
|
||||
<descrip>
|
||||
|
||||
<tag><tt>CPU_HAS_BITIMM</tt></tag>
|
||||
Checks for the availability of the "bit #imm" instruction.
|
||||
|
||||
<tag><tt>CPU_HAS_BRA8</tt></tag>
|
||||
Checks for the availability of a short (8 bit) branch.
|
||||
|
||||
<tag><tt>CPU_HAS_INA</tt></tag>
|
||||
Checks for the availability of accu inc/dec instructions.
|
||||
|
||||
<tag><tt>CPU_HAS_PUSHXY</tt></tag>
|
||||
Checks for the capability to push and pop the X and Y registers.
|
||||
|
||||
<tag><tt>CPU_HAS_ZPIND</tt></tag>
|
||||
Checks for the availability of the "zeropage indirect" addressing mode as it
|
||||
is implemented in the 65SC02 CPU.
|
||||
|
||||
<tag><tt>CPU_HAS_STZ</tt></tag>
|
||||
Checks for the availability of the "store zero" instruction as it is
|
||||
implemented in the 65SC02 CPU.
|
||||
|
||||
</descrip>
|
||||
|
||||
Case is ignored when checking the identifiers. The <tt/.cap/ function is
|
||||
easier to use than checking <tt/.cpu/ and requires no intimate knowledge
|
||||
of all instruction sets. For more detailed checking <tt/.cpu/ is still
|
||||
available.
|
||||
|
||||
Example:
|
||||
|
||||
<tscreen><verb>
|
||||
.if .cap(CPU_HAS_BRA, CPU_HAS_PUSHXY)
|
||||
phx
|
||||
bra L1
|
||||
.else
|
||||
txa
|
||||
pha
|
||||
jmp L1
|
||||
.endif
|
||||
</verb></tscreen>
|
||||
|
||||
See also: <tt><ref id=".CPU" name=".CPU"></tt>
|
||||
|
||||
|
||||
|
||||
<sect1><tt>.CONCAT</tt><label id=".CONCAT"><p>
|
||||
|
||||
Builtin string function. The function allows to concatenate a list of string
|
||||
@@ -4985,69 +5103,6 @@ This macro package defines a macro named <tt/scrcode/. It takes a string
|
||||
as argument and places this string into memory translated into screen codes.
|
||||
|
||||
|
||||
<sect1><tt>.MACPACK cpu</tt><p>
|
||||
|
||||
This macro package does not define any macros but constants used to examine
|
||||
the value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable. For
|
||||
each supported CPU a constant similar to
|
||||
|
||||
<tscreen><verb>
|
||||
CPU_6502
|
||||
CPU_65SC02
|
||||
CPU_65C02
|
||||
CPU_65816
|
||||
CPU_SWEET16
|
||||
CPU_HUC6280
|
||||
CPU_4510
|
||||
CPU_45GS02
|
||||
CPU_6502DTV
|
||||
CPU_M740
|
||||
</verb></tscreen>
|
||||
|
||||
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:
|
||||
|
||||
<tscreen><verb>
|
||||
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
|
||||
</verb></tscreen>
|
||||
|
||||
The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may
|
||||
be checked with <tt/<ref id="operators" name=".BITAND">/ 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
|
||||
<tt/CPU_ISET_65SC02/ bit set in addition to its native <tt/CPU_ISET_65C02/
|
||||
bit. Using
|
||||
|
||||
<tscreen><verb>
|
||||
.if (.cpu .bitand CPU_ISET_65SC02)
|
||||
lda (c_sp)
|
||||
.else
|
||||
ldy #$00
|
||||
lda (c_sp),y
|
||||
.endif
|
||||
</verb></tscreen>
|
||||
|
||||
it is possible to determine if the
|
||||
|
||||
<tscreen><verb>
|
||||
lda (c_sp)
|
||||
</verb></tscreen>
|
||||
|
||||
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 <ref id="6502-mode" name="6502 format"> and following.
|
||||
|
||||
<sect1><tt>.MACPACK module</tt><p>
|
||||
|
||||
This macro package defines a macro named <tt/module_header/. It takes an
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
initconio:
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
.export _lseek
|
||||
.import popax, popptr1
|
||||
.macpack cpu
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
.include "ser-error.inc"
|
||||
|
||||
.macpack module
|
||||
.macpack cpu
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
.export _strlen, _strlen_ptr4
|
||||
.importzp ptr4
|
||||
.macpack cpu
|
||||
|
||||
_strlen:
|
||||
sta ptr4 ; Save 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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
.import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__
|
||||
.import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__
|
||||
|
||||
.macpack cpu
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
; Initialize library modules
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
.export pusha0sp, pushaysp, pusha
|
||||
.importzp c_sp
|
||||
|
||||
.macpack cpu
|
||||
|
||||
; Beware: The optimizer knows about this function!
|
||||
|
||||
pusha0sp:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
.import __MAIN_START__
|
||||
.import startup
|
||||
|
||||
.macpack cpu
|
||||
|
||||
.segment "EXEHDR"
|
||||
|
||||
.byte $73, $69, $6D, $36, $35 ; 'sim65'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <time.h>
|
||||
|
||||
/* common */
|
||||
#include "capability.h"
|
||||
#include "check.h"
|
||||
#include "cpu.h"
|
||||
#include "exprdefs.h"
|
||||
@@ -60,6 +61,7 @@
|
||||
#include "studyexpr.h"
|
||||
#include "symbol.h"
|
||||
#include "symtab.h"
|
||||
#include "target.h"
|
||||
#include "toklist.h"
|
||||
#include "ulabel.h"
|
||||
#include "macro.h"
|
||||
@@ -405,6 +407,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) && !TargetHasCap (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 +546,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 +595,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 +633,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 +1192,10 @@ static ExprNode* Factor (void)
|
||||
N = Function (FuncBlank);
|
||||
break;
|
||||
|
||||
case TOK_CAP:
|
||||
N = Function (FuncCapability);
|
||||
break;
|
||||
|
||||
case TOK_CONST:
|
||||
N = Function (FuncConst);
|
||||
break;
|
||||
|
||||
@@ -192,6 +192,45 @@ static void CBMSystem (const char* Sys)
|
||||
|
||||
|
||||
|
||||
static void DefineCpuSymbols (void)
|
||||
/* Define all the symbols to evaluate .cpu. These were previously in cpu.mac. */
|
||||
{
|
||||
NewSymbol ("CPU_ISET_NONE", CPU_ISET_NONE);
|
||||
NewSymbol ("CPU_ISET_6502", CPU_ISET_6502);
|
||||
NewSymbol ("CPU_ISET_6502X", CPU_ISET_6502X);
|
||||
NewSymbol ("CPU_ISET_6502DTV", CPU_ISET_6502DTV);
|
||||
NewSymbol ("CPU_ISET_65SC02", CPU_ISET_65SC02);
|
||||
NewSymbol ("CPU_ISET_65C02", CPU_ISET_65C02);
|
||||
NewSymbol ("CPU_ISET_65816", CPU_ISET_65816);
|
||||
NewSymbol ("CPU_ISET_SWEET16", CPU_ISET_SWEET16);
|
||||
NewSymbol ("CPU_ISET_HUC6280", CPU_ISET_HUC6280);
|
||||
NewSymbol ("CPU_ISET_M740", CPU_ISET_M740);
|
||||
NewSymbol ("CPU_ISET_4510", CPU_ISET_4510);
|
||||
NewSymbol ("CPU_ISET_45GS02", CPU_ISET_45GS02);
|
||||
NewSymbol ("CPU_ISET_W65C02", CPU_ISET_W65C02);
|
||||
NewSymbol ("CPU_ISET_65CE02", CPU_ISET_65CE02);
|
||||
|
||||
/* Additional ones from cpu.mac. Not sure how useful they are after the
|
||||
** changes from #2751.
|
||||
*/
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SetSys (const char* Sys)
|
||||
/* Define a target system */
|
||||
{
|
||||
@@ -363,6 +402,9 @@ static void SetSys (const char* Sys)
|
||||
|
||||
}
|
||||
|
||||
/* Define the symbols for evaluating .cpu */
|
||||
DefineCpuSymbols ();
|
||||
|
||||
/* Initialize the translation tables for the target system */
|
||||
TgtTranslateInit ();
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -137,6 +137,7 @@ typedef enum token_t {
|
||||
TOK_BLANK,
|
||||
TOK_BSS,
|
||||
TOK_BYTE,
|
||||
TOK_CAP,
|
||||
TOK_CASE,
|
||||
TOK_CHARMAP,
|
||||
TOK_CODE,
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<ClInclude Include="common\assertion.h" />
|
||||
<ClInclude Include="common\attrib.h" />
|
||||
<ClInclude Include="common\bitops.h" />
|
||||
<ClInclude Include="common\capability.h" />
|
||||
<ClInclude Include="common\cddefs.h" />
|
||||
<ClInclude Include="common\chartype.h" />
|
||||
<ClInclude Include="common\check.h" />
|
||||
@@ -133,6 +134,7 @@
|
||||
<ClCompile Include="common\alignment.c" />
|
||||
<ClCompile Include="common\assertion.c" />
|
||||
<ClCompile Include="common\bitops.c" />
|
||||
<ClCompile Include="common\capability.c" />
|
||||
<ClCompile Include="common\chartype.c" />
|
||||
<ClCompile Include="common\check.c" />
|
||||
<ClCompile Include="common\cmdline.c" />
|
||||
@@ -171,4 +173,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
91
src/common/capability.c
Normal file
91
src/common/capability.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* 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 <stdlib.h>
|
||||
|
||||
/* 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_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 },
|
||||
{ "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;
|
||||
}
|
||||
79
src/common/capability.h
Normal file
79
src/common/capability.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
CAP_CPU_HAS_BITIMM = 5, /* CPU has "bit #imm" 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
|
||||
103
src/common/cpu.c
103
src/common/cpu.c
@@ -33,6 +33,8 @@
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* common */
|
||||
#include "addrsize.h"
|
||||
#include "check.h"
|
||||
@@ -72,24 +74,112 @@ 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,
|
||||
};
|
||||
|
||||
/* 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_BIT(Cap) (UINT32_C (1) << (Cap))
|
||||
#define CAP_NONE UINT32_C (0)
|
||||
#define CAP_6502 CAP_NONE
|
||||
#define CAP_6502X CAP_NONE
|
||||
#define CAP_6502DTV CAP_NONE
|
||||
#define CAP_65SC02 \
|
||||
(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 \
|
||||
(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 \
|
||||
(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 \
|
||||
(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 \
|
||||
(CAP_BIT (CAP_CPU_HAS_BRA8) | \
|
||||
CAP_BIT (CAP_CPU_HAS_INA))
|
||||
#define CAP_4510 \
|
||||
(CAP_BIT (CAP_CPU_HAS_BRA8) | \
|
||||
CAP_BIT (CAP_CPU_HAS_INA) | \
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY))
|
||||
#define CAP_45GS02 \
|
||||
(CAP_BIT (CAP_CPU_HAS_BRA8) | \
|
||||
CAP_BIT (CAP_CPU_HAS_INA) | \
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY))
|
||||
#define CAP_W65C02 \
|
||||
(CAP_BIT (CAP_CPU_HAS_BRA8) | \
|
||||
CAP_BIT (CAP_CPU_HAS_INA) | \
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY))
|
||||
#define CAP_65CE02 \
|
||||
(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 uint32_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 +238,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] & CAP_BIT (Cap)) != 0;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@
|
||||
|
||||
|
||||
|
||||
/* common */
|
||||
#include "capability.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
@@ -64,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,
|
||||
@@ -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 */
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <string.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
39
test/asm/listing/110-capabilities.s
Normal file
39
test/asm/listing/110-capabilities.s
Normal file
@@ -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
|
||||
|
||||
|
||||
|
||||
0
test/asm/listing/control/110-capabilities.err
Normal file
0
test/asm/listing/control/110-capabilities.err
Normal file
6
test/asm/listing/ref/110-capabilities.err2-ref
Normal file
6
test/asm/listing/ref/110-capabilities.err2-ref
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user