rename functions and modify tree file structure

This commit is contained in:
nino-porcino 2021-12-15 14:38:52 +01:00
parent 9d4bef2d64
commit 1e8e3bbcfd
34 changed files with 460 additions and 391 deletions

17
c.bat
View File

@ -1,17 +0,0 @@
@echo ======================== VIC20 ===================================================
call kickc -t VIC20_8K -D=VIC20 test.c -o test_vic20.prg -e
rem call kickc -vasmoptimize -vasmout -vcreate -vfragment -vliverange -vloop -vnonoptimize -voptimize -vparse -vsequence -vsizeinfo -vunroll -vuplift -t VIC20 -D=VIC20 test.c -o test_vic20.prg -e
copy test.prg test_vic20.prg
@echo ======================== APPLE 1 =================================================
call kickc -t asm6502 -D=APPLE1 test.c -o test_apple1.prg -e
copy test.prg test_apple1.prg
del test_apple1.klog
del test_apple1.vs
call node hexdump > test_apple1.woz
del *.klog
del *.vs
del *.dbg
del test.prg

View File

@ -1,19 +1,19 @@
// TODO make screen tables parametric (fixed values calculated by macros)
#pragma encoding(ascii) // encode strings in plain ascii
#include "../lib/utils.h"
#include "../lib/apple1.h"
#include "../lib/tms9918.h"
#include "../lib/font8x8.h"
#include "../lib/tms_screen1.h"
#include "../lib/tms_screen2.h"
#include "../lib/interrupt.h"
// #include "utils.h"
// #include "apple1.h"
// #include "tms9918.h"
// #include "font8x8.h"
// #include "tms_screen1.h"
// #include "tms_screen2.h"
// #include "interrupt.h"
// #include "demo_amiga_hand.h"
// #include "demo_interrupt.h"
// #include "demo_extvid.h"
// #include "demo_blank.h"
#include "demo_screen1.h"
#include "demo_screen2.h"
#include "demo_amiga_hand.h"
#include "demo_interrupt.h"
#include "demo_extvid.h"
#include "demo_blank.h"
void help() {
woz_puts(
@ -43,7 +43,7 @@ void main() {
else if(key == '0') break;
else woz_putc(key);
key = woz_getkey();
key = apple1_getkey();
}
woz_puts("BYE\r");
woz_mon();

View File

@ -155,15 +155,15 @@ byte amiga_data[612] = {
};
void demo_amiga_hand() {
TMS_INIT(SCREEN2_TABLE);
screen2_init_bitmap(COLOR_BYTE(COLOR_WHITE,COLOR_BLACK));
tms_init_regs(SCREEN2_TABLE);
screen2_init_bitmap(FG_BG(COLOR_BLACK,COLOR_WHITE));
SCREEN2_PUTS(0, 0, COLOR_BYTE(COLOR_BLACK,COLOR_WHITE), "*** P-LAB VIDEO CARD SYSTEM ***");
SCREEN2_PUTS(0, 2, COLOR_BYTE(COLOR_BLACK,COLOR_WHITE), "16K VRAM BYTES FREE");
SCREEN2_PUTS(0, 4, COLOR_BYTE(COLOR_BLACK,COLOR_WHITE), "READY.");
screen2_puts(0, 0, FG_BG(COLOR_BLACK,COLOR_WHITE), "*** P-LAB VIDEO CARD SYSTEM ***");
screen2_puts(0, 2, FG_BG(COLOR_BLACK,COLOR_WHITE), "16K VRAM BYTES FREE");
screen2_puts(0, 4, FG_BG(COLOR_BLACK,COLOR_WHITE), "READY.");
for(word p=0;p<612;p+=4) {
vti_line(amiga_data[p],amiga_data[p+1],amiga_data[p+2],amiga_data[p+3]);
}
SCREEN2_PUTS(18, 12, COLOR_BYTE(COLOR_DARK_BLUE, COLOR_WHITE), "APPLE1");
screen2_puts(18, 12, FG_BG(COLOR_DARK_BLUE, COLOR_WHITE), "APPLE1");
}

View File

@ -8,5 +8,5 @@ void flip_blank() {
else woz_puts("BLANK\r");
// write "blank" bit
tms_blank(blank);
tms_set_blank(blank);
}

View File

@ -8,12 +8,12 @@ void flip_external_input() {
else woz_puts("EXT INPUT OFF\r");
// fill color table with transparent color so that external input can be seen
set_vram_write_addr(SCREEN1_COLOR_TABLE);
tms_set_vram_write_addr(SCREEN1_COLOR_TABLE);
for(byte i=32;i!=0;i--) {
TMS_WRITE_DATA_PORT(COLOR_BYTE(COLOR_DARK_YELLOW, COLOR_TRANSPARENT));
TMS_WRITE_DATA_PORT(FG_BG(COLOR_DARK_YELLOW, COLOR_TRANSPARENT));
}
tms_external_video(external_input); // write "external video input" bit
set_color(0); // transparent color
tms_set_external_video(external_input); // write "external video input" bit
tms_set_color(0); // transparent color
}

View File

@ -21,18 +21,18 @@ void demo_interrupt() {
woz_puts("E EXIT TO MAIN MENU\r");
for(;;) {
if(woz_iskeypressed()) {
byte k = woz_getkey();
if(apple1_iskeypressed()) {
byte k = apple1_getkey();
if(k=='1') { tms_set_interrupt_bit(INTERRUPT_ENABLED); woz_puts("INT ENABLED\r"); }
else if(k=='0') { tms_set_interrupt_bit(INTERRUPT_DISABLED); woz_puts("INT DISABLED\r"); }
else if(k=='E') break;
}
if(last_seconds != _seconds) {
woz_put_hex(_hours); woz_putc(':');
woz_put_hex(_minutes); woz_putc(':');
woz_put_hex(_seconds); woz_putc('.');
woz_put_hex(_ticks); woz_putc('\r');
woz_print_hex(_hours); woz_putc(':');
woz_print_hex(_minutes); woz_putc(':');
woz_print_hex(_seconds); woz_putc('.');
woz_print_hex(_ticks); woz_putc('\r');
last_seconds = _seconds;
}
}

32
demo/demo_screen1.h Normal file
View File

@ -0,0 +1,32 @@
void screen1_square_sprites() {
// fills first sprite pattern with 255
tms_set_vram_write_addr(SCREEN1_SPRITE_PATTERNS); // start writing in the sprite patterns
for(byte i=0;i<8;i++) {
TMS_WRITE_DATA_PORT(255);
}
// set sprite coordinates
tms_set_vram_write_addr(SCREEN1_SPRITE_ATTRS); // start writing in the sprite attribute
for(byte i=0;i<32;i++) {
TMS_WRITE_DATA_PORT((6+i)*8); NOP; NOP; NOP; NOP; // y coordinate
TMS_WRITE_DATA_PORT((6+i)*8); NOP; NOP; NOP; NOP; // x coordinate
TMS_WRITE_DATA_PORT(0); NOP; NOP; NOP; NOP; // name
TMS_WRITE_DATA_PORT(i); NOP; NOP; NOP; NOP; // color
}
}
void prova_screen1() {
tms_init_regs(SCREEN1_TABLE);
screen1_prepare();
screen1_load_font();
screen1_home(); screen1_puts("*** P-LAB VIDEO CARD SYSTEM ***");
screen1_locate(0, 2); screen1_puts("16K VRAM BYTES FREE");
screen1_locate(0, 4); screen1_puts("READY.");
screen1_locate(0, 10);
for(word i=0;i<256;i++) screen1_putc((byte)i);
screen1_square_sprites();
}

29
demo/demo_screen2.h Normal file
View File

@ -0,0 +1,29 @@
void prova_screen2() {
tms_init_regs(SCREEN2_TABLE);
screen2_init_bitmap(FG_BG(COLOR_WHITE,COLOR_BLACK));
screen2_puts(0,0,FG_BG(COLOR_BLACK,COLOR_WHITE),"*** P-LAB VIDEO CARD SYSTEM ***");
screen2_puts(0,2,FG_BG(COLOR_BLACK,COLOR_WHITE),"16K VRAM BYTES FREE");
screen2_puts(0,4,FG_BG(COLOR_BLACK,COLOR_WHITE),"READY.");
for(byte i=0;i<16;i++) {
screen2_puts(5,(byte)(6+i),(byte)(((15-i)<<4)+i)," SCREEN 2 ");
}
vti_line(18, 45,232,187);
vti_line(18,187,232, 45);
SCREEN2_PLOT_MODE = PLOT_MODE_RESET;
vti_line(18+5, 45,232+5,187);
vti_line(18+5,187,232+5, 45);
SCREEN2_PLOT_MODE = PLOT_MODE_INVERT;
vti_line(18+5+5, 45,232+5+5,187);
vti_line(18+5+5,187,232+5+5, 45);
SCREEN2_PLOT_MODE = PLOT_MODE_SET;
//vti_ellipse_rect(7,9,202,167);
}

22
demo/m.bat Normal file
View File

@ -0,0 +1,22 @@
@rem === BUILD TETRIS ===
@SET TARGET=demo
@echo ======================== VIC20 ===================================================
call kickc -t VIC20_8K -D=VIC20 %TARGET%.c -o out\%TARGET%_vic20.prg -e
copy out\%TARGET%.prg out\%TARGET%_vic20.prg
@echo ======================== APPLE 1 =================================================
call kickc -t apple1 -D=APPLE1 %TARGET%.c -o out\%TARGET%_apple1.prg -e
@rem builds the apple1 eprom file
call node ..\tools\mkeprom out out\%TARGET%_apple1.bin
@rem clean up files
@del out\apple1_codeseg.bin
@del out\apple1_dataseg.bin
@del out\*.vs
@del out\*.klog
@del out\*.vs
@del out\*.dbg
@del out\%TARGET%.prg

View File

@ -15,7 +15,7 @@
#endif
// prints a hex byte using the WOZMON routine
void woz_put_hex(byte c) {
void woz_print_hex(byte c) {
#ifdef APPLE1
asm {
lda c
@ -53,7 +53,7 @@ void woz_mon() {
}
// returns nonzero if a key has been pressed
inline byte woz_iskeypressed() {
inline byte apple1_iskeypressed() {
#ifdef APPLE1
return PEEK(KEY_CTRL) & 0x80;
#else
@ -61,8 +61,9 @@ inline byte woz_iskeypressed() {
#endif
}
// blocking keyboard read
// reads a key from the apple-1 keyboard
byte woz_getkey() {
byte apple1_getkey() {
#ifdef APPLE1
asm {
__wait:
@ -86,7 +87,7 @@ byte woz_getkey() {
// non blocking keyboard read
// reads a key and return 0 if no key is pressed
byte woz_readkey() {
byte apple1_readkey() {
#ifdef APPLE1
if((PEEK(KEY_CTRL) & 0x80)==0) return 0;
else return PEEK(KEY_DATA) & 0x7f;
@ -104,3 +105,18 @@ byte woz_readkey() {
return key;
#endif
}
#ifdef APPLE1
#include <stdlib.h> // for memcpy
#define LOWRAM_START 0x280
#define LOWRAM_END 0x7FF
#define LOWRAM_SIZE (LOWRAM_END - LOWRAM_START + 1)
#define DATAINCODE (0x8000 - LOWRAM_SIZE)
inline void apple1_eprom_init() {
// copy the initializaton data from ROM to lowram where "Data" segment is allocated
memcpy(LOWRAM_START, DATAINCODE, LOWRAM_SIZE);
}
#endif

View File

@ -1,5 +1,7 @@
// font from LASER-500 (ASCII characters only)
#pragma data_seg(Code)
byte FONT[768] = {
0
, 0
@ -856,3 +858,5 @@ byte FONT[768] = {
, 0
, 0
};
#pragma data_seg(Data)

View File

@ -1,3 +1,5 @@
#pragma encoding(ascii) // encode strings in plain ascii
#ifdef APPLE1
const byte *VDP_DATA = 0xCC00; // TMS9918 data port (VRAM)
const byte *VDP_REG = 0xCC01; // TMS9918 register port (write) or status (read)
@ -46,7 +48,7 @@ const byte COLOR_GRAY = 0xE;
const byte COLOR_WHITE = 0xF;
// macro for combining foreground and background into a single byte value
#define COLOR_BYTE(f,b) (((f)<<4)|(b))
#define FG_BG(f,b) (((f)<<4)|(b))
// status register bits (read only)
#define FRAME_BIT(a) ((a) & 0b10000000)
@ -61,36 +63,36 @@ const byte COLOR_WHITE = 0xF;
#define TMS_READ_DATA_PORT (*VDP_DATA);
// sets the VRAM address on the TMS9918 for a write operation
void set_vram_write_addr(word addr) {
void tms_set_vram_write_addr(word addr) {
TMS_WRITE_CTRL_PORT(LOBYTE(addr));
TMS_WRITE_CTRL_PORT((HIBYTE(addr) & HIADDRESS_MASK)|WRITE_TO_VRAM);
}
// sets the VRAM address on the TMS9918 for a read operation
void set_vram_read_addr(word addr) {
void tms_set_vram_read_addr(word addr) {
TMS_WRITE_CTRL_PORT(LOBYTE(addr));
TMS_WRITE_CTRL_PORT((HIBYTE(addr) & HIADDRESS_MASK)|READ_FROM_VRAM);
}
// buffer containing the last register values, because TMS registers are write only
byte TMS_REGS_LATCH[8];
byte tms_regs_latch[8];
// writes a value to a TMS9918 register (0-7)
void TMS_WRITE_REG(byte regnum, byte val) {
void tms_write_reg(byte regnum, byte val) {
TMS_WRITE_CTRL_PORT(val);
TMS_WRITE_CTRL_PORT((regnum & REGNUM_MASK)|WRITE_TO_REG);
TMS_REGS_LATCH[regnum] = val; // save value to buffer
tms_regs_latch[regnum] = val; // save value to buffer
}
// sets border color and background for mode 0
inline void set_color(byte col) {
TMS_WRITE_REG(7, col);
inline void tms_set_color(byte col) {
tms_write_reg(7, col);
}
// initialize all registers from a table
void TMS_INIT(byte *table) {
void tms_init_regs(byte *table) {
for(byte i=0;i<8;i++) {
TMS_WRITE_REG(i, table[i]);
tms_write_reg(i, table[i]);
}
}
@ -99,24 +101,24 @@ const byte INTERRUPT_DISABLED = 0;
// sets the interrupt enable bit on register 1
void tms_set_interrupt_bit(byte val) {
byte regvalue = TMS_REGS_LATCH[1] & (~REG1_IE_MASK);
byte regvalue = tms_regs_latch[1] & (~REG1_IE_MASK);
if(val) regvalue |= REG1_IE_MASK;
TMS_WRITE_REG(1, regvalue);
tms_write_reg(1, regvalue);
}
const byte BLANK_ON = 0;
const byte BLANK_OFF = 1;
// sets the blank bit on register 1
void tms_blank(byte val) {
byte regvalue = TMS_REGS_LATCH[1] & (~REG1_BLANK_MASK);
void tms_set_blank(byte val) {
byte regvalue = tms_regs_latch[1] & (~REG1_BLANK_MASK);
if(val) regvalue |= REG1_BLANK_MASK;
TMS_WRITE_REG(1, regvalue);
tms_write_reg(1, regvalue);
}
// sets the external video input bit on register 0
void tms_external_video(byte val) {
byte regvalue = TMS_REGS_LATCH[0] & (~REG0_EXTVID_MASK);
void tms_set_external_video(byte val) {
byte regvalue = tms_regs_latch[0] & (~REG0_EXTVID_MASK);
if(val) regvalue |= REG0_EXTVID_MASK;
TMS_WRITE_REG(0, regvalue);
tms_write_reg(0, regvalue);
}

86
lib/tms_screen1.h Normal file
View File

@ -0,0 +1,86 @@
byte SCREEN1_TABLE[8] = {
0x00, 0xc0, 0x05, 0x80, 0x01, 0x20, 0x00, 0x25
};
// SCREEN 1 VALUES
// sprite patterns: $0000
// pattern table: $0800 (256*8)
// sprite attributes: $1000
// unused: $1080
// name table: $1400 (32*24)
// unused: $1800
// color table: $2000 (32)
// unused $2020-$3FFF
const word SCREEN1_PATTERN_TABLE = 0x0800;
const word SCREEN1_NAME_TABLE = 0x1400;
const word SCREEN1_COLOR_TABLE = 0x2000;
const word SCREEN1_SPRITE_PATTERNS = 0x0000;
const word SCREEN1_SPRITE_ATTRS = 0x1000;
const word SCREEN1_SIZE = (32*24);
// loads the font on the pattern table
void screen1_load_font() {
byte *source = FONT;
// start writing into VRAM from space character (32..127)
tms_set_vram_write_addr(SCREEN1_PATTERN_TABLE+(32*8));
for(word i=768;i!=0;i--) {
TMS_WRITE_DATA_PORT(*source++);
}
// reverse font (32..127)
source = FONT;
tms_set_vram_write_addr(SCREEN1_PATTERN_TABLE+((128+32)*8));
for(word i=768;i!=0;i--) {
TMS_WRITE_DATA_PORT(~(*source++));
}
}
// holds the cursor location for the putchar routine
word screen1_cursor;
// prints character to TMS (SCREEN 1 MODE)
void screen1_putc(byte c) {
tms_set_vram_write_addr(screen1_cursor++);
TMS_WRITE_DATA_PORT(c);
}
// prints a 0 terminated string to TMS (SCREEN 1 MODE)
void screen1_puts(byte *s) {
byte c;
while(c=*s++) {
screen1_putc(c);
}
}
void screen1_home() {
screen1_cursor = SCREEN1_NAME_TABLE;
}
void screen1_locate(byte x, byte y) {
screen1_cursor = SCREEN1_NAME_TABLE + ((word)y)*32 + x;
}
void screen1_prepare() {
// fills name table with spaces (32)
tms_set_vram_write_addr(SCREEN1_NAME_TABLE);
for(word i=SCREEN1_SIZE;i!=0;i--) {
TMS_WRITE_DATA_PORT(32);
}
// fill pattern table with 0
tms_set_vram_write_addr(SCREEN1_PATTERN_TABLE);
for(word i=256*8;i!=0;i--) {
TMS_WRITE_DATA_PORT(0);
}
// fill color table with black on white
tms_set_vram_write_addr(SCREEN1_COLOR_TABLE);
for(byte i=32;i!=0;i--) {
TMS_WRITE_DATA_PORT(FG_BG(COLOR_BLACK,COLOR_WHITE));
}
}

View File

@ -22,13 +22,13 @@ const word SCREEN2_SIZE = (32*24);
// prepare the screen 2 to be used as a bitmap
void screen2_init_bitmap(byte color) {
// erase the first sprite pattern
set_vram_write_addr(SCREEN2_SPRITE_PATTERNS); // start writing in the sprite patterns
tms_set_vram_write_addr(SCREEN2_SPRITE_PATTERNS); // start writing in the sprite patterns
for(byte i=0;i<8;i++) {
TMS_WRITE_DATA_PORT(0); NOP;
}
// set all sprite coordinates to 0
set_vram_write_addr(SCREEN2_SPRITE_ATTRS); // start writing in the sprite attribute
tms_set_vram_write_addr(SCREEN2_SPRITE_ATTRS); // start writing in the sprite attribute
for(byte i=0;i<32;i++) {
TMS_WRITE_DATA_PORT(0); NOP; // y coordinate
TMS_WRITE_DATA_PORT(0); NOP; // x coordinate
@ -37,38 +37,38 @@ void screen2_init_bitmap(byte color) {
}
// fill color table with black on white
set_vram_write_addr(SCREEN2_COLOR_TABLE);
tms_set_vram_write_addr(SCREEN2_COLOR_TABLE);
for(word i=768*8;i!=0;i--) {
TMS_WRITE_DATA_PORT(color);
NOP;
}
// fills name table x3 with increasing numbers
set_vram_write_addr(SCREEN2_NAME_TABLE);
tms_set_vram_write_addr(SCREEN2_NAME_TABLE);
for(word i=0;i<SCREEN2_SIZE;i++) {
TMS_WRITE_DATA_PORT(i & 0xFF);
NOP;
}
// fill pattern table with 0 (clear screen)
set_vram_write_addr(SCREEN2_PATTERN_TABLE);
tms_set_vram_write_addr(SCREEN2_PATTERN_TABLE);
for(word i=768*8;i!=0;i--) {
TMS_WRITE_DATA_PORT(0);
NOP;
}
}
void SCREEN2_PUTC(byte ch, byte x, byte y, byte col) {
void screen2_putc(byte ch, byte x, byte y, byte col) {
byte *source = &FONT[(word)(ch-32)*8];
word addr = x*8 + y*256;
set_vram_write_addr(SCREEN2_PATTERN_TABLE + addr); for(byte i=0;i<8;i++) TMS_WRITE_DATA_PORT(source[i]);
set_vram_write_addr(SCREEN2_COLOR_TABLE + addr); for(byte i=0;i<8;i++) TMS_WRITE_DATA_PORT(col);
tms_set_vram_write_addr(SCREEN2_PATTERN_TABLE + addr); for(byte i=0;i<8;i++) TMS_WRITE_DATA_PORT(source[i]);
tms_set_vram_write_addr(SCREEN2_COLOR_TABLE + addr); for(byte i=0;i<8;i++) TMS_WRITE_DATA_PORT(col);
}
void SCREEN2_PUTS(byte x, byte y, byte col, char *s) {
void screen2_puts(byte x, byte y, byte col, char *s) {
byte c;
while(c=*s++) {
SCREEN2_PUTC(c, x++, y, col);
screen2_putc(c, x++, y, col);
}
}
@ -78,13 +78,13 @@ void SCREEN2_PUTS(byte x, byte y, byte col, char *s) {
byte SCREEN2_PLOT_MODE = PLOT_MODE_SET;
void SCREEN2_PLOT(byte x, byte y) {
void screen2_plot(byte x, byte y) {
byte pow2_table_reversed[8] = { 128,64,32,16,8,4,2,1 };
word paddr = SCREEN2_PATTERN_TABLE + (word)(x & 0b11111000) + (word)(y & 0b11111000)*32 + y%8;
set_vram_read_addr(paddr);
tms_set_vram_read_addr(paddr);
byte data = TMS_READ_DATA_PORT;
byte mask = pow2_table_reversed[x%8];
set_vram_write_addr(paddr);
tms_set_vram_write_addr(paddr);
switch(SCREEN2_PLOT_MODE) {
case PLOT_MODE_RESET:
data &= ~mask;
@ -99,35 +99,6 @@ void SCREEN2_PLOT(byte x, byte y) {
TMS_WRITE_DATA_PORT(data);
}
void prova_screen2() {
TMS_INIT(SCREEN2_TABLE);
screen2_init_bitmap(COLOR_BYTE(COLOR_WHITE,COLOR_BLACK));
SCREEN2_PUTS(0,0,COLOR_BYTE(COLOR_BLACK,COLOR_WHITE),"*** P-LAB VIDEO CARD SYSTEM ***");
SCREEN2_PUTS(0,2,COLOR_BYTE(COLOR_BLACK,COLOR_WHITE),"16K VRAM BYTES FREE");
SCREEN2_PUTS(0,4,COLOR_BYTE(COLOR_BLACK,COLOR_WHITE),"READY.");
for(byte i=0;i<16;i++) {
SCREEN2_PUTS(5,(byte)(6+i),(byte)(((15-i)<<4)+i)," SCREEN 2 ");
}
vti_line(18, 45,232,187);
vti_line(18,187,232, 45);
SCREEN2_PLOT_MODE = PLOT_MODE_RESET;
vti_line(18+5, 45,232+5,187);
vti_line(18+5,187,232+5, 45);
SCREEN2_PLOT_MODE = PLOT_MODE_INVERT;
vti_line(18+5+5, 45,232+5+5,187);
vti_line(18+5+5,187,232+5+5, 45);
SCREEN2_PLOT_MODE = PLOT_MODE_SET;
//vti_ellipse_rect(7,9,202,167);
}
signed int vti_abs(signed int x) {
return x < 0 ? -x : x;
@ -150,7 +121,7 @@ void vti_line(byte _x0, byte _y0, byte _x1, byte _y1) {
signed int e2;
for(;;){ /* loop */
SCREEN2_PLOT((byte)x0, (byte)y0);
screen2_plot((byte)x0, (byte)y0);
if (x0==x1 && y0==y1) break;
e2 = err<<1;//2*err;
if (e2 >= dy) { err += dy; if(ix) ++x0; else --x0; } /* e_xy+e_x > 0 */
@ -179,20 +150,20 @@ void vti_ellipse_rect(byte _x0, byte _y0, byte _x1, byte _y1)
a *= 8*a; b1 = 8*b*b;
do {
SCREEN2_PLOT((byte) x1, (byte) y0); // I. Quadrant
SCREEN2_PLOT((byte) x0, (byte) y0); // II. Quadrant
SCREEN2_PLOT((byte) x0, (byte) y1); // III. Quadrant
SCREEN2_PLOT((byte) x1, (byte) y1); // IV. Quadrant
screen2_plot((byte) x1, (byte) y0); // I. Quadrant
screen2_plot((byte) x0, (byte) y0); // II. Quadrant
screen2_plot((byte) x0, (byte) y1); // III. Quadrant
screen2_plot((byte) x1, (byte) y1); // IV. Quadrant
e2 = 2*err;
if (e2 <= dy) { y0++; y1--; err += dy += a; } // y step
if (e2 >= dx || 2*err > dy) { x0++; x1--; err += dx += b1; } // x step
} while (x0 <= x1);
while (y0-y1 < b) { // too early stop of flat ellipses a=1
SCREEN2_PLOT((byte) x0-1, (byte) (y0)); // -> finish tip of ellipse
SCREEN2_PLOT((byte) x1+1, (byte) (y0++));
SCREEN2_PLOT((byte) x0-1, (byte) (y1));
SCREEN2_PLOT((byte) x1+1, (byte) (y1--));
screen2_plot((byte) x0-1, (byte) (y0)); // -> finish tip of ellipse
screen2_plot((byte) x1+1, (byte) (y0++));
screen2_plot((byte) x0-1, (byte) (y1));
screen2_plot((byte) x1+1, (byte) (y1--));
}
}
*/

View File

@ -1,30 +0,0 @@
/*
const fs = require('fs');
let prg = fs.readFileSync("tetris_apple1.prg");
prg = prg.slice(2);
fs.writeFileSync("tetris_apple1.bin",prg);
console.log("bin written");
*/
const fs = require('fs');
let code = fs.readFileSync("apple1_codeseg.bin");
let data = fs.readFileSync("apple1_dataseg.bin");
let mem = new Uint8Array(65536).fill(0xAA);
let code_address = 0x4000;
let data_address = 0x8000-0x7ff-0x280+1;
for(let i=0;i<code.length;i++) mem[code_address+i] = code[i];
for(let i=0;i<data.length;i++) mem[data_address+i] = data[i];
let prg = mem.slice(0x4000,0x8000);
fs.writeFileSync("tetris_apple1.bin", prg);
console.log("bin written");

87
tetris/draw.h Normal file
View File

@ -0,0 +1,87 @@
// color escape codes that can be used with "print_string"
#define BG_TRANSPARENT "\x1c\x00"
#define BG_BLACK "\x1c\x01"
#define BG_MEDIUM_GREEN "\x1c\x02"
#define BG_LIGHT_GREEN "\x1c\x03"
#define BG_DARK_BLUE "\x1c\x04"
#define BG_LIGHT_BLUE "\x1c\x05"
#define BG_DARK_RED "\x1c\x06"
#define BG_CYAN "\x1c\x07"
#define BG_MEDIUM_RED "\x1c\x08"
#define BG_LIGHT_RED "\x1c\x09"
#define BG_DARK_YELLOW "\x1c\x0A"
#define BG_LIGHT_YELLOW "\x1c\x0B"
#define BG_DARK_GREEN "\x1c\x0C"
#define BG_MAGENTA "\x1c\x0D"
#define BG_GRAY "\x1c\x0E"
#define BG_WHITE "\x1c\x0F"
#define FG_TRANSPARENT "\x1b\x00"
#define FG_BLACK "\x1b\x10"
#define FG_MEDIUM_GREEN "\x1b\x20"
#define FG_LIGHT_GREEN "\x1b\x30"
#define FG_DARK_BLUE "\x1b\x40"
#define FG_LIGHT_BLUE "\x1b\x50"
#define FG_DARK_RED "\x1b\x60"
#define FG_CYAN "\x1b\x70"
#define FG_MEDIUM_RED "\x1b\x80"
#define FG_LIGHT_RED "\x1b\x90"
#define FG_DARK_YELLOW "\x1b\xA0"
#define FG_LIGHT_YELLOW "\x1b\xB0"
#define FG_DARK_GREEN "\x1b\xC0"
#define FG_MAGENTA "\x1b\xD0"
#define FG_GRAY "\x1b\xE0"
#define FG_WHITE "\x1b\xF0"
void draw_tile(byte x, byte y, byte ch, byte col) {
byte *source = &FONTS[(word)ch*8];
word addr = x*8 + y*256;
tms_set_vram_write_addr(SCREEN2_PATTERN_TABLE + addr); for(byte i=0;i<8;i++) { TMS_WRITE_DATA_PORT(source[i]); NOP; /*NOP;*/ /*NOP; NOP;*/ /*NOP; NOP; NOP; NOP;*/ }
tms_set_vram_write_addr(SCREEN2_COLOR_TABLE + addr); for(byte i=0;i<8;i++) { TMS_WRITE_DATA_PORT(col); NOP; /*NOP;*/ /*NOP; NOP;*/ /*NOP; NOP; NOP; NOP;*/ }
}
void draw_string(byte x, byte y, byte *s, byte color) {
byte c;
while(c=*s++) {
draw_tile(x++, y, c, color);
}
}
// print string with ESC + color support
void print_string(byte x, byte y, byte *s, byte color) {
byte c;
while(c=*s++) {
if(c==0x1b) color = *s++ | (color & 0x0F);
else if(c==0x1c) color = *s++ | (color & 0xF0);
else {
draw_tile(x++, y, c, color);
}
}
}
/*
byte screen2_cursor_pos_x;
byte screen2_cursor_pos_y;
byte screen2_cursor_color;
void color(byte color) {
screen2_cursor_color = color;
}
void locate(byte x, byte y) {
screen2_cursor_pos_x = x;
screen2_cursor_pos_y = y;
}
void print_string(byte *s) {
byte c;
while(c=*s++) {
draw_tile(screen2_cursor_pos_x++, screen2_cursor_pos_y, c, screen2_cursor_color);
if(screen2_cursor_pos_x>=32) {
screen2_cursor_pos_x = 0;
screen2_cursor_pos_y++;
}
}
}
*/

View File

@ -6,9 +6,6 @@
#define BOARD_CHAR_LEFT 6
#define BOARD_CHAR_RIGHT 6
//#define NCOLS 32 /* number of screen columns */
//#define NROWS 24 /* number of screen rows, also board height */
#define CRUNCH_CHAR_1 13
#define CRUNCH_COLOR_1 FG_BG(COLOR_BLACK, COLOR_GRAY)
@ -30,14 +27,6 @@
#define NEXT_X (POS_NEXT_X+2)
#define NEXT_Y (POS_NEXT_Y+3)
void bit_fx2(int sound) {
// throw not implemented
}
void bit_fx3(int sound) {
// throw not implemented
}
void updateScore();
void drawPlayground();
void gameOver();
@ -75,13 +64,13 @@ void updateScore() {
byte color = FG_BG(COLOR_WHITE,COLOR_BLACK);
right_pad_number(score);
gr4_prints(POS_SCORE_X+1,POS_SCORE_Y+2,tmp,color);
draw_string(POS_SCORE_X+1,POS_SCORE_Y+2,tmp,color);
right_pad_number((unsigned long)total_lines);
gr4_prints(POS_LINES_X+1,POS_LINES_Y+2,tmp,color);
draw_string(POS_LINES_X+1,POS_LINES_Y+2,tmp,color);
right_pad_number((unsigned long)level);
gr4_prints(POS_LEVEL_X+1,POS_LEVEL_Y+2,tmp,color);
draw_string(POS_LEVEL_X+1,POS_LEVEL_Y+2,tmp,color);
}
#define FRAME_VERT 7
@ -95,32 +84,32 @@ void updateScore() {
void drawFrame(byte x, byte y, byte w, byte h, byte color) {
byte i;
for (i=1; i<w-1; i++) {
gr4_tile(x+i, y , FRAME_VERT, color);
gr4_tile(x+i, y+h-1, FRAME_VERT, color);
draw_tile(x+i, y , FRAME_VERT, color);
draw_tile(x+i, y+h-1, FRAME_VERT, color);
}
for (i=1; i<h-1; i++) {
gr4_tile(x , y+i, FRAME_HORIZ, color);
gr4_tile(x+w-1, y+i, FRAME_HORIZ, color);
draw_tile(x , y+i, FRAME_HORIZ, color);
draw_tile(x+w-1, y+i, FRAME_HORIZ, color);
}
gr4_tile(x ,y , FRAME_NE_CORNER, color);
gr4_tile(x+w-1 ,y , FRAME_NW_CORNER, color);
gr4_tile(x ,y+h-1, FRAME_SE_CORNER, color);
gr4_tile(x+w-1 ,y+h-1, FRAME_SW_CORNER, color);
draw_tile(x ,y , FRAME_NE_CORNER, color);
draw_tile(x+w-1 ,y , FRAME_NW_CORNER, color);
draw_tile(x ,y+h-1, FRAME_SE_CORNER, color);
draw_tile(x+w-1 ,y+h-1, FRAME_SW_CORNER, color);
}
void fillFrame(byte x, byte y, byte w, byte h, byte ch, byte color) {
byte i,j;
for (i=0; i<w; i++) {
for (j=0; j<h; j++) {
gr4_tile(x+i, y+j, ch, color);
draw_tile(x+i, y+j, ch, color);
}
}
}
// draws the board
void drawPlayground() {
set_color(COLOR_DARK_BLUE);
tms_set_color(COLOR_DARK_BLUE);
byte frame_color = FG_BG(COLOR_GRAY,COLOR_BLACK);
byte text_color = FG_BG(COLOR_LIGHT_YELLOW,COLOR_BLACK);
@ -145,11 +134,11 @@ void drawPlayground() {
drawFrame(POS_NEXT_X , POS_NEXT_Y , 8, 8, frame_color);
fillFrame(POS_NEXT_X+1 , POS_NEXT_Y+1 , 6, 6, 32, FG_BG(COLOR_BLACK, COLOR_BLACK));
gr4_prints(POS_SCORE_X+1, POS_SCORE_Y+1, "SCORE ", text_color);
gr4_prints(POS_LEVEL_X+1, POS_LEVEL_Y+1, "LEVEL ", text_color);
draw_string(POS_SCORE_X+1, POS_SCORE_Y+1, "SCORE ", text_color);
draw_string(POS_LEVEL_X+1, POS_LEVEL_Y+1, "LEVEL ", text_color);
gr4_prints(POS_LINES_X+1, POS_LINES_Y+1,"LINES ", text_color);
gr4_prints(POS_NEXT_X +1, POS_NEXT_Y +1,"NEXT" , text_color);
draw_string(POS_LINES_X+1, POS_LINES_Y+1,"LINES ", text_color);
draw_string(POS_NEXT_X +1, POS_NEXT_Y +1,"NEXT" , text_color);
}
// displays "game over" and waits for return key
@ -161,10 +150,10 @@ void gameOver() {
drawFrame(STARTBOARD_X-2, y-1,14,3, frame_color);
gr4_prints(STARTBOARD_X-1,y-0," GAME OVER ", FG_BG(COLOR_LIGHT_YELLOW,COLOR_BLACK));
draw_string(STARTBOARD_X-1,y-0," GAME OVER ", FG_BG(COLOR_LIGHT_YELLOW,COLOR_BLACK));
// sound effect
bit_fx2(7);
// ERASED: bit_fx2(7);
// since it's game over, there's no next piece
gr_erasepiece(&piece_preview);
@ -176,7 +165,7 @@ void gameOver() {
if(flip < 60 ) color = FG_BG(COLOR_LIGHT_YELLOW ,COLOR_BLACK);
else if(flip < 120 ) color = FG_BG(COLOR_DARK_BLUE ,COLOR_BLACK);
else flip = 0;
gr4_prints(STARTBOARD_X,y-0,"GAME OVER", color);
draw_string(STARTBOARD_X,y-0,"GAME OVER", color);
}
while(test_key(KEY_RETURN));
@ -202,7 +191,7 @@ void gr_erasepiece(sprite *p) {
int x = px + data->offset_x;
int y = py + data->offset_y;
data++;
gr4_tile((byte)x,(byte)y,EMPTY_GR_CHAR,EMPTY_GR_COLOR);
draw_tile((byte)x,(byte)y,EMPTY_GR_CHAR,EMPTY_GR_COLOR);
}
}
@ -233,14 +222,14 @@ void gr_drawpiece(sprite *p) {
*/
byte ch = piece_chars[piece]; //piece_chars[p->piece];
byte col = piece_colors[piece]; //piece_colors[p->piece];
gr4_tile((byte)x,(byte)y,ch,col);
draw_tile((byte)x,(byte)y,ch,col);
}
}
// fills the specified line with an empty character
void gr_crunch_line(byte line, byte crunch_char, byte crunch_color) {
for(byte i=0; i<BCOLS; i++) {
gr4_tile(STARTBOARD_X+i, STARTBOARD_Y+line, crunch_char, crunch_color);
draw_tile(STARTBOARD_X+i, STARTBOARD_Y+line, crunch_char, crunch_color);
}
}
@ -251,7 +240,7 @@ void gr_update_board() {
tile = READ_BOARD(column,line);
ch = piece_chars[tile];
col = piece_colors[tile];
gr4_tile(STARTBOARD_X+column, STARTBOARD_Y+line, ch, col);
draw_tile(STARTBOARD_X+column, STARTBOARD_Y+line, ch, col);
}
}
}

View File

@ -32,7 +32,7 @@ void drawLogo() {
if(tile) {
byte ch = piece_chars[tile];
byte col = piece_colors[tile];
gr4_tile(c,r+3,ch,col);
draw_tile(c,r+3,ch,col);
}
}
}
@ -40,23 +40,24 @@ void drawLogo() {
// introduction screen
void introScreen() {
set_color(COLOR_BLACK);
tms_set_color(COLOR_BLACK);
// simulate cls (TODO improve speed)
fillFrame(0, 0, 32, 24, 32, FG_BG(COLOR_BLACK, COLOR_BLACK));
drawLogo();
gr4_prints(3,13,"(C) 2021 ANTONINO PORCINO" , FG_BG(COLOR_LIGHT_YELLOW,COLOR_BLACK));
gr4_prints(2,18,"USE ARROWS+SPACE OR JOYSTICK", FG_BG(COLOR_WHITE ,COLOR_BLACK));
gr4_prints(5,20,"PRESS RETURN TO START" , FG_BG(COLOR_WHITE ,COLOR_BLACK));
print_string(3,13,"(C) 2021 ANTONINO PORCINO", FG_BG(COLOR_LIGHT_YELLOW,COLOR_BLACK));
print_string(7,18,"USE " BG_DARK_BLUE"I"BG_BLACK" "BG_DARK_BLUE"J"BG_BLACK" "BG_DARK_BLUE"K"BG_BLACK" "BG_DARK_BLUE"L"BG_BLACK" "BG_DARK_BLUE"SPACE"BG_BLACK , FG_BG(COLOR_WHITE ,COLOR_BLACK));
print_string(5,20,"PRESS " BG_DARK_BLUE "RETURN" BG_BLACK " TO START" , FG_BG(COLOR_WHITE ,COLOR_BLACK));
// wait for key released
while(test_key(KEY_RETURN));
// wait for key press and do the coloured animation
// wait for key press
while(!test_key(KEY_RETURN)) {
// TODO music
rand(); // extract random numbers, making rand() more "random"
}
}

View File

@ -20,7 +20,7 @@ byte test_key(byte key) {
// reads the keyboard and return the key pressed
byte read_keyboard() {
return woz_readkey();
return apple1_readkey();
}
byte player_input() {

View File

@ -1,15 +0,0 @@
void gr4_tile(byte x, byte y, byte ch, byte col) {
byte *source = &FONTS[(word)ch*8];
word addr = x*8 + y*256;
set_vram_write_addr(SCREEN2_PATTERN_TABLE + addr); for(byte i=0;i<8;i++) { TMS_WRITE_DATA_PORT(source[i]); NOP; /*NOP;*/ /*NOP; NOP;*/ /*NOP; NOP; NOP; NOP;*/ }
set_vram_write_addr(SCREEN2_COLOR_TABLE + addr); for(byte i=0;i<8;i++) { TMS_WRITE_DATA_PORT(col); NOP; /*NOP;*/ /*NOP; NOP;*/ /*NOP; NOP; NOP; NOP;*/ }
}
void gr4_prints(byte x, byte y, byte *s, byte color) {
byte c;
while(c=*s++) {
gr4_tile(x++, y, c, color);
}
}

22
tetris/m.bat Normal file
View File

@ -0,0 +1,22 @@
@rem === BUILD TETRIS ===
@SET TARGET=tetris
@echo ======================== VIC20 ===================================================
call kickc -t VIC20_8K -D=VIC20 %TARGET%.c -o out\%TARGET%_vic20.prg -e
copy out\%TARGET%.prg out\%TARGET%_vic20.prg
@echo ======================== APPLE 1 =================================================
call kickc -t apple1 -D=APPLE1 %TARGET%.c -o out\%TARGET%_apple1.prg -e
@rem builds the apple1 eprom file
call node ..\tools\mkeprom out out\%TARGET%_apple1.bin
@rem clean up files
@del out\apple1_codeseg.bin
@del out\apple1_dataseg.bin
@del out\*.vs
@del out\*.klog
@del out\*.vs
@del out\*.dbg
@del out\%TARGET%.prg

View File

@ -1,11 +0,0 @@
SET COMPILER=SDCC
@IF %COMPILER%==ZCC zcc +laser500 tetris500.c -o tetris500.bin -I..\lib500 -create-app -Cz--audio --list -m -s -DZCC
@IF %COMPILER%==SDCC zcc +laser500 tetris500.c -o tetris500.bin -I..\lib500 -create-app -Cz--audio --list -m -s -DSDCC -compiler sdcc -SO3
@copy tetris500.bin ..\..\autoload.bin
@cd ..
@cd ..
@call node makeautoload
@cd software\tetris

View File

@ -10,6 +10,8 @@ function encode(s) {
console.log(` 0b${msg.substr(msg.length-8)},`);
}
console.log("// file generated automatically by mkfont.js -- do not edit");
// char $0a.");
encode("........");
encode("........");

View File

@ -1,8 +1,6 @@
#ifndef PIECES_H
#define PIECES_H
#include "types.h"
#define NUMPIECES 7 // number of tetrominos in tetris
#define NUMTILES 4 // number of tiles in a piece
#define NUMROT 4 // number of rotations of a piece

View File

@ -9,7 +9,7 @@ typedef struct {
byte angle;
} sprite;
INLINE void sprite_copy(sprite *to, sprite *from) {
inline void sprite_copy(sprite *to, sprite *from) {
memcpy(to, from, sizeof(sprite));
}

View File

@ -1,20 +0,0 @@
@rem === BUILD TETRIS ===
@SET TARGET=tetris
@echo ======================== VIC20 ===================================================
call kickc -t VIC20_8K -D=VIC20 %TARGET%.c -o %TARGET%_vic20.prg -e
copy %TARGET%.prg %TARGET%_vic20.prg
@echo ======================== APPLE 1 =================================================
call kickc -t apple1 -D=APPLE1 %TARGET%.c -o %TARGET%_apple1.prg -e -Xassembler="-symbolfile"
copy %TARGET%.prg %TARGET%_apple1.prg
@rem call node hexdump > test_apple1.woz
call node bindump
@del *.klog
@del *.vs
@del *.dbg
@del tetris.prg
@del tetris_apple1.prg

View File

@ -37,20 +37,15 @@
// TODO solve division by counter_factor
// ERASED: #include <lib500.h>
#define INLINE inline
#define FG_BG(f,b) (((f)<<4)|(b))
#include "../utils.h"
#include "../apple1.h"
#include "../tms9918.h"
#include "../font8x8.h"
#include "../tms_screen1.h"
#include "../tms_screen2.h"
#include "../interrupt.h"
// simulate the calls made in lib500
#include "lib500_mock.h"
#include "../lib/utils.h"
#include "../lib/apple1.h"
#include "../lib/tms9918.h"
#include "../lib/font8x8.h"
#include "../lib/tms_screen1.h"
#include "../lib/tms_screen2.h"
#include "../lib/interrupt.h"
#include "draw.h"
#include "pieces.h"
#define STYLE 3
@ -378,12 +373,6 @@ void initGame() {
generate_new_piece();
}
#ifdef APPLE1
#define LOWRAM_START 0x280
#define LOWRAM_END 0x7FF
#define LOWRAM_SIZE (LOWRAM_END - LOWRAM_START + 1)
#define DATAINCODE (0x8000 - LOWRAM_SIZE)
#endif
void main() {
@ -391,13 +380,12 @@ void main() {
//install_interrupt();
#ifdef APPLE1
// copy the initializaton data from ROM to lowram where "Data" segment is allocated
memcpy(LOWRAM_START, DATAINCODE, LOWRAM_SIZE);
apple1_eprom_init();
#endif
// initialize the screen
TMS_INIT(SCREEN2_TABLE);
screen2_init_bitmap(COLOR_BYTE(COLOR_BLACK,COLOR_BLACK));
tms_init_regs(SCREEN2_TABLE);
screen2_init_bitmap(FG_BG(COLOR_BLACK,COLOR_BLACK));
while(1) {
introScreen();

View File

@ -1,9 +0,0 @@
#ifndef TYPES_H
#define TYPES_H
// ERASED: typedef unsigned char byte;
// ERASED: typedef unsigned int word;
#endif

View File

@ -1,117 +0,0 @@
byte SCREEN1_TABLE[8] = {
0x00, 0xc0, 0x05, 0x80, 0x01, 0x20, 0x00, 0x25
};
// SCREEN 1 VALUES
// sprite patterns: $0000
// pattern table: $0800 (256*8)
// sprite attributes: $1000
// unused: $1080
// name table: $1400 (32*24)
// unused: $1800
// color table: $2000 (32)
// unused $2020-$3FFF
const word SCREEN1_PATTERN_TABLE = 0x0800;
const word SCREEN1_NAME_TABLE = 0x1400;
const word SCREEN1_COLOR_TABLE = 0x2000;
const word SCREEN1_SPRITE_PATTERNS = 0x0000;
const word SCREEN1_SPRITE_ATTRS = 0x1000;
const word SCREEN1_SIZE = (32*24);
// loads the a font on the pattern table
void SCREEN1_LOAD_FONT() {
byte *source = FONT;
// start writing into VRAM from space character (32..127)
set_vram_write_addr(SCREEN1_PATTERN_TABLE+(32*8));
for(word i=768;i!=0;i--) {
TMS_WRITE_DATA_PORT(*source++);
}
// reverse font (32..127)
source = FONT;
set_vram_write_addr(SCREEN1_PATTERN_TABLE+((128+32)*8));
for(word i=768;i!=0;i--) {
TMS_WRITE_DATA_PORT(~(*source++));
}
}
// hold the cursor location for the putchar routine
word screen1_cursor;
// prints character to TMS (SCREEN 1 MODE)
void SCREEN1_PUTCHAR(byte c) {
set_vram_write_addr(screen1_cursor++);
TMS_WRITE_DATA_PORT(c);
}
// prints 0 terminated string pointed by YA
void SCREEN1_PUTS(byte *s) {
byte c;
while(c=*s++) {
SCREEN1_PUTCHAR(c);
}
}
void SCREEN1_HOME() {
screen1_cursor = SCREEN1_NAME_TABLE;
}
void SCREEN1_LOCATEXY(byte x, byte y) {
screen1_cursor = SCREEN1_NAME_TABLE + ((word)y)*32 + x;
}
void SCREEN1_FILL() {
// fills name table with spaces (32)
set_vram_write_addr(SCREEN1_NAME_TABLE);
for(word i=SCREEN1_SIZE;i!=0;i--) {
TMS_WRITE_DATA_PORT(32);
}
// fill pattern table with 0
set_vram_write_addr(SCREEN1_PATTERN_TABLE);
for(word i=256*8;i!=0;i--) {
TMS_WRITE_DATA_PORT(0);
}
// fill color table with black on white
set_vram_write_addr(SCREEN1_COLOR_TABLE);
for(byte i=32;i!=0;i--) {
TMS_WRITE_DATA_PORT(COLOR_BYTE(COLOR_BLACK,COLOR_WHITE));
}
}
void screen1_square_sprites() {
// fills first sprite pattern with 255
set_vram_write_addr(SCREEN1_SPRITE_PATTERNS); // start writing in the sprite patterns
for(byte i=0;i<8;i++) {
TMS_WRITE_DATA_PORT(255);
}
// set sprite coordinates
set_vram_write_addr(SCREEN1_SPRITE_ATTRS); // start writing in the sprite attribute
for(byte i=0;i<32;i++) {
TMS_WRITE_DATA_PORT((6+i)*8); NOP; NOP; NOP; NOP; // y coordinate
TMS_WRITE_DATA_PORT((6+i)*8); NOP; NOP; NOP; NOP; // x coordinate
TMS_WRITE_DATA_PORT(0); NOP; NOP; NOP; NOP; // name
TMS_WRITE_DATA_PORT(i); NOP; NOP; NOP; NOP; // color
}
}
void prova_screen1() {
TMS_INIT(SCREEN1_TABLE);
SCREEN1_FILL();
SCREEN1_LOAD_FONT();
SCREEN1_HOME(); SCREEN1_PUTS("*** P-LAB VIDEO CARD SYSTEM ***");
SCREEN1_LOCATEXY(0, 2); SCREEN1_PUTS("16K VRAM BYTES FREE");
SCREEN1_LOCATEXY(0, 4); SCREEN1_PUTS("READY.");
SCREEN1_LOCATEXY(0, 10);
for(word i=0;i<256;i++) SCREEN1_PUTCHAR((byte)i);
screen1_square_sprites();
}

39
tools/mkeprom.js Normal file
View File

@ -0,0 +1,39 @@
/*
const fs = require('fs');
function prg2bin(){
let prg = fs.readFileSync("tetris_apple1.prg");
prg = prg.slice(2);
fs.writeFileSync("tetris_apple1.bin",prg);
console.log("bin written");
}
*/
const fs = require('fs');
if(process.argv.length < 3) {
console.log("usage: node mkeprom.js <inputdir> <outputfile>");
console.log(" <inputdir> is the directory containing 'apple1_codeseg.bin' and 'apple1_dataseg.bin'");
console.log(" <outputfile> is outfile binary eprom file ($4000-$7FFF)");
process.exit(0);
}
let file_in = process.argv[2];
let file_out = process.argv[3];
let code = fs.readFileSync(`${file_in}/apple1_codeseg.bin`);
let data = fs.readFileSync(`${file_in}/apple1_dataseg.bin`);
let mem = new Uint8Array(65536).fill(0xAA);
let code_address = 0x4000;
let data_address = 0x8000-0x7ff-0x280+1;
for(let i=0;i<code.length;i++) mem[code_address+i] = code[i];
for(let i=0;i<data.length;i++) mem[data_address+i] = data[i];
let prg = mem.slice(0x4000,0x8000);
fs.writeFileSync(file_out, prg);
console.log(`bindump: written to ${file_out}`);