mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-10-12 21:23:37 +00:00
cpc: started investigation, cpcrslib, aspect
This commit is contained in:
parent
f2ea25d0c3
commit
8fa0389da1
31
presets/cpc/hello.asm
Normal file
31
presets/cpc/hello.asm
Normal 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
|
63
presets/cpc/keyboard_redefine.c
Normal file
63
presets/cpc/keyboard_redefine.c
Normal 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
262
presets/cpc/sprite_demo.c
Normal 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
BIN
res/cpc.bios
Normal file
Binary file not shown.
BIN
res/cpc.wasm
Executable file
BIN
res/cpc.wasm
Executable file
Binary file not shown.
@ -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?
|
||||
|
@ -40,6 +40,7 @@ export interface VideoParams {
|
||||
overscan? : boolean;
|
||||
rotate? : number;
|
||||
videoFrequency? : number; // default = 60
|
||||
aspect? : number;
|
||||
}
|
||||
|
||||
// TODO: frame buffer optimization (apple2, etc)
|
||||
|
@ -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);
|
||||
|
@ -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
146
src/machine/cpc.ts
Normal 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);
|
||||
}
|
||||
}
|
@ -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
31
src/platform/cpc.ts
Normal 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;
|
@ -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
|
||||
}
|
||||
|
120
src/worker/lib/cpc/cpcrslib.h
Normal file
120
src/worker/lib/cpc/cpcrslib.h
Normal 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__ */
|
BIN
src/worker/lib/cpc/cpcrslib.lib
Normal file
BIN
src/worker/lib/cpc/cpcrslib.lib
Normal file
Binary file not shown.
1
src/worker/lib/cpc/cpcrslib.lst
Normal file
1
src/worker/lib/cpc/cpcrslib.lst
Normal file
@ -0,0 +1 @@
|
||||
|
75
src/worker/lib/cpc/crt0-cpc.lst
Normal file
75
src/worker/lib/cpc/crt0-cpc.lst
Normal 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
|
42
src/worker/lib/cpc/crt0-cpc.rel
Normal file
42
src/worker/lib/cpc/crt0-cpc.rel
Normal 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
|
65
src/worker/lib/cpc/crt0-cpc.s
Normal file
65
src/worker/lib/cpc/crt0-cpc.s
Normal 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
|
||||
|
27
src/worker/lib/cpc/crt0-cpc.sym
Normal file
27
src/worker/lib/cpc/crt0-cpc.sym
Normal 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
|
||||
|
@ -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'];
|
||||
|
Loading…
Reference in New Issue
Block a user