251 lines
7.3 KiB
C
251 lines
7.3 KiB
C
/*
|
|
* 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
|
|
|
|
|
|
volatile cameraT *_camera = (cameraT *)CAMERA_SHARED_START; // Simulation copy of camera.
|
|
volatile cameraT *_cameraInDatabase;
|
|
volatile byte *_pointer;
|
|
|
|
uint16_t _drawlist;
|
|
uint16_t _drawlistInDatabase;
|
|
|
|
uint16_t _bytes;
|
|
uint8_t _x1;
|
|
uint8_t _y1;
|
|
uint8_t _x2;
|
|
uint8_t _y2;
|
|
bool _useColor;
|
|
byte _mmu;
|
|
byte _ram;
|
|
//float _trig;
|
|
|
|
|
|
#define SEGMENT_A23D2
|
|
|
|
|
|
// There's a lot of global use in here. We can't use the virtual stack.
|
|
|
|
|
|
#if 0
|
|
void a23d2Cos(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);
|
|
|
|
// Map 0-359 into 0-255.
|
|
_tdata = _tdata % 359;
|
|
_y1 = (360/256) * _tdata;
|
|
|
|
// Call COSEX.
|
|
POKE(A23D2_TDATA, _y1);
|
|
__attribute__((leaf)) asm volatile("jsr %[addy]":: [addy] "i"(A23D2_COSEX));
|
|
|
|
// Convert to float.
|
|
_trig = (float)PEEKW(A23D2_TDATA) / 32768;
|
|
|
|
// Restore memory map.
|
|
POKE(MMU_MEM_BANK_3, 3);
|
|
}
|
|
#endif
|
|
|
|
|
|
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 with our setup database.
|
|
// Usually we'd swap in bank 4, but we'd have to save that, too. Back it up.
|
|
scdMemCpy((byte *)(SCRATCH_END - 0x06), (byte *)A23D2_TEST_DATABASE, 0x06);
|
|
|
|
// Initialize A2-3D2 so we can use the "fast entry point" (NXTPT) when rendering.
|
|
_bytes = 0;
|
|
_pointer = (byte *)A23D2_TEST_DATABASE; // 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!
|
|
|
|
// Save ZP that A2-3D2 is going to clobber.
|
|
scdMemCpy((byte *)COMPILER_ZP_SAVE, (byte *)COMPILER_ZP_START, COMPILER_ZP_LENGTH);
|
|
|
|
// Call ENTRYN. This sets up A2-3D2.
|
|
__attribute__((leaf)) asm volatile("jsr %[addy]":: [addy] "i"(A23D2_ENTRYN));
|
|
|
|
// Save A2-3D2s ZP for later.
|
|
scdMemCpy((byte *)A23D2_ZP_SAVE, (byte *)A23D2_ZP_START, A23D2_ZP_LENGTH);
|
|
|
|
// Restore ZP that A2-3D2 clobbered.
|
|
scdMemCpy((byte *)COMPILER_ZP_START, (byte *)COMPILER_ZP_SAVE, COMPILER_ZP_LENGTH);
|
|
|
|
// Put back the RAM we clobbered.
|
|
scdMemCpy((byte *)A23D2_TEST_DATABASE, (byte *)(SCRATCH_END - 0x06), 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;
|
|
|
|
// Save ZP that A2-3D2 is going to clobber.
|
|
scdMemCpy((byte *)COMPILER_ZP_SAVE, (byte *)COMPILER_ZP_START, COMPILER_ZP_LENGTH);
|
|
|
|
// Restore A2-3D2s ZP.
|
|
scdMemCpy((byte *)A23D2_ZP_START, (byte *)A23D2_ZP_SAVE, A23D2_ZP_LENGTH);
|
|
|
|
// Set IBP.
|
|
POKEW(A23D2_IBP, DATABASE);
|
|
|
|
// Call NXTPT.
|
|
__attribute__((leaf)) asm volatile("jsr %[addy]":: [addy] "i"(A23D2_NXTPT) : "a","x","y","c","v"); // Call NXTPT.
|
|
|
|
// Save A2-3D2s ZP for later.
|
|
scdMemCpy((byte *)A23D2_ZP_SAVE, (byte *)A23D2_ZP_START, A23D2_ZP_LENGTH);
|
|
|
|
// Restore ZP that A2-3D2 clobbered.
|
|
scdMemCpy((byte *)COMPILER_ZP_START, (byte *)COMPILER_ZP_SAVE, COMPILER_ZP_LENGTH);
|
|
|
|
// Restore memory map.
|
|
POKE(MMU_MEM_BANK_4, 4);
|
|
POKE(MMU_MEM_BANK_3, 3);
|
|
}
|
|
|
|
|
|
#if 0
|
|
void a23d2Sin(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);
|
|
|
|
// Map 0-359 into 0-255.
|
|
_tdata = _tdata % 359;
|
|
_y1 = (360/256) * _tdata;
|
|
|
|
// Call SINEX.
|
|
POKE(A23D2_TDATA, _y1);
|
|
__attribute__((leaf)) asm volatile("jsr %[addy]":: [addy] "i"(A23D2_SINEX));
|
|
|
|
// Convert to float.
|
|
_trig = (float)PEEKW(A23D2_TDATA) / 32768;
|
|
|
|
// Restore memory map.
|
|
POKE(MMU_MEM_BANK_3, 3);
|
|
}
|
|
#endif
|