cpc: started investigation, cpcrslib, aspect

This commit is contained in:
Steven Hugg 2021-11-22 10:49:16 -06:00
parent f2ea25d0c3
commit 8fa0389da1
21 changed files with 893 additions and 9 deletions

31
presets/cpc/hello.asm Normal file
View File

@ -0,0 +1,31 @@
; from https://www.chibiakumas.com/z80/helloworld.php#LessonH1
PrintChar = 0xbb5a
WaitChar = 0xbb06
org 0x4000
Start:
ld hl,Message ;Address of string
call PrintString ;Show String to screen
call WaitChar
ret ;Finished Hello World
PrintString:
ld a,(hl) ;Print a '255' terminated string
cp 255
ret z
inc hl
call PrintChar
jr PrintString
Message:
db 'Hello World! Press a key...',255
NewLine:
ld a,13 ;Carriage return
call PrintChar
ld a,10 ;Line Feed
call PrintChar
ret

View File

@ -0,0 +1,63 @@
// from https://github.com/cpcitor/cpcrslib/tree/master/examples
#include "cpcrslib.h"
void wait(void){
__asm
_kkk:
ld b,#100
llll:
halt
djnz llll
__endasm;
}
main()
{
cpc_SetModo(1);
cpc_AssignKey(4,0x4804); // key "ESC"
cpc_PrintStr("Welcome to cpcrslib keyboard utilities.");
cpc_PrintStr("Press a Key to redefine as #1");
cpc_RedefineKey(0); //redefine key. There are 12 available keys (0..11)
cpc_PrintStr("Done!");
cpc_PrintStr("Now, press any key to continue");
while(!(cpc_AnyKeyPressed())){}
cpc_PrintStr("Well done! Let's do it again");
cpc_PrintStr("Press any key to continue");
while(!(cpc_AnyKeyPressed())){}
cpc_PrintStr("Press a Key to redefine as #3");
cpc_RedefineKey(3); //redefine key. There are 12 available keys (0..11)
cpc_PrintStr("Done!");
wait();
cpc_SetModo(1);
cpc_SetBorder(3);
cpc_PrintStr("Now let's test the selected keys. Press ESC to EXIT");
cpc_PrintStr("Press a Key to test it..");
while (!cpc_TestKey(4)) { // IF NOT ESC is pressed
if (cpc_TestKey(0)) { //test if the key has been pressed.
cpc_PrintStr("OK Key #1");
}
if (cpc_TestKey(3)) { //test if the key has been pressed.
cpc_PrintStr("OK Key #2");
}
//else cpc_PrintStr(no);
}
return 0;
}

262
presets/cpc/sprite_demo.c Normal file
View File

@ -0,0 +1,262 @@
// from https://github.com/cpcitor/cpcrslib/tree/master/examples
#include "cpcrslib.h"
extern unsigned char sp_1[]; //masked sprite data
extern unsigned char sp_2[]; //masked sprite data
extern unsigned char tintas[]; //inks
extern unsigned char buffer[]; //inks
struct sprite // minimun sprite structure
{
char *sp0; //2 bytes 01
char *sp1; //2 bytes 23
int coord0; //2 bytes 45 current superbuffer address
int coord1; //2 bytes 67 old superbuffer address
unsigned char cx, cy; //2 bytes 89 current coordinates
unsigned char ox, oy; //2 bytes 1011 old coordinates
unsigned char move1; // los bits 4,3,2 definen el tipo de dibujo!!
unsigned char move; // in this example, to know the movement direction of the sprite
};
struct sprite sprite00,sprite01,sprite02;
void data(void)
{
__asm
_buffer:
.db #30
_sp_1:
.db #4,#15 //sprite dimensions in bytes withd, height
.db #0xFF,#0x00,#0x00,#0xCF,#0x00,#0xCF,#0xFF,#0x00 //data: mask, sprite, mask, sprite...
.db #0xAA,#0x45,#0x00,#0x3C,#0x00,#0x3C,#0x55,#0x8A
.db #0x00,#0x8A,#0x00,#0x55,#0x00,#0xAA,#0x00,#0x45
.db #0x00,#0x8A,#0x00,#0x20,#0x00,#0x00,#0x00,#0x65
.db #0x00,#0x28,#0x00,#0x55,#0x00,#0xAA,#0x00,#0x14
.db #0x00,#0x7D,#0x00,#0xBE,#0x00,#0xFF,#0x00,#0xBE
.db #0xAA,#0x14,#0x00,#0xFF,#0x00,#0xBE,#0x55,#0x28
.db #0xAA,#0x00,#0x00,#0x3C,#0x00,#0x79,#0x55,#0x00
.db #0x00,#0x51,#0x00,#0x51,#0x00,#0xA2,#0x55,#0xA2
.db #0x00,#0xF3,#0x00,#0x10,#0x00,#0x20,#0x00,#0xF3
.db #0x00,#0xF3,#0x00,#0x51,#0x00,#0xA2,#0x00,#0xF3
.db #0x55,#0x28,#0x00,#0x0F,#0x00,#0x0F,#0xAA,#0x14
.db #0xFF,#0x00,#0x55,#0x0A,#0xAA,#0x05,#0xFF,#0x00
.db #0x55,#0x02,#0x55,#0x28,#0xAA,#0x14,#0xAA,#0x01
.db #0x00,#0x03,#0x55,#0x02,#0xAA,#0x01,#0x00,#0x03
_sp_2:
.db #4,#21
.db #0xFF,#0x00,#0x00,#0xCC,#0x00,#0xCC,#0xFF,#0x00
.db #0xFF,#0x00,#0xAA,#0x44,#0x55,#0x88,#0xFF,#0x00
.db #0xFF,#0x00,#0xAA,#0x44,#0x55,#0x88,#0xFF,#0x00
.db #0xFF,#0x00,#0xAA,#0x44,#0x55,#0x88,#0xFF,#0x00
.db #0xFF,#0x00,#0x00,#0xCF,#0x00,#0xCF,#0xFF,#0x00
.db #0xAA,#0x45,#0x00,#0xCF,#0x00,#0xCF,#0x55,#0x8A
.db #0xAA,#0x45,#0x00,#0xE5,#0x00,#0xDA,#0x55,#0x8A
.db #0xAA,#0x45,#0x00,#0xCF,#0x00,#0xCF,#0x55,#0x8A
.db #0xAA,#0x45,#0x00,#0xCF,#0x00,#0xCF,#0x55,#0x8A
.db #0xAA,#0x45,#0x00,#0xCF,#0x00,#0xCF,#0x55,#0x8A
.db #0xAA,#0x45,#0x00,#0xCF,#0x00,#0xCF,#0x55,#0x8A
.db #0xFF,#0x00,#0x00,#0xCF,#0x00,#0xCF,#0xFF,#0x00
.db #0xAA,#0x01,#0x00,#0x03,#0x00,#0x03,#0x55,#0x02
.db #0x00,#0xA9,#0x00,#0x03,#0x00,#0x03,#0x00,#0x56
.db #0x00,#0xA9,#0x00,#0x03,#0x00,#0x03,#0x00,#0x56
.db #0xAA,#0x01,#0x00,#0x03,#0x00,#0x03,#0x55,#0x02
.db #0xAA,#0x01,#0x00,#0x03,#0x00,#0x03,#0x55,#0x02
.db #0xAA,#0x01,#0x00,#0x06,#0x00,#0x09,#0x55,#0x02
.db #0xFF,#0x00,#0x00,#0x0C,#0x00,#0x0C,#0xFF,#0x00
.db #0xFF,#0x00,#0x00,#0x0C,#0x00,#0x0C,#0xFF,#0x00
.db #0xFF,#0x00,#0x00,#0x0C,#0x00,#0x0C,#0xFF,#0x00
// There is a tool called Sprot that allows to generate masked sprites for z88dk.
// ask for it: www.amstrad.es/forum/
_tintas: //firmware inks
.db #0,#13,#1,#6,#26,#24,#15,#8,#10,#22,#14,#3,#18,#4,#11,#25
__endasm;
}
void *p_sprites[7];
void initPointers()
{
p_sprites[0] = &sprite00;
p_sprites[1] = &sprite01;
p_sprites[2] = &sprite02;
}
void set_colours(void)
{
unsigned char x;
for (x=0; x<16; x++)
{
cpc_SetInk(x,tintas[x]);
}
cpc_SetBorder(0);
}
void pause(void)
{
__asm
ld b,#80
pause_loop:
halt
djnz pause_loop
__endasm;
}
void collide(void)
{
cpc_SetColour(16,1);
pause();
cpc_SetColour(16,9);
}
void draw_tilemap(void)
{
unsigned char x,y;
//set the tiles of the map. In this example, the tile map is 32x16 tile
//Tile Map configuration file: TileMapConf.asm
y=0;
for(x=0; x<32; x++)
{
cpc_SetTile(x,y,1);
}
for(y=1; y<15; y++)
{
for (x=0; x<32; x++)
{
cpc_SetTile(x,y,0);
}
}
y=15;
for (x=0; x<32; x++)
{
cpc_SetTile(x,y,2);
}
}
void print_credits(void)
{
cpc_PrintGphStrXY("SMALL;SPRITE;DEMO",9*2+3,20*8);
cpc_PrintGphStrXY("SDCC;;;CPCRSLIB",10*2+3,21*8);
cpc_PrintGphStrXY("BY;ARTABURU;2015",10*2+2,22*8);
cpc_PrintGphStrXY("ESPSOFT<AMSTRAD<ES",10*2+3-3,24*8);
}
main()
{
initPointers();
set_colours();
cpc_SetInkGphStr(0,0);
cpc_SetModo(0);
cpc_DisableFirmware();
// All the sprite values are initilized
sprite00.sp1=sp_1;
sprite00.sp0=sp_1;
sprite00.ox=50;
sprite00.oy=70;
sprite00.cx=50;
sprite00.cy=70;
sprite00.move1=3;
cpc_SuperbufferAddress(p_sprites[0]); //first time it's important to do this
sprite01.sp1=sp_2;
sprite01.sp0=sp_2;
sprite01.ox=50;
sprite01.oy=106;
sprite01.cx=50;
sprite01.cy=106;
sprite01.move=1;
sprite01.move1=3;
cpc_SuperbufferAddress(p_sprites[1]);
sprite02.sp1=sp_2;
sprite02.sp0=sp_2;
sprite02.ox=20;
sprite02.oy=100;
sprite02.cx=20;
sprite02.cy=100;
sprite02.move=2;
sprite02.move1=3;
cpc_SuperbufferAddress(p_sprites[2]);
//Drawing the tile map
draw_tilemap();
cpc_ShowTileMap(); //Show entire tile map in the screen
print_credits();
cpc_SetTile(0,1,2);
/*cpc_GetTiles(0,0,2,3, buffer);
cpc_PutTiles(0,13,2,3, buffer);
cpc_GetTiles(0,13,2,3, buffer);
cpc_PutTiles(8,9,2,3, buffer); */
cpc_ShowTileMap(); //Show entire tile map in the screen
while(1)
{
//cpc_PutTile2x8(sp_1,3,5);
//cpc_PutTile2x8(sp_1,10,170);
//Default number keys for moving one of the sprites:
// 0: cursor right
// 1: cursor left
// 2: cursor up
// 3: cursor down
//for example., if key 0 is pressed, and the sprite is inside tilemap, then
//the sprite is moved one byte to the right:
if (cpc_TestKey(0)==1 && sprite00.cx<60) sprite00.cx++;
if (cpc_TestKey(1)==1 && sprite00.cx>0) sprite00.cx--;
if (cpc_TestKey(2)==1 && sprite00.cy>0) sprite00.cy-=2;
if (cpc_TestKey(3)==1 && sprite00.cy<112) sprite00.cy+=2;
// The other sprites are automatically moved
if (sprite01.move==0) //0 = left, 1 = right
{
if (sprite01.cx>0) sprite01.cx--;
else sprite01.move=1;
}
if (sprite01.move==1) //0 = left, 1 = right
{
if (sprite01.cx<60) sprite01.cx++;
else sprite01.move=0;
}
if (sprite02.move==2) //2 = up, 3 = down
{
if (sprite02.cy>0) sprite02.cy-=2;
else sprite02.move=3;
}
if (sprite02.move==3) //2 = up, 3 = down
{
if (sprite02.cy<106) sprite02.cy+=2;
else sprite02.move=2;
}
cpc_ResetTouchedTiles(); //clear touched tile table
//Sprite phase 1
cpc_PutSpTileMap(p_sprites[0]); //search the tiles where is and was the sprite
cpc_PutSpTileMap(p_sprites[1]);
cpc_PutSpTileMap(p_sprites[2]);
cpc_UpdScr(); //Update the screen to new situatio (show the touched tiles)
//Sprite phase 2
cpc_PutMaskSpTileMap2b(p_sprites[0]); //Requires to move sprite with cpc_SpUpdX or cpc_SpUpdY
cpc_PutMaskSpTileMap2b(p_sprites[1]);
cpc_PutMaskSpTileMap2b(p_sprites[2]);
cpc_ShowTileMap2(); //Show the touched tiles-> show the new sprite situatuion
if (cpc_CollSp(p_sprites[0],p_sprites[1])) collide(); //test if there is collision between sprite00 and sprite01
if (cpc_CollSp(p_sprites[0],p_sprites[2])) collide();
}
}

BIN
res/cpc.bios Normal file

Binary file not shown.

BIN
res/cpc.wasm Executable file

Binary file not shown.

View File

@ -791,7 +791,10 @@ export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPl
var videoFrequency;
if (hasVideo(m)) {
var vp = m.getVideoParams();
this.video = new RasterVideo(this.mainElement, vp.width, vp.height, {overscan:!!vp.overscan,rotate:vp.rotate|0});
this.video = new RasterVideo(this.mainElement, vp.width, vp.height,
{overscan: !!vp.overscan,
rotate: vp.rotate|0,
aspect: vp.aspect});
this.video.create();
m.connectVideo(this.video.getFrameData());
// TODO: support keyboard w/o video?

View File

@ -40,6 +40,7 @@ export interface VideoParams {
overscan? : boolean;
rotate? : number;
videoFrequency? : number; // default = 60
aspect? : number;
}
// TODO: frame buffer optimization (apple2, etc)

View File

@ -65,7 +65,7 @@ export function _setKeyboardEvents(canvas:HTMLElement, callback:KeyboardCallback
};
};
type VideoCanvasOptions = {rotate?:number, overscan?:boolean};
type VideoCanvasOptions = {rotate?:number, overscan?:boolean, aspect?:number};
export class RasterVideo {
@ -113,6 +113,10 @@ export class RasterVideo {
if (this.options && this.options.overscan) {
this.vcanvas.css('padding','0px');
}
if (this.options && this.options.aspect) {
console.log(this.options);
this.vcanvas.css('aspect-ratio', this.options.aspect+"");
}
this.ctx = canvas.getContext('2d');
this.imageData = this.ctx.createImageData(this.width, this.height);
this.datau32 = new Uint32Array(this.imageData.data.buffer);

View File

@ -99,7 +99,7 @@ export abstract class BaseWASMMachine {
}
async loadWASM() {
await this.fetchWASM();
this.exports.memory.grow(64); // TODO: need more when probing?
this.exports.memory.grow(96); // TODO: need more when probing?
await this.fetchBIOS();
await this.initWASM();
}

146
src/machine/cpc.ts Normal file
View File

@ -0,0 +1,146 @@
//// WASM Machine
import { KeyFlags } from "../common/emu";
import { Machine } from "../common/baseplatform";
import { TrapCondition } from "../common/devices";
import { BaseWASMMachine } from "../common/wasmplatform";
const BIN_HEADER = [
0,
0,0,0,0,0,0,0,0,
0,0,0,
0,0,0,0,0,0,
1,
0,0,
0x0, 0x40, // load addr
0,
0x0, 0x0, // length
0x0, 0x40, // start addr
0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
];
export class CPC_WASMMachine extends BaseWASMMachine implements Machine {
numTotalScanlines = 312;
cpuCyclesPerLine = 224;
joymask0 = 0;
loadROM(rom: Uint8Array) {
let runaddr = 0x4000; //0x5de9;
let combined = new Uint8Array(rom.length + BIN_HEADER.length);
combined.set(BIN_HEADER, 0);
combined[24] = rom.length & 0xff;
combined[25] = rom.length >> 8;
combined[26] = runaddr & 0xff;
combined[27] = runaddr >> 8;
combined.set(rom, BIN_HEADER.length);
super.loadROM(combined);
}
reset() {
super.reset();
// advance bios
this.exports.machine_exec(this.sys, 1000000); // TODO?
// load rom (SNA or BIN)
if (this.romptr && this.romlen) {
this.exports.machine_load_rom(this.sys, this.romptr, this.romlen);
}
}
advanceFrame(trap: TrapCondition) : number {
//var scanline = this.exports.machine_get_raster_line(this.sys);
var probing = this.probe != null;
if (probing) this.exports.machine_reset_probe_buffer();
var clocks = super.advanceFrameClock(trap, Math.floor(1000000 / 50)); // TODO: use ticks, not msec
if (probing) this.copyProbeData();
return clocks;
}
/*
z80_tick_t tick_cb; // 0
uint64_t bc_de_hl_fa; // 8
uint64_t bc_de_hl_fa_; // 16
uint64_t wz_ix_iy_sp; // 24
uint64_t im_ir_pc_bits; // 32
uint64_t pins; // 48
void* user_data;
z80_trap_t trap_cb;
void* trap_user_data;
int trap_id;
*/
getCPUState() {
this.exports.machine_save_cpu_state(this.sys, this.cpustateptr);
var s = this.cpustatearr;
var af = s[9] + (s[8]<<8); // not FA
var hl = s[10] + (s[11]<<8);
var de = s[12] + (s[13]<<8);
var bc = s[14] + (s[15]<<8);
var sp = s[24] + (s[25]<<8);
var iy = s[26] + (s[27]<<8);
var ix = s[28] + (s[29]<<8);
var pc = s[34] + (s[35]<<8);
var ir = s[36] + (s[37]<<8);
return {
PC:pc,
SP:sp,
AF:af,
BC:bc,
DE:de,
HL:hl,
IX:ix,
IY:iy,
IR:ir,
o:this.readConst(pc),
}
}
saveState() {
this.exports.machine_save_state(this.sys, this.stateptr);
return {
c:this.getCPUState(),
state:this.statearr.slice(0),
};
}
loadState(state) : void {
this.statearr.set(state.state);
this.exports.machine_load_state(this.sys, this.stateptr);
}
getVideoParams() {
return {width:768, height:272, overscan:true, videoFrequency:50, aspect:1.3};
}
setKeyInput(key: number, code: number, flags: number): void {
// TODO: handle shifted keys
if (key == 16 || key == 17 || key == 18 || key == 224) return; // meta keys
//console.log(key, code, flags);
//if (flags & KeyFlags.Shift) { key += 64; }
// convert to c64 (TODO: zx)
var mask = 0;
var mask2 = 0;
if (key == 37) { key = 0x8; mask = 0x4; } // LEFT
if (key == 38) { key = 0xb; mask = 0x1; } // UP
if (key == 39) { key = 0x9; mask = 0x8; } // RIGHT
if (key == 40) { key = 0xa; mask = 0x2; } // DOWN
if (key == 32) { mask = 0x10; } // FIRE
if (key == 65) { key = 65; mask2 = 0x4; } // LEFT
if (key == 87) { key = 87; mask2 = 0x1; } // UP
if (key == 68) { key = 68; mask2 = 0x8; } // RIGHT
if (key == 83) { key = 83; mask2 = 0x2; } // DOWN
if (key == 69) { mask2 = 0x10; } // FIRE
if (key == 113) { key = 0xf1; } // F2
if (key == 115) { key = 0xf3; } // F4
if (key == 119) { key = 0xf5; } // F8
if (key == 121) { key = 0xf7; } // F10
if (flags & KeyFlags.KeyDown) {
this.exports.machine_key_down(this.sys, key);
this.joymask0 |= mask;
} else if (flags & KeyFlags.KeyUp) {
this.exports.machine_key_up(this.sys, key);
this.joymask0 &= ~mask;
}
this.exports.cpc_joystick(this.sys, this.joymask0, 0);
}
}

View File

@ -10,6 +10,7 @@ export function importPlatform(name: string) : Promise<any> {
case "basic": return import("../platform/basic");
case "c64": return import("../platform/c64");
case "coleco": return import("../platform/coleco");
case "cpc": return import("../platform/cpc");
case "devel": return import("../platform/devel");
case "galaxian": return import("../platform/galaxian");
case "kim1": return import("../platform/kim1");

31
src/platform/cpc.ts Normal file
View File

@ -0,0 +1,31 @@
import { CPC_WASMMachine } from "../machine/cpc";
import { Platform, BaseZ80MachinePlatform } from "../common/baseplatform";
import { PLATFORMS } from "../common/emu";
const CPC_PRESETS = [
{id:'hello.asm', name:'Hello World (ASM)'},
{id:'sprite_demo.c', name:'Sprite Demo (C)'},
{id:'keyboard_redefine.c', name:'Keyboard Redefine (C)'},
];
const CPC_MEMORY_MAP = { main:[
{name:'BIOS', start:0x0000, size:0x4000, type:'rom'},
{name:'Screen RAM', start:0xc000, size:0x4000, type:'ram'},
] }
// WASM CPC platform
class CPCWASMPlatform extends BaseZ80MachinePlatform<CPC_WASMMachine> implements Platform {
newMachine() { return new CPC_WASMMachine('cpc'); }
getPresets() { return CPC_PRESETS; }
getDefaultExtension() { return ".asm"; };
readAddress(a) { return this.machine.readConst(a); }
getMemoryMap() { return CPC_MEMORY_MAP; }
showHelp() {
window.open("https://worldofspectrum.org/faq/reference/reference.htm", "_help");
}
}
PLATFORMS['cpc.464'] = CPCWASMPlatform;

View File

@ -486,7 +486,7 @@ class VCSStellaPlatform implements Platform {
gamma: 0.8,
scalingMode: this.Stellerator.ScalingMode.qis,
tvEmulation: this.Stellerator.TvEmulation.composite,
phosphorLevel: 0.5,
phosphorLevel: 0.25,
scanlineLevel: 0.2,
keyboardTarget: this.mainElement
}

View File

@ -0,0 +1,120 @@
#ifndef __cpcrslib_h__
#define __cpcrslib_h__
void cpc_SetMode( char color) __z88dk_fastcall;
void cpc_SetModo( char x) __z88dk_fastcall;
void cpc_SetColour(unsigned char num, char color) __z88dk_callee;
void cpc_SetInk(unsigned char num, unsigned char color) __z88dk_callee;
void cpc_SetBorder( char color) __z88dk_fastcall;
int cpc_GetScrAddress(char x, char y) __z88dk_callee;
void cpc_ClrScr(void);
void cpc_EnableFirmware(void);
void cpc_DisableFirmware(void);
unsigned char cpc_Random(void);
void cpc_PrintStr(char *text) __z88dk_fastcall;
void cpc_RRI(unsigned int pos, unsigned char w, unsigned char h) __z88dk_callee;
void cpc_RLI(unsigned int pos, unsigned char w, unsigned char h) __z88dk_callee;
void cpc_PutSprite(char *sprite, int posicion) __z88dk_callee;
void cpc_PutSp(char *sprite, char height, char width, int address) __z88dk_callee;
void cpc_PutSp4x14(char *sprite, int address) __z88dk_callee;
void cpc_PutSpriteXOR(char *sprite, int posicion) __z88dk_callee;
void cpc_PutSpXOR(char *sprite, char height, char width, int address) __z88dk_callee;
//void cpc_PutSpriteTr(char *sprite, int *posicion) __z88dk_callee;
void cpc_PutSpTr(char *sprite, char height, char width, int address) __z88dk_callee;
void cpc_GetSp(char *sprite, char alto, char ancho, int posicion) __z88dk_callee;
void cpc_PutMaskSprite(char *sprite,unsigned int addr) __z88dk_callee;
void cpc_PutMaskSp(char *sprite, char alto, char ancho, int posicion) __z88dk_callee;
void cpc_PutMaskSp4x16(char *sprite,unsigned int addr) __z88dk_callee;
void cpc_PutMaskSp2x8(char *sprite,unsigned int addr) __z88dk_callee;
unsigned char cpc_CollSp(char *sprite, char *sprite2) __z88dk_callee;
void cpc_PutTile2x8(char *sprite, unsigned char x, unsigned char y);
void cpc_PutTile2x8b(char *sprite, int posicion) __z88dk_callee;
void cpc_PrintGphStr(char *text, int destino) __z88dk_callee;
void cpc_PrintGphStrM1(char *text, int destino) __z88dk_callee;
void cpc_PrintGphStr2X(char *text, int destino) __z88dk_callee;
void cpc_PrintGphStrM12X(char *text, int destino) __z88dk_callee;
void cpc_PrintGphStrXY(char *text, char a, char b) __z88dk_callee;
void cpc_PrintGphStrXYM1(char *text, char a, char b) __z88dk_callee;
void cpc_PrintGphStrXY2X(char *text, char a, char b) __z88dk_callee;
void cpc_PrintGphStrXYM12X(char *text, char a, char b) __z88dk_callee;
void cpc_SetInkGphStr(char a, char b) __z88dk_callee;
void cpc_SetInkGphStrM1(char a, char b) __z88dk_callee;
void cpc_PrintGphStrStd(char color, char *cadena, int destino);
void cpc_PrintGphStrStdXY(char color, char *cadena, char x, char y);
int cpc_AnyKeyPressed(void);
void cpc_ScanKeyboard(void);
char cpc_TestKeyF(char number) __z88dk_fastcall;
void cpc_DeleteKeys(void);
void cpc_AssignKey(unsigned char tecla, int valor);
unsigned char cpc_TestKey(unsigned char tecla) __z88dk_fastcall;
void cpc_RedefineKey(unsigned char tecla) __z88dk_fastcall;
// Uncompression tools
void cpc_UnExo(char *origen, int destino) __z88dk_callee;
void cpc_Uncrunch(char *origen, int destino) __z88dk_callee;
// TILE MAP:
void cpc_InitTileMap(void);
void cpc_SetTile(unsigned char x, unsigned char y, unsigned char b);
void cpc_ShowTileMap();
void cpc_ShowTileMap2(void);
void cpc_ResetTouchedTiles(void);
void cpc_PutSpTileMap(char *sprite) __z88dk_fastcall;
void cpc_PutSpTileMapF(char *sprite);
void cpc_UpdScr(void);
void cpc_PutSpTileMap2b(char *sprite);
void cpc_PutMaskSpTileMap2b(char *sprite) __z88dk_fastcall;
void cpc_PutMaskInkSpTileMap2b(char *sprite);
void cpc_PutTrSpTileMap2b(char *sprite);
void cpc_PutTrSpriteTileMap2b(char *sprite);
void cpc_SetTouchTileXY(unsigned char x, unsigned char y, unsigned char t);
unsigned char cpc_ReadTile(unsigned char x, unsigned char y) __z88dk_callee;
//void cpc_SpUpdY(char *sprite, char valor);
//void cpc_SpUpdX(char *sprite, char valor);
// Superbufer:
void cpc_SuperbufferAddress(char *sprite);
void cpc_ScrollRight00(void);
void cpc_ScrollRight01(void);
void cpc_ScrollLeft00(void);
void cpc_ScrollLeft01(void);
// Doble buffer:
void cpc_SetSolidSprite(void);
void cpc_SetMaskedSprite(void);
void cpc_ScrollRight(char z) __z88dk_fastcall;
void cpc_ScrollLeft(char z) __z88dk_fastcall;
void cpc_ScrollUp(char z) __z88dk_fastcall;
void cpc_ScrollDown(char z) __z88dk_fastcall;
#endif /* __cpcrslib_h__ */

Binary file not shown.

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,75 @@
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 1.
Hexadecimal [16-Bits]
1 ; crt0.s for ZX Spectrum
2
3 .module crt0
4 .globl _main
5 .globl ___sdcc_call_hl
6
7 ; Ordering of segments for the linker - copied from sdcc crt0.s
8 .area _CODE
9 .area _INITIALIZER
10 .area _HOME
11 .area _GSINIT
12 .area _GSFINAL
13 .area _DATA
14 .area _INITIALIZED
15 .area _BSEG
16 .area _BSS
17 .area _HEAP
18
19 .area _CODE
20
0000 21 _Start:
0000 F3 [ 4] 22 di
0001 ED 56 [ 8] 23 im 1
24 ; stack pointer already set by BIOS
0003 CD 00 00 [17] 25 call gsinit ; Initialize global and static variables.
0006 CD 00 00 [17] 26 call _main
0009 C7 [11] 27 rst 0x0 ; Restart when main() returns.
28
29 .area _GSINIT
0000 30 gsinit::
31
32 ; Implicitly zeroed global and static variables.
0000 01 00 00 [10] 33 ld bc, #l__DATA
0003 78 [ 4] 34 ld a, b
0004 B1 [ 4] 35 or a, c
0005 28 0F [12] 36 jr Z, zeroed_data
0007 21 00 00 [10] 37 ld hl, #s__DATA
000A 36 00 [10] 38 ld (hl), #0x00
000C 0B [ 6] 39 dec bc
000D 78 [ 4] 40 ld a, b
000E B1 [ 4] 41 or a, c
000F 28 05 [12] 42 jr Z, zeroed_data
0011 5D [ 4] 43 ld e, l
0012 54 [ 4] 44 ld d, h
0013 13 [ 6] 45 inc de
0014 ED B0 [21] 46 ldir
0016 47 zeroed_data:
48
49 ; Explicitly initialized global variables.
0016 01 00 00 [10] 50 ld bc, #l__INITIALIZER
0019 78 [ 4] 51 ld a, b
001A B1 [ 4] 52 or a, c
001B 28 08 [12] 53 jr Z, gsinit_static
001D 11 00 00 [10] 54 ld de, #s__INITIALIZED
0020 21 00 00 [10] 55 ld hl, #s__INITIALIZER
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 2.
Hexadecimal [16-Bits]
0023 ED B0 [21] 56 ldir
57
0025 58 gsinit_static:
59 ; Explicitly initialized static variables inserted by compiler here.
60
61 .area _GSFINAL
0000 C9 [10] 62 ret
63
64 .area _HOME
65

View File

@ -0,0 +1,42 @@
XL2
H A areas 9 global symbols
M crt0
S l__DATA Ref0000
S _main Ref0000
S s__DATA Ref0000
S .__.ABS. Def0000
S s__INITIALIZED Ref0000
S ___sdcc_call_hl Ref0000
S l__INITIALIZER Ref0000
S s__INITIALIZER Ref0000
A _CODE size A flags 0 addr 0
A _INITIALIZER size 0 flags 0 addr 0
A _HOME size 0 flags 0 addr 0
A _GSINIT size 25 flags 0 addr 0
S gsinit Def0000
A _GSFINAL size 1 flags 0 addr 0
A _DATA size 0 flags 0 addr 0
A _INITIALIZED size 0 flags 0 addr 0
A _BSEG size 0 flags 0 addr 0
A _BSS size 0 flags 0 addr 0
A _HEAP size 0 flags 0 addr 0
T 00 00
R 00 00 00 00
T 00 00 F3 ED 56 CD 00 00 CD 00 00 C7
R 00 00 00 00 00 06 03 00 02 09 01 00
T 00 00
R 00 00 03 00
T 00 00 01 00 00 78 B1 28 0F 21 00 00 36 00 0B 78
R 00 00 03 00 02 03 00 00 02 0A 02 00
T 0E 00 B1 28 05 5D 54 13 ED B0
R 00 00 03 00
T 16 00
R 00 00 03 00
T 16 00 01 00 00 78 B1 28 08 11 00 00 21 00 00 ED
R 00 00 03 00 02 03 06 00 02 0A 04 00 02 0D 07 00
T 24 00 B0
R 00 00 03 00
T 25 00
R 00 00 03 00
T 00 00 C9
R 00 00 04 00

View File

@ -0,0 +1,65 @@
; crt0.s for ZX Spectrum
.module crt0
.globl _main
.globl ___sdcc_call_hl
; Ordering of segments for the linker - copied from sdcc crt0.s
.area _CODE
.area _INITIALIZER
.area _HOME
.area _GSINIT
.area _GSFINAL
.area _DATA
.area _INITIALIZED
.area _BSEG
.area _BSS
.area _HEAP
.area _CODE
_Start:
di
im 1
; stack pointer already set by BIOS
call gsinit ; Initialize global and static variables.
call _main
rst 0x0 ; Restart when main() returns.
.area _GSINIT
gsinit::
; Implicitly zeroed global and static variables.
ld bc, #l__DATA
ld a, b
or a, c
jr Z, zeroed_data
ld hl, #s__DATA
ld (hl), #0x00
dec bc
ld a, b
or a, c
jr Z, zeroed_data
ld e, l
ld d, h
inc de
ldir
zeroed_data:
; Explicitly initialized global variables.
ld bc, #l__INITIALIZER
ld a, b
or a, c
jr Z, gsinit_static
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
ldir
gsinit_static:
; Explicitly initialized static variables inserted by compiler here.
.area _GSFINAL
ret
.area _HOME

View File

@ -0,0 +1,27 @@
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 1.
Hexadecimal [16-Bits]
Symbol Table
.__.$$$.= 2710 L | .__.ABS.= 0000 G | .__.CPU.= 0000 L
.__.H$L.= 0000 L | 0 _Start 0000 R | ___sdcc_ **** GX
_main **** GX | 3 gsinit 0000 GR | 3 gsinit_s 0025 R
l__DATA **** GX | l__INITI **** GX | s__DATA **** GX
s__INITI **** GX | s__INITI **** GX | 3 zeroed_d 0016 R
ASxxxx Assembler V02.00 + NoICE + SDCC mods (Zilog Z80 / Hitachi HD64180), page 2.
Hexadecimal [16-Bits]
Area Table
0 _CODE size A flags 0
1 _INITIAL size 0 flags 0
2 _HOME size 0 flags 0
3 _GSINIT size 25 flags 0
4 _GSFINAL size 1 flags 0
5 _DATA size 0 flags 0
6 _INITIAL size 0 flags 0
7 _BSEG size 0 flags 0
8 _BSS size 0 flags 0
9 _HEAP size 0 flags 0

View File

@ -331,12 +331,12 @@ var PLATFORM_PARAMS = {
'zx': {
arch: 'z80',
code_start: 0x5ccb,
rom_size: 0xff58-0x5ccb,
rom_size: 0xff58-0x5ccb,
data_start: 0xf000,
data_size: 0xfe00-0xf000,
stack_end: 0xff58,
extra_link_args: ['crt0-zx.rel'],
extra_link_files: ['crt0-zx.rel', 'crt0-zx.lst'],
data_size: 0xfe00-0xf000,
stack_end: 0xff58,
extra_link_args: ['crt0-zx.rel'],
extra_link_files: ['crt0-zx.rel', 'crt0-zx.lst'],
},
'devel-6502': {
arch: '6502',
@ -344,6 +344,18 @@ var PLATFORM_PARAMS = {
libargs: ['crt0.o', 'sim6502.lib'],
extra_link_files: ['crt0.o', 'devel-6502.cfg'],
},
// https://github.com/cpcitor/cpc-dev-tool-chain
'cpc': {
arch: 'z80',
code_start: 0x4000,
rom_size: 0xb100-0x4000,
data_start: 0xb100,
data_size: 0xb100-0xc000,
stack_end: 0xc000,
extra_compile_files: ['cpcrslib.h'],
extra_link_args: ['crt0-cpc.rel', 'cpcrslib.lib'],
extra_link_files: ['crt0-cpc.rel', 'crt0-cpc.lst', 'cpcrslib.lib', 'cpcrslib.lst'],
},
};
PLATFORM_PARAMS['sms-sms-libcv'] = PLATFORM_PARAMS['sms-sg1000-libcv'];