1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-08 15:29:37 +00:00

Merge branch 'cc65:master' into KIMLife

This commit is contained in:
David W Plummer 2023-09-16 10:14:00 -07:00 committed by GitHub
commit a6f3c1bee6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
132 changed files with 2678 additions and 475 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

@ -7,6 +7,10 @@ For details look at the [Website](https://cc65.github.io).
## People
Project founder:
* Ullrich von Bassewitz
Core team members:
* [Christian Groessler](https://github.com/groessler): Atari, Atari5200, and CreatiVision library Maintainer

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

@ -27,7 +27,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro start = $4000;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -43,7 +43,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -22,7 +22,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -26,7 +26,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -27,7 +27,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro start = $4000;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -43,7 +43,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -22,7 +22,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -26,7 +26,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
LC: load = MAIN, run = LC, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -52,7 +52,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro, define = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = bss, optional = yes;
BSS: load = MAIN, type = bss, define = yes;
AUTOSTRT: load = TRAILER, type = ro;
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;

View File

@ -36,7 +36,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro, define = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = bss, optional = yes;
BSS: load = MAIN, type = bss, define = yes;
}
FEATURES {

View File

@ -40,7 +40,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro, define = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = bss, optional = yes;
BSS: load = MAIN, type = bss, define = yes;
AUTOSTRT: load = TRAILER, type = ro;
}

View File

@ -67,7 +67,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro, define = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = bss, optional = yes;
BSS: load = MAIN, type = bss, define = yes;
AUTOSTRT: load = TRAILER, type = ro;
}

View File

@ -78,7 +78,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro, define = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = bss, optional = yes;
BSS: load = MAIN, type = bss, define = yes;
AUTOSTRT: load = TRAILER, type = ro;

View File

@ -58,7 +58,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro, define = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = bss, optional = yes;
BSS: load = MAIN, type = bss, define = yes;
SRPREPHDR: load = UNUSED, type = ro;
SRPREPTRL: load = UNUSED, type = ro;

View File

@ -65,7 +65,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro, define = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = bss, optional = yes;
BSS: load = MAIN, type = bss, define = yes;
AUTOSTRT: load = TRAILER, type = ro;
}

View File

@ -23,7 +23,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BASTAIL: load = MAIN, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -44,7 +44,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BSS: load = BSS, type = bss, define = yes;
OVL1ADDR: load = OVL1ADDR, type = ro;

View File

@ -23,7 +23,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BSS: load = BSS, type = bss, define = yes;
}

View File

@ -11,10 +11,10 @@ SEGMENTS {
ZP: load = ZP, type = zp, optional = yes;
VECTORS: load = ROM, run = RAM, type = rw, define = yes;
DATA: load = ROM, run = RAM, type = rw, define = yes, start = $0204;
INIT: load = RAM, type = bss, optional = yes;
BSS: load = RAM, type = bss, define = yes;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
INIT: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
AUDIO: load = ROM, type = ro, optional = yes, start = $BF00;
SETUP: load = ROM, type = ro, start = $BFE8;

View File

@ -57,7 +57,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = rw, optional = yes; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BSS: load = BSS, type = bss, define = yes;
BRAM01ADDR: load = BRAM01ADDR, type = ro, optional = yes;

View File

@ -24,7 +24,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw, optional = yes;
INIT: load = MAIN, type = rw, optional = yes; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BSS: load = BSS, type = bss, define = yes;
}

View File

@ -22,7 +22,7 @@ SEGMENTS {
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BASTAIL: load = MAIN, type = ro, optional = yes;
BSS: load = BSS, type = bss, define = yes;

View File

@ -603,7 +603,7 @@ url="ca65.html" name="assembler manual">.
The header file <tt/apple2_filetype.h/ also defines many values
that can be used to set these variables. It is included in
<tt/apple2.h/, which is in turn included in <tt/apple2enh.h/.
<tt/apple2.h/.
<tag>Example</tag>

View File

@ -21,7 +21,8 @@ as it comes with the cc65 C compiler. It describes the memory layout,
enhanced&nbsp;Apple&nbsp;//e specific header files, available drivers, and any
pitfalls specific to that platform.
Please note that enhanced&nbsp;Apple&nbsp;//e specific functions are just mentioned
Please note that this target requires a 65C02 or 65816 CPU,
enhanced&nbsp;Apple&nbsp;//e specific functions are just mentioned
here, they are described in detail in the separate <url url="funcref.html"
name="function reference">. Even functions marked as "platform dependent" may
be available on more than one platform. Please see the function reference for

View File

@ -120,7 +120,7 @@ Long options:
--list-bytes n Maximum number of bytes per listing line
--memory-model model Set the memory model
--pagelength n Set the page length for the listing
--relax-checks Relax some checks (see docs)
--relax-checks Disables some error checks
--smart Enable smart mode
--target sys Set the target system
--verbose Increase verbosity
@ -265,14 +265,17 @@ Here is a description of all the command line options:
<label id="option--relax-checks">
<tag><tt>--relax-checks</tt></tag>
Relax some checks done by the assembler. This will allow code that is an
Disables some error checks done by the assembler. This will allow code that is an
error in most cases and flagged as such by the assembler, but can be valid
in special situations.
Examples are:
Disabled checks are:
<itemize>
<item>Short branches between two different segments.
<item>Byte sized address loads where the address is not a zeropage address.
<item>Address vs. fragment size: a byte sized load from an non-zeropage
address is truncated instead of producing an error.
<item>Indirect jump on page boundary: <tt>jmp (label)</tt> on a label that
resides on a page boundary (<tt>$xxFF</tt>) fetches the second byte from the
wrong address on 6502 CPUs, now allowed instead of producing an error.
</itemize>
@ -1367,17 +1370,22 @@ writable.
Reading this pseudo variable will give the assembler version according to
the following formula:
VER_MAJOR*$100 + VER_MINOR*$10
<tt>(VER_MAJOR * 0x100) + VER_MINOR</tt>
It may be used to encode the assembler version or check the assembler for
special features not available with older versions.
The upper 8 bits are the major-, the lower 8 bits are the minor version.
Example:
Version 2.14 of the assembler will return $2E0 as numerical constant when
reading the pseudo variable <tt/.VERSION/.
For example, version 47.11 of the assembler would have this macro defined as
<tt/0x2f0b/.
Note: until 2.19 this pseudo variable was defined as <tt>(VER_MAJOR * 0x100) + VER_MINOR * 0x10</tt> -
which resulted in broken values starting at version 2.16 of the assembler. For
this reason the value of this pseudo variable is considered purely informal - you should
not use it to check for a specific assembler version and use different code
according to the detected version - please update your code to work with the
recent version of the assembler instead (There is very little reason to not use
the most recent version - and even less to support older versions in your code).
<sect>Pseudo functions<label id="pseudo-functions"><p>
@ -1409,10 +1417,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>
@ -2283,7 +2287,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
Switch on or off case sensitivity on identifiers. The default is off
(that is, identifiers are case sensitive), but may be changed by the
-i switch on the command line.
The command must be followed by a '+' or '-' character to switch the
The command can be followed by a '+' or '-' character to switch the
option on or off respectively.
Example:
@ -2432,7 +2436,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
Switch on or off debug info generation. The default is off (that is,
the object file will not contain debug infos), but may be changed by the
-g switch on the command line.
The command must be followed by a '+' or '-' character to switch the
The command can be followed by a '+' or '-' character to switch the
option on or off respectively.
Example:
@ -2795,12 +2799,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
@ -3380,7 +3378,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
Note: Line continuations do not work in a comment. A backslash at the
end of a comment is treated as part of the comment and does not trigger
line continuation.
The command must be followed by a '+' or '-' character to switch the
The command can be followed by a '+' or '-' character to switch the
option on or off respectively.
Example:
@ -3395,7 +3393,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
<sect1><tt>.LIST</tt><label id=".LIST"><p>
Enable output to the listing. The command must be followed by a boolean
Enable output to the listing. The command can be followed by a boolean
switch ("on", "off", "+" or "-") and will enable or disable listing
output.
The option has no effect if the listing is not enabled by the command line
@ -4040,7 +4038,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE"
<sect1><tt>.SMART</tt><label id=".SMART"><p>
Switch on or off smart mode. The command must be followed by a '+' or '-'
Switch on or off smart mode. The command can be followed by a '+' or '-'
character to switch the option on or off respectively. The default is off
(that is, the assembler doesn't try to be smart), but this default may be
changed by the -s switch on the command line.
@ -4262,8 +4260,13 @@ macro actually takes in the definition. You may also leave intermediate
parameters empty. Empty parameters are replaced by empty space (that is,
they are removed when the macro is expanded). If you have a look at our
macro definition above, you will see, that replacing the "addr" parameter
by nothing will lead to wrong code in most lines. To help you, writing
macros with a variable parameter list, there are some control commands:
by nothing will lead to wrong code in most lines.
The names "a", "x" and "y" should be avoided for macro parameters, as these
will usually conflict with the 6502 registers.
For writing macros with a variable parameter list, control commands are
available:
<tt><ref id=".IFBLANK" name=".IFBLANK"></tt> tests the rest of the line and
returns true, if there are any tokens on the remainder of the line. Since
@ -4274,15 +4277,15 @@ opposite.
Look at this example:
<tscreen><verb>
.macro ldaxy a, x, y
.ifnblank a
lda #a
.macro ldaxy i, j, k
.ifnblank i
lda #i
.endif
.ifnblank x
ldx #x
.ifnblank j
ldx #j
.endif
.ifnblank y
ldy #y
.ifnblank k
ldy #k
.endif
.endmacro
</verb></tscreen>

View File

@ -741,7 +741,7 @@ Here is a description of all the command line options:
<tag><tt/return-type/</tag>
Warn about no return statement in function returning non-void.
<tag><tt/struct-param/</tag>
Warn when passing structs by value.
Warn when passing structs by value. (Disabled by default.)
<tag><tt/unknown-pragma/</tag>
Warn about #pragmas that aren't recognized by cc65.
<tag><tt/unreachable-code/</tag>
@ -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
@ -805,10 +807,12 @@ and the one defined by the ISO standard:
<itemize>
<item> The datatypes "float" and "double" are not available.
Floating point constants may be used, though they will have to be
converted and stored into integer values.
Floating point arithmetic expressions are not supported.
<p>
<item> C Functions may not return structs (or unions), and structs may not
be passed as parameters by value. However, struct assignment *is*
possible.
<item> C Functions may pass and return structs (or unions) by value, but only
of 1, 2 or 4 byte sizes.
<p>
<item> Most of the C library is available with only the fastcall calling
convention (<ref id="extension-fastcall" name="see below">). It means

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

@ -435,6 +435,16 @@ see also <tt>testcode/lib/em-test.c</tt> and <tt>samples/multidemo.c</tt>.
(incomplete)
<sect1><tt/inet.h/<label id="inet.h"><p>
<itemize>
<item><ref id="htonl" name="htonl">
<item><ref id="htons" name="htons">
<item><ref id="ntohl" name="ntohl">
<item><ref id="ntohs" name="ntohs">
</itemize>
<sect1><tt/geos.h/<label id="geos.h"><p>
<url url="geos.html" name="GEOS API">.
@ -976,7 +986,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>
@ -4388,6 +4398,45 @@ to undefined behaviour.
</descrip>
</quote>
<sect1>htonl<label id="htonl"><p>
<quote>
<descrip>
<tag/Function/Swaps byte order in a 32 bit word.
<tag/Header/<tt/<ref id="inet.h" name="arpa/inet.h">/
<tag/Declaration/<tt/int htonl(val)/
<tag/Description/Converts a 32 bit word from from network byte order
(big endian) to little endian (or vice-versa).
<tag/Notes/<itemize>
<item>The function is only available as fastcall function, so it may only
be used in presence of a prototype.
</itemize>
<tag/See also/
<ref id="ntohl" name="ntohl">
<tag/Availability/cc65
</descrip>
</quote>
<sect1>htons<label id="htons"><p>
<quote>
<descrip>
<tag/Function/Swaps byte order in a 16 bit word.
<tag/Header/<tt/<ref id="inet.h" name="arpa/inet.h">/
<tag/Declaration/<tt/int htons(val)/
<tag/Description/Converts a 16 bit word from from network byte order
(big endian) to little endian (or vice-versa) by swapping both its bytes.
<tag/Notes/<itemize>
<item>The function is only available as fastcall function, so it may only
be used in presence of a prototype.
</itemize>
<tag/See also/
<ref id="ntohs" name="ntohs">
<tag/Availability/cc65
</descrip>
</quote>
<sect1>isalnum<label id="isalnum"><p>
@ -5757,6 +5806,44 @@ memory allocated for the driver.
</descrip>
</quote>
<sect1>ntohl<label id="ntohl"><p>
<quote>
<descrip>
<tag/Function/Swaps byte order in a 32 bit word.
<tag/Header/<tt/<ref id="inet.h" name="arpa/inet.h">/
<tag/Declaration/<tt/int __fastcall__ ntohl (int val);/
<tag/Description/Converts a 32 bit word from from host byte order (little endian)
to big endian (or vice-versa).
<tag/Notes/<itemize>
<item>The function is only available as fastcall function, so it may only
be used in presence of a prototype.
</itemize>
<tag/See also/
<ref id="htonl" name="htonl">
<tag/Availability/cc65
</descrip>
</quote>
<sect1>ntohs<label id="ntohs"><p>
<quote>
<descrip>
<tag/Function/Swaps byte order in a 16 bit word.
<tag/Header/<tt/<ref id="inet.h" name="arpa/inet.h">/
<tag/Declaration/<tt/int __fastcall__ ntohs (int val);/
<tag/Description/Converts a 16 bit word from from host byte order (little endian)
to big endian (or vice-versa) by swapping both its bytes.
<tag/Notes/<itemize>
<item>The function is only available as fastcall function, so it may only
be used in presence of a prototype.
</itemize>
<tag/See also/
<ref id="htons" name="htons">
<tag/Availability/cc65
</descrip>
</quote>
<sect1>offsetof<label id="offsetof"><p>
<quote>

View File

@ -270,7 +270,7 @@ required for the correct process of GEOS sequential application building.
<p>Large GEOS applications typically don't fit in one piece in their designated
memory area. They are therefore split into overlays which are loaded into memory
on demand. The individual overlays are stored as records of a VLIR (Variable
Length Index Record) file. When GEOS starts a VLIR overlay appliation it loads
Length Index Record) file. When GEOS starts a VLIR overlay application it loads
record number 0 which is supposed to contain the main program. The record numbers
starting with 1 are to be used for the actual overlays.

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

67
include/arpa/inet.h Normal file
View File

@ -0,0 +1,67 @@
/*****************************************************************************/
/* */
/* arpa/inet.h */
/* */
/* Endianness utilities for cc65 */
/* */
/* */
/* */
/* (C) 2023 Colin Leroy-Mira, <colin@colino.net> */
/* */
/* */
/* 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 _ARPA_INET_H
#define _ARPA_INET_H
/*****************************************************************************/
/* Code */
/*****************************************************************************/
#if (__OPT_i__ < 200)
int __fastcall__ ntohs (int val);
int __fastcall__ htons (int val);
#else
#define ntohs(x) \
( \
__AX__=(x), \
asm("sta tmp1"), \
asm("txa"), \
asm("ldx tmp1"), \
__AX__ \
)
#define htons(x) ntohs(x)
#endif
long __fastcall__ ntohl (long val);
long __fastcall__ htonl (long val);
/* End of arpa/inet.h */
#endif

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,13 +122,17 @@ 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 =
CC65FLAGS = -Or -W error
CA65FLAGS = -g
CC65FLAGS = -g -Or -W error
EXTZP = cbm510 \
cbm610 \
@ -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

@ -14,6 +14,8 @@
.include "apple2.inc"
.macpack cpu
.segment "ONCE"
.ifdef __APPLE2ENH__
@ -51,8 +53,13 @@ cputdirect:
cmp WNDWDTH
bcc :+
jsr newline
left: lda #$00 ; Goto left edge of screen
left:
.if (.cpu .bitand CPU_ISET_65SC02)
stz CH ; Goto left edge of screen
.else
lda #$00 ; Goto left edge of screen
sta CH
.endif
: rts
newline:
@ -78,17 +85,18 @@ mask: and INVFLG ; Apply normal, inverse, flash
putchardirect:
pha
ldy CH
.ifdef __APPLE2ENH__
lda CH
bit RD80VID ; In 80 column mode?
bpl put ; No, just go ahead
tya
lsr ; Div by 2
tay
bcs put ; Odd cols go in main memory
bit HISCR ; Assume SET80COL
put: tay
.else
ldy CH
.endif
put: lda (BASL),Y ; Get current character
lda (BASL),Y ; Get current character
tax ; Return old character for _cgetc
pla
sta (BASL),Y

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

@ -26,6 +26,7 @@
.include "ser-error.inc"
.macpack module
.macpack cpu
; ------------------------------------------------------------------------
; Header. Includes jump table
@ -57,9 +58,13 @@
;----------------------------------------------------------------------------
; I/O definitions
.if (.cpu .bitand CPU_ISET_65C02)
ACIA = $C088
.else
Offset = $8F ; Move 6502 false read out of I/O to page $BF
ACIA = $C088-Offset
.endif
ACIA_DATA = ACIA+0 ; Data register
ACIA_STATUS = ACIA+1 ; Status register
ACIA_CMD = ACIA+2 ; Command register
@ -127,16 +132,41 @@ ParityTable:
.byte $60 ; SER_PAR_EVEN
.byte $A0 ; SER_PAR_MARK
.byte $E0 ; SER_PAR_SPACE
; Check five bytes at known positions on the
; slot's firmware to make sure this is an SSC
; (or Apple //c comm port) firmware that drives
; an ACIA 6551 chip.
;
; The SSC firmware and the Apple //c(+) comm
; port firmware all begin with a BIT instruction.
; The IIgs, on the other hand, has a
; Zilog Z8530 chip and its firmware starts with
; a SEP instruction. We don't want to load this
; driver on the IIgs' serial port. We'll
; differentiate the firmware on this byte.
;
; The next four bytes we check are the Pascal
; Firmware Protocol Bytes that identify a
; serial card. Those are the same bytes for
; SSC firmwares, Apple //c firmwares and IIgs
; Zilog Z8530 firmwares - which is the reason
; we have to check for the firmware's first
; instruction too.
IdOfsTable:
.byte $00 ; First instruction
.byte $05 ; Pascal 1.0 ID byte
.byte $07 ; Pascal 1.0 ID byte
.byte $0B ; Pascal 1.1 generic signature byte
.byte $0C ; Device signature byte
IdValTable:
.byte $38 ; Fixed
.byte $18 ; Fixed
.byte $01 ; Fixed
.byte $31 ; Serial or parallel I/O card type 1
.byte $2C ; BIT
.byte $38 ; ID Byte 0 (from Pascal 1.0), fixed
.byte $18 ; ID Byte 1 (from Pascal 1.0), fixed
.byte $01 ; Generic signature for Pascal 1.1, fixed
.byte $31 ; Device signature byte (serial or
; parallel I/O card type 1)
IdTableLen = * - IdValTable
@ -200,7 +230,9 @@ SER_OPEN:
asl
asl
asl
.if .not (.cpu .bitand CPU_ISET_65C02)
adc #Offset ; Assume carry to be clear
.endif
tax
; Check if the handshake setting is valid
@ -284,14 +316,9 @@ InvBaud:lda #SER_ERR_BAUD_UNAVAIL
SER_GET:
ldx Index
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
beq :+
lda #$00 ; TryHard = false
jsr TryToSend
; Check for buffer empty
: lda RecvFreeCnt ; (25)
lda RecvFreeCnt ; (25)
cmp #$FF
bne :+
lda #SER_ERR_NO_DATA
@ -315,7 +342,11 @@ SER_GET:
inc RecvHead
inc RecvFreeCnt
ldx #$00 ; (59)
.if (.cpu .bitand CPU_ISET_65C02)
sta (ptr1)
.else
sta (ptr1,x)
.endif
txa ; Return code = 0
rts
@ -328,20 +359,21 @@ SER_PUT:
; Try to send
ldy SendFreeCnt
iny ; Y = $FF?
cpy #$FF ; Nothing to flush
beq :+
pha
lda #$00 ; TryHard = false
jsr TryToSend
pla
; Put byte into send buffer & send
: ldy SendFreeCnt
; Reload SendFreeCnt after TryToSend
ldy SendFreeCnt
bne :+
lda #SER_ERR_OVERFLOW
ldx #0 ; return value is char
rts
; Put byte into send buffer & send
: ldy SendTail
sta SendBuf,y
inc SendTail
@ -404,19 +436,19 @@ SER_IRQ:
and #$08
beq Done ; Jump if no ACIA interrupt
lda ACIA_DATA,x ; Get byte from ACIA
ldy RecvFreeCnt ; Check if we have free space left
ldx RecvFreeCnt ; Check if we have free space left
beq Flow ; Jump if no space in receive buffer
ldy RecvTail ; Load buffer pointer
sta RecvBuf,y ; Store received byte in buffer
inc RecvTail ; Increment buffer pointer
dec RecvFreeCnt ; Decrement free space counter
ldy RecvFreeCnt ; Check for buffer space low
cpy #33
cpx #33 ; Check for buffer space low
bcc Flow ; Assert flow control if buffer space low
rts ; Interrupt handled (carry already set)
; Assert flow control if buffer space too low
Flow: lda RtsOff
Flow: ldx Index
lda RtsOff
sta ACIA_CMD,x
sta Stopped
sec ; Interrupt handled
@ -427,12 +459,13 @@ Done: rts
TryToSend:
sta tmp1 ; Remember tryHard flag
Again: lda SendFreeCnt
NextByte:
lda SendFreeCnt
cmp #$FF
beq Quit ; Bail out
; Check for flow stopped
lda Stopped
Again: lda Stopped
bne Quit ; Bail out
; Check that ACIA is ready to send
@ -449,4 +482,4 @@ Send: ldy SendHead
sta ACIA_DATA,x
inc SendHead
inc SendFreeCnt
jmp Again
jmp NextByte

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

@ -227,14 +227,8 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
; returned.
SER_GET:
ldy SendFreeCnt ; Send data if necessary
iny ; Y == $FF?
beq :+
lda #$00 ; TryHard = false
jsr TryToSend
; Check for buffer empty
: lda RecvFreeCnt ; (25)
lda RecvFreeCnt ; (25)
cmp #$FF
bne :+
lda #SER_ERR_NO_DATA
@ -269,20 +263,21 @@ SER_GET:
SER_PUT:
; Try to send
ldy SendFreeCnt
iny ; Y = $FF?
cpy #$FF ; Nothing to flush
beq :+
pha
lda #$00 ; TryHard = false
jsr TryToSend
pla
; Put byte into send buffer & send
: ldy SendFreeCnt
; Reload SendFreeCnt after TryToSend
ldy SendFreeCnt
bne :+
lda #SER_ERR_OVERFLOW
ldx #0 ; return value is char
rts
; Put byte into send buffer & send
: ldy SendTail
sta SendBuf,y
inc SendTail
@ -329,19 +324,19 @@ SER_IRQ:
and #$08
beq Done ; Jump if no ACIA interrupt
lda ACIA::DATA,x ; Get byte from ACIA
ldy RecvFreeCnt ; Check if we have free space left
ldx RecvFreeCnt ; Check if we have free space left
beq Flow ; Jump if no space in receive buffer
ldy RecvTail ; Load buffer pointer
sta RecvBuf,y ; Store received byte in buffer
inc RecvTail ; Increment buffer pointer
dec RecvFreeCnt ; Decrement free space counter
ldy RecvFreeCnt ; Check for buffer space low
cpy #33
cpx #33
bcc Flow ; Assert flow control if buffer space low
rts ; Interrupt handled (carry already set)
; Assert flow control if buffer space too low
Flow: lda RtsOff
Flow: ldx Index ; Reload port
lda RtsOff
sta ACIA::CMD,x
sta Stopped
sec ; Interrupt handled
@ -352,12 +347,13 @@ Done: rts
TryToSend:
sta tmp1 ; Remember tryHard flag
Again: lda SendFreeCnt
NextByte:
lda SendFreeCnt
cmp #$FF
beq Quit ; Bail out
; Check for flow stopped
lda Stopped
Again: lda Stopped
bne Quit ; Bail out
; Check that ACIA is ready to send
@ -374,4 +370,4 @@ Send: ldy SendHead
sta ACIA::DATA
inc SendHead
inc SendFreeCnt
jmp Again
jmp NextByte

View File

@ -314,15 +314,10 @@ SER_CLOSE:
;
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty
@L1: lda RecvFreeCnt ; (25)
lda RecvFreeCnt ; (25)
cmp #$ff
bne @L2
lda #SER_ERR_NO_DATA
@ -362,21 +357,23 @@ SER_PUT:
; Try to send
ldx SendFreeCnt
inx ; X = $ff?
cpx #$FF ; Nothing to flush
beq @L2
pha
lda #$00
jsr TryToSend
pla
; Put byte into send buffer & send
; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt
bne @L3
ldx SendFreeCnt
bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero
rts
@L3: ldx SendTail
; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x
inc SendTail
dec SendFreeCnt
@ -466,25 +463,25 @@ NmiHandler:
sta tmp1 ; Remember tryHard flag
@L0: lda SendFreeCnt
cmp #$ff
beq @L3 ; Bail out
beq @L2 ; Bail out
; Check for flow stopped
@L1: lda Stopped
bne @L3 ; Bail out
bne @L2 ; Bail out
; Check that swiftlink is ready to send
@L2: lda ACIA_STATUS
lda ACIA_STATUS
and #$10
bne @L4
bne @L3
bit tmp1 ;keep trying if must try hard
bmi @L0
@L3: rts
bmi @L1
@L2: rts
; Send byte and try again
@L4: ldx SendHead
@L3: ldx SendHead
lda SendBuf,x
sta ACIA_DATA
inc SendHead

View File

@ -288,15 +288,10 @@ SER_CLOSE:
;
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty
@L1: lda RecvFreeCnt ; (25)
lda RecvFreeCnt ; (25)
cmp #$ff
bne @L2
lda #SER_ERR_NO_DATA
@ -336,21 +331,23 @@ SER_PUT:
; Try to send
ldx SendFreeCnt
inx ; X = $ff?
cpx #$FF ; Nothing to flush
beq @L2
pha
lda #$00
jsr TryToSend
pla
; Put byte into send buffer & send
; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt
bne @L3
ldx SendFreeCnt
bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero
rts
@L3: ldx SendTail
; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x
inc SendTail
dec SendFreeCnt
@ -443,25 +440,25 @@ NmiHandler:
sta tmp1 ; Remember tryHard flag
@L0: lda SendFreeCnt
cmp #$ff
beq @L3 ; Bail out
beq @L2 ; Bail out
; Check for flow stopped
@L1: lda Stopped
bne @L3 ; Bail out
bne @L2 ; Bail out
; Check that swiftlink is ready to send
@L2: lda ACIA_STATUS
lda ACIA_STATUS
and #$10
bne @L4
bne @L3
bit tmp1 ;keep trying if must try hard
bmi @L0
@L3: rts
bmi @L1
@L2: rts
; Send byte and try again
@L4: ldx SendHead
@L3: ldx SendHead
lda SendBuf,x
sta ACIA_DATA
inc SendHead

View File

@ -244,15 +244,10 @@ InvBaud:
;
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty
@L1: lda RecvFreeCnt
lda RecvFreeCnt
cmp #$ff
bne @L2
lda #SER_ERR_NO_DATA
@ -292,21 +287,23 @@ SER_PUT:
; Try to send
ldx SendFreeCnt
inx ; X = $ff?
cpx #$FF ; Nothing to flush
beq @L2
pha
lda #$00
jsr TryToSend
pla
; Put byte into send buffer & send
; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt
bne @L3
ldx SendFreeCnt
bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero
rts
@L3: ldx SendTail
; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x
inc SendTail
dec SendFreeCnt
@ -395,31 +392,31 @@ SER_IRQ:
sta IndReg ; Switch to the system bank
@L0: lda SendFreeCnt
cmp #$ff
beq @L3 ; Bail out
beq @L2 ; Bail out
; Check for flow stopped
@L1: lda Stopped
bne @L3 ; Bail out
bne @L2 ; Bail out
; Check that swiftlink is ready to send
@L2: ldy #ACIA::STATUS
ldy #ACIA::STATUS
lda (acia),y
and #$10
bne @L4
bne @L3
bit tmp1 ; Keep trying if must try hard
bmi @L0
bmi @L1
; Switch back the bank and return
@L3: lda ExecReg
@L2: lda ExecReg
sta IndReg
rts
; Send byte and try again
@L4: ldx SendHead
@L3: ldx SendHead
lda SendBuf,x
ldy #ACIA::DATA
sta (acia),y

View File

@ -245,15 +245,10 @@ InvBaud:
;
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty
@L1: lda RecvFreeCnt
lda RecvFreeCnt
cmp #$ff
bne @L2
lda #SER_ERR_NO_DATA
@ -293,21 +288,23 @@ SER_PUT:
; Try to send
ldx SendFreeCnt
inx ; X = $ff?
cpx #$ff ; Nothing to flush
beq @L2
pha
lda #$00
jsr TryToSend
pla
; Put byte into send buffer & send
; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt
bne @L3
ldx SendFreeCnt
bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero
rts
@L3: ldx SendTail
; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x
inc SendTail
dec SendFreeCnt
@ -395,31 +392,31 @@ SER_IRQ:
sta IndReg ; Switch to the system bank
@L0: lda SendFreeCnt
cmp #$ff
beq @L3 ; Bail out
beq @L2 ; Bail out
; Check for flow stopped
@L1: lda Stopped
bne @L3 ; Bail out
bne @L2 ; Bail out
; Check that swiftlink is ready to send
@L2: ldy #ACIA::STATUS
ldy #ACIA::STATUS
lda (acia),y
and #$10
bne @L4
bne @L3
bit tmp1 ; Keep trying if must try hard
bmi @L0
bmi @L1
; Switch back the bank and return
@L3: lda ExecReg
@L2: lda ExecReg
sta IndReg
rts
; Send byte and try again
@L4: ldx SendHead
@L3: ldx SendHead
lda SendBuf,x
ldy #ACIA::DATA
sta (acia),y

32
libsrc/common/ntohl.s Normal file
View File

@ -0,0 +1,32 @@
;
; Colin Leroy-Mira <colin@colino.net>, 2023-09-06
;
; int __fastcall__ ntohl (long val);
;
.export _ntohl, _htonl
.import popa
.importzp tmp1, tmp2, sreg
_htonl := _ntohl
_ntohl:
; The parts of our 32 bit word
; are in sreg+1, sreg, X, A.
; Save A and X
stx tmp1
sta tmp2
; Invert high word
lda sreg+1
ldx sreg
; Invert low word
ldy tmp1
sty sreg
ldy tmp2
sty sreg+1
rts

16
libsrc/common/ntohs.s Normal file
View File

@ -0,0 +1,16 @@
;
; Colin Leroy-Mira <colin@colino.net>, 2023-09-06
;
; int __fastcall__ ntohs (int val);
;
.export _ntohs, _htons
.importzp tmp1
_htons := _ntohs
_ntohs:
sta tmp1
txa
ldx tmp1
rts

View File

@ -8,28 +8,46 @@
.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)
bra L0 ; Same as cputs...
.else
jmp L0 ; Same as cputs...
.endif
_cputs: sta ptr1 ; Save s
stx ptr1+1
L0: ldy #0
L1: lda (ptr1),y
beq L9 ; Jump if done
.if (.cpu .bitand CPU_ISET_65SC02)
L0: lda (ptr1) ; (5)
beq L9 ; (7) Jump if done
jsr _cputc ; (13) Output char, advance cursor
inc ptr1 ; (18) Bump low byte
bne L0 ; (20) Next char
inc ptr1+1 ; (25) Bump high byte
bne L0
.else
L0: ldy #0 ; (2)
L1: lda (ptr1),y ; (7)
beq L9 ; (9) Jump if done
iny
sty tmp1 ; Save offset
jsr _cputc ; Output char, advance cursor
ldy tmp1 ; Get offset
bne L1 ; Next char
inc ptr1+1 ; Bump high byte
sty tmp1 ; (14) Save offset
jsr _cputc ; (20) Output char, advance cursor
ldy tmp1 ; (23) Get offset
bne L1 ; (25) Next char
inc ptr1+1 ; (30) Bump high byte
bne L1
.endif
; Done
L9: rts

View File

@ -10,7 +10,7 @@
.importzp sp, ptr1, ptr2, ptr3, tmp1
.macpack generic
.macpack cpu
.data
@ -74,21 +74,40 @@ out: jsr popax ; count
; Loop outputting characters
.if (.cpu .bitand CPU_ISET_65SC02)
@L1: dec outdesc+6
beq @L4
@L2: ldy tmp1
lda (ptr1),y
iny
bne @L3
inc ptr1+1
@L3: sty tmp1
jsr _cputc
jmp @L1
@L2: lda (ptr1) ; (5)
inc ptr1 ; (10)
bne @L3 ; (12)
inc ptr1+1 ; (17)
@L3: jsr _cputc ; (23)
bra @L1 ; (26)
@L4: dec outdesc+7
bne @L2
rts
.else
@L1: dec outdesc+6
beq @L4
@L2: ldy tmp1 ; (3)
lda (ptr1),y ; (8)
iny ; (10)
bne @L3 ; (12)
inc ptr1+1 ; (17)
@L3: sty tmp1 ; (20)
jsr _cputc ; (26)
jmp @L1 ; (32)
@L4: dec outdesc+7
bne @L2
rts
.endif
; ----------------------------------------------------------------------------
; vcprintf - formatted console i/o
;

View File

@ -95,12 +95,6 @@ IS_UPPER:
BAD_CHAR:
jmp plot
;-----------------------------------------------------------------------------
; Initialize the conio subsystem. "INIT" segment is nothing special on the
; Creativision, it is part of the "ROM" memory.
.segment "INIT"
initconio:
lda #$0
sta SCREEN_PTR

View File

@ -15,7 +15,6 @@
sta $FA ; Middle display data
jsr popa
sta $FB ; Leftmost display data
jsr SCANDS
rts
jmp SCANDS
.endproc

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

@ -252,15 +252,10 @@ InvBaud:
;
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
jsr TryToSend
; Check for buffer empty
@L1: lda RecvFreeCnt ; (25)
lda RecvFreeCnt ; (25)
cmp #$ff
bne @L2
lda #SER_ERR_NO_DATA
@ -300,21 +295,23 @@ SER_PUT:
; Try to send
ldx SendFreeCnt
inx ; X = $ff?
cpx #$ff ; Nothing to flush
beq @L2
pha
lda #$00
jsr TryToSend
pla
; Put byte into send buffer & send
; Reload SendFreeCnt after TryToSend
@L2: ldx SendFreeCnt
bne @L3
ldx SendFreeCnt
bne @L2
lda #SER_ERR_OVERFLOW ; X is already zero
rts
@L3: ldx SendTail
; Put byte into send buffer & send
@L2: ldx SendTail
sta SendBuf,x
inc SendTail
dec SendFreeCnt
@ -387,25 +384,25 @@ SER_IRQ:
sta tmp1 ; Remember tryHard flag
@L0: lda SendFreeCnt
cmp #$ff
beq @L3 ; Bail out
beq @L2 ; Bail out
; Check for flow stopped
@L1: lda Stopped
bne @L3 ; Bail out
bne @L2 ; Bail out
; Check that swiftlink is ready to send
@L2: lda ACIA_STATUS
lda ACIA_STATUS
and #$10
bne @L4
bne @L3
bit tmp1 ;keep trying if must try hard
bmi @L0
@L3: rts
bmi @L1
@L2: rts
; Send byte and try again
@L4: ldx SendHead
@L3: ldx SendHead
lda SendBuf,x
sta ACIA_DATA
inc SendHead

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

@ -43,6 +43,10 @@
/*****************************************************************************/
/* EffAddr Flags */
#define EFFADDR_OVERRIDE_ZP 0x00000001UL
/* GetEA result struct */
typedef struct EffAddr EffAddr;
@ -51,6 +55,7 @@ struct EffAddr {
unsigned long AddrModeSet; /* Possible addressing modes */
struct ExprNode* Expr; /* Expression if any (NULL otherwise) */
unsigned Reg; /* Register number in sweet16 mode */
unsigned long Flags; /* Other properties */
/* The following fields are used inside instr.c */
unsigned AddrMode; /* Actual addressing mode used */

View File

@ -72,11 +72,13 @@ void GetEA (EffAddr* A)
/* Clear the output struct */
A->AddrModeSet = 0;
A->Expr = 0;
A->Flags = 0;
/* Handle an addressing size override */
switch (CurTok.Tok) {
case TOK_OVERRIDE_ZP:
Restrictions = AM65_DIR | AM65_DIR_X | AM65_DIR_Y;
A->Flags |= EFFADDR_OVERRIDE_ZP;
NextTok ();
break;

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

@ -75,7 +75,7 @@ void FinishIncludePaths (void)
AddSubSearchPathFromEnv (IncSearchPath, "CC65_HOME", "asminc");
/* Add some compiled-in search paths if defined at compile time. */
#if defined(CA65_INC) && !defined(_WIN32)
#if defined(CA65_INC) && !defined(_WIN32) && !defined(_AMIGA)
AddSearchPath (IncSearchPath, CA65_INC);
#endif

View File

@ -1269,7 +1269,8 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
ExprNode* Left = A->Expr->Left;
if ((A->Expr->Op == EXPR_BYTE0 || A->Expr->Op == EXPR_BYTE1) &&
Left->Op == EXPR_SYMBOL &&
GetSymAddrSize (Left->V.Sym) != ADDR_SIZE_ZP) {
GetSymAddrSize (Left->V.Sym) != ADDR_SIZE_ZP &&
!(A->Flags & EFFADDR_OVERRIDE_ZP)) {
/* Output a warning */
Warning (1, "Suspicious address expression");
@ -1617,11 +1618,12 @@ static void PutJMP (const InsDesc* Ins)
if (EvalEA (Ins, &A)) {
/* Check for indirect addressing */
if (A.AddrModeBit & AM65_ABS_IND) {
if ((A.AddrModeBit & AM65_ABS_IND) && (CPU < CPU_65SC02) && (RelaxChecks == 0)) {
/* Compare the low byte of the expression to 0xFF to check for
** a page cross. Be sure to use a copy of the expression otherwise
** things will go weird later.
** things will go weird later. This only affects the 6502 CPU,
** and was corrected in 65C02 and later CPUs in this family.
*/
ExprNode* E = GenNE (GenByteExpr (CloneExpr (A.Expr)), 0xFF);
@ -1629,7 +1631,7 @@ static void PutJMP (const InsDesc* Ins)
unsigned Msg = GetStringId ("\"jmp (abs)\" across page border");
/* Generate the assertion */
AddAssertion (E, ASSERT_ACT_WARN, Msg);
AddAssertion (E, ASSERT_ACT_ERROR, Msg);
}
/* No error, output code */

View File

@ -858,7 +858,12 @@ static void OneLine (void)
/* The line has switched the segment */
Size = 0;
}
DefSizeOfSymbol (Sym, Size);
/* Suppress .size Symbol if this Symbol already has a multiply-defined error,
** as it will only create its own additional unnecessary error.
*/
if ((Sym->Flags & SF_MULTDEF) == 0) {
DefSizeOfSymbol (Sym, Size);
}
}
/* Line separator must come here */

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

@ -112,6 +112,7 @@ struct CharSource {
CharSource* Next; /* Linked list of char sources */
token_t Tok; /* Last token */
int C; /* Last character */
int SkipN; /* For '\r\n' line endings, skip '\n\ if next */
const CharSourceFunctions* Func; /* Pointer to function table */
union {
InputFile File; /* File data */
@ -325,6 +326,7 @@ static void UseCharSource (CharSource* S)
Source = S;
/* Read the first character from the new file */
S->SkipN = 0;
S->Func->NextChar (S);
/* Setup the next token so it will be skipped on the next call to
@ -386,6 +388,11 @@ static void IFNextChar (CharSource* S)
while (1) {
int N = fgetc (S->V.File.F);
if (N == '\n' && S->SkipN) {
N = fgetc (S->V.File.F);
}
S->SkipN = 0;
if (N == EOF) {
/* End of file. Accept files without a newline at the end */
if (SB_NotEmpty (&S->V.File.Line)) {
@ -401,9 +408,12 @@ static void IFNextChar (CharSource* S)
/* Check for end of line */
} else if (N == '\n') {
/* End of line */
break;
} else if (N == '\r') {
/* End of line, skip '\n' if it's the next character */
S->SkipN = 1;
break;
/* Collect other stuff */
} else {
@ -738,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

@ -670,6 +670,10 @@ const Type* ArithmeticConvert (const Type* lhst, const Type* rhst)
** floating point types are not (yet) supported.
** The integral promotions are performed on both operands.
*/
if (IsClassFloat(lhst) || IsClassFloat(rhst)) {
Error ("Floating point arithmetic not supported.");
return type_long;
}
lhst = IntPromotion (lhst);
rhst = IntPromotion (rhst);
@ -803,7 +807,6 @@ const Type* GetStructReplacementType (const Type* SType)
switch (SizeOf (SType)) {
case 1: NewType = type_uchar; break;
case 2: NewType = type_uint; break;
case 3: /* FALLTHROUGH */
case 4: NewType = type_ulong; break;
default: NewType = SType; break;
}

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

@ -1901,31 +1901,46 @@ static void UnaryOp (ExprDesc* Expr)
/* Get the expression */
hie10 (Expr);
/* We can only handle integer types */
if (!IsClassInt (Expr->Type)) {
Error ("Argument must have integer type");
ED_MakeConstAbsInt (Expr, 1);
}
/* Check for a constant numeric expression */
if (ED_IsConstAbs (Expr)) {
/* Value is numeric */
switch (Tok) {
case TOK_MINUS: Expr->IVal = -Expr->IVal; break;
case TOK_PLUS: break;
case TOK_COMP: Expr->IVal = ~Expr->IVal; break;
default: Internal ("Unexpected token: %d", Tok);
if (IsClassFloat (Expr->Type)) {
switch (Tok) {
case TOK_MINUS: Expr->V.FVal = FP_D_Sub(FP_D_Make(0.0),Expr->V.FVal); break;
case TOK_PLUS: break;
case TOK_COMP: Error ("Unary ~ operator not valid for floating point constant"); break;
default: Internal ("Unexpected token: %d", Tok);
}
} else {
if (!IsClassInt (Expr->Type)) {
Error ("Constant argument must have integer or float type");
ED_MakeConstAbsInt (Expr, 1);
}
/* Value is numeric */
switch (Tok) {
case TOK_MINUS: Expr->IVal = -Expr->IVal; break;
case TOK_PLUS: break;
case TOK_COMP: Expr->IVal = ~Expr->IVal; break;
default: Internal ("Unexpected token: %d", Tok);
}
/* Adjust the type of the expression */
Expr->Type = IntPromotion (Expr->Type);
/* Limit the calculated value to the range of its type */
LimitExprValue (Expr, 1);
}
/* Adjust the type of the expression */
Expr->Type = IntPromotion (Expr->Type);
/* Limit the calculated value to the range of its type */
LimitExprValue (Expr, 1);
} else {
unsigned Flags;
/* If not constant, we can only handle integer types */
if (!IsClassInt (Expr->Type)) {
Error ("Non-constant argument must have integer type");
ED_MakeConstAbsInt (Expr, 1);
}
/* Value is not constant */
LoadExpr (CF_NONE, Expr);
@ -3090,9 +3105,10 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
Expr->Type = Expr2.Type;
} else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) {
/* Integer addition */
flags = typeadjust (Expr, &Expr2, 0);
/* Load rhs into the primary */
LoadExpr (CF_NONE, &Expr2);
/* Adjust rhs primary if needed */
flags = typeadjust (Expr, &Expr2, 0);
} else {
/* OOPS */
AddDone = -1;

View File

@ -601,7 +601,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
** We don't currently support this case.
*/
if (RType == Param->Type) {
Error ("Passing '%s' of this size by value is not supported", GetFullTypeName (Param->Type));
Error ("Passing '%s' of this size (%d) by value is not supported", GetFullTypeName (Param->Type), SizeOf (RType));
}
}

View File

@ -76,7 +76,7 @@ void FinishIncludePaths (void)
AddSubSearchPathFromEnv (SysIncSearchPath, "CC65_HOME", "include");
/* Add some compiled-in search paths if defined at compile time. */
#if defined(CC65_INC) && !defined(_WIN32)
#if defined(CC65_INC) && !defined(_WIN32) && !defined(_AMIGA)
AddSearchPath (SysIncSearchPath, CC65_INC);
#endif

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) {
@ -687,20 +704,21 @@ static void NumericConst (void)
/* Check for a fractional part and read it */
if (SB_Peek (&Src) == '.') {
Double Scale;
Double Scale, ScaleDigit;
/* Skip the dot */
SB_Skip (&Src);
/* Read fractional digits */
Scale = FP_D_Make (1.0);
ScaleDigit = FP_D_Div (FP_D_Make (1.0), FP_D_FromInt (Base));
Scale = ScaleDigit;
while (IsXDigit (SB_Peek (&Src)) && (DigitVal = HexVal (SB_Peek (&Src))) < Base) {
/* Get the value of this digit */
Double FracVal = FP_D_Div (FP_D_FromInt (DigitVal * Base), Scale);
Double FracVal = FP_D_Mul (FP_D_FromInt (DigitVal), Scale);
/* Add it to the float value */
FVal = FP_D_Add (FVal, FracVal);
/* Scale base */
Scale = FP_D_Mul (Scale, FP_D_FromInt (DigitVal));
/* Adjust Scale for next digit */
Scale = FP_D_Mul (Scale, ScaleDigit);
/* Skip the digit */
SB_Skip (&Src);
}
@ -712,12 +730,15 @@ static void NumericConst (void)
unsigned Digits;
unsigned Exp;
int Sign;
/* Skip the exponent notifier */
SB_Skip (&Src);
/* Read an optional sign */
Sign = 0;
if (SB_Peek (&Src) == '-') {
Sign = 1;
SB_Skip (&Src);
} else if (SB_Peek (&Src) == '+') {
SB_Skip (&Src);
@ -747,9 +768,11 @@ static void NumericConst (void)
Warning ("Floating constant exponent is too large");
}
/* Scale the exponent and adjust the value accordingly */
/* Scale the exponent and adjust the value accordingly.
** Decimal exponents are base 10, hexadecimal exponents are base 2 (C99).
*/
if (Exp) {
FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp)));
FVal = FP_D_Mul (FVal, FP_D_Make (pow ((Base == 16) ? 2.0 : 10.0, (Sign ? -1.0 : 1.0) * Exp)));
}
}

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;
@ -123,11 +123,23 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
** to handle sign extension correctly.
*/
/* If this is a floating point constant, convert to integer,
** and warn if precision is discarded.
*/
if (IsClassFloat (OldType) && IsClassInt (NewType)) {
long IVal = (long)Expr->V.FVal.V;
if ((Expr->V.FVal.V != FP_D_FromInt(IVal).V) && !Explicit) {
Warning ("Floating point constant (%f) converted to integer loses precision (%ld)",Expr->V.FVal.V,IVal);
}
Expr->IVal = IVal;
}
/* Check if the new datatype will have a smaller range. If it
** has a larger range, things are OK, since the value is
** 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 +151,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 +299,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 +346,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

@ -1216,7 +1216,7 @@ static void OptPrintTargetPath (const char* Opt attribute ((unused)),
SearchPaths* TargetPaths = NewSearchPath ();
AddSubSearchPathFromEnv (TargetPaths, "CC65_HOME", "target");
#if defined(CL65_TGT) && !defined(_WIN32)
#if defined(CL65_TGT) && !defined(_WIN32) && !defined(_AMIGA)
AddSearchPath (TargetPaths, CL65_TGT);
#endif
AddSubSearchPathFromBin (TargetPaths, "target");

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

@ -88,13 +88,13 @@ void InitSearchPaths (void)
AddSubSearchPathFromEnv (CfgDefaultPath, "CC65_HOME", "cfg");
/* Add some compiled-in search paths if defined at compile time. */
#if defined(LD65_LIB) && !defined(_WIN32)
#if defined(LD65_LIB) && !defined(_WIN32) && !defined(_AMIGA)
AddSearchPath (LibDefaultPath, LD65_LIB);
#endif
#if defined(LD65_OBJ) && !defined(_WIN32)
#if defined(LD65_OBJ) && !defined(_WIN32) && !defined(_AMIGA)
AddSearchPath (ObjDefaultPath, LD65_OBJ);
#endif
#if defined(LD65_CFG) && !defined(_WIN32)
#if defined(LD65_CFG) && !defined(_WIN32) && !defined(_AMIGA)
AddSearchPath (CfgDefaultPath, LD65_CFG);
#endif

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

@ -312,7 +312,7 @@ static void AssembleByte(unsigned bits, char val)
static unsigned char AnalyseNextChunks(signed *newlen, signed len, char data[32], char ColorBits)
{
char longest = 1;
char prev = 255;
unsigned char prev = 255;
char count = 0;
char index = 0;
char lindex = 0;

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

Some files were not shown because too many files have changed in this diff Show More