diff --git a/c.bat b/c.bat deleted file mode 100644 index 1a2b4c5..0000000 --- a/c.bat +++ /dev/null @@ -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 - diff --git a/test.c b/demo/demo.c similarity index 67% rename from test.c rename to demo/demo.c index 5fec598..a87e6f3 100644 --- a/test.c +++ b/demo/demo.c @@ -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(); diff --git a/demo_amiga_hand.h b/demo/demo_amiga_hand.h similarity index 88% rename from demo_amiga_hand.h rename to demo/demo_amiga_hand.h index 8879575..58d79a6 100644 --- a/demo_amiga_hand.h +++ b/demo/demo_amiga_hand.h @@ -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"); } diff --git a/demo_blank.h b/demo/demo_blank.h similarity index 90% rename from demo_blank.h rename to demo/demo_blank.h index 0686bb6..70a762a 100644 --- a/demo_blank.h +++ b/demo/demo_blank.h @@ -8,5 +8,5 @@ void flip_blank() { else woz_puts("BLANK\r"); // write "blank" bit - tms_blank(blank); + tms_set_blank(blank); } diff --git a/demo_extvid.h b/demo/demo_extvid.h similarity index 56% rename from demo_extvid.h rename to demo/demo_extvid.h index 196294c..78d8f37 100644 --- a/demo_extvid.h +++ b/demo/demo_extvid.h @@ -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 } diff --git a/demo_interrupt.h b/demo/demo_interrupt.h similarity index 78% rename from demo_interrupt.h rename to demo/demo_interrupt.h index 1c7c14f..6987759 100644 --- a/demo_interrupt.h +++ b/demo/demo_interrupt.h @@ -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; } } diff --git a/demo/demo_screen1.h b/demo/demo_screen1.h new file mode 100644 index 0000000..cfe3283 --- /dev/null +++ b/demo/demo_screen1.h @@ -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(); +} + diff --git a/demo/demo_screen2.h b/demo/demo_screen2.h new file mode 100644 index 0000000..6535276 --- /dev/null +++ b/demo/demo_screen2.h @@ -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); +} diff --git a/demo/m.bat b/demo/m.bat new file mode 100644 index 0000000..02470a3 --- /dev/null +++ b/demo/m.bat @@ -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 diff --git a/apple1.h b/lib/apple1.h similarity index 80% rename from apple1.h rename to lib/apple1.h index 9f5ea7a..96291de 100644 --- a/apple1.h +++ b/lib/apple1.h @@ -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 // 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 diff --git a/font8x8.h b/lib/font8x8.h similarity index 98% rename from font8x8.h rename to lib/font8x8.h index 3697235..f2f47c2 100644 --- a/font8x8.h +++ b/lib/font8x8.h @@ -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) diff --git a/interrupt.h b/lib/interrupt.h similarity index 100% rename from interrupt.h rename to lib/interrupt.h diff --git a/tms9918.h b/lib/tms9918.h similarity index 81% rename from tms9918.h rename to lib/tms9918.h index 73c1d45..6472538 100644 --- a/tms9918.h +++ b/lib/tms9918.h @@ -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); } diff --git a/lib/tms_screen1.h b/lib/tms_screen1.h new file mode 100644 index 0000000..2471106 --- /dev/null +++ b/lib/tms_screen1.h @@ -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)); + } +} + diff --git a/tms_screen2.h b/lib/tms_screen2.h similarity index 65% rename from tms_screen2.h rename to lib/tms_screen2.h index d227791..62ddfec 100644 --- a/tms_screen2.h +++ b/lib/tms_screen2.h @@ -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= 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--)); } } */ diff --git a/utils.h b/lib/utils.h similarity index 100% rename from utils.h rename to lib/utils.h diff --git a/tetris/bindump.js b/tetris/bindump.js deleted file mode 100644 index 7fc7f95..0000000 --- a/tetris/bindump.js +++ /dev/null @@ -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=32) { + screen2_cursor_pos_x = 0; + screen2_cursor_pos_y++; + } + } +} +*/ \ No newline at end of file diff --git a/tetris/grboard.h b/tetris/grboard.h index a1de58e..609ce9f 100644 --- a/tetris/grboard.h +++ b/tetris/grboard.h @@ -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; ioffset_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 test_apple1.woz -call node bindump - -@del *.klog -@del *.vs -@del *.dbg -@del tetris.prg -@del tetris_apple1.prg diff --git a/tetris/tetris.c b/tetris/tetris.c index 7e6d314..b2baf5d 100644 --- a/tetris/tetris.c +++ b/tetris/tetris.c @@ -37,20 +37,15 @@ // TODO solve division by counter_factor -// ERASED: #include -#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(); diff --git a/tetris/types.h b/tetris/types.h deleted file mode 100644 index 48dd8a5..0000000 --- a/tetris/types.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef TYPES_H -#define TYPES_H - -// ERASED: typedef unsigned char byte; -// ERASED: typedef unsigned int word; - -#endif - - diff --git a/tms_screen1.h b/tms_screen1.h deleted file mode 100644 index a3061e2..0000000 --- a/tms_screen1.h +++ /dev/null @@ -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(); -} diff --git a/bindump.js b/tools/bindump_old.js similarity index 100% rename from bindump.js rename to tools/bindump_old.js diff --git a/hexdump.js b/tools/hexdump_old.js similarity index 100% rename from hexdump.js rename to tools/hexdump_old.js diff --git a/tools/mkeprom.js b/tools/mkeprom.js new file mode 100644 index 0000000..cbf9c5b --- /dev/null +++ b/tools/mkeprom.js @@ -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 "); + console.log(" is the directory containing 'apple1_codeseg.bin' and 'apple1_dataseg.bin'"); + console.log(" 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