mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-06-26 06:29:29 +00:00
Compare commits
316 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a01cc6453a | ||
|
a7f09dc2ce | ||
|
d733a2cd27 | ||
|
098dcda93a | ||
|
886e19611e | ||
|
02986aed38 | ||
|
d5b5734ef9 | ||
|
579e58e966 | ||
|
47a7aa5a83 | ||
|
9142328468 | ||
|
70eee2bdae | ||
|
949e216c69 | ||
|
b160fb2ef2 | ||
|
63ee25741b | ||
|
8bdbae36e3 | ||
|
c0909bef1b | ||
|
8023d56b88 | ||
|
45bc17d7ee | ||
|
8452fe73a1 | ||
|
dff5c73d6a | ||
|
f8462de014 | ||
|
d08d73f422 | ||
|
0ede0e514b | ||
|
dbe73c4fb2 | ||
|
9ecfb3cfa8 | ||
|
312cb3d025 | ||
|
bd63ef1268 | ||
|
2e0382b0a6 | ||
|
611c174aed | ||
|
d9001df5d4 | ||
|
e6c3dc98e1 | ||
|
43d844fa79 | ||
|
c5bcd8ad9b | ||
|
c189875be3 | ||
|
16fcf33881 | ||
|
8091985fde | ||
|
c9354a83ea | ||
|
73c7ac5941 | ||
|
19e3bbbea3 | ||
|
12957d7740 | ||
|
a252ea65bd | ||
|
1c0b3e2fdd | ||
|
44271fe9b8 | ||
|
f6452a719f | ||
|
de6250b0cd | ||
|
c6345ec728 | ||
|
d31a8c4efe | ||
|
3a08c24869 | ||
|
99370530f5 | ||
|
fe6a8a6514 | ||
|
a2d818c3e5 | ||
|
fbd9089a8d | ||
|
f18365cf9f | ||
|
99f7ff41bb | ||
|
2de919a225 | ||
|
dd96813b76 | ||
|
fc432a3bbf | ||
|
483675fded | ||
|
64ef7cc885 | ||
|
69600744df | ||
|
5bc85161eb | ||
|
d11c1d1664 | ||
|
64f27879d7 | ||
|
92fde04422 | ||
|
d5460c991f | ||
|
73c74c519e | ||
|
2e2996bd73 | ||
|
9e6fc9a0e3 | ||
|
0bf41a39c7 | ||
|
ac9c14351f | ||
|
f4d9124102 | ||
|
70fdb68622 | ||
|
3dba86c75d | ||
|
cc385b7d98 | ||
|
3cea5a7d15 | ||
|
b131d29663 | ||
|
d4b8473b86 | ||
|
02834db8a1 | ||
|
37633d8875 | ||
|
5a93bc8b75 | ||
|
47cabad5ec | ||
|
de12d20459 | ||
|
c186d478fb | ||
|
3bacf50409 | ||
|
ac8f7c3f8b | ||
|
ee3ced574b | ||
|
ba179160d6 | ||
|
5d11dd37df | ||
|
61443f586f | ||
|
0f011ee856 | ||
|
13656092c5 | ||
|
f30850fdf1 | ||
|
b707c5bf09 | ||
|
232c027445 | ||
|
7bd5bffab5 | ||
|
a3d7cc7dca | ||
|
3972da4a13 | ||
|
a5a8b94991 | ||
|
63d3b88a7a | ||
|
9d39edf452 | ||
|
2f8a5bee84 | ||
|
e724ccb7d2 | ||
|
3671054b16 | ||
|
4b88223d04 | ||
|
03eb4f5e6f | ||
|
fc767a6e1f | ||
|
30e66fa26c | ||
|
ee91bd6da5 | ||
|
d9dccb3df6 | ||
|
868026c3f9 | ||
|
4164ec1fcb | ||
|
7f998b7ed1 | ||
|
6e2b94fb68 | ||
|
3018ddf27a | ||
|
20954fd5ce | ||
|
162113b915 | ||
|
58e3f3f9fb | ||
|
3853f9a86a | ||
|
30342d2618 | ||
|
9f1c5377b3 | ||
|
5735135add | ||
|
56e8fca270 | ||
|
afe73e23e3 | ||
|
33b2e92396 | ||
|
c572834c8c | ||
|
363691b964 | ||
|
664cecf4f7 | ||
|
02cb20ec87 | ||
|
8338c3a3d7 | ||
|
586a793df5 | ||
|
e2e47cd436 | ||
|
a86e554336 | ||
|
ed7758d7e0 | ||
|
8ff713a910 | ||
|
e4af92927d | ||
|
51b6f0025c | ||
|
fe8f3de450 | ||
|
936608d6d5 | ||
|
ba2644e7d0 | ||
|
f8985e3858 | ||
|
fcad9abcd9 | ||
|
1f17baf88e | ||
|
2555798b11 | ||
|
472b9f952d | ||
|
340ef9a4bc | ||
|
a3f2496785 | ||
|
9c25eb1fe9 | ||
|
50cac5afd4 | ||
|
cc8ce51f05 | ||
|
66017f8316 | ||
|
f33dc817f3 | ||
|
9345fad794 | ||
|
74a8795152 | ||
|
59c3b756bd | ||
|
fa815fc9b7 | ||
|
62c7bd41b3 | ||
|
a173597bda | ||
|
d511034428 | ||
|
bf97dc18c4 | ||
|
42b2ded666 | ||
|
d99260c87e | ||
|
c4fcf51e55 | ||
|
a611697819 | ||
|
b0d4f8f1f5 | ||
|
3beef5626c | ||
|
3766576bae | ||
|
e69a5d433d | ||
|
fa09db6026 | ||
|
b284fc694d | ||
|
0fc860f524 | ||
|
e09f115084 | ||
|
c73263d944 | ||
|
6f3affaaef | ||
|
e86eb56570 | ||
|
50a75a7d3e | ||
|
fc79cf9b0f | ||
|
05965397fd | ||
|
a965bc83d1 | ||
|
614fdf92f7 | ||
|
d87a05747e | ||
|
37b3d58de0 | ||
|
30db34837c | ||
|
e7e5ea7847 | ||
|
75fb2a8e5c | ||
|
ec089b2d89 | ||
|
c9e75ae77d | ||
|
5afd3cf498 | ||
|
f7099b8e8f | ||
|
b6467ce314 | ||
|
03254b28ff | ||
|
fdd7d79aaa | ||
|
6ca0a707e1 | ||
|
3d05c0ed1a | ||
|
37edd8268a | ||
|
b9fc162885 | ||
|
8c63bef8c9 | ||
|
0682af1eed | ||
|
d7626be789 | ||
|
9351406450 | ||
|
1d3b8ab99c | ||
|
3a960c3e6e | ||
|
69a5779975 | ||
|
07c0ae2f9c | ||
|
a444de693b | ||
|
7767608595 | ||
|
38462bceac | ||
|
eb30e5cf85 | ||
|
7b9f635bc0 | ||
|
d96296675b | ||
|
479c2f24b8 | ||
|
3fe2a151da | ||
|
c73c5ee185 | ||
|
600e62f0c6 | ||
|
38920c6dce | ||
|
349c45d7c0 | ||
|
a87dbf03cf | ||
|
2d02b64464 | ||
|
d61e2391ce | ||
|
73ab50f9b6 | ||
|
4749e18b35 | ||
|
b4dbcb83eb | ||
|
75f36d95dc | ||
|
0451e8ea33 | ||
|
c7f0fd4cd0 | ||
|
a425012b2b | ||
|
3268925638 | ||
|
10baf3abc6 | ||
|
fbe07c33d2 | ||
|
4f05ea487b | ||
|
1a062650ad | ||
|
f73e1dbf66 | ||
|
e461ae41d9 | ||
|
4584cc778f | ||
|
acb50ac4b9 | ||
|
bea49e2b11 | ||
|
fc0a43b9af | ||
|
999aed9cb4 | ||
|
5081307d81 | ||
|
bc7cd6f1a3 | ||
|
01056c66a8 | ||
|
dda51c3467 | ||
|
2dfe65932b | ||
|
8e8a65d44b | ||
|
109e60ae10 | ||
|
e3d54b9150 | ||
|
d986cda3b3 | ||
|
0904e83bf6 | ||
|
3a77e31e47 | ||
|
1f64a623aa | ||
|
2d5eec8ba3 | ||
|
186baf8c13 | ||
|
40ca02fc6b | ||
|
dbc84c94b2 | ||
|
8b23e9872e | ||
|
513fb85b8e | ||
|
01de3b8d6b | ||
|
51f0f6ffea | ||
|
a66d060c08 | ||
|
167dff50a5 | ||
|
5d3cae4804 | ||
|
bc3b2cd81d | ||
|
a7f708a303 | ||
|
c299bcddae | ||
|
dcb11a7080 | ||
|
83238f30f1 | ||
|
b28a4b5be4 | ||
|
d9b8b8b7d3 | ||
|
2dea6b1fcf | ||
|
4076b742fe | ||
|
e439f16249 | ||
|
7759cc52f1 | ||
|
4e5beb6c74 | ||
|
40cc5ee118 | ||
|
10784585d9 | ||
|
0803b80485 | ||
|
ce1c444900 | ||
|
ec73e41f8c | ||
|
87eb8e2f05 | ||
|
c54b6a1150 | ||
|
249d4735eb | ||
|
69cd28aa0e | ||
|
ce21eb29e5 | ||
|
0784eb8f77 | ||
|
9b6f797451 | ||
|
3f241bfcc2 | ||
|
8b96c746a2 | ||
|
310ce87bcc | ||
|
d2caee8cc3 | ||
|
46f6063929 | ||
|
dd5a95688f | ||
|
b0810a2f66 | ||
|
44ffa5e988 | ||
|
ba73d7bb19 | ||
|
c022c16dc2 | ||
|
47461b5a28 | ||
|
4c2442dd90 | ||
|
37167a2202 | ||
|
b00d43d1ea | ||
|
3f87b5dbb8 | ||
|
0cc8d1bc37 | ||
|
9df41590be | ||
|
45ee1b5c28 | ||
|
3681bc65e8 | ||
|
fc59dd30c3 | ||
|
7071f70bb2 | ||
|
c58d999ee4 | ||
|
8e3f929098 | ||
|
5970ae5bcc | ||
|
b3d42f944b | ||
|
0b059b48f5 | ||
|
7054ae2360 | ||
|
3244c17ce1 | ||
|
73389b1d1d | ||
|
5a39828bf5 | ||
|
c42beda98f | ||
|
0345834bb5 |
13
.github/workflows/node.js.yml
vendored
13
.github/workflows/node.js.yml
vendored
|
@ -11,18 +11,15 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
@ -33,3 +30,9 @@ jobs:
|
|||
- run: npm test
|
||||
env:
|
||||
TEST8BIT_GITHUB_TOKEN: ${{ secrets.TEST8BIT_GITHUB_TOKEN }}
|
||||
- run: make distro
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@v4.2.5
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: tmp/dist
|
||||
|
|
14
.gitignore
vendored
14
.gitignore
vendored
|
@ -1,13 +1,13 @@
|
|||
*~
|
||||
node_modules
|
||||
local/
|
||||
tests_output/
|
||||
test/output/
|
||||
/local/
|
||||
/tests_output/
|
||||
/test/output/
|
||||
.DS_Store
|
||||
tmp/
|
||||
web/
|
||||
release/
|
||||
gen/
|
||||
/tmp/
|
||||
/web/
|
||||
/release/
|
||||
/gen/
|
||||
config.js
|
||||
chromedriver.log
|
||||
nightwatch.conf.js
|
||||
|
|
14
Makefile
14
Makefile
|
@ -8,7 +8,6 @@ buildtsc:
|
|||
npm run esbuild
|
||||
|
||||
prepare: buildtsc
|
||||
patch -i meta/electron.diff -o electron.html
|
||||
cp node_modules/jquery/dist/jquery.min.js ./jquery/
|
||||
cp -r node_modules/bootstrap/dist/* ./bootstrap/
|
||||
cp node_modules/bootstrap-tourist/*.css node_modules/bootstrap-tourist/*.js ./lib/
|
||||
|
@ -23,18 +22,9 @@ distro: buildtsc
|
|||
rm -fr $(TMP) && mkdir -p $(TMP)
|
||||
git archive HEAD | tar x -C $(TMP)
|
||||
cp -rp gen $(TMP)
|
||||
cp -rp codemirror tss $(TMP)
|
||||
rm -r $(TMP)/doc $(TMP)/scripts $(TMP)/test* $(TMP)/tools $(TMP)/.[a-z]* $(TMP)/ts*.json # $(TMP)/meta
|
||||
rm -f $(TMP)/javatari && mkdir -p $(TMP)/javatari && cp -p javatari.js/release/javatari/* $(TMP)/javatari/
|
||||
tar cf - `cat electron.html | egrep "^<(script|link)" | egrep -o '"([^"]+).(js|css)"' | cut -d '"' -f2` | tar x -C $(TMP)
|
||||
|
||||
desktop: distro
|
||||
pushd $(TMP) && npm i && popd $(TMP)
|
||||
mkdir -p $(TMP)/resources
|
||||
./node_modules/.bin/electron-builder -mlw --project $(TMP) # --prepackaged $(TMP)
|
||||
mv $(TMP)/dist/*.* ./release/desktop/
|
||||
|
||||
meta/electron.diff: index.html electron.html
|
||||
-diff -u index.html electron.html > $@
|
||||
|
||||
tsweb:
|
||||
npm run esbuild-clean
|
||||
|
@ -64,4 +54,4 @@ syncprod: distro
|
|||
cp config.js $(TMP)
|
||||
#aws --profile pzp s3 sync --follow-symlinks $(TMP)/ s3://8bitworkshop.com/v$(VERSION)/
|
||||
s3cmd -c ~/.s3pzp sync -MFP --no-mime-magic $(TMP)/ config.js s3://8bitworkshop.com/v$(VERSION)/
|
||||
rsync --stats -riltz --chmod=a+rx -e "ssh" $(TMP)/ config.js $(RSYNC_PATH)/v$(VERSION)/
|
||||
rsync --stats --del -riltz --chmod=a+rx -e "ssh" $(TMP)/ config.js $(RSYNC_PATH)/v$(VERSION)/
|
||||
|
|
54
README.md
54
README.md
|
@ -1,15 +1,21 @@
|
|||
# 8bitworkshop
|
||||
|
||||
![example workflow](https://github.com/sehugg/8bitworkshop/actions/workflows/node.js.yml/badge.svg)
|
||||
![Build Status](https://github.com/sehugg/8bitworkshop/actions/workflows/node.js.yml/badge.svg)
|
||||
|
||||
|
||||
## Use Online
|
||||
|
||||
* Latest release: https://8bitworkshop.com/
|
||||
* Dev build: https://8bitworkshop.com/dev/
|
||||
* Latest Github build: https://sehugg.github.io/8bitworkshop/
|
||||
|
||||
## Install Locally
|
||||
|
||||
To clone just the main branch:
|
||||
|
||||
```sh
|
||||
git clone -b master --single-branch git@github.com:sehugg/8bitworkshop.git
|
||||
```
|
||||
|
||||
To build the 8bitworkshop IDE:
|
||||
|
||||
```sh
|
||||
|
@ -19,7 +25,9 @@ npm i
|
|||
npm run build
|
||||
```
|
||||
|
||||
### Start Server
|
||||
To use GitHub integration locally, download the Firebase config file, e.g. https://8bitworkshop.com/v[version]/config.js
|
||||
|
||||
### Start Local Web Server
|
||||
|
||||
Start a web server on http://localhost:8000/ while TypeScript compiles in the background:
|
||||
|
||||
|
@ -33,24 +41,26 @@ make tsweb
|
|||
npm test
|
||||
```
|
||||
|
||||
Note: Github tests may fail due to lack of permissions.
|
||||
Note: Github tests may fail due to lack of API key.
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2016-2021 [Steven Hugg](https://github.com/sehugg).
|
||||
Copyright © 2016-2024 [Steven E. Hugg](https://github.com/sehugg).
|
||||
|
||||
This project is [GPL-3.0](https://github.com/sehugg/8bitworkshop/blob/master/LICENSE) licensed.
|
||||
|
||||
Dependencies retain their original licenses.
|
||||
This project, unless specifically noted, is multi-licensed.
|
||||
You may choose to adhere to the terms of either the [GPL-3.0](https://github.com/sehugg/8bitworkshop/blob/master/LICENSE) License for the entire project or respect the individual licenses of its dependencies and included code samples, as applicable.
|
||||
|
||||
All included code samples (all files under the presets/ directory) are licensed under
|
||||
This project includes various dependencies, modules, and components that retain their original licenses.
|
||||
For detailed licensing information for each dependency, please refer to the respective files and documentation.
|
||||
|
||||
All included code samples located in the presets/ directory are licensed under
|
||||
[CC0](https://creativecommons.org/publicdomain/zero/1.0/)
|
||||
unless otherwise licensed.
|
||||
unless a different license is explicitly stated within the specific code sample.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
The IDE uses custom forks for many of these, found at https://github.com/sehugg?tab=repositories
|
||||
|
||||
### Emulators
|
||||
|
||||
* https://javatari.org/
|
||||
|
@ -61,6 +71,7 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg?
|
|||
* http://www.twitchasylum.com/jsvecx/
|
||||
* https://github.com/curiousdannii/ifvms.js/
|
||||
* https://6502ts.github.io/typedoc/stellerator-embedded/
|
||||
* https://github.com/yhzmr442/jspce
|
||||
|
||||
### Compilers
|
||||
|
||||
|
@ -74,6 +85,8 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg?
|
|||
* https://github.com/dmsc/fastbasic
|
||||
* https://github.com/wiz-lang/wiz
|
||||
* https://github.com/sylefeb/Silice
|
||||
* https://github.com/steux/cc7800
|
||||
* https://bellard.org/tcc/
|
||||
|
||||
### Assemblers/Linkers
|
||||
|
||||
|
@ -102,3 +115,22 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg?
|
|||
* https://github.com/sehugg/8bitworkshop-compilers
|
||||
* https://github.com/sehugg/8bit-tools
|
||||
* https://github.com/sehugg/awesome-8bitgamedev
|
||||
* https://github.com/sehugg?tab=repositories
|
||||
|
||||
|
||||
## Tool Server (experimental)
|
||||
|
||||
This is an experimental feature that relies on a Docker container to provide compiler tools like [llvm-mos](https://github.com/llvm-mos/llvm-mos-sdk).
|
||||
Right now, you have to run locally and build your own docker container.
|
||||
|
||||
```sh
|
||||
docker build -t 8bitws-server-debian scripts/docker
|
||||
docker run -p 3009:3009 8bitws-server-debian
|
||||
echo '{"REMOTE_URL":"http://localhost:3009/build"}' > remote.json
|
||||
```
|
||||
|
||||
Then add "&tool=llvm-mos" to your URL, like
|
||||
[this](http://localhost:8000/?platform=c64&file=sprite_collision.c&tool=llvm-mos).
|
||||
You can also rename your C files to have the suffix "-llvm.c".
|
||||
Right now only the platforms c64, atari8, nes (NROM), and pce are supported.
|
||||
Not very many of the current examples work with the new toolchain.
|
||||
|
|
19
css/ui.css
19
css/ui.css
|
@ -127,13 +127,15 @@ div.mem_info {
|
|||
bottom: 10px;
|
||||
background-color: #333;
|
||||
color: #66ff66;
|
||||
white-space: pre;
|
||||
padding: 20px;
|
||||
z-index: 12;
|
||||
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||
font-size: 12pt;
|
||||
box-shadow: 0px 0px 8px rgba(0,0,0,.5);
|
||||
max-height: 90vh;
|
||||
}
|
||||
div.mem_info_msg {
|
||||
white-space: pre;
|
||||
padding: 20px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
div.mem_info a {
|
||||
|
@ -148,6 +150,9 @@ div.mem_info a:hover {
|
|||
div.mem_info a.selected {
|
||||
color: #ffffff;
|
||||
}
|
||||
div.mem_info button {
|
||||
color: #fff;
|
||||
}
|
||||
.mem_info_links {
|
||||
text-align:right;
|
||||
}
|
||||
|
@ -292,9 +297,9 @@ div.emuspacer {
|
|||
padding: 20px;
|
||||
background: #000;
|
||||
margin-top:40px;
|
||||
margin-left:5%;
|
||||
margin-right:5%;
|
||||
width:90%;
|
||||
margin-left:3%;
|
||||
margin-right:3%;
|
||||
width:94%;
|
||||
pointer-events:auto;
|
||||
}
|
||||
.emuvideo:focus {
|
||||
|
@ -591,6 +596,8 @@ div.asset_toolbar {
|
|||
}
|
||||
.control-def {
|
||||
color: #ccc;
|
||||
white-space: nowrap;
|
||||
line-height:2em;
|
||||
}
|
||||
.book-title {
|
||||
font-size:12pt;
|
||||
|
|
|
@ -38,7 +38,7 @@ gcc6809 - need to check this out
|
|||
SmallerC - https://github.com/alexfru/SmallerC
|
||||
|
||||
vbcc - Targets 68K, patch for z-machine
|
||||
http://sun.hasenbraten.de/vbcc/\
|
||||
http://sun.hasenbraten.de/vbcc/
|
||||
|
||||
|
||||
OTHER COMPILERS
|
||||
|
|
90
doc/ecsroot/kernel.txt
Normal file
90
doc/ecsroot/kernel.txt
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Kernel
|
||||
# A Kernel draws a set of scanlines to the screen.
|
||||
|
||||
component Kernel
|
||||
lines: 0..255 "Height of region in scanlines"
|
||||
bgcolor: 0..255 "Background color"
|
||||
end
|
||||
|
||||
system SimpleKernel
|
||||
tempbytes 8
|
||||
on preframe do once [Kernel] ---
|
||||
lda #192 ; TODO: numlines
|
||||
sec
|
||||
sbc ypos_ypos_b0+ent
|
||||
sta {{$5}}+ofs
|
||||
|
||||
ldy hasbitmap_bitmap_b0+ent
|
||||
lda bitmap_bitmapdata_b0,y
|
||||
sec
|
||||
sbc {{$5}}+ofs
|
||||
sta {{$0}}+ofs
|
||||
lda bitmap_bitmapdata_b8,y
|
||||
sbc #0
|
||||
sta {{$1}}+ofs
|
||||
|
||||
ldy hascolormap_colormap_b0+ent
|
||||
lda colormap_colormapdata_b0,y
|
||||
sec
|
||||
sbc {{$5}}+ofs
|
||||
sta {{$2}}+ofs
|
||||
lda colormap_colormapdata_b8,y
|
||||
sbc #0
|
||||
sta {{$3}}+ofs
|
||||
|
||||
lda sprite_height_b0+ent
|
||||
sta {{$4}}+ofs
|
||||
lda ypos_ypos_b0+ent
|
||||
sta {{$5}}+ofs
|
||||
---
|
||||
on preframe do once [Sprite,HasBitmap,HasColormap,HasYpos] --
|
||||
{{@KernelSetup}} 0,0
|
||||
{{@KernelSetup}} 1,6
|
||||
--
|
||||
on kernel do once [Kernel]:
|
||||
lda %{<bgcolor}
|
||||
sta COLUBK
|
||||
ldy %{<lines}
|
||||
@LVScan:
|
||||
lda %{$4} ; height
|
||||
dcp %{$5}
|
||||
bcs @DoDraw1
|
||||
lda #0
|
||||
.byte $2C
|
||||
@DoDraw1:
|
||||
lda (%{$0}),y
|
||||
sta WSYNC
|
||||
sta GRP0
|
||||
lda (%{$2}),y
|
||||
sta COLUP0
|
||||
|
||||
lda %{$10} ; height
|
||||
dcp %{$11}
|
||||
bcs @DoDraw2
|
||||
lda #0
|
||||
.byte $2C
|
||||
@DoDraw2:
|
||||
lda (%{$6}),y
|
||||
sta GRP1
|
||||
lda (%{$8}),y
|
||||
sta COLUP1
|
||||
|
||||
dey ; decrement
|
||||
bne @LVScan ; repeat until 192 lines
|
||||
--
|
||||
end
|
||||
|
||||
scope Root
|
||||
|
||||
entity kernel [SimpleKernel]
|
||||
const lines = 100
|
||||
end
|
||||
|
||||
entity player1 [Sprite,HasBitmap,HasColormap,HasYpos]
|
||||
const plyrindex = 0
|
||||
init height = 8
|
||||
init xpos = 100
|
||||
init ypos = 100
|
||||
end
|
||||
|
||||
end scope
|
|
@ -367,6 +367,22 @@ Programmatic Asset Language
|
|||
- RLE compression
|
||||
- check constraints
|
||||
|
||||
https://github.com/endojs/endo/blob/master/packages/ses/README.md
|
||||
|
||||
- CPU-independent IR
|
||||
- structured assembler IR
|
||||
- ECS/macros module
|
||||
- HLL
|
||||
- static analysis module
|
||||
- linker/placement module
|
||||
- inlining, data reuse
|
||||
- nested tag for segments
|
||||
- binary generation module
|
||||
- remote fetch module
|
||||
- asset module (bitmaps, sprites, tiles, palettes, compression...)
|
||||
- asset editor UI
|
||||
- debugging API (custom state, per-cycle watchpoints)
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
@ -540,7 +556,6 @@ Should call trap() every cycle or insn of frame, or exit when returns true?
|
|||
|
||||
BETTER DEBUGGING
|
||||
|
||||
Need to mark start/end columns, not just line number
|
||||
Know if we are actively debugging or trap occurred
|
||||
isRunning() = stopped, running, waiting, debugging...
|
||||
Showing running PC may be distracting, maybe lines visited?
|
||||
|
@ -549,6 +564,7 @@ Use tick() and refresh(), not callbacks
|
|||
Show current datum when using READ
|
||||
Use https://codemirror.net/doc/manual.html#markText
|
||||
Reset doesn't break @ start unless debugging tools expanded
|
||||
Single-step can un-sync frame/scanline timing
|
||||
|
||||
|
||||
PORTING CC65 TO IDE
|
||||
|
@ -560,3 +576,4 @@ preprocessor differences (#define FOO 1 so #if works)
|
|||
extern void do_func(void)
|
||||
#pragma warnings
|
||||
CFG files
|
||||
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
// preload.js for Electron app
|
||||
const { ipcRenderer } = require('electron');
|
||||
const fs = require('fs');
|
||||
const _path = require('path');
|
||||
const chokidar = require('chokidar');
|
||||
|
||||
const homeDirectory = require('os').homedir();
|
||||
const wsroot = process.env.HOME_8BITWORKSHOP || _path.join(homeDirectory, '8bitworkshop');
|
||||
|
||||
function getLocalDir() {
|
||||
const _ui = window.ui_1 || window.ui || window; // TODO: module naming
|
||||
var dir = _ui.repo_id || _ui.platform_id || 'default';
|
||||
return _path.join(wsroot, dir);
|
||||
}
|
||||
function getLocalFilePath(path) {
|
||||
return _path.join(getLocalDir(), path);
|
||||
}
|
||||
|
||||
function isProbablyBinary(path, data) {
|
||||
var score = 0;
|
||||
// decode as UTF-8
|
||||
for (var i = 0; i < (data?data.length:0);) {
|
||||
let c = data[i++];
|
||||
if ((c & 0x80) == 0) {
|
||||
// more likely binary if we see a NUL or obscure control character
|
||||
if (c < 9 || (c >= 14 && c < 26) || c == 0x7f) {
|
||||
score++;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// look for invalid unicode sequences
|
||||
var nextra = 0;
|
||||
if ((c & 0xe0) == 0xc0) nextra = 1;
|
||||
else if ((c & 0xf0) == 0xe0) nextra = 2;
|
||||
else if ((c & 0xf8) == 0xf0) nextra = 3;
|
||||
else if (c < 0xa0) score++;
|
||||
else if (c == 0xff) score++;
|
||||
while (nextra--) {
|
||||
if (i >= data.length || (data[i++] & 0xc0) != 0x80) {
|
||||
score++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return score > 0;
|
||||
}
|
||||
|
||||
// this is before startUI is called
|
||||
process.once('loaded', () => {
|
||||
var watcher;
|
||||
var allfiles = new Set();
|
||||
// get workspace root dir
|
||||
// from browser: read workspace files asynchronously
|
||||
window.alternateLocalFilesystem = {
|
||||
getFileData: (path) => {
|
||||
let fullpath = getLocalFilePath(path);
|
||||
allfiles.add(fullpath);
|
||||
if (!fs.existsSync(fullpath)) {
|
||||
return null;
|
||||
}
|
||||
return new Promise( (resolve, reject) => {
|
||||
fs.readFile(fullpath, (err,buf) => {
|
||||
if (err) {
|
||||
resolve(err);
|
||||
} else {
|
||||
let isBinary = isProbablyBinary(path, buf);
|
||||
let data = isBinary ? buf : buf.toString('utf-8');
|
||||
console.log("getWorkspaceFile", path, isBinary, data.length);
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
setFileData: (path, data) => {
|
||||
let fullpath = getLocalFilePath(path);
|
||||
allfiles.add(fullpath);
|
||||
let encoding = typeof data === 'string' ? 'utf8' : null;
|
||||
console.log("setWorkspaceFile", fullpath, data.length);
|
||||
return new Promise( (resolve, reject) => {
|
||||
fs.mkdir(_path.dirname(fullpath), {recursive:true}, (err,dirpath) => {
|
||||
fs.writeFile(fullpath, data, {encoding:encoding}, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// watch/unwatch files as browser loses/gains focus
|
||||
window.addEventListener("blur", (e) => {
|
||||
let localdir = getLocalDir();
|
||||
if (!watcher && localdir) {
|
||||
// watch files for changes
|
||||
watcher = chokidar.watch(Array.from(allfiles), {
|
||||
//awaitWriteFinish: {pollInterval:50,stabilityThreshold:300},
|
||||
ignoreInitial: true
|
||||
});
|
||||
watcher.on('all', (event, path) => {
|
||||
path = path.substring(localdir.length + 1); //strip off prefix
|
||||
console.log('WATCH', event, path);
|
||||
// we don't use awaitWriteFinish b/c we might close() the watcher
|
||||
setTimeout(() => {
|
||||
window.reloadWorkspaceFile(path);
|
||||
}, 300);
|
||||
});
|
||||
console.log('watching', getLocalDir());
|
||||
}
|
||||
});
|
||||
window.addEventListener("focus", (e) => {
|
||||
if (watcher) {
|
||||
watcher.close();
|
||||
watcher = null;
|
||||
}
|
||||
console.log('stopped watching');
|
||||
});
|
||||
|
||||
// from electron.js: set workspace root directory
|
||||
/*
|
||||
TODO
|
||||
ipcRenderer.on('setWorkspaceRoot', (event, data) => {
|
||||
wsroot = data.root;
|
||||
var binpath = _path.join(wsroot, 'bin');
|
||||
if (!fs.existsSync(binpath)) fs.mkdirSync(binpath, {});
|
||||
console.log('setWorkspaceRoot', wsroot);
|
||||
});
|
||||
// from electron.js: file changed
|
||||
ipcRenderer.on('fileChanged', (event, data) => {
|
||||
var path = data.path;
|
||||
window.reloadWorkspaceFile(path);
|
||||
});
|
||||
*/
|
||||
console.log('loaded preload', window.alternateLocalFilesystem, window.startUI);
|
||||
});
|
257
electron.diff
257
electron.diff
|
@ -1,257 +0,0 @@
|
|||
--- index.html 2020-08-11 11:10:30.000000000 -0500
|
||||
+++ electron.html 2020-08-11 14:45:27.000000000 -0500
|
||||
@@ -3,16 +3,6 @@
|
||||
|
||||
<head>
|
||||
<title>8bitworkshop IDE</title>
|
||||
-<link rel="manifest" href="manifest.json">
|
||||
-<meta name="googlebot" content="nosnippet" />
|
||||
-<meta name="mobile-web-app-capable" content="yes">
|
||||
-<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
-<meta name="application-name" content="8bitworkshop">
|
||||
-<meta name="apple-mobile-web-app-title" content="8bitworkshop">
|
||||
-<meta name="theme-color" content="#ffffff">
|
||||
-<meta name="msapplication-navbutton-color" content="#ffffff">
|
||||
-<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
-<meta name="msapplication-starturl" content="/redir.html">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
@@ -21,46 +11,6 @@
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="css/ui.css">
|
||||
-
|
||||
-<!-- google analytics -->
|
||||
-<script>
|
||||
-window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
||||
-if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
- ga('create', 'UA-54497476-9', 'auto');
|
||||
- ga('set', 'anonymizeIp', true);
|
||||
-}
|
||||
-</script>
|
||||
-<script async src='https://www.google-analytics.com/analytics.js'></script>
|
||||
-
|
||||
-<!-- firebase libs -->
|
||||
-<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-app.js"></script>
|
||||
-<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-auth.js"></script>
|
||||
-<script defer src="config.js"></script>
|
||||
-
|
||||
-<!-- Sentry error reporting -->
|
||||
-<script
|
||||
- src="https://browser.sentry-cdn.com/5.20.1/bundle.min.js"
|
||||
- integrity="sha384-O8HdAJg1h8RARFowXd2J/r5fIWuinSBtjhwQoPesfVILeXzGpJxvyY/77OaPPXUo"
|
||||
- crossorigin="anonymous"></script>
|
||||
-<script>
|
||||
-if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
- Sentry.init({
|
||||
- dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@sentry.io/1813925',
|
||||
- beforeBreadcrumb(breadcrumb, hint) {
|
||||
- if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||
- if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||
- }
|
||||
- return breadcrumb;
|
||||
- },
|
||||
- beforeSend(event, hint) {
|
||||
- const error = hint.originalException;
|
||||
- if (error instanceof EmuHalt) return null; // ignore EmuHalt
|
||||
- return event;
|
||||
- },
|
||||
- });
|
||||
-}
|
||||
-</script>
|
||||
-
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -88,26 +38,6 @@
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="#" id="item_addfile_include">Add Include File...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_addfile_link">Add Linked File...</a></li>
|
||||
- <hr>
|
||||
- <!--
|
||||
- <li><a class="dropdown-item" href="#" id="item_switch_https" style="display:none">Switch to HTTPS...</a></li>
|
||||
- -->
|
||||
- <li><a class="dropdown-item" href="#" id="item_request_persist">Request Local Storage Permissions</a></li>
|
||||
- </ul>
|
||||
- </li>
|
||||
- <li class="dropdown dropdown-submenu">
|
||||
- <a tabindex="-1" href="#">Sync</a>
|
||||
- <ul class="dropdown-menu">
|
||||
- <li><a class="dropdown-item" href="#" id="item_github_login">Sign in to Github...</a></li>
|
||||
- <li><a class="dropdown-item" href="#" id="item_github_logout">Log out</a></li>
|
||||
- <hr>
|
||||
- <li><a class="dropdown-item" href="#" id="item_github_import">Import Project from GitHub...</a></li>
|
||||
- <li><a class="dropdown-item" href="#" id="item_github_pull">Pull Latest from Repository</a></li>
|
||||
- <hr>
|
||||
- <li><a class="dropdown-item" href="#" id="item_github_publish">Publish Project on GitHub...</a></li>
|
||||
- <li><a class="dropdown-item" href="#" id="item_github_push">Push Changes to Repository...</a></li>
|
||||
- <hr>
|
||||
- <li><a class="dropdown-item" href="#" id="item_repo_delete">Delete Local Repository...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
@@ -133,36 +63,6 @@
|
||||
<li><a class="dropdown-item" href="#" id="item_debug_expr">Break Expression...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
- <li class="dropdown dropdown-submenu">
|
||||
- <a tabindex="-1" href="#">Tools</a>
|
||||
- <ul class="dropdown-menu">
|
||||
- <li><a class="dropdown-item" target="_8bws_tools" href="https://8bitworkshop.com/dithertron/">Dithertron Image Converter</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_tools" href="https://8bitworkshop.com/bitmapfontgenerator/">Bitmap Font Generator</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_tools" href="http://tomeko.net/online_tools/file_to_hex.php?lang=en">Binary File to Hex Converter</a></li>
|
||||
- <li class="dropdown dropdown-submenu">
|
||||
- <a tabindex="-1" href="#">Atari 2600</a>
|
||||
- <ul class="dropdown-menu">
|
||||
- <li><a class="dropdown-item" target="_8bws_tools" href="https://alienbill.com/2600/playerpalnext.html">playerpal 2600</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_tools" href="https://alienbill.com/2600/playfieldpal.html">playfieldpal 2600</a></li>
|
||||
- </ul>
|
||||
- </li>
|
||||
- </ul>
|
||||
- </li>
|
||||
- <hr>
|
||||
- <li class="dropdown dropdown-submenu">
|
||||
- <a tabindex="-1" href="#">About</a>
|
||||
- <ul class="dropdown-menu">
|
||||
- <li><a class="dropdown-item" target="_8bws_about" href="https://8bitworkshop.com/blog">Latest News</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_about" href="https://8bitworkshop.com/projects">Projects</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_about" href="https://twitter.com/8bitworkshop">Twitter</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_about" href="https://github.com/sehugg/8bitworkshop">GitHub</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_about" href="https://github.com/sehugg/8bitworkshop/issues/new">Report an Issue</a></li>
|
||||
- <li><a class="dropdown-item" target="_8bws_about" href="https://8bitworkshop.com/blog/docs/ide.md.html">IDE Help</a></li>
|
||||
- </ul>
|
||||
- </li>
|
||||
- <!--
|
||||
- <hr><li><a class="dropdown-item" href="/redir.html">Use Latest Version</a></li>
|
||||
- -->
|
||||
</ul>
|
||||
</span>
|
||||
|
||||
@@ -258,39 +158,6 @@
|
||||
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
||||
</span>
|
||||
|
||||
- <!-- BOOKS menu -->
|
||||
- <span class="dropdown pull-right">
|
||||
- <a class="btn dropdown-toggle hidden-xs toolbarMenuButton" id="booksMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
- <span class="glyphicon glyphicon-book" aria-hidden="true"></span>
|
||||
- Get Books <span class="caret"></span>
|
||||
- </a>
|
||||
- <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="booksMenuButton">
|
||||
- <li>
|
||||
- <a class="dropdown-item dropdown-link book-vcs" target="_book_a2600" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=pzp-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B01N4DSRIZ&linkId=04d39e274c06e6c93b93d20a9a977111">
|
||||
- <img src="images/book_a2600.png"/>
|
||||
- <span class="book-title">Making Games For The Atari 2600</span>
|
||||
- </a>
|
||||
- </li>
|
||||
- <li>
|
||||
- <a class="dropdown-item dropdown-link book-arcade" target="_book_arcade" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2&tag=pzp-20&linkId=b27709c022d2ebe639e90316d9f4fd5b">
|
||||
- <img src="images/book_arcade.png"/>
|
||||
- <span class="book-title">Making 8-bit Arcade Games in C</span>
|
||||
- </a>
|
||||
- </li>
|
||||
- <li>
|
||||
- <a class="dropdown-item dropdown-link book-verilog" target="_book_verilog" href="https://www.amazon.com/gp/product/1728619440/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1728619440&linkCode=as2&tag=pzp-20&linkId=7237a25861cb6b49a4128ba53d84c3e2">
|
||||
- <img src="images/book_verilog.png"/>
|
||||
- <span class="book-title">Designing Video Game Hardware in Verilog</span>
|
||||
- </a>
|
||||
- </li>
|
||||
- <li>
|
||||
- <a class="dropdown-item dropdown-link book-nes" target="_book_nes" href="https://www.amazon.com/gp/product/1075952727/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1075952727&linkCode=as2&tag=pzp-20&linkId=633176e8b36fea7f927020e2c322d80a">
|
||||
- <img src="images/book_nes.png"/>
|
||||
- <span class="book-title">Making Games For The NES</span>
|
||||
- </a>
|
||||
- </li>
|
||||
- </ul>
|
||||
- </span>
|
||||
<!-- 8bitworkshop logo -->
|
||||
<span class="logo-gradient hidden-xs hidden-sm hidden-md pull-right" style="margin-left:auto" onclick="window.open('/','_8bitws');">8bitworkshop</span>
|
||||
|
||||
@@ -477,73 +344,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-<div id="importGithubModal" class="modal fade">
|
||||
- <div class="modal-dialog modal-md" role="document">
|
||||
- <div class="modal-content">
|
||||
- <div class="modal-header">
|
||||
- <h3 class="modal-title">Import Project from GitHub</h3>
|
||||
- </div>
|
||||
- <div class="modal-body">
|
||||
- <p>Enter the GitHub repository URL:</p>
|
||||
- <p><input id="importGithubURL" size="60" placeholder="https://github.com/user/repo"></input></p>
|
||||
- <p>If the project is compatible with 8bitworkshop, it should build automatically.</p>
|
||||
- <p>Otherwise, some work may be required -- make sure you've selected the correct platform.</p>
|
||||
- <p>Source files must be in the root folder of the repository.</p>
|
||||
- <p><button type="button" class="btn btn-primary" id="importGithubButton">Import Project</button></p>
|
||||
- </div>
|
||||
- <div class="modal-footer">
|
||||
- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
- </div>
|
||||
- </div>
|
||||
- </div>
|
||||
-</div>
|
||||
-<div id="publishGithubModal" class="modal fade">
|
||||
- <div class="modal-dialog modal-md" role="document">
|
||||
- <div class="modal-content">
|
||||
- <div class="modal-header">
|
||||
- <h3 class="modal-title">Publish Project on GitHub</h3>
|
||||
- </div>
|
||||
- <div class="modal-body">
|
||||
- <p>This will migrate your existing project to a new GitHub repository.</p>
|
||||
- <p>https://github.com/username/ <input id="githubRepoName" size="35" placeholder="Enter a project name"></input></p>
|
||||
- <p><input id="githubRepoDesc" size="60" placeholder="Enter a project description"></input></p>
|
||||
- <p>Your repository will be <select id="githubRepoPrivate">
|
||||
- <option value="public">Public</option>
|
||||
- <option value="private">Private</option>
|
||||
- </select></p>
|
||||
- <p>License: <select id="githubRepoLicense">
|
||||
- <option value="">Will decide later / all rights reserved</option>
|
||||
- <option value="cc0-1.0">CC Zero (public domain, remix-friendly)</option>
|
||||
- <option value="mit">MIT (must preserve notices)</option>
|
||||
- <option value="cc-by-4.0">CC BY (must attribute)</option>
|
||||
- <option value="cc-by-sa-4.0">CC BY-SA (must attribute, use same license)</option>
|
||||
- <option value="gpl-3.0">GPL v3 (must publish source)</option>
|
||||
- </select></p>
|
||||
- <p><button type="button" class="btn btn-primary" id="publishGithubButton">Upload Project</button></p>
|
||||
- <p>Your existing file will be moved to a new folder in the IDE.</p>
|
||||
- </div>
|
||||
- <div class="modal-footer">
|
||||
- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
- </div>
|
||||
- </div>
|
||||
- </div>
|
||||
-</div>
|
||||
-<div id="pushGithubModal" class="modal fade">
|
||||
- <div class="modal-dialog modal-md" role="document">
|
||||
- <div class="modal-content">
|
||||
- <div class="modal-header">
|
||||
- <h3 class="modal-title">Push Project Changes to GitHub</h3>
|
||||
- </div>
|
||||
- <div class="modal-body">
|
||||
- <p><input id="githubCommitMsg" size="50" placeholder="Enter a commit message"></input></p>
|
||||
- <p><button type="button" class="btn btn-primary" id="pushGithubButton">Push Changes</button></p>
|
||||
- </div>
|
||||
- <div class="modal-footer">
|
||||
- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
- </div>
|
||||
- </div>
|
||||
- </div>
|
||||
-</div>
|
||||
|
||||
<script src="jquery/jquery.min.js"></script>
|
||||
|
||||
@@ -635,12 +435,5 @@
|
||||
startUI();
|
||||
</script>
|
||||
|
||||
-<script>
|
||||
-/*
|
||||
- var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
||||
- if (!isFirefox && platform_id != 'vcs') { $("#best_in_firefox").show(); }
|
||||
-*/
|
||||
-</script>
|
||||
-
|
||||
</body>
|
||||
</html>
|
435
electron.html
435
electron.html
|
@ -1,435 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>8bitworkshop IDE</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
overflow: hidden;
|
||||
font-size: 11px;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="css/ui.css">
|
||||
|
||||
<!-- google analytics -->
|
||||
<script>
|
||||
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
||||
if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
ga('create', 'UA-54497476-9', 'auto');
|
||||
ga('set', 'anonymizeIp', true);
|
||||
}
|
||||
</script>
|
||||
<script async src='https://www.google-analytics.com/analytics.js'></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="controls_top" class="disable-select">
|
||||
<div id="controls_dynamic" style="visibility:hidden">
|
||||
<!-- main menu -->
|
||||
<span class="dropdown">
|
||||
<a class="btn dropdown-toggle toolbarMenuButton" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Menu">
|
||||
<span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span>
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-left" aria-labelledby="dropdownMenuButton" style="left:auto">
|
||||
<li><a class="dropdown-item" href="#" id="item_new_file">New Project...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_upload_file">Upload...</a></li>
|
||||
<hr>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">File</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="#" id="item_reset_file">Revert to Original...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_rename_file">Rename File...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_delete_file">Delete File...</a></li>
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="#" id="item_addfile_include">Add Include File...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_addfile_link">Add Linked File...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Download</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="#" id="item_download_file">Download Source File</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_download_rom">Download ROM Image</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_download_zip">Download Project as ZIP</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_download_allzip">Download All Changes as ZIP</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Share</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="#" id="item_share_file">Share Playable Link...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_record_video">Record Video...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_export_cassette">Make Cassette Audio...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Debug</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="#" id="item_debug_expr">Break Expression...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
|
||||
<!-- PLATFORMS menu -->
|
||||
<span class="dropdown">
|
||||
<a class="btn dropdown-toggle toolbarMenuButton" id="platformsMenuButton" style="min-width:90px" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="platform_name">PLATFORMS</span> <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="platformsMenuButton">
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Game Consoles</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=vcs">Atari 2600</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=nes">NES</a></li>
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="?platform=astrocade">Bally Astrocade</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=coleco">ColecoVision</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=sms-sg1000-libcv">Sega SG-1000</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=sms-sms-libcv">Sega Master System</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=atari7800">Atari 7800</a></li>
|
||||
<!--
|
||||
<li><a class="dropdown-item" href="?platform=vectrex">Vectrex</a></li>
|
||||
-->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Computers</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=c64">Commodore 64</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=msx">MSX (BIOS)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=msx-libcv">MSX (libCV)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=apple2">Apple ][+</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=zx">ZX Spectrum</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Arcade Systems</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=vicdual">VIC Dual</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=mw8080bw">Midway 8080</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=galaxian-scramble">Galaxian/Scramble</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=vector-z80color">Atari Color Vector (Z80)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=vector-ataricolor">Atari Color Vector (6502)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=williams-z80">Williams (Z80)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=sound_williams-z80">Williams Sound (Z80)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Hardware</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=verilog">Verilog</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=verilog-vga">Verilog (VGA @ 25 Mhz)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Interpreters</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=basic">BASIC</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=zmachine">Z-Machine</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=markdown">Markdown Text Editor</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">MAME Emulators</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=atari8-800xl.mame">Atari 800XL (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=atari8-5200.mame">Atari 5200 (MAME)</a></li>
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="?platform=vcs.mame">Atari 2600 (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=coleco.mame">ColecoVision (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=nes.mame">NES (MAME)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
|
||||
<!-- project selector -->
|
||||
<span id="repo_name" class="hidden-sm" style="color:#eee; font-size: small"></span>
|
||||
<select id="preset_select" name="" title="Project Select" style="max-width:20em;visibility:hidden;height:2.3em">
|
||||
</select>
|
||||
|
||||
<img id="compile_spinner" src="images/spinner.gif" style="visibility:hidden;margin-left:8px;margin-right:8px;height:2em">
|
||||
<span id="toolbar"></span>
|
||||
<span class="btn_group view_group hidden-sm hidden-xs" id="speed_bar" style="display:none">
|
||||
<button id="dbg_slowest" class="btn" title="Slowest"><span class="glyphicon glyphicon-fast-backward" aria-hidden="true"></span></button>
|
||||
<button id="dbg_slower" class="btn" title="Slower"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></button>
|
||||
<span class="label"><span id="fps_label">60.00</span> fps</span>
|
||||
<button id="dbg_faster" class="btn" title="Faster"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
|
||||
<button id="dbg_fastest" class="btn" title="Faster"><span class="glyphicon glyphicon-fast-forward" aria-hidden="true"></span></button>
|
||||
</span>
|
||||
<span id="verilog_bar" style="display:none">
|
||||
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
||||
</span>
|
||||
|
||||
<!-- BOOKS menu -->
|
||||
<span class="dropdown pull-right">
|
||||
<a class="btn dropdown-toggle hidden-xs hiddem-sm toolbarMenuButton" id="booksMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-book" aria-hidden="true"></span>
|
||||
Books <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="booksMenuButton">
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-vcs" target="_book_a2600" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=pzp-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B01N4DSRIZ&linkId=04d39e274c06e6c93b93d20a9a977111">
|
||||
<img src="images/book_a2600.png"/>
|
||||
<span class="book-title">Making Games For The Atari 2600</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-arcade" target="_book_arcade" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2&tag=pzp-20&linkId=b27709c022d2ebe639e90316d9f4fd5b">
|
||||
<img src="images/book_arcade.png"/>
|
||||
<span class="book-title">Making 8-bit Arcade Games in C</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-verilog" target="_book_verilog" href="https://www.amazon.com/gp/product/1728619440/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1728619440&linkCode=as2&tag=pzp-20&linkId=7237a25861cb6b49a4128ba53d84c3e2">
|
||||
<img src="images/book_verilog.png"/>
|
||||
<span class="book-title">Designing Video Game Hardware in Verilog</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-nes" target="_book_nes" href="https://www.amazon.com/gp/product/1075952727/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1075952727&linkCode=as2&tag=pzp-20&linkId=633176e8b36fea7f927020e2c322d80a">
|
||||
<img src="images/book_nes.png"/>
|
||||
<span class="book-title">Making Games For The NES</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<!-- 8bitworkshop logo -->
|
||||
<span class="logo-gradient pull-right" style="margin-left:auto" onclick="window.open('https://8bitworkshop.com/','_8bitws');">8bitworkshop</span>
|
||||
</div><!-- controls_dynamic -->
|
||||
</div><!-- controls_top -->
|
||||
|
||||
<div id="notebook">
|
||||
<div id="sidebar">
|
||||
<ul id="windowMenuList">
|
||||
</ul>
|
||||
</div>
|
||||
<div id="workspace">
|
||||
</div>
|
||||
<div class="emulator disable-select" id="emulator">
|
||||
<!-- replay slider -->
|
||||
<div id="replaydiv" class="replaydiv" style="display:none;color:#ccc;text-align:left">
|
||||
<div style="display:grid; grid-template-columns: 3em 3em auto 3em; grid-gap: 1em">
|
||||
<button id="replay_back" class="btn" title="Back one frame"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></button>
|
||||
<div>
|
||||
Frame<br>
|
||||
<span id="replay_frame" style="width:3em">-</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="0" value="0" class="slider" id="replayslider">
|
||||
<button id="replay_fwd" class="btn" title="Ahead one frame"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
|
||||
|
||||
<button id="clock_back" class="btn" title="Back one step"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></button>
|
||||
<div>
|
||||
Step<br>
|
||||
<span id="replay_clock" style="width:3em">-</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="0" value="0" class="slider" id="clockslider">
|
||||
<button id="clock_fwd" class="btn" title="Forward one step"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- emulator video -->
|
||||
<div id="emuscreen">
|
||||
</div>
|
||||
<!-- for Javatari only -->
|
||||
<div id="javatari-div" style="float:center;margin:10px;display:none">
|
||||
<div id="javatari-screen" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
|
||||
<div id="javatari-console-panel" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
|
||||
</div>
|
||||
<!-- control instructions -->
|
||||
<div class="emucontrols-vcs emucontrols-c64 text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button</span>
|
||||
</div>
|
||||
<div class="emucontrols-nes emucontrols-atari7800 text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joypad</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button A</span>
|
||||
<span class="control-def"><span class="control-key small">Shift</span> Button B</span>
|
||||
<span class="control-def"><span class="control-key small">\</span> Select</span>
|
||||
<span class="control-def"><span class="control-key small">Enter</span> Start</span>
|
||||
</div>
|
||||
<div class="emucontrols-msx emucontrols-coleco emucontrols-sms text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joypad</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button A</span>
|
||||
<span class="control-def"><span class="control-key small">Shift</span> Button B</span>
|
||||
</div>
|
||||
<div class="emucontrols-vicdual emucontrols-galaxian emucontrols-vector text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button 1</span>
|
||||
<span class="control-def"><span class="control-key small">Shift</span> Button 2</span>
|
||||
<span class="control-def"><span class="control-key">\</span> Coin</span>
|
||||
<span class="control-def"><span class="control-key small">Enter</span> Start</span>
|
||||
</div>
|
||||
<div class="emucontrols-mw8080bw text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">← →</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Fire</span>
|
||||
</div>
|
||||
<div class="emucontrols-williams text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">A W S D</span> Move</span>
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Fire</span>
|
||||
<span class="control-def"><span class="control-key">\</span> Coin</span>
|
||||
<span class="control-def"><span class="control-key small">Enter</span> Start</span>
|
||||
<span class="control-def"><span class="control-key small">6 7 8 9</span> Extra</span>
|
||||
</div>
|
||||
<div class="emucontrols-astrocade text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Trigger</span>
|
||||
<span class="control-def"><span class="control-key small">Mouse X</span> Knob</span>
|
||||
<span class="control-def"><span class="control-key small" style="display:inline-block;font-family:monospace">
|
||||
U I O P<br>
|
||||
J K L /<br>
|
||||
7 8 9 X<br>
|
||||
4 5 6 -<br>
|
||||
1 2 3 ,<br>
|
||||
\ 0 . =</span> Keypad</span>
|
||||
</div>
|
||||
<div class="emucontrols-vectrex text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key">Z X C V</span> Buttons</span>
|
||||
</div>
|
||||
<div class="emucontrols-atari8 text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key">Z</span> Button 1</span>
|
||||
<span class="control-def"><span class="control-key">X</span> Button 2</span>
|
||||
<span class="control-def"><span class="control-key">1</span> Start</span>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div id="emuoverlay" class="emuoverlay" style="display:none">
|
||||
</div>
|
||||
</div>
|
||||
<div id="mem_info" class="mem_info" style="display:none">
|
||||
</div>
|
||||
<div id="error_alert" class="alert alert-danger alert-dismissable" style="position:absolute;right:0;top:0;display:none">
|
||||
<button type="button" class="close" onclick="$('.alert').hide()" aria-hidden="true">×</button>
|
||||
<div id="error_alert_msg"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="twitbtn">
|
||||
<a target="_new" href="https://twitter.com/8bitworkshop" class="twitter-follow-button" data-show-count="false">Follow @8bitworkshop</a>-->
|
||||
<!--<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>-->
|
||||
<!--</div>-->
|
||||
<div id="pleaseWaitModal" class="modal fade">
|
||||
<div class="modal-dialog modal-md" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
Please wait...
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-striped active" role="progressbar" id="pleaseWaitProgressBar">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="videoPreviewModal" class="modal fade">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Video Preview - Right-click to save</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<img id="videoPreviewImage">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="embedLinkModal" class="modal fade">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Share Playable Link</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Here's a direct link to a playable version of your game:</p>
|
||||
<textarea rows="4" cols="80" id="embedLinkTextarea" class="cliptext"></textarea>
|
||||
<button type="button" class="btn btn-primary" data-clipboard-target="#embedLinkTextarea">Copy Direct Link</button>
|
||||
<p>You can also embed it into an IFRAME:</p>
|
||||
<textarea rows="4" cols="80" id="embedIframeTextarea" class="cliptext"></textarea>
|
||||
<button type="button" class="btn btn-primary" data-clipboard-target="#embedIframeTextarea">Copy IFRAME Tag</button>
|
||||
<p id="embedAdviceWarnIE">Note: These links may be too long for IE/Edge browsers.</p>
|
||||
<p id="embedAdviceWarnAll">Note: These links may be too long for some browsers.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
Choose one (or none) then
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="debugExprModal" class="modal fade">
|
||||
<div class="modal-dialog modal-md" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Break Expression</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Enter a break expression:</p>
|
||||
<p><input id="debugExprInput" size="60"></input></p>
|
||||
<p>Examples:</p>
|
||||
<pre id="debugExprExamples"></pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" id="debugExprSubmit">Debug</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="jquery/jquery.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
|
||||
<script src="bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="bootstrap/js/bootbox.all.min.js"></script>
|
||||
<link rel="stylesheet" href="lib/bootstrap-tourist.css">
|
||||
|
||||
<script src="src/codemirror/codemirror.js"></script>
|
||||
<script src="codemirror/mode/clike/clike.js"></script>
|
||||
<script src="codemirror/mode/z80/z80.js"></script>
|
||||
<script src="codemirror/mode/verilog/verilog.js"></script>
|
||||
<script src="codemirror/mode/markdown/markdown.js"></script>
|
||||
<script src="codemirror/mode/javascript/javascript.js"></script>
|
||||
<script src="codemirror/mode/gas/gas.js"></script>
|
||||
<script src="src/codemirror/6502.js"></script>
|
||||
<script src="src/codemirror/bataribasic.js"></script>
|
||||
<script src="src/codemirror/inform6.js"></script>
|
||||
<script src="src/codemirror/fastbasic.js"></script>
|
||||
<script src="src/codemirror/basic.js"></script>
|
||||
<script src="src/codemirror/wiz.js"></script>
|
||||
<script src="src/codemirror/vasm.js"></script>
|
||||
<link rel="stylesheet" href="css/codemirror.css">
|
||||
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
||||
<script src="codemirror/addon/search/search.js"></script>
|
||||
<script src="codemirror/addon/search/searchcursor.js"></script>
|
||||
<script src="codemirror/addon/search/jump-to-line.js"></script>
|
||||
<script src="codemirror/addon/dialog/dialog.js"></script>
|
||||
<script src="codemirror/addon/selection/active-line.js"></script>
|
||||
<link rel="stylesheet" href="codemirror/addon/dialog/dialog.css">
|
||||
|
||||
<script src="tss/js/tss/PsgDeviceChannel.js"></script>
|
||||
<script src="tss/js/tss/MasterChannel.js"></script>
|
||||
<script src="tss/js/tss/AudioLooper.js"></script>
|
||||
<script src="tss/js/Log.js"></script>
|
||||
|
||||
<!-- main IDE module -->
|
||||
<script src="gen/ui.js" type="module"></script>
|
||||
|
||||
<script>
|
||||
// submenus open on click + hover
|
||||
$( ".dropdown-submenu" ).click(function(event) {
|
||||
event.stopPropagation();
|
||||
$(this).parent().siblings().removeClass('open');
|
||||
$(this).parent().toggleClass('open');
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
255
electron.js
255
electron.js
|
@ -1,255 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const { app, dialog, Menu, BrowserWindow } = require('electron')
|
||||
const _path = require('path')
|
||||
const isMac = process.platform === 'darwin'
|
||||
|
||||
const homeDirectory = require('os').homedir();
|
||||
const wsroot = process.env.HOME_8BITWORKSHOP || _path.join(homeDirectory, '8bitworkshop');
|
||||
|
||||
// call updater
|
||||
require('update-electron-app')()
|
||||
|
||||
// init sentry
|
||||
require('@sentry/electron').init({ dsn: "https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925" });
|
||||
|
||||
function openURL(url) {
|
||||
return async () => {
|
||||
const { shell } = require('electron')
|
||||
await shell.openExternal(url);
|
||||
}
|
||||
}
|
||||
|
||||
function createWindow (platform, repo, mainfile) {
|
||||
// Create the browser window.
|
||||
const win = new BrowserWindow({
|
||||
width: 1024,
|
||||
height: 768,
|
||||
backgroundColor: '#fff',
|
||||
webPreferences: {
|
||||
preload: _path.join(__dirname, './electron-preload.js'),
|
||||
nodeIntegration: false,
|
||||
enableRemoteModule: false,
|
||||
contextIsolation: false,
|
||||
sandbox: false,
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
var qs = 'electron=1&';
|
||||
if (platform != null) {
|
||||
qs += 'platform=' + platform + '&';
|
||||
}
|
||||
if (mainfile != null) {
|
||||
qs += 'file=' + mainfile + '&'
|
||||
}
|
||||
qs += 'repo=' + (repo || '/');
|
||||
win.loadFile('electron.html', {
|
||||
search: qs
|
||||
});
|
||||
|
||||
// Maximize
|
||||
win.maximize();
|
||||
return win;
|
||||
}
|
||||
|
||||
// TODO: doesn't work if browser window reloads itself
|
||||
function reloadCurrentWindow() {
|
||||
var wnd = BrowserWindow.getFocusedWindow();
|
||||
wnd.reload();
|
||||
}
|
||||
|
||||
function openWorkspaceWindow(mainfilepath) {
|
||||
var relpath = _path.relative(wsroot, mainfilepath);
|
||||
if (relpath.startsWith('.')) {
|
||||
dialog.showErrorBox('Error', `Your workspace directory must be directly under "${wsroot}/<platform>/"`);
|
||||
return;
|
||||
}
|
||||
var toks = relpath.split(_path.sep);
|
||||
if (toks.length < 3) {
|
||||
dialog.showErrorBox('Error', `You must create a directory for your project, e.g. "${toks[0]||'<platform>'}/myproject/"`);
|
||||
return;
|
||||
}
|
||||
if (toks.length > 3) {
|
||||
dialog.showErrorBox('Error', `Your main file must be directly under "${wsroot}/<platform>/<project>/"`);
|
||||
return;
|
||||
}
|
||||
var wnd = BrowserWindow.getFocusedWindow();
|
||||
if (wnd) wnd.close();
|
||||
createWindow(toks[0], toks[0] + '/' + toks[1], toks[2]);
|
||||
}
|
||||
|
||||
function openWorkspaceDialog() {
|
||||
dialog.showOpenDialog({
|
||||
title: "Open Project",
|
||||
defaultPath: wsroot,
|
||||
properties: ['openFile', 'promptToCreate'],
|
||||
message: "Choose the main source file in your project directory (i.e. ~/8bitworkshop/c64/myproject/main.c)",
|
||||
}).then((rtn) => {
|
||||
if (!rtn.canceled && rtn.filePaths && rtn.filePaths.length > 0) {
|
||||
var path = rtn.filePaths[0];
|
||||
if (path) {
|
||||
openWorkspaceWindow(path);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
function buildMenu() {
|
||||
|
||||
const template = [
|
||||
// { role: 'appMenu' }
|
||||
...(isMac ? [{
|
||||
label: app.name,
|
||||
submenu: [
|
||||
{ role: 'about' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'services' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'hide' },
|
||||
{ role: 'hideothers' },
|
||||
{ role: 'unhide' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'quit' }
|
||||
]
|
||||
}] : []),
|
||||
// { role: 'fileMenu' }
|
||||
{
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Open Workspace...',
|
||||
click: openWorkspaceDialog,
|
||||
accelerator: 'CmdOrCtrl+O',
|
||||
},
|
||||
// When a file is requested from the recent documents menu, the open-file event of app module will be emitted for it.
|
||||
{
|
||||
"label":"Open Recent",
|
||||
"role":"recentdocuments",
|
||||
"submenu":[
|
||||
{
|
||||
"label":"Clear Recent",
|
||||
"role":"clearrecentdocuments"
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
isMac ? { role: 'close' } : { role: 'quit' }
|
||||
]
|
||||
},
|
||||
// { role: 'editMenu' }
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{ role: 'undo' },
|
||||
{ role: 'redo' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'cut' },
|
||||
{ role: 'copy' },
|
||||
{ role: 'paste' },
|
||||
...(isMac ? [
|
||||
{ role: 'pasteAndMatchStyle' },
|
||||
{ role: 'delete' },
|
||||
{ role: 'selectAll' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Speech',
|
||||
submenu: [
|
||||
{ role: 'startspeaking' },
|
||||
{ role: 'stopspeaking' }
|
||||
]
|
||||
}
|
||||
] : [
|
||||
{ role: 'delete' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'selectAll' }
|
||||
])
|
||||
]
|
||||
},
|
||||
// { role: 'viewMenu' }
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload Window',
|
||||
click: reloadCurrentWindow
|
||||
},
|
||||
{ role: 'toggledevtools' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'resetzoom' },
|
||||
{ role: 'zoomin' },
|
||||
{ role: 'zoomout' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'togglefullscreen' }
|
||||
]
|
||||
},
|
||||
// { role: 'windowMenu' }
|
||||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{ role: 'minimize' },
|
||||
{ role: 'zoom' },
|
||||
...(isMac ? [
|
||||
{ type: 'separator' },
|
||||
{ role: 'front' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'window' }
|
||||
] : [
|
||||
{ role: 'close' }
|
||||
])
|
||||
]
|
||||
},
|
||||
{
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'IDE Help',
|
||||
click: openURL('https://8bitworkshop.com/docs/docs/ide.html')
|
||||
},
|
||||
{
|
||||
label: 'Latest News',
|
||||
click: openURL('https://8bitworkshop.com/docs/blog.html')
|
||||
},
|
||||
{
|
||||
label: 'Report an Issue',
|
||||
click: openURL('https://github.com/sehugg/8bitworkshop/issues/new')
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Follow @8bitworkshop on Twitter',
|
||||
click: openURL('https://twitter.com/8bitworkshop')
|
||||
},
|
||||
{
|
||||
label: 'Become a Patreon',
|
||||
click: openURL('https://www.patreon.com/8bitworkshop')
|
||||
},
|
||||
{
|
||||
label: 'Buy 8bitworkshop Books',
|
||||
click: openURL('https://www.amazon.com/s?k=8bitworkshop&i=stripbooks&dc&qid=1598884483&tag=pzp-20')
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const menu = Menu.buildFromTemplate(template)
|
||||
Menu.setApplicationMenu(menu)
|
||||
}
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', () => {
|
||||
app.quit()
|
||||
})
|
||||
|
||||
app.on('open-file', (event, path) => {
|
||||
openWorkspaceWindow(path);
|
||||
})
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(buildMenu).then(createWindow)
|
||||
|
82
index.html
82
index.html
|
@ -23,16 +23,6 @@ body {
|
|||
</style>
|
||||
<link rel="stylesheet" href="css/ui.css">
|
||||
|
||||
<!-- google analytics -->
|
||||
<script>
|
||||
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
||||
if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
ga('create', 'UA-54497476-9', 'auto');
|
||||
ga('set', 'anonymizeIp', true);
|
||||
}
|
||||
</script>
|
||||
<script async src='https://www.google-analytics.com/analytics.js'></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
@ -89,6 +79,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<li><a class="dropdown-item" href="#" id="item_download_rom">Download ROM Image</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_download_zip">Download Project as ZIP</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_download_allzip">Download All Changes as ZIP</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_download_sym">Download Debug Symbols</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
|
@ -121,14 +112,19 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
</ul>
|
||||
</li>
|
||||
<hr>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Help</a>
|
||||
<ul class="dropdown-menu" id="help_menu">
|
||||
<li><a class="dropdown-item" target="_8bws_help" href="https://8bitworkshop.com/docs/docs/ide.html">IDE Help</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">About</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" target="_8bws_about" href="https://8bitworkshop.com/">Website</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_about" href="https://twitter.com/8bitworkshop">Twitter</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_about" href="https://8bitworkshop.com/docs/blog.html">Latest News</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_about" href="https://github.com/sehugg/8bitworkshop/issues/new">Report an Issue</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_about" href="https://8bitworkshop.com/docs/docs/ide.html">User Manual</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_help" href="https://8bitworkshop.com/">Website</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_help" href="https://oldbytes.space/@8bitworkshop">Mastodon</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_help" href="https://8bitworkshop.com/docs/blog.html">Latest News</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_help" href="https://github.com/sehugg/8bitworkshop/issues/new">Report an Issue</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--
|
||||
|
@ -153,7 +149,10 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<li><a class="dropdown-item" href="?platform=coleco">ColecoVision</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=sms-sg1000-libcv">Sega SG-1000</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=sms-sms-libcv">Sega Master System</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=sms-gg-libcv">Sega Game Gear</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=atari8-5200">Atari 5200</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=atari7800">Atari 7800</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=pce">PC Engine</a></li>
|
||||
<!--
|
||||
<li><a class="dropdown-item" href="?platform=vectrex">Vectrex</a></li>
|
||||
-->
|
||||
|
@ -163,11 +162,11 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<a tabindex="-1" href="#">Computers</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=c64">Commodore 64</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=atari8-800">Atari 800</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=msx">MSX (BIOS)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=msx-libcv">MSX (libCV)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=apple2">Apple ][+</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=zx">ZX Spectrum</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=cpc.6128">Amstrad CPC6128</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -195,19 +194,21 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=basic">BASIC</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=zmachine">Z-Machine</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=markdown">Markdown Text Editor</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">MAME/Other</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="?platform=atari8-800xl.mame">Atari 800XL (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=atari8-800.xlmame">Atari 800XL (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=atari8-5200.mame">Atari 5200 (MAME)</a></li>
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="?platform=vcs.stellerator">Atari 2600 (Stellerator)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=vcs.mame">Atari 2600 (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=coleco.mame">ColecoVision (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=nes.mame">NES (MAME)</a></li>
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="?platform=williams">Williams (6809)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -239,25 +240,25 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="booksMenuButton">
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-vcs" target="_book_a2600" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=pzp-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=B01N4DSRIZ&linkId=04d39e274c06e6c93b93d20a9a977111">
|
||||
<a class="dropdown-item dropdown-link book-vcs" target="_book_a2600" href="https://www.amazon.com/gp/product/1541021304/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&camp=1789&creative=9325&linkCode=as2&creativeASIN=B01N4DSRIZ">
|
||||
<img src="images/book_a2600.png"/>
|
||||
<span class="book-title">Making Games For The Atari 2600</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-arcade" target="_book_arcade" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2&tag=pzp-20&linkId=b27709c022d2ebe639e90316d9f4fd5b">
|
||||
<a class="dropdown-item dropdown-link book-arcade" target="_book_arcade" href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759&linkCode=as2">
|
||||
<img src="images/book_arcade.png"/>
|
||||
<span class="book-title">Making 8-bit Arcade Games in C</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-verilog" target="_book_verilog" href="https://www.amazon.com/gp/product/1728619440/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1728619440&linkCode=as2&tag=pzp-20&linkId=7237a25861cb6b49a4128ba53d84c3e2">
|
||||
<a class="dropdown-item dropdown-link book-verilog" target="_book_verilog" href="https://www.amazon.com/gp/product/1728619440/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1728619440&linkCode=as2">
|
||||
<img src="images/book_verilog.png"/>
|
||||
<span class="book-title">Designing Video Game Hardware in Verilog</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item dropdown-link book-nes" target="_book_nes" href="https://www.amazon.com/gp/product/1075952727/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1075952727&linkCode=as2&tag=pzp-20&linkId=633176e8b36fea7f927020e2c322d80a">
|
||||
<a class="dropdown-item dropdown-link book-nes" target="_book_nes" href="https://www.amazon.com/gp/product/1075952727/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1075952727&linkCode=as2">
|
||||
<img src="images/book_nes.png"/>
|
||||
<span class="book-title">Making Games For The NES</span>
|
||||
</a>
|
||||
|
@ -313,18 +314,24 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button</span>
|
||||
</div>
|
||||
<div class="emucontrols-nes emucontrols-atari7800 text-center small control-insns" style="display:none">
|
||||
<div class="emucontrols-nes emucontrols-atari7800 emucontrols-pce text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joypad</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button A</span>
|
||||
<span class="control-def"><span class="control-key small">Shift</span> Button B</span>
|
||||
<span class="control-def"><span class="control-key small">\</span> Select</span>
|
||||
<span class="control-def"><span class="control-key small">Enter</span> Start</span>
|
||||
</div>
|
||||
<div class="emucontrols-msx emucontrols-coleco emucontrols-sms text-center small control-insns" style="display:none">
|
||||
<div class="emucontrols-msx emucontrols-coleco text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joypad</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button A</span>
|
||||
<span class="control-def"><span class="control-key small">Shift</span> Button B</span>
|
||||
</div>
|
||||
<div class="emucontrols-sms text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joypad</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button A</span>
|
||||
<span class="control-def"><span class="control-key small">Shift</span> Button B</span>
|
||||
<span class="control-def"><span class="control-key small">Enter</span> Start</span>
|
||||
</div>
|
||||
<div class="emucontrols-vicdual emucontrols-galaxian emucontrols-vector text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key small">Space</span> Button 1</span>
|
||||
|
@ -361,15 +368,18 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
</div>
|
||||
<div class="emucontrols-atari8 text-center small control-insns" style="display:none">
|
||||
<span class="control-def"><span class="control-key">←↑↓→</span> Joystick</span>
|
||||
<span class="control-def"><span class="control-key">Z</span> Button 1</span>
|
||||
<span class="control-def"><span class="control-key">X</span> Button 2</span>
|
||||
<span class="control-def"><span class="control-key">1</span> Start</span>
|
||||
<span class="control-def"><span class="control-key">Shift</span> Button</span>
|
||||
<span class="control-def"><span class="control-key">F1</span> Start</span>
|
||||
<span class="control-def"><span class="control-key">F2</span> Select</span>
|
||||
<span class="control-def"><span class="control-key">F3</span> Option</span>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div id="emuoverlay" class="emuoverlay" style="display:none">
|
||||
</div>
|
||||
</div>
|
||||
<div id="mem_info" class="mem_info" style="display:none">
|
||||
<div><button type="button" class="close" onclick="$('.mem_info').hide()" aria-hidden="true">×</button></div>
|
||||
<div id="mem_info_msg" class="mem_info_msg"></div>
|
||||
</div>
|
||||
<div id="error_alert" class="alert alert-danger alert-dismissable" style="position:absolute;right:0;top:0;display:none">
|
||||
<button type="button" class="close" onclick="$('.alert').hide()" aria-hidden="true">×</button>
|
||||
|
@ -540,6 +550,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<script src="src/codemirror/basic.js"></script>
|
||||
<script src="src/codemirror/wiz.js"></script>
|
||||
<script src="src/codemirror/vasm.js"></script>
|
||||
<script src="src/codemirror/ecs.js"></script>
|
||||
<link rel="stylesheet" href="css/codemirror.css">
|
||||
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
||||
<script src="codemirror/addon/search/search.js"></script>
|
||||
|
@ -567,26 +578,19 @@ $( ".dropdown-submenu" ).click(function(event) {
|
|||
</script>
|
||||
|
||||
<!-- Sentry error reporting -->
|
||||
<script
|
||||
src="https://browser.sentry-cdn.com/6.4.1/bundle.min.js"
|
||||
integrity="sha384-THoc7rflwZFKTdZNgv6jLFFDn299Uv3t1SW5B4yGLvLiCRTYP9ys6vXZcMl95TQF"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script src='https://js.sentry-cdn.com/1fdd10e76a524c6e8d1e0a47f215fb28.min.js' crossorigin="anonymous"></script>
|
||||
<script>
|
||||
if (window.Sentry) Sentry.onLoad(function() {
|
||||
Sentry.init({
|
||||
dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||
beforeBreadcrumb(breadcrumb, hint) {
|
||||
if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||
if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||
}
|
||||
return breadcrumb;
|
||||
},
|
||||
sampleRate: window.location.host.endsWith('8bitworkshop.com') ? 0.5 : 0.05,
|
||||
beforeSend(event, hint) {
|
||||
const error = hint.originalException;
|
||||
if (error && error.hasOwnProperty('$loc')) return null; // ignore EmuHalt
|
||||
if (error && error.squelchError) return null; // ignore EmuHalt
|
||||
return event;
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9d124f087e1f0c7f74f9244b9679cc62e71fa524
|
||||
Subproject commit 113cd5741e5c414bbbe47ef8be7a896652d48f64
|
4
jquery/jquery.min.js
vendored
4
jquery/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
2
lib/stellerator/stellerator-embedded.min.js
vendored
2
lib/stellerator/stellerator-embedded.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
--- index.html 2021-08-06 18:05:46.000000000 -0500
|
||||
+++ electron.html 2021-08-09 12:01:41.000000000 -0500
|
||||
--- index.html 2022-01-22 20:17:39.000000000 -0600
|
||||
+++ electron.html 2022-01-24 15:54:13.000000000 -0600
|
||||
@@ -3,18 +3,7 @@
|
||||
|
||||
<head>
|
||||
|
@ -92,7 +92,7 @@
|
|||
</ul>
|
||||
</span>
|
||||
|
||||
@@ -277,24 +214,21 @@
|
||||
@@ -279,24 +216,21 @@
|
||||
<div class="emulator disable-select" id="emulator">
|
||||
<!-- replay slider -->
|
||||
<div id="replaydiv" class="replaydiv" style="display:none;color:#ccc;text-align:left">
|
||||
|
@ -119,7 +119,7 @@
|
|||
<button id="clock_fwd" class="btn" title="Forward one step"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -449,73 +383,6 @@
|
||||
@@ -451,73 +385,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -193,32 +193,3 @@
|
|||
|
||||
<script src="jquery/jquery.min.js"></script>
|
||||
|
||||
@@ -564,28 +431,5 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
-<!-- Sentry error reporting -->
|
||||
-<script
|
||||
- src="https://browser.sentry-cdn.com/6.4.1/bundle.min.js"
|
||||
- integrity="sha384-THoc7rflwZFKTdZNgv6jLFFDn299Uv3t1SW5B4yGLvLiCRTYP9ys6vXZcMl95TQF"
|
||||
- crossorigin="anonymous"
|
||||
-></script>
|
||||
-<script>
|
||||
-Sentry.init({
|
||||
- dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||
- beforeBreadcrumb(breadcrumb, hint) {
|
||||
- if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||
- if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||
- }
|
||||
- return breadcrumb;
|
||||
- },
|
||||
- beforeSend(event, hint) {
|
||||
- const error = hint.originalException;
|
||||
- if (error instanceof EmuHalt) return null; // ignore EmuHalt
|
||||
- return event;
|
||||
- },
|
||||
-});
|
||||
-</script>
|
||||
-
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
test_settings: {
|
||||
default: {
|
||||
launch_url: 'https://8bitworkshop.com',
|
||||
launch_url: 'https://sehugg.github.io/8bitworkshop/'
|
||||
},
|
||||
|
||||
safari: {
|
||||
|
|
18630
package-lock.json
generated
18630
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
63
package.json
63
package.json
|
@ -1,93 +1,86 @@
|
|||
{
|
||||
"name": "8bitworkshop",
|
||||
"version": "3.9.0",
|
||||
"version": "3.11.0",
|
||||
"author": "Steven Hugg",
|
||||
"category": "Development",
|
||||
"description": "Desktop version of 8bitworkshop.com retro programming IDE",
|
||||
"description": "8bitworkshop.com retro programming IDE",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sehugg/8bitworkshop.git"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@types/chroma-js": "^2.1.3",
|
||||
"@types/dompurify": "^2.3.4",
|
||||
"@types/emscripten": "^1.39.5",
|
||||
"@wasmer/wasi": "^0.12.0",
|
||||
"@wasmer/wasmfs": "^0.12.0",
|
||||
"atob": "^2.1.x",
|
||||
"binaryen": "^101.0.0",
|
||||
"chroma-js": "^2.1.2",
|
||||
"btoa": "^1.2.x",
|
||||
"clipboard": "^2.0.6",
|
||||
"dompurify": "^2.4.0",
|
||||
"error-stack-parser": "^2.0.6",
|
||||
"fast-png": "^5.0.4",
|
||||
"file-saver": "^2.0.5",
|
||||
"jquery": "^3.6.0",
|
||||
"jquery": "^3.6.3",
|
||||
"jszip": "^3.7.0",
|
||||
"localforage": "^1.9.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"octokat": "^0.10.0",
|
||||
"preact": "^10.5.14",
|
||||
"split.js": "^1.6.2",
|
||||
"yufka": "^2.0.1"
|
||||
"split.js": "^1.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bootbox": "^5.1.3",
|
||||
"@types/bootstrap": "^3.4.0",
|
||||
"@types/expect": "^24.3.0",
|
||||
"@types/file-saver": "^2.0.3",
|
||||
"@types/jquery": "^3.5.5",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/node": "^14.14.20",
|
||||
"atob": "^2.1.x",
|
||||
"bootstrap": "^3.4.1",
|
||||
"bootstrap-tourist": "^0.2.1",
|
||||
"btoa": "^1.2.x",
|
||||
"command-exists": "^1.2.9",
|
||||
"esbuild": "^0.12.16",
|
||||
"jsdom": "^12.2.0",
|
||||
"cors": "^2.8.5",
|
||||
"esbuild": "^0.12.29",
|
||||
"express": "^4.18.2",
|
||||
"fast-png": "^5.0.4",
|
||||
"jsdom": "^21.1.0",
|
||||
"lzg": "^1.0.x",
|
||||
"mocha": "^7.2.0",
|
||||
"mocha": "^9.2.0",
|
||||
"mocha-simple-html-reporter": "^2.0.0",
|
||||
"typescript": "^4.3.4",
|
||||
"typescript": "^5.2.2",
|
||||
"typescript-formatter": "^7.2.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@sentry/electron": "^2.5.1",
|
||||
"chokidar": "^3.5.0",
|
||||
"chromedriver": "^92.0.0",
|
||||
"electron": "^9.4.0",
|
||||
"electron-builder": "^22.11.7",
|
||||
"electron-packager": "^15.2.0",
|
||||
"chromedriver": "*",
|
||||
"heapdump": "^0.3.15",
|
||||
"jsfuzz": "^1.0.14",
|
||||
"nightwatch": "^1.6.4",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rgbquant": "^1.1.2",
|
||||
"typedoc": "^0.21.0",
|
||||
"update-electron-app": "^2.0.1"
|
||||
"nightwatch": "*"
|
||||
},
|
||||
"overrides": {
|
||||
"fetch-vcr": {
|
||||
"node-fetch": "2.6.7"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "make prepare",
|
||||
"test": "npm run test-node",
|
||||
"tsbuild": "tsc --build tsconfig.json",
|
||||
"esbuild": "npm run esbuild-worker && npm run esbuild-ui",
|
||||
"esbuild": "npm run esbuild-worker && npm run esbuild-ui && npm run esbuild-server",
|
||||
"esbuild-clean": "rm -f ./gen/*.*",
|
||||
"esbuild-server": "esbuild src/worker/server/server.ts --platform=node --bundle --sourcemap --target=es2020 --outfile=./gen/server/server.js",
|
||||
"esbuild-worker": "esbuild src/worker/workermain.ts --bundle --sourcemap --target=es2017 --outfile=./gen/worker/bundle.js",
|
||||
"esbuild-ui": "esbuild src/ide/ui.ts src/ide/embedui.ts --splitting --format=esm --bundle --minify --sourcemap --target=es2017 --outdir=./gen/ --external:path --external:fs",
|
||||
"server": "npm run esbuild-server && rm -fr ./server-root/sessions && node gen/server/server.js",
|
||||
"test-one": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000",
|
||||
"test-node": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli",
|
||||
"test-profile": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 --prof test/cli",
|
||||
"test-node": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli gen/test",
|
||||
"test-profile": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 --prof test/cli gen/test",
|
||||
"test-worker": "NODE_PATH=$(pwd) mocha --timeout 60000 test/cli/testworker.js",
|
||||
"test-platforms": "NODE_PATH=$(pwd) mocha --timeout 60000 test/cli/testplatforms.js",
|
||||
"test-verilog": "NODE_PATH=$(pwd) mocha --timeout 60000 --reporter mocha-simple-html-reporter --reporter-options output=test/output/verilog.html test/verilog/testverilog.js",
|
||||
"test-web-quick": "nightwatch -e chrome test/web/testembed.js",
|
||||
"test-web-all": "nightwatch -e chrome test/web",
|
||||
"start": "electron .",
|
||||
"fuzzbasic": "jsfuzz gen/common/basic/fuzz.js ~/basic/corpus/ --versifier false",
|
||||
"fuzzhdl": "jsfuzz -r binaryen gen/common/hdl/fuzz.js ~/verilator/corpus/ --versifier false",
|
||||
"machine": "node gen/tools/runmachine.js",
|
||||
"mkdoc": "typedoc --out web/jsdoc src/common/"
|
||||
},
|
||||
"main": "electron.js",
|
||||
"keywords": [
|
||||
"8bit",
|
||||
"ide",
|
||||
|
@ -102,7 +95,7 @@
|
|||
"build": {
|
||||
"appId": "com.8bitworkshop.ide",
|
||||
"icon": "meta/icons/8bitworkshop-icon-1024.png",
|
||||
"copyright": "Copyright (c) 2021 Puzzling Plans LLC",
|
||||
"copyright": "Copyright (c) 2023 Puzzling Plans LLC",
|
||||
"linux": {
|
||||
"category": "Development"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
|
||||
// reserve space for the HGR1 screen buffer
|
||||
#define CFGFILE apple2-hgr.cfg
|
||||
#pragma data-name(push,"HGR")
|
||||
#pragma data-name(pop)
|
||||
|
||||
/*
|
||||
* An Apple ][ port of the Cosmic Impalas game
|
||||
* described in the book
|
||||
|
|
55
presets/apple2/lz4test.c
Normal file
55
presets/apple2/lz4test.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
/*
|
||||
Test of the LZ4 decompression library
|
||||
with a hires graphics image.
|
||||
*/
|
||||
|
||||
// CC65 config, reserves space for the HGR1 screen buffer
|
||||
#define CFGFILE apple2-hgr.cfg
|
||||
|
||||
#pragma data-name(push,"HGR")
|
||||
// this segment is required, but we leave it empty
|
||||
// since we're going to decompress the image here
|
||||
#pragma data-name(pop)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
#include <apple2.h>
|
||||
#include <peekpoke.h>
|
||||
#include <lz4.h>
|
||||
|
||||
// STROBE = write any value to an I/O address
|
||||
#define STROBE(addr) __asm__ ("sta %w", addr)
|
||||
|
||||
// start address of the two hi-res graphics regions
|
||||
#define HGR1 0x2000
|
||||
#define HGR2 0x4000
|
||||
|
||||
// the LZ4 compressed data
|
||||
const unsigned char BITMAP_DATA_LZ4[] = {
|
||||
#embed "parrot-apple2.hires.lz4"
|
||||
};
|
||||
|
||||
|
||||
// clear screen and set graphics mode
|
||||
void clear_hgr1() {
|
||||
memset((char*)HGR1, 0, 0x2000); // clear page 1
|
||||
STROBE(0xc052); // turn off mixed-mode
|
||||
STROBE(0xc054); // page 1
|
||||
STROBE(0xc057); // hi-res
|
||||
STROBE(0xc050); // set graphics mode
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
// set hgr1 mode and clear
|
||||
clear_hgr1();
|
||||
// skip the header (usually 11 bytes)
|
||||
decompress_lz4(BITMAP_DATA_LZ4+11, (char*)HGR1, 0x2000);
|
||||
// wait for a key
|
||||
cgetc();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
|
||||
// reserve space for the HGR1 screen buffer
|
||||
#define CFGFILE apple2-hgr.cfg
|
||||
#pragma data-name(push,"HGR")
|
||||
#pragma data-name(pop)
|
||||
|
||||
/*
|
||||
Test of the LZG decompression library
|
||||
with a hires graphics image.
|
||||
|
@ -38,7 +44,7 @@ void clrscr() {
|
|||
int main (void)
|
||||
{
|
||||
clrscr();
|
||||
lzg_decode_vram(BITMAP_DATA_LZG, (char*)0x2000, (char*)0x4000);
|
||||
lzg_decode_vram(BITMAP_DATA_LZG, (unsigned char*)0x2000, (unsigned char*)0x4000);
|
||||
printf("\nHello! Press a key to reboot...\n");
|
||||
cgetc();
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
/* Workaround missing clock stuff */
|
||||
#ifdef __APPLE2__
|
||||
# define clock() 0
|
||||
# undef CLK_TCK
|
||||
# define CLK_TCK 1
|
||||
#endif
|
||||
|
||||
|
|
BIN
presets/apple2/parrot-apple2.hires.lz4
Normal file
BIN
presets/apple2/parrot-apple2.hires.lz4
Normal file
Binary file not shown.
|
@ -143,7 +143,7 @@ static void DoDiagram (void)
|
|||
|
||||
/* Calculate the next points */
|
||||
X = (int) (((long) (MaxX - 19) * I) / 360);
|
||||
Y = (int) (((long) Amp * -cc65_sin (I)) / 256);
|
||||
Y = (int) (((long) Amp * -_sin (I)) / 256);
|
||||
|
||||
/* Draw the line */
|
||||
tgi_lineto (XOrigin + X, YOrigin + Y);
|
||||
|
|
7
presets/arm32/serialout.c
Normal file
7
presets/arm32/serialout.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
#define SERIAL_OUT ((int*)0x4000048)
|
||||
|
||||
void putchar_(char c) {
|
||||
*SERIAL_OUT = c;
|
||||
}
|
||||
|
35
presets/arm32/sieve.c
Normal file
35
presets/arm32/sieve.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define size 8190
|
||||
#define sizepl 8191
|
||||
|
||||
//#link "serialout.c"
|
||||
|
||||
main() {
|
||||
char flags[sizepl];
|
||||
int i, prime, k, count, iter;
|
||||
printf("Running benchmark...\n");
|
||||
for (iter = 1; iter <= 10; iter ++) {
|
||||
count=0;
|
||||
for (i = 0; i <= size; i++)
|
||||
flags[i] = true;
|
||||
for (i = 0; i <= size; i++) {
|
||||
if (flags[i]) {
|
||||
prime = i + i + 3;
|
||||
k = i + prime;
|
||||
while (k <= size) {
|
||||
flags[k] = false;
|
||||
k += prime;
|
||||
}
|
||||
count = count + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("Primes: %d\n", count);
|
||||
return 0;
|
||||
}
|
||||
|
11
presets/arm32/skeleton.armtcc
Normal file
11
presets/arm32/skeleton.armtcc
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//#link "serialout.c"
|
||||
|
||||
int main() {
|
||||
int x = 2024;
|
||||
printf("Hello World! %d\n", x);
|
||||
return 0;
|
||||
}
|
25
presets/arm32/vidfill.c
Normal file
25
presets/arm32/vidfill.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
const char const str[] = "HELLO WORLD!";
|
||||
|
||||
int global = 0x1234;
|
||||
int global2 = 0x123456;
|
||||
|
||||
#define VIDBASE ((int*)0x4000080)
|
||||
|
||||
int vidbuf[160*128];
|
||||
|
||||
int main() {
|
||||
*VIDBASE = (int)vidbuf;
|
||||
global += str[0];
|
||||
global++;
|
||||
global2++;
|
||||
int c = 0xff880000;
|
||||
c += str[0];
|
||||
int* p = (int*) vidbuf;
|
||||
for (int i=0; i<160*128; i++) {
|
||||
p[i] = c++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
141
presets/atari7800/7800.h
Normal file
141
presets/atari7800/7800.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
; 7800.h
|
||||
; Version 1.0, 2019/12/13
|
||||
|
||||
; This file defines hardware registers and memory mapping for the
|
||||
; Atari 7800. It is distributed as a companion machine-specific support package
|
||||
; for the DASM compiler. Updates to this file, DASM, and associated tools are
|
||||
; available at https://github.com/dasm-assembler/dasm
|
||||
|
||||
|
||||
; ******************** 7800 Hardware Adresses ***************************
|
||||
;
|
||||
; MEMORY MAP USAGE OF THE 7800
|
||||
;
|
||||
; 00 - 1F TIA REGISTERS
|
||||
; 20 - 3F MARIA REGISTERS
|
||||
; 40 - FF RAM block 0 (zero page)
|
||||
; 100 - 11F TIA (mirror of 0000-001f)
|
||||
; 120 - 13F MARIA (mirror of 0020-003f)
|
||||
; 140 - 1FF RAM block 1 (stack)
|
||||
; 200 - 21F TIA (mirror of 0000-001f)
|
||||
; 220 - 23F MARIA (mirror of 0020-003f)
|
||||
; 240 - 27F ???
|
||||
; 280 - 2FF RIOT I/O ports and timers
|
||||
; 300 - 31F TIA (mirror of 0000-001f)
|
||||
; 320 - 33F MARIA (mirror of 0020-003f)
|
||||
; 340 - 3FF ???
|
||||
; 400 - 47F unused address space
|
||||
; 480 - 4FF RIOT RAM
|
||||
; 500 - 57F unused address space
|
||||
; 580 - 5FF RIOT RAM (mirror of 0480-04ff)
|
||||
; 600 - 17FF unused address space
|
||||
; 1800 - 203F RAM
|
||||
; 2040 - 20FF RAM block 0 (mirror of 0000-001f)
|
||||
; 2100 - 213F RAM
|
||||
; 2140 - 21FF RAM block 1 (mirror of 0140-01ff)
|
||||
; 2200 - 27FF RAM
|
||||
; 2800 - 2FFF mirror of 1800-27ff
|
||||
; 3000 - 3FFF unused address space
|
||||
; 4000 - FF7F potential cartridge address space
|
||||
; FF80 - FFF9 RESERVED FOR ENCRYPTION
|
||||
; FFFA - FFFF 6502 VECTORS
|
||||
|
||||
|
||||
;****** 00-1F ********* TIA REGISTERS ******************
|
||||
|
||||
INPTCTRL = $01 ;Input control. In same address space as TIA. write-only
|
||||
VBLANK = $01 ;VBLANK. D7=1:dump paddle caps to ground. write-only
|
||||
INPT0 = $08 ;Paddle Control Input 0 read-only
|
||||
INPT1 = $09 ;Paddle Control Input 1 read-only
|
||||
INPT2 = $0A ;Paddle Control Input 2 read-only
|
||||
INPT3 = $0B ;Paddle Control Input 3 read-only
|
||||
|
||||
; ** some common alternate names for INPT0/1/2/3
|
||||
INPT4B = $08 ;Joystick 0 Fire 1 read-only
|
||||
INPT4A = $09 ;Joystick 0 Fire 1 read-only
|
||||
INPT5B = $0A ;Joystick 1 Fire 0 read-only
|
||||
INPT5A = $0B ;Joystick 1 Fire 1 read-only
|
||||
INPT4R = $08 ;Joystick 0 Fire 1 read-only
|
||||
INPT4L = $09 ;Joystick 0 Fire 1 read-only
|
||||
INPT5R = $0A ;Joystick 1 Fire 0 read-only
|
||||
INPT5L = $0B ;Joystick 1 Fire 1 read-only
|
||||
|
||||
INPT4 = $0C ;Player 0 Fire Button Input read-only
|
||||
INPT5 = $0D ;Player 1 Fire Button Input read-only
|
||||
|
||||
AUDC0 = $15 ;Audio Control Channel 0 write-only
|
||||
AUDC1 = $16 ;Audio Control Channel 1 write-only
|
||||
AUDF0 = $17 ;Audio Frequency Channel 0 write-only
|
||||
AUDF1 = $18 ;Audio Frequency Channel 1 write-only
|
||||
AUDV0 = $19 ;Audio Volume Channel 0 write-only
|
||||
AUDV1 = $1A ;Audio Volume Channel 1 write-only
|
||||
|
||||
;****** 20-3F ********* MARIA REGISTERS ***************
|
||||
|
||||
BACKGRND = $20 ;Background Color write-only
|
||||
P0C1 = $21 ;Palette 0 - Color 1 write-only
|
||||
P0C2 = $22 ;Palette 0 - Color 2 write-only
|
||||
P0C3 = $23 ;Palette 0 - Color 3 write-only
|
||||
WSYNC = $24 ;Wait For Sync write-only
|
||||
P1C1 = $25 ;Palette 1 - Color 1 write-only
|
||||
P1C2 = $26 ;Palette 1 - Color 2 write-only
|
||||
P1C3 = $27 ;Palette 1 - Color 3 write-only
|
||||
MSTAT = $28 ;Maria Status read-only
|
||||
P2C1 = $29 ;Palette 2 - Color 1 write-only
|
||||
P2C2 = $2A ;Palette 2 - Color 2 write-only
|
||||
P2C3 = $2B ;Palette 2 - Color 3 write-only
|
||||
DPPH = $2C ;Display List List Pointer High write-only
|
||||
P3C1 = $2D ;Palette 3 - Color 1 write-only
|
||||
P3C2 = $2E ;Palette 3 - Color 2 write-only
|
||||
P3C3 = $2F ;Palette 3 - Color 3 write-only
|
||||
DPPL = $30 ;Display List List Pointer Low write-only
|
||||
P4C1 = $31 ;Palette 4 - Color 1 write-only
|
||||
P4C2 = $32 ;Palette 4 - Color 2 write-only
|
||||
P4C3 = $33 ;Palette 4 - Color 3 write-only
|
||||
CHARBASE = $34 ;Character Base Address write-only
|
||||
CHBASE = $34 ;Character Base Address write-only
|
||||
P5C1 = $35 ;Palette 5 - Color 1 write-only
|
||||
P5C2 = $36 ;Palette 5 - Color 2 write-only
|
||||
P5C3 = $37 ;Palette 5 - Color 3 write-only
|
||||
OFFSET = $38 ;Unused - Store zero here write-only
|
||||
P6C1 = $39 ;Palette 6 - Color 1 write-only
|
||||
P6C2 = $3A ;Palette 6 - Color 2 write-only
|
||||
P6C3 = $3B ;Palette 6 - Color 3 write-only
|
||||
CTRL = $3C ;Maria Control Register write-only
|
||||
P7C1 = $3D ;Palette 7 - Color 1 write-only
|
||||
P7C2 = $3E ;Palette 7 - Color 2 write-only
|
||||
P7C3 = $3F ;Palette 7 - Color 3 write-only
|
||||
|
||||
|
||||
;****** 280-2FF ******* PIA PORTS AND TIMERS ************
|
||||
|
||||
SWCHA = $280 ;P0+P1 Joystick Directional Input read-write
|
||||
CTLSWA = $281 ;I/O Control for SCHWA read-write
|
||||
SWACNT = $281 ;VCS name for above read-write
|
||||
SWCHB = $282 ;Console Switches read-write
|
||||
CTLSWB = $283 ;I/O Control for SCHWB read-write
|
||||
SWBCNT = $283 ;VCS name for above read-write
|
||||
|
||||
INTIM = $284 ;Iterval Timer Read read-only
|
||||
TIM1T = $294 ;Set 1 CLK Interval (838 nsec/interval) write-only
|
||||
TIM8T = $295 ;Set 8 CLK Interval (6.7 usec/interval) write-only
|
||||
TIM64T = $296 ;Set 64 CLK Interval (63.6 usec/interval) write-only
|
||||
T1024T = $297 ;Set 1024 CLK Interval (858.2 usec/interval) write-only
|
||||
TIM64TI = $29E ;Interrupt timer 64T write-only
|
||||
|
||||
;XM
|
||||
XCTRL = $470 ; 7=YM2151 6=RAM@6k 5=RAM@4k 4=pokey@450 3=hsc 2=cart 1=RoF_bank1 0=RoF_bank2
|
||||
|
||||
; Pokey register relative locations, since its base may be different
|
||||
; depending on the hardware.
|
||||
PAUDF0 = $0 ; extra audio channels and frequencies
|
||||
PAUDC0 = $1
|
||||
PAUDF1 = $2
|
||||
PAUDC1 = $3
|
||||
PAUDF2 = $4
|
||||
PAUDC2 = $5
|
||||
PAUDF3 = $6
|
||||
PAUDC3 = $7
|
||||
PAUDCTL = $8 ; Audio Control
|
||||
PRANDOM = $A ; 17 bit polycounter pseudo random
|
||||
PSKCTL = $F ; Serial Port control
|
59
presets/atari7800/example_small_sprites.c78
Normal file
59
presets/atari7800/example_small_sprites.c78
Normal file
|
@ -0,0 +1,59 @@
|
|||
// example from https://github.com/steux/cc7800 - license: GPLv3
|
||||
|
||||
#include "prosystem.h"
|
||||
#include "multisprite.h"
|
||||
|
||||
char i, xpos, ypos;
|
||||
|
||||
#define NB_SMALL_SPRITES 128
|
||||
ramchip short sp_xpos[NB_SMALL_SPRITES], sp_ypos[NB_SMALL_SPRITES];
|
||||
ramchip char sp_direction[NB_SMALL_SPRITES];
|
||||
|
||||
const signed short dx[24] = {300, 289, 259, 212, 149, 77, 0, -77, -150, -212, -259, -289, -300, -289, -259, -212, -149, -77, 0, 77, 149, 212, 259, 289};
|
||||
const signed short dy[24] = {0, 124, 240, 339, 415, 463, 480, 463, 415, 339, 240, 124, 0, -124, -239, -339, -415, -463, -480, -463, -415, -339, -240, -124};
|
||||
const char horizontal_pingpong[24] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13 };
|
||||
const char vertical_pingpong[24] = { 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||
|
||||
// Generated with sprites7800 missile.yaml
|
||||
holeydma reversed scattered(16,1) char missile[16] = {
|
||||
0x18, 0x96, 0x7a, 0x7e, 0x7e, 0x6e, 0x9a, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
multisprite_init();
|
||||
|
||||
*P0C1 = multisprite_color(0x1c); // Yellow
|
||||
*P0C2 = multisprite_color(0x37); // Orange
|
||||
*P0C3 = multisprite_color(0x43); // Red
|
||||
|
||||
// Initialize small sprites
|
||||
for (ypos = 0, xpos = 0, i = 0, X = 0; X != NB_SMALL_SPRITES; xpos++, ypos++, X++) {
|
||||
sp_xpos[X] = xpos << 8;
|
||||
sp_ypos[X] = ypos << 8;
|
||||
sp_direction[X] = i++;
|
||||
if (i == 24) i = 0;
|
||||
}
|
||||
|
||||
// Main loop
|
||||
do {
|
||||
multisprite_flip();
|
||||
for (i = 0; i != NB_SMALL_SPRITES; i++) {
|
||||
X = i;
|
||||
Y = sp_direction[X];
|
||||
sp_xpos[X] += dx[Y];
|
||||
sp_ypos[X] += dy[Y];
|
||||
xpos = sp_xpos[X] >> 8;
|
||||
ypos = sp_ypos[X] >> 8;
|
||||
if ((xpos < 5 && (dx[Y] >> 8) < 0) ||
|
||||
(xpos >= 150 && (dx[Y] >> 8) >= 0)) {
|
||||
sp_direction[X] = horizontal_pingpong[Y];
|
||||
}
|
||||
if ((ypos < 5 && (dy[Y] >> 8) < 0) ||
|
||||
(ypos >= MS_YMAX - 20 && (dy[Y] >> 8) >= 0)) {
|
||||
sp_direction[X] = vertical_pingpong[Y];
|
||||
}
|
||||
multisprite_display_small_sprite(xpos, ypos, missile, 1, 0, 8);
|
||||
}
|
||||
} while(1);
|
||||
}
|
110
presets/atari7800/example_vertical_scrolling.c78
Normal file
110
presets/atari7800/example_vertical_scrolling.c78
Normal file
|
@ -0,0 +1,110 @@
|
|||
// example from https://github.com/steux/cc7800 - license: GPLv3
|
||||
|
||||
#include "prosystem.h"
|
||||
#include "gfx.h"
|
||||
#define DMA_CHECK
|
||||
#define VERTICAL_SCROLLING
|
||||
#define _MS_DL_SIZE 64
|
||||
#define _MS_DL_MALLOC(y) ((y == 6 || y == 7 || y == 8)?_MS_DL_SIZE * 2:_MS_DL_SIZE)
|
||||
#include "multisprite.h"
|
||||
|
||||
char i, counter, xpos, ypos;
|
||||
char *ptr;
|
||||
char xchest;
|
||||
|
||||
#define NB_SPRITES 32
|
||||
ramchip short sp_xpos[NB_SPRITES], sp_ypos[NB_SPRITES];
|
||||
ramchip char sp_direction[NB_SPRITES];
|
||||
|
||||
const signed short dx[24] = {300, 289, 259, 212, 149, 77, 0, -77, -150, -212, -259, -289, -300, -289, -259, -212, -149, -77, 0, 77, 149, 212, 259, 289};
|
||||
const signed short dy[24] = {0, 124, 240, 339, 415, 463, 480, 463, 415, 339, 240, 124, 0, -124, -239, -339, -415, -463, -480, -463, -415, -339, -240, -124};
|
||||
const char horizontal_pingpong[24] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13 };
|
||||
const char vertical_pingpong[24] = { 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||
|
||||
const char background[22] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 };
|
||||
#define LTR(x) (((x) - ' ') * 2)
|
||||
const char hello_world[] = { LTR('H'), LTR('E'), LTR('L'), LTR('L'), LTR('O'), LTR(' '), LTR('W'), LTR('O'), LTR('R'), LTR('L'), LTR('D') };
|
||||
|
||||
void main()
|
||||
{
|
||||
counter = 0;
|
||||
|
||||
multisprite_init();
|
||||
multisprite_set_charbase(tiles);
|
||||
|
||||
// Set up a full background
|
||||
for (counter = 0; counter < _MS_DLL_ARRAY_SIZE; counter++) {
|
||||
if (counter & 2) {
|
||||
ptr = background + 2;
|
||||
} else {
|
||||
ptr = background;
|
||||
}
|
||||
multisprite_display_tiles(0, _MS_DLL_ARRAY_SIZE - 1 - counter, ptr, 20, 1);
|
||||
}
|
||||
multisprite_save();
|
||||
|
||||
*P0C1 = multisprite_color(0x1c); // Setup Palette 0: Yellow
|
||||
*P0C2 = multisprite_color(0xc5); // Green
|
||||
*P0C3 = 0x0f; // White
|
||||
|
||||
*P1C1 = multisprite_color(0x55); // Dark pink
|
||||
*P1C2 = multisprite_color(0x5B); // Light pink
|
||||
|
||||
*P2C1 = multisprite_color(0x32);
|
||||
*P2C2 = multisprite_color(0x3D);
|
||||
*P2C3 = multisprite_color(0x37);
|
||||
|
||||
*P3C1 = multisprite_color(0x92);
|
||||
*P3C2 = multisprite_color(0x97);
|
||||
*P3C3 = multisprite_color(0x9D);
|
||||
|
||||
// Initialize sprites
|
||||
for (ypos = 0, xpos = 0, i = 0, X = 0; X != NB_SPRITES; xpos++, ypos++, X++) {
|
||||
sp_xpos[X] = xpos << 8;
|
||||
sp_ypos[X] = ypos << 8;
|
||||
sp_direction[X] = i++;
|
||||
if (i == 24) i = 0;
|
||||
}
|
||||
|
||||
// Main loop
|
||||
do {
|
||||
// Prepare scrolling data
|
||||
if (multisprite_vscroll_buffer_empty()) {
|
||||
if (counter & 2) {
|
||||
ptr = background + 2;
|
||||
} else {
|
||||
ptr = background;
|
||||
}
|
||||
multisprite_vscroll_buffer_tiles(0, ptr, 20, 1);
|
||||
multisprite_vscroll_buffer_sprite(xchest, chest, 2, 3);
|
||||
xchest += 45;
|
||||
counter++;
|
||||
}
|
||||
|
||||
while (*MSTAT & 0x80);
|
||||
multisprite_flip();
|
||||
multisprite_vertical_scrolling(-1);
|
||||
multisprite_reserve_dma(104, sizeof(hello_world), 2);
|
||||
for (i = 0; i != NB_SPRITES; i++) {
|
||||
X = i;
|
||||
Y = sp_direction[X];
|
||||
sp_xpos[X] += dx[Y];
|
||||
sp_ypos[X] += dy[Y];
|
||||
xpos = sp_xpos[X] >> 8;
|
||||
ypos = sp_ypos[X] >> 8;
|
||||
if ((xpos < 5 && (dx[Y] >> 8) < 0) ||
|
||||
(xpos >= 150 && (dx[Y] >> 8) >= 0)) {
|
||||
sp_direction[X] = horizontal_pingpong[Y];
|
||||
}
|
||||
if ((ypos < 5 && (dy[Y] >> 8) < 0) ||
|
||||
(ypos >= MS_YMAX - 20 && (dy[Y] >> 8) >= 0)) {
|
||||
sp_direction[X] = vertical_pingpong[Y];
|
||||
}
|
||||
multisprite_display_sprite(xpos, ypos, bb_char1, 2, 0);
|
||||
}
|
||||
for (xpos = 40, i = 0; i != sizeof(hello_world); xpos += 8, i++) {
|
||||
ptr = chars0 + hello_world[X = i];
|
||||
multisprite_display_sprite_fast(xpos, 104, ptr, 2, 2);
|
||||
}
|
||||
} while(1);
|
||||
}
|
152
presets/atari7800/gfx.h
Normal file
152
presets/atari7800/gfx.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
// example from https://github.com/steux/cc7800 - license: GPLv3
|
||||
|
||||
reversed scattered(16,4) char tiles[64] = {
|
||||
0x5a, 0x5a, 0x95, 0x95, 0x69, 0x69, 0x65, 0x65, 0x69, 0x69, 0x95, 0x95, 0xa5, 0xa5, 0x65, 0x65,
|
||||
0xa5, 0xa5, 0xa9, 0xa9, 0x96, 0x96, 0xa6, 0xa6, 0x96, 0x96, 0xa9, 0xa9, 0x5a, 0x5a, 0xa6, 0xa6,
|
||||
0x5a, 0x5a, 0x95, 0x95, 0x69, 0x69, 0x65, 0x65, 0x69, 0x69, 0x95, 0x95, 0xa5, 0xa5, 0x65, 0x65,
|
||||
0xa5, 0xa5, 0xa9, 0xa9, 0x96, 0x96, 0xa6, 0xa6, 0x96, 0x96, 0xa9, 0xa9, 0x5a, 0x5a, 0xa6, 0xa6
|
||||
};
|
||||
holeydma reversed scattered(16,32) char chars0[512] = {
|
||||
0x00, 0x00, 0x05, 0x00, 0x50, 0x50, 0x51, 0x40, 0x05, 0x00, 0x50, 0x10, 0x15, 0x40, 0x00, 0x50,
|
||||
0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0x00, 0x50, 0x50, 0x51, 0x40, 0x05, 0x00, 0x50, 0x10, 0x15, 0x40, 0x00, 0x50,
|
||||
0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x09, 0x00, 0x60, 0x90, 0x62, 0x40, 0x16, 0x60, 0x90, 0x60, 0x5f, 0x90, 0x01, 0xb0,
|
||||
0x06, 0xc0, 0x36, 0x00, 0x90, 0x60, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24,
|
||||
0x00, 0x00, 0x05, 0x00, 0x50, 0x50, 0x51, 0x80, 0x25, 0x50, 0x50, 0x50, 0x90, 0x60, 0x01, 0x40,
|
||||
0x05, 0x00, 0x05, 0x00, 0x50, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
|
||||
0x00, 0x00, 0x09, 0x00, 0x50, 0x92, 0x65, 0x90, 0x6f, 0xf0, 0xf2, 0x70, 0xd9, 0x70, 0x09, 0xc0,
|
||||
0x27, 0x00, 0x0e, 0x40, 0xd6, 0x70, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
|
||||
0x00, 0x00, 0x06, 0x00, 0x90, 0x61, 0x99, 0x60, 0x50, 0x00, 0x01, 0x80, 0x26, 0x40, 0x06, 0x00,
|
||||
0x18, 0x00, 0x01, 0x80, 0x25, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
|
||||
0x00, 0x00, 0x06, 0x00, 0xf0, 0xf3, 0x6e, 0x70, 0xe6, 0x40, 0x06, 0xc0, 0x26, 0xc0, 0x0f, 0x00,
|
||||
0x24, 0x00, 0x02, 0x42, 0x66, 0x64, 0x66, 0x60, 0x00, 0x00, 0x66, 0x60, 0x00, 0x00, 0x02, 0x70,
|
||||
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x62, 0x40, 0x26, 0x40, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x02, 0x42, 0x66, 0x64, 0x66, 0x60, 0x00, 0x00, 0x66, 0x60, 0x00, 0x00, 0x02, 0x40,
|
||||
0x00, 0x00, 0x0f, 0x00, 0x00, 0x02, 0x6a, 0x60, 0x3f, 0xa0, 0x1b, 0x00, 0x6d, 0xa0, 0x00, 0x00,
|
||||
0x28, 0x00, 0x02, 0x83, 0xda, 0x7c, 0xf6, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x09, 0xc0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa6, 0x90, 0x00, 0x90, 0x28, 0x00, 0x92, 0x60, 0x00, 0x00,
|
||||
0x24, 0x00, 0x01, 0x80, 0x29, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xae, 0xb0, 0x6a, 0xb0, 0xac, 0xa0, 0xa2, 0x70, 0x00, 0x00,
|
||||
0x36, 0x00, 0x0a, 0xc0, 0xaf, 0xa0, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x27, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0xa6, 0x80, 0x90, 0x60, 0x62, 0x80, 0x00, 0x00,
|
||||
0x0a, 0x00, 0x06, 0x00, 0x90, 0x60, 0x09, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xa2, 0x80, 0xfa, 0xc0, 0xb0, 0xa0, 0xea, 0xa0, 0x00, 0x00,
|
||||
0x0e, 0x80, 0x2b, 0x00, 0xf0, 0xf0, 0x0f, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xac, 0x00,
|
||||
0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xa2, 0x80, 0x0a, 0x00, 0x80, 0xa0, 0x2a, 0xa0, 0x00, 0x00,
|
||||
0x02, 0x80, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xa0, 0x00,
|
||||
0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf3, 0xc0, 0x0f, 0x00, 0xc0, 0xf0, 0x3f, 0xf0, 0x00, 0x00,
|
||||
0x03, 0xc0, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
holeydma reversed scattered(16,32) char chars1[512] = {
|
||||
0x15, 0x40, 0x05, 0x00, 0x15, 0x40, 0x15, 0x40, 0x01, 0x40, 0x55, 0x50, 0x15, 0x40, 0x55, 0x50,
|
||||
0x15, 0x40, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x54, 0x00, 0x15, 0x40,
|
||||
0x15, 0x40, 0x05, 0x00, 0x15, 0x40, 0x15, 0x40, 0x01, 0x40, 0x55, 0x50, 0x15, 0x40, 0x55, 0x50,
|
||||
0x15, 0x40, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x54, 0x00, 0x15, 0x40,
|
||||
0x5a, 0x70, 0x0d, 0x00, 0x7a, 0xd0, 0x7a, 0x50, 0x07, 0x40, 0xda, 0xa0, 0x5a, 0xd0, 0x7a, 0xd0,
|
||||
0x7a, 0x50, 0xda, 0x70, 0x00, 0x00, 0x00, 0x00, 0x05, 0xa0, 0x00, 0x00, 0xa7, 0x00, 0xda, 0x70,
|
||||
0x70, 0xd0, 0x05, 0x00, 0x50, 0x50, 0x50, 0xd0, 0x05, 0x40, 0x50, 0x00, 0xd0, 0x70, 0x50, 0x50,
|
||||
0x50, 0xd0, 0x70, 0x50, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x50, 0x50,
|
||||
0x51, 0x70, 0x1d, 0x00, 0xa0, 0xd0, 0xa0, 0xd0, 0x37, 0x40, 0xd7, 0x40, 0xd0, 0xa0, 0xa1, 0xe0,
|
||||
0x70, 0xd0, 0x70, 0x50, 0x07, 0x00, 0x0d, 0x00, 0x1e, 0x00, 0x75, 0xd0, 0x0b, 0x40, 0xa0, 0x70,
|
||||
0xd3, 0x50, 0x37, 0x00, 0x00, 0x70, 0x00, 0x70, 0x1d, 0xc0, 0x75, 0xc0, 0x70, 0x00, 0x03, 0x40,
|
||||
0xd0, 0x70, 0x50, 0xd0, 0x05, 0x00, 0x07, 0x00, 0x14, 0x00, 0xdd, 0x70, 0x01, 0xc0, 0x00, 0xd0,
|
||||
0x76, 0xd0, 0x27, 0x00, 0x03, 0x60, 0x07, 0x60, 0x6b, 0x40, 0xaa, 0x70, 0x77, 0x40, 0x07, 0x80,
|
||||
0xb7, 0x60, 0xb7, 0x70, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0xaa, 0xa0, 0x02, 0x70, 0x03, 0x60,
|
||||
0xdc, 0x70, 0x07, 0x00, 0x03, 0x40, 0x07, 0x40, 0x43, 0x40, 0x00, 0x70, 0x77, 0x40, 0x07, 0x00,
|
||||
0x37, 0x40, 0x37, 0x70, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x70, 0x03, 0x40,
|
||||
0xd8, 0xf0, 0x0d, 0x00, 0x36, 0x80, 0x0a, 0x70, 0xf7, 0xf0, 0x00, 0x70, 0x7a, 0xf0, 0x07, 0x00,
|
||||
0x7a, 0x70, 0x2a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xdf, 0x70, 0x03, 0xe0, 0x0d, 0x80,
|
||||
0xf0, 0x70, 0x0f, 0x00, 0x1c, 0x00, 0x00, 0xd0, 0x7d, 0xd0, 0x00, 0xf0, 0xd0, 0x70, 0x0f, 0x00,
|
||||
0xf0, 0xd0, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x7d, 0xf0, 0x03, 0x40, 0x07, 0x00,
|
||||
0xf0, 0xd0, 0x0f, 0x00, 0xf8, 0x00, 0xf0, 0xf0, 0xab, 0xe0, 0xf0, 0xf0, 0xf0, 0x70, 0x0f, 0x00,
|
||||
0xf0, 0xf0, 0x70, 0xf0, 0x0f, 0x00, 0x0f, 0x00, 0x2f, 0x00, 0xaa, 0xa0, 0x0f, 0x80, 0x0a, 0x00,
|
||||
0xd0, 0xf0, 0x0f, 0x00, 0xd0, 0x00, 0xf0, 0x70, 0x03, 0xc0, 0xd0, 0x70, 0x70, 0xf0, 0x0d, 0x00,
|
||||
0x70, 0x70, 0xf0, 0xd0, 0x0f, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||
0xbd, 0xe0, 0xff, 0xf0, 0xff, 0xf0, 0xbf, 0xe0, 0x03, 0xc0, 0xbf, 0xe0, 0xbf, 0xe0, 0x0f, 0x00,
|
||||
0xbf, 0xe0, 0xbf, 0xe0, 0x0a, 0x00, 0x3e, 0x00, 0x0b, 0xf0, 0x00, 0x00, 0xfe, 0x00, 0x0d, 0x00,
|
||||
0x3f, 0xc0, 0xff, 0xf0, 0xff, 0xf0, 0x3f, 0xc0, 0x03, 0xc0, 0x3f, 0xc0, 0x3f, 0xc0, 0x0f, 0x00,
|
||||
0x3f, 0xc0, 0x3f, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x0f, 0x00,
|
||||
0x2a, 0x80, 0xaa, 0xa0, 0xaa, 0xa0, 0x2a, 0x80, 0x02, 0x80, 0x2a, 0x80, 0x2a, 0x80, 0x0a, 0x00,
|
||||
0x2a, 0x80, 0x2a, 0x80, 0x00, 0x00, 0x28, 0x00, 0x02, 0xa0, 0x00, 0x00, 0xa8, 0x00, 0x0a, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
holeydma reversed scattered(16,32) char chars2[512] = {
|
||||
0x15, 0x40, 0x05, 0x00, 0x55, 0x40, 0x15, 0x40, 0x55, 0x00, 0x55, 0x50, 0x55, 0x50, 0x15, 0x40,
|
||||
0x50, 0x50, 0x15, 0x40, 0x05, 0x50, 0x50, 0x50, 0x50, 0x00, 0x50, 0x14, 0x50, 0x50, 0x15, 0x40,
|
||||
0x15, 0x40, 0x05, 0x00, 0x55, 0x40, 0x15, 0x40, 0x55, 0x00, 0x55, 0x50, 0x55, 0x50, 0x15, 0x40,
|
||||
0x50, 0x50, 0x15, 0x40, 0x05, 0x50, 0x50, 0x50, 0x50, 0x00, 0x50, 0x14, 0x50, 0x50, 0x15, 0x40,
|
||||
0x5a, 0x70, 0x1d, 0xc0, 0x7a, 0xd0, 0x7a, 0x50, 0xdb, 0x40, 0xda, 0xa0, 0x5a, 0xa0, 0x7a, 0xd0,
|
||||
0x70, 0x50, 0x27, 0x80, 0x09, 0x60, 0x51, 0xe0, 0x70, 0x00, 0x74, 0x5c, 0xd4, 0x70, 0xda, 0x70,
|
||||
0x70, 0xd0, 0x15, 0x40, 0x50, 0x50, 0x50, 0xd0, 0x71, 0x40, 0x50, 0x00, 0xd0, 0x00, 0x50, 0x50,
|
||||
0x50, 0xd0, 0x05, 0x00, 0x03, 0x40, 0xd1, 0x40, 0x50, 0x00, 0x54, 0xd4, 0x74, 0x50, 0x50, 0x50,
|
||||
0x51, 0x70, 0xda, 0x70, 0x50, 0xd0, 0x70, 0xa0, 0x72, 0x50, 0xd0, 0x00, 0xd0, 0x00, 0x50, 0xa0,
|
||||
0x70, 0xd0, 0x07, 0x00, 0x03, 0x40, 0xdd, 0x80, 0x50, 0x00, 0x75, 0xdc, 0x77, 0x50, 0xd0, 0x70,
|
||||
0xd3, 0x50, 0x70, 0x50, 0xd0, 0x70, 0xd0, 0x00, 0x50, 0xd0, 0x70, 0x00, 0x70, 0x00, 0xd0, 0x00,
|
||||
0xd0, 0x70, 0x0d, 0x00, 0x01, 0xc0, 0x77, 0x00, 0xd0, 0x00, 0xdd, 0x74, 0x5d, 0xd0, 0x70, 0xd0,
|
||||
0x73, 0xd0, 0x77, 0x70, 0x77, 0x60, 0x70, 0x00, 0x70, 0x70, 0x77, 0x00, 0x77, 0x00, 0x73, 0x70,
|
||||
0x77, 0x70, 0x07, 0x00, 0x03, 0x40, 0x76, 0x00, 0x70, 0x00, 0x7b, 0xb4, 0x77, 0x70, 0x70, 0x70,
|
||||
0xd1, 0x70, 0x77, 0x70, 0x77, 0x40, 0x70, 0x00, 0x70, 0x70, 0x77, 0x00, 0x77, 0x00, 0x73, 0x70,
|
||||
0x77, 0x70, 0x07, 0x00, 0x03, 0x40, 0x74, 0x00, 0x70, 0x00, 0x73, 0x34, 0x77, 0x70, 0x70, 0x70,
|
||||
0xd2, 0xa0, 0x7a, 0xf0, 0xfa, 0xd0, 0x70, 0x00, 0xf0, 0xf0, 0xda, 0x00, 0x7a, 0x00, 0xf2, 0xd0,
|
||||
0x7a, 0x70, 0x07, 0x00, 0x03, 0x40, 0xf7, 0x00, 0x70, 0x00, 0xd2, 0x3c, 0xfb, 0xd0, 0x70, 0xf0,
|
||||
0xf0, 0x00, 0xd0, 0x70, 0xd0, 0x70, 0xf0, 0x00, 0x70, 0xd0, 0x70, 0x00, 0xd0, 0x00, 0xd0, 0x70,
|
||||
0xf0, 0xd0, 0x0d, 0x00, 0x01, 0xc0, 0xdf, 0x00, 0xf0, 0x00, 0x70, 0x34, 0xd3, 0x70, 0xf0, 0xd0,
|
||||
0xf0, 0x10, 0xf0, 0x70, 0xf0, 0xf0, 0xf0, 0xf0, 0x73, 0xe0, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0xf0,
|
||||
0xf0, 0xf0, 0x0f, 0x00, 0xf3, 0xc0, 0xfb, 0xc0, 0xf0, 0x00, 0xf0, 0x3c, 0xf2, 0xf0, 0xf0, 0xf0,
|
||||
0xd0, 0x30, 0xd0, 0xf0, 0xd0, 0x70, 0xf0, 0x70, 0xf3, 0xc0, 0xd0, 0x00, 0x70, 0x00, 0xd0, 0xd0,
|
||||
0x70, 0x70, 0x07, 0x00, 0xd3, 0x40, 0xd1, 0xc0, 0x70, 0x00, 0xd0, 0x34, 0xd0, 0xf0, 0xf0, 0xf0,
|
||||
0xbd, 0xe0, 0xf0, 0xf0, 0xff, 0xe0, 0xbf, 0xe0, 0xff, 0x80, 0xff, 0xf0, 0xf0, 0x00, 0xbf, 0xe0,
|
||||
0xf0, 0xf0, 0x3f, 0xc0, 0xbf, 0x80, 0xf2, 0xf0, 0xff, 0xf0, 0xf0, 0x3c, 0xf0, 0xf0, 0xbd, 0xe0,
|
||||
0x3f, 0xc0, 0xf0, 0xf0, 0xff, 0xc0, 0x3f, 0xc0, 0xff, 0x00, 0xff, 0xf0, 0xf0, 0x00, 0x3f, 0xc0,
|
||||
0xf0, 0xf0, 0x3f, 0xc0, 0x3f, 0x00, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0x3c, 0xf0, 0xf0, 0x3f, 0xc0,
|
||||
0x2a, 0x80, 0xa0, 0xa0, 0xaa, 0x80, 0x2a, 0x80, 0xaa, 0x00, 0xaa, 0xa0, 0xa0, 0x00, 0x2a, 0x80,
|
||||
0xa0, 0xa0, 0x2a, 0x80, 0x2a, 0x00, 0xa0, 0xa0, 0xaa, 0xa0, 0xa0, 0x28, 0xa0, 0xa0, 0x2a, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
holeydma reversed scattered(16,32) char chars3[512] = {
|
||||
0x55, 0x40, 0x15, 0x40, 0x55, 0x40, 0x15, 0x40, 0x55, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x14,
|
||||
0x50, 0x50, 0x50, 0x50, 0x55, 0x50, 0x15, 0x40, 0x00, 0x50, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x55, 0x40, 0x15, 0x40, 0x55, 0x40, 0x15, 0x40, 0x55, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x14,
|
||||
0x50, 0x50, 0x50, 0x50, 0x55, 0x50, 0x15, 0x40, 0x00, 0x50, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5a, 0x70, 0x5a, 0xd0, 0x7a, 0xd0, 0x7a, 0x50, 0xa7, 0xa0, 0xd0, 0x70, 0x50, 0xd0, 0x70, 0x1c,
|
||||
0x70, 0x50, 0xd0, 0x70, 0xaa, 0x70, 0x1e, 0x80, 0x01, 0xac, 0x2b, 0x40, 0x07, 0x00, 0x0c, 0x00,
|
||||
0x70, 0xd0, 0xd0, 0x70, 0x50, 0x50, 0x50, 0xd0, 0x05, 0x00, 0x50, 0x50, 0xd0, 0x70, 0x50, 0x14,
|
||||
0x50, 0xd0, 0x70, 0x50, 0x00, 0x50, 0x14, 0x00, 0x01, 0x04, 0x01, 0xc0, 0x05, 0x00, 0x04, 0x00,
|
||||
0x50, 0x70, 0xd0, 0x70, 0x50, 0xd0, 0x70, 0xa0, 0x07, 0x00, 0xd0, 0x70, 0xd0, 0x70, 0x50, 0x14,
|
||||
0xb5, 0xe0, 0x70, 0x50, 0x03, 0x60, 0x1c, 0x00, 0x0d, 0x08, 0x01, 0xc0, 0x37, 0x40, 0x14, 0x00,
|
||||
0xd0, 0x50, 0x70, 0x50, 0xd0, 0x70, 0xd0, 0x00, 0x0d, 0x00, 0x70, 0xd0, 0x70, 0x50, 0xd0, 0x34,
|
||||
0x1d, 0x40, 0x50, 0xd0, 0x01, 0xc0, 0x34, 0x00, 0x07, 0x00, 0x01, 0x40, 0x1d, 0xc0, 0x34, 0x00,
|
||||
0x77, 0xe0, 0x70, 0x70, 0x77, 0x60, 0xb7, 0x40, 0x07, 0x00, 0x70, 0x70, 0x70, 0x70, 0x73, 0x34,
|
||||
0x27, 0x80, 0xb7, 0x60, 0x07, 0x80, 0x34, 0x00, 0x37, 0x70, 0x03, 0x40, 0x77, 0x70, 0x77, 0x74,
|
||||
0xdd, 0x40, 0x70, 0x70, 0x77, 0x40, 0x37, 0x40, 0x07, 0x00, 0x70, 0x70, 0x70, 0x70, 0x73, 0x34,
|
||||
0x07, 0x00, 0x37, 0x40, 0x07, 0x00, 0x34, 0x00, 0x37, 0x70, 0x03, 0x40, 0x77, 0x70, 0x77, 0x74,
|
||||
0xda, 0x80, 0x70, 0xf0, 0xf7, 0x80, 0x2a, 0x70, 0x07, 0x00, 0xd0, 0x70, 0x70, 0xf0, 0xf7, 0xdc,
|
||||
0x3f, 0x40, 0x27, 0x80, 0x1e, 0x00, 0x34, 0x00, 0x2d, 0xa0, 0x03, 0x40, 0xa7, 0xa0, 0x7d, 0xf4,
|
||||
0xf0, 0x00, 0xd0, 0x70, 0xdf, 0x00, 0x00, 0xd0, 0x0d, 0x00, 0x70, 0xf0, 0xd0, 0x70, 0xdf, 0x7c,
|
||||
0x37, 0xc0, 0x0d, 0x00, 0x3c, 0x00, 0x1c, 0x00, 0x07, 0x00, 0x01, 0xc0, 0x0f, 0x00, 0xf7, 0xdc,
|
||||
0xf0, 0x00, 0xbf, 0x60, 0xfb, 0xc0, 0xf0, 0xf0, 0x0f, 0x00, 0xf0, 0xf0, 0xbf, 0x60, 0xfe, 0xfc,
|
||||
0xfa, 0xf0, 0x0f, 0x00, 0xf8, 0x00, 0x3c, 0x00, 0x3e, 0x0c, 0x03, 0xc0, 0x0f, 0x00, 0xb6, 0xa8,
|
||||
0xd0, 0x00, 0x1f, 0xc0, 0xd3, 0x40, 0xf0, 0x70, 0x07, 0x00, 0xd0, 0x70, 0x3f, 0xc0, 0xdc, 0xdc,
|
||||
0x70, 0x70, 0x07, 0x00, 0xd0, 0x00, 0x1c, 0x00, 0x34, 0x0c, 0x03, 0x40, 0x0d, 0x00, 0x3c, 0x00,
|
||||
0xf0, 0x00, 0x2b, 0xf0, 0xf2, 0xf0, 0xbf, 0xe0, 0x0f, 0x00, 0xbf, 0xe0, 0x2f, 0x80, 0xf8, 0xbc,
|
||||
0xf0, 0xf0, 0x0f, 0x00, 0xff, 0xf0, 0x3f, 0xc0, 0xff, 0xf8, 0x3f, 0xc0, 0x0f, 0x00, 0x2c, 0x00,
|
||||
0xf0, 0x00, 0x03, 0xf0, 0xf0, 0xf0, 0x3f, 0xc0, 0x0f, 0x00, 0x3f, 0xc0, 0x0f, 0x00, 0xf0, 0x3c,
|
||||
0xf0, 0xf0, 0x0f, 0x00, 0xff, 0xf0, 0x3f, 0xc0, 0xff, 0xf0, 0x3f, 0xc0, 0x0f, 0x00, 0x0c, 0x00,
|
||||
0xa0, 0x00, 0x02, 0xa0, 0xa0, 0xa0, 0x2a, 0x80, 0x0a, 0x00, 0x2a, 0x80, 0x0a, 0x00, 0xa0, 0x28,
|
||||
0xa0, 0xa0, 0x0a, 0x00, 0xaa, 0xa0, 0x2a, 0x80, 0xaa, 0xa0, 0x2a, 0x80, 0x0a, 0x00, 0x08, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
holeydma reversed scattered(16,2) char bb_char1[32] = {
|
||||
0x01, 0x00, 0x01, 0x40, 0x0a, 0x94, 0x2a, 0x90, 0x3b, 0xa0, 0xc8, 0xe5, 0xc8, 0xe4, 0xc8, 0xd0,
|
||||
0xc8, 0xe5, 0xbb, 0x84, 0x0c, 0x20, 0x2a, 0x90, 0x0e, 0x50, 0x3f, 0x94, 0x3d, 0x68, 0x5d, 0x6a
|
||||
};
|
||||
reversed scattered(16,2) char chest[32] = {
|
||||
0x00, 0x00, 0x05, 0x50, 0x2b, 0xf4, 0x96, 0xfc, 0x69, 0xbd, 0xbe, 0x6a, 0x55, 0x55, 0xaa, 0xbf,
|
||||
0xd5, 0xd5, 0xd9, 0xb7, 0xef, 0x9d, 0xef, 0x9d, 0xef, 0x9d, 0xdd, 0x9d, 0xd5, 0xf7, 0xff, 0x95
|
||||
};
|
16
presets/atari7800/skeleton.cc7800
Normal file
16
presets/atari7800/skeleton.cc7800
Normal file
|
@ -0,0 +1,16 @@
|
|||
// example from https://github.com/steux/cc7800 - license: GPLv3
|
||||
|
||||
#include "conio.h"
|
||||
|
||||
char i;
|
||||
|
||||
void main()
|
||||
{
|
||||
clrscr();
|
||||
for (i = 0; i != 8; i++) {
|
||||
textcolor(i);
|
||||
gotoxy(0, i);
|
||||
cputs("Hello World!");
|
||||
}
|
||||
while(1);
|
||||
}
|
|
@ -6,66 +6,11 @@
|
|||
;
|
||||
|
||||
processor 6502
|
||||
|
||||
; ************ Hardware Adresses ***************************
|
||||
|
||||
INPTCTRL equ $01 ;Input control
|
||||
AUDC0 equ $15 ;Audio Control Channel 0
|
||||
AUDC1 equ $16 ;Audio Control Channel 1
|
||||
AUDF0 equ $17 ;Audio Frequency Channel 0
|
||||
AUDF1 equ $18 ;Audio Frequency Channel 1
|
||||
AUDV0 equ $19 ;Audio Volume Channel 0
|
||||
AUDV1 equ $1A ;Audio Volume Channel 1
|
||||
INPT0 equ $08 ;Paddle Control Input 0
|
||||
INPT1 equ $09 ;Paddle Control Input 1
|
||||
INPT2 equ $0A ;Paddle Control Input 2
|
||||
INPT3 equ $0B ;Paddle Control Input 3
|
||||
INPT4 equ $0C ;Player 0 Fire Button Input
|
||||
INPT5 equ $0D ;Player 1 Fire Button Input
|
||||
|
||||
BACKGRND equ $20 ;Background Color
|
||||
P0C1 equ $21 ;Palette 0 - Color 1
|
||||
P0C2 equ $22 ;Palette 0 - Color 2
|
||||
P0C3 equ $23 ;Palette 0 - Color 3
|
||||
WSYNC equ $24 ;Wait For Sync
|
||||
P1C1 equ $25 ;Palette 1 - Color 1
|
||||
P1C2 equ $26 ;Palette 1 - Color 2
|
||||
P1C3 equ $27 ;Palette 1 - Color 3
|
||||
MSTAT equ $28 ;Maria Status
|
||||
P2C1 equ $29 ;Palette 2 - Color 1
|
||||
P2C2 equ $2A ;Palette 2 - Color 2
|
||||
P2C3 equ $2B ;Palette 2 - Color 3
|
||||
DPPH equ $2C ;Display List List Pointer High
|
||||
P3C1 equ $2D ;Palette 3 - Color 1
|
||||
P3C2 equ $2E ;Palette 3 - Color 2
|
||||
P3C3 equ $2F ;Palette 3 - Color 3
|
||||
DPPL equ $30 ;Display List List Pointer Low
|
||||
P4C1 equ $31 ;Palette 4 - Color 1
|
||||
P4C2 equ $32 ;Palette 4 - Color 2
|
||||
P4C3 equ $33 ;Palette 4 - Color 3
|
||||
CHARBASE equ $34 ;Character Base Address
|
||||
P5C1 equ $35 ;Palette 5 - Color 1
|
||||
P5C2 equ $36 ;Palette 5 - Color 2
|
||||
P5C3 equ $37 ;Palette 5 - Color 3
|
||||
OFFSET equ $38 ;Unused - Store zero here
|
||||
P6C1 equ $39 ;Palette 6 - Color 1
|
||||
P6C2 equ $3A ;Palette 6 - Color 2
|
||||
P6C3 equ $3B ;Palette 6 - Color 3
|
||||
CTRL equ $3C ;Maria Control Register
|
||||
P7C1 equ $3D ;Palette 7 - Color 1
|
||||
P7C2 equ $3E ;Palette 7 - Color 2
|
||||
P7C3 equ $3F ;Palette 7 - Color 3
|
||||
|
||||
SWCHA equ $280 ;P0, P1 Joystick Directional Input
|
||||
SWCHB equ $282 ;Console Switches
|
||||
CTLSWA equ $281 ;I/O Control for SCHWA
|
||||
CTLSWB equ $283 ;I/O Control for SCHWB
|
||||
|
||||
SEG.U data
|
||||
|
||||
include "7800.h"
|
||||
|
||||
;******* Vairables ********************************
|
||||
|
||||
SEG.U data
|
||||
org $40
|
||||
|
||||
xpos ds.b 1 ;X Position of sprite
|
||||
|
@ -75,12 +20,9 @@ dlpnt ds.w 1
|
|||
dlend ds.b 12 ;Index of end of each DL
|
||||
|
||||
|
||||
|
||||
|
||||
;**********************************************************
|
||||
|
||||
SEG code
|
||||
|
||||
org $4000 ;Start of code
|
||||
|
||||
START
|
||||
|
|
69
presets/atari7800/test_conio.c78
Normal file
69
presets/atari7800/test_conio.c78
Normal file
|
@ -0,0 +1,69 @@
|
|||
// example from https://github.com/steux/cc7800 - license: GPLv3
|
||||
|
||||
#include "conio.h"
|
||||
#include "assert.h"
|
||||
|
||||
char i;
|
||||
|
||||
reversed scattered(8,1) char special_char[8] = {
|
||||
0x66, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
clrscr();
|
||||
// Draw a square
|
||||
gotoxy(0, 0);
|
||||
textcolor(7);
|
||||
putch(CONIO_TL_CORNER);
|
||||
for (i = 0; i != 20; i++) {
|
||||
putch(CONIO_HBAR);
|
||||
}
|
||||
putch(CONIO_TR_CORNER);
|
||||
for (i = 0; i != 8; i++) {
|
||||
gotoxy(0, i + 1);
|
||||
putch(CONIO_VBAR);
|
||||
gotoxy(21, i + 1);
|
||||
putch(CONIO_VBAR);
|
||||
}
|
||||
gotoxy(0, 9);
|
||||
putch(CONIO_BL_CORNER);
|
||||
for (i = 0; i != 20; i++) {
|
||||
putch(CONIO_HBAR);
|
||||
}
|
||||
putch(CONIO_BR_CORNER);
|
||||
// Write some text
|
||||
for (i = 0; i != 8; i++) {
|
||||
textcolor(i);
|
||||
gotoxy(i + 1, i + 1);
|
||||
cputs("Hello World!");
|
||||
}
|
||||
// Long text test
|
||||
gotoxy(0, 10);
|
||||
cputs("This is a long text that fits in a line.");
|
||||
|
||||
gotoxy(10, 11);
|
||||
cputs("World!");
|
||||
gotoxy(4, 11);
|
||||
cputs("Hello");
|
||||
|
||||
gotoxy(10, 12);
|
||||
cputs("World!");
|
||||
gotoxy(4, 12);
|
||||
textcolor(4);
|
||||
cputs("Hello");
|
||||
|
||||
gotoxy(0, 13);
|
||||
for (i = 0; i != 8; i++) {
|
||||
textcolor(i);
|
||||
putch('!');
|
||||
}
|
||||
|
||||
gotoxy(0, 14);
|
||||
for (i = 0; i != 8; i++) {
|
||||
textcolor(7 - i);
|
||||
putch(128); // Special character
|
||||
}
|
||||
|
||||
while(1);
|
||||
}
|
|
@ -20,15 +20,16 @@ dlloop ;Create Display List
|
|||
|
||||
lda #$06
|
||||
sta CHACTL ;Set Character Control
|
||||
lda #$84 ;Set color PF2
|
||||
sta COLOR0+2
|
||||
sta COLOR0+4 ; bakground
|
||||
lda #$0F ;Set color PF1
|
||||
sta COLOR0+1
|
||||
lda #$3f
|
||||
lda #$28
|
||||
sta COLOR0+0
|
||||
lda #$0F
|
||||
sta COLOR0+1
|
||||
lda #$d6
|
||||
sta COLOR0+2
|
||||
lda #$58
|
||||
sta COLOR0+3
|
||||
lda #$84
|
||||
sta COLOR0+4 ; bakground
|
||||
lda #$00 ;Set Display list pointer
|
||||
sta SDLSTL ;Shadow DLISTL
|
||||
lda #$10
|
||||
|
@ -36,6 +37,7 @@ dlloop ;Create Display List
|
|||
lda #$e0 ;Set Charcter Set Base
|
||||
sta CHBAS
|
||||
lda #$22 ;Enable DMA
|
||||
lda #$21
|
||||
sta SDMCTL ;Shadow DMACTL
|
||||
|
||||
print
|
||||
|
@ -57,19 +59,31 @@ wait
|
|||
jmp wait
|
||||
|
||||
;Display list data (starts at $1000)
|
||||
dlist .byte $70,$70,$70 ;24 blank scanlines
|
||||
.byte $42,$00,$18,$02 ;mode 2 @ $1800
|
||||
.byte $43,$00,$18,$02 ;mode 3 @ $1800
|
||||
.byte $44,$00,$18,$02 ;mode 4 @ $1800
|
||||
.byte $45,$00,$18,$02 ;mode 5 @ $1800
|
||||
.byte $46,$00,$18,$06 ;mode 6 @ $1800
|
||||
.byte $47,$00,$18,$06 ;mode 7 @ $1800
|
||||
dlist .byte $70,$70 ;16 blank scanlines
|
||||
.byte $42,$00,$18,$02,$70 ;mode 2 @ $1800
|
||||
.byte $43,$00,$18,$70 ;mode 3 @ $1800
|
||||
.byte $44,$00,$18,$70 ;mode 4 @ $1800
|
||||
.byte $45,$00,$18,$70 ;mode 5 @ $1800
|
||||
.byte $46,$00,$18,$70 ;mode 6 @ $1800
|
||||
.byte $47,$00,$18,$70 ;mode 7 @ $1800
|
||||
.byte $48,$00,$18,$08,$70 ;mode 2 @ $1800
|
||||
.byte $49,$00,$18,$70 ;mode 3 @ $1800
|
||||
.byte $4a,$00,$18,$70 ;mode 4 @ $1800
|
||||
.byte $4b,$00,$18,$70 ;mode 5 @ $1800
|
||||
.byte $4c,$00,$18,$70 ;mode 6 @ $1800
|
||||
.byte $4d,$00,$18,$70 ;mode 7 @ $1800
|
||||
.byte $4e,$00,$18,$70 ;mode 7 @ $1800
|
||||
.byte $4f,$00,$18,$70 ;mode 7 @ $1800
|
||||
.byte $41,$00,$10 ;JMP -> $1000
|
||||
dlistend
|
||||
|
||||
;Text data
|
||||
text1 .byte "Hello World! "
|
||||
.byte $a1,$a2,$a3
|
||||
.repeat 16
|
||||
.byte 32
|
||||
.repend
|
||||
.byte "12345"
|
||||
.byte 0
|
||||
|
||||
;Cartridge footer
|
164
presets/atari8-800/pokeymusic.ca65
Normal file
164
presets/atari8-800/pokeymusic.ca65
Normal file
|
@ -0,0 +1,164 @@
|
|||
|
||||
AUDF0 = $d200
|
||||
AUDC0 = $d201
|
||||
AUDCTL = $d208
|
||||
|
||||
.data
|
||||
|
||||
Chan0dur: .res 4 ; current note duration channel 0
|
||||
Chan0note: .res 4 ; current note pitch channel 0
|
||||
Chan0duty: .res 4 ; current duty bits channel 0
|
||||
DurationTimer: .res 1 ; duration until next cmd
|
||||
CurChannel: .res 1 ; next channel to add note
|
||||
Volume: .res 1 ; initial volume of note (0-31)
|
||||
|
||||
; set_irq() saves/restores entire zeropage segment
|
||||
; which we don't want!
|
||||
; so we have to set this with an equate
|
||||
SongPtr = $fe
|
||||
;.segment "EXTZP"
|
||||
;SongPtr: .res 2 ; ptr to next song byte
|
||||
|
||||
.code
|
||||
|
||||
; Update channel pitch in AUDF0
|
||||
; 8-bit rotation of duty cycle bits
|
||||
.export _music_duty
|
||||
_music_duty:
|
||||
ldx #3
|
||||
ldy #0
|
||||
@loop:
|
||||
lda Chan0dur,x
|
||||
beq :++
|
||||
lda Chan0duty,x
|
||||
asl
|
||||
bcc :+
|
||||
ora #1
|
||||
: sta Chan0duty,x
|
||||
lda Chan0note,x
|
||||
beq :+
|
||||
; If next bit is set, add 1 to AUDF0
|
||||
adc #0
|
||||
sta AUDF0,y
|
||||
:
|
||||
iny
|
||||
iny
|
||||
dex
|
||||
bpl @loop
|
||||
rts
|
||||
|
||||
; Decrement the volumes for each channel
|
||||
.export _music_tick
|
||||
_music_tick:
|
||||
ldx #3
|
||||
ldy #0
|
||||
@loop1:
|
||||
lda Chan0dur,x
|
||||
beq :+
|
||||
lsr
|
||||
ora #$a0
|
||||
sta AUDC0,y
|
||||
dec Chan0dur,x
|
||||
:
|
||||
iny
|
||||
iny
|
||||
dex
|
||||
bpl @loop1
|
||||
|
||||
; Also decrement next-note timer, fetch next note
|
||||
lda DurationTimer
|
||||
bmi @Done
|
||||
beq @NextData
|
||||
dec DurationTimer
|
||||
rts
|
||||
|
||||
; Timer ran out, so fetch next note
|
||||
@NextData:
|
||||
ldx #0
|
||||
lda (SongPtr,x)
|
||||
bmi @LoadDuration
|
||||
; < $80, play next note
|
||||
ldx CurChannel ; next channel
|
||||
tay
|
||||
jsr music_do_note
|
||||
inx
|
||||
txa
|
||||
and #3
|
||||
sta CurChannel ; inc next channel
|
||||
jsr @IncDataPtr
|
||||
jmp @NextData
|
||||
; >= $80, load next duration
|
||||
@LoadDuration:
|
||||
cmp #$ff ; $ff = end of song
|
||||
bne @NoResetTrack
|
||||
sta DurationTimer
|
||||
jmp music_done
|
||||
@NoResetTrack:
|
||||
and #$7f
|
||||
; asl
|
||||
sta DurationTimer ; store duration * 2
|
||||
@IncDataPtr:
|
||||
; increment song pointer
|
||||
inc SongPtr
|
||||
bne @Done
|
||||
inc SongPtr+1
|
||||
@Done:
|
||||
rts
|
||||
|
||||
music_do_note:
|
||||
; Play a note
|
||||
; X = channel (0,1)
|
||||
; Y = note index (0-63)
|
||||
lda FREQZ,y
|
||||
sta Chan0note,x
|
||||
lda DUTYZ,y
|
||||
sta Chan0duty,x
|
||||
lda Volume
|
||||
sta Chan0dur,x
|
||||
rts
|
||||
|
||||
music_done:
|
||||
rts
|
||||
|
||||
.export _music_start
|
||||
_music_start:
|
||||
sta SongPtr
|
||||
stx SongPtr+1
|
||||
lda #24
|
||||
sta Volume
|
||||
lda #0
|
||||
sta DurationTimer
|
||||
sta CurChannel
|
||||
ldx #3
|
||||
: sta Chan0dur,x
|
||||
dex
|
||||
bpl :-
|
||||
lda #$01
|
||||
sta AUDCTL
|
||||
rts
|
||||
|
||||
.export _music_get_ptr
|
||||
_music_get_ptr:
|
||||
lda SongPtr
|
||||
ldx SongPtr+1
|
||||
rts
|
||||
|
||||
.export _music_is_done
|
||||
_music_is_done:
|
||||
ldx #0
|
||||
lda (SongPtr,x)
|
||||
cmp #$ff
|
||||
php
|
||||
pla
|
||||
lsr
|
||||
and #1
|
||||
rts
|
||||
|
||||
; Table of AUDF base values for each note
|
||||
FREQZ:
|
||||
.byte 254, 254, 254, 255, 240, 227, 214, 202, 190, 180, 169, 160, 151, 142, 134, 127, 119, 113, 106, 100, 94, 89, 84, 79, 75, 70, 66, 63, 59, 56, 52, 49, 47, 44, 41, 39, 37, 34, 32, 31, 29, 27, 25, 24, 23, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7
|
||||
|
||||
; Table of duty-cycle bits for each note
|
||||
DUTYZ:
|
||||
.byte 0, 0, 0, 0, 181, 1, 17, 1, 219, 0, 239, 17, 17, 181, 181, 0, 239, 0, 181, 181, 239, 85, 73, 181, 1, 239, 219, 0, 73, 0, 239, 219, 0, 17, 219, 73, 0, 239, 239, 0, 17, 85, 239, 73, 0, 181, 73, 1, 0, 0, 0, 0, 1, 17, 85, 219, 0, 73, 181, 1, 85, 0, 85, 0
|
||||
|
45
presets/atari8-800/testmusic.c
Normal file
45
presets/atari8-800/testmusic.c
Normal file
File diff suppressed because one or more lines are too long
80
presets/c64/23matches.c
Normal file
80
presets/c64/23matches.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
|
||||
#include "common.h"
|
||||
#include <cbm_petscii_charmap.h>
|
||||
|
||||
int matches; // number of matches remaining
|
||||
int take; // # of matches to take on this turn
|
||||
|
||||
void print_matches() {
|
||||
printf("\nThere are %d matches left.\n", matches);
|
||||
}
|
||||
|
||||
void human_moves() {
|
||||
print_matches();
|
||||
// loop until we get a valid move
|
||||
while (1) {
|
||||
printf("\n>> Your turn. Take 1, 2, or 3 matches?");
|
||||
// did we get exactly one input value?
|
||||
if (scanf("%d", &take) == 1) {
|
||||
// is it between 1 and 3?
|
||||
if (take >= 1 && take <= 3) {
|
||||
// are there not enough matches?
|
||||
if (take > matches) {
|
||||
printf("Not enough matches! Try again.\n");
|
||||
continue; // go back to start of loop
|
||||
} else {
|
||||
// take the appropriate number of matches
|
||||
printf("You took %d matches.\n", take);
|
||||
matches -= take;
|
||||
break; // break out of loop
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("Bad input! Type a number from 1 to 3.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void computer_moves() {
|
||||
print_matches();
|
||||
// simple AI: hard coded if 1-4 matches left
|
||||
// otherwise take random number from 1 to 3
|
||||
switch (matches) {
|
||||
case 1: take = 1; break;
|
||||
case 2: take = 1; break;
|
||||
case 3: take = 2; break;
|
||||
case 4: take = 3; break;
|
||||
default: take = (rand() % 3) + 1; break;
|
||||
}
|
||||
printf("\n<< My turn. I'll take %d matches.\n", take);
|
||||
matches -= take;
|
||||
}
|
||||
|
||||
void play_game(void) {
|
||||
printf(
|
||||
"When it is your turn, you may take\n"
|
||||
"1, 2 or 3 matches. I will do the same.\n\n"
|
||||
"Whoever takes the last match loses.\n");
|
||||
|
||||
matches = 23;
|
||||
// loop until no more matches
|
||||
while (matches > 0) {
|
||||
// move human, check if they lost
|
||||
human_moves();
|
||||
if (matches == 0) {
|
||||
printf("You lose, turkey!\nBetter luck next time.\n");
|
||||
break;
|
||||
}
|
||||
// move computer, check if they lost
|
||||
computer_moves();
|
||||
if (matches == 0) {
|
||||
printf("I lost! You must be good!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
clrscr();
|
||||
printf("*** 23 MATCHES ***\n\n");
|
||||
play_game();
|
||||
}
|
BIN
presets/c64/badspacerobots-c64.multi.bin
Normal file
BIN
presets/c64/badspacerobots-c64.multi.bin
Normal file
Binary file not shown.
7
presets/c64/basicheader.acme
Normal file
7
presets/c64/basicheader.acme
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
* = $0801
|
||||
!word Start
|
||||
!byte $00,$00,$9e
|
||||
!text "2066"
|
||||
!byte $00,$00,$00
|
||||
* = $0812
|
|
@ -5,6 +5,6 @@
|
|||
.org $0801 ; start of BASIC program
|
||||
|
||||
.word BASIC_END, 10 ; Next line and current line number
|
||||
.byte $9e," 2064",0 ; SYS 2064
|
||||
.byte $9e," 2062",0 ; SYS 2062
|
||||
BASIC_END:
|
||||
.word 0 ; End of program
|
||||
|
|
|
@ -2,12 +2,19 @@
|
|||
#include "common.h"
|
||||
|
||||
word bcd_add(word a, word b) {
|
||||
register word c, d; // intermediate values
|
||||
c = a + 0x0666; // add 6 to each BCD digit
|
||||
d = c ^ b; // sum without carry propagation
|
||||
c += b; // provisional sum
|
||||
d = ~(c ^ d) & 0x1110; // just the BCD carry bits
|
||||
d = (d >> 2) | (d >> 3); // correction
|
||||
return c - d; // corrected BCD sum
|
||||
asm("sed");
|
||||
a += b;
|
||||
asm("cld");
|
||||
return a;
|
||||
}
|
||||
|
||||
void draw_bcd_word(word address, word bcd) {
|
||||
byte i;
|
||||
address += 4;
|
||||
for (i=0; i<4; i++) {
|
||||
POKE(address, (bcd & 0b1111) + '0');
|
||||
address--;
|
||||
bcd >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
|
||||
/* add two BCD numbers */
|
||||
unsigned int bcd_add(unsigned int a, unsigned int b);
|
||||
unsigned int bcd_add2(unsigned int a, unsigned int b);
|
||||
|
||||
/* print a 16-bit BCD to a specific address */
|
||||
void draw_bcd_word(word address, word bcd_value);
|
||||
|
||||
|
|
49
presets/c64/c64-sid.cfg
Normal file
49
presets/c64/c64-sid.cfg
Normal file
|
@ -0,0 +1,49 @@
|
|||
FEATURES {
|
||||
STARTADDRESS: default = $0801;
|
||||
}
|
||||
SYMBOLS {
|
||||
__LOADADDR__: type = import;
|
||||
__EXEHDR__: type = import;
|
||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||
__HIMEM__: type = weak, value = $8000;
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", define = yes, start = $0002, size = $001A;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||
LOWMAIN: file = %O, define = yes, start = __HEADER_LAST__, size = $1000 - __HEADER_LAST__, fill = yes;
|
||||
SIDFILE: file = %O, define = yes, start = $1000, size = $1000, fill = yes;
|
||||
MAIN: file = %O, define = yes, start = $2000, size = __HIMEM__ - $2000;
|
||||
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
|
||||
VICBANK: file = %O, start = $8000, size = $4000;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = LOWMAIN, type = ro;
|
||||
LOWCODE: load = LOWMAIN, type = ro, optional = yes;
|
||||
SIDFILE: load = SIDFILE, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = ro;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
INIT: load = MAIN, type = rw;
|
||||
ONCE: load = MAIN, type = ro, define = yes;
|
||||
BSS: load = BSS, type = bss, define = yes;
|
||||
VICBANK: load = MAIN, type = ro, optional = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
segment = RODATA;
|
||||
CONDES: type = interruptor,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__,
|
||||
segment = RODATA,
|
||||
import = __CALLIRQ__;
|
||||
}
|
127
presets/c64/c64.wiz
Normal file
127
presets/c64/c64.wiz
Normal file
|
@ -0,0 +1,127 @@
|
|||
|
||||
struct CoordXY {
|
||||
x : u8,
|
||||
y : u8
|
||||
}
|
||||
|
||||
struct SIDVoice {
|
||||
freq : u16, /* Frequency */
|
||||
pw : u16, /* Pulse width */
|
||||
ctrl : u16, /* Control register */
|
||||
ad : u16, /* Attack/decay */
|
||||
sr : u16 /* Sustain/release */
|
||||
}
|
||||
|
||||
typealias SpriteData : [u8; 64];
|
||||
|
||||
union VICBank {
|
||||
spritedata : [SpriteData; 256],
|
||||
data : [u8; 0x4000]
|
||||
}
|
||||
|
||||
namespace c64 {
|
||||
extern var colorram @ 0xD800 : [u8; 0x400];
|
||||
|
||||
namespace color {
|
||||
let BLACK = 0x00;
|
||||
let WHITE = 0x01;
|
||||
let RED = 0x02;
|
||||
let CYAN = 0x03;
|
||||
let PURPLE = 0x04;
|
||||
let GREEN = 0x05;
|
||||
let BLUE = 0x06;
|
||||
let YELLOW = 0x07;
|
||||
let ORANGE = 0x08;
|
||||
let BROWN = 0x09;
|
||||
let LIGHTRED = 0x0A;
|
||||
let GRAY1 = 0x0B;
|
||||
let GRAY2 = 0x0C;
|
||||
let LIGHTGREEN = 0x0D;
|
||||
let LIGHTBLUE = 0x0E;
|
||||
let GRAY3 = 0x0F;
|
||||
}
|
||||
|
||||
namespace vic {
|
||||
namespace sprite {
|
||||
extern var pos @ 0xD000 : [CoordXY; 8];
|
||||
extern var coord @ 0xD000 : [u8; 16];
|
||||
extern var hi_x @ 0xD010 : u8;
|
||||
extern var enable @ 0xD015 : u8;
|
||||
extern var expand_y @ 0xD017 : u8;
|
||||
extern var priority @ 0xD01B : u8;
|
||||
extern var multicolor @ 0xD01C : u8;
|
||||
extern var expand_x @ 0xD01D : u8;
|
||||
extern var coll @ 0xD01E : u8;
|
||||
extern var coll_bg @ 0xD01F : u8;
|
||||
extern var mcolor @ 0xD025 : [u8; 2];
|
||||
extern var color @ 0xD027 : [u8; 8];
|
||||
}
|
||||
extern var control1 @ 0xD011 : u8;
|
||||
extern var rasterline @ 0xD012 : u8;
|
||||
extern var lightpen @ 0xD013 : CoordXY;
|
||||
extern var control2 @ 0xD016 : u8;
|
||||
extern var mem @ 0xD018 : u8;
|
||||
extern var irr @ 0xD019 : u8;
|
||||
extern var imr @ 0xD01A : u8;
|
||||
extern var bordercolor @ 0xD020 : u8;
|
||||
extern var bgcolor @ 0xD021 : [u8; 4];
|
||||
}
|
||||
|
||||
namespace sid {
|
||||
extern writeonly v1 @ 0xd400 : [SIDVoice; 3];
|
||||
|
||||
extern writeonly flt_freq @ 0xd415 : u16;/* Filter frequency */
|
||||
extern writeonly flt_ctrl @ 0xd417 : u8; /* Filter control register */
|
||||
extern writeonly amp @ 0xd418 : u8; /* Amplitude */
|
||||
extern writeonly ad1 @ 0xd419 : u8; /* A/D converter 1 */
|
||||
extern writeonly ad2 @ 0xd41a : u8; /* A/D converter 2 */
|
||||
extern writeonly noise @ 0xd41b : u8; /* Noise generator */
|
||||
extern const read3 @ 0xd41c : u8; /* Value of voice 3 */
|
||||
}
|
||||
|
||||
namespace cia1 {
|
||||
// CIA1 Registers
|
||||
extern writeonly port_a @ 0xDC00 : u8;
|
||||
extern const port_b @ 0xDC01 : u8;
|
||||
extern writeonly data_direction_a @ 0xDC02 : u8;
|
||||
extern writeonly data_direction_b @ 0xDC03 : u8;
|
||||
extern const timer_a_lo @ 0xDC04 : u8;
|
||||
extern const timer_a_hi @ 0xDC05 : u8;
|
||||
extern const timer_b_lo @ 0xDC06 : u8;
|
||||
extern const timer_b_hi @ 0xDC07 : u8;
|
||||
extern const sdr @ 0xDC0C : u8;
|
||||
extern const icr @ 0xDC0D : u8;
|
||||
extern const cra @ 0xDC0E : u8;
|
||||
extern const crb @ 0xDC0F : u8;
|
||||
}
|
||||
|
||||
namespace cia2 {
|
||||
// CIA2 Registers
|
||||
extern writeonly port_a @ 0xDD00 : u8;
|
||||
extern const port_b @ 0xDD01 : u8;
|
||||
extern writeonly data_direction_a @ 0xDD02 : u8;
|
||||
extern writeonly data_direction_b @ 0xDD03 : u8;
|
||||
extern const timer_a_lo @ 0xDD04 : u8;
|
||||
extern const timer_a_hi @ 0xDD05 : u8;
|
||||
extern const timer_b_lo @ 0xDD06 : u8;
|
||||
extern const timer_b_hi @ 0xDD07 : u8;
|
||||
extern const sdr @ 0xDD0C : u8;
|
||||
extern const icr @ 0xDD0D : u8;
|
||||
extern const cra @ 0xDD0E : u8;
|
||||
extern const crb @ 0xDD0F : u8;
|
||||
}
|
||||
|
||||
namespace kernal {
|
||||
let ioinit = 0xFDA3 as func;
|
||||
let rantam = 0xFD50 as func;
|
||||
let restor = 0xFD15 as func;
|
||||
let cint = 0xFF5B as func;
|
||||
let scnkey = 0xEA87 as func;
|
||||
let chrin = 0xF157 as func : u8 in a;
|
||||
let chrout = 0xF1CA as func(char : u8 in a);
|
||||
let screen = 0xE505 as func : u16 in xy;
|
||||
let plot_save = 0xE50A as func(save : bool in carry) : u16 in xy;
|
||||
let plot_restore = 0xE50A as func(x : u8 in x, y : u8 in y, save : bool in carry);
|
||||
}
|
||||
}
|
||||
|
30
presets/c64/cartheader.acme
Normal file
30
presets/c64/cartheader.acme
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
* = $7ffe
|
||||
; 2-byte load address for ROM image
|
||||
!word $8000
|
||||
; http://swut.net/c64cart-howto.html
|
||||
; https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image
|
||||
!word CartKReset ; cold start vector
|
||||
!word CartWStart ; warm start vector
|
||||
!byte $c3, $c2, $cd, $38, $30 ; "CBM80"
|
||||
CartKReset
|
||||
STX $D016 ; Turn on VIC for PAL / NTSC check
|
||||
JSR $FDA3 ; IOINIT - Init CIA chips
|
||||
JSR $FD50 ; RANTAM - Clear/test system RAM
|
||||
JSR $FD15 ; RESTOR - Init KERNAL RAM vectors
|
||||
JSR $FF5B ; CINT - Init VIC and screen editor
|
||||
CLI ; Re-enable IRQ interrupts
|
||||
CartBReset
|
||||
; init BASIC?
|
||||
!ifdef CART_INIT_BASIC {
|
||||
JSR $E453 ; Init BASIC RAM vectors
|
||||
JSR $E3BF ; Main BASIC RAM Init routine
|
||||
JSR $E422 ; Power-up message / NEW command
|
||||
LDX #$FB
|
||||
TXS ; Reduce stack pointer for BASIC
|
||||
; don't init BASIC, just NOP
|
||||
} else {
|
||||
!fill 12, $ea ; nop
|
||||
}
|
||||
CartWStart
|
||||
; should be * = $x025
|
|
@ -1,24 +1,31 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <c64.h>
|
||||
#include <joystick.h>
|
||||
|
||||
#include "bcd.h"
|
||||
//#link "bcd.c"
|
||||
//#resource "c64-sid.cfg"
|
||||
#define CFGFILE c64-sid.cfg
|
||||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include "sidplaysfx.h"
|
||||
//#resource "sidmusic1.bin"
|
||||
//#link "sidplaysfx.ca65"
|
||||
|
||||
#include "rasterirq.h"
|
||||
//#link "rasterirq.ca65"
|
||||
|
||||
#include "bcd.h"
|
||||
//#link "bcd.c"
|
||||
|
||||
#include "scrolling.h"
|
||||
//#link "scrolling.c"
|
||||
|
||||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
// indices of sound effects (0..3)
|
||||
typedef enum { SND_START, SND_HIT, SND_COIN, SND_JUMP } SFXIndex;
|
||||
// indices of sound effects
|
||||
#define SND_JUMP 0
|
||||
#define SND_HIT 2
|
||||
#define SND_COIN 1
|
||||
#define SND_FALL 3
|
||||
|
||||
///// DEFINES
|
||||
|
||||
|
@ -62,7 +69,7 @@ const byte ITEM_CHARS[3][4] = {
|
|||
#define NUM_SPRITE_PATTERNS 13
|
||||
|
||||
/*{w:12,h:21,bpp:2,brev:1,count:13,aspect:2}*/
|
||||
const char SPRITE_DATA[NUM_SPRITE_PATTERNS][3*21] = {
|
||||
const char SPRITE_DATA[NUM_SPRITE_PATTERNS][64] = {
|
||||
// left direction
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0xEA,0x00,
|
||||
|
@ -372,8 +379,9 @@ void refresh_floor(byte floor) {
|
|||
|
||||
byte explode_timer = 0;
|
||||
|
||||
#define SPRITE_SHAPE_FIRST 192
|
||||
#define SPRITE_XPLODE 7
|
||||
#define SHAPE_XPLODE0 (32+10)
|
||||
#define SHAPE_XPLODE0 (SPRITE_SHAPE_FIRST+10)
|
||||
#define NUM_XPLODE_SHAPES 3
|
||||
|
||||
void explode(int x, byte y) {
|
||||
|
@ -446,7 +454,7 @@ void draw_actor(byte i) {
|
|||
a->onscreen = 0;
|
||||
return; // offscreen vertically
|
||||
}
|
||||
name = 32 + (a->state - WALKING);
|
||||
name = SPRITE_SHAPE_FIRST + (a->state - WALKING);
|
||||
switch (a->state) {
|
||||
case INACTIVE:
|
||||
a->onscreen = 0;
|
||||
|
@ -469,7 +477,7 @@ void draw_actor(byte i) {
|
|||
void refresh_actors() {
|
||||
byte i;
|
||||
yscroll = BOTTOM_Y + scroll_fine_y + (START_ORIGIN_Y - origin_y)*8;
|
||||
sprite_clear();
|
||||
sprshad.spr_ena = 0; // make all sprites invisible
|
||||
for (i=0; i<MAX_ACTORS; i++)
|
||||
draw_actor(i);
|
||||
animate_explosion();
|
||||
|
@ -541,6 +549,7 @@ void move_actor(struct Actor* actor, byte joystick, bool scroll) {
|
|||
actor->yvel = 15;
|
||||
if (joystick & JOY_LEFT_MASK) actor->xvel = -1;
|
||||
if (joystick & JOY_RIGHT_MASK) actor->xvel = 1;
|
||||
if (scroll) sid_sfx(SND_JUMP);
|
||||
} else if (joystick & JOY_LEFT_MASK) {
|
||||
actor->x--;
|
||||
actor->dir = 1;
|
||||
|
@ -605,6 +614,7 @@ void move_actor(struct Actor* actor, byte joystick, bool scroll) {
|
|||
if (actor->state == WALKING &&
|
||||
is_in_gap(actor->x, floors[actor->level].gap)) {
|
||||
fall_down(actor);
|
||||
if (scroll) sid_sfx(SND_FALL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,11 +636,11 @@ void pickup_object(Actor* actor) {
|
|||
if (objtype == ITEM_MINE) {
|
||||
// we hit a mine, fall down
|
||||
fall_down(actor);
|
||||
//sfx_play(SND_HIT,0);
|
||||
sid_sfx(SND_HIT);
|
||||
} else {
|
||||
// we picked up an object, add to score
|
||||
//score = bcd_add(score, 1);
|
||||
//sfx_play(SND_COIN,0);
|
||||
sid_sfx(SND_COIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -664,7 +674,7 @@ bool check_collision(Actor* a) {
|
|||
|
||||
///
|
||||
|
||||
void draw_blimp(struct cvu_sprite* sprite) {
|
||||
void draw_blimp() {
|
||||
/*
|
||||
sprite->name = 48;
|
||||
wait_vblank();
|
||||
|
@ -680,7 +690,6 @@ void draw_blimp(struct cvu_sprite* sprite) {
|
|||
cvu_set_sprite(SPRITES, 31, sprite);
|
||||
refresh_actors();
|
||||
*/
|
||||
sprite=sprite;
|
||||
}
|
||||
|
||||
void blimp_pickup_scene() {
|
||||
|
@ -718,6 +727,9 @@ void play_scene() {
|
|||
create_actors_on_floor(2);
|
||||
refresh_screen();
|
||||
|
||||
sid_init(1);
|
||||
sid_start();
|
||||
|
||||
while (actors[0].level != MAX_FLOORS-1) {
|
||||
refresh_actors();
|
||||
move_player();
|
||||
|
@ -729,6 +741,7 @@ void play_scene() {
|
|||
if (VIC.spr_coll & 0x01) {
|
||||
if (actors[0].level > 0 && check_collision(&actors[0])) {
|
||||
fall_down(&actors[0]);
|
||||
sid_sfx(SND_HIT);
|
||||
}
|
||||
}
|
||||
if (swap_needed) sprite_update(hidbuf);
|
||||
|
@ -740,26 +753,34 @@ void play_scene() {
|
|||
blimp_pickup_scene();
|
||||
}
|
||||
|
||||
// main display list
|
||||
void game_displaylist(void) {
|
||||
// VIC.bordercolor = 2;
|
||||
sid_update();
|
||||
// VIC.bordercolor = 0;
|
||||
// DLIST_NEXT(42);
|
||||
// VIC.bordercolor = 3;
|
||||
DLIST_RESTART(20);
|
||||
}
|
||||
|
||||
// main program
|
||||
void main() {
|
||||
byte i;
|
||||
|
||||
// set up scrolling
|
||||
scroll_setup();
|
||||
// set up sprites
|
||||
sprite_clear();
|
||||
for (i=0; i<NUM_SPRITE_PATTERNS; i++) {
|
||||
sprite_shape(hidbuf, 32+i, SPRITE_DATA[i]);
|
||||
}
|
||||
sprite_set_shapes(SPRITE_DATA, SPRITE_SHAPE_FIRST, NUM_SPRITE_PATTERNS);
|
||||
sprshad.spr_mcolor = 0xff;
|
||||
sprshad.spr_mcolor0 = 0x0f;
|
||||
sprshad.spr_mcolor1 = 0x00;
|
||||
VIC.spr_mcolor0 = 0x0f;
|
||||
VIC.spr_mcolor1 = 0x00;
|
||||
// select character set 2
|
||||
VIC.addr = 0x15;
|
||||
// start scrolling @ bottom of level
|
||||
origin_y = START_ORIGIN_Y;
|
||||
// install joystick
|
||||
joy_install (joy_static_stddrv);
|
||||
// setup display list
|
||||
DLIST_SETUP(game_displaylist);
|
||||
// main game loop
|
||||
while (1) {
|
||||
make_floors();
|
||||
|
|
|
@ -1,10 +1,40 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
void raster_wait(unsigned char line) {
|
||||
void raster_wait(byte line) {
|
||||
while (VIC.rasterline < line) ;
|
||||
}
|
||||
|
||||
void wait_vblank(void) {
|
||||
raster_wait(255);
|
||||
raster_wait(250);
|
||||
}
|
||||
|
||||
static byte VIC_BANK_PAGE[4] = {
|
||||
0xc0, 0x80, 0x40, 0x00
|
||||
};
|
||||
|
||||
char* get_vic_bank_start() {
|
||||
return (char*)(VIC_BANK_PAGE[CIA2.pra & 3] << 8);
|
||||
}
|
||||
|
||||
char* get_screen_memory() {
|
||||
return ((VIC.addr & 0xf0) << 6) + get_vic_bank_start();
|
||||
}
|
||||
|
||||
#ifdef __CC65__
|
||||
char __fastcall__ poll_keyboard() {
|
||||
asm("jmp $f142");
|
||||
return __A__;
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_raster_irq(char scanline) {
|
||||
// deactivate CIA interrupts (keyboard, etc)
|
||||
CIA1.icr = 0x7f;
|
||||
// set raster line for interrupt
|
||||
VIC.ctrl1 &= 0x7f; // clear raster line bit 8
|
||||
VIC.rasterline = scanline;
|
||||
// activate VIC raster interrupts
|
||||
VIC.imr = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,141 @@
|
|||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#include <c64.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <peekpoke.h>
|
||||
#include <string.h>
|
||||
#include <c64.h>
|
||||
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t word;
|
||||
typedef int8_t sbyte;
|
||||
typedef enum { false, true } bool;
|
||||
#ifdef __CC65__
|
||||
#include <conio.h>
|
||||
#include <joystick.h>
|
||||
#endif
|
||||
|
||||
#define COLS 40
|
||||
#define ROWS 25
|
||||
typedef uint8_t byte; // 8-bit unsigned
|
||||
typedef int8_t sbyte; // 8-bit signed
|
||||
typedef uint16_t word; // 16-bit unsigned
|
||||
typedef enum { false, true } bool; // boolean
|
||||
|
||||
void raster_wait(unsigned char line);
|
||||
void wait_vblank(void);
|
||||
#define COLS 40 // total # of columns
|
||||
#define ROWS 25 // total # of rows
|
||||
|
||||
|
||||
///// MACROS /////
|
||||
|
||||
// VIC Control Register 1 Flags
|
||||
#define VIC_CTRL1_RST8 0x80 // Bit 8 of RASTER (read) or raster line interrupt set (write)
|
||||
#define VIC_CTRL1_ECM 0x40 // Extended Color Mode
|
||||
#define VIC_CTRL1_BMM 0x20 // Bitmap Mode
|
||||
#define VIC_CTRL1_DEN 0x10 // Display Enable
|
||||
#define VIC_CTRL1_RSEL 0x08 // Row Select (25 or 24 rows)
|
||||
#define VIC_CTRL1_YSCROLL_MASK 0x07 // Vertical Fine Scrolling
|
||||
|
||||
// VIC Control Register 2 Flags
|
||||
#define VIC_CTRL2_RES 0x20 // Chip reset
|
||||
#define VIC_CTRL2_MCM 0x10 // Multicolor Mode Enable
|
||||
#define VIC_CTRL2_CSEL 0x08 // Column Select (40 or 38 columns)
|
||||
#define VIC_CTRL2_XSCROLL_MASK 0x07 // Horizontal Fine Scrolling
|
||||
|
||||
// VIC Memory Control Register Flags
|
||||
#define VIC_ADDR_VM_MASK 0xf0 // Video Matrix Base Address Mask (character data)
|
||||
#define VIC_ADDR_CB_MASK 0x0e // Character Bank Base Address Mask (screen memory)
|
||||
|
||||
// VIC Interrupt Register Flags
|
||||
#define VIC_IRR_IRQ 0x80 // Interrupt Request
|
||||
#define VIC_IRR_ILP 0x08 // Light Pen Interrupt
|
||||
#define VIC_IRR_IMMC 0x04 // Sprite-Sprite Collision Interrupt
|
||||
#define VIC_IRR_IMBC 0x02 // Sprite-Background Collision Interrupt
|
||||
#define VIC_IRR_IRST 0x01 // Raster Line Interrupt
|
||||
|
||||
// VIC Interrupt Mask Register Flags
|
||||
#define VIC_IMR_ELP 0x08 // Enable Light Pen Interrupt
|
||||
#define VIC_IMR_EMMC 0x04 // Enable Sprite-Sprite Collision Interrupt
|
||||
#define VIC_IMR_EMBC 0x02 // Enable Sprite-Background Collision Interrupt
|
||||
#define VIC_IMR_ERST 0x01 // Enable Raster Interrupt
|
||||
|
||||
// lookup screen address macro
|
||||
#define SCRNADR(base,col,row) ((base)+(col)+(row)*40)
|
||||
|
||||
// default screen base address on startup
|
||||
#define DEFAULT_SCREEN ((void*)0x400)
|
||||
|
||||
// is raster line > 255?
|
||||
#define RASTER_HIBIT (VIC.ctrl1 & 0x80)
|
||||
|
||||
// set VIC Bank (given the start address)
|
||||
#define SET_VIC_BANK(_addr) \
|
||||
CIA2.pra = (CIA2.pra & ~3) | (((((_addr)>>8)&0xc0)>>6)^3);
|
||||
|
||||
// set VIC character memory (given the start address)
|
||||
#define SET_VIC_BITMAP(_addr) \
|
||||
VIC.addr = (VIC.addr & 0b11110001) | ((((_addr)>>8)&0x38)>>2);
|
||||
|
||||
// set VIC screen memory (given the start address)
|
||||
#define SET_VIC_SCREEN(_addr) \
|
||||
VIC.addr = (VIC.addr & 0b00001111) | ((((_addr)>>8)&0x3c)<<2);
|
||||
|
||||
// set scrolling registers
|
||||
#define SET_SCROLL_Y(_y) \
|
||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | (_y & 7);
|
||||
|
||||
#define SET_SCROLL_X(_x) \
|
||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | (_x & 7);
|
||||
|
||||
|
||||
// enable RAM from 0xa000-0xffff, disable interrupts
|
||||
#define ENABLE_HIMEM() \
|
||||
asm("php"); \
|
||||
asm("sei"); \
|
||||
POKE(1, PEEK(1) & ~0b111);
|
||||
|
||||
// enable ROM and interrupts
|
||||
#define DISABLE_HIMEM() \
|
||||
POKE(1, PEEK(1) | 0b111); \
|
||||
asm("plp");
|
||||
|
||||
///// FUNCTIONS /////
|
||||
|
||||
// wait until specific raster line
|
||||
void raster_wait(byte line);
|
||||
|
||||
// wait until end of frame
|
||||
void wait_vblank();
|
||||
|
||||
// get current VIC bank start address
|
||||
char* get_vic_bank_start();
|
||||
|
||||
// get current screen memory address
|
||||
char* get_screen_memory();
|
||||
|
||||
// read joystick fast
|
||||
#define READ_STICK(index) ~PEEK(0xdc01-(index))
|
||||
|
||||
#define STICK_UP(joy) ((joy & 0x1) != 0)
|
||||
#define STICK_DOWN(joy) ((joy & 0x2) != 0)
|
||||
#define STICK_LEFT(joy) ((joy & 0x4) != 0)
|
||||
#define STICK_RIGHT(joy) ((joy & 0x8) != 0)
|
||||
#define STICK_BUTTON(joy) ((joy & 0x10) != 0)
|
||||
#define STICK_MOVED(joy) ((joy & 0x1f) != 0)
|
||||
|
||||
#ifdef __CC65__
|
||||
// return key in buffer, or 0 if none (BIOS call)
|
||||
char __fastcall__ poll_keyboard();
|
||||
#endif
|
||||
|
||||
#ifndef __CC65__
|
||||
inline void clrscr() {
|
||||
__asm__ volatile ("jsr $E544" : : : "a","x","y"); // regs clobbered
|
||||
}
|
||||
inline void waitvsync() {
|
||||
raster_wait(255);
|
||||
}
|
||||
#endif
|
||||
|
||||
// for use with set_irq()
|
||||
// sets up the VIC to send raster interrupts
|
||||
// and disables CIA interrupts
|
||||
void set_raster_irq(char scanline);
|
||||
|
||||
#endif
|
||||
|
|
638
presets/c64/fullscrollgame.c
Normal file
638
presets/c64/fullscrollgame.c
Normal file
|
@ -0,0 +1,638 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include <cbm_petscii_charmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <joystick.h>
|
||||
|
||||
//#resource "c64-sid.cfg"
|
||||
#define CFGFILE c64-sid.cfg
|
||||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include "scrolling.h"
|
||||
//#link "scrolling2.c"
|
||||
|
||||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
//#link "level2.ca65"
|
||||
|
||||
#define CAMERA_OFFSET_X 158
|
||||
#define CAMERA_OFFSET_Y 120
|
||||
#define CAMERA_MAX_DX 12
|
||||
#define CAMERA_MAX_DY 8
|
||||
|
||||
#define MAX_ACTORS 8
|
||||
#define ACTOR_OFFSET_X 28
|
||||
#define ACTOR_OFFSET_Y 30
|
||||
#define ACTOR_WIDTH 24
|
||||
#define ACTOR_HEIGHT 21
|
||||
|
||||
#define JUMP_VELOCITY -36
|
||||
#define MAX_FALL_VELOCITY 64
|
||||
#define MAX_HORIZ_VELOCITY 16
|
||||
|
||||
#define MAP_COLS 16
|
||||
#define MAP_ROWS 16
|
||||
|
||||
#define DEFAULT_CHAR chartileset_data[16]
|
||||
#define DEFAULT_COLOR chartileset_colour_data[1]
|
||||
|
||||
#define FLAG_SOLID 1
|
||||
#define FLAG_PLATFORM 2
|
||||
#define FLAG_LADDER 4
|
||||
|
||||
|
||||
// level map data
|
||||
extern const byte charset_data[];
|
||||
extern const byte charset_attrib_data[];
|
||||
extern const byte chartileset_data[];
|
||||
extern const byte chartileset_colour_data[];
|
||||
extern const byte chartileset_tag_data[];
|
||||
extern const byte map_data[];
|
||||
|
||||
|
||||
static byte framecount;
|
||||
static byte framemask;
|
||||
|
||||
const byte BITMASKS[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
|
||||
|
||||
static byte tileflagmap[MAP_ROWS*MAP_COLS];
|
||||
static byte tileindex;
|
||||
static byte tilechar;
|
||||
|
||||
static bool get_cell_at(byte world_x, byte world_y) {
|
||||
sbyte col = world_x >> 2;
|
||||
sbyte row = world_y >> 2;
|
||||
byte xofs = world_x & 3;
|
||||
byte yofs = world_y & 3;
|
||||
if (col < 0 || col >= MAP_COLS || row < 0 || row >= MAP_ROWS) {
|
||||
return false;
|
||||
} else {
|
||||
tileindex = map_data[col + row * MAP_ROWS];
|
||||
tilechar = chartileset_data[xofs + (yofs + tileindex*4)*4];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
byte compute_tile_flags() {
|
||||
switch (tileindex) {
|
||||
case 3: return FLAG_PLATFORM;
|
||||
case 4: return FLAG_PLATFORM;
|
||||
case 5: return FLAG_SOLID;
|
||||
case 6: return FLAG_LADDER;
|
||||
case 7: return FLAG_PLATFORM | FLAG_LADDER;
|
||||
case 8: return FLAG_SOLID;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
byte get_tile_flags(word world_x, word world_y) {
|
||||
byte tilex = world_x >> 5;
|
||||
byte tiley = world_y >> 5;
|
||||
if (tilex < MAP_COLS && tiley < MAP_ROWS)
|
||||
return tileflagmap[tilex + tiley*MAP_COLS];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void build_tile_flag_map(void) {
|
||||
byte x,y;
|
||||
byte i=0;
|
||||
for (y=0; y<MAP_ROWS; y++) {
|
||||
for (x=0; x<MAP_COLS; x++) {
|
||||
if (get_cell_at(x*4, y*4))
|
||||
tileflagmap[i++] = compute_tile_flags();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_cell(word ofs, byte scrn_x, byte scrn_y) {
|
||||
byte ch, color;
|
||||
if (get_cell_at(scrn_x + origin_x, scrn_y + origin_y)) {
|
||||
ch = tilechar;
|
||||
color = chartileset_colour_data[tileindex];
|
||||
} else {
|
||||
ch = DEFAULT_CHAR;
|
||||
color = DEFAULT_COLOR;
|
||||
}
|
||||
hidbuf[ofs] = ch;
|
||||
colorbuf[ofs] = color;
|
||||
}
|
||||
|
||||
void scroll_draw_column(byte col) {
|
||||
byte y;
|
||||
word ofs = col;
|
||||
for (y=0; y<ROWS; y++) {
|
||||
draw_cell(ofs, col, y);
|
||||
ofs += COLS;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_draw_row(byte row) {
|
||||
byte x;
|
||||
word ofs = row * COLS;
|
||||
for (x=0; x<COLS; x++) {
|
||||
draw_cell(ofs, x, row);
|
||||
++ofs;
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_SPRITE_PATTERNS 13
|
||||
/*{w:12,h:21,bpp:2,brev:1,count:13,aspect:2}*/
|
||||
const char SPRITE_DATA[NUM_SPRITE_PATTERNS][64] = {
|
||||
// left direction
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0xEA,0x00,
|
||||
0x02,0xEA,0x00,0x02,0xEA,0x00,0x02,0xEA,0x00,
|
||||
0x00,0xA8,0x50,0x00,0x15,0x50,0x00,0xAA,0x50,
|
||||
0x00,0xAA,0x50,0x00,0xAA,0x50,0x0A,0xAA,0x50,
|
||||
0x02,0xAA,0x50,0x00,0xFF,0x00,0x00,0xAA,0x00,
|
||||
0x00,0xAA,0x00,0x00,0xA2,0x80,0x00,0xA2,0x80,
|
||||
0x00,0x22,0x80,0x01,0x51,0x40,0x01,0x51,0x40
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0xAA,0x00,
|
||||
0x02,0xAA,0x00,0x22,0xAA,0x00,0x22,0xAA,0x00,
|
||||
0x20,0xA8,0x00,0x28,0x54,0x00,0x2A,0x56,0x80,
|
||||
0x0A,0x56,0xA0,0x02,0x56,0xA0,0x02,0x56,0x20,
|
||||
0x02,0x56,0x20,0x03,0xFF,0x20,0x02,0xAA,0x00,
|
||||
0x02,0x8A,0x00,0x02,0x8A,0x00,0x01,0x4A,0x00,
|
||||
0x05,0x4A,0x00,0x00,0x05,0x00,0x00,0x05,0x40
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0xEA,0x00,
|
||||
0x02,0xEA,0x00,0x02,0xEA,0x00,0x02,0xEA,0x00,
|
||||
0x00,0xA8,0x50,0x00,0x15,0x50,0x00,0xAA,0x50,
|
||||
0x20,0xAA,0x50,0x2A,0xAA,0x50,0x0A,0xAA,0x50,
|
||||
0x00,0xAA,0x50,0x00,0xFF,0x00,0x00,0xAA,0x00,
|
||||
0x00,0xAA,0x00,0x0A,0xA2,0x80,0x0A,0xA2,0x94,
|
||||
0x0A,0x02,0x94,0x15,0x00,0x94,0x15,0x00,0x04
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0xBF,0x80,
|
||||
0x00,0xAE,0x80,0x00,0xAE,0x80,0x00,0xAE,0x80,
|
||||
0x00,0x2A,0x00,0x00,0x15,0x02,0x20,0xAA,0xAA,
|
||||
0x2A,0xBF,0xA8,0x0A,0xAA,0xA0,0x02,0xBF,0x80,
|
||||
0x00,0xAA,0x80,0x00,0xFF,0xC0,0x00,0xAA,0x80,
|
||||
0x00,0xAA,0x80,0x02,0xA2,0xA0,0x02,0x80,0xA0,
|
||||
0x02,0x80,0xA0,0x01,0x40,0x50,0x05,0x40,0x54
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0xEA,0x00,
|
||||
0x02,0xEA,0x00,0x02,0xEA,0x00,0x02,0xEA,0x00,
|
||||
0x00,0xA8,0x50,0x00,0x15,0x50,0x00,0xAA,0x50,
|
||||
0x08,0xAA,0x90,0x0A,0xAA,0xA0,0x02,0xAA,0x60,
|
||||
0x00,0xAA,0x50,0x00,0xFF,0x00,0x00,0xAA,0x00,
|
||||
0x00,0xA2,0x00,0x00,0xA8,0x80,0x00,0x2A,0x80,
|
||||
0x02,0x8A,0x90,0x01,0x40,0x50,0x05,0x41,0x40
|
||||
},
|
||||
// right direction
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0xAB,0x80,
|
||||
0x00,0xAB,0x80,0x00,0xAB,0x80,0x00,0xAB,0x80,
|
||||
0x05,0x2A,0x00,0x05,0x54,0x00,0x05,0xAA,0x00,
|
||||
0x05,0xAA,0x00,0x05,0xAA,0x00,0x05,0xAA,0xA0,
|
||||
0x05,0xAA,0x80,0x00,0xFF,0x00,0x00,0xAA,0x00,
|
||||
0x00,0xAA,0x00,0x02,0x8A,0x00,0x02,0x8A,0x00,
|
||||
0x02,0x88,0x00,0x01,0x45,0x40,0x01,0x45,0x40
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0xAA,0x00,
|
||||
0x02,0xAA,0x00,0x02,0xAA,0x20,0x02,0xAA,0x20,
|
||||
0x00,0xA8,0x20,0x00,0x54,0xA0,0x0A,0x56,0xA0,
|
||||
0x2A,0x56,0x80,0x2A,0x56,0x00,0x22,0x56,0x00,
|
||||
0x22,0x56,0x00,0x23,0xFF,0x00,0x02,0xAA,0x00,
|
||||
0x02,0x8A,0x00,0x02,0x8A,0x00,0x02,0x85,0x00,
|
||||
0x02,0x85,0x40,0x01,0x40,0x00,0x05,0x40,0x00
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0xAB,0x80,
|
||||
0x00,0xAB,0x80,0x00,0xAB,0x80,0x00,0xAB,0x80,
|
||||
0x05,0x2A,0x00,0x05,0x54,0x00,0x05,0xAA,0x00,
|
||||
0x05,0xAA,0x08,0x05,0xAA,0xA8,0x05,0xAA,0xA0,
|
||||
0x05,0xAA,0x00,0x00,0xFF,0x00,0x00,0xAA,0x00,
|
||||
0x00,0xAA,0x00,0x02,0x8A,0xA0,0x16,0x8A,0xA0,
|
||||
0x16,0x80,0xA0,0x16,0x00,0x54,0x10,0x00,0x54
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0xBF,0x80,
|
||||
0x00,0xAE,0x80,0x00,0xAE,0x80,0x00,0xAE,0x80,
|
||||
0x00,0x2A,0x00,0x20,0x15,0x00,0x2A,0xAA,0x82,
|
||||
0x0A,0xBF,0xAA,0x02,0xAA,0xA8,0x00,0xBF,0xA0,
|
||||
0x00,0xAA,0x80,0x00,0xFF,0xC0,0x00,0xAA,0x80,
|
||||
0x00,0xAA,0x80,0x02,0xA2,0xA0,0x02,0x80,0xA0,
|
||||
0x02,0x80,0xA0,0x01,0x40,0x50,0x05,0x40,0x54
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0xAB,0x80,
|
||||
0x00,0xAB,0x80,0x00,0xAB,0x80,0x00,0xAB,0x80,
|
||||
0x05,0x2A,0x00,0x05,0x54,0x00,0x05,0xAA,0x00,
|
||||
0x06,0xAA,0x20,0x0A,0xAA,0xA0,0x09,0xAA,0x80,
|
||||
0x05,0xAA,0x00,0x00,0xFF,0x00,0x00,0xAA,0x00,
|
||||
0x00,0x8A,0x00,0x02,0x2A,0x00,0x02,0xA8,0x00,
|
||||
0x06,0xA2,0x80,0x05,0x01,0x40,0x01,0x41,0x50
|
||||
},
|
||||
// explosion
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,
|
||||
0x00,0x20,0x00,0x08,0x20,0x80,0x02,0x02,0x00,
|
||||
0x00,0x10,0x00,0x00,0x54,0x00,0x00,0x10,0x00,
|
||||
0x02,0x02,0x00,0x08,0x20,0x80,0x00,0x20,0x00,
|
||||
0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0x02,0x00,
|
||||
0x08,0x00,0x80,0x20,0x00,0x20,0x20,0x54,0x20,
|
||||
0x21,0x01,0x20,0x21,0x01,0x20,0x21,0x01,0x20,
|
||||
0x20,0x54,0x20,0x20,0x00,0xA0,0x08,0x00,0x80,
|
||||
0x02,0x02,0x00,0x00,0xA8,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
},
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xA8,0x00,0x02,0x02,0x00,
|
||||
0x08,0x10,0x80,0x08,0x54,0x80,0x08,0x10,0x80,
|
||||
0x02,0x02,0x00,0x00,0xA8,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
},
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
STANDING, JUMPING, CLIMBING
|
||||
} ActorState;
|
||||
|
||||
typedef struct Actor {
|
||||
word xx;
|
||||
word yy;
|
||||
sbyte xvel;
|
||||
sbyte yvel;
|
||||
ActorState state;
|
||||
bool faceleft;
|
||||
} Actor;
|
||||
|
||||
Actor actors[MAX_ACTORS];
|
||||
|
||||
Actor* const player = &actors[0];
|
||||
|
||||
void draw_actor(register Actor* actor, byte index) {
|
||||
byte shape = 240;
|
||||
word xpos = actor->xx + pixofs_x + fine_correct_x + ACTOR_OFFSET_X;
|
||||
word ypos = actor->yy + pixofs_y + fine_correct_y + ACTOR_OFFSET_Y;
|
||||
if (xpos > 320 || ypos > 250) {
|
||||
ypos = 255;
|
||||
}
|
||||
switch (actor->state) {
|
||||
case STANDING:
|
||||
if (actor->xvel && actor->xx & 4) shape += 4;
|
||||
if (!actor->faceleft) shape += 5;
|
||||
break;
|
||||
case JUMPING:
|
||||
shape += 2;
|
||||
if (!actor->faceleft) shape += 5;
|
||||
break;
|
||||
case CLIMBING:
|
||||
shape += 1;
|
||||
if (actor->yy & 2) shape += 5;
|
||||
break;
|
||||
}
|
||||
sprite_draw(index, xpos, ypos, shape);
|
||||
}
|
||||
|
||||
const char velocity_bitmasks[8] = {
|
||||
0b00000000, // 0/8
|
||||
0b00001000, // 1/8
|
||||
0b00100010, // 2/8
|
||||
0b10010010, // 3/8
|
||||
0b01010101, // 4/8
|
||||
0b01110101, // 5/8
|
||||
0b11101110, // 6/8
|
||||
0b11110111, // 7/8
|
||||
// 0b11111111, // 8/8
|
||||
};
|
||||
|
||||
static byte box[4]; // hit box
|
||||
|
||||
/*
|
||||
void actor_set_position(register Actor* actor,
|
||||
word world_x,
|
||||
word world_y,
|
||||
ActorState state) {
|
||||
actor->xx = world_x;
|
||||
actor->yy = world_y;
|
||||
actor->state = state;
|
||||
actor->tileindex = (world_x>>5) | (world_y>>5)*MAP_COLS;
|
||||
}
|
||||
*/
|
||||
|
||||
void move_actor(register Actor* actor,
|
||||
sbyte cmd_dx,
|
||||
sbyte cmd_dy) {
|
||||
word xx,yy;
|
||||
byte flags;
|
||||
sbyte dx = cmd_dx;
|
||||
sbyte dy = cmd_dy;
|
||||
bool state = actor->state;
|
||||
|
||||
xx = actor->xx + dx;
|
||||
yy = actor->yy + dy;
|
||||
// if we are standing, move hit box 1 pixel below our feet
|
||||
if (state == STANDING) {
|
||||
yy += 1 - dy; // cancel out any climbing vertical offset (dy)
|
||||
dy = 0;
|
||||
}
|
||||
// get hit box flags on all 4 corners
|
||||
{
|
||||
box[0] = get_tile_flags(xx, yy-ACTOR_HEIGHT);
|
||||
box[1] = get_tile_flags(xx+ACTOR_WIDTH, yy-ACTOR_HEIGHT);
|
||||
box[2] = get_tile_flags(xx, yy);
|
||||
box[3] = get_tile_flags(xx+ACTOR_WIDTH, yy);
|
||||
// cancel x velocity if either top corners is solid
|
||||
if (dx < 0 && ((box[0] | box[2]) & FLAG_SOLID)) {
|
||||
if (state != STANDING || box[0] & FLAG_SOLID) {
|
||||
actor->xvel = 0;
|
||||
dx = 0;
|
||||
}
|
||||
}
|
||||
else if (dx > 0 && ((box[1] | box[3]) & FLAG_SOLID)) {
|
||||
if (state != STANDING || box[1] & FLAG_SOLID) {
|
||||
actor->xvel = 0;
|
||||
dx = 0;
|
||||
}
|
||||
}
|
||||
// cancel upward velocity if both top corners are solid
|
||||
if (dy < 0 && ((box[0] | box[1]) & FLAG_SOLID)) {
|
||||
actor->yvel = 0;
|
||||
dy = 0;
|
||||
}
|
||||
switch (state) {
|
||||
case JUMPING:
|
||||
// are we moving downward?
|
||||
if (dy > 0) {
|
||||
// hit a solid brick?
|
||||
flags = box[2] | box[3];
|
||||
if (flags & FLAG_SOLID) {
|
||||
// don't land if we are bumping against a wall
|
||||
// but land if entire bottom border is solid
|
||||
if (box[2] & box[3] & FLAG_SOLID) flags = FLAG_PLATFORM;
|
||||
else if (box[0] & box[2] & FLAG_SOLID) { }
|
||||
else if (box[1] & box[3] & FLAG_SOLID) { }
|
||||
else flags = FLAG_PLATFORM;
|
||||
}
|
||||
// land on platform, but only if we
|
||||
// transit past the lower boundary of a cell
|
||||
if (flags & FLAG_PLATFORM) {
|
||||
// maximum speed is 8 pixels/frame
|
||||
if ((yy & 31) <= 8) {
|
||||
if ((actor->yy & 31) >= 24) {
|
||||
actor->yy |= 31;
|
||||
actor->yvel = 0;
|
||||
dy = 0;
|
||||
actor->state = STANDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STANDING:
|
||||
// if either bottom corner is empty, fall down
|
||||
if ((box[2] | box[3]) == 0) {
|
||||
actor->state = JUMPING;
|
||||
}
|
||||
// climbing a ladder?
|
||||
else if (cmd_dy) {
|
||||
// look at top corners if going up, bottom corners if down
|
||||
flags = cmd_dy < 0 ? box[0] & box[1] : box[2] & box[3];
|
||||
if (flags & FLAG_LADDER) {
|
||||
actor->state = CLIMBING;
|
||||
} else {
|
||||
dy = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CLIMBING:
|
||||
// any flags set on bottom corners?
|
||||
flags = box[2] & box[3];
|
||||
if (!(flags & FLAG_LADDER)) {
|
||||
// top of ladder, stand up
|
||||
if (dy < 0) {
|
||||
actor->state = STANDING;
|
||||
} else {
|
||||
// bottom of ladder, don't go thru floor
|
||||
actor->state = JUMPING;
|
||||
dy = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// update position and tile coordinate
|
||||
// unless we zeroed out the velocity
|
||||
if (dx) actor->xx += dx;
|
||||
if (dy) actor->yy += dy;
|
||||
}
|
||||
|
||||
void control_actor(register Actor* actor, byte joy) {
|
||||
sbyte dx = 0;
|
||||
sbyte dy = 0;
|
||||
sbyte speed = 1;
|
||||
ActorState state = actor->state;
|
||||
// jump button
|
||||
if (JOY_BTN_1(joy) && state == STANDING) {
|
||||
actor->yvel = JUMP_VELOCITY;
|
||||
actor->state = state = JUMPING;
|
||||
framecount = 0; // TODO?
|
||||
}
|
||||
// update position based on x/y velocity
|
||||
if (actor->xvel) {
|
||||
dx += actor->xvel >> 3;
|
||||
if (framemask & velocity_bitmasks[actor->xvel & 7]) {
|
||||
dx++;
|
||||
}
|
||||
}
|
||||
if (actor->yvel) {
|
||||
dy += actor->yvel >> 3;
|
||||
if (framemask & velocity_bitmasks[actor->yvel & 7]) {
|
||||
dy++;
|
||||
}
|
||||
}
|
||||
// apply gravity when jumping or falling
|
||||
if (state == JUMPING &&
|
||||
actor->yvel < MAX_FALL_VELOCITY) {
|
||||
actor->yvel += 2;
|
||||
}
|
||||
// arrow keys give left/right velocity
|
||||
if (JOY_LEFT(joy)) {
|
||||
actor->faceleft = true;
|
||||
if (actor->xvel > -MAX_HORIZ_VELOCITY)
|
||||
actor->xvel -= speed;
|
||||
} else if (JOY_RIGHT(joy)) {
|
||||
actor->faceleft = false;
|
||||
if (actor->xvel < MAX_HORIZ_VELOCITY)
|
||||
actor->xvel += speed;
|
||||
} else {
|
||||
// slow down actor to a stop, horizontally
|
||||
if (actor->xvel) actor->xvel /= 2;
|
||||
}
|
||||
// climb ladder?
|
||||
if (state == STANDING || state == CLIMBING) {
|
||||
if (JOY_UP(joy)) { dy = -1; }
|
||||
if (JOY_DOWN(joy)) { dy = 1; }
|
||||
}
|
||||
// move sprite
|
||||
if (dx | dy) {
|
||||
move_actor(actor, dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
void camera_follow(register Actor* actor) {
|
||||
int dx, dy;
|
||||
byte moving = actor->xvel || actor->yvel;
|
||||
// compute distance between player and camera
|
||||
dx = CAMERA_OFFSET_X - pixofs_x - actor->xx;
|
||||
dy = CAMERA_OFFSET_Y - pixofs_y - actor->yy;
|
||||
// if we are moving, scroll only when distance
|
||||
// from center is greater
|
||||
if (moving) {
|
||||
if (dx < -CAMERA_MAX_DX) dx += CAMERA_MAX_DX;
|
||||
else if (dx > CAMERA_MAX_DX) dx -= CAMERA_MAX_DX;
|
||||
else dx = 0;
|
||||
if (dy < -CAMERA_MAX_DY) dy += CAMERA_MAX_DY;
|
||||
else if (dy > CAMERA_MAX_DY) dy -= CAMERA_MAX_DY;
|
||||
else dy = 0;
|
||||
}
|
||||
// divide dx and dy by 16
|
||||
dx >>= 4;
|
||||
dy >>= 4;
|
||||
// do we need to scroll?
|
||||
if (dx || dy) {
|
||||
// what direction?
|
||||
byte dir = 0;
|
||||
if (dx < 0) dir |= SCROLL_LEFT;
|
||||
if (dx > 0) dir |= SCROLL_RIGHT;
|
||||
if (dy < 0) dir |= SCROLL_UP;
|
||||
if (dy > 0) dir |= SCROLL_DOWN;
|
||||
// start the scroll (ignored if one is already going)
|
||||
scroll_start(dir);
|
||||
// fast 8-pixel scroll if screen is moving too fast
|
||||
if (moving && (abs(dx) >= 4 || abs(dy) >= 4)) {
|
||||
scroll_finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void control_enemy(struct Actor* enemy) {
|
||||
byte control = 0;
|
||||
int pdx = player->xx - enemy->xx;
|
||||
int pdy = player->yy - enemy->yy;
|
||||
if (pdy > 0) {
|
||||
control |= JOY_DOWN_MASK;
|
||||
} else if (pdy < 0) {
|
||||
control |= JOY_UP_MASK;
|
||||
}
|
||||
if (pdx < -32) {
|
||||
control |= JOY_LEFT_MASK;
|
||||
} else if (pdx > 32) {
|
||||
control |= JOY_RIGHT_MASK;
|
||||
}
|
||||
control_actor(enemy, control);
|
||||
}
|
||||
|
||||
void next_frame() {
|
||||
char joy;
|
||||
// increment frame counter
|
||||
framemask = BITMASKS[++framecount & 7];
|
||||
// get joystick bits
|
||||
joy = joy_read(0);
|
||||
// move player
|
||||
control_actor(player, joy);
|
||||
// move enemy
|
||||
control_enemy(&actors[1]);
|
||||
// move the camera if needed
|
||||
camera_follow(player);
|
||||
// animate sprites in shadow sprite ram
|
||||
draw_actor(&actors[0], 0);
|
||||
draw_actor(&actors[1], 1);
|
||||
// wait for vblank
|
||||
wait_vblank();
|
||||
// then update sprite registers
|
||||
sprite_update(visbuf);
|
||||
// do scrolling stuff each frame
|
||||
scroll_update();
|
||||
}
|
||||
|
||||
void setup_sprites(void) {
|
||||
sprite_clear();
|
||||
sprite_set_shapes(SPRITE_DATA, 240, NUM_SPRITE_PATTERNS);
|
||||
sprshad.spr_color[0] = COLOR_WHITE;
|
||||
sprshad.spr_color[1] = COLOR_LIGHTRED;
|
||||
sprshad.spr_mcolor = 0xff;
|
||||
VIC.spr_mcolor0 = 12;
|
||||
VIC.spr_mcolor1 = 14;
|
||||
}
|
||||
|
||||
void setup_charset() {
|
||||
// multicolor character mode
|
||||
VIC.ctrl2 |= 0x10;
|
||||
VIC.bgcolor0 = 6;
|
||||
VIC.bgcolor1 = 0;
|
||||
VIC.bgcolor2 = 1;
|
||||
|
||||
// select character set @ 0x8800
|
||||
VIC.addr = 0x12;
|
||||
memcpy((char*)0x8800, charset_data, 0x800);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
||||
clrscr();
|
||||
|
||||
// setup scrolling library
|
||||
scroll_setup();
|
||||
|
||||
// setup the character set for the level
|
||||
setup_charset();
|
||||
|
||||
// copy sprites to VIC bank
|
||||
setup_sprites();
|
||||
|
||||
// build cache for actor-level collisions
|
||||
build_tile_flag_map();
|
||||
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
|
||||
// repaint screen memory w/ the map
|
||||
scroll_refresh();
|
||||
|
||||
player->xx = 3*32+8;
|
||||
player->yy = 2*32+8-16;
|
||||
|
||||
player->xx = 0;
|
||||
player->yy = 31;
|
||||
player->state = STANDING;
|
||||
/*
|
||||
player->xx = 32;
|
||||
player->yy = 0;
|
||||
player->xx = 33;
|
||||
player->yy = 100;
|
||||
player->state = JUMPING;
|
||||
*/
|
||||
// actor_set_position(player, 63, 63, STANDING);
|
||||
actors[1].xx = 128;
|
||||
|
||||
// infinite loop
|
||||
while (1) {
|
||||
next_frame();
|
||||
}
|
||||
}
|
42
presets/c64/hello.acme
Normal file
42
presets/c64/hello.acme
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
!src "cartheader.acme"
|
||||
|
||||
!address {
|
||||
Temp = $02
|
||||
}
|
||||
|
||||
Start:
|
||||
sei ; turn off interrupts
|
||||
ldy #0
|
||||
Loop:
|
||||
lda Message,y ; load message byte
|
||||
beq EOM ; 0 = end of string
|
||||
clc
|
||||
adc #$40
|
||||
sta $400+41,y ; store to screen
|
||||
iny
|
||||
bne Loop ; next character
|
||||
EOM:
|
||||
|
||||
Wait1:
|
||||
lda $d011
|
||||
bmi Wait1 ; wait for line < 256
|
||||
Wait2:
|
||||
lda $d012 ; get current scanline
|
||||
Wait3:
|
||||
cmp $d012
|
||||
beq Wait3 ; wait for scanline to change
|
||||
lsr ; divide by 2
|
||||
lsr ; divide by 2
|
||||
clc
|
||||
adc Temp ; add to frame counter
|
||||
sta $d020 ; set border color
|
||||
lda $d011 ; get status bits
|
||||
bpl Wait2 ; repeat until line >= 256
|
||||
sty $d020 ; reset border color
|
||||
dec Temp ; change frame counter
|
||||
jmp Wait1 ; endless loop
|
||||
|
||||
Message:
|
||||
!scr "HELLO WORLD", 0
|
||||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
; program start
|
||||
Temp equ $03
|
||||
|
||||
Start
|
||||
jsr $FF81 ; CINT (clear screen)
|
||||
sei ; turn off interrupts
|
||||
ldy #0
|
||||
sty $d020 ; reset border color
|
||||
|
|
181
presets/c64/hello.wiz
Normal file
181
presets/c64/hello.wiz
Normal file
|
@ -0,0 +1,181 @@
|
|||
|
||||
|
||||
import "c64.wiz";
|
||||
|
||||
bank zeropage @ 0x02 : [vardata; 254];
|
||||
bank stackpage @ 0x100 : [vardata; 256];
|
||||
bank textscrn @ 0x400 : [vardata; 0x400];
|
||||
bank ram @ 0x2000 : [vardata; 0x7800];
|
||||
bank prghdr @ 0x7ff : [prgdata; 0x2];
|
||||
bank prg @ 0x801 : [varinitdata; 0x7000];
|
||||
|
||||
in textscrn {
|
||||
var scrn: [u8; 40*25];
|
||||
var _unused: [u8; 16];
|
||||
var spriteptr: [u8; 8];
|
||||
}
|
||||
|
||||
extern var vicbank @ 0x0000 : VICBank;
|
||||
|
||||
// PRG file header
|
||||
in prghdr {
|
||||
const prgstart : u16 = 0x801;
|
||||
}
|
||||
|
||||
// BASIC header
|
||||
in prg {
|
||||
namespace prgheader {
|
||||
const nextline = &BASIC_END;
|
||||
const linenum : u16 = 10;
|
||||
const sysstmt = "\x9e 2062\0";
|
||||
BASIC_END:
|
||||
const hdrend : u16 = 0;
|
||||
}
|
||||
PRG_START:
|
||||
/*
|
||||
c64.kernal.ioinit();
|
||||
c64.kernal.rantam();
|
||||
c64.kernal.restor();
|
||||
c64.kernal.cint();
|
||||
*/
|
||||
c64.vic.bordercolor = a = c64.color.ORANGE;
|
||||
c64.kernal.chrout('A');
|
||||
for x in 0..250 {
|
||||
// scrn[x] = a = x;
|
||||
// (&scrn[40*8])[x] = a = x;
|
||||
// (0x600 as *u8)[x] = a = x;
|
||||
(&scrn[40*12])[x] = a = message[x] + 0xc0;
|
||||
}
|
||||
for x in 0..255 {
|
||||
a = message[x];
|
||||
break if zero;
|
||||
a += 0xc0;
|
||||
(&scrn[40*20])[x] = a;
|
||||
}
|
||||
upandaway();
|
||||
return;
|
||||
|
||||
const message = "HELLO WORLD!\0";
|
||||
|
||||
const SPRITE : [u8; 3*21] = [
|
||||
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||
0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0,
|
||||
0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0,
|
||||
0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0,
|
||||
0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40,
|
||||
0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80,
|
||||
0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00,
|
||||
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||
];
|
||||
|
||||
const yValues : [u8] = [
|
||||
32, 35, 38, 41, 44, 47, 49, 52,
|
||||
54, 56, 58, 60, 61, 62, 63, 63,
|
||||
64, 63, 63, 62, 61, 60, 58, 56,
|
||||
54, 52, 49, 47, 44, 41, 38, 35,
|
||||
32, 28, 25, 22, 19, 16, 14, 11,
|
||||
9, 7, 5, 3, 2, 1, 0, 0,
|
||||
0, 0, 0, 1, 2, 3, 5, 7,
|
||||
9, 11, 14, 16, 19, 22, 25, 28
|
||||
];
|
||||
|
||||
const pwr2 : [u8] = [
|
||||
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
|
||||
];
|
||||
|
||||
in zeropage {
|
||||
var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8;
|
||||
var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8, w10 @ &b10 : u16;
|
||||
var ptr0 @ &b0, ptr2 @ &b2, ptr4 @ &b4, ptr6 @ &b6, ptr8 @ &b8, ptr10 @ &b10 : *u8;
|
||||
}
|
||||
|
||||
inline func rasterWait(line : u8 in a) {
|
||||
while (c64.vic.rasterline < line) { }
|
||||
}
|
||||
|
||||
func upandaway() {
|
||||
//unsigned char n, t;
|
||||
//int rx, x;
|
||||
//char sx, msb;
|
||||
var xp : u16 in w0;
|
||||
var rx : u16 in w2;
|
||||
var msb : u8 in b4;
|
||||
let sprdata = &vicbank.spritedata[13] as *u8;
|
||||
|
||||
c64.vic.bgcolor[0] = a = 3;
|
||||
nointerrupt = true; // clear interrupts to avoid glitching
|
||||
|
||||
for y in 0..(sizeof(typeof(SPRITE)) - 1) {
|
||||
sprdata[y] = a = SPRITE[y];
|
||||
//POKE(832 + n, sprite[n]);
|
||||
}
|
||||
c64.vic.sprite.enable = a = 255;
|
||||
for x in 0..7 {
|
||||
spriteptr[x] = a = 13;
|
||||
y = a = x<<1;
|
||||
c64.vic.sprite.coord[y] = a = 50;
|
||||
y ++;
|
||||
c64.vic.sprite.coord[y] = a = 50;
|
||||
//POKE(2040 + t, 13); // Set sprite x data from 13th block for all sprites
|
||||
}
|
||||
do {
|
||||
<:xp = a = 0;
|
||||
>:xp = a = 0;
|
||||
//while (xp < 550) {
|
||||
while (true) {
|
||||
<:xp = a = <:xp + 1;
|
||||
>:xp = a = >:xp +# 0;
|
||||
msb = a = 0; // MSB of X coordinates
|
||||
// Wait until raster hits position 250 before drawing upper sprites
|
||||
rasterWait(250);
|
||||
// Set border color, which indicates the raster position
|
||||
c64.vic.bordercolor = a = 1;
|
||||
<:rx = a = <:xp;
|
||||
>:rx = a = >:xp;
|
||||
for x in 0..7 {
|
||||
<:rx = a = <:rx - 24;
|
||||
>:rx = a = >:rx -# 0;
|
||||
//if (rx >= 0 && rx < 366)
|
||||
if (true) {
|
||||
// if (rx > 255)
|
||||
a = >:rx;
|
||||
if (!zero) {
|
||||
// Set MSB of x coordinate for sprite if x position > 255
|
||||
a = msb;
|
||||
a |= pwr2[x];
|
||||
msb = a;
|
||||
}
|
||||
y = a = x<<1;
|
||||
c64.vic.sprite.coord[y] = a = <:rx;
|
||||
// Y position is an indirect Sinus function of X, using array
|
||||
// index for retrieving the Y value
|
||||
y = a = <:rx & 63;
|
||||
a = yValues[y] + 40;
|
||||
push(a);
|
||||
y = a = (x<<1) + 1;
|
||||
a = pop();
|
||||
c64.vic.sprite.coord[y] = a;
|
||||
} else {
|
||||
c64.vic.sprite.pos[y].x = 0;
|
||||
}
|
||||
}
|
||||
c64.vic.sprite.hi_x = a = msb; // Set MSB of x coordinate
|
||||
// Wait until raster hits position 135 before drawing lower sprites
|
||||
rasterWait(135);
|
||||
c64.vic.bordercolor = a = 2; // Set border color
|
||||
for x in 0..7 {
|
||||
// Add 128 to current sprite Y position
|
||||
y = a = (x<<1) + 1;
|
||||
c64.vic.sprite.coord[y] = a = c64.vic.sprite.coord[y]+128;
|
||||
}
|
||||
cmp(a = >:xp, >:550);
|
||||
if (zero) {
|
||||
cmp(a = <:xp, <:550);
|
||||
break if zero;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
16
presets/c64/helloc.c
Normal file
16
presets/c64/helloc.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include <cbm_petscii_charmap.h>
|
||||
|
||||
void main(void) {
|
||||
clrscr(); // clear screen
|
||||
puts("Hello World!\n"); // write message at cursor
|
||||
chline(12); // horizontal line
|
||||
bordercolor(COLOR_LIGHTBLUE); // set color to blue
|
||||
bgcolor(COLOR_GREEN); // set background color
|
||||
textcolor(COLOR_YELLOW); // set text color
|
||||
puts("\nThis text is yellow!\n"); // write message
|
||||
cgetc(); // wait for input
|
||||
}
|
BIN
presets/c64/image-c64.multi.lz4
Normal file
BIN
presets/c64/image-c64.multi.lz4
Normal file
Binary file not shown.
131
presets/c64/joygame.c
Normal file
131
presets/c64/joygame.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
#define NUM_SPRITES 3
|
||||
|
||||
/*{w:12,h:21,bpp:2,brev:1,wpimg:64,count:3,aspect:2}*/
|
||||
const char SPRITE_MC_DATA[64*NUM_SPRITES] = {
|
||||
0x0A,0xAA,0x80,0x0A,0xAA,0x80,0x2A,0xAA,
|
||||
0xA0,0x2A,0xAA,0xA0,0xAA,0xAA,0xAA,0xFF,
|
||||
0xD5,0x40,0x0D,0xD7,0x40,0x3D,0xD5,0x54,
|
||||
0x37,0x55,0x54,0x37,0x55,0x54,0x35,0x55,
|
||||
0x00,0x3A,0xA0,0x00,0xEA,0xA8,0x00,0xAB,
|
||||
0xAA,0x00,0xAB,0xAA,0x00,0xAB,0xAA,0x80,
|
||||
0xAA,0xEA,0x80,0xAA,0xAA,0x80,0x0F,0xFC,
|
||||
0x00,0x0F,0xFC,0x00,0x0F,0xFF,0xC0,0x00,
|
||||
|
||||
0x02,0xAA,0xA0,0x02,0xAA,0xA0,0x0A,0xAA,
|
||||
0xA8,0x0A,0xAA,0xA8,0xAA,0xAA,0xAA,0x01,
|
||||
0x57,0xFF,0x01,0xD7,0x70,0x15,0x57,0x7C,
|
||||
0x15,0x55,0xDC,0x15,0x55,0xDC,0x00,0x55,
|
||||
0x5C,0x00,0x0A,0xAC,0x00,0x2A,0xAB,0x00,
|
||||
0xAA,0xEA,0x00,0xAA,0xEA,0x02,0xAA,0xEA,
|
||||
0x02,0xAB,0xAA,0x02,0xAA,0xAA,0x00,0x3F,
|
||||
0xF0,0x00,0x3F,0xF0,0x03,0xFF,0xF0,0x00,
|
||||
|
||||
0x00,0xAA,0x80,0x02,0xAA,0xA0,0x0A,0xAA,0xA8,
|
||||
0x0A,0xAE,0xA8,0x0A,0xBB,0xA8,0x0A,0xBA,0xA8,
|
||||
0x0A,0xBB,0xA8,0x0A,0xAE,0xA8,0x0A,0xAA,0xA8,
|
||||
0x09,0xAA,0x98,0x08,0x6A,0x48,0x08,0x1D,0x08,
|
||||
0x02,0x0C,0x20,0x02,0x0C,0x20,0x02,0x0C,0x20,
|
||||
0x00,0x8C,0x80,0x00,0x8C,0x80,0x00,0x55,0x40,
|
||||
0x00,0x77,0x40,0x00,0x5D,0x40,0x00,0x15,0x00,
|
||||
0x80,
|
||||
};
|
||||
|
||||
// starting index for sprites
|
||||
#define SPRITE_SHAPE 192
|
||||
|
||||
// player data
|
||||
int player_x = 172;
|
||||
byte player_y = 145;
|
||||
byte faceleft = 0; // 0 = face right, 1 = face left
|
||||
|
||||
void init_sprite_shapes(void) {
|
||||
byte i;
|
||||
for (i=0; i<NUM_SPRITES; i++) {
|
||||
sprite_shape(SPRITE_SHAPE+i, SPRITE_MC_DATA+64*i);
|
||||
}
|
||||
}
|
||||
|
||||
void init_sprite_positions(void) {
|
||||
byte i;
|
||||
// setup sprite positions
|
||||
player_x = 172;
|
||||
player_y = 145;
|
||||
// set random positions for non-players
|
||||
// and draw them to sprite shadow buffer
|
||||
srand(7);
|
||||
for (i=1; i<8; i++) {
|
||||
int x = rand() % (320 - 24) + 24;
|
||||
byte y = rand() % (229 - 50) + 50;
|
||||
sprite_draw(i, x, y, SPRITE_SHAPE + 2);
|
||||
sprshad.spr_color[i] = i | 8;
|
||||
}
|
||||
}
|
||||
|
||||
void move_player(byte joy) {
|
||||
// move sprite based on joystick
|
||||
if (JOY_LEFT(joy)) { player_x -= 1; faceleft = 1; } // move left 1 pixel
|
||||
if (JOY_RIGHT(joy)) { player_x += 1; faceleft = 0; } // move right 1 pixel
|
||||
if (JOY_UP(joy)) { player_y -= 1; } // move up 1 pixel
|
||||
if (JOY_DOWN(joy)) { player_y += 1; } // move down 1 pixel
|
||||
|
||||
// draw player into sprite shadow buffer
|
||||
sprite_draw(0, player_x, player_y, SPRITE_SHAPE + faceleft);
|
||||
}
|
||||
|
||||
void move_non_players(void) {
|
||||
byte i;
|
||||
// wiggle non-player sprites randomly
|
||||
for (i=1; i<8; i++) {
|
||||
sprshad.spr_pos[i].y += rand() & i;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
// variables
|
||||
byte bgcoll; // sprite background collision flags
|
||||
byte sprcoll; // sprite collision flags
|
||||
byte joy; // joystick flags
|
||||
|
||||
clrscr();
|
||||
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
|
||||
// set multicolor sprites and colors
|
||||
sprshad.spr_mcolor = 0b11111111;
|
||||
sprshad.spr_color[0] = SPRITE_MC_DATA[63];
|
||||
VIC.spr_mcolor0 = COLOR_GRAY2;
|
||||
VIC.spr_mcolor1 = COLOR_BLACK;
|
||||
|
||||
// setup sprites
|
||||
init_sprite_shapes();
|
||||
init_sprite_positions();
|
||||
|
||||
// loop forever
|
||||
while (1) {
|
||||
// wait for end of frame
|
||||
waitvsync();
|
||||
// update sprite registers from sprite shadow
|
||||
// buffer before frame starts drawing
|
||||
sprite_update(DEFAULT_SCREEN);
|
||||
|
||||
// get joystick bits
|
||||
joy = joy_read(0);
|
||||
move_player(joy);
|
||||
// move other objects
|
||||
move_non_players();
|
||||
|
||||
// grab and reset collision flags
|
||||
sprcoll = VIC.spr_coll;
|
||||
bgcoll = VIC.spr_bg_coll;
|
||||
// change color when player collides with sprite
|
||||
sprshad.spr_color[0] = (sprcoll & 1) ? 10 : 3;
|
||||
}
|
||||
}
|
|
@ -1,94 +1,59 @@
|
|||
// ported from
|
||||
// https://odensskjegg.home.blog/2018/12/29/recreating-the-commodore-64-user-guide-code-samples-in-cc65-part-three-sprites/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <conio.h>
|
||||
#include <peekpoke.h>
|
||||
#include <c64.h>
|
||||
#include <joystick.h>
|
||||
#include "common.h"
|
||||
|
||||
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||
const char sprite[3*21] = {
|
||||
0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0,
|
||||
0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0,
|
||||
0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0,
|
||||
0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40,
|
||||
0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80,
|
||||
0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00,
|
||||
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||
/*{w:24,h:21,bpp:1,brev:1,count:1}*/
|
||||
const char SPRITE_DATA[64] = {
|
||||
0x0f,0xff,0x80,0x17,0xff,0x40,0x2b,0xfe,
|
||||
0xa0,0x7f,0xff,0xf0,0xff,0xc0,0x3f,0xe0,
|
||||
0x3f,0xc0,0x17,0xbe,0xc0,0x2d,0x7f,0xf0,
|
||||
0x2b,0x7f,0xf8,0x2a,0xff,0xf8,0x15,0xf6,
|
||||
0x00,0x3f,0xf8,0x00,0xfd,0xfc,0x00,0xfd,
|
||||
0xff,0x00,0xfe,0xff,0x80,0xff,0x7f,0xc0,
|
||||
0xff,0xff,0xc0,0xff,0xff,0xc0,0x0a,0xa8,
|
||||
0x00,0x0f,0xf8,0x00,0x0f,0xff,0x80,0x03,
|
||||
};
|
||||
|
||||
/*{w:12,h:21,bpp:2,brev:1}*/
|
||||
const char spritemc[3*21] = {
|
||||
0x00,0xFF,0xC0,0x03,0xFF,0xF0,0x0F,0xFF,0xFC,
|
||||
0x0F,0xFB,0xFC,0x0F,0xEE,0xFC,0x0F,0xEF,0xFC,
|
||||
0x0F,0xEE,0xFC,0x0F,0xFB,0xFC,0x0F,0xFF,0xFC,
|
||||
0x09,0xFF,0xD8,0x08,0x7F,0x48,0x08,0x1D,0x08,
|
||||
0x02,0x0C,0x20,0x02,0x0C,0x20,0x02,0x0C,0x20,
|
||||
0x00,0x8C,0x80,0x00,0x8C,0x80,0x00,0x55,0x40,
|
||||
0x00,0x77,0x40,0x00,0x5D,0x40,0x00,0x15,0x00
|
||||
};
|
||||
void main(void) {
|
||||
// variables
|
||||
int x = 172; // sprite X position (16-bit)
|
||||
byte y = 145; // sprite Y position (8-bit)
|
||||
byte bgcoll; // sprite background collision flags
|
||||
byte joy; // joystick flags
|
||||
|
||||
// Raster wait with line argument
|
||||
void rasterWait(unsigned char line) {
|
||||
while (VIC.rasterline < line) ;
|
||||
}
|
||||
// copy sprite pattern to RAM address 0x3800
|
||||
memcpy((char*)0x3800, SPRITE_DATA, sizeof(SPRITE_DATA));
|
||||
// set sprite #0 shape entry (224)
|
||||
POKE(0x400 + 0x3f8 + 0, 0x3800 / 64);
|
||||
// set position and color
|
||||
VIC.spr_pos[0].x = 172;
|
||||
VIC.spr_pos[0].y = 145;
|
||||
VIC.spr_color[0] = COLOR_GREEN;
|
||||
// enable sprite #0
|
||||
VIC.spr_ena = 0b00000001;
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int n;
|
||||
int x,y;
|
||||
char bgcoll;
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
// set background color
|
||||
VIC.bgcolor0 = 3;
|
||||
// clear interrupts to avoid glitching
|
||||
__asm__("SEI");
|
||||
// set sprite bitmap data
|
||||
for (n = 0 ; n < sizeof(sprite) ; n++) {
|
||||
POKE(0x340 + n, sprite[n]);
|
||||
POKE(0x380 + n, spritemc[n]);
|
||||
}
|
||||
// enable 1st and 2nd sprite
|
||||
VIC.spr_ena = 0x03;
|
||||
VIC.spr_mcolor = 0x02;
|
||||
// set colors
|
||||
VIC.spr_mcolor0 = 4;
|
||||
VIC.spr_mcolor1 = 7;
|
||||
// 2x zoom 1st sprite
|
||||
VIC.spr_exp_x = 0x01;
|
||||
VIC.spr_exp_y = 0x01;
|
||||
// set address of sprite data
|
||||
POKE(0x7f8, 13);
|
||||
POKE(0x7f9, 14);
|
||||
// set initial x/y positions
|
||||
x = 160;
|
||||
y = 128;
|
||||
// loop
|
||||
|
||||
// loop forever
|
||||
while (1) {
|
||||
// get joystick bits
|
||||
char joy = joy_read(0);
|
||||
// move sprite based on arrow keys
|
||||
if (JOY_LEFT(joy)) --x;
|
||||
if (JOY_UP(joy)) --y;
|
||||
if (JOY_RIGHT(joy)) ++x;
|
||||
if (JOY_DOWN(joy)) ++y;
|
||||
// set VIC registers based on position
|
||||
VIC.spr0_x = x;
|
||||
VIC.spr0_y = y-32;
|
||||
VIC.spr1_x = x;
|
||||
VIC.spr1_y = y+32;
|
||||
VIC.spr_hi_x = (x & 256) ? 1 : 0;
|
||||
// change color when we collide with background
|
||||
bgcoll = VIC.spr_bg_coll;
|
||||
VIC.spr0_color = (bgcoll & 1) ? 10 : 0;
|
||||
VIC.spr1_color = (bgcoll & 2) ? 10 : 0;
|
||||
joy = joy_read(0);
|
||||
// move sprite based on joystick
|
||||
if (JOY_LEFT(joy)) { x -= 1; } // move left 1 pixel
|
||||
if (JOY_RIGHT(joy)) { x += 1; } // move right 1 pixel
|
||||
if (JOY_UP(joy)) { y -= 1; } // move up 1 pixel
|
||||
if (JOY_DOWN(joy)) { y += 1; } // move down 1 pixel
|
||||
// wait for end of frame
|
||||
rasterWait(255);
|
||||
waitvsync();
|
||||
// set sprite registers based on position
|
||||
VIC.spr_pos[0].x = x;
|
||||
VIC.spr_pos[0].y = y;
|
||||
// set X coordinate high bit
|
||||
VIC.spr_hi_x = (x & 0x100) ? 1 : 0;
|
||||
// grab and reset collision flags
|
||||
bgcoll = VIC.spr_bg_coll;
|
||||
// change color when we collide with background
|
||||
VIC.spr_color[0] = (bgcoll & 1) ?
|
||||
COLOR_LIGHTRED : COLOR_CYAN;
|
||||
}
|
||||
// uninstall joystick driver (not really necessary)
|
||||
joy_uninstall();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
294
presets/c64/level2.ca65
Normal file
294
presets/c64/level2.ca65
Normal file
|
@ -0,0 +1,294 @@
|
|||
|
||||
|
||||
; Generated by CharPad 2.8, Subchrist Software, 2021.
|
||||
; Assemble with 64TASS or similar.
|
||||
|
||||
|
||||
; Character display mode : Multi-colour.
|
||||
|
||||
; Character colouring method : Per-Tile.
|
||||
|
||||
|
||||
; Colour values...
|
||||
|
||||
COLR_SCREEN = 11
|
||||
COLR_CHAR_DEF = 13
|
||||
COLR_CHAR_MC1 = 0
|
||||
COLR_CHAR_MC2 = 1
|
||||
|
||||
|
||||
; Quantities and dimensions...
|
||||
|
||||
CHAR_COUNT = 256
|
||||
TILE_COUNT = 16
|
||||
TILE_WID = 4
|
||||
TILE_HEI = 4
|
||||
MAP_WID = 16
|
||||
MAP_HEI = 16
|
||||
MAP_WID_CHRS = 64
|
||||
MAP_HEI_CHRS = 64
|
||||
MAP_WID_PXLS = 512
|
||||
MAP_HEI_PXLS = 512
|
||||
|
||||
|
||||
; Data block sizes (in bytes)...
|
||||
|
||||
SZ_CHARSET_DATA = 2048 ; ($800)
|
||||
SZ_CHARSET_ATTRIB_DATA = 256 ; ($100)
|
||||
SZ_TILESET_DATA = 256 ; ($100)
|
||||
SZ_TILESET_ATTRIB_DATA = 16 ; ($10)
|
||||
SZ_MAP_DATA = 256 ; ($100)
|
||||
|
||||
|
||||
|
||||
|
||||
; * INSERT EXAMPLE PROGRAM HERE! * (Or just include this file in your project).
|
||||
|
||||
.global _charset_data
|
||||
.global _chartileset_data
|
||||
.global _charset_attrib_data
|
||||
.global _chartileset_colour_data
|
||||
.global _map_row_pointers
|
||||
.global _map_data
|
||||
|
||||
|
||||
; CHARSET IMAGE DATA...
|
||||
; 256 images, 8 bytes per image, total size is 2048 ($800) bytes.
|
||||
|
||||
_charset_data:
|
||||
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$C0,$91,$95,$91,$80,$C0,$F2,$F5
|
||||
.byte $03,$11,$55,$11,$01,$03,$AF,$4F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
|
||||
.byte $AA,$AA,$88,$22,$CC,$33,$DD,$55,$AA,$AA,$88,$22,$CC,$33,$DD,$55
|
||||
.byte $AA,$AA,$88,$22,$CC,$33,$DD,$55,$AA,$AA,$88,$22,$CC,$33,$DD,$55
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $AA,$BB,$FE,$FF,$FF,$CF,$33,$55,$AA,$BB,$FE,$FF,$FF,$CF,$33,$55
|
||||
.byte $AA,$BB,$FE,$FF,$FF,$CF,$33,$55,$AA,$BB,$FE,$FF,$FF,$CF,$33,$55
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $AA,$AF,$B3,$AC,$B0,$AC,$B0,$AC,$AA,$FD,$35,$11,$05,$11,$05,$11
|
||||
.byte $AA,$BF,$B3,$BC,$B0,$BC,$B0,$BC,$AA,$FD,$35,$11,$05,$11,$05,$11
|
||||
.byte $B0,$AC,$B0,$AC,$B0,$AD,$B4,$95,$05,$11,$05,$11,$05,$11,$45,$55
|
||||
.byte $B0,$BC,$B0,$BC,$B0,$BD,$B4,$95,$05,$11,$05,$11,$05,$11,$45,$55
|
||||
.byte $AA,$BF,$B3,$BC,$B0,$BC,$B0,$BC,$AA,$FD,$35,$11,$05,$11,$05,$11
|
||||
.byte $AA,$BF,$B3,$BC,$B0,$BC,$B0,$BC,$AA,$FD,$35,$11,$05,$11,$05,$11
|
||||
.byte $B0,$BC,$B0,$BC,$B0,$BD,$B4,$95,$05,$11,$05,$11,$05,$11,$45,$55
|
||||
.byte $B0,$BC,$B0,$BC,$B0,$BD,$B4,$95,$05,$11,$05,$11,$05,$11,$45,$55
|
||||
.byte $02,$02,$02,$02,$02,$02,$02,$02,$D0,$D0,$D0,$EA,$FF,$D5,$D0,$D0
|
||||
.byte $0B,$0B,$0B,$AB,$FF,$5B,$0B,$0B,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
.byte $02,$02,$02,$02,$02,$02,$02,$02,$D0,$D0,$D0,$EA,$FF,$D5,$D0,$D0
|
||||
.byte $0B,$0B,$0B,$AB,$FF,$5B,$0B,$0B,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
.byte $02,$02,$02,$02,$02,$02,$02,$02,$D0,$D0,$D0,$EA,$FF,$D5,$D0,$D0
|
||||
.byte $0B,$0B,$0B,$AB,$FF,$5B,$0B,$0B,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
.byte $02,$02,$02,$02,$02,$02,$02,$02,$D0,$D0,$D0,$EA,$FF,$D5,$D0,$D0
|
||||
.byte $0B,$0B,$0B,$AB,$FF,$5B,$0B,$0B,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
.byte $AA,$BB,$FE,$FF,$FF,$CF,$33,$55,$AA,$BB,$FE,$FF,$FF,$CF,$33,$55
|
||||
.byte $AA,$BB,$FE,$FF,$FF,$CF,$33,$55,$AA,$BB,$FE,$FF,$FF,$CF,$33,$55
|
||||
.byte $02,$02,$02,$02,$02,$02,$02,$02,$D0,$D0,$D0,$EA,$FF,$D5,$D0,$D0
|
||||
.byte $0B,$0B,$0B,$AB,$FF,$5B,$0B,$0B,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
.byte $02,$02,$02,$02,$02,$02,$02,$02,$D0,$D0,$D0,$EA,$FF,$D5,$D0,$D0
|
||||
.byte $0B,$0B,$0B,$AB,$FF,$5B,$0B,$0B,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
.byte $02,$02,$02,$02,$02,$02,$02,$02,$D0,$D0,$D0,$EA,$FF,$D5,$D0,$D0
|
||||
.byte $0B,$0B,$0B,$AB,$FF,$5B,$0B,$0B,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
.byte $AA,$00,$B3,$EF,$BF,$EF,$9D,$55,$AA,$00,$33,$FF,$FF,$FF,$DD,$55
|
||||
.byte $AA,$00,$33,$FF,$FF,$FF,$DD,$55,$AA,$00,$31,$FF,$FD,$F7,$DD,$55
|
||||
.byte $EF,$BF,$EF,$BB,$EF,$BF,$EF,$BB,$DF,$FD,$F4,$DD,$FF,$FD,$F4,$DD
|
||||
.byte $55,$15,$45,$15,$51,$15,$45,$15,$55,$55,$55,$55,$55,$55,$55,$55
|
||||
.byte $EF,$BF,$EF,$BB,$EF,$BF,$EF,$BB,$DF,$FD,$F4,$DD,$FF,$FD,$F4,$DD
|
||||
.byte $55,$15,$45,$15,$51,$15,$45,$15,$55,$55,$55,$55,$55,$55,$55,$55
|
||||
.byte $EF,$BF,$EF,$BB,$EF,$BF,$EF,$BB,$DF,$FD,$F4,$DD,$FF,$FD,$F4,$D1
|
||||
.byte $55,$15,$45,$15,$51,$15,$45,$15,$55,$55,$55,$55,$55,$55,$55,$55
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$02,$02,$02,$0B,$0B,$2F,$BF,$00,$00,$00,$00,$80,$80,$E0,$F8
|
||||
.byte $00,$02,$02,$02,$0B,$0B,$2F,$BF,$00,$00,$00,$00,$80,$80,$E0,$F8
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,$FE,$FE,$FC,$FD,$F9,$F9
|
||||
.byte $FF,$FF,$7F,$7F,$3F,$BF,$9F,$9F,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$F1,$F1,$E0,$E1,$C1,$C0,$FF,$FF
|
||||
.byte $8F,$8F,$07,$87,$83,$03,$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $AA,$25,$0B,$02,$00,$02,$09,$24,$AA,$56,$F9,$E7,$9F,$6F,$1B,$06
|
||||
.byte $AA,$95,$6F,$DB,$F6,$F9,$E4,$90,$AA,$58,$E0,$80,$00,$80,$60,$18
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$02,$02,$0B,$0B,$2F,$2F,$BF,$BF
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $02,$02,$0B,$0B,$2F,$2F,$BF,$BF,$FD,$FD,$F4,$F4,$D0,$D0,$40,$40
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$02,$02,$0B,$0B,$2F,$2F,$BF,$BF
|
||||
.byte $FD,$FD,$F4,$F4,$D0,$D0,$40,$40,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $02,$02,$0B,$0B,$2F,$2F,$BF,$95,$FD,$FD,$F4,$F4,$D0,$D0,$40,$40
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $80,$80,$E0,$E0,$F8,$F8,$FE,$FE,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $7F,$7F,$1F,$1F,$07,$07,$01,$01,$80,$80,$E0,$E0,$F8,$F8,$FE,$FE
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$7F,$7F,$1F,$1F,$07,$07,$01,$01
|
||||
.byte $80,$80,$E0,$E0,$F8,$F8,$FE,$FE,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $7F,$7F,$1F,$1F,$07,$07,$01,$01,$80,$80,$E0,$E0,$F8,$F8,$FE,$56
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$01,$03,$01,$01,$03,$03,$07,$0F,$5E,$FA,$EA
|
||||
.byte $00,$00,$00,$40,$C0,$D5,$BF,$AD,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$7A,$1E,$0F,$3D,$34,$D0,$40,$00
|
||||
.byte $B4,$D0,$C0,$F0,$70,$1C,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$80,$E0,$FA,$D5,$40,$00,$00,$00,$00,$00,$AA,$55,$00,$00,$00
|
||||
.byte $00,$00,$00,$AA,$55,$00,$00,$00,$00,$02,$0B,$AF,$57,$01,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
|
||||
|
||||
; CHARSET IMAGE ATTRIBUTE DATA...
|
||||
; 256 attributes, 1 attribute per image, 8 bits per attribute, total size is 256 ($100) bytes.
|
||||
; nb. Upper nybbles = material, lower nybbles = colour.
|
||||
|
||||
_charset_attrib_data:
|
||||
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
.byte $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
|
||||
|
||||
|
||||
; CHARTILESET DATA...
|
||||
; 16 tiles, 4x4 (16) cells per tile, 8 bits per cell, total size is 256 ($100) bytes.
|
||||
|
||||
_chartileset_data:
|
||||
|
||||
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F
|
||||
.byte $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$1B,$1C,$1D,$1E,$1F
|
||||
.byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F
|
||||
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F
|
||||
.byte $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F
|
||||
.byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$5B,$5C,$5D,$5E,$5F
|
||||
.byte $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6A,$6B,$6C,$6D,$6E,$6F
|
||||
.byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7A,$7B,$7C,$7D,$7E,$7F
|
||||
.byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F
|
||||
.byte $90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F
|
||||
.byte $A0,$A1,$A2,$A3,$A4,$A5,$A6,$A7,$A8,$A9,$AA,$AB,$AC,$AD,$AE,$AF
|
||||
.byte $B0,$B1,$B2,$B3,$B4,$B5,$B6,$B7,$B8,$B9,$BA,$BB,$BC,$BD,$BE,$BF
|
||||
.byte $C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF
|
||||
.byte $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$DB,$DC,$DD,$DE,$DF
|
||||
.byte $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7,$E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF
|
||||
.byte $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF
|
||||
|
||||
|
||||
; CHARTILESET COLOUR DATA...
|
||||
; 16 colours, 1 colour per tile, 8 bits per colour, total size is 16 ($10) bytes.
|
||||
; nb. Lower nybbles = colour, upper nybbles are unused.
|
||||
|
||||
_chartileset_colour_data:
|
||||
|
||||
.byte $03,$03,$03,$0B,$0D,$0B,$0D,$0D,$0D,$0A,$06,$0C,$0C,$0C,$0F,$0D
|
||||
|
||||
|
||||
; CHARTILESET TAG DATA...
|
||||
; 16 tags, 1 tag per tile, 8 bits per tag, total size is 16 ($10) bytes.
|
||||
|
||||
_chartileset_tag_data:
|
||||
|
||||
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
|
||||
|
||||
; MAP DATA...
|
||||
; 16x16 (256) cells, 8 bits per cell, total size is 256 ($100) bytes.
|
||||
|
||||
_map_data:
|
||||
map_data:
|
||||
|
||||
.byte $01,$01,$02,$01,$01,$01,$01,$01,$02,$01,$01,$01,$01,$01,$01,$01
|
||||
.byte $05,$03,$03,$03,$06,$03,$05,$03,$03,$03,$03,$03,$03,$03,$03,$05
|
||||
.byte $05,$00,$00,$04,$06,$06,$06,$09,$08,$00,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$0F,$04,$04,$07,$07,$07,$04,$08,$0F,$00,$0B,$00,$0C,$05,$05
|
||||
.byte $05,$00,$00,$05,$05,$05,$05,$05,$05,$00,$00,$05,$05,$00,$00,$05
|
||||
.byte $05,$0E,$0A,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$00,$00,$04,$00,$04,$00,$04,$04,$07,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$0E,$00,$00,$00,$00,$00,$00,$00,$06,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$05,$00,$07,$04,$04,$0F,$0F,$0F,$07,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$00,$0A,$06,$00,$00,$00,$00,$00,$06,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$00,$09,$04,$04,$04,$07,$00,$00,$06,$00,$00,$00,$00,$00,$05
|
||||
.byte $05,$00,$05,$00,$00,$00,$06,$00,$00,$05,$0D,$00,$00,$00,$00,$05
|
||||
.byte $05,$00,$00,$00,$00,$05,$05,$00,$00,$00,$00,$05,$0D,$00,$00,$05
|
||||
.byte $05,$00,$00,$00,$05,$05,$00,$00,$00,$00,$00,$00,$00,$05,$00,$05
|
||||
.byte $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05
|
||||
|
||||
.global _map_row_pointers
|
||||
_map_row_pointers:
|
||||
.word map_data + 0*16
|
||||
.word map_data + 1*16
|
||||
.word map_data + 2*16
|
||||
.word map_data + 3*16
|
||||
.word map_data + 4*16
|
||||
.word map_data + 5*16
|
||||
.word map_data + 6*16
|
||||
.word map_data + 7*16
|
||||
.word map_data + 8*16
|
||||
.word map_data + 9*16
|
||||
.word map_data + 10*16
|
||||
.word map_data + 11*16
|
||||
.word map_data + 12*16
|
||||
.word map_data + 13*16
|
||||
.word map_data + 14*16
|
||||
.word map_data + 15*16
|
|
@ -12,18 +12,17 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
//#link "multilines.c"
|
||||
|
||||
void setup_bitmap_multi();
|
||||
void set_pixel(byte x, byte y, byte color);
|
||||
//#link "mcbitmap.c"
|
||||
#include "mcbitmap.h"
|
||||
|
||||
/* Graphics definitions */
|
||||
#define SCREEN_X 160
|
||||
#define SCREEN_Y 192
|
||||
#define MAXCOL 16
|
||||
|
||||
#define maxiterations 16
|
||||
#define maxiterations 64
|
||||
#define fpshift (10)
|
||||
#define fpone (1<<fpshift)
|
||||
#define tofp(_x) ((_x)<<fpshift)
|
||||
#define fromfp(_x) ((_x)>>fpshift)
|
||||
#define fpabs(_x) (abs(_x))
|
||||
|
@ -71,13 +70,14 @@ void mandelbrot (signed short x1, signed short y1, signed short x2,
|
|||
if (count == maxiterations) {
|
||||
color = (0);
|
||||
} else {
|
||||
color = COLORS[count % MAXCOL];
|
||||
}
|
||||
/* Set pixel */
|
||||
color = count < MAXCOL
|
||||
? COLORS[count]
|
||||
: COLORS[MAXCOL-1];
|
||||
set_pixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ int main (void)
|
|||
VIC.bgcolor0 = 0x00;
|
||||
|
||||
/* Calc mandelbrot set */
|
||||
mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2));
|
||||
mandelbrot (-fpone/2, -fpone, 0, -fpone/2);
|
||||
|
||||
/* Fetch the character from the keyboard buffer and discard it */
|
||||
cgetc ();
|
||||
|
|
|
@ -1,36 +1,35 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <c64.h>
|
||||
#include <peekpoke.h>
|
||||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include "mcbitmap.h"
|
||||
|
||||
void setup_bitmap_multi() {
|
||||
VIC.ctrl1 = 0x38;
|
||||
VIC.ctrl2 = 0x18;
|
||||
// set VIC bank ($4000-$7FFF)
|
||||
// https://www.c64-wiki.com/wiki/VIC_bank
|
||||
CIA2.pra = 0x02;
|
||||
// set VIC screen to $6000
|
||||
VIC.addr = 0x80;
|
||||
// clear bitmap and screen RAM
|
||||
memset((void*)0x4000, 0, 0x2000);
|
||||
memset((void*)0xd800, 0, 40*25);
|
||||
SET_VIC_BANK(MCB_BITMAP);
|
||||
SET_VIC_BITMAP(MCB_BITMAP);
|
||||
SET_VIC_SCREEN(MCB_COLORS);
|
||||
memset((void*)MCB_BITMAP, 0, 0x2000);
|
||||
memset((void*)MCB_COLORS, 0, 0x800);
|
||||
memset(COLOR_RAM, 0, 40*25);
|
||||
}
|
||||
|
||||
const byte PIXMASK[4] = { ~0xc0, ~0x30, ~0x0c, ~0x03 };
|
||||
const byte PIXSHIFT[4] = { 6, 4, 2, 0 };
|
||||
|
||||
byte is_pixel(byte x, byte y) {
|
||||
word ofs = ((x>>2)*8 + (y>>3)*320) | (y&7) | 0x4000;
|
||||
return PEEK(ofs) & ~PIXMASK[x & 3];
|
||||
word ofs = ((x>>2)*8 + (y>>3)*320) | (y&7) | MCB_BITMAP;
|
||||
byte pixvalue;
|
||||
ENABLE_HIMEM();
|
||||
pixvalue = PEEK(ofs);
|
||||
DISABLE_HIMEM();
|
||||
return pixvalue & ~PIXMASK[x & 3];;
|
||||
}
|
||||
|
||||
void set_pixel(byte x, byte y, byte color) {
|
||||
word ofs,b,cram,sram;
|
||||
byte ccol,scol;
|
||||
byte ccol,scol,used;
|
||||
byte val;
|
||||
|
||||
if (x >= 160 || y >= 192) return;
|
||||
|
@ -40,35 +39,44 @@ void set_pixel(byte x, byte y, byte color) {
|
|||
if (color == VIC.bgcolor0) {
|
||||
val = 0;
|
||||
} else {
|
||||
// calculate character (and color RAM) offset
|
||||
cram = ((x>>2) + (y>>3)*40);
|
||||
sram = cram | 0x6000;
|
||||
sram = cram | MCB_COLORS;
|
||||
cram |= 0xd800;
|
||||
// read color ram, screen memory, and used bits
|
||||
ENABLE_HIMEM();
|
||||
ccol = PEEK(cram);
|
||||
scol = PEEK(sram);
|
||||
// color RAM contains unused bits (0x10 and 0x20)
|
||||
used = PEEK(sram | 0x400);
|
||||
DISABLE_HIMEM();
|
||||
// unused in lower nibble of screen RAM? (value 2)
|
||||
if (color == (scol & 0xf) || !(ccol & 0x10)) {
|
||||
if (color == (scol & 0xf) || !(used & 0x10)) {
|
||||
val = 2;
|
||||
scol = (scol & 0xf0) | color;
|
||||
ccol |= 0x10;
|
||||
used |= 0x10;
|
||||
POKE(sram, scol);
|
||||
// unused in upper nibble of screen RAM? (value 1)
|
||||
} else if (color == (scol >> 4) || !(ccol & 0x20)) {
|
||||
} else if (color == (scol >> 4) || !(used & 0x20)) {
|
||||
val = 1;
|
||||
scol = (scol & 0xf) | (color << 4);
|
||||
ccol |= 0x20;
|
||||
used |= 0x20;
|
||||
POKE(sram, scol);
|
||||
// all other colors in use, use color RAM
|
||||
} else {
|
||||
val = 3;
|
||||
ccol = 0x30 | color;
|
||||
}
|
||||
used |= 0x40;
|
||||
ccol = color;
|
||||
POKE(cram, ccol);
|
||||
}
|
||||
// write to unused bit
|
||||
POKE(sram | 0x400, used);
|
||||
}
|
||||
|
||||
ofs = ((x>>2)*8 + (y>>3)*320) | (y&7) | 0x4000;
|
||||
ofs = ((x>>2)*8 + (y>>3)*320) | (y&7) | MCB_BITMAP;
|
||||
x &= 3;
|
||||
ENABLE_HIMEM();
|
||||
b = PEEK(ofs) & PIXMASK[x];
|
||||
DISABLE_HIMEM();
|
||||
if (val) {
|
||||
b |= val << PIXSHIFT[x];
|
||||
}
|
||||
|
@ -91,6 +99,7 @@ void draw_line(int x0, int y0, int x1, int y1, byte color) {
|
|||
}
|
||||
}
|
||||
|
||||
// support recursion
|
||||
#pragma static-locals(push,off)
|
||||
byte flood_fill(byte x, byte y, byte color) {
|
||||
register byte x1 = x;
|
16
presets/c64/mcbitmap.h
Normal file
16
presets/c64/mcbitmap.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#define MCB_COLORS 0xc000
|
||||
#define MCB_BITMAP 0xe000
|
||||
|
||||
void setup_bitmap_multi();
|
||||
|
||||
byte is_pixel(byte x, byte y);
|
||||
|
||||
void set_pixel(byte x, byte y, byte color);
|
||||
|
||||
void draw_line(int x0, int y0, int x1, int y1, byte color);
|
||||
|
||||
byte flood_fill(byte x, byte y, byte color);
|
||||
|
208
presets/c64/multisprite.ca65
Normal file
208
presets/c64/multisprite.ca65
Normal file
|
@ -0,0 +1,208 @@
|
|||
|
||||
VIC_BASE = $0
|
||||
VIC_SCRN_BASE = VIC_BASE + $400
|
||||
|
||||
MAX_MSPRITES = 28
|
||||
|
||||
MIN_Y_SPACING = 35
|
||||
|
||||
DEBUG = 0
|
||||
|
||||
.code
|
||||
|
||||
.global _msprite_render_init
|
||||
_msprite_render_init:
|
||||
lda #0
|
||||
sta j
|
||||
sta k
|
||||
sta $d001 ; ypos #0
|
||||
sta $d003
|
||||
sta $d005
|
||||
sta $d007
|
||||
sta $d009
|
||||
sta $d00b
|
||||
sta $d00d
|
||||
sta $d00f ; ypos #7
|
||||
lda #$ff
|
||||
sta $d015 ; sprite enable
|
||||
rts
|
||||
|
||||
.global _msprite_render_section
|
||||
_msprite_render_section:
|
||||
lda $d012
|
||||
clc
|
||||
adc #MIN_Y_SPACING
|
||||
sta bailout_line
|
||||
@loop:
|
||||
.if DEBUG
|
||||
inc $d020
|
||||
.endif
|
||||
lda $d012
|
||||
cmp bailout_line
|
||||
bcs @loopexit
|
||||
ldy k
|
||||
cpy #MAX_MSPRITES
|
||||
bcs @loopexit
|
||||
lda _msprite_order,y ; $ff = end of sprite list
|
||||
tay ; Y = sprite index from sort array
|
||||
lda j
|
||||
asl
|
||||
tax ; X = j * 2
|
||||
; if (VIC.spr_pos[j].y >= 250) break;
|
||||
lda $d001,x
|
||||
cmp #250
|
||||
bcs @loopexit ; offscreen?
|
||||
; if (VIC.spr_pos[j].y+22 >= VIC.rasterline) break;
|
||||
clc
|
||||
adc #22
|
||||
cmp $d012 ; are we done drawing
|
||||
bcs @loopexit ; this sprite yet?
|
||||
; VIC.spr_pos[j].y = msprite_y[i];
|
||||
lda _msprite_y,y
|
||||
sta $d001,x
|
||||
; VIC.spr_pos[j].x = msprite_x[i];
|
||||
lda _msprite_x_lo,y
|
||||
sta $d000,x
|
||||
ldx j ; X = j
|
||||
; VIC.spr_color[j] = msprite_color[i];
|
||||
lda _msprite_color,y
|
||||
sta $d027,x
|
||||
; POKE(0x7f8+j, msprite_shape[i]);
|
||||
lda _msprite_shape,y
|
||||
sta VIC_SCRN_BASE + $03f8,x
|
||||
; set hi X bit
|
||||
lda _msprite_x_hi,y
|
||||
lsr
|
||||
lda NOTBITS,x
|
||||
and $d010
|
||||
bcc @nohix
|
||||
ora BITS,x
|
||||
@nohix:
|
||||
sta $d010 ; update X hi bits
|
||||
inc k ; next object
|
||||
inx
|
||||
txa
|
||||
and #7
|
||||
sta j ; next h/w sprite
|
||||
jmp @loop
|
||||
@loopexit:
|
||||
.if DEBUG
|
||||
lda #0
|
||||
sta $d020
|
||||
.endif
|
||||
rts
|
||||
|
||||
; http://selmiak.bplaced.net/games/c64/index.php?lang=eng&game=Tutorials&page=Sprite-Multiplexing
|
||||
.global _msprite_sort
|
||||
_msprite_sort:
|
||||
ldx #$00
|
||||
@sortloop:
|
||||
ldy _msprite_order+1,x
|
||||
lda _msprite_y,y
|
||||
ldy _msprite_order,x
|
||||
cmp _msprite_y,y
|
||||
bcs @sortskip
|
||||
stx @sortreload+1
|
||||
@sortswap:
|
||||
lda _msprite_order+1,x
|
||||
sta _msprite_order,x
|
||||
tya
|
||||
sta _msprite_order+1,x
|
||||
cpx #$00
|
||||
beq @sortreload
|
||||
dex
|
||||
ldy _msprite_order+1,x
|
||||
lda _msprite_y,y
|
||||
ldy _msprite_order,x
|
||||
cmp _msprite_y,y
|
||||
bcc @sortswap
|
||||
@sortreload:
|
||||
ldx #$00 ; self-modifying code
|
||||
@sortskip:
|
||||
inx
|
||||
cpx #MAX_MSPRITES-1
|
||||
bcc @sortloop
|
||||
rts
|
||||
|
||||
.global _msprite_add_velocity
|
||||
_msprite_add_velocity:
|
||||
tay
|
||||
dey
|
||||
@loop:
|
||||
lda _msprite_y_frac,y
|
||||
clc
|
||||
adc _msprite_yvel_lo,y
|
||||
sta _msprite_y_frac,y
|
||||
lda _msprite_y,y
|
||||
adc _msprite_yvel_hi,y
|
||||
sta _msprite_y,y
|
||||
lda _msprite_x_frac,y
|
||||
clc
|
||||
adc _msprite_xvel_lo,y
|
||||
sta _msprite_x_frac,y
|
||||
lda _msprite_xvel_hi,y
|
||||
bmi @xneg
|
||||
lda _msprite_x_lo,y
|
||||
adc _msprite_xvel_hi,y
|
||||
sta _msprite_x_lo,y
|
||||
lda _msprite_x_hi,y
|
||||
adc #0
|
||||
sta _msprite_x_hi,y
|
||||
dey
|
||||
bpl @loop
|
||||
rts
|
||||
@xneg:
|
||||
lda _msprite_x_lo,y
|
||||
adc _msprite_xvel_hi,y
|
||||
sta _msprite_x_lo,y
|
||||
lda _msprite_x_hi,y
|
||||
adc #$ff
|
||||
sta _msprite_x_hi,y
|
||||
dey
|
||||
bpl @loop
|
||||
rts
|
||||
|
||||
BITS:
|
||||
.byte $01,$02,$04,$08,$10,$20,$40,$80
|
||||
NOTBITS:
|
||||
.byte $FE,$FD,$FB,$F7,$EF,$DF,$BF,$7F
|
||||
|
||||
;;;;;
|
||||
|
||||
.data
|
||||
|
||||
j: .res 1 ; h/w sprite index
|
||||
k: .res 1 ; object index
|
||||
bailout_line: .res 1
|
||||
|
||||
.global _msprite_order
|
||||
.global _msprite_x_lo
|
||||
.global _msprite_x_hi
|
||||
.global _msprite_y
|
||||
.global _msprite_color
|
||||
.global _msprite_shape
|
||||
.global _msprite_flags
|
||||
.global _msprite_last_y
|
||||
|
||||
_msprite_order: .res MAX_MSPRITES
|
||||
_msprite_x_lo: .res MAX_MSPRITES
|
||||
_msprite_x_hi: .res MAX_MSPRITES
|
||||
_msprite_y: .res MAX_MSPRITES
|
||||
_msprite_color: .res MAX_MSPRITES
|
||||
_msprite_shape: .res MAX_MSPRITES
|
||||
_msprite_flags: .res MAX_MSPRITES
|
||||
_msprite_last_y:.res 1
|
||||
|
||||
.global _msprite_x_frac
|
||||
.global _msprite_xvel_lo
|
||||
.global _msprite_xvel_hi
|
||||
.global _msprite_y_frac
|
||||
.global _msprite_yvel_lo
|
||||
.global _msprite_yvel_hi
|
||||
|
||||
_msprite_x_frac: .res MAX_MSPRITES
|
||||
_msprite_xvel_lo: .res MAX_MSPRITES
|
||||
_msprite_xvel_hi: .res MAX_MSPRITES
|
||||
_msprite_y_frac: .res MAX_MSPRITES
|
||||
_msprite_yvel_lo: .res MAX_MSPRITES
|
||||
_msprite_yvel_hi: .res MAX_MSPRITES
|
24
presets/c64/multisprite.h
Normal file
24
presets/c64/multisprite.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#define MAX_MSPRITES 28
|
||||
|
||||
extern byte msprite_order[MAX_MSPRITES];
|
||||
extern byte msprite_x_lo[MAX_MSPRITES];
|
||||
extern byte msprite_x_hi[MAX_MSPRITES];
|
||||
extern byte msprite_y[MAX_MSPRITES];
|
||||
extern byte msprite_color[MAX_MSPRITES];
|
||||
extern byte msprite_shape[MAX_MSPRITES];
|
||||
//extern byte msprite_flags[MAX_MSPRITES];
|
||||
extern byte msprite_xvel_lo[MAX_MSPRITES];
|
||||
extern byte msprite_xvel_hi[MAX_MSPRITES];
|
||||
extern byte msprite_yvel_lo[MAX_MSPRITES];
|
||||
extern byte msprite_yvel_hi[MAX_MSPRITES];
|
||||
|
||||
extern byte msprite_last_y;
|
||||
|
||||
void __fastcall__ msprite_render_init();
|
||||
void __fastcall__ msprite_render_section();
|
||||
void __fastcall__ msprite_sort();
|
||||
void __fastcall__ msprite_add_velocity(byte numsprites);
|
||||
|
File diff suppressed because one or more lines are too long
300
presets/c64/plasma.c
Normal file
300
presets/c64/plasma.c
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*****************************************************************************\
|
||||
** plasma test program for cc65. **
|
||||
** **
|
||||
** (w)2001 by groepaz **
|
||||
** **
|
||||
** Cleanup and porting by Ullrich von Bassewitz. **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <conio.h>
|
||||
#include <cc65.h>
|
||||
|
||||
|
||||
|
||||
#if defined(__C64__) || defined(__C128__)
|
||||
# define SCREEN1 0xE000
|
||||
# define SCREEN2 0xE400
|
||||
# define CHARSET 0xE800
|
||||
# define outb(addr,val) (*(addr)) = (val)
|
||||
# define inb(addr) (*(addr))
|
||||
#elif defined(__CBM510__)
|
||||
# define SCREEN1 0xF000
|
||||
# define SCREEN2 0xF400
|
||||
# define CHARSET 0xE000
|
||||
# define outb(addr,val) pokebsys ((unsigned)(addr), val)
|
||||
# define inb(addr) peekbsys ((unsigned)(addr))
|
||||
#elif defined(__PLUS4__)
|
||||
# define SCREEN1 0x6400
|
||||
# define SCREEN2 0x6C00
|
||||
# define CHARSET 0x7000
|
||||
# define outb(addr,val) (*(addr)) = (val)
|
||||
# define inb(addr) (*(addr))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Values for the VIC address register to switch between the two pages */
|
||||
#if defined(__PLUS4__)
|
||||
#define PAGE1 ((SCREEN1 >> 8) & 0xF8)
|
||||
#define PAGE2 ((SCREEN2 >> 8) & 0xF8)
|
||||
#define CHARADR ((CHARSET >> 8) & 0xFC)
|
||||
#else
|
||||
#define PAGE1 ((SCREEN1 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
|
||||
#define PAGE2 ((SCREEN2 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Use static local variables for speed */
|
||||
#pragma static-locals (1);
|
||||
|
||||
|
||||
static const unsigned char sinustable[0x100] = {
|
||||
0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a,
|
||||
0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52,
|
||||
0x4f, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3f, 0x3c,
|
||||
0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28,
|
||||
0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x18,
|
||||
0x16, 0x15, 0x13, 0x11, 0x10, 0x0f, 0x0d, 0x0c,
|
||||
0x0b, 0x0a, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
|
||||
0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
|
||||
0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x13, 0x15,
|
||||
0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24,
|
||||
0x26, 0x28, 0x2b, 0x2d, 0x2f, 0x32, 0x34, 0x37,
|
||||
0x39, 0x3c, 0x3f, 0x41, 0x44, 0x47, 0x4a, 0x4d,
|
||||
0x4f, 0x52, 0x55, 0x58, 0x5b, 0x5e, 0x61, 0x64,
|
||||
0x67, 0x6a, 0x6d, 0x70, 0x74, 0x77, 0x7a, 0x7d,
|
||||
0x80, 0x83, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96,
|
||||
0x99, 0x9c, 0x9f, 0xa2, 0xa5, 0xa8, 0xab, 0xae,
|
||||
0xb1, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xc1, 0xc4,
|
||||
0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd3, 0xd5, 0xd8,
|
||||
0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8,
|
||||
0xea, 0xeb, 0xed, 0xef, 0xf0, 0xf1, 0xf3, 0xf4,
|
||||
0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xfc,
|
||||
0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfd,
|
||||
0xfd, 0xfc, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf6,
|
||||
0xf5, 0xf4, 0xf3, 0xf1, 0xf0, 0xef, 0xed, 0xeb,
|
||||
0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0, 0xde, 0xdc,
|
||||
0xda, 0xd8, 0xd5, 0xd3, 0xd1, 0xce, 0xcc, 0xc9,
|
||||
0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xb9, 0xb6, 0xb3,
|
||||
0xb1, 0xae, 0xab, 0xa8, 0xa5, 0xa2, 0x9f, 0x9c,
|
||||
0x99, 0x96, 0x93, 0x90, 0x8c, 0x89, 0x86, 0x83
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void doplasma (register unsigned char* scrn)
|
||||
{
|
||||
unsigned char xbuf[40];
|
||||
unsigned char ybuf[25];
|
||||
unsigned char c1a,c1b;
|
||||
unsigned char c2a,c2b;
|
||||
unsigned char c1A,c1B;
|
||||
unsigned char c2A,c2B;
|
||||
register unsigned char i, ii;
|
||||
|
||||
c1a = c1A;
|
||||
c1b = c1B;
|
||||
for (ii = 0; ii < 25; ++ii) {
|
||||
ybuf[ii] = (sinustable[c1a] + sinustable[c1b]);
|
||||
c1a += 4;
|
||||
c1b += 9;
|
||||
}
|
||||
c1A += 3;
|
||||
c1B -= 5;
|
||||
c2a = c2A;
|
||||
c2b = c2B;
|
||||
for (i = 0; i < 40; ++i) {
|
||||
xbuf[i] = (sinustable[c2a] + sinustable[c2b]);
|
||||
c2a += 3;
|
||||
c2b += 7;
|
||||
}
|
||||
c2A += 2;
|
||||
c2B -= 3;
|
||||
for (ii = 0; ii < 25; ++ii) {
|
||||
/* Unrolling the following loop will give a speed increase of
|
||||
** nearly 100% (~24fps), but it will also increase the code
|
||||
** size a lot.
|
||||
*/
|
||||
for (i = 0; i < 40; ++i, ++scrn) {
|
||||
*scrn = (xbuf[i] + ybuf[ii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void makechar (void)
|
||||
{
|
||||
static const unsigned char bittab[8] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
|
||||
};
|
||||
unsigned char i, ii, b, s;
|
||||
unsigned c;
|
||||
|
||||
gotoxy (0, 1);
|
||||
for (c = 0; c < 0x100; ++c) {
|
||||
s = sinustable[c];
|
||||
for (i = 0; i < 8; ++i){
|
||||
b = 0;
|
||||
for (ii = 0; ii < 8; ++ii) {
|
||||
if ((rand() & 0xFFu) > s) {
|
||||
b |= bittab[ii];
|
||||
}
|
||||
}
|
||||
((unsigned char*)CHARSET) [(c*8) + i] = b;
|
||||
}
|
||||
if ((c & 0x07) == 0) {
|
||||
cputc ('.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned char border;
|
||||
unsigned char background;
|
||||
unsigned char text;
|
||||
unsigned char v;
|
||||
clock_t t;
|
||||
unsigned long f = 0;
|
||||
unsigned long sec;
|
||||
unsigned sec10;
|
||||
unsigned long fps;
|
||||
unsigned fps10;
|
||||
|
||||
|
||||
#if defined(__C64__)
|
||||
unsigned char block;
|
||||
#endif
|
||||
#if defined(__C128__)
|
||||
unsigned char block;
|
||||
unsigned char initflag;
|
||||
unsigned char graphflag;
|
||||
#endif
|
||||
#if defined(__PLUS4__)
|
||||
unsigned int i;
|
||||
unsigned char v2;
|
||||
#endif
|
||||
|
||||
clrscr ();
|
||||
cprintf ("Making charset, mompls");
|
||||
makechar();
|
||||
|
||||
/* Set the border and background colors */
|
||||
border = bordercolor (COLOR_BLUE);
|
||||
background = bgcolor (COLOR_BLUE);
|
||||
text = textcolor (COLOR_BLACK);
|
||||
clrscr ();
|
||||
|
||||
#if defined(__C64__) || defined(__C128__)
|
||||
/* Move the VIC 16K block */
|
||||
block = inb (&CIA2.pra);
|
||||
outb (&CIA2.pra, (block & 0xFC) | ((SCREEN1 >> 14) ^ 0x03));
|
||||
#endif
|
||||
#if defined(__C128__)
|
||||
/* Save and change some flags, so that kernal/basic interrupt handler will
|
||||
** not interfere with our routine.
|
||||
*/
|
||||
initflag = *(unsigned char*) 0xA04;
|
||||
*(unsigned char*) 0xA04 &= 0xFE;
|
||||
graphflag = *(unsigned char*) 0xD8;
|
||||
*(unsigned char*) 0xD8 = 0xFF;
|
||||
#endif
|
||||
|
||||
/* Remember the VIC address register */
|
||||
#if defined(__PLUS4__)
|
||||
v = inb (&TED.char_addr);
|
||||
v2 = inb (&TED.video_addr);
|
||||
#else
|
||||
v = inb (&VIC.addr);
|
||||
#endif
|
||||
|
||||
#if defined(__PLUS4__)
|
||||
for (i=0;i<1000;i++) {
|
||||
((unsigned char *) (SCREEN1-0x0400))[i] = 0;
|
||||
((unsigned char *) (SCREEN2-0x0400))[i] = 0;
|
||||
}
|
||||
outb (&TED.char_addr, CHARADR);
|
||||
#endif
|
||||
|
||||
/* Run the demo until a key was hit */
|
||||
t = clock ();
|
||||
while (!kbhit()) {
|
||||
/* Build page 1, then make it visible */
|
||||
doplasma ((unsigned char*)SCREEN1);
|
||||
#if defined(__PLUS4__)
|
||||
outb (&TED.video_addr, PAGE1);
|
||||
#else
|
||||
outb (&VIC.addr, PAGE1);
|
||||
#endif
|
||||
|
||||
/* Build page 2, then make it visible */
|
||||
doplasma ((unsigned char*)SCREEN2);
|
||||
#if defined(__PLUS4__)
|
||||
outb (&TED.video_addr, PAGE2);
|
||||
#else
|
||||
outb (&VIC.addr, PAGE2);
|
||||
#endif
|
||||
|
||||
/* Count frames */
|
||||
f += 2;
|
||||
}
|
||||
t = clock() - t;
|
||||
|
||||
/* Switch back the VIC screen */
|
||||
#if defined(__PLUS4__)
|
||||
outb (&TED.video_addr, v2);
|
||||
outb (&TED.char_addr, v);
|
||||
#else
|
||||
outb (&VIC.addr, v);
|
||||
#endif
|
||||
|
||||
#if defined(__C64__) || defined(__C128__)
|
||||
/* Move back the VIC 16K block */
|
||||
outb (&CIA2.pra, block);
|
||||
#endif
|
||||
#if defined(__C128__)
|
||||
/* Restore the flags */
|
||||
*(unsigned char*) 0xA04 = initflag;
|
||||
*(unsigned char*) 0xD8 = graphflag;
|
||||
#endif
|
||||
|
||||
/* Fetch the character from the keyboard buffer and discard it */
|
||||
(void) cgetc();
|
||||
|
||||
/* Reset screen colors */
|
||||
bordercolor (border);
|
||||
bgcolor (background);
|
||||
textcolor (text);
|
||||
clrscr ();
|
||||
|
||||
/* Calculate stats */
|
||||
sec = (t * 10) / CLK_TCK;
|
||||
sec10 = sec % 10;
|
||||
sec /= 10;
|
||||
fps = (f * (CLK_TCK * 10)) / t;
|
||||
fps10 = fps % 10;
|
||||
fps /= 10;
|
||||
|
||||
/* Output stats */
|
||||
gotoxy (0, 0); cprintf ("time : %lu.%us", sec, sec10);
|
||||
gotoxy (0, 1); cprintf ("frames: %lu", f);
|
||||
gotoxy (0, 2); cprintf ("fps : %lu.%u", fps, fps10);
|
||||
|
||||
if (doesclrscrafterexit ()) {
|
||||
cputsxy (0, 4, "Press any key when done...");
|
||||
(void) cgetc ();
|
||||
}
|
||||
|
||||
/* Done */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
111
presets/c64/rasterirq.ca65
Normal file
111
presets/c64/rasterirq.ca65
Normal file
|
@ -0,0 +1,111 @@
|
|||
|
||||
; use CC65's interrupter (slower)
|
||||
USE_INTERRUPTOR = 0
|
||||
|
||||
.segment "DATA"
|
||||
|
||||
StartDlist: .word NullDlist-1
|
||||
NextDlist: .word NullDlist-1
|
||||
|
||||
.segment "CODE"
|
||||
|
||||
.global ___dlist_setup
|
||||
.global ___dlist_done
|
||||
.global DLIST_IRQ_NEXT
|
||||
.global DLIST_IRQ_RESTART
|
||||
|
||||
.if USE_INTERRUPTOR
|
||||
.interruptor DLIST_IRQ
|
||||
.endif
|
||||
|
||||
___dlist_setup:
|
||||
sei ; set interrupt bit, make the CPU ignore interrupt requests
|
||||
|
||||
sta StartDlist+0 ; save XA as pointer to start of dlist
|
||||
stx StartDlist+1
|
||||
|
||||
lda #%01111111 ; switch off interrupt signals from CIA-1
|
||||
sta $DC0D
|
||||
|
||||
and $D011 ; clear most significant bit of VIC's raster register
|
||||
sta $D011
|
||||
|
||||
lda $DC0D ; acknowledge pending interrupts from CIA-1
|
||||
lda $DD0D ; acknowledge pending interrupts from CIA-2
|
||||
|
||||
lda #252 ; set rasterline where interrupt shall occur
|
||||
sta $D012
|
||||
|
||||
.if !USE_INTERRUPTOR
|
||||
lda #<DLIST_IRQ ; set interrupt vectors, pointing to interrupt service routine below
|
||||
sta $0314
|
||||
lda #>DLIST_IRQ
|
||||
sta $0315
|
||||
.endif
|
||||
|
||||
lda #%00000001 ; enable raster interrupt signals from VIC
|
||||
sta $D01A
|
||||
cli
|
||||
rts
|
||||
|
||||
DLIST_IRQ:
|
||||
DLIST_CALL:
|
||||
lda NextDlist+1
|
||||
pha
|
||||
lda NextDlist+0
|
||||
pha
|
||||
rts
|
||||
|
||||
DLIST_IRQ_RESTART:
|
||||
sta $D012 ; set IRQ raster line
|
||||
lda StartDlist+0
|
||||
sta NextDlist+0
|
||||
lda StartDlist+1
|
||||
sta NextDlist+1
|
||||
bne DLIST_ACK
|
||||
|
||||
DLIST_IRQ_NEXT:
|
||||
sta $D012
|
||||
pla
|
||||
sta NextDlist+0
|
||||
pla
|
||||
sta NextDlist+1
|
||||
DLIST_ACK:
|
||||
asl $D019 ; acknowledge the interrupt by clearing the VIC's interrupt flag
|
||||
.if USE_INTERRUPTOR
|
||||
clc
|
||||
rts
|
||||
.else
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti ; return from interrupt
|
||||
.endif
|
||||
|
||||
___dlist_done:
|
||||
php
|
||||
sei ; disable interrupts
|
||||
lda #$0 ; disable raster interrupt signals from VIC
|
||||
sta $D01A
|
||||
lda #$ff
|
||||
sta $DC0D
|
||||
.if !USE_INTERRUPTOR
|
||||
lda #$31 ; set interrupt vectors back to KERNAL
|
||||
sta $0314
|
||||
lda #$ea
|
||||
sta $0315
|
||||
.else
|
||||
lda #<(NullDlist-1)
|
||||
sta StartDlist
|
||||
lda #>(NullDlist-1)
|
||||
sta StartDlist+1
|
||||
.endif
|
||||
plp
|
||||
rts
|
||||
|
||||
|
||||
NullDlist:
|
||||
lda #252
|
||||
jmp DLIST_IRQ_RESTART
|
26
presets/c64/rasterirq.h
Normal file
26
presets/c64/rasterirq.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _RASTERIRQ_H
|
||||
#define _RASTERIRQ_H
|
||||
|
||||
|
||||
// internal function, use macro instead
|
||||
void __dlist_setup(void* ptr);
|
||||
void __dlist_done();
|
||||
|
||||
// initialize display list with function 'func'
|
||||
#define DLIST_SETUP(func) \
|
||||
__dlist_setup(((char*)func)-1)
|
||||
|
||||
// continue on line 'line'
|
||||
#define DLIST_NEXT(line) \
|
||||
__A__ = line; \
|
||||
asm ("jsr DLIST_IRQ_NEXT");
|
||||
|
||||
// restart display list on line 'line'
|
||||
#define DLIST_RESTART(line) \
|
||||
__A__ = line; \
|
||||
asm ("jmp DLIST_IRQ_RESTART");
|
||||
|
||||
// stop display list
|
||||
#define DLIST_DONE() __dlist_done();
|
||||
|
||||
#endif
|
29
presets/c64/screen_ram.c
Normal file
29
presets/c64/screen_ram.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include <cbm_screen_charmap.h>
|
||||
|
||||
void main(void) {
|
||||
unsigned int i;
|
||||
|
||||
clrscr(); // clear the screen
|
||||
|
||||
POKE(0x400, 'A'); // write to first byte of screen memory
|
||||
POKE(0x400, 65); // character code for 'A'
|
||||
POKE(0x400 + 40*24 + 39, 'Z'); // row 24, column 39
|
||||
|
||||
// fill with random characters
|
||||
for (i=0; i<40*25; i++)
|
||||
POKE(0x400 + i, 205 + (rand() & 1));
|
||||
|
||||
// set character set to uppercase + graphics characters
|
||||
SET_VIC_BITMAP(0x1000);
|
||||
|
||||
// set color map underlying characters
|
||||
for (i=0; i<40*25; i++)
|
||||
COLOR_RAM[i] = COLOR_GREEN;
|
||||
|
||||
// infinite loop (avoid "ready" prompt)
|
||||
while (1);
|
||||
}
|
|
@ -1,48 +1,72 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include <cbm_petscii_charmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
#define SCROLL_TOP 0
|
||||
#define SCROLL_ROWS 10
|
||||
|
||||
void rasterWait(unsigned char line) {
|
||||
while (VIC.rasterline < line) ;
|
||||
byte scroll_x = 0; // x scroll position
|
||||
|
||||
// return the next character on the right side
|
||||
// for a given row
|
||||
char get_char_for_row(byte row) {
|
||||
return '0' + row;
|
||||
}
|
||||
|
||||
byte x = 0; // x scroll position
|
||||
byte y = 0; // y scroll position
|
||||
byte* scrnbuf; // screen buffer
|
||||
void draw_right_column() {
|
||||
// get the top-right corner address of scroll area
|
||||
word addr = SCRNADR(0x400, 39, SCROLL_TOP);
|
||||
byte row;
|
||||
// draw one character per row
|
||||
for (row=0; row<SCROLL_ROWS; row++) {
|
||||
POKE(addr, get_char_for_row(row));
|
||||
addr += 40;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_one_column_left() {
|
||||
// copy several rows of screen memory
|
||||
// backwards one byte
|
||||
const word start = SCRNADR(0x400, 0, SCROLL_TOP);
|
||||
const word nbytes = SCROLL_ROWS*40-1;
|
||||
memcpy((byte*)start, (byte*)start+1, nbytes);
|
||||
// draw the right column of characters
|
||||
draw_right_column();
|
||||
}
|
||||
|
||||
void scroll_one_pixel_left() {
|
||||
// scroll left one pixel
|
||||
scroll_x -= 1;
|
||||
// set scroll register with lower three bits
|
||||
VIC.ctrl2 = (VIC.ctrl2 & ~0b111) | (scroll_x & 0b111);
|
||||
// move screen memory if the scroll register
|
||||
// has just gone past 0 and wrapped to 7
|
||||
if ((scroll_x & 0b111) == 0b111) {
|
||||
scroll_one_column_left();
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
clrscr();
|
||||
printf("\r\n Hello World!");
|
||||
printf("\r\n\r\n This is how we scroll");
|
||||
printf("\r\n\r\n One line at a time");
|
||||
printf("\r\n\r\n But we don't have time");
|
||||
printf("\r\n\r\n To copy all the bytes ");
|
||||
printf("\n Hello Scrolling World!");
|
||||
printf("\n\n We change scroll registers");
|
||||
printf("\n\n And move screen memory");
|
||||
printf("\n\n But we don't have time");
|
||||
printf("\n\n To copy all 25 rows ");
|
||||
printf("\n\n In a single frame ");
|
||||
|
||||
VIC.ctrl1 = 0x10; // 24 lines
|
||||
VIC.ctrl2 = 0x00; // 38 columns
|
||||
|
||||
// get screen buffer address
|
||||
scrnbuf = (byte*)((VIC.addr << 6) & 0x3c00);
|
||||
VIC.bordercolor = COLOR_GRAY1;
|
||||
|
||||
// infinite loop
|
||||
while (1) {
|
||||
x--;
|
||||
// set scroll registers
|
||||
VIC.ctrl1 = VIC.ctrl1 & 0xf8;
|
||||
VIC.ctrl1 |= (y & 7);
|
||||
VIC.ctrl2 = VIC.ctrl2 & 0xf8;
|
||||
VIC.ctrl2 |= (x & 7);
|
||||
// wait for vsync
|
||||
rasterWait(255);
|
||||
// every 8 pixels, move screen cells
|
||||
if ((x & 7) == 0) {
|
||||
memcpy(scrnbuf, scrnbuf+1, 40*8-1);
|
||||
}
|
||||
// wait for end of frame
|
||||
wait_vblank();
|
||||
// scroll one pixel to the left
|
||||
// and move screen memory every 8 pixels
|
||||
scroll_one_pixel_left();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,61 +1,58 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include <cbm_petscii_charmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
#define BUFFER_0 0x400
|
||||
#define BUFFER_1 0x3c00
|
||||
|
||||
void rasterWait(unsigned char line) {
|
||||
while (VIC.rasterline < line) ;
|
||||
}
|
||||
|
||||
byte x = 0; // x scroll position
|
||||
byte y = 0; // y scroll position
|
||||
byte scroll_x = 0; // x scroll position
|
||||
byte* scrnbuf[2]; // screen buffer(s)
|
||||
byte frame = 0;
|
||||
byte visbuf; // which buffer is visible? 0 or 1
|
||||
|
||||
void main(void) {
|
||||
void scroll_one_pixel_left() {
|
||||
byte* src;
|
||||
byte* dst;
|
||||
// scroll left
|
||||
scroll_x--;
|
||||
// set scroll registers
|
||||
SET_SCROLL_X(scroll_x);
|
||||
// calculate frame pointers
|
||||
// source = visible buffer
|
||||
src = scrnbuf[visbuf] + (scroll_x & 7) * 128;
|
||||
// destination = hidden buffer
|
||||
dst = scrnbuf[visbuf ^ 1] + (scroll_x & 7) * 128;
|
||||
// wait for end of frame
|
||||
wait_vblank();
|
||||
// scroll hidden buffer
|
||||
memcpy(dst, src+1, 128);
|
||||
// every 8 pixels, switch visible and hidden buffers
|
||||
// and set VIC to point to other buffer
|
||||
if ((scroll_x & 7) == 0) {
|
||||
visbuf ^= 1;
|
||||
SET_VIC_SCREEN(visbuf ? BUFFER_1 : BUFFER_0);
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
clrscr();
|
||||
printf("\r\n\r\n\r\n Hello World!");
|
||||
printf("\r\n\r\n\r\n This is how we scroll");
|
||||
printf("\r\n\r\n\r\n One line at a time");
|
||||
printf("\r\n\r\n\r\n And now we have two buffers");
|
||||
printf("\r\n\r\n\r\n To copy all the bytes ");
|
||||
printf("\n\n\n Hello Scrolling World!");
|
||||
printf("\n\n\n We scroll in one direction");
|
||||
printf("\n\n\n And now we have two buffers");
|
||||
printf("\n\n\n And copy hidden -> visible");
|
||||
printf("\n\n\n 128 bytes (of 1024) per frame");
|
||||
|
||||
VIC.ctrl1 = 0x10; // 24 lines
|
||||
VIC.ctrl2 = 0x00; // 38 columns
|
||||
VIC.bordercolor = COLOR_GRAY1;
|
||||
|
||||
// get screen buffer addresses
|
||||
scrnbuf[0] = (byte*) 0x400;
|
||||
scrnbuf[1] = (byte*) 0x3c00;
|
||||
memcpy(scrnbuf[1], scrnbuf[0], 24*40);
|
||||
scrnbuf[0] = (byte*) BUFFER_0;
|
||||
scrnbuf[1] = (byte*) BUFFER_1;
|
||||
|
||||
// infinite loop
|
||||
while (1) {
|
||||
// scroll left
|
||||
x--;
|
||||
// set scroll registers
|
||||
VIC.ctrl1 = VIC.ctrl1 & 0xf8;
|
||||
VIC.ctrl1 |= (y & 7);
|
||||
VIC.ctrl2 = VIC.ctrl2 & 0xf8;
|
||||
VIC.ctrl2 |= (x & 7);
|
||||
// calculate frame pointers
|
||||
src = scrnbuf[frame&1] + (x&7)*128;
|
||||
dst = scrnbuf[frame&1^1] + (x&7)*128;
|
||||
// wait for vsync
|
||||
rasterWait(255);
|
||||
// scroll hidden buffer
|
||||
memcpy(dst, src+1, 128);
|
||||
// every 8 pixels, switch farmes
|
||||
if ((x & 7) == 0) {
|
||||
VIC.addr = (VIC.addr & 0xf) | ((frame & 1) ? 0x10 : 0xf0);
|
||||
frame++;
|
||||
}
|
||||
scroll_one_pixel_left();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,66 +1,45 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include <cbm_petscii_charmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <joystick.h>
|
||||
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t word;
|
||||
typedef int8_t sbyte;
|
||||
|
||||
#define COLS 40
|
||||
#define ROWS 25
|
||||
|
||||
void raster_wait(unsigned char line) {
|
||||
while (VIC.rasterline < line) ;
|
||||
}
|
||||
|
||||
void wait_vblank() {
|
||||
raster_wait(255); // TODO
|
||||
}
|
||||
|
||||
sbyte scroll_fine_x = 0;
|
||||
sbyte scroll_fine_y = 0;
|
||||
byte curbuf = 0;
|
||||
byte* scrnbuf[2]; // screen buffer(s)
|
||||
byte hidbuf = 0;
|
||||
|
||||
void scroll_update_regs() {
|
||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
||||
SET_SCROLL_X(scroll_fine_x);
|
||||
SET_SCROLL_Y(scroll_fine_y);
|
||||
}
|
||||
|
||||
void scroll_swap() {
|
||||
// swap hidden and visible buffers
|
||||
curbuf ^= 1;
|
||||
// wait for vblank and update registers
|
||||
hidbuf ^= 1;
|
||||
// wait for end of frame and update registers
|
||||
wait_vblank();
|
||||
scroll_update_regs();
|
||||
VIC.addr = (VIC.addr & 0xf) | (curbuf ? 0x00 : 0x10);
|
||||
// copy visible buffer to hidden buffer
|
||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1], COLS*ROWS);
|
||||
SET_VIC_SCREEN(hidbuf ? 0x8000 : 0x8400);
|
||||
}
|
||||
|
||||
void scroll_left() {
|
||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+1, COLS*ROWS-1);
|
||||
memcpy(scrnbuf[hidbuf], scrnbuf[hidbuf^1]+1, COLS*ROWS-1);
|
||||
scroll_swap();
|
||||
}
|
||||
|
||||
void scroll_right() {
|
||||
memcpy(scrnbuf[curbuf]+1, scrnbuf[curbuf^1], COLS*ROWS-1);
|
||||
memcpy(scrnbuf[hidbuf]+1, scrnbuf[hidbuf^1], COLS*ROWS-1);
|
||||
scroll_swap();
|
||||
}
|
||||
|
||||
void scroll_up() {
|
||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+COLS, COLS*(ROWS-1));
|
||||
memcpy(scrnbuf[hidbuf], scrnbuf[hidbuf^1]+COLS, COLS*(ROWS-1));
|
||||
scroll_swap();
|
||||
}
|
||||
|
||||
void scroll_down() {
|
||||
memcpy(scrnbuf[curbuf]+COLS, scrnbuf[curbuf^1], COLS*(ROWS-1));
|
||||
memcpy(scrnbuf[hidbuf]+COLS, scrnbuf[hidbuf^1], COLS*(ROWS-1));
|
||||
scroll_swap();
|
||||
}
|
||||
|
||||
|
@ -92,29 +71,32 @@ void scroll_setup() {
|
|||
// get screen buffer addresses
|
||||
scrnbuf[0] = (byte*) 0x8000;
|
||||
scrnbuf[1] = (byte*) 0x8400;
|
||||
|
||||
// copy existing text to screen 0
|
||||
memcpy(scrnbuf[0], (byte*)0x400, COLS*ROWS);
|
||||
// copy screen 1 to screen 0
|
||||
memcpy(scrnbuf[1], scrnbuf[0], COLS*ROWS);
|
||||
|
||||
// set VIC bank ($4000-$7FFF)
|
||||
// set VIC bank
|
||||
// https://www.c64-wiki.com/wiki/VIC_bank
|
||||
CIA2.pra = 0x01;
|
||||
SET_VIC_BANK(0x8000);
|
||||
|
||||
VIC.ctrl1 = 0x10; // 24 lines
|
||||
VIC.ctrl2 = 0x00; // 38 columns
|
||||
VIC.ctrl1 &= ~0x08; // 24 lines
|
||||
VIC.ctrl2 &= ~0x08; // 38 columns
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
||||
clrscr();
|
||||
printf("\r\n\r\n\r\n Hello World!");
|
||||
printf("\r\n\r\n\r\n This is how we scroll");
|
||||
printf("\r\n\r\n\r\n One line at a time");
|
||||
printf("\r\n\r\n\r\n And now we have two buffers");
|
||||
printf("\r\n\r\n\r\n To copy all the bytes ");
|
||||
printf("\n\n\n Hello World!");
|
||||
printf("\n\n\n This is how we scroll");
|
||||
printf("\n\n\n And now we have two buffers");
|
||||
printf("\n\n\n And can go in any direction");
|
||||
printf("\n\n\n But we are not incremental");
|
||||
printf("\n\n\n And have to pause to scroll and copy");
|
||||
|
||||
scroll_setup();
|
||||
VIC.bordercolor = COLOR_GRAY1;
|
||||
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
|
@ -129,7 +111,7 @@ void main(void) {
|
|||
if (JOY_RIGHT(joy)) scroll_horiz(1);
|
||||
if (JOY_DOWN(joy)) scroll_vert(1);
|
||||
// update regs
|
||||
wait_vblank();
|
||||
waitvsync();
|
||||
scroll_update_regs();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,166 +1,54 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include "scrolling.h"
|
||||
//#link "scrolling.c"
|
||||
|
||||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
#include <cbm_petscii_charmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <joystick.h>
|
||||
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t word;
|
||||
typedef int8_t sbyte;
|
||||
|
||||
#define COLS 40
|
||||
#define ROWS 25
|
||||
|
||||
void raster_wait(unsigned char line) {
|
||||
while (VIC.rasterline < line) ;
|
||||
}
|
||||
|
||||
void wait_vblank() {
|
||||
raster_wait(255); // TODO
|
||||
}
|
||||
|
||||
sbyte scroll_fine_x;
|
||||
sbyte scroll_fine_y;
|
||||
byte origin_x;
|
||||
byte origin_y;
|
||||
byte curbuf;
|
||||
byte* scrnbuf[2]; // screen buffer(s)
|
||||
byte tempbuf[COLS*ROWS];
|
||||
|
||||
void draw_cell(byte x, byte y) {
|
||||
static void draw_cell(word ofs, byte x, byte y) {
|
||||
byte xx = x + origin_x;
|
||||
byte yy = y + origin_y;
|
||||
byte ch = xx ^ yy;
|
||||
word ofs = x+y*COLS;
|
||||
scrnbuf[curbuf][ofs] = ch; // character
|
||||
tempbuf[ofs] = ch; // color
|
||||
hidbuf[ofs] = ch; // character
|
||||
colorbuf[ofs] = ch; // color
|
||||
}
|
||||
|
||||
void scroll_draw_column(byte col) {
|
||||
byte y;
|
||||
word ofs = col;
|
||||
for (y=0; y<ROWS; y++) {
|
||||
draw_cell(col, y);
|
||||
draw_cell(ofs, col, y);
|
||||
ofs += COLS;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_draw_row(byte row) {
|
||||
byte x;
|
||||
word ofs = row * COLS;
|
||||
for (x=0; x<COLS; x++) {
|
||||
draw_cell(x, row);
|
||||
draw_cell(ofs, x, row);
|
||||
++ofs;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_update_regs() {
|
||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
||||
}
|
||||
|
||||
void scroll_swap() {
|
||||
// swap hidden and visible buffers
|
||||
curbuf ^= 1;
|
||||
// wait for vblank and update registers
|
||||
wait_vblank();
|
||||
scroll_update_regs();
|
||||
VIC.addr = (VIC.addr & 0xf) | (curbuf ? 0x00 : 0x10);
|
||||
}
|
||||
|
||||
void scroll_copy() {
|
||||
// copy temp buf to color ram
|
||||
memcpy(COLOR_RAM, tempbuf, COLS*ROWS);
|
||||
// copy visible buffer to hidden buffer
|
||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1], COLS*ROWS);
|
||||
}
|
||||
|
||||
// TODO: left and up can be faster, b/c we can copy color ram downward
|
||||
|
||||
void scroll_left() {
|
||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+1, COLS*ROWS-1);
|
||||
++origin_x;
|
||||
memcpy(tempbuf, COLOR_RAM+1, COLS*ROWS-1);
|
||||
scroll_draw_column(COLS-1);
|
||||
scroll_swap();
|
||||
scroll_copy();
|
||||
}
|
||||
|
||||
void scroll_up() {
|
||||
memcpy(scrnbuf[curbuf], scrnbuf[curbuf^1]+COLS, COLS*(ROWS-1));
|
||||
++origin_y;
|
||||
memcpy(tempbuf, COLOR_RAM+COLS, COLS*(ROWS-1));
|
||||
scroll_draw_row(ROWS-1);
|
||||
scroll_swap();
|
||||
scroll_copy();
|
||||
}
|
||||
|
||||
void scroll_right() {
|
||||
memcpy(scrnbuf[curbuf]+1, scrnbuf[curbuf^1], COLS*ROWS-1);
|
||||
--origin_x;
|
||||
memcpy(tempbuf+1, COLOR_RAM, COLS*ROWS-1);
|
||||
scroll_draw_column(0);
|
||||
scroll_swap();
|
||||
scroll_copy();
|
||||
}
|
||||
|
||||
void scroll_down() {
|
||||
memcpy(scrnbuf[curbuf]+COLS, scrnbuf[curbuf^1], COLS*(ROWS-1));
|
||||
--origin_y;
|
||||
memcpy(tempbuf+COLS, COLOR_RAM, COLS*(ROWS-1));
|
||||
scroll_draw_row(0);
|
||||
scroll_swap();
|
||||
scroll_copy();
|
||||
}
|
||||
|
||||
void scroll_horiz(sbyte delta_x) {
|
||||
scroll_fine_x += delta_x;
|
||||
while (scroll_fine_x < 0) {
|
||||
scroll_fine_x += 8;
|
||||
scroll_left();
|
||||
}
|
||||
while (scroll_fine_x >= 8) {
|
||||
scroll_fine_x -= 8;
|
||||
scroll_right();
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_vert(sbyte delta_y) {
|
||||
scroll_fine_y += delta_y;
|
||||
while (scroll_fine_y < 0) {
|
||||
scroll_fine_y += 8;
|
||||
scroll_up();
|
||||
}
|
||||
while (scroll_fine_y >= 8) {
|
||||
scroll_fine_y -= 8;
|
||||
scroll_down();
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_setup() {
|
||||
scroll_fine_x = 0;
|
||||
scroll_fine_y = 0;
|
||||
origin_x = 0x80;
|
||||
origin_y = 0x80;
|
||||
curbuf = 0;
|
||||
// get screen buffer addresses
|
||||
scrnbuf[0] = (byte*) 0x8000;
|
||||
scrnbuf[1] = (byte*) 0x8400;
|
||||
// copy existing text to screen 0
|
||||
memcpy(scrnbuf[0], (byte*)0x400, COLS*ROWS);
|
||||
// copy screen 1 to screen 0
|
||||
memcpy(scrnbuf[1], scrnbuf[0], COLS*ROWS);
|
||||
|
||||
// set VIC bank ($4000-$7FFF)
|
||||
// https://www.c64-wiki.com/wiki/VIC_bank
|
||||
CIA2.pra = 0x01;
|
||||
|
||||
VIC.ctrl1 = 0x10; // 24 lines
|
||||
VIC.ctrl2 = 0x00; // 38 columns
|
||||
}
|
||||
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||
const char SPRITE1[3*21] = {
|
||||
0x80,0x7F,0x01,0x01,0xFF,0xC0,0x03,0xFF,0xE0,
|
||||
0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0,
|
||||
0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0,
|
||||
0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40,
|
||||
0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80,
|
||||
0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00,
|
||||
0x00,0x3E,0x00,0x00,0x3E,0x00,0x80,0x1C,0x01
|
||||
};
|
||||
|
||||
void main(void) {
|
||||
sbyte n =0;
|
||||
byte n = 0;
|
||||
|
||||
clrscr();
|
||||
printf("\r\n\r\n\r\n Hello World!");
|
||||
|
@ -169,22 +57,38 @@ void main(void) {
|
|||
printf("\r\n\r\n\r\n So we have to use a temp buffer");
|
||||
printf("\r\n\r\n\r\n And copy it just in time");
|
||||
|
||||
// setup scrolling library
|
||||
scroll_setup();
|
||||
VIC.bordercolor = 12;
|
||||
|
||||
// setup sprite library and copy sprite to VIC bank
|
||||
sprite_clear();
|
||||
sprite_set_shapes(SPRITE1, 192, 1);
|
||||
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
|
||||
// infinite loop
|
||||
while (1) {
|
||||
static char speed = 1;
|
||||
// get joystick bits
|
||||
char joy = joy_read(0);
|
||||
// speed up scrolling while button pressed
|
||||
speed = JOY_BTN_1(joy) ? 2 : 1;
|
||||
// move sprite based on arrow keys
|
||||
if (JOY_LEFT(joy)) scroll_horiz(-1);
|
||||
if (JOY_UP(joy)) scroll_vert(-1);
|
||||
if (JOY_RIGHT(joy)) scroll_horiz(1);
|
||||
if (JOY_DOWN(joy)) scroll_vert(1);
|
||||
// update regs
|
||||
if (JOY_LEFT(joy)) scroll_horiz(-speed);
|
||||
if (JOY_UP(joy)) scroll_vert(-speed);
|
||||
if (JOY_RIGHT(joy)) scroll_horiz(speed);
|
||||
if (JOY_DOWN(joy)) scroll_vert(speed);
|
||||
// animate sprite in shadow sprite ram
|
||||
sprite_draw(0, n++, 70, 192);
|
||||
sprite_draw(0, 172, 145, 192);
|
||||
// wait for end of frame
|
||||
wait_vblank();
|
||||
scroll_update_regs();
|
||||
// update scroll registers
|
||||
// and swap screens if we must
|
||||
scroll_update();
|
||||
// then update sprite registers
|
||||
sprite_update(visbuf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include <cbm_petscii_charmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <joystick.h>
|
||||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
|
@ -17,26 +8,31 @@
|
|||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
static void draw_cell(byte x, byte y) {
|
||||
#include <cbm_petscii_charmap.h>
|
||||
|
||||
static void draw_cell(word ofs, byte x, byte y) {
|
||||
byte xx = x + origin_x;
|
||||
byte yy = y + origin_y;
|
||||
byte ch = xx ^ yy;
|
||||
word ofs = x+y*COLS;
|
||||
hidbuf[ofs] = ch; // character
|
||||
colorbuf[ofs] = ch; // color
|
||||
}
|
||||
|
||||
void scroll_draw_column(byte col) {
|
||||
byte y;
|
||||
word ofs = col;
|
||||
for (y=0; y<ROWS; y++) {
|
||||
draw_cell(col, y);
|
||||
draw_cell(ofs, col, y);
|
||||
ofs += COLS;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_draw_row(byte row) {
|
||||
byte x;
|
||||
word ofs = row * COLS;
|
||||
for (x=0; x<COLS; x++) {
|
||||
draw_cell(x, row);
|
||||
draw_cell(ofs, x, row);
|
||||
++ofs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,43 +47,82 @@ const char SPRITE1[3*21] = {
|
|||
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||
};
|
||||
|
||||
int playerx = 0;
|
||||
int playery = 0;
|
||||
int camerax = 0;
|
||||
int cameray = 0;
|
||||
|
||||
void update_player() {
|
||||
sprite_draw(0, playerx-camerax+160, playery-cameray+140, 192);
|
||||
}
|
||||
|
||||
void camera_follow(byte moving) {
|
||||
int dx, dy;
|
||||
dx = camerax - playerx;
|
||||
dy = cameray - playery;
|
||||
if (moving && abs(dx) < 32 && abs(dy) < 32) return;
|
||||
dx >>= 4;
|
||||
dy >>= 4;
|
||||
if (dx) {
|
||||
if (dx > 8) dx = 8;
|
||||
else if (dx < -8) dx = -8;
|
||||
camerax -= dx;
|
||||
}
|
||||
if (dy) {
|
||||
if (dy > 8) dy = 8;
|
||||
else if (dy < -8) dy = -8;
|
||||
cameray -= dy;
|
||||
}
|
||||
scroll_xy(dx, dy);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
byte n = 0;
|
||||
|
||||
clrscr();
|
||||
printf("\r\n\r\n\r\n Hello World!");
|
||||
printf("\r\n\r\n\r\n This is how we scroll");
|
||||
printf("\r\n\r\n\r\n But color RAM can't move");
|
||||
printf("\r\n\r\n\r\n So we have to use a temp buffer");
|
||||
printf("\r\n\r\n\r\n And copy it just in time");
|
||||
printf("\r\n\r\n\r\n Use the joystick to move");
|
||||
printf("\r\n\r\n\r\n And the camera will follow");
|
||||
|
||||
// setup scrolling library
|
||||
scroll_setup();
|
||||
VIC.bordercolor = 12;
|
||||
|
||||
// setup sprite library and copy sprite to VIC bank
|
||||
sprite_clear();
|
||||
sprite_shape(hidbuf, 32, SPRITE1);
|
||||
sprite_set_shapes(SPRITE1, 192, 1);
|
||||
sprshad.spr_color[0] = 13;
|
||||
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
|
||||
// infinite loop
|
||||
while (1) {
|
||||
static char speed;
|
||||
static char joy;
|
||||
static bool slowframe = false;
|
||||
// get joystick bits
|
||||
char joy = joy_read(0);
|
||||
joy = joy_read(0);
|
||||
// speed up scrolling while button pressed
|
||||
speed = JOY_BTN_1(joy) ? 3 : 1;
|
||||
// if we copied screen memory last frame,
|
||||
// double speed of player for this frame
|
||||
if (slowframe) speed *= 2;
|
||||
// move sprite based on arrow keys
|
||||
if (JOY_LEFT(joy)) scroll_horiz(-1);
|
||||
if (JOY_UP(joy)) scroll_vert(-1);
|
||||
if (JOY_RIGHT(joy)) scroll_horiz(1);
|
||||
if (JOY_DOWN(joy)) scroll_vert(1);
|
||||
if (JOY_LEFT(joy)) playerx -= speed;
|
||||
if (JOY_RIGHT(joy)) playerx += speed;
|
||||
if (JOY_UP(joy)) playery -= speed;
|
||||
if (JOY_DOWN(joy)) playery += speed;
|
||||
// move the camera?
|
||||
camera_follow(joy);
|
||||
slowframe = swap_needed;
|
||||
// animate sprite in shadow sprite ram
|
||||
sprite_draw(0, n++, 70, 32);
|
||||
// wait for vblank
|
||||
update_player();
|
||||
// wait for end of frame
|
||||
wait_vblank();
|
||||
// then update sprite registers
|
||||
sprite_update(visbuf);
|
||||
// update scroll registers
|
||||
// and swap screens if we must
|
||||
scroll_update();
|
||||
// then update sprite registers
|
||||
sprite_update(visbuf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,53 +11,123 @@ byte* hidbuf;
|
|||
byte* visbuf;
|
||||
byte colorbuf[COLS*ROWS];
|
||||
byte swap_needed;
|
||||
byte copy_needed;
|
||||
|
||||
//
|
||||
|
||||
void scroll_swap(void) {
|
||||
void scroll_swap() {
|
||||
byte* tmp;
|
||||
// set VIC bank address
|
||||
VIC.addr = (VIC.addr & 0xf) | (((word)hidbuf >> 8) << 2);
|
||||
// swap hidden and visible buffers
|
||||
tmp = hidbuf;
|
||||
hidbuf = visbuf;
|
||||
visbuf = tmp;
|
||||
// set VIC bank address
|
||||
SET_VIC_SCREEN((word)visbuf);
|
||||
}
|
||||
|
||||
void scroll_copy(void) {
|
||||
// copy temp buf to color ram
|
||||
void copy_color_ram_slow() {
|
||||
memcpy(COLOR_RAM, colorbuf, COLS*ROWS);
|
||||
// copy visible buffer to hidden buffer
|
||||
}
|
||||
|
||||
void copy_color_ram_fast() {
|
||||
// fast copy loop for upper 1/2 of color ram
|
||||
asm("ldy #0");
|
||||
asm("@loop:");
|
||||
asm("lda %v,y", colorbuf);
|
||||
asm("sta $d800,y");
|
||||
asm("lda %v + $100,y", colorbuf);
|
||||
asm("sta $d900,y");
|
||||
asm("iny");
|
||||
asm("bne @loop");
|
||||
// second loop for lower 1/2 of color ram
|
||||
asm("@loop2:");
|
||||
asm("lda %v + $200,y", colorbuf);
|
||||
asm("sta $da00,y");
|
||||
asm("lda %v + $300,y", colorbuf);
|
||||
asm("sta $db00,y");
|
||||
asm("@skip: iny");
|
||||
asm("bne @loop2");
|
||||
}
|
||||
|
||||
void copy_to_hidden_buffer_slow() {
|
||||
memcpy(hidbuf, visbuf, COLS*ROWS);
|
||||
}
|
||||
|
||||
void scroll_update(void) {
|
||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
||||
if (swap_needed) {
|
||||
scroll_swap();
|
||||
scroll_copy();
|
||||
swap_needed = 0;
|
||||
void copy_to_hidden_buffer_fast() {
|
||||
// self-modifying code
|
||||
asm("ldy %v+1", visbuf);
|
||||
asm("sty @loop+2+6*0");
|
||||
asm("iny");
|
||||
asm("sty @loop+2+6*1");
|
||||
asm("iny");
|
||||
asm("sty @loop+2+6*2");
|
||||
asm("iny");
|
||||
asm("sty @skip-1-3");
|
||||
asm("ldy %v+1", hidbuf);
|
||||
asm("sty @loop+5+6*0");
|
||||
asm("iny");
|
||||
asm("sty @loop+5+6*1");
|
||||
asm("iny");
|
||||
asm("sty @loop+5+6*2");
|
||||
asm("iny");
|
||||
asm("sty @skip-1");
|
||||
// fast copy loop
|
||||
asm("ldy #0");
|
||||
asm("@loop:");
|
||||
asm("lda $8000,y");
|
||||
asm("sta $8000,y");
|
||||
asm("lda $8100,y");
|
||||
asm("sta $8100,y");
|
||||
asm("lda $8200,y");
|
||||
asm("sta $8200,y");
|
||||
asm("cpy #$e8");
|
||||
asm("bcs @skip");
|
||||
asm("lda $8300,y");
|
||||
asm("sta $8300,y");
|
||||
asm("@skip: iny");
|
||||
asm("bne @loop");
|
||||
}
|
||||
|
||||
void copy_if_needed() {
|
||||
if (copy_needed) {
|
||||
copy_to_hidden_buffer_fast();
|
||||
copy_needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_left(void) {
|
||||
memcpy(hidbuf, hidbuf+1, COLS*ROWS-1);
|
||||
memcpy(colorbuf, colorbuf+1, COLS*ROWS-1);
|
||||
void scroll_update() {
|
||||
SET_SCROLL_X(scroll_fine_x);
|
||||
SET_SCROLL_Y(scroll_fine_y);
|
||||
if (swap_needed) {
|
||||
scroll_swap();
|
||||
copy_color_ram_fast();
|
||||
swap_needed = false;
|
||||
copy_needed = true;
|
||||
} else {
|
||||
copy_if_needed();
|
||||
}
|
||||
}
|
||||
|
||||
static void scroll_left() {
|
||||
copy_if_needed();
|
||||
memmove(hidbuf, hidbuf+1, COLS*ROWS-1);
|
||||
memmove(colorbuf, colorbuf+1, COLS*ROWS-1);
|
||||
++origin_x;
|
||||
scroll_draw_column(COLS-1);
|
||||
swap_needed = true;
|
||||
}
|
||||
|
||||
void scroll_up(void) {
|
||||
memcpy(hidbuf, hidbuf+COLS, COLS*(ROWS-1));
|
||||
memcpy(colorbuf, colorbuf+COLS, COLS*(ROWS-1));
|
||||
static void scroll_up() {
|
||||
copy_if_needed();
|
||||
memmove(hidbuf, hidbuf+COLS, COLS*(ROWS-1));
|
||||
memmove(colorbuf, colorbuf+COLS, COLS*(ROWS-1));
|
||||
++origin_y;
|
||||
scroll_draw_row(ROWS-1);
|
||||
swap_needed = true;
|
||||
}
|
||||
|
||||
void scroll_right(void) {
|
||||
static void scroll_right() {
|
||||
copy_if_needed();
|
||||
memmove(hidbuf+1, hidbuf, COLS*ROWS-1);
|
||||
memmove(colorbuf+1, colorbuf, COLS*ROWS-1);
|
||||
--origin_x;
|
||||
|
@ -65,7 +135,8 @@ void scroll_right(void) {
|
|||
swap_needed = true;
|
||||
}
|
||||
|
||||
void scroll_down(void) {
|
||||
static void scroll_down() {
|
||||
copy_if_needed();
|
||||
memmove(hidbuf+COLS, hidbuf, COLS*(ROWS-1));
|
||||
memmove(colorbuf+COLS, colorbuf, COLS*(ROWS-1));
|
||||
--origin_y;
|
||||
|
@ -97,23 +168,31 @@ void scroll_vert(sbyte delta_y) {
|
|||
}
|
||||
}
|
||||
|
||||
void scroll_setup(void) {
|
||||
scroll_fine_x = scroll_fine_y = 0;
|
||||
origin_x = origin_y = 0x80;
|
||||
swap_needed = true;
|
||||
void scroll_xy(sbyte delta_x, sbyte delta_y) {
|
||||
if (delta_x) scroll_horiz(delta_x);
|
||||
if (delta_y) scroll_vert(delta_y);
|
||||
}
|
||||
|
||||
// get screen buffer addresses
|
||||
void scroll_setup() {
|
||||
scroll_fine_x = scroll_fine_y = 0;
|
||||
origin_x = origin_y = 0;
|
||||
swap_needed = true;
|
||||
copy_needed = true;
|
||||
|
||||
// setup screen buffer addresses
|
||||
hidbuf = (byte*) 0x8000;
|
||||
visbuf = (byte*) 0x8400;
|
||||
// copy existing text to screen 0
|
||||
|
||||
// copy existing screen contents to hidden buffer
|
||||
memcpy(hidbuf, (byte*)0x400, COLS*ROWS);
|
||||
// copy screen 1 to screen 0
|
||||
// copy also to hidden buffer
|
||||
memcpy(visbuf, hidbuf, COLS*ROWS);
|
||||
|
||||
// set VIC bank ($4000-$7FFF)
|
||||
// set VIC bank ($8000-$BFFF)
|
||||
// https://www.c64-wiki.com/wiki/VIC_bank
|
||||
CIA2.pra = 0x01;
|
||||
SET_VIC_BANK(0x8000);
|
||||
|
||||
// set up 24 line / 38 column mode to hide edges
|
||||
VIC.ctrl1 &= ~0x08; // 24 lines
|
||||
VIC.ctrl2 &= ~0x08; // 38 columns
|
||||
}
|
||||
|
|
|
@ -20,14 +20,32 @@ extern byte swap_needed; // TRUE if scroll_update() swaps
|
|||
void scroll_setup(void);
|
||||
|
||||
// scroll in X or Y directions
|
||||
void scroll_xy(sbyte delta_x, sbyte delta_y);
|
||||
void scroll_horiz(sbyte delta_x);
|
||||
void scroll_vert(sbyte delta_y);
|
||||
|
||||
// call this after vblank
|
||||
// call this right after vblank
|
||||
void scroll_update(void);
|
||||
|
||||
// caller must implement these two
|
||||
void scroll_draw_column(byte col);
|
||||
void scroll_draw_row(byte row);
|
||||
|
||||
|
||||
/* incremental scrolling library */
|
||||
extern int pixofs_x; // X scroll pixel offset
|
||||
extern int pixofs_y; // Y scroll pixel offset
|
||||
extern sbyte fine_correct_x;
|
||||
extern sbyte fine_correct_y;
|
||||
|
||||
void scroll_start(byte dir);
|
||||
void scroll_finish(void);
|
||||
void scroll_refresh(void);
|
||||
|
||||
#define SCROLL_LEFT 1
|
||||
#define SCROLL_RIGHT 2
|
||||
#define SCROLL_UP 4
|
||||
#define SCROLL_DOWN 8
|
||||
|
||||
|
||||
#endif
|
||||
|
|
281
presets/c64/scrolling2.c
Normal file
281
presets/c64/scrolling2.c
Normal file
|
@ -0,0 +1,281 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "scrolling.h"
|
||||
|
||||
#define VICBANK 0x8000
|
||||
#define BUFFER_A (byte*) 0x8000
|
||||
#define BUFFER_B (byte*) 0x8400
|
||||
|
||||
sbyte scroll_fine_x;
|
||||
sbyte scroll_fine_y;
|
||||
byte origin_x;
|
||||
byte origin_y;
|
||||
byte* hidbuf;
|
||||
byte* visbuf;
|
||||
byte colorbuf[COLS*ROWS];
|
||||
int pixofs_x;
|
||||
int pixofs_y;
|
||||
sbyte fine_correct_x;
|
||||
sbyte fine_correct_y;
|
||||
|
||||
byte scroll_dir;
|
||||
byte scroll_seq;
|
||||
|
||||
//
|
||||
|
||||
static void wait_offscreen(void) {
|
||||
while (VIC.rasterline < 250 && VIC.rasterline > 40) ;
|
||||
}
|
||||
|
||||
void scroll_swap(void) {
|
||||
byte* tmp;
|
||||
// swap hidden and visible buffers
|
||||
tmp = hidbuf;
|
||||
hidbuf = visbuf;
|
||||
visbuf = tmp;
|
||||
// set VIC bank address
|
||||
wait_offscreen();
|
||||
VIC.addr = (VIC.addr & 0xf) | (((word)visbuf >> 8) << 2);
|
||||
}
|
||||
|
||||
void copy_color_ram_slow() {
|
||||
memcpy(COLOR_RAM, colorbuf, COLS*ROWS);
|
||||
}
|
||||
|
||||
void copy_color_ram_fast() {
|
||||
// fast copy loop for upper 1/2 of color ram
|
||||
asm("ldy #0");
|
||||
asm("@loop:");
|
||||
asm("lda %v,y", colorbuf);
|
||||
asm("sta $d800,y");
|
||||
asm("lda %v + $100,y", colorbuf);
|
||||
asm("sta $d900,y");
|
||||
asm("iny");
|
||||
asm("bne @loop");
|
||||
// second loop for lower 1/2 of color ram
|
||||
asm("@loop2:");
|
||||
asm("lda %v + $200,y", colorbuf);
|
||||
asm("sta $da00,y");
|
||||
asm("lda %v + $300,y", colorbuf);
|
||||
asm("sta $db00,y");
|
||||
asm("@skip: iny");
|
||||
asm("bne @loop2");
|
||||
}
|
||||
|
||||
void copy_to_hidden_buffer_slow() {
|
||||
memcpy(hidbuf, visbuf, COLS*ROWS);
|
||||
}
|
||||
|
||||
void copy_to_hidden_buffer_fast() {
|
||||
// self-modifying code
|
||||
asm("ldy %v+1", visbuf);
|
||||
asm("sty @loop+2+6*0");
|
||||
asm("iny");
|
||||
asm("sty @loop+2+6*1");
|
||||
asm("iny");
|
||||
asm("sty @loop+2+6*2");
|
||||
asm("iny");
|
||||
asm("sty @skip-1-3");
|
||||
asm("ldy %v+1", hidbuf);
|
||||
asm("sty @loop+5+6*0");
|
||||
asm("iny");
|
||||
asm("sty @loop+5+6*1");
|
||||
asm("iny");
|
||||
asm("sty @loop+5+6*2");
|
||||
asm("iny");
|
||||
asm("sty @skip-1");
|
||||
// fast copy loop
|
||||
asm("ldy #0");
|
||||
asm("@loop:");
|
||||
asm("lda $8000,y");
|
||||
asm("sta $8000,y");
|
||||
asm("lda $8100,y");
|
||||
asm("sta $8100,y");
|
||||
asm("lda $8200,y");
|
||||
asm("sta $8200,y");
|
||||
asm("cpy #$e8");
|
||||
asm("bcs @skip");
|
||||
asm("lda $8300,y");
|
||||
asm("sta $8300,y");
|
||||
asm("@skip: iny");
|
||||
asm("bne @loop");
|
||||
}
|
||||
|
||||
void scroll_start(byte dir) {
|
||||
if (scroll_seq == 0 && dir) {
|
||||
scroll_dir = dir;
|
||||
scroll_seq = 8;
|
||||
// correct sprites b/c our fine offset is one pixel
|
||||
// off depending on last scroll direction
|
||||
if (dir & SCROLL_LEFT) fine_correct_x = 1;
|
||||
else if (dir & SCROLL_RIGHT) fine_correct_x = 0;
|
||||
if (dir & SCROLL_UP) fine_correct_y = 1;
|
||||
else if (dir & SCROLL_DOWN) fine_correct_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_step_move_buffer(char* src, char* dst) {
|
||||
word size = COLS*ROWS;
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
++src;
|
||||
--size;
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
++dst;
|
||||
--size;
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
src += COLS;
|
||||
size -= COLS;
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
dst += COLS;
|
||||
size -= COLS;
|
||||
}
|
||||
memmove(dst, src, size);
|
||||
}
|
||||
|
||||
void scroll_step_draw_cells() {
|
||||
if (scroll_dir & SCROLL_UP) ++origin_y;
|
||||
if (scroll_dir & SCROLL_DOWN) --origin_y;
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
++origin_x;
|
||||
scroll_draw_column(COLS-1);
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
--origin_x;
|
||||
scroll_draw_column(0);
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
scroll_draw_row(ROWS-1);
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
scroll_draw_row(0);
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_step_move_sprites() {
|
||||
// copy sprites from visible to hidden buffer
|
||||
memcpy(hidbuf + 0x3f8, visbuf + 0x3f8, 8);
|
||||
}
|
||||
|
||||
void scroll_update_pixofs() {
|
||||
// fine scroll starts at 8-5 = 32107 or 12-8 = 45670
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
pixofs_x -= 1;
|
||||
scroll_fine_x = (scroll_seq - 5) & 7;
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
pixofs_x += 1;
|
||||
scroll_fine_x = (12 - scroll_seq) & 7;
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
pixofs_y -= 1;
|
||||
scroll_fine_y = (scroll_seq - 5) & 7;
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
pixofs_y += 1;
|
||||
scroll_fine_y = (12 - scroll_seq) & 7;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_offset_sprites(byte delta) {
|
||||
byte dx = 0;
|
||||
byte dy = 0;
|
||||
// fine scroll starts at 8-5 = 32107 or 12-8 = 45670
|
||||
if (scroll_dir & SCROLL_LEFT) {
|
||||
dx = -delta;
|
||||
}
|
||||
if (scroll_dir & SCROLL_RIGHT) {
|
||||
dx = delta;
|
||||
}
|
||||
if (scroll_dir & SCROLL_UP) {
|
||||
dy = -delta;
|
||||
}
|
||||
if (scroll_dir & SCROLL_DOWN) {
|
||||
dy = delta;
|
||||
}
|
||||
VIC.spr_pos[0].x += dx;
|
||||
VIC.spr_pos[1].x += dx;
|
||||
VIC.spr_pos[0].y += dy;
|
||||
VIC.spr_pos[1].y += dy;
|
||||
}
|
||||
|
||||
void scroll_update_scroll_regs() {
|
||||
wait_offscreen();
|
||||
VIC.ctrl1 = (VIC.ctrl1 & 0xf8) | scroll_fine_y;
|
||||
VIC.ctrl2 = (VIC.ctrl2 & 0xf8) | scroll_fine_x;
|
||||
}
|
||||
|
||||
void scroll_next_step(void) {
|
||||
switch (--scroll_seq) {
|
||||
case 7:
|
||||
scroll_step_move_buffer(visbuf, hidbuf);
|
||||
break;
|
||||
case 6:
|
||||
scroll_step_move_buffer(colorbuf, colorbuf);
|
||||
break;
|
||||
case 5:
|
||||
scroll_step_draw_cells();
|
||||
break;
|
||||
case 4:
|
||||
scroll_step_move_sprites();
|
||||
break;
|
||||
case 3:
|
||||
scroll_swap();
|
||||
copy_color_ram_fast();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_update(void) {
|
||||
if (scroll_seq) {
|
||||
scroll_update_pixofs();
|
||||
scroll_update_scroll_regs();
|
||||
scroll_offset_sprites(1);
|
||||
scroll_next_step();
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_finish(void) {
|
||||
while (scroll_seq) {
|
||||
scroll_update_pixofs();
|
||||
if (scroll_seq == 4) { scroll_offset_sprites(8); }
|
||||
scroll_next_step();
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_setup(void) {
|
||||
origin_x = origin_y = 0;
|
||||
pixofs_x = pixofs_y = 0;
|
||||
scroll_fine_x = scroll_fine_y = 3;
|
||||
scroll_dir = 0;
|
||||
scroll_seq = 0;
|
||||
|
||||
// setup screen buffer addresses
|
||||
hidbuf = BUFFER_A;
|
||||
visbuf = BUFFER_B;
|
||||
|
||||
memset(BUFFER_A, 0, 0x800);
|
||||
memset(colorbuf, 0, sizeof(colorbuf));
|
||||
|
||||
SET_VIC_BANK(VICBANK);
|
||||
|
||||
// set up 24 line / 38 column mode to hide edges
|
||||
VIC.ctrl1 &= ~0x08; // 24 lines
|
||||
VIC.ctrl2 &= ~0x08; // 38 columns
|
||||
}
|
||||
|
||||
void scroll_refresh(void) {
|
||||
byte i;
|
||||
for (i=0; i<25; i++) {
|
||||
scroll_draw_row(i);
|
||||
}
|
||||
scroll_swap();
|
||||
copy_color_ram_fast();
|
||||
copy_to_hidden_buffer_fast();
|
||||
scroll_dir = 0;
|
||||
scroll_seq = 0;
|
||||
scroll_fine_x = scroll_fine_y = 3;
|
||||
}
|
162
presets/c64/scrolling_text.c
Normal file
162
presets/c64/scrolling_text.c
Normal file
File diff suppressed because one or more lines are too long
179
presets/c64/scrollingmap1.c
Normal file
179
presets/c64/scrollingmap1.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
#include <cbm_petscii_charmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <joystick.h>
|
||||
|
||||
//#resource "c64-sid.cfg"
|
||||
#define CFGFILE c64-sid.cfg
|
||||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include "scrolling.h"
|
||||
//#link "scrolling.c"
|
||||
|
||||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
//#link "level1.ca65"
|
||||
|
||||
extern const byte charset_data[];
|
||||
extern const byte charset_attrib_data[];
|
||||
extern const byte chartileset_data[];
|
||||
extern const byte chartileset_tag_data[];
|
||||
extern const byte* map_row_pointers[];
|
||||
|
||||
#define MAP_COLS 28
|
||||
#define MAP_ROWS 11
|
||||
|
||||
static void draw_cell(word ofs, byte x, byte y) {
|
||||
sbyte xx = x + origin_x;
|
||||
sbyte yy = y + origin_y;
|
||||
sbyte col = xx >> 2;
|
||||
sbyte row = yy >> 2;
|
||||
byte xofs = xx & 3;
|
||||
byte yofs = yy & 3;
|
||||
char ch;
|
||||
char color;
|
||||
if (col < 0 || col >= MAP_COLS || row < 0 || row >= MAP_ROWS) {
|
||||
ch = 0;
|
||||
color = 0;
|
||||
} else {
|
||||
byte tileindex = map_row_pointers[row][col];
|
||||
ch = chartileset_data[xofs + yofs*4 + tileindex*16];
|
||||
color = charset_attrib_data[ch];
|
||||
}
|
||||
hidbuf[ofs] = ch;
|
||||
colorbuf[ofs] = color;
|
||||
}
|
||||
|
||||
void scroll_draw_column(byte col) {
|
||||
byte y;
|
||||
word ofs = col;
|
||||
for (y=0; y<ROWS; y++) {
|
||||
draw_cell(ofs, col, y);
|
||||
ofs += COLS;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_draw_row(byte row) {
|
||||
byte x;
|
||||
word ofs = row * COLS;
|
||||
for (x=0; x<COLS; x++) {
|
||||
draw_cell(ofs, x, row);
|
||||
++ofs;
|
||||
}
|
||||
}
|
||||
|
||||
/*{w:24,h:21,bpp:1,brev:1}*/
|
||||
const char SPRITE1[3*21] = {
|
||||
0x00,0x7F,0x00,0x01,0xFF,0xC0,0x03,0xFF,0xE0,
|
||||
0x03,0xE7,0xE0,0x07,0xD9,0xF0,0x07,0xDF,0xF0,
|
||||
0x07,0xD9,0xF0,0x03,0xE7,0xE0,0x03,0xFF,0xE0,
|
||||
0x03,0xFF,0xE0,0x02,0xFF,0xA0,0x01,0x7F,0x40,
|
||||
0x01,0x3E,0x40,0x00,0x9C,0x80,0x00,0x9C,0x80,
|
||||
0x00,0x49,0x00,0x00,0x49,0x00,0x00,0x3E,0x00,
|
||||
0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00
|
||||
};
|
||||
|
||||
int playerx = 0;
|
||||
int playery = 0;
|
||||
int camerax = 0;
|
||||
int cameray = 0;
|
||||
|
||||
void update_player() {
|
||||
sprite_draw(0, playerx-camerax+172, playery-cameray+140, 255);
|
||||
}
|
||||
|
||||
void camera_follow(byte moving) {
|
||||
int dx, dy;
|
||||
dx = camerax - playerx;
|
||||
dy = cameray - playery;
|
||||
if (moving && abs(dx) < 32 && abs(dy) < 32) return;
|
||||
dx >>= 4;
|
||||
dy >>= 4;
|
||||
if (dx) {
|
||||
if (dx > 8) dx = 8;
|
||||
else if (dx < -8) dx = -8;
|
||||
camerax -= dx;
|
||||
scroll_horiz(dx);
|
||||
}
|
||||
if (dy) {
|
||||
if (dy > 8) dy = 8;
|
||||
else if (dy < -8) dy = -8;
|
||||
cameray -= dy;
|
||||
scroll_vert(dy);
|
||||
}
|
||||
}
|
||||
|
||||
void refresh_world(void) {
|
||||
byte i;
|
||||
for (i=0; i<25; i++) {
|
||||
scroll_draw_row(i);
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
||||
clrscr();
|
||||
|
||||
// setup scrolling library
|
||||
scroll_setup();
|
||||
|
||||
// multicolor character mode
|
||||
VIC.ctrl2 |= 0x10;
|
||||
VIC.bgcolor0 = 6;
|
||||
VIC.bgcolor1 = 0;
|
||||
VIC.bgcolor2 = 1;
|
||||
|
||||
// select character set @ 0x8800
|
||||
VIC.addr = 0x12;
|
||||
memcpy((char*)0x8800, charset_data, 520);
|
||||
|
||||
// setup sprite library and copy sprite to VIC bank
|
||||
sprite_clear();
|
||||
sprite_set_shapes(SPRITE1, 255, 1);
|
||||
sprshad.spr_color[0] = 13;
|
||||
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
|
||||
// repaint screen memory w/ the map
|
||||
refresh_world();
|
||||
|
||||
// infinite loop
|
||||
while (1) {
|
||||
static char speed;
|
||||
static char joy;
|
||||
static bool slowframe = false;
|
||||
// get joystick bits
|
||||
joy = joy_read(0);
|
||||
// speed up scrolling while button pressed
|
||||
speed = JOY_BTN_1(joy) ? 3 : 1;
|
||||
// if we copied screen memory last frame,
|
||||
// double speed of player for this frame
|
||||
if (slowframe) speed *= 2;
|
||||
// move sprite based on arrow keys
|
||||
if (JOY_LEFT(joy)) playerx -= speed;
|
||||
if (JOY_RIGHT(joy)) playerx += speed;
|
||||
if (JOY_UP(joy)) playery -= speed;
|
||||
if (JOY_DOWN(joy)) playery += speed;
|
||||
// move the camera?
|
||||
camera_follow(joy);
|
||||
slowframe = swap_needed;
|
||||
// animate sprite in shadow sprite ram
|
||||
update_player();
|
||||
// wait for vblank
|
||||
wait_vblank();
|
||||
// then update sprite registers
|
||||
sprite_update(visbuf);
|
||||
// update scroll registers
|
||||
// and swap screens if we must
|
||||
scroll_update();
|
||||
}
|
||||
}
|
100
presets/c64/siddemo.c
Normal file
100
presets/c64/siddemo.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include <tgi.h>
|
||||
#include <6502.h>
|
||||
|
||||
//#resource "c64-sid.cfg"
|
||||
#define CFGFILE c64-sid.cfg
|
||||
|
||||
//#resource "sidmusic1.bin"
|
||||
//#link "sidplaysfx.ca65"
|
||||
#include "sidplaysfx.h"
|
||||
|
||||
static const unsigned char Palette[2] =
|
||||
{ TGI_COLOR_BLUE, TGI_COLOR_WHITE };
|
||||
|
||||
static int sweep = 0;
|
||||
|
||||
#define BITMAP_START 0xe020
|
||||
|
||||
// recursive macros to quickly set bitmap memory
|
||||
#define SID_SIGNAL_4(index) \
|
||||
POKE(BITMAP_START + (index) + 0, SID.noise); \
|
||||
POKE(BITMAP_START + (index) + 1, SID.noise); \
|
||||
POKE(BITMAP_START + (index) + 2, SID.noise); \
|
||||
POKE(BITMAP_START + (index) + 3, SID.noise);
|
||||
|
||||
#define SID_SIGNAL_16(index) \
|
||||
SID_SIGNAL_4(index); \
|
||||
SID_SIGNAL_4(index+4); \
|
||||
SID_SIGNAL_4(index+8); \
|
||||
SID_SIGNAL_4(index+12);
|
||||
|
||||
#define SID_SIGNAL_64(index) \
|
||||
SID_SIGNAL_16(index); \
|
||||
SID_SIGNAL_16(index+16); \
|
||||
SID_SIGNAL_16(index+32); \
|
||||
SID_SIGNAL_16(index+48);
|
||||
|
||||
void show_signal() {
|
||||
// push SID voice 3 signal to screen memory
|
||||
// as fast as we can
|
||||
SID_SIGNAL_64(0);
|
||||
SID_SIGNAL_64(64);
|
||||
SID_SIGNAL_64(128);
|
||||
SID_SIGNAL_64(192);
|
||||
}
|
||||
|
||||
void show_envelope() {
|
||||
// read envelope value and plot vertical lines
|
||||
// via TGI library
|
||||
byte value = 199 - (SID.read3 >> 1);
|
||||
tgi_setcolor(0);
|
||||
tgi_line(sweep, 199 - 128, sweep, value - 1);
|
||||
tgi_setcolor(1);
|
||||
tgi_line(sweep, value, sweep, 240);
|
||||
if (++sweep == 320) sweep = 0;
|
||||
}
|
||||
|
||||
char music_update() {
|
||||
sid_update();
|
||||
return IRQ_NOT_HANDLED;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
// install TGI graphics driver
|
||||
tgi_install(tgi_static_stddrv);
|
||||
tgi_init();
|
||||
tgi_clear();
|
||||
tgi_setpalette(Palette);
|
||||
|
||||
// initialize SID player
|
||||
sid_init(0);
|
||||
sid_start();
|
||||
|
||||
// install joystick driver
|
||||
joy_install(joy_static_stddrv);
|
||||
|
||||
// set IRQ routine called every frame
|
||||
set_irq(music_update, (void*)0x9f00, 0x100);
|
||||
|
||||
while (1) {
|
||||
// play sound effect when joystick is moved
|
||||
byte joy = joy_read(0);
|
||||
if (joy) {
|
||||
sid_sfx(joy & 3);
|
||||
// exit when fire button pressed
|
||||
if (JOY_BTN_1(joy)) { break; }
|
||||
}
|
||||
// sync with frame rate
|
||||
waitvsync();
|
||||
// update graphs
|
||||
show_envelope();
|
||||
show_signal();
|
||||
}
|
||||
|
||||
tgi_uninstall();
|
||||
sid_stop();
|
||||
}
|
340
presets/c64/side_scroller.c
Normal file
340
presets/c64/side_scroller.c
Normal file
|
@ -0,0 +1,340 @@
|
|||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
#include "rasterirq.h"
|
||||
//#link "rasterirq.ca65"
|
||||
|
||||
#include "bcd.h"
|
||||
//#link "bcd.c"
|
||||
|
||||
#include "sidmacros.h"
|
||||
|
||||
///// SPRITE DATA
|
||||
|
||||
#define NUM_SPRITE_PATTERNS 4
|
||||
|
||||
/*{w:12,h:21,bpp:2,brev:1,wpimg:64,count:4,aspect:2}*/
|
||||
const char SPRITE_DATA[64*NUM_SPRITE_PATTERNS] = {
|
||||
0x0A,0xAA,0x80,0x0A,0xAA,0x80,0x2A,0xAA,
|
||||
0xA0,0x2A,0xAA,0xA0,0xAA,0xAA,0xA8,0xFF,
|
||||
0xD5,0x40,0xCD,0xD7,0x40,0x3D,0xD5,0x54,
|
||||
0x37,0x55,0x54,0x37,0x54,0x50,0x05,0x55,
|
||||
0x00,0x3A,0xA0,0x00,0xEA,0xA8,0x00,0xAB,
|
||||
0xAA,0x00,0xAB,0xAA,0x00,0xAB,0xAA,0x80,
|
||||
0xAA,0xEA,0x80,0xAA,0xAA,0x80,0x0F,0xFC,
|
||||
0x00,0x0F,0xFC,0x00,0x0F,0xFF,0xC0,0x00,
|
||||
|
||||
0x02,0xAA,0xA0,0x02,0xAA,0xA0,0x0A,0xAA,
|
||||
0xA8,0x0A,0xAA,0xA8,0x2A,0xAA,0xAA,0x01,
|
||||
0x57,0xFF,0x01,0xD7,0x73,0x15,0x57,0x7C,
|
||||
0x15,0x55,0xDC,0x05,0x15,0xDC,0x00,0x55,
|
||||
0x50,0x00,0x0A,0xAC,0x00,0x2A,0xAB,0x00,
|
||||
0xAA,0xEA,0x00,0xAA,0xEA,0x02,0xAA,0xEA,
|
||||
0x02,0xAB,0xAA,0x02,0xAA,0xAA,0x00,0x3F,
|
||||
0xF0,0x00,0x3F,0xF0,0x03,0xFF,0xF0,0x00,
|
||||
|
||||
0x03,0xFF,0xF0,0x0E,0xAA,0xAC,0x0E,0xAA,0xAC,
|
||||
0x3A,0xAE,0xAB,0x3A,0xBB,0xAB,0x3A,0xBA,0xAB,
|
||||
0x3A,0xBB,0xAB,0x3A,0xAE,0xAB,0x3A,0xAA,0xAB,
|
||||
0x35,0xAA,0x97,0x04,0x6A,0x44,0x04,0x15,0x04,
|
||||
0x01,0x04,0x10,0x01,0x04,0x10,0x01,0x04,0x10,
|
||||
0x00,0x44,0x40,0x00,0x44,0x40,0x00,0xEA,0xC0,
|
||||
0x00,0xD9,0xC0,0x00,0xE6,0xC0,0x00,0x3F,0x00,
|
||||
0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0xFF,0x00,0x03,0xAA,
|
||||
0xC0,0x0E,0xAA,0xB0,0x3A,0xAA,0xAC,0xE9,
|
||||
0x69,0x6B,0xEA,0x69,0xAB,0xEA,0xAA,0xAB,
|
||||
0xEA,0xAA,0xAB,0x3A,0x96,0xAC,0x3A,0x69,
|
||||
0xAC,0x0E,0xAA,0xB0,0x0E,0xAA,0xB0,0x0F,
|
||||
0xAA,0xF0,0x3A,0xAA,0xAC,0xEE,0xAA,0xBB,
|
||||
0xEE,0xAA,0xBB,0x33,0xAA,0xCC,0x03,0xAB,
|
||||
0x00,0x00,0xEB,0x00,0x00,0x3F,0xC0,0x00,
|
||||
};
|
||||
|
||||
///// DEFINES
|
||||
|
||||
#define GAME_BASE 0x400
|
||||
#define SCORE_BASE 0x2c00
|
||||
|
||||
#define SPRITE_SHAPE 192 // first sprite shape #
|
||||
#define PLAYER_SHAPE SPRITE_SHAPE
|
||||
#define POWERUP_SHAPE (SPRITE_SHAPE+2)
|
||||
#define OBSTACLE_SHAPE (SPRITE_SHAPE+3)
|
||||
|
||||
#define PLAYER_INDEX 0 // sprite indices
|
||||
#define POWERUP_INDEX 1
|
||||
#define OBSTACLE_INDEX 2
|
||||
|
||||
#define CENTER_X 172 // sprite start X coord.
|
||||
#define FLOOR_Y (128 << 8) // sprite start Y (fixed 8.8)
|
||||
#define JUMP_VELOCITY (-900) // jump velocity (fixed 8.8)
|
||||
#define GRAVITY 32 // gravity (fixed 8.8)
|
||||
|
||||
#define POWERUP_Y 80 // sprite Y of power up
|
||||
#define OBSTACLE_Y 96 // sprite Y of obstacle
|
||||
|
||||
#define SCROLL_TOP 8 // scroll top row
|
||||
#define SCROLL_ROWS 14 // scroll # of rows
|
||||
#define GROUND_ROW 7 // ground row (+ top row)
|
||||
|
||||
///// VARIABLES
|
||||
|
||||
word player_x; // player X
|
||||
word player_y; // player Y (fixed 8.8)
|
||||
signed int player_vel_y; // player Y velocity (fixed 8.8)
|
||||
byte faceleft = 0; // 0 = face right, 1 = face left
|
||||
word scroll_x = 0; // current scroll X position
|
||||
word score = 0; // current player score
|
||||
|
||||
///// FUNCTIONS
|
||||
|
||||
// display list used by rasterirq.h
|
||||
// draws scoreboard and sets scroll register
|
||||
void display_list() {
|
||||
// set x scroll register to scroll value
|
||||
SET_SCROLL_X(scroll_x);
|
||||
// set background color
|
||||
VIC.bgcolor[0] = COLOR_CYAN;
|
||||
// next interrupt is two rows from bottom
|
||||
DLIST_NEXT(248-16);
|
||||
|
||||
// set background color
|
||||
VIC.bgcolor[0] = COLOR_BLUE;
|
||||
// screen memory = 0x2800
|
||||
SET_VIC_SCREEN(SCORE_BASE);
|
||||
// clear x scroll register
|
||||
SET_SCROLL_X(0);
|
||||
// next interrupt is bottom of frame
|
||||
DLIST_NEXT(250);
|
||||
|
||||
// reset screen to 0x400
|
||||
SET_VIC_SCREEN(0x400);
|
||||
// next interrupt is above top of next frame
|
||||
DLIST_RESTART(40);
|
||||
}
|
||||
|
||||
void update_scoreboard() {
|
||||
draw_bcd_word(SCRNADR(SCORE_BASE,7,24), score);
|
||||
}
|
||||
|
||||
void add_score(int delta) {
|
||||
score = bcd_add(score, delta);
|
||||
update_scoreboard();
|
||||
}
|
||||
|
||||
// clear scoreboard and draw initial strings
|
||||
void init_scoreboard() {
|
||||
memset((void*)SCORE_BASE, ' ', 1024);
|
||||
memcpy((void*)SCRNADR(SCORE_BASE,1,24), "SCORE:", 6);
|
||||
update_scoreboard();
|
||||
}
|
||||
|
||||
void init_sprite_shapes() {
|
||||
sprite_set_shapes(SPRITE_DATA,
|
||||
SPRITE_SHAPE,
|
||||
NUM_SPRITE_PATTERNS);
|
||||
}
|
||||
|
||||
void init_sprite_positions() {
|
||||
// setup sprite positions
|
||||
player_x = CENTER_X;
|
||||
player_y = FLOOR_Y;
|
||||
player_vel_y = 0;
|
||||
sprshad.spr_color[POWERUP_INDEX] = COLOR_YELLOW;
|
||||
sprshad.spr_color[OBSTACLE_INDEX] = COLOR_GRAY3;
|
||||
}
|
||||
|
||||
void move_player(byte joy) {
|
||||
// move sprite based on joystick
|
||||
if (JOY_LEFT(joy)) {
|
||||
player_x -= 2;
|
||||
faceleft = 1;
|
||||
}
|
||||
if (JOY_RIGHT(joy)) {
|
||||
player_x += 1;
|
||||
faceleft = 0;
|
||||
}
|
||||
if (JOY_BTN_1(joy) && player_y == FLOOR_Y) {
|
||||
player_vel_y = JUMP_VELOCITY;
|
||||
}
|
||||
|
||||
// apply velocity
|
||||
player_y += player_vel_y;
|
||||
// apply gravity
|
||||
player_vel_y += GRAVITY;
|
||||
// stop velocity when falling thru floor
|
||||
if (player_y >= FLOOR_Y) {
|
||||
player_y = FLOOR_Y; // reset Y position
|
||||
player_vel_y = 0; // reset velocity
|
||||
}
|
||||
|
||||
// keep player from moving offscreen
|
||||
if (player_x < 36) player_x = 36;
|
||||
if (player_x > 300) player_x = 300;
|
||||
|
||||
// draw player into sprite shadow buffer
|
||||
sprite_draw(PLAYER_INDEX,
|
||||
player_x,
|
||||
player_y >> 8, // fixed point conversion
|
||||
PLAYER_SHAPE + faceleft);
|
||||
}
|
||||
|
||||
void move_items() {
|
||||
// move in sync with scrolling world
|
||||
// draw powerup
|
||||
sprite_draw(POWERUP_INDEX,
|
||||
((scroll_x*2) & 0x1ff),
|
||||
POWERUP_Y,
|
||||
POWERUP_SHAPE);
|
||||
// draw obstacle
|
||||
sprite_draw(OBSTACLE_INDEX,
|
||||
((scroll_x+256) & 0x1ff),
|
||||
OBSTACLE_Y,
|
||||
OBSTACLE_SHAPE);
|
||||
}
|
||||
|
||||
byte get_char_for_row(byte row) {
|
||||
// ground?
|
||||
if (row >= GROUND_ROW) { return 253; }
|
||||
// obstacle?
|
||||
if (row >= GROUND_ROW-3) {
|
||||
// only show obstacle for certain values of scroll_x
|
||||
if ((scroll_x & 0b1110000) == 0) { return 247; }
|
||||
}
|
||||
// default is the sky (empty space)
|
||||
return 32;
|
||||
}
|
||||
|
||||
void draw_right_column() {
|
||||
// get the top-right corner address of scroll area
|
||||
word addr = SCRNADR(GAME_BASE, 39, SCROLL_TOP);
|
||||
byte row;
|
||||
// draw one character per row
|
||||
for (row=0; row<SCROLL_ROWS; row++) {
|
||||
POKE(addr, get_char_for_row(row));
|
||||
addr += 40;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_one_column_left() {
|
||||
// copy several rows of screen memory
|
||||
// backwards one byte
|
||||
const word start = SCRNADR(GAME_BASE, 0, SCROLL_TOP);
|
||||
const word nbytes = SCROLL_ROWS*40-1;
|
||||
memcpy((byte*)start, (byte*)start+1, nbytes);
|
||||
// draw the right column of characters
|
||||
draw_right_column();
|
||||
}
|
||||
|
||||
void scroll_one_pixel_left() {
|
||||
// scroll left one pixel
|
||||
scroll_x -= 1;
|
||||
// set scroll register with lower three bits
|
||||
VIC.ctrl2 = (VIC.ctrl2 & ~7) | (scroll_x & 7);
|
||||
// move screen memory if the scroll register
|
||||
// has just gone past 0 and wrapped to 7
|
||||
if ((scroll_x & 7) == 7) {
|
||||
scroll_one_column_left();
|
||||
}
|
||||
}
|
||||
|
||||
void detect_player_collision(byte bg_coll, byte spr_coll) {
|
||||
// did we hit a powerup? (#0 and #1)
|
||||
bool hit_powerup = (spr_coll & 0b011) == 0b011;
|
||||
// did player and obstacle sprite (#0 and #2) collide?
|
||||
bool hit_obstacle = (spr_coll & 0b101) == 0b101;
|
||||
// did player (#0) collide with background?
|
||||
hit_obstacle |= (bg_coll & 0b001) != 0;
|
||||
// did we hit anything bad?
|
||||
if (hit_obstacle) {
|
||||
// make player fall downward and backward
|
||||
player_vel_y = -JUMP_VELOCITY;
|
||||
player_x -= 1;
|
||||
sprshad.spr_color[PLAYER_INDEX] = COLOR_LIGHTRED;
|
||||
SID_PLAY_TONE(500);
|
||||
if (score != 0) { add_score(0x9999); } // BCD -1
|
||||
} else {
|
||||
sprshad.spr_color[PLAYER_INDEX] = COLOR_GREEN;
|
||||
}
|
||||
// did we hit powerup?
|
||||
if (hit_powerup) {
|
||||
sprshad.spr_color[POWERUP_INDEX] += 1; // cycle colors
|
||||
SID_PLAY_TONE(8000);
|
||||
add_score(1);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
// clear screen, set background color
|
||||
clrscr();
|
||||
VIC.bgcolor[0] = COLOR_CYAN;
|
||||
VIC.bordercolor = COLOR_BLUE;
|
||||
|
||||
// set vertical scroll = 3, 25 rows
|
||||
VIC.ctrl1 = 0b00011011;
|
||||
// set 38 column mode (for X scrolling)
|
||||
VIC.ctrl2 = 0b00000000;
|
||||
// set uniform color of characters
|
||||
memset(COLOR_RAM, COLOR_WHITE, 1000);
|
||||
|
||||
// install the joystick driver
|
||||
joy_install (joy_static_stddrv);
|
||||
|
||||
// setup sound
|
||||
SID_INIT(8,0);
|
||||
|
||||
// set multicolor sprites and colors in shadow buffer
|
||||
sprite_clear(); // clear shadow buffer
|
||||
sprshad.spr_mcolor = 0b11111111; // all sprites multicolor
|
||||
sprshad.spr_exp_y = 1; // double height
|
||||
|
||||
// set colors
|
||||
sprshad.spr_color[PLAYER_INDEX] = COLOR_GREEN;
|
||||
VIC.spr_mcolor0 = COLOR_GRAY2;
|
||||
VIC.spr_mcolor1 = COLOR_BLACK;
|
||||
|
||||
// setup sprites
|
||||
init_sprite_shapes();
|
||||
init_sprite_positions();
|
||||
|
||||
// setup scoreboard
|
||||
init_scoreboard();
|
||||
|
||||
// setup rasterirq library for scoreboard split
|
||||
DLIST_SETUP(display_list);
|
||||
|
||||
// game loop, repeat forever
|
||||
while (1) {
|
||||
// saved collision flags
|
||||
byte spr_coll, bg_coll;
|
||||
|
||||
// wait for end of frame
|
||||
waitvsync();
|
||||
|
||||
//--- START TIME CRITICAL SECTION
|
||||
// grab and reset collision flags
|
||||
spr_coll = VIC.spr_coll;
|
||||
bg_coll = VIC.spr_bg_coll;
|
||||
|
||||
// update sprite registers from sprite shadow buffer
|
||||
sprite_update(DEFAULT_SCREEN);
|
||||
|
||||
// scroll screen
|
||||
scroll_one_pixel_left();
|
||||
//--- END TIME CRITICAL SECTION
|
||||
|
||||
// use collision flags to see if player collided
|
||||
detect_player_collision(bg_coll, spr_coll);
|
||||
|
||||
// get joystick bits and move player
|
||||
move_player(joy_read(0));
|
||||
|
||||
// move obstacle and powerup sprites
|
||||
move_items();
|
||||
}
|
||||
}
|
51
presets/c64/sidmacros.h
Normal file
51
presets/c64/sidmacros.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
// SID voices are v1, v2, v3
|
||||
|
||||
// wave options flags
|
||||
#define SID_GATE 0x01
|
||||
#define SID_SYNC 0x02
|
||||
#define SID_RINGMOD 0x04
|
||||
#define SID_TESTBIT 0x08
|
||||
#define SID_TRIANGLE 0x10
|
||||
#define SID_SAWTOOTH 0x20
|
||||
#define SID_SQUARE 0x40
|
||||
#define SID_NOISE 0x80
|
||||
|
||||
// Init SID global volume
|
||||
// volume: 0-15
|
||||
// filters: bitmask
|
||||
#define SID_INIT(volume, filters) \
|
||||
SID.amp = (volume) | ((filters)<<4);
|
||||
|
||||
// stop voice
|
||||
#define SID_STOP(voice, options) \
|
||||
SID.voice.ctrl = options & ~SID_GATE;
|
||||
|
||||
// start voice
|
||||
#define SID_START(voice, options) \
|
||||
SID.voice.ctrl = options | SID_GATE;
|
||||
|
||||
// set ADSR envelope
|
||||
#define SID_ADSR(voice,attack,decay,sustain,release) \
|
||||
SID.voice.ad = ((decay)&15) | ((attack)<<4); \
|
||||
SID.voice.sr = ((release)&15) | ((sustain)<<4);
|
||||
|
||||
// set frequency (0 - 65535)
|
||||
#define SID_FREQ(voice,_freq) \
|
||||
SID.voice.freq = (_freq);
|
||||
|
||||
// set pulse width (0 - 4095)
|
||||
#define SID_PULSEWIDTH(voice,_pw) \
|
||||
SID.voice.pw = (_pw);
|
||||
|
||||
// play a quick square wave pulse
|
||||
#define SID_PULSE_DECAY(voice, freq) \
|
||||
SID_STOP(voice,0) \
|
||||
SID_FREQ(voice,freq); \
|
||||
SID_PULSEWIDTH(voice,0x200); \
|
||||
SID_ADSR(voice,3,8,0,4); \
|
||||
SID_START(voice,SID_SQUARE); \
|
||||
|
||||
// play a tone if one is not already playing
|
||||
#define SID_PLAY_TONE(freq) \
|
||||
if (!SID.read3) { SID_PULSE_DECAY(v3, (freq)) }
|
BIN
presets/c64/sidmusic1.bin
Normal file
BIN
presets/c64/sidmusic1.bin
Normal file
Binary file not shown.
72
presets/c64/sidplaysfx.ca65
Normal file
72
presets/c64/sidplaysfx.ca65
Normal file
|
@ -0,0 +1,72 @@
|
|||
|
||||
; music and SFX from GoatTracker 2 sample files
|
||||
; http://sourceforge.net/projects/goattracker2
|
||||
|
||||
.segment "DATA"
|
||||
|
||||
_sid_playing: .byte $00
|
||||
|
||||
.segment "SIDFILE"
|
||||
|
||||
.incbin "sidmusic1.bin"
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
.global _sid_init, _sid_update, _sid_sfx
|
||||
.global _sid_start, _sid_stop, _sid_playing
|
||||
|
||||
_sid_init:
|
||||
jmp $1000
|
||||
|
||||
_sid_update:
|
||||
bit _sid_playing
|
||||
bpl @noplay
|
||||
jmp $1003
|
||||
@noplay:
|
||||
rts
|
||||
|
||||
_sid_sfx:
|
||||
tax
|
||||
lda sfxtbllo,x ;Address in A,Y
|
||||
ldy sfxtblhi,x
|
||||
ldx #$0e ;Channel index in X
|
||||
jmp $1006 ;(0, 7 or 14)
|
||||
|
||||
_sid_start:
|
||||
lda #$80
|
||||
bne skipstop
|
||||
_sid_stop:
|
||||
lda #$00
|
||||
sta $d418
|
||||
skipstop:
|
||||
sta _sid_playing
|
||||
rts
|
||||
|
||||
sfxtbllo: .byte <arpeggio2
|
||||
.byte <arpeggio1
|
||||
.byte <gunshot
|
||||
.byte <explosion
|
||||
|
||||
sfxtblhi: .byte >arpeggio2
|
||||
.byte >arpeggio1
|
||||
.byte >gunshot
|
||||
.byte >explosion
|
||||
|
||||
arpeggio2:
|
||||
.byte $00,$89,$04,$A2,$41,$A2,$A2,$A6,$A6,$A6,$40,$A9,$A9,$A9,$A2,$A2
|
||||
.byte $A2,$A6,$A6,$A6,$A9,$A9,$A9,$A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9
|
||||
.byte $A2,$A2,$A2,$A6,$A6,$A6,$A9,$A9,$A9,$00
|
||||
|
||||
arpeggio1:
|
||||
.byte $0A,$00,$02,$A0,$41,$A0,$A0,$A4,$A4,$A4,$A7,$A7,$A7,$A0,$A0,$A0
|
||||
.byte $A4,$A4,$A4,$A7,$A7,$A7,$A0,$A0,$A0,$A4,$A4,$A4,$A7,$A7,$A7,$A0
|
||||
.byte $A0,$A0,$A4,$A4,$A4,$A7,$A7,$A7,$00
|
||||
|
||||
gunshot:
|
||||
.byte $00,$F9,$08,$C4,$81,$A8,$41,$C0,$81,$BE,$BC,$80,$BA,$B8,$B6,$B4
|
||||
.byte $B2,$B0,$AE,$AC,$AA,$A8,$A6,$A4,$A2,$A0,$9E,$9C,$9A,$98,$96,$94
|
||||
.byte $92,$90,$00
|
||||
|
||||
explosion:
|
||||
.byte $00,$FA,$08,$B8,$81,$A4,$41,$A0,$B4,$81,$98,$92,$9C,$90,$95,$9E
|
||||
.byte $92,$80,$94,$8F,$8E,$8D,$8C,$8B,$8A,$89,$88,$87,$86,$84,$00
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user