Added A2-3D2 example.
This commit is contained in:
parent
72a6812c1a
commit
cd27a5061a
23 changed files with 924 additions and 88 deletions
|
@ -28,6 +28,7 @@ TARGET=f256lib.h
|
|||
|
||||
cat f256lib/stddclmr.h > ${TARGET}
|
||||
|
||||
echo "#ifndef F256LIB_AMALGAMATED_BUILD" >> ${TARGET}
|
||||
echo "#define F256LIB_AMALGAMATED_BUILD" >> ${TARGET}
|
||||
|
||||
cat f256lib/f_api.h >> ${TARGET}
|
||||
|
@ -73,4 +74,5 @@ cat f256lib/f_sprite.c >> ${TARGET}
|
|||
cat f256lib/f_file.c >> ${TARGET}
|
||||
cat f256lib/f_platform.c >> ${TARGET}
|
||||
|
||||
echo "#endif" >> ${TARGET}
|
||||
echo "#endif // F256LIB_IMPLEMENTATION" >> ${TARGET}
|
||||
echo "#endif // F256LIB_AMALGAMATED_BUILD" >> ${TARGET}
|
||||
|
|
BIN
examples/a23d2/a2-3d/A2-3D2#066000
(Stored with Git LFS)
Normal file
BIN
examples/a23d2/a2-3d/A2-3D2#066000
(Stored with Git LFS)
Normal file
Binary file not shown.
75
examples/a23d2/build.sh
Executable file
75
examples/a23d2/build.sh
Executable file
|
@ -0,0 +1,75 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
PROJECT=3ddemo
|
||||
|
||||
F256=$(readlink -f $(pwd)/../..)
|
||||
LLVM=${F256}/llvm-mos
|
||||
PATH=${LLVM}/bin:${PATH}
|
||||
CLANG="mos-f256k-clang -I${F256} -I$(pwd)/src -Os"
|
||||
|
||||
# Out-of-tree build to keep things tidy.
|
||||
[[ -d .builddir ]] && rm -rf .builddir
|
||||
mkdir -p .builddir
|
||||
|
||||
# Generate overlay data. Do not use relative paths.
|
||||
${F256}/overlay 5 $(pwd)/.builddir $(pwd)/src
|
||||
|
||||
pushd .builddir
|
||||
|
||||
# Copy Apple ][ binary library A2-3D2 and truncate it to 8k.
|
||||
# The truncated bits are Apple ][ rendering code, so we don't need it.
|
||||
cp ../a2-3d/A2-3D2#066000 a2-3d2.bin
|
||||
truncate -s 8k a2-3d2.bin
|
||||
|
||||
# Compile the 3D scene database generator and run it.
|
||||
cc -I../src -I${F256} ../tools/scene.c -o scene
|
||||
./scene
|
||||
|
||||
# Concatinate our embedded binary data into a single file.
|
||||
cat a2-3d2.bin scene.3d > embedded.bin
|
||||
|
||||
# Compile our code and the A2-3D2 support library.
|
||||
${CLANG} -c main.c
|
||||
${CLANG} -c a23d2.c
|
||||
|
||||
# Link!
|
||||
${CLANG} -T ../f256.ld \
|
||||
-Wl,-Map=${PROJECT}.map \
|
||||
-o ${PROJECT} \
|
||||
main.o a23d2.o
|
||||
|
||||
# Rename results to PGZ.
|
||||
mv ${PROJECT} ${PROJECT}.pgz
|
||||
|
||||
# Generate debugging goodness.
|
||||
llvm-nm ${PROJECT}.elf > ${PROJECT}.sym
|
||||
llvm-objdump --syms -d --print-imm-hex ${PROJECT}.elf > ${PROJECT}.lst
|
||||
hexdump -C ${PROJECT}.pgz > ${PROJECT}.hex
|
||||
python ${F256}/pgz-thunk.py ${PROJECT}.pgz
|
||||
|
||||
# Put the PGZ in the main directory.
|
||||
mv ${PROJECT}.pgz ../.
|
||||
popd
|
116
examples/a23d2/f256.ld
Normal file
116
examples/a23d2/f256.ld
Normal file
|
@ -0,0 +1,116 @@
|
|||
/* fake C Stack */
|
||||
PROVIDE(__stack = 0xA000);
|
||||
/* entry point to my program */
|
||||
PROVIDE(__f256_start = 0x300);
|
||||
/* page size of a block of memory */
|
||||
PROVIDE(__BLOCK_SIZE = 0x2000);
|
||||
/* swappable block address */
|
||||
PROVIDE(__SLOT_ADDR = 0xA000);
|
||||
|
||||
/* f256k uses first 16 bytes of ZP for mmu control? */
|
||||
__rc0 = 0x10;
|
||||
/* __rc0 = 0xc3; */
|
||||
INCLUDE imag-regs.ld
|
||||
/*
|
||||
ASSERT(__rc0 == 0x10, "Inconsistent zero page map.")
|
||||
ASSERT(__rc31 == 0x2f, "Inconsistent zero page map.")
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
/* kernel uses 0xf0-0xff for parameter passing */
|
||||
/* A2-3D2 uses 0x60-0xc2 */
|
||||
zp : ORIGIN = __rc31 + 1, LENGTH = 0xF0 - (__rc31 + 1)
|
||||
/* zp : ORIGIN = 0x10, LENGTH = 80 */
|
||||
ram (rw) : ORIGIN = __f256_start, LENGTH = __stack-__f256_start
|
||||
}
|
||||
|
||||
/* LMAs */
|
||||
__block8_lma = ( 8<<24)|__SLOT_ADDR;
|
||||
__block9_lma = ( 9<<24)|__SLOT_ADDR;
|
||||
__block10_lma = (10<<24)|__SLOT_ADDR;
|
||||
__block11_lma = (11<<24)|__SLOT_ADDR;
|
||||
__block12_lma = (12<<24)|__SLOT_ADDR;
|
||||
__block13_lma = (13<<24)|__SLOT_ADDR;
|
||||
__block14_lma = (14<<24)|__SLOT_ADDR;
|
||||
__block15_lma = (15<<24)|__SLOT_ADDR;
|
||||
__block16_lma = (16<<24)|__SLOT_ADDR;
|
||||
__block17_lma = (17<<24)|__SLOT_ADDR;
|
||||
__block18_lma = (18<<24)|__SLOT_ADDR;
|
||||
__block19_lma = (19<<24)|__SLOT_ADDR;
|
||||
__block20_lma = (20<<24)|__SLOT_ADDR;
|
||||
__block21_lma = (21<<24)|__SLOT_ADDR;
|
||||
__block22_lma = (22<<24)|__SLOT_ADDR;
|
||||
__block23_lma = (23<<24)|__SLOT_ADDR;
|
||||
|
||||
/* Stash preloaded binary data */
|
||||
__binarydata_lma = 0x54000; /* Block 42 */
|
||||
__BINARYDATA_SIZE = 0x2C000; /* Size of A2-3D2, 3D/2D data area, and 2 bitmaps. */
|
||||
|
||||
MEMORY {
|
||||
block8 : ORIGIN = __block8_lma, LENGTH = __BLOCK_SIZE
|
||||
block9 : ORIGIN = __block9_lma, LENGTH = __BLOCK_SIZE
|
||||
block10 : ORIGIN = __block10_lma, LENGTH = __BLOCK_SIZE
|
||||
block11 : ORIGIN = __block11_lma, LENGTH = __BLOCK_SIZE
|
||||
block12 : ORIGIN = __block12_lma, LENGTH = __BLOCK_SIZE
|
||||
block13 : ORIGIN = __block13_lma, LENGTH = __BLOCK_SIZE
|
||||
block14 : ORIGIN = __block14_lma, LENGTH = __BLOCK_SIZE
|
||||
block15 : ORIGIN = __block15_lma, LENGTH = __BLOCK_SIZE
|
||||
block16 : ORIGIN = __block16_lma, LENGTH = __BLOCK_SIZE
|
||||
block17 : ORIGIN = __block17_lma, LENGTH = __BLOCK_SIZE
|
||||
block18 : ORIGIN = __block18_lma, LENGTH = __BLOCK_SIZE
|
||||
block19 : ORIGIN = __block19_lma, LENGTH = __BLOCK_SIZE
|
||||
block20 : ORIGIN = __block20_lma, LENGTH = __BLOCK_SIZE
|
||||
block21 : ORIGIN = __block21_lma, LENGTH = __BLOCK_SIZE
|
||||
block22 : ORIGIN = __block22_lma, LENGTH = __BLOCK_SIZE
|
||||
block23 : ORIGIN = __block23_lma, LENGTH = __BLOCK_SIZE
|
||||
binarydata : ORIGIN = __binarydata_lma, LENGTH = __BINARYDATA_SIZE
|
||||
}
|
||||
|
||||
REGION_ALIAS("c_writeable", ram)
|
||||
REGION_ALIAS("c_readonly", ram)
|
||||
|
||||
SECTIONS {
|
||||
INCLUDE c.ld
|
||||
.block8 : { *(.block8 .block8.*) } >block8 end_block8 = .;
|
||||
.block9 : { *(.block9 .block9.*) } >block9 end_block9 = .;
|
||||
.block10 : { *(.block10 .block10.*) } >block10 end_block10 = .;
|
||||
.block11 : { *(.block11 .block11.*) } >block11 end_block11 = .;
|
||||
.block12 : { *(.block12 .block12.*) } >block12 end_block12 = .;
|
||||
.block13 : { *(.block13 .block13.*) } >block13 end_block13 = .;
|
||||
.block14 : { *(.block14 .block14.*) } >block14 end_block14 = .;
|
||||
.block15 : { *(.block15 .block15.*) } >block15 end_block15 = .;
|
||||
.block16 : { *(.block16 .block16.*) } >block16 end_block16 = .;
|
||||
.block17 : { *(.block17 .block17.*) } >block17 end_block17 = .;
|
||||
.block18 : { *(.block18 .block18.*) } >block18 end_block18 = .;
|
||||
.block19 : { *(.block19 .block19.*) } >block19 end_block19 = .;
|
||||
.block20 : { *(.block20 .block20.*) } >block20 end_block20 = .;
|
||||
.block21 : { *(.block21 .block21.*) } >block21 end_block21 = .;
|
||||
.block22 : { *(.block22 .block22.*) } >block22 end_block22 = .;
|
||||
.block23 : { *(.block23 .block23.*) } >block23 end_block23 = .;
|
||||
.binarydata : { *(.binarydata .binarydata.*) } >binarydata end_binarydata = .;
|
||||
}
|
||||
|
||||
OUTPUT_FORMAT {
|
||||
BYTE(0x5A) /* pgZ */
|
||||
|
||||
/* RAM Segment */
|
||||
SHORT(ORIGIN(ram)) /* where to load it, 24 bits */
|
||||
BYTE(0x00)
|
||||
SHORT(__bss_start-ORIGIN(ram)) /* size to load */
|
||||
BYTE(0x00)
|
||||
TRIM(ram)
|
||||
|
||||
/* Overlay Segments */
|
||||
INCLUDE output.ld
|
||||
|
||||
/* Binary Data */
|
||||
SHORT(ORIGIN(binarydata))
|
||||
BYTE(ORIGIN(binarydata)>>16)
|
||||
SHORT(end_binarydata - __binarydata_lma)
|
||||
BYTE((end_binarydata - __binarydata_lma)>>16)
|
||||
TRIM(binarydata)
|
||||
|
||||
/* Launch the program, at _start */
|
||||
SHORT(_start)
|
||||
LONG(0)
|
||||
}
|
26
examples/a23d2/run.sh
Executable file
26
examples/a23d2/run.sh
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
python ../../FoenixMgr/FoenixMgr/fnxmgr.py --run-pgz 3ddemo.pgz
|
178
examples/a23d2/src/a23d2.c
Normal file
178
examples/a23d2/src/a23d2.c
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* 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 "a23d2.h"
|
||||
|
||||
#include <string.h> // For memcopy
|
||||
|
||||
|
||||
cameraT *_camera = (cameraT *)0x200; // Simulation copy of camera.
|
||||
cameraT *_cameraInDatabase;
|
||||
|
||||
uint16_t _drawlist;
|
||||
uint16_t _drawlistInDatabase;
|
||||
|
||||
byte *_pointer;
|
||||
uint16_t _bytes;
|
||||
uint8_t _x1;
|
||||
uint8_t _y1;
|
||||
uint8_t _x2;
|
||||
uint8_t _y2;
|
||||
bool _useColor;
|
||||
byte _mmu;
|
||||
byte _ram;
|
||||
|
||||
|
||||
#define SEGMENT_A23D2
|
||||
|
||||
|
||||
// There's a lot of global use in here. We can't use the virtual stack.
|
||||
|
||||
|
||||
void a23d2Draw(void) {
|
||||
|
||||
_pointer = (byte *)_drawlist;
|
||||
|
||||
// Move our 3D/2D data buffer at 0x56000 into slot 4.
|
||||
POKE(MMU_MEM_BANK_4, DATABASE_FAR_BLOCK);
|
||||
|
||||
while (true) {
|
||||
switch (*_pointer++) {
|
||||
|
||||
// Line.
|
||||
case (byte)LIN2D:
|
||||
_x1 = (uint8_t)((int8_t)(*_pointer++) + 128);
|
||||
_y1 = 255 - (uint8_t)((int8_t)(*_pointer++) + 128);
|
||||
_x2 = (uint8_t)((int8_t)(*_pointer++) + 128);
|
||||
_y2 = 255 - (uint8_t)((int8_t)(*_pointer++) + 128);
|
||||
bitmapLine(_x1, _y1, _x2, _y2);
|
||||
continue;
|
||||
|
||||
// Point.
|
||||
case (byte)PNT2D:
|
||||
_x1 = (uint8_t)((int8_t)(*_pointer++) + 128);
|
||||
_y1 = 255 - (uint8_t)((int8_t)(*_pointer++) + 128);
|
||||
bitmapPutPixel(_x1, _y1);
|
||||
continue;
|
||||
|
||||
// Set Color.
|
||||
case (byte)STCOL:
|
||||
_x1 = (int8_t)(*_pointer++);
|
||||
if (_useColor) bitmapSetColor(_x1);
|
||||
continue;
|
||||
|
||||
// Set Resolution.
|
||||
case (byte)SRES:
|
||||
// Eat this byte. We don't need it.
|
||||
_pointer++;
|
||||
continue;
|
||||
|
||||
// End.
|
||||
case (byte)END:
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Restore memory map.
|
||||
POKE(MMU_MEM_BANK_4, 4);
|
||||
}
|
||||
|
||||
|
||||
void a23d2Init(void) {
|
||||
// We need to manually page 0x54000 into 0x6000.
|
||||
// This isn't actually large enough for A2-3D2 but what we should only
|
||||
// lose Apple ][ stuff we're not using anyway.
|
||||
POKE(MMU_MEM_BANK_3, A23D2_FAR_BLOCK);
|
||||
|
||||
// We're going to clobber from 0x80fb to 0x8101. Back it up.
|
||||
memcpy((byte *)0x2f7, (byte *)0x80fb, 0x06);
|
||||
|
||||
// Initialize A2-3D2 so we can use the "fast entry point" (NXTPT) when rendering.
|
||||
_bytes = 0;
|
||||
_pointer = (byte *)0x80fb; // Standard location for test database in A2-3D2.
|
||||
_pointer[_bytes++] = SCRSZ; // Screen size. 256x240. Center is 0,0.
|
||||
_pointer[_bytes++] = 255;
|
||||
_pointer[_bytes++] = 239;
|
||||
_pointer[_bytes++] = 0;
|
||||
_pointer[_bytes++] = 0;
|
||||
_pointer[_bytes++] = END; // Setup complete!
|
||||
|
||||
asm("jsr 0x606c"); // Call ENTRYS. This preserves the ZP for us.
|
||||
|
||||
// Put back the RAM we clobbered.
|
||||
memcpy((byte *)0x80fb, (byte *)0x2f7, 0x06);
|
||||
|
||||
// Move our 3D/2D data buffer at 0x56000 into slot 4.
|
||||
POKE(MMU_MEM_BANK_4, DATABASE_FAR_BLOCK);
|
||||
|
||||
// Set up drawlists.
|
||||
_drawlistInDatabase = DATABASE + 1; // First value after ARRAY in near memory.
|
||||
POKE(DRAWLIST_P0, END);
|
||||
POKE(DRAWLIST_P1, END);
|
||||
|
||||
// Set up camera.
|
||||
_cameraInDatabase = (cameraT *)(DATABASE + 4); // First value after EYE in near memory.
|
||||
_camera->x = _cameraInDatabase->x;
|
||||
_camera->y = _cameraInDatabase->y;
|
||||
_camera->z = _cameraInDatabase->z;
|
||||
_camera->p = _cameraInDatabase->p;
|
||||
_camera->b = _cameraInDatabase->b;
|
||||
_camera->h = _cameraInDatabase->h;
|
||||
|
||||
// Restore memory map.
|
||||
POKE(MMU_MEM_BANK_4, 4);
|
||||
POKE(MMU_MEM_BANK_3, 3);
|
||||
}
|
||||
|
||||
|
||||
void a23d2Render(void) {
|
||||
// We need to manually page 0x54000 into 0x6000.
|
||||
// This isn't actually large enough for A2-3D2 but what we should only
|
||||
// lose Apple ][ stuff we're not using anyway.
|
||||
POKE(MMU_MEM_BANK_3, A23D2_FAR_BLOCK);
|
||||
|
||||
// Move our 3D/2D data buffer at 0x56000 into slot 4.
|
||||
POKE(MMU_MEM_BANK_4, DATABASE_FAR_BLOCK);
|
||||
|
||||
// Update drawlist.
|
||||
POKEW(_drawlistInDatabase, _drawlist);
|
||||
|
||||
// Update camera position.
|
||||
_cameraInDatabase->x = _camera->x;
|
||||
_cameraInDatabase->y = _camera->y;
|
||||
_cameraInDatabase->z = _camera->z;
|
||||
_cameraInDatabase->p = _camera->p;
|
||||
_cameraInDatabase->b = _camera->b;
|
||||
_cameraInDatabase->h = _camera->h;
|
||||
|
||||
memcpy((byte *)0x29d, (byte *)0x60, 0x62); // Save the ZP we're going to clobber.
|
||||
POKEW(0x9b, DATABASE); // Set IBP.
|
||||
asm("jsr 0x6118":::"a","x","y","c","v"); // Call NXTPT.
|
||||
memcpy((byte *)0x60, (byte *)0x29d, 0x62); // Put the ZP back.
|
||||
|
||||
// Restore memory map.
|
||||
POKE(MMU_MEM_BANK_4, 4);
|
||||
POKE(MMU_MEM_BANK_3, 3);
|
||||
}
|
111
examples/a23d2/src/a23d2.h
Normal file
111
examples/a23d2/src/a23d2.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __F256K__
|
||||
#include "f256lib.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
typedef uint8_t byte;
|
||||
#endif
|
||||
|
||||
|
||||
#define A23D2_FAR_BLOCK 42
|
||||
#define DATABASE_FAR_BLOCK 43
|
||||
|
||||
#define DATABASE_FAR 0x56000
|
||||
#define DRAWLIST_P0_FAR 0x57000
|
||||
#define DRAWLIST_P1_FAR 0x57800
|
||||
|
||||
#define DATABASE 0x8000
|
||||
#define DRAWLIST_P0 0x9000
|
||||
#define DRAWLIST_P1 0x9800
|
||||
|
||||
|
||||
// A2-3D1 Commands. Commented out items are Apple ][ only.
|
||||
#define PNT 0x00 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Point
|
||||
#define SPNT 0x01 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Start Point
|
||||
#define CPNT 0x02 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Continue Point
|
||||
#define RAY 0x03 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Define 3D Ray
|
||||
#define CLPSW 0x04 // N - Define Clipper (0=off, 1=on)
|
||||
#define EYE 0x05 // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB, P, B, H - Define 3D Eye/Camera
|
||||
#define LIN2D 0x06 // X1, Y1, X2, Y2 - Draw 2D Line
|
||||
//#define DISP 0x07 // N - Display Select (50=set graphics, 51=set text, 52=clear mixed, 53=set mixed, 54=set page 1, 55=set page 2, 56=clear hi-res, 57=set hi-res)
|
||||
//#define ERAS 0x08 // N - Erase Screen (0=erase page 1, 1=erase page 2, 2=fill page 1, 3=fill page 2)
|
||||
//#define DRAW 0x09 // N - Select Draw Page (0=page 1, 1=page 2)
|
||||
#define PNT2D 0x0a // X1, Y1 - Draw 2D Point
|
||||
#define JMP 0x0b // LSB, MSB - Interpretive Jump
|
||||
//#define LMODE 0x0c // N - Line Drawing Mode (0=solid, 1=xor)
|
||||
#define ARRAY 0x0d // LSB, MSB - Enable Output Array
|
||||
#define SCRSZ 0x0e // WIDTH, HEIGHT, xCENTER, yCENTER - Define Screen Size
|
||||
#define FIELD 0x0f // xLSB, xMSB, yLSB, yMSB, zLSB, zMSB - Field of View Selection
|
||||
#define INIT 0x10 // Easy Init
|
||||
#define NOP 0x11 // No Operation
|
||||
|
||||
// A2-3D2 Commands. Commented out items are Apple ][ only.
|
||||
#define STCOL 0x12 // COL - Set Color
|
||||
#define ICALL 0x13 // STAT, LOC, ADDR - Independent Object Call
|
||||
#define SRES 0x14 // RES - Set Resolution (0=140x192, 1=280x192)
|
||||
//#define HLIN 0x15 // x1L, x1H, y1, x2L, x2H, y2 - Hi-Res (280x192) Line 2D
|
||||
//#define SHRB 0x16 // xL, xH, y - Set Hi-Res Bias
|
||||
//#define HLIN2 0x17 // x1, y1, x2, y2 - Hi-Res (x limited) Line 2D
|
||||
//#define HPNT 0x18 // xL, xH, y - Hi-Res (280x192) Point 2D
|
||||
//#define HPNT2 0x19 // x, y - Hi-Res (x limited) Point 2D
|
||||
#define SKIP 0x1a // SIZE, STATUS - Skip Segment
|
||||
//#define PAUS 0x1b // TIME - Pause for TIME/5ths of a Second
|
||||
#define SET323 0x1c // LSB, MSB - Set 3D to 3D Array Address
|
||||
#define GN323 0x1d // STATUS - Set 3D to 3D Status
|
||||
#define END 0x79 // End of Database
|
||||
|
||||
|
||||
typedef struct cameraS {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
byte p;
|
||||
byte b;
|
||||
byte h;
|
||||
} cameraT;
|
||||
|
||||
|
||||
extern cameraT *_camera;
|
||||
extern cameraT *_cameraInDatabase;
|
||||
|
||||
extern uint16_t _drawlist;
|
||||
extern uint16_t _drawlistInDatabase;
|
||||
|
||||
extern byte *_pointer;
|
||||
extern uint16_t _bytes;
|
||||
extern uint8_t _x1;
|
||||
extern uint8_t _y1;
|
||||
extern uint8_t _x2;
|
||||
extern uint8_t _y2;
|
||||
extern bool _useColor;
|
||||
extern byte _mmu;
|
||||
extern byte _ram;
|
||||
|
||||
|
||||
// NOTE:
|
||||
// There are no function prototypes in this header.
|
||||
// This library lives in it's own overlay segment and the overlay tool
|
||||
// will generate prototypes as well as trampoline macros for us.
|
230
examples/a23d2/src/main.c
Normal file
230
examples/a23d2/src/main.c
Normal file
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory Map:
|
||||
*
|
||||
* Far Heap (upper 448k):
|
||||
*
|
||||
* 0x7ffff - Top of far heap / End of bitmap page 1
|
||||
* - Bitmap page is 0x14000 (81920 bytes)
|
||||
* 0x6c000 - Start of bitmap page 1
|
||||
* 0x6bfff - End of bitmap page 2
|
||||
* - Bitmap page is 0x14000 (81920 bytes)
|
||||
* 0x58000 - Start of bitmap page 2
|
||||
* 0x57fff - End of A2-3D2 and data to be used in slots 3 and 2/4 below
|
||||
* - ...
|
||||
* 0x54000 - Start of A2-3D2 and data to be used in slots 3 and 2/4 below
|
||||
* - 57344 bytes free
|
||||
* 0x45fff - End of overlay code
|
||||
* - ...
|
||||
* 0x10000 - Bottom of far heap / Start of overlay code
|
||||
*
|
||||
*
|
||||
* Near Heap (lower 64k):
|
||||
*
|
||||
* 0xffff - Top of near heap
|
||||
* - ...
|
||||
* 0xe000 - Microkernel
|
||||
* - ...
|
||||
* 0xc000 - I/O and microkernel
|
||||
* - ...
|
||||
* 0xa000 - Overlay code
|
||||
* 0x9fff - Top of virtual stack
|
||||
* - ...
|
||||
* 0x8000 - Program code / 3D/2D data
|
||||
* - ...
|
||||
* 0x6000 - Program code / 3D library
|
||||
* - ...
|
||||
* 0x0300 - Start of program code
|
||||
* 0x02ff - End of program arguments / data storage
|
||||
* - ... (We're going to overwrite this!)
|
||||
* 0x0200 - Start of program arguments / data storage
|
||||
* 0x01ff - Top of CPU stack space
|
||||
* - ...
|
||||
* 0x0100 - Bottom of CPU stack space
|
||||
* 0x00ff - End of microkernel use
|
||||
* - ...
|
||||
* 0x00f0 - Start of microkernel use
|
||||
* - 46 bytes free
|
||||
* 0x00c2 - End of A2-3D2 use
|
||||
* - ...
|
||||
* 0x0060 - Start of A2-3D2 use
|
||||
* - 49 bytes free
|
||||
* 0x002f - llvm virtual register 31
|
||||
* - ...
|
||||
* 0x0010 - llvm virtual register 0
|
||||
* 0x000f - MMU_MEM_BANK_7
|
||||
* - ...
|
||||
* 0x0008 - MMU_MEM_BANK_0
|
||||
* - 7 bytes free
|
||||
* 0x0001 - MMU_IO_CTRL
|
||||
* 0x0000 - MMU_MEM_CTRL
|
||||
*
|
||||
*
|
||||
* Calling the 3D Renderer:
|
||||
*
|
||||
* The MMU splits the near heap into 8k "slots" that 8k "blocks" of far heap
|
||||
* can be mapped into. f256lib, by default, sets the near heap up as
|
||||
* follows:
|
||||
*
|
||||
* 0xe000 - Slot 7 - Microkernel
|
||||
* 0xc000 - Slot 6 - I/O and Microkernel
|
||||
* 0xa000 - Slot 5 - Code Overlay Region
|
||||
* 0x8000 - Slot 4 - Program Code
|
||||
* 0x6000 - Slot 3 - Program Code
|
||||
* 0x4000 - Slot 2 - Program Code
|
||||
* 0x2000 - Slot 1 - Program Code
|
||||
* 0x0000 - Slot 0 - Zero Page & Program Code
|
||||
*
|
||||
* Our 3D library, subLOGIC's A2-3D2, was designed to be run on an Apple ][.
|
||||
* The Apple ][ has two high-resolution video pages in the middle of the
|
||||
* memory map and A2-3D2 loads at 0x6000 immediately after the second video
|
||||
* page. This makes sense on the Apple. On the Foenix, it's in the way at
|
||||
* slot 3. The library also needs a 3D scene database and outputs an array
|
||||
* of 2D drawing instructions. Given the size of A2-3D2 this pushes our
|
||||
* memory usage up into slot 4. This leaves slots 0 to 2 for the simulator.
|
||||
* That's less than 24k. Not good.
|
||||
*
|
||||
* We're going to place the 3D library and related data in the far heap and
|
||||
* manually swap them in using the MMU when we need to render the scene. To
|
||||
* do this, we need to ensure we're not currently executing code from
|
||||
* somewhere in the slot 2 to 4 range. To accomplish this, all the functions
|
||||
* that deal with A2-3D2 are placed in an overlay. This ensures whatever
|
||||
* code calls into slots 2 to 4 has a program counter between 0xa000 and
|
||||
* 0xbfff - well out of the way of the 3D stuff.
|
||||
*
|
||||
* The last thing to worry about is data needed by both the simulator and
|
||||
* A2-3D2. This is basically only the camera position and rotation. These
|
||||
* 10 bytes will be stored directly into RAM from 0x200 to 0x20a overwriting
|
||||
* any command line arguments that may have been in memory.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define WITHOUT_FILE
|
||||
#define WITHOUT_SPRITE
|
||||
#define WITHOUT_TILE
|
||||
#define F256LIB_IMPLEMENTATION
|
||||
#include "f256lib.h"
|
||||
|
||||
#include "a23d2.h"
|
||||
|
||||
|
||||
/*
|
||||
* embedded.bin is loaded at 0x54000:
|
||||
*
|
||||
* 8k a2-3d2.bin @ 0x54000
|
||||
* 8k scene.3d @ 0x56000
|
||||
*
|
||||
*/
|
||||
EMBED(".binarydata.embedded", embedded, "embedded.bin");
|
||||
|
||||
|
||||
void runSimulation(void) {
|
||||
bool pageZero;
|
||||
|
||||
// Which page is visible?
|
||||
pageZero = true;
|
||||
|
||||
// Draw it!
|
||||
while (true) {
|
||||
|
||||
// Flip pages.
|
||||
if (pageZero) {
|
||||
// Looking at bitmap 0.
|
||||
pageZero = false;
|
||||
bitmapSetActive(1);
|
||||
bitmapSetVisible(0, true);
|
||||
bitmapSetVisible(1, false);
|
||||
_drawlist = DRAWLIST_P1;
|
||||
} else {
|
||||
// Looking at bitmap 1.
|
||||
pageZero = true;
|
||||
bitmapSetActive(0);
|
||||
bitmapSetVisible(1, true);
|
||||
bitmapSetVisible(0, false);
|
||||
_drawlist = DRAWLIST_P0;
|
||||
}
|
||||
|
||||
// Erase old scene.
|
||||
bitmapSetColor(0);
|
||||
_useColor = false;
|
||||
a23d2Draw();
|
||||
|
||||
// Draw new scene.
|
||||
a23d2Render();
|
||||
_useColor = true;
|
||||
a23d2Draw();
|
||||
|
||||
// Move camera.
|
||||
_camera->p += 1; // Change pitch angle.
|
||||
_camera->b += 2; // Change bank angle.
|
||||
_camera->h += 3; // Change heading angle.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
byte c;
|
||||
byte ega[16][3] = {
|
||||
{ 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0xaa },
|
||||
{ 0x00, 0xaa, 0x00 },
|
||||
{ 0x00, 0xaa, 0xaa },
|
||||
{ 0xaa, 0x00, 0x00 },
|
||||
{ 0xaa, 0x00, 0xaa },
|
||||
{ 0xaa, 0x55, 0x00 },
|
||||
{ 0xaa, 0xaa, 0xaa },
|
||||
{ 0x55, 0x55, 0x55 },
|
||||
{ 0x55, 0x55, 0xff },
|
||||
{ 0x55, 0xff, 0x55 },
|
||||
{ 0x55, 0xff, 0xff },
|
||||
{ 0xff, 0x55, 0x55 },
|
||||
{ 0xff, 0x55, 0xff },
|
||||
{ 0xff, 0xff, 0x55 },
|
||||
{ 0xff, 0xff, 0xff }
|
||||
};
|
||||
|
||||
// Load EGA palette into CLUT0.
|
||||
for (c=0; c<16; c++) graphicsDefineColor(0, c, ega[c][0], ega[c][1], ega[c][2]);
|
||||
|
||||
a23d2Init();
|
||||
|
||||
// Set up bitmap planes.
|
||||
for (c=0; c<2; c++) {
|
||||
// Clear screen.
|
||||
bitmapSetActive(c);
|
||||
bitmapSetColor(0);
|
||||
bitmapClear();
|
||||
// 3D Viewport edge.
|
||||
bitmapSetColor(14);
|
||||
bitmapLine(256, 0, 256, 239);
|
||||
}
|
||||
bitmapSetVisible(0, true);
|
||||
bitmapSetVisible(1, false);
|
||||
|
||||
runSimulation();
|
||||
|
||||
return 0;
|
||||
}
|
96
examples/a23d2/tools/scene.c
Normal file
96
examples/a23d2/tools/scene.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "a23d2.h"
|
||||
|
||||
|
||||
uint8_t db[8192] = { 0 };
|
||||
uint16_t bytes = 0;
|
||||
|
||||
|
||||
void cube(void) {
|
||||
int16_t i = 0;
|
||||
uint8_t scene[] = {
|
||||
STCOL, 0x04, // Red
|
||||
SPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x03, // Cube
|
||||
CPNT, 0x00, 0x01, 0x00, 0xff, 0x00, 0x03,
|
||||
CPNT, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
|
||||
CPNT, 0x00, 0xff, 0x00, 0x01, 0x00, 0x03,
|
||||
CPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x03,
|
||||
CPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x05,
|
||||
CPNT, 0x00, 0x01, 0x00, 0xff, 0x00, 0x05,
|
||||
RAY, 0x00, 0x01, 0x00, 0xff, 0x00, 0x03,
|
||||
CPNT, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
|
||||
RAY, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
|
||||
CPNT, 0x00, 0xff, 0x00, 0x01, 0x00, 0x05,
|
||||
RAY, 0x00, 0xff, 0x00, 0x01, 0x00, 0x03,
|
||||
CPNT, 0x00, 0xff, 0x00, 0xff, 0x00, 0x05,
|
||||
SPNT, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, // Edge Line
|
||||
CPNT, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03,
|
||||
END
|
||||
};
|
||||
|
||||
while (scene[i] != END) {
|
||||
db[bytes++] = scene[i++];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *out;
|
||||
|
||||
// All scene databases need to begin with the ARRAY and EYE records.
|
||||
// The CLPSW clipping setting is up to you. :-)
|
||||
|
||||
db[bytes++] = ARRAY; // Will be filled in by the program.
|
||||
db[bytes++] = 0;
|
||||
db[bytes++] = 0;
|
||||
|
||||
db[bytes++] = EYE; // Will be filled in by the program.
|
||||
db[bytes++] = 0x00; // X
|
||||
db[bytes++] = 0x00;
|
||||
db[bytes++] = 0x00; // Y
|
||||
db[bytes++] = 0x00;
|
||||
db[bytes++] = 0x00; // Z
|
||||
db[bytes++] = 0x00;
|
||||
db[bytes++] = 0x00; // P
|
||||
db[bytes++] = 0x00; // B
|
||||
db[bytes++] = 0x00; // H
|
||||
|
||||
db[bytes++] = CLPSW;
|
||||
db[bytes++] = 0x00;
|
||||
|
||||
cube();
|
||||
|
||||
db[bytes++] = END;
|
||||
|
||||
out = fopen("scene.3d", "wb");
|
||||
if (out) {
|
||||
fwrite(db, 1, 8192, out);
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
port=/dev/ttyUSB1
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
chunk_size=1024
|
||||
cpu=65c02
|
||||
data_rate=6000000
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
port=/dev/ttyUSB1
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
chunk_size=1024
|
||||
cpu=65c02
|
||||
data_rate=6000000
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
port=/dev/ttyUSB1
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
chunk_size=1024
|
||||
cpu=65c02
|
||||
data_rate=6000000
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
port=/dev/ttyUSB1
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
chunk_size=1024
|
||||
cpu=65c02
|
||||
data_rate=6000000
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
port=/dev/ttyUSB1
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
chunk_size=1024
|
||||
cpu=65c02
|
||||
data_rate=6000000
|
|
@ -25,6 +25,19 @@
|
|||
#include "../../f256lib.h"
|
||||
|
||||
|
||||
/*
|
||||
* Add return values to overlay tool.
|
||||
* Overlay tool may need to generate prototypes for multiple file programs.
|
||||
* Move bitmap memory to top of far ram.
|
||||
* Add cc65 support.
|
||||
* Move docs to top of amalgamated build.
|
||||
* Check out https://github.com/econtrerasd/VickyGraph/tree/main/Calypsi-65816-grfdemo/src
|
||||
* Find way to create Windows version binaries.
|
||||
* Docs!
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void dirtest(void) {
|
||||
|
||||
DIR *dir;
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
port=/dev/ttyUSB1
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
chunk_size=1024
|
||||
cpu=65c02
|
||||
data_rate=6000000
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
port=/dev/ttyUSB1
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
chunk_size=1024
|
||||
cpu=65c02
|
||||
data_rate=6000000
|
|
@ -58,7 +58,7 @@ void f256Init(void) {
|
|||
#ifndef WITHOUT_KERNEL
|
||||
kernelReset();
|
||||
#endif
|
||||
#if !(defined WITHOUT_BITMAP || defined WITHOUT_TILE || defined WITHOUT_SPRITE)
|
||||
#ifndef WITHOUT_GRAPHICS
|
||||
graphicsReset();
|
||||
#endif
|
||||
#ifndef WITHOUT_TEXT
|
||||
|
|
|
@ -125,31 +125,18 @@ typedef unsigned char bool;
|
|||
|
||||
// Near memory slot to use for far memory swapping.
|
||||
#ifndef SWAP_SLOT
|
||||
#define SWAP_SLOT MMU_MEM_BANK_5
|
||||
#define SWAP_SLOT MMU_MEM_BANK_7
|
||||
#endif
|
||||
|
||||
// This is an attempt to allow us to free up slot 5 and use other slots
|
||||
// for swapping RAM in and out. ***TODO*** Currently, it does not work.
|
||||
#if SWAP_SLOT == MMU_MEM_BANK_6
|
||||
#if SWAP_SLOT == MMU_MEM_BANK_7
|
||||
|
||||
#define SWAP_IO_SETUP() \
|
||||
byte sios_mmu = PEEK(MMU_IO_CTRL); \
|
||||
byte sios_ram = PEEK(MMU_MEM_BANK_6); \
|
||||
({ \
|
||||
asm("sei"); \
|
||||
POKE(MMU_IO_CTRL, 4); \
|
||||
})
|
||||
#define SWAP_IO_SETUP() \
|
||||
byte sios_ram = PEEK(MMU_MEM_BANK_7); \
|
||||
asm("sei");
|
||||
|
||||
#define SWAP_IO_SHUTDOWN() ({ \
|
||||
POKE(MMU_MEM_BANK_6, sios_ram); \
|
||||
POKE(MMU_IO_CTRL, sios_mmu); \
|
||||
asm("cli"); \
|
||||
})
|
||||
|
||||
#elif SWAP_SLOT == MMU_MEM_BANK_7
|
||||
|
||||
#define SWAP_IO_SETUP() asm("sei");
|
||||
#define SWAP_IO_SHUTDOWN() asm("cli");
|
||||
#define SWAP_IO_SHUTDOWN() \
|
||||
POKE(MMU_MEM_BANK_7, sios_ram); \
|
||||
asm("cli");
|
||||
|
||||
#else
|
||||
|
||||
|
@ -168,7 +155,7 @@ typedef unsigned char bool;
|
|||
|
||||
|
||||
// Things not in the Merlin defs.
|
||||
#define EIGHTK 0x2000
|
||||
#define EIGHTK 0x2000
|
||||
|
||||
#define TEXT_MATRIX 0xc000 // I/O Page 2
|
||||
|
||||
|
@ -202,6 +189,25 @@ typedef struct colorS {
|
|||
} colorT;
|
||||
|
||||
|
||||
// Allow embedding binary data into program
|
||||
#define IBSTR2(x) #x
|
||||
#define IBSTR(x) IBSTR2(x)
|
||||
#define EMBED(INCBIN_SECTION, name, file) \
|
||||
__asm__(".section " INCBIN_SECTION ",\"aR\" \n" \
|
||||
".global incbin_" IBSTR(name) "_start\n" \
|
||||
".balign 16\n" \
|
||||
"incbin_" IBSTR(name) "_start:\n" \
|
||||
".incbin \"" file "\"\n" \
|
||||
\
|
||||
".global incbin_" IBSTR(name) "_end\n" \
|
||||
".balign 1\n" \
|
||||
"incbin_" IBSTR(name) "_end:\n" \
|
||||
".byte 0\n" \
|
||||
); \
|
||||
extern __attribute__((aligned(16))) const char incbin_ ## name ## _start[]; \
|
||||
extern const char incbin_ ## name ## _end[]
|
||||
|
||||
|
||||
// Single-byte
|
||||
#define PEEK(addy) ((byte)*(volatile byte *)(addy))
|
||||
#define POKE(addy, value) (*(volatile byte *)(addy) = (value))
|
||||
|
@ -219,8 +225,8 @@ typedef struct colorS {
|
|||
#define POKED(addy,value) (*(volatile uint32_t *)(addy) = (value))
|
||||
|
||||
// Bit fun.
|
||||
#define LOW_BYTE(v) ((byte)(x))
|
||||
#define HIGH_BYTE(v) ((byte)(((uint16_t)(x)) >> 8))
|
||||
#define LOW_BYTE(x) ((byte)(x))
|
||||
#define HIGH_BYTE(x) ((byte)(((uint16_t)(x)) >> 8))
|
||||
#define SWAP_NIBBLES(x) ((x & 0x0F) << 4 | (x & 0xF0) >> 4)
|
||||
#define SWAP_UINT16(x) (((x) >> 8) | ((x) << 8))
|
||||
#define CHECK_BIT(x, pos) (x & (1UL << pos))
|
||||
|
|
|
@ -36,10 +36,17 @@ static uint32_t _PAGE_SIZE;
|
|||
static uint32_t _BITMAP_BASE[3]; // Maximum of 3 pages possible.
|
||||
static byte _BITMAP_CLUT[3];
|
||||
static byte _color;
|
||||
static byte _active; // Current drawing page.
|
||||
static byte _active; // Current drawing page.
|
||||
|
||||
// uint32_t address = _BITMAP_BASE[_active] + (y * _MAX_X + (int32_t)x); \
|
||||
|
||||
#define bitmapPutPixelIOSet(x, y) FAR_POKE((_BITMAP_BASE[_active] + mathUnsignedAddition(mathUnsignedMultiply(y, _MAX_X), (int32_t)x)), _color)
|
||||
#define bitmapPutPixelIOSet(x, y) ({ \
|
||||
uint32_t address = _BITMAP_BASE[_active] + mathUnsignedAddition(mathUnsignedMultiply(y, _MAX_X), (int32_t)x); \
|
||||
byte block = address / EIGHTK; \
|
||||
address &= 0x1FFF; \
|
||||
POKE(SWAP_SLOT, block); \
|
||||
POKE(SWAP_ADDR + address, _color); \
|
||||
})
|
||||
|
||||
|
||||
void bitmapClear(void) {
|
||||
|
@ -64,7 +71,6 @@ void bitmapClear(void) {
|
|||
for (c=0; c<5120; c++) mem[c] = _color;
|
||||
|
||||
SWAP_RESTORE_SLOT();
|
||||
|
||||
SWAP_IO_SHUTDOWN();
|
||||
#endif
|
||||
}
|
||||
|
@ -137,7 +143,6 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
|
|||
}
|
||||
|
||||
SWAP_RESTORE_SLOT();
|
||||
|
||||
SWAP_IO_SHUTDOWN();
|
||||
}
|
||||
|
||||
|
@ -166,11 +171,12 @@ void bitmapReset(void) {
|
|||
// Fractional pageBlock. Round up.
|
||||
pageBlocks++;
|
||||
}
|
||||
realSize = mathUnsignedMultiply(pageBlocks, EIGHTK);
|
||||
realSize = mathUnsignedMultiply(pageBlocks, EIGHTK); // Works out to 80k or 0x14000.
|
||||
|
||||
_BITMAP_BASE[0] = 0x10000;
|
||||
_BITMAP_BASE[1] = mathUnsignedAddition(_BITMAP_BASE[0], realSize); // Page 2 = 0x24000
|
||||
_BITMAP_BASE[2] = mathUnsignedAddition(_BITMAP_BASE[1], realSize); // Page 3 = 0x38000
|
||||
// Bitmaps start at the top of far memory and work downwards for each additional page.
|
||||
_BITMAP_BASE[0] = 0x080000 - realSize; // Page 1 = 0x6c000
|
||||
_BITMAP_BASE[1] = _BITMAP_BASE[0] - realSize; // Page 2 = 0x58000
|
||||
_BITMAP_BASE[2] = _BITMAP_BASE[1] - realSize; // Page 3 = 0x44000
|
||||
|
||||
/*
|
||||
textPrint("\nbase0 = "); textPrintInt(_BITMAP_BASE[0]);
|
||||
|
|
|
@ -33,27 +33,39 @@ static void dmaWait(void);
|
|||
|
||||
|
||||
void dmaFill(uint32_t start, uint32_t length, byte value) {
|
||||
while (PEEKW(RAST_ROW_L) != 482); // Wait for VBL.
|
||||
|
||||
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, PEEK(DMA_CTRL) | DMA_CTRL_START);
|
||||
|
||||
dmaWait();
|
||||
// dmaWait();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dma2dFill(uint32_t start, uint16_t width, uint16_t height, uint16_t stride, byte value) {
|
||||
POKE(DMA_CTRL, DMA_CTRL_2D | DMA_CTRL_ENABLE);
|
||||
while (PEEKW(RAST_ROW_L) != 482); // Wait for VBL.
|
||||
|
||||
asm("sei");
|
||||
POKE(DMA_CTRL, DMA_CTRL_2D | DMA_CTRL_FILL | DMA_CTRL_ENABLE);
|
||||
POKE(DMA_FILL_VAL, value);
|
||||
POKEA(DMA_DST_ADDR, start);
|
||||
POKEW(DMA_WIDTH, width);
|
||||
POKEW(DMA_HEIGHT, height);
|
||||
POKEW(DMA_STRIDE_DST, stride);
|
||||
POKE(DMA_CTRL, PEEK(DMA_CTRL) | DMA_CTRL_START);
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("cli");
|
||||
|
||||
dmaWait();
|
||||
// dmaWait();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#endif
|
||||
|
||||
|
||||
//***FIX*** IIgs colors aren't as useful as EGA colors.
|
||||
colorT textColors[16] = {
|
||||
{ 0x00, 0x00, 0x00 }, // 0 Black
|
||||
{ 0xdd, 0x00, 0x33 }, // 1 Deep Red
|
||||
|
|
|
@ -47,6 +47,8 @@ void trimEnd(char *string);
|
|||
void findBank(char *name) {
|
||||
int x;
|
||||
|
||||
printf("Found Segment: %s\n", name);
|
||||
|
||||
// Is this the MAIN segment?
|
||||
if (strcmp(name, "MAIN") == 0) {
|
||||
_currentBank = 0;
|
||||
|
@ -83,6 +85,7 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo
|
|||
char *b;
|
||||
bool found;
|
||||
int x;
|
||||
int line = 1;
|
||||
int comments = 0;
|
||||
bool inComment = false;
|
||||
int brackets = 0;
|
||||
|
@ -102,6 +105,9 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo
|
|||
* Someone should fix it. :-)
|
||||
*/
|
||||
|
||||
// Always start in the lower 64k.
|
||||
_currentBank = 0;
|
||||
|
||||
in = fopen(filename, "rt");
|
||||
if (in == NULL) {
|
||||
fclose(trampoline);
|
||||
|
@ -132,10 +138,10 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo
|
|||
if ((c == '/') && (pos > 0) && (buffer[pos-1] == '/')) inComment = true;
|
||||
|
||||
// Look for '/*' comment start.
|
||||
if ((c == '*') && (pos > 0) && (buffer[pos-1] == '/')) comments++;
|
||||
if ((c == '*') && (pos > 0) && (buffer[pos-1] == '/') && !inComment) comments++;
|
||||
|
||||
// Look for '*/' comment end.
|
||||
if ((c == '/') && (pos > 0) && (buffer[pos-1] == '*')) comments--;
|
||||
if ((c == '/') && (pos > 0) && (buffer[pos-1] == '*') && !inComment) comments--;
|
||||
}
|
||||
|
||||
// Count brackets so we know if we're inside a function or not.
|
||||
|
@ -150,6 +156,8 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo
|
|||
// End of line?
|
||||
if ((c == 13) || (c == 10)) {
|
||||
|
||||
line++;
|
||||
|
||||
inComment = false;
|
||||
crSinceStart++;
|
||||
|
||||
|
@ -191,6 +199,8 @@ void parseCFile(char *filename, char *targetFile, FILE *trampoline, char *trampo
|
|||
*b = '(';
|
||||
// Write out new function definition.
|
||||
fprintf(out, "%s%cFAR%d_%s {\n", buffer, found ? '*' : ' ', _currentBank, start);
|
||||
// Create trampoline prototype.
|
||||
fprintf(trampoline, "%s%cFAR%d_%s;\n", buffer, found ? '*' : ' ', _currentBank, start);
|
||||
// Create trampoline macro.
|
||||
fprintf(trampoline, "#define %s(...) ({ \\\n"
|
||||
"\t\tunsigned char ___mmu = (unsigned char)*(volatile unsigned char *)%#06x; \\\n"
|
||||
|
|
Loading…
Add table
Reference in a new issue