From 47a9dee1ab7c1b2204b6a67c304b278be8c2dc9f Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Fri, 5 Jan 2024 17:21:38 -0600 Subject: [PATCH] DMA, fixed text, random numbers, lines. --- examples/pgztest/build.sh | 10 ---- examples/pgztest/pgztest.c | 80 ++++++++++++++++++++++++++++++-- f256lib/bitmap.c | 94 ++++++++++++++++++++++++++++++-------- f256lib/bitmap.h | 4 +- f256lib/dma.c | 56 +++++++++++++++++++++++ f256lib/dma.h | 45 ++++++++++++++++++ f256lib/f256.c | 37 +++++++++++++-- f256lib/f256.h | 19 ++++++-- f256lib/text.c | 36 +++++++++++---- f256lib/text.h | 1 + 10 files changed, 331 insertions(+), 51 deletions(-) create mode 100644 f256lib/dma.c create mode 100644 f256lib/dma.h diff --git a/examples/pgztest/build.sh b/examples/pgztest/build.sh index 7064004..5db0eab 100755 --- a/examples/pgztest/build.sh +++ b/examples/pgztest/build.sh @@ -31,16 +31,6 @@ PATH=${LLVM}/bin:${PATH} START=0x2000 echo "__f256_start = ${START};" > ${SETTINGS} -:<= x1) { + dx = x2 - x1; + incX = 1; + } else { + dx = x1 - x2; + incX = -1; + } + + if (y2 >= y1) { + dy = y2 - y1; + incY = 1; + } else { + dy = y1 - y2; + incY = -1; + } + + x = x1; + y = y1; + + if (dx >= dy) { + dy <<= 1; + balance = dy - dx; + dx <<= 1; + while (x != x2) { + putpixel(x, y); + if (balance >= 0) { + y += incY; + balance -= dx; + } + balance += dy; + x += incX; + } + putpixel(x, y); + } else { + dx <<= 1; + balance = dx - dy; + dy <<= 1; + while (y != y2) { + putpixel(x, y); + if (balance >= 0) { + x += incX; + balance -= dy; + } + balance += dx; + y += incY; + } + putpixel(x, y); + } +} + + +void putpixel(int16_t x, int16_t y) { uint32_t pixelRAM; byte block; // We only map 8k of the bitmap into CPU RAM at once. // We use slot 5 for this. We need to figure out // where our pixel lands and bring that into RAM. - pixelRAM = _BITMAP_BASE + (y * _MAX_X) + x; + pixelRAM = _BITMAP_BASE + ((int32_t)y * (int32_t)_MAX_X) + (int32_t)x; block = pixelRAM / 0x2000; pixelRAM &= 0x1FFF; // Find offset into this block. POKE(MMU_MEM_BANK_5, block); @@ -89,7 +144,6 @@ void resetGraphics(void) { _MAX_X = 320; _MAX_Y = 240; _BITMAP_BASE = 0x10000; - _color = 255; POKE(MMU_IO_CTRL, MMU_IO_PAGE_0); // Swap I/O page 0 into bank 6. @@ -100,7 +154,7 @@ void resetGraphics(void) { // Set up bitmap 0. POKE(VKY_BM0_CTRL, 1); // Enable bitmap 0, GLUT 0. - POKED(VKY_BM0_ADDR_L, _BITMAP_BASE); // Location of bitmap data. + POKEA(VKY_BM0_ADDR_L, _BITMAP_BASE); // Location of bitmap data. //POKE(VKY_BM0_ADDR_L, _BITMAP_BASE & 0xFF); // Location of bitmap data. //POKE(VKY_BM0_ADDR_M, (_BITMAP_BASE >> 8) & 0xFF); // Location of bitmap data. //POKE(VKY_BM0_ADDR_H, (_BITMAP_BASE >> 16) & 0xFF); // Location of bitmap data. @@ -110,7 +164,9 @@ void resetGraphics(void) { // Set palette to a gradient so there's at least *something*. for (x=0; x<256; x++) defineGraphicsColor(x, x, x, x); + _color = 0; clearBitmap(); + _color = 255; } diff --git a/f256lib/bitmap.h b/f256lib/bitmap.h index 1627206..323c09e 100644 --- a/f256lib/bitmap.h +++ b/f256lib/bitmap.h @@ -36,7 +36,9 @@ extern "C" void clearBitmap(void); void defineGraphicsColor(byte slot, byte r, byte g, byte b); -void putpixel(int x, int y); +void getBitmapResolution(int16_t *x, int16_t *y); +void line(int16_t x1, int16_t y1, int16_t x2, int16_t y2); +void putpixel(int16_t x, int16_t y); void resetGraphics(void); void setGraphicsColor(byte c); diff --git a/f256lib/dma.c b/f256lib/dma.c new file mode 100644 index 0000000..74098ac --- /dev/null +++ b/f256lib/dma.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "dma.h" + + +char error; + + +static void dmaWait(void); + + +void dmaFill(uint32_t start, uint32_t length, byte value) { + byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + + POKE(MMU_IO_CTRL, MMU_IO_PAGE_0); // Swap I/O page 0 into bank 6. + + POKE(DMA_CTRL, DMA_CTRL_FILL | DMA_CTRL_ENABLE); + POKE(DMA_FILL_VAL, value); + POKEA(DMA_DST_ADDR, start); + POKEA(DMA_COUNT, length); + POKE(DMA_CTRL, DMA_CTRL_FILL | DMA_CTRL_ENABLE | DMA_CTRL_START); + + dmaWait(); + + POKE(MMU_IO_CTRL, mmu); // Restore MMU state. +} + + +static void dmaWait(void) { + while (PEEK(DMA_STATUS) & DMA_STAT_BUSY) + // Spin our wheels. + ; + + POKE(DMA_CTRL, 0); +} diff --git a/f256lib/dma.h b/f256lib/dma.h new file mode 100644 index 0000000..ebb1cfe --- /dev/null +++ b/f256lib/dma.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef DMA_H +#define DMA_H + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#include "f256.h" + + +void dmaFill(uint32_t start, uint32_t length, byte value); + + +#ifdef __cplusplus +} +#endif + + +#endif // DMA_H diff --git a/f256lib/f256.c b/f256lib/f256.c index a86afd0..43bde53 100644 --- a/f256lib/f256.c +++ b/f256lib/f256.c @@ -25,6 +25,7 @@ #include "text.c" #include "bitmap.c" +#include "dma.c" void f256Init(void) { @@ -33,10 +34,11 @@ void f256Init(void) { POKE(MMU_IO_CTRL, MMU_IO_PAGE_0); // Swap I/O page 0 into bank 6. //POKE(VKY_MSTR_CTRL_0, 1); // Enable text. - POKE(VKY_MSTR_CTRL_0, 12); // Enable bitmaps. - //POKE(VKY_MSTR_CTRL_0, 15); // Enable text and bitmaps. + //POKE(VKY_MSTR_CTRL_0, 12); // Enable bitmaps. + POKE(VKY_MSTR_CTRL_0, 15); // Enable text and bitmaps. //POKE(VKY_MSTR_CTRL_0, 63); // Enable text and all graphics. - POKE(VKY_MSTR_CTRL_1, 16); // Enable FON_OVLY. + //POKE(VKY_MSTR_CTRL_1, 20); // Enable FON_OVLY and DBL_Y. + POKE(VKY_MSTR_CTRL_1, 4); // Enable DBL_Y. POKE(MMU_IO_CTRL, mmu); // Restore MMU state. @@ -50,4 +52,33 @@ void f256Init(void) { POKE(MMU_MEM_BANK_5, 5); // MMU_MEM_BANK_6 is always mapped to I/O. // MMU_MEM_BANK_7 belongs to the MicroKernel. + + rndSeed(0); //***TODO*** Use clock or something. +} + + +uint16_t rndRead(void) { + byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + uint16_t result; + + POKE(MMU_IO_CTRL, MMU_IO_PAGE_0); // Swap I/O page 0 into bank 6. + + POKE(VKY_RND_CTRL, 1); // Enable. + result = PEEKW(VKY_RNDL); + + POKE(MMU_IO_CTRL, mmu); // Restore MMU state. + + return result; +} + + +void rndSeed(uint16_t seed) { + byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + + POKE(MMU_IO_CTRL, MMU_IO_PAGE_0); // Swap I/O page 0 into bank 6. + + POKEW(VKY_SEEDL, seed); + POKE(VKY_RND_CTRL, 3); // Enable, load seed. + + POKE(MMU_IO_CTRL, mmu); // Restore MMU state. } diff --git a/f256lib/f256.h b/f256lib/f256.h index bd89c5c..971c2a7 100644 --- a/f256lib/f256.h +++ b/f256lib/f256.h @@ -51,12 +51,22 @@ extern "C" typedef unsigned char byte; +// Single-byte #define PEEK(addy) ((byte)*(volatile byte *)(addy)) #define POKE(addy, value) (*(volatile byte *)(addy) = (value)) -#define PEEKW(addy) ((uint_16)*(volatile uint16_t *)(addy)) -#define POKEW(addy,value) (*(volatile uint16_t *)(addy) = (value)) + +// Word (two bytes) +#define PEEKW(addy) ((uint16_t)*(volatile uint16_t *)(addy)) +#define POKEW(addy, value) (*(volatile uint16_t *)(addy) = (value)) + +// Address (three bytes) +//#define PEEKA +#define POKEA(addy, value) POKE(addy, value & 0xFF); POKE(addy + 1, (value >> 8) & 0xFF); POKE(addy + 2, (value >> 16) & 0xFF) + +// Double-word (four bytes) #define PEEKD(addy) ((uint_32)*(volatile uint32_t *)(addy)) #define POKED(addy,value) (*(volatile uint32_t *)(addy) = (value)) + #define VECTOR(member) (size_t)(&((struct call *)0xff00)->member) #define EVENT(member) (size_t)(&((struct events *)0)->member) #define CALL(fn) \ @@ -72,11 +82,14 @@ extern struct event_t event; // The event struct is allocated in crt0. extern char error; -void f256Init(void); +void f256Init(void); +uint16_t rndRead(void); +void rndSeed(uint16_t seed); #include "text.h" #include "bitmap.h" +#include "dma.h" #ifdef __cplusplus diff --git a/f256lib/text.c b/f256lib/text.c index 577a4ad..7f3012f 100644 --- a/f256lib/text.c +++ b/f256lib/text.c @@ -48,7 +48,7 @@ colorT textColors[16] = { static byte _MAX_COL = 80; -static byte _MAX_ROW = 60; +static byte _MAX_ROW = 30; static byte _row = 0; static byte _col = 0; static byte _fcolor = 15; @@ -119,11 +119,11 @@ void gotoxy(byte x, byte y) { // Print a string to the screen. void print(char *message) { - int x = 0; - int i = 0; - int j = 0; - byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. - volatile byte *vram = (byte *)TEXT_MATRIX + _col + (_MAX_COL * _row); + int x = 0; + int i = 0; + int j = 0; + byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + volatile byte *vram = (byte *)TEXT_MATRIX + (_MAX_COL * _row); volatile byte *save = 0; while (message[x] != 0) { @@ -158,10 +158,10 @@ void print(char *message) { for (i = 0; i < _MAX_COL; i++) *vram++ = 32; // Set up on bottom line. _row--; - vram = (byte *)TEXT_MATRIX + _MAX_COL * (_MAX_ROW - 2) + 1; - break; + vram = (byte *)TEXT_MATRIX + (_MAX_ROW - 1); + } else { + vram += _MAX_COL; } - vram += _MAX_COL; break; } x++; @@ -173,6 +173,22 @@ void print(char *message) { } +void printInt(int32_t value){ + char c[2]; + + if (value < 0) { + print("-"); + value = -value; + } + + if (value > 9) printInt(value / 10); + + c[0] = '0' + (value % 10); + c[1] = 0; + print(c); +} + + // Reset display to text, "standard" colors. void resetText(void) { byte mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. @@ -180,7 +196,7 @@ void resetText(void) { byte y; _MAX_COL = 80; - _MAX_ROW = 60; + _MAX_ROW = 30; _fcolor = 15; _bcolor = 0; diff --git a/f256lib/text.h b/f256lib/text.h index c3d1729..208552a 100644 --- a/f256lib/text.h +++ b/f256lib/text.h @@ -71,6 +71,7 @@ void cls(void); void defineTextColor(byte slot, byte fr, byte fg, byte fb, byte br, byte bg, byte bb); void gotoxy(byte x, byte y); void print(char *message); +void printInt(int32_t value); void resetText(void); void setTextColor(byte f, byte b);