1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-01 13:41:34 +00:00

Merge branch 'master' into ca65_jmp_abs_wrap_error

This commit is contained in:
bbbradsmith 2023-08-19 14:07:52 -04:00
commit d09e0a7f20
71 changed files with 1781 additions and 216 deletions

View File

@ -43,6 +43,11 @@ jobs:
- name: Build the document files.
shell: bash
run: make -j2 doc
- name: Upload a documents snapshot.
uses: actions/upload-artifact@v3
with:
name: docs
path: ./html
- name: Build 64-bit Windows versions of the tools.
run: |
make -C src clean

View File

@ -86,20 +86,24 @@ jobs:
mv cc65.zip cc65-snapshot-win32.zip
- name: Upload a 32-bit Snapshot Zip
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: cc65-snapshot-win32.zip
name: cc65-snapshot-win32
path: cc65-snapshot-win32.zip
- name: Upload a 64-bit Snapshot Zip
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: cc65-snapshot-win64.zip
name: cc65-snapshot-win64
path: cc65-snapshot-win64.zip
- name: Get the online documents repo.
uses: actions/checkout@v3
with:
repository: cc65/doc
# this token will expire, if it does, generate a new one as decribed in https://github.com/cc65/cc65/issues/2065
# - apparently only a "classic" token works here
# - the token must exist in the cc65/cc65 repo
token: ${{ secrets.DOC_PAT }} # use secret token instead of default
path: doc.git
- name: Update the online documents.
run: |
@ -110,11 +114,19 @@ jobs:
git config user.email "cc65.nomail@github.com"
git config push.default simple
git add -A
git commit -m "Updated from cc65 commit ${GITHUB_SHA}."
#git push -v
# prevent failure when there is nothing to commit
git diff-index --quiet HEAD || git commit -m "Updated from https://github.com/cc65/cc65/commit/${GITHUB_SHA}"
git push
- name: Package offline documents.
run: 7z a cc65-snapshot-docs.zip ./html/*.*
- name: Upload a Documents Snapshot Zip
uses: actions/upload-artifact@v3
with:
name: cc65-snapshot-docs
path: cc65-snapshot-docs.zip
# enter secrets under "repository secrets"
- name: Upload snapshot to sourceforge
- name: Upload 32-bit Windows snapshot to sourceforge
uses: nogsantos/scp-deploy@master
with:
src: cc65-snapshot-win32.zip
@ -123,5 +135,14 @@ jobs:
port: ${{ secrets.SSH_PORT }}
user: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
- name: Upload documents snapshot to sourceforge
uses: nogsantos/scp-deploy@master
with:
src: cc65-snapshot-docs.zip
host: ${{ secrets.SSH_HOST }}
remote: ${{ secrets.SSH_DIR }}
port: ${{ secrets.SSH_PORT }}
user: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
# TODO: Publish snapshot zip at https://github.com/cc65/cc65.github.io

View File

@ -0,0 +1,78 @@
name: Windows Test Scheduled
# Scheduled or manually dispatched because it's slower than the Linux test.
on:
schedule:
- cron: '0 0 */1 * *'
# every 1 days
workflow_dispatch:
# allow manual dispatch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# don't run more than once at a time
jobs:
build_windows:
name: Build, Test (Windows MSVC)
runs-on: windows-latest
steps:
# This cache is used to remember the last build.
# If there are no changes and the last build was successful,
# the build and test steps will be omitted.
# If the last build failed, the full attempt will be repeated.
# Github Actions will retain the last build cache for up to 7 days.
- name: Create Cache
shell: bash
run: mkdir ~/.cache-sha
- name: Cache SHA
uses: actions/cache@v3
id: check-sha
with:
path: ~/.cache-sha
key: cache-sha-wintest-${{ github.sha }}
- name: Git Setup
if: steps.check-sha.outputs.cache-hit != 'true'
shell: bash
run: git config --global core.autocrlf input
- name: Checkout source
if: steps.check-sha.outputs.cache-hit != 'true'
uses: actions/checkout@v3
- name: Add msbuild to PATH
if: steps.check-sha.outputs.cache-hit != 'true'
uses: microsoft/setup-msbuild@v1.1
- name: Build app (MSVC debug)
if: steps.check-sha.outputs.cache-hit != 'true'
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug
- name: Build app (MSVC release)
if: steps.check-sha.outputs.cache-hit != 'true'
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release
- name: Build utils (MinGW)
if: steps.check-sha.outputs.cache-hit != 'true'
shell: cmd
run: make -j2 util SHELL=cmd
- name: Build the platform libraries (make lib)
if: steps.check-sha.outputs.cache-hit != 'true'
shell: cmd
run: make -j2 lib QUIET=1 SHELL=cmd
- name: Run the regression tests (make test)
if: steps.check-sha.outputs.cache-hit != 'true'
shell: cmd
run: make test QUIET=1 SHELL=cmd
- name: Test that the samples can be built (make samples)
if: steps.check-sha.outputs.cache-hit != 'true'
shell: cmd
run: make -j2 samples SHELL=cmd

View File

@ -74,10 +74,12 @@ color := $0787
The following is still very incomplete - if in doubt please look at existing sourcefiles and adapt to the existing style
* Your files should obey the C89 standard.
* Your files should generally obey the C89 standard, with a few C99 things (this is a bit similar to what cc65 itself supports). The exceptions are:
* use stdint.h for variables that require a certain bit size
* In printf-style functions use the PRIX64 (and similar) macros to deal with 64bit values (from inttypes.h)
This list is not necessarily complete - if in doubt, please ask.
* We generally have a "no warnings" policy
* Warnings must not be hidden by using typecasts - fix the code instead
* In printf-style functions use the PRIX64 (and similar) macros to deal with 64bit values
* Warnings must not be hidden by using typecasts - fix the code instead
* The normal indentation width should be four spaces.
* You must use ANSI C comments (```/* */```); you must not use C++ comments (```//```).
* When you add functions to an existing file, you should separate them by the same number of blank lines that separate the functions that already are in that file.

View File

@ -21,7 +21,7 @@ mostlyclean clean:
avail unavail bin:
@$(MAKE) -C src --no-print-directory $@
lib:
lib libtest:
@$(MAKE) -C libsrc --no-print-directory $@
doc html info:
@ -43,7 +43,7 @@ util:
checkstyle:
@$(MAKE) -C .github/checks --no-print-directory $@
# simple "test" target, only run regression tests for c64 target
# runs regression tests, requires libtest target libraries
test:
@$(MAKE) -C test --no-print-directory $@

View File

@ -259,7 +259,7 @@ NLINES := $0387 ; Number of screen lines
; BASIC
VARTAB := $03E1 ; Pointer to start of BASIC variables
MEMSIZE := $03E9 ; Pointer to highest BASIC RAM location (+1)
MEMSIZE := $0259 ; Pointer to highest BASIC RAM location (+1)
; ---------------------------------------------------------------------------
; Vector and other locations

View File

@ -1409,10 +1409,6 @@ either a string or an expression value.
.endmacro
</verb></tscreen>
This command is new and must be enabled with the <tt/.FEATURE addrsize/ command.
See: <tt><ref id=".FEATURE" name=".FEATURE"></tt>
<sect1><tt>.BANK</tt><label id=".BANK"><p>
@ -2795,12 +2791,6 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
<descrip>
<tag><tt>addrsize</tt><label id="addrsize"></tag>
Enables the .ADDRSIZE pseudo function. This function is experimental and not enabled by default.
See also: <tt><ref id=".ADDRSIZE" name=".ADDRSIZE"></tt>
<tag><tt>at_in_identifiers</tt><label id="at_in_identifiers"></tag>
Accept the at character ('@') as a valid character in identifiers. The

View File

@ -754,6 +754,8 @@ Here is a description of all the command line options:
Warn about unused function parameters.
<tag><tt/unused-var/</tag>
Warn about unused variables.
<tag><tt/const-overflow/</tag>
Warn if numerical constant conversion implies overflow. (Disabled by default.)
</descrip>
The full list of available warning names can be retrieved by using the

View File

@ -2,12 +2,14 @@ body {
font-family: arial, helvetica, sans-serif;
font-size: 100%;
text-align: justify;
margin-left: 110px;
margin-top: 10px;
margin-right: 30px;
margin-bottom: 10px;
margin: 0px;
padding-left: 110px;
padding-top: 10px;
padding-right: 30px;
padding-bottom: 10px;
background-image: url(doc.png);
background-repeat: repeat-y;
background-position:left top;
}
h1, h2, h2 a:link, h2 a:active, h2 a:visited {
@ -25,7 +27,7 @@ h1 {
}
h2 {
font-size: 160%;
font-size: 150%;
text-shadow: 1px 1px 3px #303030;
letter-spacing: 1px;
margin-top: 2em;

View File

@ -976,7 +976,7 @@ previously been allocated by <tt/<ref id="malloc" name="malloc">/, <tt/<ref
id="calloc" name="calloc">/ or <tt/<ref id="realloc" name="realloc">/.
<tag/Notes/<itemize>
<item>Passing a pointer to a block that was is not the result of one of the
allocation functions, or that has been free'd will give unpredicable results.
allocation functions, or that has been free'd will give unpredictable results.
<item>The function is available only as a fastcall function; so, it may be used
only in the presence of a prototype.
</itemize>

View File

@ -187,8 +187,21 @@ Currently the following extra screen configuration modules are implemented:
<itemize>
<item><tt>osic1p-screen-s3-32x28.o</tt>: 32 columns by 28 lines mode
for Briel Superboard ///</item>
<item><tt>osic1p-screen-c1p-48x12.s</tt>: 48 columns by 12 lines mode
for Challenger 1P</item>
</itemize>
On the Briel Superboard /// you enter 32 column mode by holding down
the BREAK key on powerup.
On the Challenger 1P you can enable 48 column mode by writing a 1 to
bit 0 of address &dollar;D800, and writing a 0 to go back to 24 column mode.
You can use code like the following to do this:
<tscreen><verb>
*(char*)0xd800 = 1; /* Switch to 48 column mode */
</verb></tscreen>
<sect>Limitations<p>
<sect1>stdio implementation<p>

View File

@ -44,6 +44,13 @@ The simulator is called as follows:
--version Print the simulator version number
</verb></tscreen>
sim65 will exit with the error code of the simulated program,
which is limited to an 8-bit result 0-255.
An error in sim65, like bad arguments or an internal problem will exit with <tt/1/.
A timeout from <tt/-x/ will exist with <tt/2/.
<sect1>Command line options in detail<p>
@ -126,9 +133,17 @@ a set of built-in paravirtualization functions (<ref id="paravirt-internal" name
<sect>Creating a Test in Assembly<p>
Assembly tests may similarly be assembled and linked with
<tt/--target sim6502/ or <tt/--target sim65c02/,
and the sim65 library provides an <tt/exit/ symbol that the program may <tt/JMP/
to terminate with the current A register value as an exit code.
<tt/--target sim6502/ or <tt/--target sim65c02/.
Define and export <tt/_main/ as an entry point,
and the sim65 library provides two ways to return an 8-bit exit code:
<itemize>
<item>Return from <tt/_main/ with the exit code in <tt/A/.
<item><tt/jmp exit/ with the code in <tt/A/.
</itemize>
The binary file has a 12 byte header:

View File

@ -54,7 +54,21 @@ struct __os {
unsigned char color2; // = $0E PF color 2
unsigned char color3; // = $0F PF color 3
unsigned char color4; // = $10 PF color 4
unsigned char _free_1[0xEF]; // = $11-$FF User space
unsigned char paddl0; // = $11 POT0 Shadow
unsigned char paddl1; // = $12 POT1 Shadow
unsigned char paddl2; // = $13 POT2 Shadow
unsigned char paddl3; // = $14 POT3 Shadow
unsigned char paddl4; // = $15 POT4 Shadow
unsigned char paddl5; // = $16 POT5 Shadow
unsigned char paddl6; // = $17 POT6 Shadow
unsigned char paddl7; // = $18 POT7 Shadow
/*cc65 runtime zero page variables*/
unsigned char rowcrs_5200; // = $19 Cursor row (conio)
unsigned char colcrs_5200; // = $1A Cursor column (conio)
unsigned char* savmsc; // = $1B/$1C Pointer to screen memory (conio)
unsigned char _filler_1[0xE3]; // = $1D-$FF Filler
/*Stack*/
unsigned char stack[0x100]; // = $100-$1FF Stack

View File

@ -334,17 +334,17 @@ struct __os {
void (*vserin)(void); // = $020A/$020B POKEY SERIAL INPUT READY IRQ
void (*vseror)(void); // = $020C/$020D POKEY SERIAL OUTPUT READY IRQ
void (*vseroc)(void); // = $020E/$020F POKEY SERIAL OUTPUT COMPLETE IRQ
void (*vtimr1)(void); // = $0210/$0201 POKEY TIMER 1 IRQ
void (*vtimr2)(void); // = $0212/$0203 POKEY TIMER 2 IRQ
void (*vtimr4)(void); // = $0214/$0205 POKEY TIMER 4 IRQ
void (*vimirq)(void); // = $0216/$0207 IMMEDIATE IRQ VECTOR
unsigned int cdtmv1; // = $0218/$0210 COUNT DOWN TIMER 1
void (*vtimr1)(void); // = $0210/$0211 POKEY TIMER 1 IRQ
void (*vtimr2)(void); // = $0212/$0213 POKEY TIMER 2 IRQ
void (*vtimr4)(void); // = $0214/$0215 POKEY TIMER 4 IRQ
void (*vimirq)(void); // = $0216/$0217 IMMEDIATE IRQ VECTOR
unsigned int cdtmv1; // = $0218/$0219 COUNT DOWN TIMER 1
unsigned int cdtmv2; // = $021A/$021B COUNT DOWN TIMER 2
unsigned int cdtmv3; // = $021C/$021D COUNT DOWN TIMER 3
unsigned int cdtmv4; // = $021E/$021F COUNT DOWN TIMER 4
unsigned int cdtmv5; // = $0220/$0221 COUNT DOWN TIMER 5
void (*vvblki)(void); // = $0222/$0223 IMMEDIATE VERTICAL BLANK NMI VECTOR
void (*vvblkd)(void); // = $0224/$0224 DEFERRED VERTICAL BLANK NMI VECTOR
void (*vvblkd)(void); // = $0224/$0225 DEFERRED VERTICAL BLANK NMI VECTOR
void (*cdtma1)(void); // = $0226/$0227 COUNT DOWN TIMER 1 JSR ADDRESS
void (*cdtma2)(void); // = $0228/$0229 COUNT DOWN TIMER 2 JSR ADDRESS
unsigned char cdtmf3; // = $022A COUNT DOWN TIMER 3 FLAG

View File

@ -4,13 +4,15 @@
reassembled by Maciej 'YTM/Elysium' Witkowiak
*/
/* Here are constants which didn't fit into any other cathegory... */
/* Here are constants which didn't fit into any other category... */
#ifndef _GCONST_H
#define _GCONST_H
#define NULL 0
#define FALSE NULL
#ifndef NULL
#define NULL ((void *) 0)
#endif
#define FALSE 0
#define TRUE 0xff
#define MOUSE_SPRNUM 0
#define DISK_DRV_LGH 0x0d80

View File

@ -39,9 +39,8 @@
/* NULL pointer */
#ifndef _HAVE_NULL
#define NULL 0
#define _HAVE_NULL
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* Locale information constants */
@ -82,6 +81,3 @@ char* __fastcall__ setlocale (int category, const char* locale);
/* End of locale.h */
#endif

View File

@ -53,9 +53,8 @@ typedef unsigned size_t;
#endif
/* NULL pointer */
#ifndef _HAVE_NULL
#define NULL ((void *) 0)
#define _HAVE_NULL
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* offsetof macro */
@ -65,6 +64,3 @@ typedef unsigned size_t;
/* End of stddef.h */
#endif

View File

@ -38,9 +38,8 @@
/* NULL pointer */
#ifndef _HAVE_NULL
#define NULL 0
#define _HAVE_NULL
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* size_t is needed */

View File

@ -44,6 +44,11 @@ typedef unsigned size_t;
#define _HAVE_size_t
#endif
/* NULL pointer */
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* Standard exit codes */
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
@ -167,6 +172,3 @@ int __fastcall__ putenv (char* s);
/* End of stdlib.h */
#endif

View File

@ -37,9 +37,8 @@
#define _STRING_H
/* NULL pointer */
#ifndef _HAVE_NULL
#define NULL 0
#define _HAVE_NULL
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* size_t is needed */

View File

@ -39,9 +39,8 @@
/* NULL pointer */
#ifndef _HAVE_NULL
#define NULL 0
#define _HAVE_NULL
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* size_t is needed */

View File

@ -39,6 +39,10 @@ TARGETS = apple2 \
sym1 \
telestrat
TARGETTEST = none \
sim6502 \
sim65c02
DRVTYPES = emd \
joy \
mou \
@ -53,7 +57,7 @@ OUTPUTDIRS := lib
$(subst ../,,$(wildcard ../target/*/drv/*)) \
$(subst ../,,$(wildcard ../target/*/util))
.PHONY: all mostlyclean clean install zip lib $(TARGETS)
.PHONY: all mostlyclean clean install zip lib libtest $(TARGETS)
.SUFFIXES:
@ -81,6 +85,8 @@ datadir = $(PREFIX)/share/cc65
all lib: $(TARGETS)
libtest: $(TARGETTEST)
mostlyclean:
$(call RMDIR,../libwrk)
@ -116,9 +122,13 @@ endef # ZIP_recipe
zip:
$(foreach dir,$(OUTPUTDIRS),$(ZIP_recipe))
$(TARGETS):
$(TARGETS): | ../lib
@$(MAKE) --no-print-directory $@
# ../lib must be created globally before doing lib targets in parallel
../lib:
@$(call MKDIR,$@)
else # TARGET
CA65FLAGS =
@ -287,10 +297,12 @@ $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../libwrk/$(TARGET) ../lib
@echo $(TARGET) - $(<F)
@$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $<
$(EXTRA_OBJS): | ../lib
../lib/$(TARGET).lib: $(OBJS) | ../lib
$(AR65) a $@ $?
../libwrk/$(TARGET) ../lib ../target/$(TARGET)/util:
../libwrk/$(TARGET) ../target/$(TARGET)/util:
@$(call MKDIR,$@)
$(TARGET): $(EXTRA_OBJS) ../lib/$(TARGET).lib

View File

@ -3,22 +3,37 @@
;
.export initcwd
.import __cwd
.import __cwd, __dos_type
.include "zeropage.inc"
.include "apple2.inc"
.include "mli.inc"
initcwd:
; Set static prefix buffer
lda #<__cwd
ldx #>__cwd
sta mliparam + MLI::PREFIX::PATHNAME
stx mliparam + MLI::PREFIX::PATHNAME+1
; Check for ProDOS 8
lda __dos_type
beq done
; Get current working directory
lda #GET_PREFIX_CALL
ldx #PREFIX_COUNT
jsr callmli
; Save random counter
lda RNDL
pha
lda RNDH
pha
; Call MLI
; We're not using mli.s' callmli because its
; mliparam is in BSS and this will be called
; before LC code is moved to the Language Card.
jsr $BF00 ; MLI call entry point
.byte GET_PREFIX_CALL ; MLI command
.addr mli_parameters ; MLI parameter
; Restore random counter
pla
sta RNDH
pla
sta RNDL
; Check for null prefix
ldx __cwd
@ -39,3 +54,9 @@ initcwd:
sta __cwd,x
done: rts
.rodata
mli_parameters:
.byte $01 ; Number of parameters
.addr __cwd ; Address of parameter

View File

@ -29,7 +29,8 @@ __syschdir:
bcs cleanup
; Update current working directory
jsr initcwd ; Returns with A = 0
jsr initcwd
lda #$00
; Cleanup name
cleanup:jsr popname ; Preserves A

View File

@ -34,8 +34,7 @@ ram_top := __MAIN_START__ + __MAIN_SIZE__
.ifdef ASM
.include "osic1p.inc"
.macpack generic
.include "screen-c1p-24x24.s"
load := $08 ; private variables
count := $0A
@ -45,7 +44,7 @@ GETCHAR := $FFBF ; gets one character from ACIA
FIRSTVISC = $85 ; Offset of first visible character in video RAM
LINEDIST = $20 ; Offset in video RAM between two lines
ldy #<$0000
ldy #$00
lda #<load_addr
ldx #>load_addr
sta load
@ -57,9 +56,9 @@ LINEDIST = $20 ; Offset in video RAM between two lines
stx count+1 ; save size with each byte incremented separately
L1: dec count
bnz L2
bne L2
dec count+1
bze L3
beq L3
L2: jsr GETCHAR ; (doesn't change .Y)
sta (load),y
@ -70,12 +69,12 @@ L2: jsr GETCHAR ; (doesn't change .Y)
lsr a
and #8 - 1
ora #$10 ; eight arrow characters
sta SCRNBASE + FIRSTVISC + 2 * LINEDIST + 11
sta C1P_SCR_BASE + FIRSTVISC + 2 * LINEDIST + 11
iny
bnz L1
bne L1
inc load+1
bnz L1 ; branch always
bne L1 ; branch always
L3: jmp load_addr
@ -112,18 +111,15 @@ CR = $0D
hex2 >load_addr
.byte CR, "85", CR, "08", CR
.byte "86", CR, "09", CR
.byte "A9", CR
hex2 <load_size
.byte CR, "49", CR, "FF", CR
.byte "85", CR, "0A", CR
.byte "A9", CR
hex2 >load_size
.byte CR, "49", CR, "FF", CR
.byte "85", CR, "0B", CR
.byte "E6", CR, "0A", CR
.byte "A2", CR
hex2 (<load_size) + 1
.byte CR, "86", CR, "0A", CR
.byte "A2", CR
hex2 (>load_size) + 1
.byte CR, "86", CR, "0B", CR
.byte "C6", CR, "0A", CR
.byte "D0", CR, "04", CR
.byte "E6", CR, "0B", CR
.byte "C6", CR, "0B", CR
.byte "F0", CR, "16", CR
.byte "20", CR, "BF", CR, "FF", CR
.byte "91", CR, "08", CR

View File

@ -0,0 +1,16 @@
;
; Implementation of screen-layout related functions for Challenger 1P in 48x12 mode.
;
.include "../osiscreen.inc"
C1P_SCR_BASE := $D000 ; Base of C1P video RAM
C1P_VRAM_SIZE = $0400 ; Size of C1P video RAM (1 kB)
C1P_SCR_WIDTH = $30 ; Screen width
C1P_SCR_HEIGHT = $0C ; Screen height
C1P_SCR_FIRSTCHAR = $8B ; Offset of cursor position (0, 0) from base
; of video RAM
C1P_SCROLL_DIST = $40 ; Memory distance for scrolling by one line
osi_screen_funcs C1P_SCR_BASE, C1P_VRAM_SIZE, C1P_SCR_FIRSTCHAR, \
C1P_SCR_WIDTH, C1P_SCR_HEIGHT, C1P_SCROLL_DIST

View File

@ -30,13 +30,14 @@
ldy ptr1+1
BRK_TELEMON XFREAD
; compute nb of bytes read
lda PTR_READ_DEST+1
sec
lda PTR_READ_DEST
sbc ptr2
pha
lda PTR_READ_DEST+1
sbc ptr2+1
tax
lda PTR_READ_DEST
sec
sbc ptr2
; here A and X contains number of bytes read
pla
rts
.endproc

View File

@ -42,16 +42,16 @@ next:
ldy ptr3+1
ldx tmp1 ; send fd in X
BRK_TELEMON XFWRITE
; compute nb of bytes written
lda PTR_READ_DEST+1
sec
lda PTR_READ_DEST
sbc ptr1
pha
lda PTR_READ_DEST+1
sbc ptr1+1
tax
lda PTR_READ_DEST
sec
sbc ptr1
pla
rts

View File

@ -496,7 +496,7 @@ static ExprNode* FuncIsMnemonic (void)
/* Skip the name */
NextTok ();
return GenLiteralExpr (Instr > 0);
return GenLiteralExpr (Instr >= 0);
}

View File

@ -118,7 +118,6 @@ void SetFeature (feature_t Feature, unsigned char On)
case FEAT_C_COMMENTS: CComments = On; break;
case FEAT_FORCE_RANGE: ForceRange = On; break;
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= On; break;
case FEAT_ADDRSIZE: AddrSize = On; break;
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = On; break;
case FEAT_STRING_ESCAPES: StringEscapes = On; break;
case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = On; break;

View File

@ -85,5 +85,4 @@ unsigned char OrgPerSeg = 0; /* Make .org local to current seg */
unsigned char CComments = 0; /* Allow C like comments */
unsigned char ForceRange = 0; /* Force values into expected range */
unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */
unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */
unsigned char BracketAsIndirect = 0; /* Use '[]' not '()' for indirection */

View File

@ -87,7 +87,6 @@ extern unsigned char OrgPerSeg; /* Make .org local to current seg */
extern unsigned char CComments; /* Allow C like comments */
extern unsigned char ForceRange; /* Force values into expected range */
extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */
extern unsigned char AddrSize; /* Allow .ADDRSIZE function */
extern unsigned char BracketAsIndirect; /* Use '[]' not '()' for indirection */

View File

@ -1043,6 +1043,11 @@ static void DoFeature (void)
ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal);
return;
}
if (Feature == FEAT_ADDRSIZE) {
Warning (1, "Deprecated feature: '.feature addrsize'. Pseudo function .addrsize is always available.");
}
NextTok ();
/* Optional +/- or ON/OFF */

View File

@ -748,24 +748,7 @@ static token_t FindDotKeyword (void)
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
sizeof (DotKeywords [0]), CmpDotKeyword);
if (R != 0) {
/* By default, disable any somewhat experiemental DotKeyword. */
switch (R->Tok) {
case TOK_ADDRSIZE:
/* Disallow .ADDRSIZE function by default */
if (AddrSize == 0) {
return TOK_NONE;
}
break;
default:
break;
}
return R->Tok;
} else {
return TOK_NONE;
}

View File

@ -79,6 +79,7 @@ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */
IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */
IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */
IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */
IntStack WarnConstOverflow = INTSTACK(0); /* - overflow conversion of numerical constants */
/* Map the name of a warning to the intstack that holds its state */
typedef struct WarnMapEntry WarnMapEntry;
@ -102,6 +103,7 @@ static WarnMapEntry WarnMap[] = {
{ &WarnUnusedLabel, "unused-label" },
{ &WarnUnusedParam, "unused-param" },
{ &WarnUnusedVar, "unused-var" },
{ &WarnConstOverflow, "const-overflow" },
};
Collection DiagnosticStrBufs;

View File

@ -76,6 +76,7 @@ extern IntStack WarnUnusedLabel; /* - unused labels */
extern IntStack WarnUnusedParam; /* - unused parameters */
extern IntStack WarnUnusedVar; /* - unused variables */
extern IntStack WarnUnusedFunc; /* - unused functions */
extern IntStack WarnConstOverflow; /* - overflow conversion of numerical constants */
/* Forward */
struct StrBuf;

View File

@ -39,6 +39,8 @@
#include <errno.h>
#include <ctype.h>
#include <math.h>
#include <inttypes.h>
#include <limits.h>
/* common */
#include "chartype.h"
@ -151,6 +153,11 @@ static const struct Keyword {
#define IT_ULONG 0x08
/* Internal type for numeric constant scanning.
** Size must be explicit for cross-platform uniformity.
*/
typedef uint32_t scan_t;
/*****************************************************************************/
/* code */
@ -521,7 +528,8 @@ static void NumericConst (void)
int IsFloat;
char C;
unsigned DigitVal;
unsigned long IVal; /* Value */
scan_t IVal; /* Scanned value. */
int Overflow;
/* Get the pp-number first, then parse on it */
CopyPPNumber (&Src);
@ -575,6 +583,7 @@ static void NumericConst (void)
/* Since we now know the correct base, convert the input into a number */
SB_SetIndex (&Src, Index);
IVal = 0;
Overflow = 0;
while ((C = SB_Peek (&Src)) != '\0' && (Base <= 10 ? IsDigit (C) : IsXDigit (C))) {
DigitVal = HexVal (C);
if (DigitVal >= Base) {
@ -582,9 +591,17 @@ static void NumericConst (void)
SB_Clear (&Src);
break;
}
IVal = (IVal * Base) + DigitVal;
/* Test result of adding digit for overflow. */
if (((scan_t)(IVal * Base + DigitVal) / Base) != IVal) {
Overflow = 1;
}
IVal = IVal * Base + DigitVal;
SB_Skip (&Src);
}
if (Overflow) {
Error ("Numerical constant \"%s\" too large for internal %d-bit representation",
SB_GetConstBuf (&Src), (int)(sizeof(IVal)*CHAR_BIT));
}
/* Distinguish between integer and floating point constants */
if (!IsFloat) {

View File

@ -793,6 +793,8 @@ static int HandleSymRedefinition (SymEntry* Sym, const Type* T, unsigned Flags)
*/
Error ("Redeclaration of enumerator constant '%s'", Sym->Name);
Sym = 0;
} else if (Flags & SC_STRUCTFIELD) {
Error ("Duplicate member '%s'", Sym->Name);
}
}
}
@ -1338,15 +1340,14 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
Name);
Entry = 0;
} else if ((Flags & SC_ESUTYPEMASK) != SC_TYPEDEF) {
/* If a static declaration follows a non-static declaration, then
** diagnose the conflict. It will warn and compile an extern
** declaration if both declarations are global, otherwise give an
** error.
/* If a static declaration follows a non-static declaration, then the result is undefined.
** Most compilers choose to either give an error at compile time,
** or remove the extern property for a link time error if used.
*/
if (SymTab == SymTab0 &&
(Flags & SC_EXTERN) == 0 &&
(Entry->Flags & SC_EXTERN) != 0) {
Warning ("Static declaration of '%s' follows non-static declaration", Name);
Error ("Static declaration of '%s' follows non-static declaration", Name);
} else if ((Flags & SC_EXTERN) != 0 &&
(Entry->Owner == SymTab0 || (Entry->Flags & SC_DEF) != 0) &&
(Entry->Flags & SC_EXTERN) == 0) {
@ -1358,8 +1359,12 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
*/
if (Entry->Owner == SymTab0) {
if ((Flags & SC_STORAGE) == 0) {
/* Linkage must be unchanged */
/* Linkage must be unchanged.
** The C standard specifies that a later extern declaration will be ignored,
** and will use the previous linkage instead. Giving a warning for this case.
*/
Flags &= ~SC_EXTERN;
Warning ("Extern declaration of '%s' follows static declaration, extern ignored", Name);
} else {
Error ("Non-static declaration of '%s' follows static declaration", Name);
}

View File

@ -55,7 +55,7 @@
static void DoConversion (ExprDesc* Expr, const Type* NewType)
static void DoConversion (ExprDesc* Expr, const Type* NewType, int Explicit)
/* Emit code to convert the given expression to a new type. */
{
const Type* OldType;
@ -128,6 +128,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
** internally already represented by a long.
*/
if (NewBits <= OldBits) {
long OldVal = Expr->IVal;
/* Cut the value to the new size */
Expr->IVal &= (0xFFFFFFFFUL >> (32 - NewBits));
@ -139,6 +140,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
Expr->IVal |= shl_l (~0UL, NewBits);
}
}
if ((OldVal != Expr->IVal) && IS_Get (&WarnConstOverflow) && !Explicit) {
Warning ("Implicit conversion of constant overflows %d-bit destination", NewBits);
}
}
/* Do the integer constant <-> absolute address conversion if necessary */
@ -283,7 +288,7 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType)
/* Both types must be complete */
if (!IsIncompleteESUType (NewType) && !IsIncompleteESUType (Expr->Type)) {
/* Do the actual conversion */
DoConversion (Expr, NewType);
DoConversion (Expr, NewType, 0);
} else {
/* We should have already generated error elsewhere so that we
** could just silently fail here to avoid excess errors, but to
@ -330,7 +335,7 @@ void TypeCast (ExprDesc* Expr)
ReplaceType (Expr, NewType);
} else if (IsCastType (Expr->Type)) {
/* Convert the value. The result has always the new type */
DoConversion (Expr, NewType);
DoConversion (Expr, NewType, 1);
} else {
TypeCompatibilityDiagnostic (NewType, Expr->Type, 1,
"Cast to incompatible type '%s' from '%s'");

View File

@ -850,14 +850,25 @@ static char *filterInput (FILE *F, char *tbl)
/* loads file into buffer filtering it out */
int a, prevchar = -1, i = 0, bracket = 0, quote = 1;
for (;;) {
a = getc(F);
if ((a == '\n') || (a == '\015')) a = ' ';
if (a == ',' && quote) a = ' ';
if (a == '\042') quote =! quote;
a = getc(F);
while (1) {
if (i >= BLOODY_BIG_BUFFER) {
AbEnd ("File too large for internal parsing buffer (%d bytes)",BLOODY_BIG_BUFFER);
}
if (((a == '\n') || (a == '\015')) ||
(a == ',' && quote)) {
a = ' ';
}
if (a == '\042') {
quote =! quote;
}
if (quote) {
if ((a == '{') || (a == '(')) bracket++;
if ((a == '}') || (a == ')')) bracket--;
if ((a == '{') || (a == '(')) {
bracket++;
}
if ((a == '}') || (a == ')')) {
bracket--;
}
}
if (a == EOF) {
tbl[i] = '\0';
@ -873,13 +884,18 @@ static char *filterInput (FILE *F, char *tbl)
if (a == ';' && quote) {
do {
a = getc (F);
} while (a != '\n');
fseek (F, -1, SEEK_CUR);
} while (a != '\n' && a != EOF);
/* Don't discard this newline/EOF, continue to next loop.
** A previous implementation used fseek(F,-1,SEEK_CUR),
** which is invalid for text mode files, and was unreliable across platforms.
*/
continue;
} else {
tbl[i++] = a;
prevchar = a;
}
}
a = getc(F);
}
if (bracket != 0) AbEnd ("There are unclosed brackets!");

View File

@ -64,18 +64,12 @@ static CPURegs Regs;
/* Cycles for the current insn */
static unsigned Cycles;
/* Total number of CPU cycles exec'd */
static unsigned long TotalCycles;
/* NMI request active */
static unsigned HaveNMIRequest;
/* IRQ request active */
static unsigned HaveIRQRequest;
/* flag to print cycles at program termination */
int PrintCycles;
/*****************************************************************************/
/* Helper functions and macros */
@ -3277,18 +3271,6 @@ unsigned ExecuteInsn (void)
Handlers[CPU][OPC] ();
}
/* Count cycles */
TotalCycles += Cycles;
/* Return the number of clock cycles needed by this insn */
return Cycles;
}
unsigned long GetCycles (void)
/* Return the total number of cycles executed */
{
/* Return the total number of cycles */
return TotalCycles;
}

View File

@ -96,12 +96,6 @@ unsigned ExecuteInsn (void);
** executed instruction.
*/
unsigned long GetCycles (void);
/* Return the total number of clock cycles executed */
extern int PrintCycles;
/* flag to print cycles at program termination */
/* End of 6502.h */

View File

@ -41,6 +41,20 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* flag to print cycles at program termination */
int PrintCycles = 0;
/* cycles are counted by main.c */
extern unsigned long long TotalCycles;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -99,3 +113,14 @@ void Internal (const char* Format, ...)
va_end (ap);
exit (SIM65_ERROR);
}
void SimExit (int Code)
/* Exit the simulation with an exit code */
{
if (PrintCycles) {
fprintf (stdout, "%llu cycles\n", TotalCycles);
}
exit (Code);
}

View File

@ -49,12 +49,17 @@
#define SIM65_ERROR 0x7F
/* Does not use EXIT_FAILURE because it may overlap with test results. */
#define SIM65_ERROR -1
/* An error result for errors that are not part of the simulated test.
** Note that set simulated test can only return 8-bit errors 0-255.
*/
#define SIM65_ERROR_TIMEOUT 0x7E
#define SIM65_ERROR_TIMEOUT -2
/* An error result for max CPU instructions exceeded. */
extern int PrintCycles;
/* flag to print cycles at program termination */
/*****************************************************************************/
@ -75,6 +80,9 @@ void ErrorCode (int Code, const char* Format, ...) attribute((noreturn, format(p
void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
/* Print an internal error message and die */
void SimExit (int Code);
/* Exit the simulation with an exit code */
/* End of error.h */

View File

@ -60,8 +60,14 @@
/* Name of program file */
const char* ProgramFile;
/* exit simulator after MaxCycles Cycles */
unsigned long MaxCycles;
/* count of total cycles executed */
unsigned long long TotalCycles = 0;
/* exit simulator after MaxCycles Cccles */
unsigned long long MaxCycles = 0;
/* countdown from MaxCycles */
unsigned long long RemainCycles;
/* Header signature 'sim65' */
static const unsigned char HeaderSignature[] = {
@ -72,7 +78,6 @@ static const unsigned char HeaderSignature[] = {
static const unsigned char HeaderVersion = 2;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -139,7 +144,7 @@ static void OptQuitXIns (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* quit after MaxCycles cycles */
{
MaxCycles = strtoul(Arg, NULL, 0);
MaxCycles = strtoull(Arg, NULL, 0);
}
static unsigned char ReadProgramFile (void)
@ -184,6 +189,7 @@ static unsigned char ReadProgramFile (void)
}
/* Get load address */
Val2 = 0; /* suppress uninitialized variable warning */
if (((Val = fgetc(F)) == EOF) ||
((Val2 = fgetc(F)) == EOF)) {
Error ("'%s': Header missing load address", ProgramFile);
@ -236,6 +242,7 @@ int main (int argc, char* argv[])
unsigned I;
unsigned char SPAddr;
unsigned int Cycles;
/* Initialize the cmdline module */
InitCmdLine (&argc, &argv, "sim65");
@ -298,18 +305,24 @@ int main (int argc, char* argv[])
MemInit ();
SPAddr = ReadProgramFile ();
ParaVirtInit (I, SPAddr);
Reset ();
RemainCycles = MaxCycles;
while (1) {
ExecuteInsn ();
if (MaxCycles && (GetCycles () >= MaxCycles)) {
ErrorCode (SIM65_ERROR_TIMEOUT, "Maximum number of cycles reached.");
Cycles = ExecuteInsn ();
TotalCycles += Cycles;
if (MaxCycles) {
if (Cycles > RemainCycles) {
ErrorCode (SIM65_ERROR_TIMEOUT, "Maximum number of cycles reached.");
}
RemainCycles -= Cycles;
}
}
/* Return an apropriate exit code */
return EXIT_SUCCESS;
/* Unreachable. sim65 program must exit through paravirtual PVExit
** or timeout from MaxCycles producing an error.
*/
return SIM65_ERROR;
}

View File

@ -124,11 +124,7 @@ static unsigned PopParam (unsigned char Incr)
static void PVExit (CPURegs* Regs)
{
Print (stderr, 1, "PVExit ($%02X)\n", Regs->AC);
if (PrintCycles) {
Print (stdout, 0, "%lu cycles\n", GetCycles ());
}
exit (Regs->AC);
SimExit (Regs->AC); /* Error code in range 0-255. */
}
@ -242,7 +238,15 @@ static void PVClose (CPURegs* Regs)
Print (stderr, 2, "PVClose ($%04X)\n", FD);
RetVal = close (FD);
if (FD != 0xFFFF) {
RetVal = close (FD);
} else {
/* test/val/constexpr.c "abuses" close, expecting close(-1) to return -1.
** This behaviour is not the same on all target platforms.
** MSVC's close treats it as a fatal error instead and terminates.
*/
RetVal = 0xFFFF;
}
SetAX (Regs, RetVal);
}

View File

@ -22,6 +22,7 @@ continue:
@$(MAKE) -C val all
@$(MAKE) -C ref all
@$(MAKE) -C err all
@$(MAKE) -C standard all
@$(MAKE) -C misc all
@$(MAKE) -C todo all
@ -31,6 +32,7 @@ mostlyclean:
@$(MAKE) -C val clean
@$(MAKE) -C ref clean
@$(MAKE) -C err clean
@$(MAKE) -C standard clean
@$(MAKE) -C misc clean
@$(MAKE) -C todo clean

View File

@ -12,7 +12,7 @@ endif
WORKDIR = ../testwrk/asm
SUBDIRS = cpudetect opcodes listing val err
SUBDIRS = cpudetect opcodes listing val err misc
.PHONY: all continue mostlyclean clean

70
test/asm/misc/Makefile Normal file
View File

@ -0,0 +1,70 @@
# Makefile for the remaining asm tests that need special care in one way or another
ifneq ($(shell echo),)
CMD_EXE = 1
endif
ifdef CMD_EXE
S = $(subst /,\,/)
NOT = - # Hack
EXE = .exe
NULLDEV = nul:
MKDIR = mkdir $(subst /,\,$1)
RMDIR = -rmdir /s /q $(subst /,\,$1)
else
S = /
NOT = !
EXE =
NULLDEV = /dev/null
MKDIR = mkdir -p $1
RMDIR = $(RM) -r $1
endif
ifdef QUIET
.SILENT:
NULLOUT = >$(NULLDEV)
NULLERR = 2>$(NULLDEV)
endif
SIM65FLAGS = -x 200000000
CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65)
LD65 := $(if $(wildcard ../../../bin/ld65*),..$S..$S..$Sbin$Sld65,ld65)
SIM65 := $(if $(wildcard ../../../bin/sim65*),..$S..$S..$Sbin$Ssim65,sim65)
WORKDIR = ..$S..$S..$Stestwrk$Sasm$Smisc
.PHONY: all clean
SOURCES := $(wildcard *.s)
TESTS = $(SOURCES:%.s=$(WORKDIR)/%.6502.prg)
TESTS += $(SOURCES:%.s=$(WORKDIR)/%.65c02.prg)
all: $(TESTS)
$(WORKDIR):
$(call MKDIR,$(WORKDIR))
define PRG_template
# sim65 ensure 64-bit wait time does not timeout
$(WORKDIR)/sim65-timein.$1.prg: sim65-timein.s | $(WORKDIR)
$(if $(QUIET),echo misc/sim65-timein.$1.prg)
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
$(LD65) -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
$(SIM65) -x 4400000000 -c $$@ $(NULLOUT) $(NULLERR)
# sim65 ensure 64-bit wait time does timeout
$(WORKDIR)/sim65-timeout.$1.prg: sim65-timeout.s | $(WORKDIR)
$(if $(QUIET),echo misc/sim65-timeout.$1.prg)
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
$(LD65) -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
$(NOT) $(SIM65) -x 4400000000 -c $$@ $(NULLOUT) $(NULLERR)
endef # PRG_template
$(eval $(call PRG_template,6502))
$(eval $(call PRG_template,65c02))
clean:
@$(call RMDIR,$(WORKDIR))

View File

@ -0,0 +1,55 @@
; Shared timer for:
; sim65-timein.s
; sim65-timeout.s
; wait A * 100,000,000 cycles, plus small amount of overhead
wait100m:
tay
bne :+
rts ; return quickly if A=0
:
jsr wait50331648 ; 50331648
jsr wait25165824 ; 75497472
jsr wait12582912 ; 88080384
jsr wait6291456 ; 94371840
jsr wait3145728 ; 97517568
jsr wait1572864 ; 99090432
jsr wait786432 ; 99876864
jsr wait98304 ; 99975168
jsr wait24576 ; 99999744
jsr wait192 ; 99999936
jsr wait48 ; 99999984
nop ; 99999986
nop ; 99999988
php ; 99999991
plp ; 99999995
dey ; 99999997
bne :- ; 100000000
rts
; Note that this branch could cross a page if poorly aligned,
; adding an additional 1 cycle per loop.
; This precision is not important for the tests used.
wait50331648: jsr wait25165824
wait25165824: jsr wait12582912
wait12582912: jsr wait6291456
wait6291456: jsr wait3145728
wait3145728: jsr wait1572864
wait1572864: jsr wait786432
wait786432: jsr wait393216
wait393216: jsr wait196608
wait196608: jsr wait98304
wait98304: jsr wait49152
wait49152: jsr wait24576
wait24576: jsr wait12288
wait12288: jsr wait6144
wait6144: jsr wait3072
wait3072: jsr wait1536
wait1536: jsr wait768
wait768: jsr wait384
wait384: jsr wait192
wait192: jsr wait96
wait96: jsr wait48
wait48: jsr wait24
wait24: jsr wait12
wait12: rts

View File

@ -0,0 +1,17 @@
; Verifies that sim65 can handle 64-bit timeout counter.
; sim65 sim65-timein.prg -x 4400000000
.export _main
.import exit
_main:
; wait ~4,300,000,000 cycles
lda #43
jsr wait100m
; This is a positive test.
; If the timeout did not occur, returning 0 reports success.
lda #0
rts
; wait100m
.include "sim65-time-wait.inc"

View File

@ -0,0 +1,17 @@
; Verifies that sim65 can handle 64-bit timeout counter.
; sim65 sim65-timeout.prg -x 4400000000
.export _main
.import exit
_main:
; wait ~4,500,000,000 cycles
lda #45
jsr wait100m
; This is a negative test.
; If the timeout did not occur, returning 0 reports failure.
lda #0
rts
; wait100m
.include "sim65-time-wait.inc"

View File

@ -36,3 +36,9 @@ val:
Runtime assembly tests using sim65 that should end with an exit code of 0 if
they pass. If they fail the exit code should be either -1, or a number
indicating what part of the test failed.
misc:
-----
This is for tests that require special make steps or conditions.

View File

@ -22,7 +22,7 @@ ifdef QUIET
NULLERR = 2>$(NULLDEV)
endif
SIM65FLAGS = -x 5000000000
SIM65FLAGS = -x 4000000000
CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65)
LD65 := $(if $(wildcard ../../../bin/ld65*),..$S..$S..$Sbin$Sld65,ld65)

32
test/asm/val/addrsize.s Normal file
View File

@ -0,0 +1,32 @@
; test .addrsize and ensure .feature addrsize is allowed, but inactive
.export _main
.segment "ZEROPAGE"
zplabel:
.segment "CODE"
abslabel:
; exit with 0
_main:
lda #0
tax
rts
.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
.feature addrsize
.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
.feature addrsize +
.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
.feature addrsize -
.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"

View File

@ -6,7 +6,6 @@
zplabel:
.segment "CODE"
abslabel:
; exit with 0
@ -17,13 +16,6 @@ _main:
tax
rts
.feature addrsize +
.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
.feature addrsize -
.feature at_in_identifiers on
ident@with@at:
rts

846
test/asm/val/ismnemonic.s Normal file
View File

@ -0,0 +1,846 @@
; Tests to ensure .ismnemonic is working correctly
; The .ismnemonic function calls FindInstruction internally,
; which is how the assembler detects all instructions
;
; Currently supported CPUs:
; "6502"
; "6502X"
; "6502DTV"
; "65SC02"
; "65C02"
; "4510"
; "huc6280"
; "65816"
; "sweet16"
; count any errors:
ismnemonic_error .set 0
; macro to test an instruction
.macro test_Ismnemonic instr
.if .ismnemonic(instr)
; do nothing
.else
ismnemonic_error .set 1
.endif
.endmacro
; test .feature ubiquitous_idents
; allow overloading mnemonics
.feature ubiquitous_idents
.setcpu "6502"
; make an adc macro
.macro adc
.endmacro
; should not match
.if .ismnemonic(adc)
ismnemonic_error .set 1
.endif
.delmac adc
; test all instructions:
; there is no instruction table for "none", make sure 'adc' (common to all CPUs) and 'add' (sweet16) doesn't match
.setcpu "none"
.if .ismnemonic(adc) || .ismnemonic(add)
ismnemonic_error .set 1
.endif
.setcpu "6502"
test_Ismnemonic adc
test_Ismnemonic and
test_Ismnemonic asl
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic brk
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic cmp
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic dec
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic eor
test_Ismnemonic inc
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic jmp
test_Ismnemonic jsr
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic lsr
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pha
test_Ismnemonic php
test_Ismnemonic pla
test_Ismnemonic plp
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic rti
test_Ismnemonic rts
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic sei
test_Ismnemonic sta
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic tsx
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic tya
.setcpu "6502X"
test_Ismnemonic adc
test_Ismnemonic alr
test_Ismnemonic anc
test_Ismnemonic and
test_Ismnemonic ane
test_Ismnemonic arr
test_Ismnemonic asl
test_Ismnemonic axs
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic brk
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic cmp
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic dcp
test_Ismnemonic dec
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic eor
test_Ismnemonic inc
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic isc
test_Ismnemonic jam
test_Ismnemonic jmp
test_Ismnemonic jsr
test_Ismnemonic las
test_Ismnemonic lax
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic lsr
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pha
test_Ismnemonic php
test_Ismnemonic pla
test_Ismnemonic plp
test_Ismnemonic rla
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic rra
test_Ismnemonic rti
test_Ismnemonic rts
test_Ismnemonic sax
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic sei
test_Ismnemonic sha
test_Ismnemonic shx
test_Ismnemonic shy
test_Ismnemonic slo
test_Ismnemonic sre
test_Ismnemonic sta
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic tas
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic tsx
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic tya
.setcpu "6502DTV"
test_Ismnemonic adc
test_Ismnemonic alr
test_Ismnemonic anc
test_Ismnemonic and
test_Ismnemonic ane
test_Ismnemonic arr
test_Ismnemonic asl
test_Ismnemonic axs
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic bra
test_Ismnemonic brk
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic cmp
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic dec
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic eor
test_Ismnemonic inc
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic jmp
test_Ismnemonic jsr
test_Ismnemonic las
test_Ismnemonic lax
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic lsr
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pha
test_Ismnemonic php
test_Ismnemonic pla
test_Ismnemonic plp
test_Ismnemonic rla
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic rra
test_Ismnemonic rti
test_Ismnemonic rts
test_Ismnemonic sac
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic sei
test_Ismnemonic sha
test_Ismnemonic shx
test_Ismnemonic shy
test_Ismnemonic sir
test_Ismnemonic sta
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic tsx
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic tya
.setcpu "65SC02"
test_Ismnemonic adc
test_Ismnemonic and
test_Ismnemonic asl
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic bra
test_Ismnemonic brk
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic cmp
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic dea
test_Ismnemonic dec
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic eor
test_Ismnemonic ina
test_Ismnemonic inc
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic jmp
test_Ismnemonic jsr
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic lsr
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pha
test_Ismnemonic php
test_Ismnemonic phx
test_Ismnemonic phy
test_Ismnemonic pla
test_Ismnemonic plp
test_Ismnemonic plx
test_Ismnemonic ply
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic rti
test_Ismnemonic rts
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic sei
test_Ismnemonic sta
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic stz
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic trb
test_Ismnemonic tsb
test_Ismnemonic tsx
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic tya
.setcpu "65C02"
test_Ismnemonic adc
test_Ismnemonic and
test_Ismnemonic asl
test_Ismnemonic bbr0
test_Ismnemonic bbr1
test_Ismnemonic bbr2
test_Ismnemonic bbr3
test_Ismnemonic bbr4
test_Ismnemonic bbr5
test_Ismnemonic bbr6
test_Ismnemonic bbr7
test_Ismnemonic bbs0
test_Ismnemonic bbs1
test_Ismnemonic bbs2
test_Ismnemonic bbs3
test_Ismnemonic bbs4
test_Ismnemonic bbs5
test_Ismnemonic bbs6
test_Ismnemonic bbs7
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic bra
test_Ismnemonic brk
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic cmp
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic dea
test_Ismnemonic dec
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic eor
test_Ismnemonic ina
test_Ismnemonic inc
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic jmp
test_Ismnemonic jsr
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic lsr
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pha
test_Ismnemonic php
test_Ismnemonic phx
test_Ismnemonic phy
test_Ismnemonic pla
test_Ismnemonic plp
test_Ismnemonic plx
test_Ismnemonic ply
test_Ismnemonic rmb0
test_Ismnemonic rmb1
test_Ismnemonic rmb2
test_Ismnemonic rmb3
test_Ismnemonic rmb4
test_Ismnemonic rmb5
test_Ismnemonic rmb6
test_Ismnemonic rmb7
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic rti
test_Ismnemonic rts
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic sei
test_Ismnemonic smb0
test_Ismnemonic smb1
test_Ismnemonic smb2
test_Ismnemonic smb3
test_Ismnemonic smb4
test_Ismnemonic smb5
test_Ismnemonic smb6
test_Ismnemonic smb7
test_Ismnemonic sta
test_Ismnemonic stp
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic stz
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic trb
test_Ismnemonic tsb
test_Ismnemonic tsx
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic tya
test_Ismnemonic wai
.setcpu "4510"
test_Ismnemonic adc
test_Ismnemonic and
test_Ismnemonic asl
test_Ismnemonic asr
test_Ismnemonic asw
test_Ismnemonic bbr0
test_Ismnemonic bbr1
test_Ismnemonic bbr2
test_Ismnemonic bbr3
test_Ismnemonic bbr4
test_Ismnemonic bbr5
test_Ismnemonic bbr6
test_Ismnemonic bbr7
test_Ismnemonic bbs0
test_Ismnemonic bbs1
test_Ismnemonic bbs2
test_Ismnemonic bbs3
test_Ismnemonic bbs4
test_Ismnemonic bbs5
test_Ismnemonic bbs6
test_Ismnemonic bbs7
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic bra
test_Ismnemonic brk
test_Ismnemonic bsr
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cle
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic cmp
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic cpz
test_Ismnemonic dea
test_Ismnemonic dec
test_Ismnemonic dew
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic dez
test_Ismnemonic eom
test_Ismnemonic eor
test_Ismnemonic ina
test_Ismnemonic inc
test_Ismnemonic inw
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic inz
test_Ismnemonic jmp
test_Ismnemonic jsr
test_Ismnemonic lbcc
test_Ismnemonic lbcs
test_Ismnemonic lbeq
test_Ismnemonic lbmi
test_Ismnemonic lbne
test_Ismnemonic lbpl
test_Ismnemonic lbra
test_Ismnemonic lbvc
test_Ismnemonic lbvs
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic ldz
test_Ismnemonic lsr
test_Ismnemonic map
test_Ismnemonic neg
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pha
test_Ismnemonic phd
test_Ismnemonic php
test_Ismnemonic phw
test_Ismnemonic phx
test_Ismnemonic phy
test_Ismnemonic phz
test_Ismnemonic pla
test_Ismnemonic plp
test_Ismnemonic plx
test_Ismnemonic ply
test_Ismnemonic plz
test_Ismnemonic rmb0
test_Ismnemonic rmb1
test_Ismnemonic rmb2
test_Ismnemonic rmb3
test_Ismnemonic rmb4
test_Ismnemonic rmb5
test_Ismnemonic rmb6
test_Ismnemonic rmb7
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic row
test_Ismnemonic rti
test_Ismnemonic rtn
test_Ismnemonic rts
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic see
test_Ismnemonic sei
test_Ismnemonic smb0
test_Ismnemonic smb1
test_Ismnemonic smb2
test_Ismnemonic smb3
test_Ismnemonic smb4
test_Ismnemonic smb5
test_Ismnemonic smb6
test_Ismnemonic smb7
test_Ismnemonic sta
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic stz
test_Ismnemonic tab
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic taz
test_Ismnemonic tba
test_Ismnemonic trb
test_Ismnemonic tsb
test_Ismnemonic tsx
test_Ismnemonic tsy
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic tya
test_Ismnemonic tys
test_Ismnemonic tza
.setcpu "HuC6280"
test_Ismnemonic adc
test_Ismnemonic and
test_Ismnemonic asl
test_Ismnemonic bbr0
test_Ismnemonic bbr1
test_Ismnemonic bbr2
test_Ismnemonic bbr3
test_Ismnemonic bbr4
test_Ismnemonic bbr5
test_Ismnemonic bbr6
test_Ismnemonic bbr7
test_Ismnemonic bbs0
test_Ismnemonic bbs1
test_Ismnemonic bbs2
test_Ismnemonic bbs3
test_Ismnemonic bbs4
test_Ismnemonic bbs5
test_Ismnemonic bbs6
test_Ismnemonic bbs7
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic bra
test_Ismnemonic brk
test_Ismnemonic bsr
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic cla
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic clx
test_Ismnemonic cly
test_Ismnemonic cmp
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic csh
test_Ismnemonic csl
test_Ismnemonic dea
test_Ismnemonic dec
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic eor
test_Ismnemonic ina
test_Ismnemonic inc
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic jmp
test_Ismnemonic jsr
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic lsr
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pha
test_Ismnemonic php
test_Ismnemonic phx
test_Ismnemonic phy
test_Ismnemonic pla
test_Ismnemonic plp
test_Ismnemonic plx
test_Ismnemonic ply
test_Ismnemonic rmb0
test_Ismnemonic rmb1
test_Ismnemonic rmb2
test_Ismnemonic rmb3
test_Ismnemonic rmb4
test_Ismnemonic rmb5
test_Ismnemonic rmb6
test_Ismnemonic rmb7
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic rti
test_Ismnemonic rts
test_Ismnemonic sax
test_Ismnemonic say
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic sei
test_Ismnemonic set
test_Ismnemonic smb0
test_Ismnemonic smb1
test_Ismnemonic smb2
test_Ismnemonic smb3
test_Ismnemonic smb4
test_Ismnemonic smb5
test_Ismnemonic smb6
test_Ismnemonic smb7
test_Ismnemonic st0
test_Ismnemonic st1
test_Ismnemonic st2
test_Ismnemonic sta
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic stz
test_Ismnemonic sxy
test_Ismnemonic tai
test_Ismnemonic tam
test_Ismnemonic tam0
test_Ismnemonic tam1
test_Ismnemonic tam2
test_Ismnemonic tam3
test_Ismnemonic tam4
test_Ismnemonic tam5
test_Ismnemonic tam6
test_Ismnemonic tam7
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic tdd
test_Ismnemonic tia
test_Ismnemonic tii
test_Ismnemonic tin
test_Ismnemonic tma
test_Ismnemonic tma0
test_Ismnemonic tma1
test_Ismnemonic tma2
test_Ismnemonic tma3
test_Ismnemonic tma4
test_Ismnemonic tma5
test_Ismnemonic tma6
test_Ismnemonic tma7
test_Ismnemonic trb
test_Ismnemonic tsb
test_Ismnemonic tst
test_Ismnemonic tsx
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic tya
.setcpu "65816"
test_Ismnemonic adc
test_Ismnemonic and
test_Ismnemonic asl
test_Ismnemonic bcc
test_Ismnemonic bcs
test_Ismnemonic beq
test_Ismnemonic bit
test_Ismnemonic bmi
test_Ismnemonic bne
test_Ismnemonic bpl
test_Ismnemonic bra
test_Ismnemonic brk
test_Ismnemonic brl
test_Ismnemonic bvc
test_Ismnemonic bvs
test_Ismnemonic clc
test_Ismnemonic cld
test_Ismnemonic cli
test_Ismnemonic clv
test_Ismnemonic cmp
test_Ismnemonic cop
test_Ismnemonic cpa
test_Ismnemonic cpx
test_Ismnemonic cpy
test_Ismnemonic dea
test_Ismnemonic dec
test_Ismnemonic dex
test_Ismnemonic dey
test_Ismnemonic eor
test_Ismnemonic ina
test_Ismnemonic inc
test_Ismnemonic inx
test_Ismnemonic iny
test_Ismnemonic jml
test_Ismnemonic jmp
test_Ismnemonic jsl
test_Ismnemonic jsr
test_Ismnemonic lda
test_Ismnemonic ldx
test_Ismnemonic ldy
test_Ismnemonic lsr
test_Ismnemonic mvn
test_Ismnemonic mvp
test_Ismnemonic nop
test_Ismnemonic ora
test_Ismnemonic pea
test_Ismnemonic pei
test_Ismnemonic per
test_Ismnemonic pha
test_Ismnemonic phb
test_Ismnemonic phd
test_Ismnemonic phk
test_Ismnemonic php
test_Ismnemonic phx
test_Ismnemonic phy
test_Ismnemonic pla
test_Ismnemonic plb
test_Ismnemonic pld
test_Ismnemonic plp
test_Ismnemonic plx
test_Ismnemonic ply
test_Ismnemonic rep
test_Ismnemonic rol
test_Ismnemonic ror
test_Ismnemonic rti
test_Ismnemonic rtl
test_Ismnemonic rts
test_Ismnemonic sbc
test_Ismnemonic sec
test_Ismnemonic sed
test_Ismnemonic sei
test_Ismnemonic sep
test_Ismnemonic sta
test_Ismnemonic stp
test_Ismnemonic stx
test_Ismnemonic sty
test_Ismnemonic stz
test_Ismnemonic swa
test_Ismnemonic tad
test_Ismnemonic tas
test_Ismnemonic tax
test_Ismnemonic tay
test_Ismnemonic tcd
test_Ismnemonic tcs
test_Ismnemonic tda
test_Ismnemonic tdc
test_Ismnemonic trb
test_Ismnemonic tsa
test_Ismnemonic tsb
test_Ismnemonic tsc
test_Ismnemonic tsx
test_Ismnemonic txa
test_Ismnemonic txs
test_Ismnemonic txy
test_Ismnemonic tya
test_Ismnemonic tyx
test_Ismnemonic wai
test_Ismnemonic wdm
test_Ismnemonic xba
test_Ismnemonic xce
.setcpu "sweet16"
test_Ismnemonic add
test_Ismnemonic bc
test_Ismnemonic bk
test_Ismnemonic bm
test_Ismnemonic bm1
test_Ismnemonic bnc
test_Ismnemonic bnm1
test_Ismnemonic bnz
test_Ismnemonic bp
test_Ismnemonic br
test_Ismnemonic bs
test_Ismnemonic bz
test_Ismnemonic cpr
test_Ismnemonic dcr
test_Ismnemonic inr
test_Ismnemonic ld
test_Ismnemonic ldd
test_Ismnemonic pop
test_Ismnemonic popd
test_Ismnemonic rs
test_Ismnemonic rtn
test_Ismnemonic set
test_Ismnemonic st
test_Ismnemonic std
test_Ismnemonic stp
test_Ismnemonic sub
.setcpu "6502"
.import _exit
.export _main
_main:
.if ismnemonic_error
ldx #$01
.else
ldx #$00
.endif
txa
jmp _exit

View File

@ -0,0 +1,7 @@
/* too big for internal integer representation */
unsigned long huge = 4294967296;
int main(void)
{
return 0;
}

View File

@ -0,0 +1,20 @@
/* Integer constant overflow warnings. */
/* Warnings as errors. */
#pragma warn(error,on)
/* Warn on const overflow */
#pragma warn(const-overflow,on)
unsigned char a = 256;
signed char b = 128;
unsigned char c = -129;
unsigned short int d = 0x00010000;
unsigned short int e = 0x80000000;
signed short int f = 32768L;
signed short int g = -32769L;
int main(void)
{
return 0;
}

View File

@ -0,0 +1,17 @@
/* Ensure that a duplicate member in a struct produces an error.
** https://github.com/cc65/cc65/issues/2015
*/
struct bads {
int a;
int a; /* this is an error */
};
union badu {
int a, a; /* also an error */
};
int main(void)
{
return 0;
}

View File

@ -163,6 +163,11 @@ $(WORKDIR)/goto.$1.$2.prg: goto.c $(ISEQUAL) | $(WORKDIR)
$(CC65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out
$(ISEQUAL) $(WORKDIR)/goto.$1.$2.out goto.ref
# should not compile until 3-byte struct by value tests are re-enabled
$(WORKDIR)/struct-by-value.$1.$2.prg: struct-by-value.c | $(WORKDIR)
$(if $(QUIET),echo misc/struct-by-value.$1.$2.prg)
$(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR)
# the rest are tests that fail currently for one reason or another
$(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR)
@echo "FIXME: " $$@ "currently does not compile."

156
test/misc/struct-by-value.c Normal file
View File

@ -0,0 +1,156 @@
/* This test ensures that compilation fails if a 3-byte struct by value
** is attempted, to avoid re-introducting a bug by accident:
** https://github.com/cc65/cc65/issues/2022
** When 3-byte structs are re-enabled, this test will compile,
** which should trigger a "misc" test failure.
** When this happens:
** Delete this comment from the top.
** Replace test/val/struct-by-value.c with this one.
** See:
** https://github.com/cc65/cc65/issues/2086
*/
/* Test of passing and returning structs by value.
Structs of 1, 2, 3, 4 bytes are supported.
Note that structs of 3 bytes had a past issue:
https://github.com/cc65/cc65/issues/2022
*/
int fail = 0;
struct s1 { char a; };
struct s2 { char a, b; };
struct s3 { char a, b, c; };
struct s4 { char a, b, c, d; };
const struct s1 c1 = { 1 };
const struct s2 c2 = { 2, 3 };
const struct s3 c3 = { 4, 5, 6 };
const struct s4 c4 = { 7, 8, 9, 10 };
struct s1 return1() { return c1; }
struct s2 return2() { return c2; }
struct s3 return3() { return c3; }
struct s4 return4() { return c4; }
int compare1(struct s1 a, struct s1 b)
{
if (a.a != b.a) return 1;
return 0;
}
int compare2(struct s2 a, struct s2 b)
{
if (a.a != b.a) return 1;
if (a.b != b.b) return 1;
return 0;
}
int compare3(struct s3 a, struct s3 b)
{
if (a.a != b.a) return 1;
if (a.b != b.b) return 1;
if (a.c != b.c) return 1;
return 0;
}
int compare4(struct s4 a, struct s4 b)
{
if (a.a != b.a) return 1;
if (a.b != b.b) return 1;
if (a.c != b.c) return 1;
if (a.d != b.d) return 1;
return 0;
}
int pass1(struct s1 p1)
{
struct s1 a1;
a1 = p1;
if (a1.a != c1.a) return 1;
return 0;
}
int pass2(struct s2 p2)
{
struct s2 a2;
a2 = p2;
if (a2.a != c2.a) return 1;
if (a2.b != c2.b) return 1;
return 0;
}
int pass3(struct s3 p3)
{
struct s3 a3;
a3 = p3;
if (a3.a != c3.a) return 1;
if (a3.b != c3.b) return 1;
if (a3.c != c3.c) return 1;
return 0;
}
int pass4(struct s4 p4)
{
struct s4 a4;
a4 = p4;
if (a4.a != c4.a) return 1;
if (a4.b != c4.b) return 1;
if (a4.c != c4.c) return 1;
if (a4.d != c4.d) return 1;
return 0;
}
void reset(char* gg)
{
char i;
for (i=0;i<5;++i) gg[i] = 128+i;
}
int test(char* gg, char start)
{
char i;
for (i=start;i<5;++i)
if (gg[i] != 128+i) return 1;
return 0;
}
int main()
{
/* Used to check #2022 bug condition of extra bytes being overwritten. */
union
{
char gg[5];
struct s1 g1;
struct s2 g2;
struct s3 g3;
struct s4 g4;
} guard;
reset(guard.gg);
guard.g1 = return1();
fail += compare1(guard.g1,c1);
fail += test(guard.gg,1);
reset(guard.gg);
guard.g2 = return2();
fail += compare2(guard.g2,c2);
fail += test(guard.gg,2);
reset(guard.gg);
guard.g3 = return3();
fail += compare3(guard.g3,c3);
fail += test(guard.gg,3);
reset(guard.gg);
guard.g4 = return4();
fail += compare4(guard.g4,c4);
fail += test(guard.gg,4);
fail += pass1(c1);
fail += pass2(c2);
fail += pass3(c3);
fail += pass4(c4);
return fail;
}

View File

@ -68,7 +68,11 @@ compiler is working as expected (when the tests behave as described):
which will require additional changes to the makefile(s).
To run the tests use "make" in this (top) directory, the makefile should exit
These tests only require a subset of the platform libraries. In the (top)
directory above this one, "make libtest" can be used to build only those
libraries needed for testing, instead of "make lib".
To run the tests use "make" in this (test) directory, the makefile should exit
with no error.
When a test failed you can use "make continue" to run further tests.

View File

@ -22,7 +22,7 @@ ifdef QUIET
NULLERR = 2>$(NULLDEV)
endif
SIM65FLAGS = -x 5000000000 -c
SIM65FLAGS = -x 4000000000 -c
CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65)
CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65)

View File

@ -31,7 +31,7 @@ CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65)
LD65 := $(if $(wildcard ../../bin/ld65*),..$S..$Sbin$Sld65,ld65)
SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65)
WORKDIR = ../../testwrk/val
WORKDIR = ../../testwrk/todo
OPTIONS = g O Os Osi Osir Osr Oi Oir Or
@ -49,7 +49,7 @@ $(WORKDIR):
define PRG_template
$(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR)
$(if $(QUIET),echo val/$$*.$1.$2.prg)
$(if $(QUIET),echo todo/$$*.$1.$2.prg)
$(CC65) -t sim$2 $$(CC65FLAGS) -$1 -o $$(@:.prg=.s) $$< $(NULLERR)
$(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR)
$(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR)

View File

@ -24,7 +24,7 @@ ifdef QUIET
NULLERR = 2>$(NULLDEV)
endif
SIM65FLAGS = -x 5000000000 -c
SIM65FLAGS = -x 4000000000 -c
CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65)
CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65)

View File

@ -22,7 +22,6 @@ long long0 = 0;
long long1 = 0;
unsigned long ulong0 = 0;
unsigned long ulong1 = 0;
#define NULL 0
char *cP0=NULL;
char *cP1=NULL;
int *iP0=NULL;

View File

@ -0,0 +1,66 @@
/* test struct assignment, of structs with a length of 3, which happen to be
a special case eg when passing/returning structs
related to bugs #2022, #2079 */
#include <stdio.h>
#include <stdlib.h>
int failures = 0;
struct foo { char a; char b; char c; };
struct foo foo, bar;
void f3(void)
{
foo.a = 6;
foo.b = 6;
foo.c = 6;
bar.a = 1;
bar.b = 2;
bar.c = 3;
foo = bar;
printf("%d %d %d, %d %d %d (1,2,3 1,2,3)\n",
foo.a, foo.b, foo.c,
bar.a, bar.b, bar.c);
if ((foo.a != 1) || (foo.b != 2) || (foo.c != 3) ||
(bar.a != 1) || (bar.b != 2) || (bar.c != 3)) {
failures++;
}
foo.a = 3;
foo.b = 2;
foo.c = 1;
printf("%d %d %d, %d %d %d (3,2,1 1,2,3)\n",
foo.a, foo.b, foo.c,
bar.a, bar.b, bar.c);
if ((foo.a != 3) || (foo.b != 2) || (foo.c != 1) ||
(bar.a != 1) || (bar.b != 2) || (bar.c != 3)) {
failures++;
}
bar.a = 5;
bar.b = 6;
bar.c = 7;
printf("%d %d %d, %d %d %d (3,2,1 5,6,7)\n",
foo.a, foo.b, foo.c,
bar.a, bar.b, bar.c);
if ((foo.a != 3) || (foo.b != 2) || (foo.c != 1) ||
(bar.a != 5) || (bar.b != 6) || (bar.c != 7)) {
failures++;
}
bar = foo;
foo.a = 6;
foo.b = 6;
foo.c = 6;
printf("%d %d %d, %d %d %d (6,6,6 3,2,1)\n",
foo.a, foo.b, foo.c,
bar.a, bar.b, bar.c);
if ((foo.a != 6) || (foo.b != 6) || (foo.c != 6) ||
(bar.a != 3) || (bar.b != 2) || (bar.c != 1)) {
failures++;
}
}
int main(void)
{
f3();
return failures;
}

View File

@ -20,3 +20,4 @@
#define SIZEOF_LONG_32BIT
#define UNSIGNED_CHARS
#define UNSIGNED_BITFIELDS
#define INTEGER_CONSTANT_MAX_32BIT

View File

@ -4,6 +4,14 @@
!!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC
*/
/* INTEGER_CONSTANT_MAX_32BIT
** This suppresses constants longer than 32-bit, which are now an error:
** https://github.com/cc65/cc65/pull/2084
** Because cc65's internal representation is implicitly/explicitly
** 32-bit in many places, values larger than this aren't representable,
** but also can't be checked for overflow once accepted.
*/
#include "common.h"
struct defs {
@ -62,7 +70,12 @@ long pow2(long n) {
return s;
}
long d[39], o[39], x[39];
#ifndef INTEGER_CONSTANT_MAX_32BIT
#define CTCOUNT 39
#else
#define CTCOUNT 36
#endif
long d[CTCOUNT], o[CTCOUNT], x[CTCOUNT];
#ifndef NO_OLD_FUNC_DECL
s241(pd0)
@ -212,13 +225,15 @@ int s241(struct defs *pd0) {
d[33] = 1073741823; o[33] = 07777777777; x[33] = 0x3fffffff;
d[34] = 1073741824; o[34] = 010000000000; x[34] = 0x40000000;
d[35] = 4294967295; o[35] = 037777777777; x[35] = 0xffffffff;
#if CTCOUNT > 36
d[36] = 4294967296; o[36] = 040000000000; x[36] = 0x100000000;
d[37] = 68719476735; o[37] = 0777777777777; x[37] = 0xfffffffff;
d[38] = 68719476736; o[38] = 01000000000000; x[38] = 0x1000000000;
#endif
/* WHEW! */
for (j=0; j<39; j++){
for (j=0; j<CTCOUNT; j++){
if ( g[j] != d[j]
|| d[j] != o[j]
|| o[j] != x[j]) {

View File

@ -7,13 +7,12 @@
/*
see: https://github.com/cc65/cc65/issues/191
https://github.com/cc65/cc65/issues/2111
*/
#pragma warn(error, on)
static int n = 0;
extern int n; /* should not give an error */
static int n; /* should not give an error */
extern int n; /* extern is ignored, gives a warning but keeps previous static definiton */
static int n; /* no error or warning, the previous static is still in effect */
int main(void)
{