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:
commit
a6f3c1bee6
5
.github/workflows/build-on-pull-request.yml
vendored
5
.github/workflows/build-on-pull-request.yml
vendored
|
@ -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
|
||||
|
|
35
.github/workflows/snapshot-on-push-master.yml
vendored
35
.github/workflows/snapshot-on-push-master.yml
vendored
|
@ -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
|
||||
|
|
78
.github/workflows/windows-test-scheduled.yml
vendored
Normal file
78
.github/workflows/windows-test-scheduled.yml
vendored
Normal 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
|
|
@ -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.
|
||||
|
|
4
Makefile
4
Makefile
|
@ -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 $@
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@ as it comes with the cc65 C compiler. It describes the memory layout,
|
|||
enhanced Apple //e specific header files, available drivers, and any
|
||||
pitfalls specific to that platform.
|
||||
|
||||
Please note that enhanced Apple //e specific functions are just mentioned
|
||||
Please note that this target requires a 65C02 or 65816 CPU,
|
||||
enhanced Apple //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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
12
doc/doc.css
12
doc/doc.css
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
13
doc/osi.sgml
13
doc/osi.sgml
|
@ -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 $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>
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
67
include/arpa/inet.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
32
libsrc/common/ntohl.s
Normal 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
16
libsrc/common/ntohs.s
Normal 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
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
sta $FA ; Middle display data
|
||||
jsr popa
|
||||
sta $FB ; Leftmost display data
|
||||
jsr SCANDS
|
||||
rts
|
||||
jmp SCANDS
|
||||
|
||||
.endproc
|
||||
|
|
|
@ -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
|
||||
|
|
16
libsrc/osic1p/extra/screen-c1p-48x12.s
Normal file
16
libsrc/osic1p/extra/screen-c1p-48x12.s
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@ static ExprNode* FuncIsMnemonic (void)
|
|||
/* Skip the name */
|
||||
NextTok ();
|
||||
|
||||
return GenLiteralExpr (Instr > 0);
|
||||
return GenLiteralExpr (Instr >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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'");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user