mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2026-10-24 08:02:27 +00:00
c64: fullscrollgame-sdcc.c for sdcc4, fixed source line offset bug, test
This commit is contained in:
1 parent
83f5bcf256
commit
344cdd21f9
9 files changed
+60
-8
No files matched your search
+2
-1
@@ -55,7 +55,8 @@ See [extension/CHANGELOG.md](extension/CHANGELOG.md).
|
||||
### Build tools
|
||||
|
||||
- Many toolchains are now WASI builds: cc65 (pinned to 2021 6ac4aa4), DASM 2.20.17, acme, zmac, yasm and merlin32.
|
||||
- SDCC 4 mos6502 backend: C64 presets (`hello-sdcc.c`, `screen_ram-sdcc.c`, `joymove-sdcc.c`, `siegegame-sdcc.c`, `sprite_collision-sdcc.c`); `load_header` platform param wraps the image as a DOS 3.3 binary (apple2) or a PRG with a `SYS` stub (c64).
|
||||
- SDCC 4 mos6502 backend: C64 presets (`hello-sdcc.c`, `screen_ram-sdcc.c`, `joymove-sdcc.c`, `siegegame-sdcc.c`, `sprite_collision-sdcc.c`, `fullscrollgame-sdcc.c`); `load_header` platform param wraps the image as a DOS 3.3 binary (apple2) or a PRG with a `SYS` stub (c64).
|
||||
- C64 `fullscrollgame.c` now takes its level data from `level2-data.c` (the same data as `level2.s`, in C) so the SDCC build can link it; `scrolling2.c` uses plain C copies under SDCC.
|
||||
- Updated batari BASIC; sdcc now parses `#symbol` directives and fixes lost link errors.
|
||||
- New build directives replace the legacy CFGFILE-style ones; build parameters no longer leak between builds.
|
||||
- `#pragma compile("...")` and oscar64 symbol/listing parsing.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// fullscrollgame.c built with SDCC's mos6502 backend instead of cc65.
|
||||
// The program is fullscrollgame.c; common.h supplies the C64 definitions SDCC lacks.
|
||||
// (The C files are #included, since cc65 and SDCC objects can't be linked together,
|
||||
// and the level data from level2.s is converted to C in level2-data.c.)
|
||||
|
||||
#include "common.h"
|
||||
#include "common.c"
|
||||
|
||||
#include "scrolling.h"
|
||||
#include "scrolling2.c"
|
||||
|
||||
#include "sprites.h"
|
||||
#include "sprites.c"
|
||||
|
||||
#include "level2-data.c"
|
||||
|
||||
#include "fullscrollgame.c"
|
||||
@@ -1,4 +1,5 @@
|
||||
|
||||
#ifndef __SDCC
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <c64.h>
|
||||
@@ -7,6 +8,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <joystick.h>
|
||||
#endif
|
||||
|
||||
//#resource "c64-sid.cfg"
|
||||
#define CFGFILE c64-sid.cfg
|
||||
@@ -20,7 +22,7 @@
|
||||
#include "sprites.h"
|
||||
//#link "sprites.c"
|
||||
|
||||
//#link "level2.s"
|
||||
//#link "level2-data.c"
|
||||
|
||||
#define CAMERA_OFFSET_X 158
|
||||
#define CAMERA_OFFSET_Y 120
|
||||
|
||||
@@ -43,6 +43,15 @@ void copy_color_ram_slow() {
|
||||
memcpy(COLOR_RAM, colorbuf, COLS*ROWS);
|
||||
}
|
||||
|
||||
void copy_to_hidden_buffer_slow() {
|
||||
memcpy(hidbuf, visbuf, COLS*ROWS);
|
||||
}
|
||||
|
||||
#ifdef __SDCC
|
||||
// (SDCC build: no cc65 inline assembly, so use the plain C copies)
|
||||
void copy_color_ram_fast() { copy_color_ram_slow(); }
|
||||
void copy_to_hidden_buffer_fast() { copy_to_hidden_buffer_slow(); }
|
||||
#else
|
||||
void copy_color_ram_fast() {
|
||||
// fast copy loop for upper 1/2 of color ram
|
||||
asm("ldy #0");
|
||||
@@ -63,10 +72,6 @@ void copy_color_ram_fast() {
|
||||
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);
|
||||
@@ -101,6 +106,7 @@ void copy_to_hidden_buffer_fast() {
|
||||
asm("@skip: iny");
|
||||
asm("bne @loop");
|
||||
}
|
||||
#endif
|
||||
|
||||
void scroll_start(byte dir) {
|
||||
if (scroll_seq == 0 && dir) {
|
||||
|
||||
@@ -48,6 +48,7 @@ const C64_PRESETS : Preset[] = [
|
||||
{id:'lander.cpp', name:'Lunar Lander'},
|
||||
{id:'hello-sdcc.c', name:'Hello World (SDCC)', category:'C (SDCC)'},
|
||||
{id:'sprite_collision-sdcc.c', name:'Sprite Collision (SDCC)'},
|
||||
{id:'fullscrollgame-sdcc.c', name:'Full-Scrolling Game (SDCC)'},
|
||||
];
|
||||
|
||||
const C64_MEMORY_MAP = { main:[
|
||||
|
||||
@@ -102,6 +102,7 @@ export function parseListing(code: string,
|
||||
export function parseSourceLines(code: string, lineMatch, offsetMatch, funcMatch?, segMatch?) {
|
||||
var lines = [];
|
||||
var lastlinenum = 0;
|
||||
var lastpath: string;
|
||||
var state = { segment: '', func: '', funcbase: 0 };
|
||||
for (var line of code.split(re_crlf)) {
|
||||
parseSegFunc(line, segMatch, funcMatch, state);
|
||||
@@ -109,6 +110,7 @@ export function parseSourceLines(code: string, lineMatch, offsetMatch, funcMatch
|
||||
var linem = lineMatch.exec(line);
|
||||
if (linem && linem[1]) {
|
||||
lastlinenum = parseInt(linem[1]);
|
||||
lastpath = linem[2]; // optional source file, for listings that mix files
|
||||
} else if (lastlinenum) {
|
||||
var linem = offsetMatch.exec(line);
|
||||
if (linem && linem[1]) {
|
||||
@@ -117,7 +119,8 @@ export function parseSourceLines(code: string, lineMatch, offsetMatch, funcMatch
|
||||
line: lastlinenum,
|
||||
offset: offset - state.funcbase,
|
||||
segment: state.segment,
|
||||
func: state.func
|
||||
func: state.func,
|
||||
...(lastpath ? { path: lastpath } : {})
|
||||
});
|
||||
lastlinenum = 0;
|
||||
}
|
||||
|
||||
@@ -559,6 +559,13 @@ export function parseRSTListing(rstout: string, srcprefix: string) {
|
||||
// the mos6502 backend writes `;<tab>file.c: 17: source`, with a space after the colon
|
||||
const srcre = new RegExp(`^\\s+\\d+ ;\\s*(?:<stdin>|/*${name}\\.[^:\\s]+):\\s*(\\d+):`, 'i');
|
||||
var srclines = parseSourceLines(rstout, srcre, /^\s*([0-9A-F]{4,8})/i);
|
||||
if (!srclines.length) {
|
||||
// the mos6502 backend names the file of every line, so a main file
|
||||
// that #includes the others (the -sdcc.c wrappers) still gets a
|
||||
// listing: tag each line with its file (see processListings);
|
||||
// the pattern captures the line number first, then the file name
|
||||
srclines = parseSourceLines(rstout, /^\s+\d+ ;\t(?=[^\s:]+: (\d+):)([^\s:]+)/, /^\s*([0-9A-F]{4,8})/i);
|
||||
}
|
||||
// TODO: you have to get rid of all source lines to get asm listing
|
||||
return {
|
||||
asmlines: srclines.length ? asmlines : null,
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ describe('8bws CLI', function () {
|
||||
assert.equal(bin[2] | bin[3] << 8, bin.length - 4);
|
||||
assert.ok(bin.length > 4000); // the whole game, not just the wrapper
|
||||
});
|
||||
['hello', 'screen_ram', 'joymove', 'siegegame', 'sprite_collision'].forEach(function (name) {
|
||||
['hello', 'sprite_collision'].forEach(function (name) {
|
||||
it('should build the c64 ' + name + ' SDCC preset as a PRG', function () {
|
||||
var out = path.join(os.tmpdir(), '8bws-c64-' + name + '-sdcc.prg');
|
||||
cli('build', '-p', 'c64', 'presets/c64/' + name + '-sdcc.c', '-o', out);
|
||||
|
||||
@@ -28,8 +28,23 @@ const RST_MOS6502 = [
|
||||
" 00000869 20 4E 08 [ 6] 138 \tjsr\t_putstr",
|
||||
].join("\n");
|
||||
|
||||
// a main file that only #includes the others (e.g. fullscrollgame-sdcc.c)
|
||||
const RST_MOS6502_INCLUDES = [
|
||||
" 00000865 126 _main:",
|
||||
" 128 ;\tgame.c: 18: putstr(message);",
|
||||
" 00000865 A2 08 [ 2] 136 \tldx\t#>_message",
|
||||
" 140 ;\tlib.c: 4: x++;",
|
||||
" 00000869 E6 02 [ 5] 142 \tinc\t*_x",
|
||||
].join("\n");
|
||||
|
||||
describe("sdcc listings", function () {
|
||||
|
||||
it("tags mos6502 lines with the included file they came from", function () {
|
||||
const l = parseRSTListing(RST_MOS6502_INCLUDES, "game-sdcc");
|
||||
assert.deepStrictEqual(l.lines.map((x) => [x.path, x.line, x.offset]),
|
||||
[["game.c", 18, 0x865], ["lib.c", 4, 0x869]]);
|
||||
});
|
||||
|
||||
it("maps mos6502 source comments", function () {
|
||||
const l = parseRSTListing(RST_MOS6502, "hello");
|
||||
assert.deepStrictEqual(l.lines.map((x) => [x.line, x.offset]), [[17, 0x865], [18, 0x865]]); // the function line maps to its label
|
||||
|
||||
Reference in new issue
Block a user