cpc: cpctelera, start @ 0x4000, new vsync
This commit is contained in:
parent
68320b8ee9
commit
c3403a0506
|
@ -60,6 +60,7 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg?
|
||||||
* https://github.com/DrGoldfire/Z80.js
|
* https://github.com/DrGoldfire/Z80.js
|
||||||
* http://www.twitchasylum.com/jsvecx/
|
* http://www.twitchasylum.com/jsvecx/
|
||||||
* https://github.com/curiousdannii/ifvms.js/
|
* https://github.com/curiousdannii/ifvms.js/
|
||||||
|
* https://6502ts.github.io/typedoc/stellerator-embedded/
|
||||||
|
|
||||||
### Compilers
|
### Compilers
|
||||||
|
|
||||||
|
@ -87,6 +88,7 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg?
|
||||||
* https://shiru.untergrund.net/code.shtml
|
* https://shiru.untergrund.net/code.shtml
|
||||||
* http://www.colecovision.eu/ColecoVision/development/libcv.shtml
|
* http://www.colecovision.eu/ColecoVision/development/libcv.shtml
|
||||||
* https://github.com/toyoshim/tss
|
* https://github.com/toyoshim/tss
|
||||||
|
* https://github.com/lronaldo/cpctelera
|
||||||
|
|
||||||
### Firmware
|
### Firmware
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<li><a class="dropdown-item" href="?platform=apple2">Apple ][+</a></li>
|
<li><a class="dropdown-item" href="?platform=apple2">Apple ][+</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=zx">ZX Spectrum</a></li>
|
<li><a class="dropdown-item" href="?platform=zx">ZX Spectrum</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
|
<li><a class="dropdown-item" href="?platform=x86">x86 (FreeDOS)</a></li>
|
||||||
|
<li><a class="dropdown-item" href="?platform=cpc.6128">Amstrad CPC6128</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown dropdown-submenu">
|
<li class="dropdown dropdown-submenu">
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
//-----------------------------LICENSE NOTICE------------------------------------
|
||||||
|
// This file is part of CPCtelera: An Amstrad CPC Game Engine
|
||||||
|
// Copyright (C) 2015 ronaldo / Fremos / Cheesetea / ByteRealms (@FranGallegoBR)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cpctelera.h"
|
||||||
|
|
||||||
|
// Constant to set the number of VSYNCs to wait for as a delay between
|
||||||
|
// each pair of strings drawn. This will let as see how they are
|
||||||
|
// drawn, making it a little bit slower.
|
||||||
|
// - WFRAMES = 3 (Work at 12.5 FPS (50/3))
|
||||||
|
#define WFRAMES 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wait n complete screen frames of (1/50)s
|
||||||
|
//
|
||||||
|
void wait_frames(u16 nframes) {
|
||||||
|
u16 i, j; // frame counter and active wait loop counter
|
||||||
|
|
||||||
|
// Loop for nframe times, waiting for VSYNC
|
||||||
|
for (i=0; i < nframes; i++) {
|
||||||
|
cpct_waitVSYNC();
|
||||||
|
|
||||||
|
// VSYNC is usually active for ~1500 cycles, then we have to do
|
||||||
|
// something that takes approximately this amount of time before
|
||||||
|
// waiting for the next VSYNC, or we will find the same VSYNC signal
|
||||||
|
// This active wait loop will do at least 750 comparisons, what
|
||||||
|
// is the same as 750*4 cycles (at least)
|
||||||
|
for (j=0; j < 750; j++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Strings Example: Main program
|
||||||
|
//
|
||||||
|
void main(void) {
|
||||||
|
u8 *pvideomem; // Pointer to the video memory location where strings will be drawn
|
||||||
|
u8 times; // Counter of number of times to draw
|
||||||
|
u8 colours[5] = {0}; // 5 Colour values, 1 for mode 2, 2 for mode 1 and 2 more for mode 0
|
||||||
|
|
||||||
|
// First, disable firmware to prevent it from restoring video modes and
|
||||||
|
// interfering with drawString functions
|
||||||
|
cpct_disableFirmware();
|
||||||
|
|
||||||
|
// Loop forever showing characters on different modes and colours
|
||||||
|
//
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Show some strings in Mode 0, using different colours
|
||||||
|
//
|
||||||
|
|
||||||
|
// Clear Screen filling it up with 0's and set mode 0
|
||||||
|
cpct_disableFirmware();
|
||||||
|
cpct_disableUpperROM();
|
||||||
|
cpct_clearScreen(0);
|
||||||
|
cpct_setVideoMode(0);
|
||||||
|
|
||||||
|
// Let's start drawing strings at the start of video memory (0xC000)
|
||||||
|
pvideomem = CPCT_VMEM_START;
|
||||||
|
|
||||||
|
// Draw 25 strings, 1 for each character line on the screen
|
||||||
|
for (times=0; times < 25; times++) {
|
||||||
|
// Pick up the next foreground colour available for next string
|
||||||
|
// rotating colours when the 16 available have been used
|
||||||
|
// We use module 16 (AND 0x0F) for faster calculations
|
||||||
|
colours[0] = ++colours[0] & 15;
|
||||||
|
|
||||||
|
// Draw the string and wait for some VSYNCs
|
||||||
|
cpct_drawStringM0("$ Mode 0 string $", pvideomem, colours[0], colours[3]);
|
||||||
|
wait_frames(WFRAMES);
|
||||||
|
|
||||||
|
// Point to the start of the next character line on screen (80 bytes away)
|
||||||
|
pvideomem += 0x50;
|
||||||
|
}
|
||||||
|
// Rotate background colour for next time we draw Mode 0 strings
|
||||||
|
colours[3] = ++colours[3] & 15;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Show some strings in Mode 1, using different colours
|
||||||
|
//
|
||||||
|
|
||||||
|
// Clear Screen filling it up with 0's and set mode 1
|
||||||
|
cpct_clearScreen(0);
|
||||||
|
cpct_setVideoMode(1);
|
||||||
|
|
||||||
|
// Let's start drawing strings at the start of video memory (0xC000)
|
||||||
|
pvideomem = CPCT_VMEM_START;
|
||||||
|
|
||||||
|
// Draw 25 strings, 1 for each character line on the screen
|
||||||
|
for (times=0; times < 25; times++) {
|
||||||
|
|
||||||
|
// Rotate foreground colour using module 4 (AND 0x03)
|
||||||
|
colours[1] = ++colours[1] & 3;
|
||||||
|
|
||||||
|
// Draw a string using normal drawString function for mode 1
|
||||||
|
cpct_drawStringM1("Mode 1 string :D", pvideomem, colours[1], colours[4]);
|
||||||
|
|
||||||
|
// Rotate foreground colour again
|
||||||
|
colours[1] = ++colours[1] & 3;
|
||||||
|
|
||||||
|
// Draw a string using fast drawString function for mode 1 (in a column 38 bytes to the right)
|
||||||
|
cpct_drawStringM1_f("Mode 1 string (Fast)", pvideomem + 38, colours[1], colours[4]);
|
||||||
|
|
||||||
|
// Rotate foreground colour another time and wait for a few VSYNCs
|
||||||
|
colours[1] = ++colours[1] & 3;
|
||||||
|
wait_frames(WFRAMES);
|
||||||
|
|
||||||
|
// Point to the start of the next character line on screen (80 bytes away)
|
||||||
|
pvideomem += 0x50;
|
||||||
|
}
|
||||||
|
colours[4] = ++colours[4] & 3;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Show some strings in Mode 2, using different colours
|
||||||
|
//
|
||||||
|
|
||||||
|
// Clear Screen filling it up with 0's and set mode 2
|
||||||
|
cpct_clearScreen(0);
|
||||||
|
cpct_setVideoMode(2);
|
||||||
|
|
||||||
|
// Let's start drawing strings at the start of video memory (0xC000)
|
||||||
|
pvideomem = CPCT_VMEM_START;
|
||||||
|
|
||||||
|
// Draw 25 strings, 1 for each character line on the screen
|
||||||
|
for (times=0; times < 25; times++) {
|
||||||
|
// Alternate between foreground colour or inverse colour (the only 2
|
||||||
|
// available on mode 2) using an XOR 1 operation that alternates the
|
||||||
|
// value between 0 and 1
|
||||||
|
colours[2] ^= 1;
|
||||||
|
|
||||||
|
// Draw string on the screen using current colour and wait for a few VSYNCs
|
||||||
|
cpct_drawStringM2("And, finally, this is a long mode 2 string!!", pvideomem, colours[2]);
|
||||||
|
wait_frames(WFRAMES);
|
||||||
|
|
||||||
|
// Point to the start of the next character line on screen (80 bytes away)
|
||||||
|
pvideomem += 0x50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
//-----------------------------LICENSE NOTICE------------------------------------
|
||||||
|
// This file is part of CPCtelera: An Amstrad CPC Game Engine
|
||||||
|
// Copyright (C) 2016 ronaldo / Fremos / Cheesetea / ByteRealms (@FranGallegoBR)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cpctelera.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Total random numbers to show (up to 255)
|
||||||
|
#define N_RND_NUMBERS 50
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// wait4UserKeypress
|
||||||
|
// Waits till the user presses a key, counting the number of
|
||||||
|
// loop iterations passed.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// <u32> Number of iterations passed
|
||||||
|
//
|
||||||
|
u32 wait4UserKeypress() {
|
||||||
|
u32 c = 0; // Count the number of cycles passed till user k
|
||||||
|
|
||||||
|
// Wait 'till the user presses a key, counting loop iterations
|
||||||
|
do {
|
||||||
|
c++; // One more cycle
|
||||||
|
cpct_scanKeyboard_f(); // Scan the scan the keyboard
|
||||||
|
} while ( ! cpct_isAnyKeyPressed_f() );
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// initialize
|
||||||
|
// Shows introductory messages and initializes the pseudo-random
|
||||||
|
// number generator
|
||||||
|
//
|
||||||
|
void initialize() {
|
||||||
|
u32 seed; // Value to initialize the random seed
|
||||||
|
|
||||||
|
// Introductory message
|
||||||
|
printf("\017\003========= BASIC RANDOM NUMBERS =========\n\n\r");
|
||||||
|
printf("\017\002Press any key to generate random numbers\n\n\r");
|
||||||
|
|
||||||
|
// Wait till the users presses a key and use the number of
|
||||||
|
// passed cycles as random seed for the Random Number Generator
|
||||||
|
seed = wait4UserKeypress();
|
||||||
|
|
||||||
|
// Random seed may never be 0, so check first and add 1 if it was 0
|
||||||
|
if (!seed)
|
||||||
|
seed++;
|
||||||
|
|
||||||
|
// Print the seed and seed the random number generator
|
||||||
|
printf("\017\003Selected seed: \017\002%d\n\r", seed);
|
||||||
|
cpct_srand8(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// printRandomNumbers
|
||||||
|
// Prints some random numbers in the screen, as requested.
|
||||||
|
// INPUT:
|
||||||
|
// nNumbers - Total amount of pseudo-random numbers to print
|
||||||
|
//
|
||||||
|
void printRandomNumbers(u8 nNumbers) {
|
||||||
|
// Anounce numbers
|
||||||
|
printf("\017\003Generating \017\002%d\017\003 random numbers\n\n\r\017\001", N_RND_NUMBERS);
|
||||||
|
|
||||||
|
// Count from nNumbers to 0, printing random numbers
|
||||||
|
while (nNumbers--) {
|
||||||
|
u8 random_number = cpct_rand(); // Get next random number
|
||||||
|
printf("%d ", random_number); // Print it
|
||||||
|
}
|
||||||
|
|
||||||
|
// End printing with newlines
|
||||||
|
printf("\n\n\r");
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// MAIN ENTRY POINT OF THE APPLICATION
|
||||||
|
//
|
||||||
|
void main(void) {
|
||||||
|
// Loop forever
|
||||||
|
while (1) {
|
||||||
|
// Initialize everything and print some random numbers
|
||||||
|
initialize();
|
||||||
|
printRandomNumbers(N_RND_NUMBERS);
|
||||||
|
|
||||||
|
// Wait 'till the user stops pressing a key
|
||||||
|
do { cpct_scanKeyboard_f(); } while ( cpct_isAnyKeyPressed_f() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
//-----------------------------LICENSE NOTICE------------------------------------
|
||||||
|
// This file is part of CPCtelera: An Amstrad CPC Game Engine
|
||||||
|
// Copyright (C) 2014-2015 ronaldo / Fremos / Cheesetea / ByteRealms (@FranGallegoBR)
|
||||||
|
// Copyright (C) 2015 Maximo / Cheesetea / ByteRealms (@rgallego87)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cpctelera.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Declare sprites and palette, without defining them
|
||||||
|
|
||||||
|
// Palette for Cheesetea's Sprite Logo
|
||||||
|
extern const u8 G_palette[4];
|
||||||
|
|
||||||
|
// Cheesetea's Sprite Logo, by Maximo (@rgallego87)
|
||||||
|
extern const u8 G_spriteLogoCT[744];
|
||||||
|
|
||||||
|
// Sprite size (in bytes)
|
||||||
|
#define SP_W 12
|
||||||
|
#define SP_H 62
|
||||||
|
|
||||||
|
// Screen size (in bytes)
|
||||||
|
#define SCR_W 80
|
||||||
|
#define SCR_H 200
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAIN: Using keyboard to move a sprite example
|
||||||
|
//
|
||||||
|
void main(void) {
|
||||||
|
u8 x=10, y=10; // Sprite coordinates
|
||||||
|
u8* pvideomem; // Pointer to video memory
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up the screen
|
||||||
|
//
|
||||||
|
// Disable firmware to prevent it from interfering with setPalette and setVideoMode
|
||||||
|
cpct_disableFirmware();
|
||||||
|
|
||||||
|
// Set the colour palette
|
||||||
|
cpct_fw2hw (G_palette, 4); // Convert our palette from firmware to hardware colours
|
||||||
|
cpct_setPalette(G_palette, 4); // Set up the hardware palette using hardware colours
|
||||||
|
|
||||||
|
// Set video mode 1 (320x200, 4 colours)
|
||||||
|
cpct_setVideoMode(1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Infinite moving loop
|
||||||
|
//
|
||||||
|
while(1) {
|
||||||
|
// Scan Keyboard (fastest routine)
|
||||||
|
// The Keyboard has to be scanned to obtain pressed / not pressed status of
|
||||||
|
// every key before checking each individual key's status.
|
||||||
|
cpct_scanKeyboard_f();
|
||||||
|
|
||||||
|
// Check if user has pressed a Cursor Key and, if so, move the sprite if
|
||||||
|
// it will still be inside screen boundaries
|
||||||
|
if (cpct_isKeyPressed(Key_CursorRight) && x < (SCR_W - SP_W) ) ++x;
|
||||||
|
else if (cpct_isKeyPressed(Key_CursorLeft) && x > 0 ) --x;
|
||||||
|
if (cpct_isKeyPressed(Key_CursorUp) && y > 0 ) --y;
|
||||||
|
else if (cpct_isKeyPressed(Key_CursorDown) && y < (SCR_H - SP_H) ) ++y;
|
||||||
|
|
||||||
|
// Get video memory byte for coordinates x, y of the sprite (in bytes)
|
||||||
|
pvideomem = cpct_getScreenPtr(CPCT_VMEM_START, x, y);
|
||||||
|
|
||||||
|
// Draw the sprite in the video memory location got from coordinates x, y
|
||||||
|
cpct_drawSprite(G_spriteLogoCT, pvideomem, SP_W, SP_H);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions of the sprites and palette
|
||||||
|
//
|
||||||
|
|
||||||
|
// Palete for mode 1 (4 firmware colours)
|
||||||
|
const u8 G_palette[4] = { 0x00, 0x18, 0x1A, 0x0D };
|
||||||
|
|
||||||
|
// Sprite definition of the Cheesetea Logo, by Maximo (@rgallego87).
|
||||||
|
const u8 G_spriteLogoCT[744] = {
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x11,0x9F,0x88,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x23,0x0F,0x4C,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x47,0x0F,0x2E,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x47,0x0F,0x2E,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x03,0x4F,0x0F,0x3F,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x37,0xCF,0x0F,0x2F,0x88,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x7F,0xCF,0x0F,0x2F,0x4C,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x7F,0xCF,0x0F,0x4F,0x4C,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x7F,0x0F,0x1F,0xCF,0x4C,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x01,0x6F,0x0F,0x1F,0xEF,0x2E,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x13,0xEF,0x0F,0x1F,0xEF,0x1F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x13,0xEF,0x0F,0x1F,0xEF,0x1F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x13,0xEF,0x0F,0x1F,0xEF,0x1F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x13,0xEF,0x0F,0x0F,0x6F,0x1F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x01,0xFF,0x0F,0x0F,0x2F,0x3F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x7F,0xCF,0x0F,0x2F,0x4C,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x33,0x7F,0xCF,0x0F,0x2F,0x4F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x23,0x7F,0xCF,0x0F,0x2F,0x6F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x23,0x7F,0xCF,0x0F,0x3F,0x6F,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x47,0x1F,0xEF,0x0F,0x0F,0xFF,0x08,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x8F,0x1F,0xEF,0x0F,0x0F,0xFF,0x8C,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0xBC,0xF0,0xF0,0xF0,0xF0,0xF0,0x8C,0x00,0x00,
|
||||||
|
0x00,0x00,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,
|
||||||
|
0x00,0x10,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,
|
||||||
|
0x00,0x10,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,
|
||||||
|
0x00,0x10,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,0x00,0x00,
|
||||||
|
0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,
|
||||||
|
0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,
|
||||||
|
0x00,0x10,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xC0,0x00,
|
||||||
|
0x00,0x10,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,
|
||||||
|
0x00,0x10,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xE0,0x00,
|
||||||
|
0x00,0x00,0x70,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0x80,0x00,
|
||||||
|
0x00,0x00,0x00,0x30,0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||||
|
};
|
|
@ -0,0 +1,80 @@
|
||||||
|
//-----------------------------LICENSE NOTICE------------------------------------
|
||||||
|
// This file is part of CPCtelera: An Amstrad CPC Game Engine
|
||||||
|
// Copyright (C) 2015 ronaldo / Fremos / Cheesetea / ByteRealms (@FranGallegoBR)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cpctelera.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAIN PROGRAM:
|
||||||
|
// Do not disable firmware in this example, as printf makes use of it through putchar
|
||||||
|
//
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
// Needed for screen clear to work
|
||||||
|
cpct_disableFirmware ();
|
||||||
|
cpct_disableUpperROM ();
|
||||||
|
|
||||||
|
// Clear Screen filling it up with 0's
|
||||||
|
cpct_clearScreen(0);
|
||||||
|
|
||||||
|
// Print out some messages using printf and sizeof to know the sizes in bytes
|
||||||
|
// ...of all the builting types in SDCC (using CPCtelera's aliases)
|
||||||
|
// We use Firmware Screen Character Commands to change colour on screen.
|
||||||
|
// Printing \0XX is equivalent to printing the character XX (in octal).
|
||||||
|
// Character 15 (017 in octal) does the PEN command, and uses immediate next
|
||||||
|
// character as the parameter for PEN. Then, \017\003 is equivalent to PEN 3.
|
||||||
|
//
|
||||||
|
printf(" \017\003Welcome to \017\002CPCtelera\017\003!\017\001\n\r\n\r");
|
||||||
|
printf("This example makes use of standard C");
|
||||||
|
printf("libraries to print out byte sizes of");
|
||||||
|
printf("standard SDCC types, using \017\002CPCtelera\017\001's");
|
||||||
|
printf("convenient aliases.\n\r\n\r");
|
||||||
|
printf("Size of \017\003 u8 \017\001=\017\002 %d \017\001byte\n\r", sizeof(u8));
|
||||||
|
printf("Size of \017\003u16 \017\001=\017\002 %d \017\001byte\n\r", sizeof(u16));
|
||||||
|
printf("Size of \017\003u32 \017\001=\017\002 %d \017\001byte\n\r", sizeof(u32));
|
||||||
|
printf("Size of \017\003u64 \017\001=\017\002 %d \017\001byte\n\r", sizeof(u64));
|
||||||
|
printf("Size of \017\003 i8 \017\001=\017\002 %d \017\001byte\n\r", sizeof(i8));
|
||||||
|
printf("Size of \017\003i16 \017\001=\017\002 %d \017\001byte\n\r", sizeof(i16));
|
||||||
|
printf("Size of \017\003i32 \017\001=\017\002 %d \017\001byte\n\r", sizeof(i32));
|
||||||
|
printf("Size of \017\003i64 \017\001=\017\002 %d \017\001byte\n\r", sizeof(i64));
|
||||||
|
printf("Size of \017\003f32 \017\001=\017\002 %d \017\001byte\n\r", sizeof(f32));
|
||||||
|
|
||||||
|
|
||||||
|
// cpct_disableFirmware ();
|
||||||
|
cpct_disableUpperROM ();
|
||||||
|
|
||||||
|
// 2 boxes with varying colour patterns
|
||||||
|
cpct_drawSolidBox((u8*)0xC265, cpct_px2byteM1(1, 0, 2, 1), 10, 20);
|
||||||
|
cpct_drawSolidBox((u8*)0xC275, cpct_px2byteM1(0, 2, 0, 1), 10, 20);
|
||||||
|
|
||||||
|
// 2 stripped boxes in 2 alternating colours
|
||||||
|
cpct_drawSolidBox((u8*)0xC355, 0xA0, 10, 20); // 0xA0 = cpct_px2byteM1(1, 0, 1, 0)
|
||||||
|
cpct_drawSolidBox((u8*)0xC365, 0x0A, 10, 20); // 0x0A = cpct_px2byteM1(2, 0, 2, 0)
|
||||||
|
|
||||||
|
// Another 2 stripped boxes, with the strips displaced
|
||||||
|
cpct_drawSolidBox((u8*)0xC445, 0x50, 10, 20); // 0x50 = cpct_px2byteM1(0, 1, 0, 1)
|
||||||
|
cpct_drawSolidBox((u8*)0xC455, 0x05, 10, 20); // 0x05 = cpct_px2byteM1(0, 2, 0, 2)
|
||||||
|
|
||||||
|
// 2 Boxes in solid colour (4 pixels of the same colour)
|
||||||
|
cpct_drawSolidBox((u8*)0xC535, cpct_px2byteM1(2, 2, 2, 2), 10, 20); // 0xF0
|
||||||
|
cpct_drawSolidBox((u8*)0xC545, cpct_px2byteM1(1, 1, 1, 1), 10, 20); // 0x0F
|
||||||
|
|
||||||
|
// Loop forever
|
||||||
|
while (1);
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
//-----------------------------LICENSE NOTICE------------------------------------
|
||||||
|
// This file is part of CPCtelera: An Amstrad CPC Game Engine
|
||||||
|
// Copyright (C) 2015 ronaldo / Fremos / Cheesetea / ByteRealms (@FranGallegoBR)
|
||||||
|
// Created in collaboration with Roald Strauss (aka mr_lou / CPCWiki)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cpctelera.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Useful constants
|
||||||
|
// * Start of screen video memory
|
||||||
|
// * Size in bytes of a complete screen video pixel line
|
||||||
|
// * Offset from the start of a pixel line to the start of the next (inside same group of 8 pixel lines)
|
||||||
|
// * Screen character line to be used for scrolling (0-24)
|
||||||
|
#define PIXEL_LINE_SIZE 0x0050
|
||||||
|
#define PIXEL_LINE_OFFSET 0x0800
|
||||||
|
#define CHARLINE 12
|
||||||
|
|
||||||
|
//
|
||||||
|
// Waits n times for a VSYNC signal (1/50s). After each VSYNC signal,
|
||||||
|
// if waits for 2 interrupts (using HALT 2 times) to ensure that VSYNC
|
||||||
|
// stops being active until looking for the next VSYNC signal.
|
||||||
|
//
|
||||||
|
void wait_n_VSYNCs(u8 n) {
|
||||||
|
do {
|
||||||
|
// Wait for 1 VSYNC signal
|
||||||
|
cpct_waitVSYNC();
|
||||||
|
|
||||||
|
// If we still have to wait for more VSYNC signals, wait first
|
||||||
|
// for this present VSYNC signal to become inactive. For that,
|
||||||
|
// wait for 2 system interrupts using ASM halt instruction.
|
||||||
|
if (--n) {
|
||||||
|
__asm__("halt");
|
||||||
|
__asm__("halt");
|
||||||
|
}
|
||||||
|
} while(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Scrolls a Character line (8 pixel lines) 1 byte to the left. To do
|
||||||
|
// this, it goes byte by byte copying the next byte (the one to the right)
|
||||||
|
// pCharline: pointer to the first byte of the character line (the 8 pixel lines)
|
||||||
|
// lineSize: number of total bytes a pixel line has
|
||||||
|
//
|
||||||
|
void scrollLine(u8* pCharline, u16 lineSize) {
|
||||||
|
// Scroll 8 pixel lines. This loop is executed 8 times: when pCharline is incremented
|
||||||
|
// the 9th time, it will overflow (will be greater than 0xFFFF, cycling through 0x0000)
|
||||||
|
// and will be lower than 0xC000.
|
||||||
|
for (; pCharline > CPCT_VMEM_START; pCharline += PIXEL_LINE_OFFSET)
|
||||||
|
cpct_memcpy(pCharline, pCharline+1, lineSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAIN LOOP
|
||||||
|
//
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
// Test to be used for scrolling (declared constant as it won't be modified,
|
||||||
|
// and that prevents compiler from generating code for initializing it)
|
||||||
|
const u8 *text="This is a simple software scrolling mode 1 text. Not really smooth, but easy to understand. ";
|
||||||
|
|
||||||
|
// Pointer to the first byte of the screen character line
|
||||||
|
// (8 pixel lines) to be scrolled. First 25 pixel lines of screen
|
||||||
|
// video memory are the 25 pixel 0 lines of each screen character line
|
||||||
|
// (group of 8 pixel lines), hence this calculation.
|
||||||
|
u8* pCharline_start = CPCT_VMEM_START + (PIXEL_LINE_SIZE * CHARLINE);
|
||||||
|
|
||||||
|
// Pointer to the first byte of the last screen character of the
|
||||||
|
// character line (last 2 bytes of the 8 pixel lines)
|
||||||
|
const u8* pNextCharLocation = pCharline_start + PIXEL_LINE_SIZE - 2;
|
||||||
|
|
||||||
|
const u8 textlen=strlen(text); // Save the lenght of the text for later use
|
||||||
|
u8 nextChar=0; // Next character of the text to be drawn on the screen
|
||||||
|
u8 penColour=1; // Pen colour for the characters
|
||||||
|
|
||||||
|
cpct_disableFirmware ();
|
||||||
|
cpct_disableUpperROM ();
|
||||||
|
|
||||||
|
// Infinite scrolling loop
|
||||||
|
cpct_drawStringM1("Hold any key to pause scroll", CPCT_VMEM_START, 1, 3);
|
||||||
|
while (1) {
|
||||||
|
// When holding a key, wait for release (Loop scanning the keyboard
|
||||||
|
// until no single key is pressed)
|
||||||
|
do { cpct_scanKeyboard_f(); } while( cpct_isAnyKeyPressed_f() );
|
||||||
|
|
||||||
|
// Draw next character at the rightmost character location of the
|
||||||
|
// character line being scrolled
|
||||||
|
cpct_drawCharM1_f(pNextCharLocation, penColour, 0, text[nextChar]);
|
||||||
|
|
||||||
|
// nextChar will hold the index of the next Character, returning to
|
||||||
|
// the first one when there are no more characters left, and changing
|
||||||
|
// Pen colour for next sentence
|
||||||
|
if (++nextChar == textlen) {
|
||||||
|
nextChar = 0;
|
||||||
|
if (++penColour > 3) penColour = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll character line 2 times, as each scroll call will move
|
||||||
|
// the pixels 1 byte = 4 pixels. So, 2 times = 8 pixels = 1 Character
|
||||||
|
// Sinchronyze with VSYNC previous to each call to make it smooth
|
||||||
|
wait_n_VSYNCs(2);
|
||||||
|
scrollLine(pCharline_start, PIXEL_LINE_SIZE);
|
||||||
|
wait_n_VSYNCs(2);
|
||||||
|
scrollLine(pCharline_start, PIXEL_LINE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
#include "cpctelera.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
// Needed for screen clear to work
|
||||||
|
cpct_disableFirmware ();
|
||||||
|
cpct_disableUpperROM ();
|
||||||
|
|
||||||
|
// Clear Screen filling it up with 0's
|
||||||
|
cpct_clearScreen(0);
|
||||||
|
|
||||||
|
// Print out some messages using printf
|
||||||
|
printf("\017\003Hello \017\002World!\n\r");
|
||||||
|
|
||||||
|
// printf() may have enabled upper ROM, disable
|
||||||
|
cpct_disableUpperROM ();
|
||||||
|
|
||||||
|
// Loop forever
|
||||||
|
while (1);
|
||||||
|
}
|
BIN
res/cpc.wasm
BIN
res/cpc.wasm
Binary file not shown.
|
@ -82,7 +82,7 @@ export class C64_WASMMachine extends BaseWASMMachine implements Machine, Probeab
|
||||||
var clocks = Math.floor((this.numTotalScanlines - scanline) * (19656+295) / this.numTotalScanlines);
|
var clocks = Math.floor((this.numTotalScanlines - scanline) * (19656+295) / this.numTotalScanlines);
|
||||||
var probing = this.probe != null;
|
var probing = this.probe != null;
|
||||||
if (probing) this.exports.machine_reset_probe_buffer();
|
if (probing) this.exports.machine_reset_probe_buffer();
|
||||||
var clocks = super.advanceFrameClock(trap, clocks);
|
clocks = super.advanceFrameClock(trap, clocks);
|
||||||
if (probing) this.copyProbeData();
|
if (probing) this.copyProbeData();
|
||||||
return clocks;
|
return clocks;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,15 +32,15 @@ export class CPC_WASMMachine extends BaseWASMMachine implements Machine {
|
||||||
cpuCyclesPerLine = 224;
|
cpuCyclesPerLine = 224;
|
||||||
|
|
||||||
joymask0 = 0;
|
joymask0 = 0;
|
||||||
|
runaddr = 0x4000;
|
||||||
|
|
||||||
loadROM(rom: Uint8Array) {
|
loadROM(rom: Uint8Array) {
|
||||||
let runaddr = 0x4000; //0x5de9;
|
|
||||||
let combined = new Uint8Array(rom.length + BIN_HEADER.length);
|
let combined = new Uint8Array(rom.length + BIN_HEADER.length);
|
||||||
combined.set(BIN_HEADER, 0);
|
combined.set(BIN_HEADER, 0);
|
||||||
combined[24] = rom.length & 0xff;
|
combined[24] = rom.length & 0xff;
|
||||||
combined[25] = rom.length >> 8;
|
combined[25] = rom.length >> 8;
|
||||||
combined[26] = runaddr & 0xff;
|
combined[26] = this.runaddr & 0xff;
|
||||||
combined[27] = runaddr >> 8;
|
combined[27] = this.runaddr >> 8;
|
||||||
combined.set(rom, BIN_HEADER.length);
|
combined.set(rom, BIN_HEADER.length);
|
||||||
super.loadROM(combined);
|
super.loadROM(combined);
|
||||||
}
|
}
|
||||||
|
@ -51,13 +51,18 @@ export class CPC_WASMMachine extends BaseWASMMachine implements Machine {
|
||||||
// load rom (SNA or BIN)
|
// load rom (SNA or BIN)
|
||||||
if (this.romptr && this.romlen) {
|
if (this.romptr && this.romlen) {
|
||||||
this.exports.machine_load_rom(this.sys, this.romptr, this.romlen);
|
this.exports.machine_load_rom(this.sys, this.romptr, this.romlen);
|
||||||
|
// advance clock until program starts
|
||||||
|
for (var i=0; i<100000 && this.getPC() != this.runaddr; i++) {
|
||||||
|
this.exports.machine_tick(this.sys);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
advanceFrame(trap: TrapCondition) : number {
|
advanceFrame(trap: TrapCondition) : number {
|
||||||
//var scanline = this.exports.machine_get_raster_line(this.sys);
|
var scanline = this.exports.machine_get_raster_line(this.sys);
|
||||||
|
var clocks = Math.floor((this.numTotalScanlines - scanline) * 19965 / this.numTotalScanlines);
|
||||||
var probing = this.probe != null;
|
var probing = this.probe != null;
|
||||||
if (probing) this.exports.machine_reset_probe_buffer();
|
if (probing) this.exports.machine_reset_probe_buffer();
|
||||||
var clocks = super.advanceFrameClock(trap, Math.floor(1000000 / 50)); // TODO: use ticks, not msec
|
clocks = super.advanceFrameClock(trap, clocks);
|
||||||
if (probing) this.copyProbeData();
|
if (probing) this.copyProbeData();
|
||||||
return clocks;
|
return clocks;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +122,6 @@ export class CPC_WASMMachine extends BaseWASMMachine implements Machine {
|
||||||
if (key == 16 || key == 17 || key == 18 || key == 224) return; // meta keys
|
if (key == 16 || key == 17 || key == 18 || key == 224) return; // meta keys
|
||||||
//console.log(key, code, flags);
|
//console.log(key, code, flags);
|
||||||
//if (flags & KeyFlags.Shift) { key += 64; }
|
//if (flags & KeyFlags.Shift) { key += 64; }
|
||||||
// convert to c64 (TODO: zx)
|
|
||||||
var mask = 0;
|
var mask = 0;
|
||||||
var mask2 = 0;
|
var mask2 = 0;
|
||||||
if (key == 37) { key = 0x8; mask = 0x4; } // LEFT
|
if (key == 37) { key = 0x8; mask = 0x4; } // LEFT
|
||||||
|
@ -141,6 +145,6 @@ export class CPC_WASMMachine extends BaseWASMMachine implements Machine {
|
||||||
this.exports.machine_key_up(this.sys, key);
|
this.exports.machine_key_up(this.sys, key);
|
||||||
this.joymask0 &= ~mask;
|
this.joymask0 &= ~mask;
|
||||||
}
|
}
|
||||||
this.exports.cpc_joystick(this.sys, this.joymask0, 0);
|
// TODO: this.exports.cpc_joystick(this.sys, this.joymask0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,13 @@ import { PLATFORMS } from "../common/emu";
|
||||||
|
|
||||||
const CPC_PRESETS = [
|
const CPC_PRESETS = [
|
||||||
{id:'hello.asm', name:'Hello World (ASM)'},
|
{id:'hello.asm', name:'Hello World (ASM)'},
|
||||||
{id:'sprite_demo.c', name:'Sprite Demo (C)'},
|
{id:'easy_stdio_boxes.c', name:'Standard I/O (C)'},
|
||||||
{id:'keyboard_redefine.c', name:'Keyboard Redefine (C)'},
|
{id:'easy_mode_strings.c', name:'Video Modes (C)'},
|
||||||
|
{id:'easy_random.c', name:'Random Numbers (C)'},
|
||||||
|
{id:'easy_sprites.c', name:'Keyboard + Sprites (C)'},
|
||||||
|
{id:'medium_scrolling.c', name:'Scrolling Text (C)'},
|
||||||
|
//{id:'sprite_demo.c', name:'Sprite Demo (C)'},
|
||||||
|
//{id:'keyboard_redefine.c', name:'Keyboard Redefine (C)'},
|
||||||
];
|
];
|
||||||
|
|
||||||
const CPC_MEMORY_MAP = { main:[
|
const CPC_MEMORY_MAP = { main:[
|
||||||
|
@ -24,8 +29,11 @@ class CPCWASMPlatform extends BaseZ80MachinePlatform<CPC_WASMMachine> implements
|
||||||
readAddress(a) { return this.machine.readConst(a); }
|
readAddress(a) { return this.machine.readConst(a); }
|
||||||
getMemoryMap() { return CPC_MEMORY_MAP; }
|
getMemoryMap() { return CPC_MEMORY_MAP; }
|
||||||
showHelp() {
|
showHelp() {
|
||||||
window.open("https://worldofspectrum.org/faq/reference/reference.htm", "_help");
|
window.open("http://lronaldo.github.io/cpctelera/files/readme-txt.html", "_help");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: make different cpc_init() types for different platforms
|
||||||
|
PLATFORMS['cpc.6128'] = CPCWASMPlatform;
|
||||||
PLATFORMS['cpc.464'] = CPCWASMPlatform;
|
PLATFORMS['cpc.464'] = CPCWASMPlatform;
|
||||||
|
PLATFORMS['cpc.kcc'] = CPCWASMPlatform;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
crt0-cpc.rel:
|
||||||
|
/opt/homebrew/bin/sdasz80 -los crt0-cpc.s
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -1,75 +1,80 @@
|
||||||
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 1.
|
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180 / ZX-Next / eZ80), page 1.
|
||||||
Hexadecimal [16-Bits]
|
Hexadecimal [24-Bits]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1 ; crt0.s for ZX Spectrum
|
1 ; crt0.s for ZX Spectrum
|
||||||
2
|
2
|
||||||
3 .module crt0
|
3 .module crt0
|
||||||
4 .globl _main
|
4 .globl _main
|
||||||
5 .globl ___sdcc_call_hl
|
5 .globl ___sdcc_call_hl
|
||||||
6
|
6 .globl l__DATA
|
||||||
7 ; Ordering of segments for the linker - copied from sdcc crt0.s
|
7 .globl s__DATA
|
||||||
8 .area _CODE
|
8 .globl s__INITIALIZED
|
||||||
9 .area _INITIALIZER
|
9 .globl s__INITIALIZER
|
||||||
10 .area _HOME
|
10 .globl l__INITIALIZER
|
||||||
11 .area _GSINIT
|
11
|
||||||
12 .area _GSFINAL
|
12 ; Ordering of segments for the linker - copied from sdcc crt0.s
|
||||||
13 .area _DATA
|
13 .area _CODE
|
||||||
14 .area _INITIALIZED
|
14 .area _INITIALIZER
|
||||||
15 .area _BSEG
|
15 .area _HOME
|
||||||
16 .area _BSS
|
16 .area _GSINIT
|
||||||
17 .area _HEAP
|
17 .area _GSFINAL
|
||||||
18
|
18 .area _DATA
|
||||||
19 .area _CODE
|
19 .area _INITIALIZED
|
||||||
20
|
20 .area _BSEG
|
||||||
0000 21 _Start:
|
21 .area _BSS
|
||||||
0000 F3 [ 4] 22 di
|
22 .area _HEAP
|
||||||
0001 ED 56 [ 8] 23 im 1
|
23
|
||||||
24 ; stack pointer already set by BIOS
|
24 .area _CODE
|
||||||
0003 CD 00 00 [17] 25 call gsinit ; Initialize global and static variables.
|
25
|
||||||
0006 CD 00 00 [17] 26 call _main
|
000000 26 _Start:
|
||||||
0009 C7 [11] 27 rst 0x0 ; Restart when main() returns.
|
27 ;di
|
||||||
28
|
28 ;im 1
|
||||||
29 .area _GSINIT
|
29 ; stack pointer already set by BIOS
|
||||||
0000 30 gsinit::
|
000000 CD 00 00 [17] 30 call gsinit ; Initialize global and static variables.
|
||||||
31
|
000003 CD 00 00 [17] 31 call _main
|
||||||
32 ; Implicitly zeroed global and static variables.
|
000006 C7 [11] 32 rst 0x0 ; Restart when main() returns.
|
||||||
0000 01 00 00 [10] 33 ld bc, #l__DATA
|
33
|
||||||
0003 78 [ 4] 34 ld a, b
|
34 .area _GSINIT
|
||||||
0004 B1 [ 4] 35 or a, c
|
000000 35 gsinit::
|
||||||
0005 28 0F [12] 36 jr Z, zeroed_data
|
36
|
||||||
0007 21 00 00 [10] 37 ld hl, #s__DATA
|
37 ; Implicitly zeroed global and static variables.
|
||||||
000A 36 00 [10] 38 ld (hl), #0x00
|
000000 01 00 00 [10] 38 ld bc, #l__DATA
|
||||||
000C 0B [ 6] 39 dec bc
|
000003 78 [ 4] 39 ld a, b
|
||||||
000D 78 [ 4] 40 ld a, b
|
000004 B1 [ 4] 40 or a, c
|
||||||
000E B1 [ 4] 41 or a, c
|
000005 28 0F [12] 41 jr Z, zeroed_data
|
||||||
000F 28 05 [12] 42 jr Z, zeroed_data
|
000007 21 00 00 [10] 42 ld hl, #s__DATA
|
||||||
0011 5D [ 4] 43 ld e, l
|
00000A 36 00 [10] 43 ld (hl), #0x00
|
||||||
0012 54 [ 4] 44 ld d, h
|
00000C 0B [ 6] 44 dec bc
|
||||||
0013 13 [ 6] 45 inc de
|
00000D 78 [ 4] 45 ld a, b
|
||||||
0014 ED B0 [21] 46 ldir
|
00000E B1 [ 4] 46 or a, c
|
||||||
0016 47 zeroed_data:
|
00000F 28 05 [12] 47 jr Z, zeroed_data
|
||||||
48
|
000011 5D [ 4] 48 ld e, l
|
||||||
49 ; Explicitly initialized global variables.
|
000012 54 [ 4] 49 ld d, h
|
||||||
0016 01 00 00 [10] 50 ld bc, #l__INITIALIZER
|
000013 13 [ 6] 50 inc de
|
||||||
0019 78 [ 4] 51 ld a, b
|
000014 ED B0 [21] 51 ldir
|
||||||
001A B1 [ 4] 52 or a, c
|
000016 52 zeroed_data:
|
||||||
001B 28 08 [12] 53 jr Z, gsinit_static
|
53
|
||||||
001D 11 00 00 [10] 54 ld de, #s__INITIALIZED
|
54 ; Explicitly initialized global variables.
|
||||||
0020 21 00 00 [10] 55 ld hl, #s__INITIALIZER
|
000016 01 00 00 [10] 55 ld bc, #l__INITIALIZER
|
||||||
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 2.
|
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180 / ZX-Next / eZ80), page 2.
|
||||||
Hexadecimal [16-Bits]
|
Hexadecimal [24-Bits]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
0023 ED B0 [21] 56 ldir
|
000019 78 [ 4] 56 ld a, b
|
||||||
57
|
00001A B1 [ 4] 57 or a, c
|
||||||
0025 58 gsinit_static:
|
00001B 28 08 [12] 58 jr Z, gsinit_static
|
||||||
59 ; Explicitly initialized static variables inserted by compiler here.
|
00001D 11 00 00 [10] 59 ld de, #s__INITIALIZED
|
||||||
60
|
000020 21 00 00 [10] 60 ld hl, #s__INITIALIZER
|
||||||
61 .area _GSFINAL
|
000023 ED B0 [21] 61 ldir
|
||||||
0000 C9 [10] 62 ret
|
62
|
||||||
63
|
000025 63 gsinit_static:
|
||||||
64 .area _HOME
|
64 ; Explicitly initialized static variables inserted by compiler here.
|
||||||
65
|
65
|
||||||
|
66 .area _GSFINAL
|
||||||
|
000000 C9 [10] 67 ret
|
||||||
|
68
|
||||||
|
69 .area _HOME
|
||||||
|
70
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
XL2
|
XL3
|
||||||
H A areas 9 global symbols
|
H A areas 9 global symbols
|
||||||
M crt0
|
M crt0
|
||||||
S l__DATA Ref0000
|
S l__DATA Ref000000
|
||||||
S _main Ref0000
|
S _main Ref000000
|
||||||
S s__DATA Ref0000
|
S s__DATA Ref000000
|
||||||
S .__.ABS. Def0000
|
S .__.ABS. Def000000
|
||||||
S s__INITIALIZED Ref0000
|
S s__INITIALIZED Ref000000
|
||||||
S ___sdcc_call_hl Ref0000
|
S ___sdcc_call_hl Ref000000
|
||||||
S l__INITIALIZER Ref0000
|
S l__INITIALIZER Ref000000
|
||||||
S s__INITIALIZER Ref0000
|
S s__INITIALIZER Ref000000
|
||||||
A _CODE size A flags 0 addr 0
|
A _CODE size 7 flags 0 addr 0
|
||||||
A _INITIALIZER size 0 flags 0 addr 0
|
A _INITIALIZER size 0 flags 0 addr 0
|
||||||
A _HOME size 0 flags 0 addr 0
|
A _HOME size 0 flags 0 addr 0
|
||||||
A _GSINIT size 25 flags 0 addr 0
|
A _GSINIT size 25 flags 0 addr 0
|
||||||
S gsinit Def0000
|
S gsinit Def000000
|
||||||
A _GSFINAL size 1 flags 0 addr 0
|
A _GSFINAL size 1 flags 0 addr 0
|
||||||
A _DATA size 0 flags 0 addr 0
|
A _DATA size 0 flags 0 addr 0
|
||||||
A _INITIALIZED size 0 flags 0 addr 0
|
A _INITIALIZED size 0 flags 0 addr 0
|
||||||
A _BSEG size 0 flags 0 addr 0
|
A _BSEG size 0 flags 0 addr 0
|
||||||
A _BSS size 0 flags 0 addr 0
|
A _BSS size 0 flags 0 addr 0
|
||||||
A _HEAP size 0 flags 0 addr 0
|
A _HEAP size 0 flags 0 addr 0
|
||||||
T 00 00
|
T 00 00 00
|
||||||
R 00 00 00 00
|
R 00 00 00 00
|
||||||
T 00 00 F3 ED 56 CD 00 00 CD 00 00 C7
|
T 00 00 00 CD 00 00 CD 00 00 C7
|
||||||
R 00 00 00 00 00 06 03 00 02 09 01 00
|
R 00 00 00 00 00 04 03 00 02 07 01 00
|
||||||
T 00 00
|
T 00 00 00
|
||||||
R 00 00 03 00
|
R 00 00 03 00
|
||||||
T 00 00 01 00 00 78 B1 28 0F 21 00 00 36 00 0B 78
|
T 00 00 00 01 00 00 78 B1 28 0F 21 00 00 36 00 0B
|
||||||
R 00 00 03 00 02 03 00 00 02 0A 02 00
|
R 00 00 03 00 02 04 00 00 02 0B 02 00
|
||||||
T 0E 00 B1 28 05 5D 54 13 ED B0
|
T 0D 00 00 78 B1 28 05 5D 54 13 ED B0
|
||||||
R 00 00 03 00
|
R 00 00 03 00
|
||||||
T 16 00
|
T 16 00 00
|
||||||
R 00 00 03 00
|
R 00 00 03 00
|
||||||
T 16 00 01 00 00 78 B1 28 08 11 00 00 21 00 00 ED
|
T 16 00 00 01 00 00 78 B1 28 08 11 00 00 21 00 00
|
||||||
R 00 00 03 00 02 03 06 00 02 0A 04 00 02 0D 07 00
|
R 00 00 03 00 02 04 06 00 02 0B 04 00 02 0E 07 00
|
||||||
T 24 00 B0
|
T 23 00 00 ED B0
|
||||||
R 00 00 03 00
|
R 00 00 03 00
|
||||||
T 25 00
|
T 25 00 00
|
||||||
R 00 00 03 00
|
R 00 00 03 00
|
||||||
T 00 00 C9
|
T 00 00 00 C9
|
||||||
R 00 00 04 00
|
R 00 00 04 00
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
.module crt0
|
.module crt0
|
||||||
.globl _main
|
.globl _main
|
||||||
.globl ___sdcc_call_hl
|
.globl ___sdcc_call_hl
|
||||||
|
.globl l__DATA
|
||||||
|
.globl s__DATA
|
||||||
|
.globl s__INITIALIZED
|
||||||
|
.globl s__INITIALIZER
|
||||||
|
.globl l__INITIALIZER
|
||||||
|
|
||||||
; Ordering of segments for the linker - copied from sdcc crt0.s
|
; Ordering of segments for the linker - copied from sdcc crt0.s
|
||||||
.area _CODE
|
.area _CODE
|
||||||
|
@ -19,8 +24,8 @@
|
||||||
.area _CODE
|
.area _CODE
|
||||||
|
|
||||||
_Start:
|
_Start:
|
||||||
di
|
;di
|
||||||
im 1
|
;im 1
|
||||||
; stack pointer already set by BIOS
|
; stack pointer already set by BIOS
|
||||||
call gsinit ; Initialize global and static variables.
|
call gsinit ; Initialize global and static variables.
|
||||||
call _main
|
call _main
|
||||||
|
@ -34,7 +39,7 @@ gsinit::
|
||||||
ld a, b
|
ld a, b
|
||||||
or a, c
|
or a, c
|
||||||
jr Z, zeroed_data
|
jr Z, zeroed_data
|
||||||
ld hl, #s__DATA
|
ld hl, #s__DATA
|
||||||
ld (hl), #0x00
|
ld (hl), #0x00
|
||||||
dec bc
|
dec bc
|
||||||
ld a, b
|
ld a, b
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 1.
|
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180 / ZX-Next / eZ80), page 1.
|
||||||
Hexadecimal [16-Bits]
|
Hexadecimal [24-Bits]
|
||||||
|
|
||||||
Symbol Table
|
Symbol Table
|
||||||
|
|
||||||
.__.$$$.= 2710 L | .__.ABS.= 0000 G | .__.CPU.= 0000 L
|
.__.$$$.= 002710 L | .__.ABS.= 000000 G | .__.CPU.= 000000 L
|
||||||
.__.H$L.= 0000 L | 0 _Start 0000 R | ___sdcc_ **** GX
|
.__.H$L.= 000000 L | 0 _Start 000000 R | ___sdcc_ ****** GX
|
||||||
_main **** GX | 3 gsinit 0000 GR | 3 gsinit_s 0025 R
|
_main ****** GX | 3 gsinit 000000 GR | 3 gsinit_s 000025 R
|
||||||
l__DATA **** GX | l__INITI **** GX | s__DATA **** GX
|
l__DATA ****** GX | l__INITI ****** GX | s__DATA ****** GX
|
||||||
s__INITI **** GX | s__INITI **** GX | 3 zeroed_d 0016 R
|
s__INITI ****** GX | s__INITI ****** GX | 3 zeroed_d 000016 R
|
||||||
|
|
||||||
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 2.
|
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180 / ZX-Next / eZ80), page 2.
|
||||||
Hexadecimal [16-Bits]
|
Hexadecimal [24-Bits]
|
||||||
|
|
||||||
Area Table
|
Area Table
|
||||||
|
|
||||||
0 _CODE size A flags 0
|
0 _CODE size 7 flags 0
|
||||||
1 _INITIAL size 0 flags 0
|
1 _INITIAL size 0 flags 0
|
||||||
2 _HOME size 0 flags 0
|
2 _HOME size 0 flags 0
|
||||||
3 _GSINIT size 25 flags 0
|
3 _GSINIT size 25 flags 0
|
||||||
4 _GSFINAL size 1 flags 0
|
4 _GSFINAL size 1 flags 0
|
||||||
5 _DATA size 0 flags 0
|
5 _DATA size 0 flags 0
|
||||||
6 _INITIAL size 0 flags 0
|
6 _INITIAL size 0 flags 0
|
||||||
7 _BSEG size 0 flags 0
|
7 _BSEG size 0 flags 0
|
||||||
8 _BSS size 0 flags 0
|
8 _BSS size 0 flags 0
|
||||||
9 _HEAP size 0 flags 0
|
9 _HEAP size 0 flags 0
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,7 @@ var PLATFORM_PARAMS = {
|
||||||
extra_link_files: ['crt0.o', 'devel-6502.cfg'],
|
extra_link_files: ['crt0.o', 'devel-6502.cfg'],
|
||||||
},
|
},
|
||||||
// https://github.com/cpcitor/cpc-dev-tool-chain
|
// https://github.com/cpcitor/cpc-dev-tool-chain
|
||||||
'cpc': {
|
'cpc.rslib': {
|
||||||
arch: 'z80',
|
arch: 'z80',
|
||||||
code_start: 0x4000,
|
code_start: 0x4000,
|
||||||
rom_size: 0xb100-0x4000,
|
rom_size: 0xb100-0x4000,
|
||||||
|
@ -356,6 +356,18 @@ var PLATFORM_PARAMS = {
|
||||||
extra_link_args: ['crt0-cpc.rel', 'cpcrslib.lib'],
|
extra_link_args: ['crt0-cpc.rel', 'cpcrslib.lib'],
|
||||||
extra_link_files: ['crt0-cpc.rel', 'crt0-cpc.lst', 'cpcrslib.lib', 'cpcrslib.lst'],
|
extra_link_files: ['crt0-cpc.rel', 'crt0-cpc.lst', 'cpcrslib.lib', 'cpcrslib.lst'],
|
||||||
},
|
},
|
||||||
|
// https://lronaldo.github.io/cpctelera/ (TODO)
|
||||||
|
'cpc': {
|
||||||
|
arch: 'z80',
|
||||||
|
code_start: 0x4000,
|
||||||
|
rom_size: 0xb100-0x4000,
|
||||||
|
data_start: 0xb100,
|
||||||
|
data_size: 0xb100-0xc000,
|
||||||
|
stack_end: 0xc000,
|
||||||
|
extra_compile_files: ['cpctelera.h'],
|
||||||
|
extra_link_args: ['crt0-cpc.rel', 'cpctelera.lib'],
|
||||||
|
extra_link_files: ['crt0-cpc.rel', 'crt0-cpc.lst', 'cpctelera.lib', 'cpctelera.lst'],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
PLATFORM_PARAMS['sms-sms-libcv'] = PLATFORM_PARAMS['sms-sg1000-libcv'];
|
PLATFORM_PARAMS['sms-sms-libcv'] = PLATFORM_PARAMS['sms-sg1000-libcv'];
|
||||||
|
|
Loading…
Reference in New Issue