From 80fea259163a1b535f9b64eeeeb0390dbef9d69a Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 28 Dec 2021 13:13:05 +0100 Subject: [PATCH] More samples --- include/c64/kernalio.c | 73 ++++++++-- include/c64/kernalio.h | 1 + include/c64/memmap.c | 2 + include/c64/rasterirq.c | 2 + include/gfx/bitmap.c | 94 ++++++++----- include/gfx/bitmap.h | 36 ++--- oscar64/ByteCodeGenerator.cpp | 5 +- oscar64/NativeCodeGenerator.cpp | 21 ++- oscar64/NativeCodeGenerator.h | 9 +- samples/hires/func3d.c | 233 ++++++++++++++++++++++++++++++++ samples/hires/make.bat | 2 + samples/hires/splitscreen.c | 104 ++++++++++++++ samples/kernalio/charread.c | 22 +++ samples/kernalio/charwrite.c | 16 +++ samples/kernalio/diskdir.c | 64 +++++++++ samples/kernalio/fileread.c | 28 ++++ samples/kernalio/filewrite.c | 28 ++++ samples/kernalio/hiresread.c | 39 ++++++ samples/kernalio/hireswrite.c | 63 +++++++++ samples/kernalio/make.bat | 7 + samples/memmap/charsetcopy.c | 69 ++++++++++ samples/memmap/charsethi.c | 34 +++++ samples/memmap/make.bat | 2 + 23 files changed, 890 insertions(+), 64 deletions(-) create mode 100644 samples/hires/func3d.c create mode 100644 samples/hires/make.bat create mode 100644 samples/hires/splitscreen.c create mode 100644 samples/kernalio/charread.c create mode 100644 samples/kernalio/charwrite.c create mode 100644 samples/kernalio/diskdir.c create mode 100644 samples/kernalio/fileread.c create mode 100644 samples/kernalio/filewrite.c create mode 100644 samples/kernalio/hiresread.c create mode 100644 samples/kernalio/hireswrite.c create mode 100644 samples/kernalio/make.bat create mode 100644 samples/memmap/charsetcopy.c create mode 100644 samples/memmap/charsethi.c diff --git a/include/c64/kernalio.c b/include/c64/kernalio.c index 3e5e333..3860e81 100644 --- a/include/c64/kernalio.c +++ b/include/c64/kernalio.c @@ -20,6 +20,8 @@ void krnio_setnam(const char * name) } } +#pragma native(krnio_setnam) + bool krnio_open(char fnum, char device, char channel) { __asm @@ -47,6 +49,8 @@ bool krnio_open(char fnum, char device, char channel) } +#pragma native(krnio_open) + void krnio_close(char fnum) { __asm @@ -56,6 +60,8 @@ void krnio_close(char fnum) } } +#pragma native(krnio_close) + krnioerr krnio_status(void) { __asm @@ -67,6 +73,8 @@ krnioerr krnio_status(void) } } +#pragma native(krnio_status) + bool krnio_chkout(char fnum) { __asm @@ -81,6 +89,8 @@ bool krnio_chkout(char fnum) } } +#pragma native(krnio_chkout) + bool krnio_chkin(char fnum) { __asm @@ -95,6 +105,8 @@ bool krnio_chkin(char fnum) } } +#pragma native(krnio_chkin) + void krnio_clrchn(void) { __asm @@ -103,6 +115,8 @@ void krnio_clrchn(void) } } +#pragma native(krnio_clrchn) + bool krnio_chrout(char ch) { __asm @@ -115,30 +129,53 @@ bool krnio_chrout(char ch) } } +#pragma native(krnio_chrout) + int krnio_chrin(void) { __asm { jsr $ffcf // chrin sta accu - jsr $ffb7 - beq W1 - lda #$ff - sta accu - W1: + lda #0 sta accu + 1 } } +#pragma native(krnio_chrin) + int krnio_getch(char fnum) { int ch = -1; if (krnio_chkin(fnum)) + { ch = krnio_chrin(); + krnioerr err = krnio_status(); + if (err) + { + if (err == KRNIO_EOF) + ch |= 0x100; + else + ch = -1; + } + } krnio_clrchn(); return ch; } +int krnio_putch(char fnum, char ch) +{ + if (krnio_chkout(fnum)) + { + krnio_chrout(ch); + krnio_clrchn(); + return 0; + } + else + return -1; +} + + int krnio_puts(char fnum, const char * data) { if (krnio_chkout(fnum)) @@ -153,6 +190,8 @@ int krnio_puts(char fnum, const char * data) return -1; } +#pragma native(krnio_puts) + int krnio_write(char fnum, const char * data, int num) { if (krnio_chkout(fnum)) @@ -166,14 +205,24 @@ int krnio_write(char fnum, const char * data, int num) return -1; } +#pragma native(krnio_write) + int krnio_read(char fnum, char * data, int num) { if (krnio_chkin(fnum)) { int i = 0; int ch; - while (i < num && (ch = krnio_chrin()) >= 0) + while (i < num) + { + ch = krnio_chrin(); + krnioerr err = krnio_status(); + if (err && err != KRNIO_EOF) + break; data[i++] = (char)ch; + if (err) + break; + } krnio_clrchn(); return i; } @@ -181,16 +230,22 @@ int krnio_read(char fnum, char * data, int num) return -1; } +#pragma native(krnio_read) + int krnio_gets(char fnum, char * data, int num) { if (krnio_chkin(fnum)) { int i = 0; int ch; - while (i + 1 < num && (ch = krnio_chrin()) >= 0) + while (i + 1 < num) { + ch = krnio_chrin(); + krnioerr err = krnio_status(); + if (err && err != KRNIO_EOF) + break; data[i++] = (char)ch; - if (ch == 13 || ch == 10) + if (ch == 13 || ch == 10 || err) break; } data[i] = 0; @@ -201,3 +256,5 @@ int krnio_gets(char fnum, char * data, int num) return -1; } + +#pragma native(krnio_gets) diff --git a/include/c64/kernalio.h b/include/c64/kernalio.h index edc1cfb..fdd09c4 100644 --- a/include/c64/kernalio.h +++ b/include/c64/kernalio.h @@ -36,6 +36,7 @@ int krnio_chrin(void); int krnio_getch(char fnum); +int krnio_putch(char fnum, char ch); int krnio_write(char fnum, const char * data, int num); diff --git a/include/c64/memmap.c b/include/c64/memmap.c index 7db319f..feeb683 100644 --- a/include/c64/memmap.c +++ b/include/c64/memmap.c @@ -54,6 +54,8 @@ void mmap_trampoline(void) *((void **)0xfffe) = NMITrampoline; } +#pragma native(mmap_trampoline) + void mmap_set(char pla) { PLAShadow = pla; diff --git a/include/c64/rasterirq.c b/include/c64/rasterirq.c index c6ca0d7..bf23c26 100644 --- a/include/c64/rasterirq.c +++ b/include/c64/rasterirq.c @@ -210,6 +210,8 @@ void rirq_build(RIRQCode * ic, byte size) } } +#pragma native(rirq_build) + void rirq_set(byte n, byte row, RIRQCode * write) { rasterIRQLow[n] = (unsigned)&write->code & 0xff; diff --git a/include/gfx/bitmap.c b/include/gfx/bitmap.c index c82b59a..b56b98d 100644 --- a/include/gfx/bitmap.c +++ b/include/gfx/bitmap.c @@ -38,16 +38,22 @@ void bm_set(Bitmap * bm, int x, int y) bm->data[bm->cwidth * (y & ~7) + (x & ~7) + (y & 7)] |= 0x80 >> (x & 7); } +#pragma native(bm_set) + void bm_clr(Bitmap * bm, int x, int y) { bm->data[bm->cwidth * (y & ~7) + (x & ~7) + (y & 7)] &= ~(0x80 >> (x & 7)); } +#pragma native(bm_clr) + bool bm_get(Bitmap * bm, int x, int y) { return (bm->data[bm->cwidth * (y & ~7) + (x & ~7) + (y & 7)] & (0x80 >> (x & 7))) != 0; } +#pragma native(bm_get) + void bm_put(Bitmap * bm, int x, int y, bool c) { char * dp = bm->data + bm->cwidth * (y & ~7) + (x & ~7) + (y & 7); @@ -58,6 +64,8 @@ void bm_put(Bitmap * bm, int x, int y, bool c) *dp &= ~m; } +#pragma native(bm_put) + char NineShadesOfGrey[9][8] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0 {0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88, 0x00}, // 8 @@ -116,7 +124,9 @@ void bm_scan_fill(int left, int right, char * lp, int x0, int x1, char pat) } } -static unsigned usqrt(unsigned n) +#pragma native(bm_scan_fill) + +unsigned bm_usqrt(unsigned n) { unsigned p, q, r, h @@ -142,9 +152,11 @@ static unsigned usqrt(unsigned n) return p; } +#pragma native(bm_usqrt) + void bm_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const char * pattern) { - int y0 = y - r, y1 = y + r; + int y0 = y - r, y1 = y + r + 1; if (y0 < clip->top) y0 = clip->top; if (y1 > clip->bottom) @@ -159,7 +171,7 @@ void bm_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const ch { int d = (iy - y); - int t = usqrt(rr - d * d); + int t = bm_usqrt(rr - d * d); bm_scan_fill(clip->left, clip->right, lp, x - t, x + t + 1, pat[iy & 7]); lp ++; @@ -546,6 +558,8 @@ static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, b ip += asm_np(BLIT_CODE + ip, ASM_RTS); } +#pragma native(buildline) + static inline void callline(byte * dst, byte bit, int m, char lh, char pattern) { __asm @@ -573,8 +587,7 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern) } } - -void bm_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern) +void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern) { int dx = x1 - x0, dy = y1 - y0; byte quad = 0; @@ -614,7 +627,7 @@ static int muldiv(int x, int mul, int div) return (int)((long)x * mul / div); } -void bm_line_clipped(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern) +void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern) { int dx = x1 - x0, dy = y1 - y0; @@ -698,7 +711,7 @@ void bm_line_clipped(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y return; } - bm_line(bm, x0, y0, x1, y1, pattern); + bmu_line(bm, x0, y0, x1, y1, pattern); } static inline void callddop(byte * src, byte * dst, byte pat) @@ -778,6 +791,8 @@ static char builddop_src(char ip, char shift, bool reverse) return ip; } +#pragma native(builddop_src) + static AsmIns blitops_op[4] = {ASM_BRK, ASM_AND, ASM_ORA, ASM_EOR}; static char builddop_op(char ip, BlitOp op) @@ -805,6 +820,8 @@ static char builddop_op(char ip, BlitOp op) return ip; } +#pragma native(builddop_op) + static void builddop(char shift, char w, char lmask, char rmask, BlitOp op, bool reverse) { byte ip = 0; @@ -921,7 +938,9 @@ static void builddop(char shift, char w, char lmask, char rmask, BlitOp op, bool ip += asm_np(BLIT_CODE + ip, ASM_RTS); } -void bm_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) +#pragma native(builddop) + +void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) { int rx = dx + w; char dxh0 = dx >> 3, dxh1 = rx >> 3; @@ -1005,7 +1024,9 @@ void bm_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int } } -void bm_bitblit_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) +#pragma native(bmu_bitblit) + +void bm_bitblit(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) { if (dx >= clip->right || dy >= clip->bottom) return; @@ -1033,53 +1054,53 @@ void bm_bitblit_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * h = clip->bottom - dy; if (w > 0 && h > 0) - bm_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, pattern, op); + bmu_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, pattern, op); } -inline void bm_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h) +inline void bmu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h) { - bm_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_SET); + bmu_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_SET); } -inline void bm_rect_clear(Bitmap * dbm, int dx, int dy, int w, int h) +inline void bmu_rect_clear(Bitmap * dbm, int dx, int dy, int w, int h) { - bm_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_RESET); + bmu_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_RESET); } -inline void bm_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern) +inline void bmu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern) { - bm_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, pattern, BLTOP_PATTERN); + bmu_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, pattern, BLTOP_PATTERN); } -inline void bm_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) +inline void bmu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) { bm_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, nullptr, BLTOP_COPY); } -inline void bm_rect_fill_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h) +inline void bm_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h) { - bm_bitblit_clipped(dbm, clip, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_SET); + bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_SET); } -inline void bm_rect_clear_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h) +inline void bm_rect_clear(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h) { - bm_bitblit_clipped(dbm, clip, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_RESET); + bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_RESET); } -inline void bm_rect_pattern_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern) +inline void bm_rect_pattern(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern) { - bm_bitblit_clipped(dbm, clip, dx, dy, dbm, dx, dy, w, h, pattern, BLTOP_PATTERN); + bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, w, h, pattern, BLTOP_PATTERN); } -inline void bm_rect_copy_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) +inline void bm_rect_copy(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) { - bm_bitblit_clipped(dbm, clip, dx, dy, sbm, sx, sy, w, h, nullptr, BLTOP_COPY); + bm_bitblit(dbm, clip, dx, dy, sbm, sx, sy, w, h, nullptr, BLTOP_COPY); } static char tworks[8]; -int bm_text(Bitmap * bm, const char * str, char len) +int bmu_text(Bitmap * bm, const char * str, char len) { char lx = 0; int tw = 0; @@ -1197,6 +1218,8 @@ int bm_text(Bitmap * bm, const char * str, char len) return tw; } +#pragma native(bmu_text) + int bm_text_size(const char * str, char len) { int tw = 0; @@ -1218,16 +1241,16 @@ static Bitmap tbitmap = { tbuffer, nullptr, 40, 1, 320 }; -int bm_put_chars(Bitmap * bm, int x, int y, const char * str, char len, BlitOp op) +int bmu_put_chars(Bitmap * bm, int x, int y, const char * str, char len, BlitOp op) { - int tw = bm_text(&tbitmap, str, len); + int tw = bmu_text(&tbitmap, str, len); - bm_bitblit(bm, x, y, &tbitmap, 0, 0, tw, 8, nullptr, op); + bmu_bitblit(bm, x, y, &tbitmap, 0, 0, tw, 8, nullptr, op); return tw; } -int bm_put_chars_clipped(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, char len, BlitOp op) +int bm_put_chars(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, char len, BlitOp op) { int tw = 0; @@ -1274,9 +1297,9 @@ int bm_put_chars_clipped(Bitmap * bm, ClipRect * clip, int x, int y, const char fx++; } - int cw = bm_text(&tbitmap, str, fx); + int cw = bmu_text(&tbitmap, str, fx); - bm_bitblit_clipped(bm, clip, x, y, &tbitmap, 0, 0, cw, 8, nullptr, op); + bm_bitblit(bm, clip, x, y, &tbitmap, 0, 0, cw, 8, nullptr, op); while (fx < len) { @@ -1290,6 +1313,11 @@ int bm_put_chars_clipped(Bitmap * bm, ClipRect * clip, int x, int y, const char return tw; } +int bm_put_string(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, BlitOp op) +{ + return bm_put_chars(bm, clip, x, y, str, strlen(str), op); +} + int bm_transform(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, Bitmap * sbm, int sx, int sy, int dxx, int dxy, int dyx, int dyy) { long lsx = (long)sx << 16, lsy = (long)sy << 16; @@ -1335,3 +1363,5 @@ int bm_transform(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, Bi lsy += (long)dyy << 8; } } + +#pragma native(bm_transform) diff --git a/include/gfx/bitmap.h b/include/gfx/bitmap.h index c0c53d7..643a6c4 100644 --- a/include/gfx/bitmap.h +++ b/include/gfx/bitmap.h @@ -51,6 +51,9 @@ enum BlitOp extern char NineShadesOfGrey[9][8]; +unsigned bm_usqrt(unsigned n); + + void bm_init(Bitmap * bm, char * data, char cw, char ch); void bm_alloc(Bitmap * bm, char cw, char ch); @@ -80,40 +83,41 @@ inline bool bm_get(Bitmap * bm, int x, int y); inline void bm_put(Bitmap * bm, int x, int y, bool c); -void bm_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern); +void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern); -void bm_line_clipped(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern); +void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern); -void bm_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); +void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); -inline void bm_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h); +inline void bmu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h); -inline void bm_rect_clear(Bitmap * dbm, int dx, int dy, int w, int h); +inline void bmu_rect_clear(Bitmap * dbm, int dx, int dy, int w, int h); -inline void bm_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern); +inline void bmu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern); -inline void bm_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); +inline void bmu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); -void bm_bitblit_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); +void bm_bitblit(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); -inline void bm_rect_fill_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h); +inline void bm_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h); -inline void bm_rect_clear_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h); +inline void bm_rect_clear(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h); -inline void bm_rect_pattern_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern); +inline void bm_rect_pattern(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern); -inline void bm_rect_copy_clipped(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); +inline void bm_rect_copy(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); -int bm_text(Bitmap * bm, const char * str, char len); +int bmu_text(Bitmap * bm, const char * str, char len); -int bm_text_size(const char * str, char len); +int bmu_text_size(const char * str, char len); -int bm_put_chars(Bitmap * bm, int x, int y, const char * str, char len, BlitOp op); +int bmu_put_chars(Bitmap * bm, int x, int y, const char * str, char len, BlitOp op); -int bm_put_chars_clipped(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, char len, BlitOp op); +int bm_put_chars(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, char len, BlitOp op); +int bm_put_string(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, BlitOp op); int bm_transform(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, Bitmap * sbm, int sx, int sy, int dxx, int dxy, int dyx, int dyy); diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 8957348..96ad0e7 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -4742,7 +4742,10 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) mIns[i + 2].mCode = BC_NOP; progress = true; } - else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister)) + else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && + !mIns[i + 0].mRelocate && !mIns[i + 2].mRelocate && + mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && + !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister)) { if (mIns[i + 0].mRegister == BC_REG_ACCU) mIns[i + 1].mLive |= LIVE_ACCU; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a93e50e..50aa266 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -168,6 +168,14 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps) if (mFlags & NCIF_USE_CPU_REG_A) requiredTemps += CPU_REG_A; + + if (mFlags & NCIF_FEXEC) + { + requiredTemps += BC_REG_LOCALS; + requiredTemps += BC_REG_LOCALS + 1; + for(int i= BC_REG_FPARAMS; i< BC_REG_FPARAMS_END; i++) + requiredTemps += i; + } } else { @@ -832,7 +840,7 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data) } data.mRegs[BC_REG_WORK_Y].Reset(); - if (!(mFlags & NCIF_RUNTIME)) + if (!(mFlags & NCIF_RUNTIME) || (mFlags & NCIF_FEXEC)) { for (int i = BC_REG_TMP; i < BC_REG_TMP_SAVED; i++) data.mRegs[i].Reset(); @@ -1470,7 +1478,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT } data.ResetZeroPage(BC_REG_WORK_Y); - if (!(mFlags & NCIF_RUNTIME)) + if (!(mFlags & NCIF_RUNTIME) || (mFlags & NCIF_FEXEC)) { for (int i = BC_REG_TMP; i < BC_REG_TMP_SAVED; i++) data.ResetZeroPage(i); @@ -2207,6 +2215,13 @@ void NativeCodeInstruction::FilterRegUsage(NumberSet& requiredTemps, NumberSet& if (!providedTemps[CPU_REG_A]) requiredTemps += CPU_REG_A; } + + if (mFlags & NCIF_FEXEC) + { + for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++) + if (!providedTemps[i]) + requiredTemps += i; + } } else { @@ -7588,7 +7603,7 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProc } NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("bcexec"))); - mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME)); + mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_FEXEC)); if (ins->mDst.mTemp >= 0) { diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 24ca0dd..40f7144 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -47,13 +47,14 @@ static const uint32 NCIF_RUNTIME = 0x00000004; static const uint32 NCIF_YZERO = 0x00000008; static const uint32 NCIF_VOLATILE = 0x00000010; static const uint32 NCIF_LONG = 0x00000020; +static const uint32 NCIF_FEXEC = 0x00000040; -static const uint32 NCIF_USE_CPU_REG_A = 0x00000040; -static const uint32 NCIF_USE_CPU_REG_X = 0x00000080; -static const uint32 NCIF_USE_CPU_REG_Y = 0x00000100; +static const uint32 NCIF_USE_CPU_REG_A = 0x00001000; +static const uint32 NCIF_USE_CPU_REG_X = 0x00002000; +static const uint32 NCIF_USE_CPU_REG_Y = 0x00004000; // use a 32bit zero page register indexed by X for JSR -static const uint32 NCIF_USE_ZP_32_X = 0x00000200; +static const uint32 NCIF_USE_ZP_32_X = 0x00008000; class NativeCodeInstruction { diff --git a/samples/hires/func3d.c b/samples/hires/func3d.c new file mode 100644 index 0000000..ffe6607 --- /dev/null +++ b/samples/hires/func3d.c @@ -0,0 +1,233 @@ +// func3d +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma region(main, 0x0a00, 0xc800, , , {code, data, bss, heap, stack} ) + + +#define Color ((char *)0xc800) +#define Hires ((char *)0xe000) + +Bitmap Screen = { + Hires, nullptr, 40, 25, 320 +}; + +ClipRect SRect = { + 0, 0, 320, 200 +} + +char chk[] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55}; +char white[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +char black[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + +Matrix4 wmat, pmat, tmat, rmat; +Vector3 vlight; + + +void init(void) +{ + mmap_set(MMAP_NO_BASIC); + + vic_setmode(VICM_HIRES, Color, Hires); + + vic.color_back = VCOL_WHITE; + vic.color_border = VCOL_WHITE; + + mmap_trampoline(); + mmap_set(MMAP_NO_ROM); + + memset(Color, 0x01, 1000); + memset(Hires, 0, 8000); +} + +void restore(void) +{ + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); + mmap_set(MMAP_ROM); +} + +struct Point +{ + int x, y; +}; + +#define HALF 15 +#define FULL (HALF + HALF) +#define SIZE (FULL + 1) +#define QFULL (FULL * FULL) + +Vector3 v[SIZE][SIZE]; +Point p[SIZE][SIZE]; +float z[SIZE][SIZE]; + +struct Surf +{ + float z; + char x, y; +} surfs[QFULL]; + + + +void qsort(Surf * n, int s) +{ + if (s > 1) + { + Surf pn = n[0]; + int pi = 0; + for(int i=1; i pn.z) + { + n[pi] = n[i]; + pi++; + n[i] = n[pi] + } + } + n[pi] = pn; + + qsort(n, pi); + qsort(n + pi + 1, s - pi - 1); + } +} + + +int main(void) +{ + init(); + + bm_put_string(&Screen, &SRect, 0, 0, "Preparing function", BLTOP_COPY); + + mat4_ident(&wmat); + mat4_make_perspective(&pmat, 0.5 * PI, 1.0, 0.0, 200.0); + + bm_put + + for(int ix=0; ix 0) + { + c = 8 - (int)(f * 9); + if (c < 5) + patt = 0xff; + } + + bm_quad_fill(&Screen, &SRect, + p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y, + p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, + p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, + p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, + NineShadesOfGrey[c]); + + + bm_line(&Screen, &SRect, + p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y, + p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, patt); + + bm_line(&Screen, &SRect, + p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, + p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt); + + bm_line(&Screen, &SRect, + p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y, + p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, patt); + + bm_line(&Screen, &SRect, + p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, + p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt); + } + + mmap_set(MMAP_NO_BASIC); +// getch(); + + restore(); + + return 0; +} \ No newline at end of file diff --git a/samples/hires/make.bat b/samples/hires/make.bat new file mode 100644 index 0000000..c8949ff --- /dev/null +++ b/samples/hires/make.bat @@ -0,0 +1,2 @@ +..\..\bin\oscar64 splitscreen.c +..\..\bin\oscar64 func3d.c -n diff --git a/samples/hires/splitscreen.c b/samples/hires/splitscreen.c new file mode 100644 index 0000000..1cb06b7 --- /dev/null +++ b/samples/hires/splitscreen.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include + +#define Color ((char *)0xc800) +#define Hires ((char *)0xe000) + +char white[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +char check[] = {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa}; +char black[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + +Bitmap Screen; + +RIRQCode rirqtop, rirqbottom; + +#pragma align(rirqtop, 32) +#pragma align(rirqbottom, 32) + +CharWin twin; +CharWin ewin; + +int main(void) +{ + mmap_trampoline(); + + mmap_set(MMAP_CHAR_ROM); + memcpy((char *)0xd000, (char *)0xd000, 4096); + mmap_set(MMAP_NO_ROM); + + rirq_init(true); + + vic.ctrl1 = VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3; + vic.ctrl2 = VIC_CTRL2_CSEL; + + vic.color_back = VCOL_BLACK; + + memset(Color, 0x10, 1000); + + vic_setbank(3); + vic.memptr = 0x28; + + rirq_build(&rirqtop, 2); + rirq_write(&rirqtop, 0, &vic.memptr, 0x28); + rirq_write(&rirqtop, 1, &vic.ctrl1, VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3); + + rirq_build(&rirqbottom, 3); + rirq_delay(&rirqbottom, 10); + rirq_write(&rirqbottom, 1, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3); + rirq_write(&rirqbottom, 2, &vic.memptr, 0x26); + + rirq_set(0, 10, &rirqtop); + rirq_set(1, 49 + 8 * 20, &rirqbottom); + rirq_sort(); + + rirq_start(); + + bm_init(&Screen, Hires, 40, 25); + + bmu_rect_pattern(&Screen, 0, 0, 320, 160, check); + bmu_rect_fill(&Screen, 0, 159, 320, 1); + bmu_rect_clear(&Screen, 0, 158, 320, 1); + + cwin_init(&twin, Color, 0, 20, 40, 4); + cwin_init(&ewin, Color, 0, 24, 40, 1); + + ClipRect rect = {0, 0, 320, 158}; + + cwin_clear(&twin); + cwin_putat_string(&twin, 0, 0, p"Enter x, y and radius for circle", 0x07); + + for(;;) + { + cwin_clear(&ewin); + cwin_cursor_move(&ewin, 0, 0); + + mmap_set(MMAP_NO_BASIC); + cwin_edit(&ewin); + mmap_set(MMAP_RAM); + + char str[40]; + cwin_read_string(&ewin, str); + + int n, x, y, r; + n = sscanf(str, "%d %d %d", &x, &y, &r); + + cwin_putat_string(&twin, 0, 1, str, 0x0e); + sprintf(str, p"N: %D X: %3D Y: %3D R: %2D", n, x, y, r); + cwin_putat_string(&twin, 0, 2, str, 0x07); + + if (n == 3) + { + bm_circle_fill(&Screen, &rect, x, y, r + 1, black); + bm_circle_fill(&Screen, &rect, x, y, r - 1, white); + } + + } + + return 0; +} diff --git a/samples/kernalio/charread.c b/samples/kernalio/charread.c new file mode 100644 index 0000000..d723946 --- /dev/null +++ b/samples/kernalio/charread.c @@ -0,0 +1,22 @@ +#include +#include + +int main(void) +{ + krnio_setnam("@0:CHARS,P,R"); + if (krnio_open(2, 9, 2)) + { + int ch, k = 0; + while ((ch = krnio_getch(2)) >= 0) + { + printf("%d : %d\n", k, ch) + k++; + if (ch & 0x100) + break; + } + + krnio_close(2); + } + + return 0; +} diff --git a/samples/kernalio/charwrite.c b/samples/kernalio/charwrite.c new file mode 100644 index 0000000..63e682f --- /dev/null +++ b/samples/kernalio/charwrite.c @@ -0,0 +1,16 @@ +#include +#include + +int main(void) +{ + krnio_setnam("@0:CHARS,P,W"); + if (krnio_open(2, 9, 2)) + { + for(char i=0; i<128; i++) + krnio_putch(2, i); + + krnio_close(2); + } + + return 0; +} diff --git a/samples/kernalio/diskdir.c b/samples/kernalio/diskdir.c new file mode 100644 index 0000000..caef559 --- /dev/null +++ b/samples/kernalio/diskdir.c @@ -0,0 +1,64 @@ +#include +#include + +int main(void) +{ + // Set name for directory + + krnio_setnam("$"); + + // Open #2 on drive 9 (or 8) + + if (krnio_open(2, 9, 0)) + { + // Switch input to file #2 + + if (krnio_chkin(2)) + { + // Skip BASIC load address + + krnio_chrin(); + krnio_chrin(); + + // Loop while we have more lines + + int ch; + while((ch = krnio_chrin()) > 0) + { + unsigned line; + char buff[40]; + + // Skip second basic link byte + krnio_chrin(); + + // Read line number (size in blocks) + ch = krnio_chrin(); + line = ch; + ch = krnio_chrin(); + line += 256 * ch; + + // Read file name, reading till end of basic line + int n = 0; + while ((ch = krnio_chrin()) > 0) + buff[n++] = ch; + buff[n] = 0; + + // Print size and name + + printf("%u %s\n", line, buff); + } + + // Reset channels + + krnio_clrchn(); + } + + // Close file #2 + + krnio_close(2); + } + else + printf("FAIL OPEN %d\n", krnio_status()); + + return 0; +} diff --git a/samples/kernalio/fileread.c b/samples/kernalio/fileread.c new file mode 100644 index 0000000..9d058ed --- /dev/null +++ b/samples/kernalio/fileread.c @@ -0,0 +1,28 @@ +#include +#include + +struct Score +{ + char name[5]; + unsigned score; +}; + +Score score[4]; + +int main(void) +{ + krnio_setnam("HIGHSCORE,P,R"); + if (krnio_open(2, 9, 2)) + { + krnio_read(2, (char*)score, sizeof(score)); + + krnio_close(2); + } + + for(int i=0; i<4; i++) + { + printf("%s : %u\n", score[i].name, score[i].score); + } + + return 0; +} diff --git a/samples/kernalio/filewrite.c b/samples/kernalio/filewrite.c new file mode 100644 index 0000000..58147d4 --- /dev/null +++ b/samples/kernalio/filewrite.c @@ -0,0 +1,28 @@ +#include +#include + +struct Score +{ + char name[5]; + unsigned score; +}; + +Score score[] = { + {"AAA", 10000}, + {"BBB", 9000}, + {"CCC", 8000}, + {"DDD", 4000} +}; + +int main(void) +{ + krnio_setnam("@0:HIGHSCORE,P,W"); + if (krnio_open(2, 9, 2)) + { + krnio_write(2, (char*)score, sizeof(score)); + + krnio_close(2); + } + + return 0; +} diff --git a/samples/kernalio/hiresread.c b/samples/kernalio/hiresread.c new file mode 100644 index 0000000..fdc1c0e --- /dev/null +++ b/samples/kernalio/hiresread.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include + +Bitmap Screen; + +#define ScreenMem ((char *)0xe000) +#define ColorMem ((char *)0xd000) + +int main(void) +{ + mmap_trampoline(); + + bm_init(&Screen, ScreenMem, 40, 25); + + mmap_set(MMAP_RAM); + memset(ScreenMem, 0, 8000); + memset(ColorMem, 0x70, 1000); + mmap_set(MMAP_NO_ROM); + + vic_setmode(VICM_HIRES, ColorMem, ScreenMem); + + mmap_set(MMAP_ROM); + krnio_setnam("TESTIMAGE,P,R"); + if (krnio_open(2, 9, 2)) + { + krnio_read(2, ScreenMem, 8000); + krnio_close(2); + } + + getchar(); + + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); + + return 0; +} diff --git a/samples/kernalio/hireswrite.c b/samples/kernalio/hireswrite.c new file mode 100644 index 0000000..feed6ec --- /dev/null +++ b/samples/kernalio/hireswrite.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include + +Bitmap Screen, Brush; +char Buffer[200]; + +#define ScreenMem ((char *)0xe000) +#define ColorMem ((char *)0xd000) + +int main(void) +{ + mmap_trampoline(); + + bm_init(&Screen, ScreenMem, 40, 25); + bm_alloc(&Brush, 2, 2); + + mmap_set(MMAP_RAM); + memset(ScreenMem, 0, 8000); + memset(ColorMem, 0x70, 1000); + mmap_set(MMAP_NO_ROM); + + vic_setmode(VICM_HIRES, ColorMem, ScreenMem); + + ClipRect crb = {0, 0, 16, 16}; + bm_fill(&Brush, 0); + bm_circle_fill(&Brush, &crb, 7, 7, 6, NineShadesOfGrey[8]); + + ClipRect crr = {0, 0, 320, 200}; + bm_circle_fill(&Screen, &crr, 160, 100, 90, NineShadesOfGrey[8]); + bm_circle_fill(&Screen, &crr, 120, 80, 20, NineShadesOfGrey[0]); + bm_circle_fill(&Screen, &crr, 200, 80, 20, NineShadesOfGrey[0]); + + for(int x=-40; x<=40; x+=4) + { + int y = bm_usqrt(50 * 50 - x * x); + bm_bitblit(&Screen, &crr, 160 - 7 + x, 100 + y, &Brush, 0, 0, 15, 15, nullptr, BLTOP_AND_NOT); + } + + + mmap_set(MMAP_ROM); + krnio_setnam("@0:TESTIMAGE,P,W"); + if (krnio_open(2, 9, 2)) + { + for(int i=0; i<8000; i+=200) + { + mmap_set(MMAP_NO_ROM); + memcpy(Buffer, ScreenMem + i, 200); + mmap_set(MMAP_ROM); + + krnio_write(2, Buffer, 200); + } + + krnio_close(2); + } + + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); + + return 0; +} diff --git a/samples/kernalio/make.bat b/samples/kernalio/make.bat new file mode 100644 index 0000000..c4e82ee --- /dev/null +++ b/samples/kernalio/make.bat @@ -0,0 +1,7 @@ +..\..\bin\oscar64 diskdir.c +..\..\bin\oscar64 filewrite.c +..\..\bin\oscar64 fileread.c +..\..\bin\oscar64 charwrite.c +..\..\bin\oscar64 charread.c +..\..\bin\oscar64 hireswrite.c +..\..\bin\oscar64 hiresread.c diff --git a/samples/memmap/charsetcopy.c b/samples/memmap/charsetcopy.c new file mode 100644 index 0000000..0a1dfa0 --- /dev/null +++ b/samples/memmap/charsetcopy.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +// make space until 0xcc00 by extending the default region + +#pragma region( main, 0x0a00, 0xcc00, , , {code, data, bss, heap, stack} ) + +// space for our custom charset from c000 to c800, will be copied to +// 0xd000 during startup to free space for stack and heap + +#pragma section( charset, 0) + +#pragma region( charset, 0xc000, 0xc800, , , {charset} ) + +// set initialized data segment to charset section + +#pragma data(charset) + +char charset[2048] = { + #embed "../resources/charset.bin" +} + +// back to normal + +#pragma data(data) + +// pointers to charset and screen in memory + +#define Screen ((char *)0xcc00) +#define Charset ((char *)0xd000) + +int main(void) +{ + // Install the trampoline + mmap_trampoline(); + + // make all of RAM visibile to the CPU + mmap_set(MMAP_RAM); + + // copy the font + memcpy(Charset, charset, 2048) + + // make lower part of RAM visible to CPU + mmap_set(MMAP_NO_BASIC); + + // map the vic to the new charset + + vic_setmode(VICM_TEXT, Screen, Charset) + + for(int i=0; i<1000; i++) + Screen[i] = (char)i; + + // wait for keypress + + getchar(); + + // restore VIC + + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000) + + // restore basic ROM + mmap_set(MMAP_ROM); + + return 0; +} + diff --git a/samples/memmap/charsethi.c b/samples/memmap/charsethi.c new file mode 100644 index 0000000..b315b3d --- /dev/null +++ b/samples/memmap/charsethi.c @@ -0,0 +1,34 @@ +#include +#include +#include + + +// space for our custom charset from c800 + +#pragma section( charset, 0) + +#pragma region( charset, 0xc800, 0xd000, , , {charset} ) + +#pragma data(charset) + +char charset[2048] = { + #embed "../resources/charset.bin" +} + +#pragma data(data) + +#define Screen ((char *)0xc000) + + +int main(void) +{ + // map the vic to the new charset + + vic_setmode(VICM_TEXT, Screen, charset) + + for(int i=0; i<1000; i++) + Screen[i] = (char)i; + + return 0; +} + diff --git a/samples/memmap/make.bat b/samples/memmap/make.bat index d888275..dd6a4e0 100644 --- a/samples/memmap/make.bat +++ b/samples/memmap/make.bat @@ -1,3 +1,5 @@ ..\..\bin\oscar64 largemem.c ..\..\bin\oscar64 allmem.c ..\..\bin\oscar64 charsetlo.c +..\..\bin\oscar64 charsethi.c +..\..\bin\oscar64 charsetcopy.c