diff --git a/presets/coleco/climber.c b/presets/coleco/climber.c index 277a7663..12d0cc80 100644 --- a/presets/coleco/climber.c +++ b/presets/coleco/climber.c @@ -1,4 +1,4 @@ - + #include #include #include @@ -6,10 +6,7 @@ #include "common.h" //#link "common.c" - -#ifdef CV_SMS //#link "fonts.s" -#endif #define XOFS 12 // sprite horiz. offset @@ -592,14 +589,18 @@ void play_scene() { } void setup_graphics() { +#ifndef CV_MSX cvu_memtovmemcpy(PATTERN, (void *)(font_bitmap_0 - '0'*8), 0x800); +#endif cvu_memtovmemcpy(PATTERN+8*64, char_table, sizeof(char_table)); cvu_memtovmemcpy(PATTERN+8*128, static_sprite_table, sizeof(static_sprite_table)); - + +#ifndef CV_MSX cvu_vmemset(COLOR, 0x30|BGCOL, 8); // set color for chars 0-63 cvu_vmemset(COLOR+8, 0x0|BGCOL, 32-8); // set chars 63-255 cvu_vmemset(COLOR+16, 0xb0|BGCOL, 1); // set chars 128-128+8 - +#endif + cvu_memtovmemcpy(SPRITE_PATTERNS, sprite_table, sizeof(sprite_table)); flip_sprite_patterns(SPRITE_PATTERNS + 512, (const byte*)sprite_table, sizeof(sprite_table)); flip_sprite_patterns(SPRITE_PATTERNS + 384, (const byte*)blimp_sprite_table, sizeof(blimp_sprite_table)); diff --git a/presets/msx/eliza.c b/presets/msx/eliza.c new file mode 100644 index 00000000..33b0a953 --- /dev/null +++ b/presets/msx/eliza.c @@ -0,0 +1,367 @@ +/* eliza.c + * ys + * original code by Weizenbaum, 1966 + * this rendition based on Charles Hayden's Java implementation from http://chayden.net/eliza/Eliza.html + * + * Note: There are certainly far more optimal and elegant ways to code this... we kept this + * structure to be faithful to the original. -scaz + */ + +#include +#include +#include + +#define NUMKEYWORDS 37 +#define MAXLINELEN 40 +#define NUMSWAPS 14 + +#include "msxbios.h" +//#link "msxbios.c" + + +const char *keywords[]= { + "CAN YOU","CAN I","YOU ARE","YOURE","I DONT","I FEEL", + "WHY DONT YOU","WHY CANT I","ARE YOU","I CANT","I AM","IM ", + "YOU ","I WANT","WHAT","HOW","WHO","WHERE", + "WHEN","WHY", + "NAME","CAUSE","SORRY","DREAM","HELLO","HI ","MAYBE", + " NO","YOUR","ALWAYS","THINK","ALIKE","YES","FRIEND", + "COMPUTER","CAR","NOKEYFOUND"}; + +const char *SWAPS[NUMSWAPS][2] = { + {"ARE","AM"}, + {"WERE", "WAS"}, + {"YOU","I"}, + {"YOUR", "MY"}, + {"IVE", "YOU'VE"}, + {"IM", "YOU'RE"}, + {"YOU", "ME"}, + {"ME", "YOU"}, + {"AM","ARE"}, + {"WAS", "WERE"}, + {"I","YOU"}, + {"MY", "YOUR"}, + {"YOUVE", "I'VE"}, + {"YOURE", "I'M"} +}; + +int ResponsesPerKeyword[NUMKEYWORDS]= { + 3,2,4,4,4,3, + 3,2,3,3,4,4, + 3,5,9,9,9,9, + 9,9, + 2,4,4,4,1,1,5, + 5,2,4,3,7,3,6, + 7,5,6}; + +const char *responses[NUMKEYWORDS][9] = { + { "DON'T YOU BELIEVE THAT I CAN*", + "PERHAPS YOU WOULD LIKE TO BE ABLE TO*", + "YOU WANT ME TO BE ABLE TO*"}, + { "PERHAPS YOU DON'T WANT TO*", + "DO YOU WANT TO BE ABLE TO*"}, + { "WHAT MAKES YOU THINK I AM*", + "DOES IT PLEASE YOU TO BELIEVE I AM*", + "PERHAPS YOU WOULD LIKE TO BE*", + "DO YOU SOMETIMES WISH YOU WERE*"}, + { "WHAT MAKES YOU THINK I AM*", + "DOES IT PLEASE YOU TO BELIEVE I AM*", + "PERHAPS YOU WOULD LIKE TO BE*", + "DO YOU SOMETIMES WISH YOU WERE*"}, + { "DON'T YOU REALLY*", + "WHY DON'T YOU*", + "DO YOU WISH TO BE ABLE TO*", + "DOES THAT TROUBLE YOU?"}, + { "TELL ME MORE ABOUT SUCH FEELINGS.", + "DO YOU OFTEN FEEL*", + "DO YOU ENJOY FEELING*"}, + { "DO YOU REALLY BELIEVE I DON'T*", + "PERHAPS IN GOOD TIME I WILL*", + "DO YOU WANT ME TO*"}, + { "DO YOU THINK YOU SHOULD BE ABLE TO*", + "WHY CAN'T YOU*"}, + { "WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*", + "WOULD YOU PREFER IF I WERE NOT*", + "PERHAPS IN YOUR FANTASIES I AM*"}, + { "HOW DO YOU KNOW YOU CAN'T*", + "HAVE YOU TRIED?", + "PERHAPS YOU CAN NOW*"}, + { "DID YOU COME TO ME BECAUSE YOU ARE*", + "HOW LONG HAVE YOU BEEN*", + "DO YOU BELIEVE IT IS NORMAL TO BE*", + "DO YOU ENJOY BEING*"}, + { "DID YOU COME TO ME BECAUSE YOU ARE*", + "HOW LONG HAVE YOU BEEN*", + "DO YOU BELIEVE IT IS NORMAL TO BE*", + "DO YOU ENJOY BEING*"}, + { "WE WERE DISCUSSING YOU-- NOT ME.", + "OH, I*", + "YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?"}, + { "WHAT WOULD IT MEAN TO YOU IF YOU GOT*", + "WHY DO YOU WANT*", + "SUPPOSE YOU SOON GOT*", + "WHAT IF YOU NEVER GOT*", + "I SOMETIMES ALSO WANT*"}, + { "WHY DO YOU ASK?", + "DOES THAT QUESTION INTEREST YOU?", + "WHAT ANSWER WOULD PLEASE YOU THE MOST?", + "WHAT DO YOU THINK?", + "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?", + "WHAT IS IT THAT YOU REALLY WANT TO KNOW?", + "HAVE YOU ASKED ANYONE ELSE?", + "HAVE YOU ASKED SUCH QUESTIONS BEFORE?", + "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"}, + { "WHY DO YOU ASK?", + "DOES THAT QUESTION INTEREST YOU?", + "WHAT ANSWER WOULD PLEASE YOU THE MOST?", + "WHAT DO YOU THINK?", + "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?", + "WHAT IS IT THAT YOU REALLY WANT TO KNOW?", + "HAVE YOU ASKED ANYONE ELSE?", + "HAVE YOU ASKED SUCH QUESTIONS BEFORE?", + "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"}, + { "WHY DO YOU ASK?", + "DOES THAT QUESTION INTEREST YOU?", + "WHAT ANSWER WOULD PLEASE YOU THE MOST?", + "WHAT DO YOU THINK?", + "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?", + "WHAT IS IT THAT YOU REALLY WANT TO KNOW?", + "HAVE YOU ASKED ANYONE ELSE?", + "HAVE YOU ASKED SUCH QUESTIONS BEFORE?", + "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"}, + { "WHY DO YOU ASK?", + "DOES THAT QUESTION INTEREST YOU?", + "WHAT ANSWER WOULD PLEASE YOU THE MOST?", + "WHAT DO YOU THINK?", + "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?", + "WHAT IS IT THAT YOU REALLY WANT TO KNOW?", + "HAVE YOU ASKED ANYONE ELSE?", + "HAVE YOU ASKED SUCH QUESTIONS BEFORE?", + "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"}, + { "WHY DO YOU ASK?", + "DOES THAT QUESTION INTEREST YOU?", + "WHAT ANSWER WOULD PLEASE YOU THE MOST?", + "WHAT DO YOU THINK?", + "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?", + "WHAT IS IT THAT YOU REALLY WANT TO KNOW?", + "HAVE YOU ASKED ANYONE ELSE?", + "HAVE YOU ASKED SUCH QUESTIONS BEFORE?", + "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"}, + { "WHY DO YOU ASK?", + "DOES THAT QUESTION INTEREST YOU?", + "WHAT ANSWER WOULD PLEASE YOU THE MOST?", + "WHAT DO YOU THINK?", + "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?", + "WHAT IS IT THAT YOU REALLY WANT TO KNOW?", + "HAVE YOU ASKED ANYONE ELSE?", + "HAVE YOU ASKED SUCH QUESTIONS BEFORE?", + "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?"}, + { "NAMES DON'T INTEREST ME.", + "I DON'T CARE ABOUT NAMES-- PLEASE GO ON."}, + { "IS THAT THE REAL REASON?", + "DON'T ANY OTHER REASONS COME TO MIND?", + "DOES THAT REASON EXPLAIN ANY THING ELSE?", + "WHAT OTHER REASONS MIGHT THERE BE?"}, + { "PLEASE DON'T APOLOGIZE.", + "APOLOGIES ARE NOT NECESSARY.", + "WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?", + "DON'T BE SO DEFENSIVE!"}, + { "WHAT DOES THAT DREAM SUGGEST TO YOU?", + "DO YOU DREAM OFTEN?", + "WHAT PERSONS APPEAR IN YOUR DREAMS?", + "ARE YOU DISTURBED BY YOUR DREAMS?"}, + { "HOW DO YOU DO--PLEASE STATE YOUR PROBLEM."}, + { "HOW DO YOU DO--PLEASE STATE YOUR PROBLEM."}, + { "YOU DON'T SEEM QUITE CERTAIN.", + "WHY THE UNCERTAIN TONE?", + "CAN'T YOU BE MORE POSITIVE?", + "YOU AREN'T SURE?", + "DON'T YOU KNOW?"}, + { "ARE YOU SAYING NO JUST TO BE NEGATIVE?", + "YOU ARE BEING A BIT NEGATIVE.", + "WHY NOT?", + "ARE YOU SURE?", + "WHY NO?"}, + { "WHY ARE YOU CONCERNED ABOUT MY*", + "WHAT ABOUT YOUR OWN*"}, + { "CAN YOU THINK OF A SPECIFIC EXAMPLE?", + "WHEN?", + "WHAT ARE YOU THINKING OF?", + "REALLY, ALWAYS?"}, + { "DO YOU REALLY THINK SO?", + "BUT YOU ARE NOT SURE YOU*", + "DO YOU DOUBT YOU*"}, + { "IN WHAT WAY?", + "WHAT RESEMBLANCE DO YOU SEE?", + "WHAT DOES THE SIMILARITY SUGGEST TO YOU?", + "WHAT OTHER CONNECTIONS DO YOU SEE?", + "COULD THERE REALLY BE SOME CONNECTION?", + "HOW?"}, + { "YOU SEEM QUITE POSITIVE.", + "ARE YOU SURE?", + "I SEE.", + "I UNDERSTAND."}, + { "WHY DO YOU BRING UP THE TOPIC OF FRIENDS?", + "DO YOUR FRIENDS WORRY YOU?", + "DO YOUR FRIENDS PICK ON YOU?", + "ARE YOU SURE YOU HAVE ANY FRIENDS?", + "DO YOU IMPOSE ON YOUR FRIENDS?", + "PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU?"}, + { "DO COMPUTERS WORRY YOU?", + "ARE YOU TALKING ABOUT ME IN PARTICULAR?", + "ARE YOU FRIGHTENED BY MACHINES?", + "WHY DO YOU MENTION COMPUTERS?", + "WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?", + "DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?", + "WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?"}, + { "OH, DO YOU LIKE CARS?", + "MY FAVORITE CAR IS A LAMBORGINI COUNTACH. WHAT IS YOUR FAVORITE CAR?", + "MY FAVORITE CAR COMPANY IS FERRARI. WHAT IS YOURS?", + "DO YOU LIKE PORSCHES?", + "DO YOU LIKE PORSCHE TURBO CARRERAS?"}, + { "SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?", + "WHAT DOES THAT SUGGEST TO YOU?", + "I SEE.", + "I'M NOT SURE I UNDERSTAND YOU FULLY.", + "COME, COME ELUCIDATE YOUR THOUGHTS.", + "CAN YOU ELABORATE ON THAT?", + "THAT IS QUITE INTERESTING."} + + +}; + +void print_center(const char *msg) { + int numspaces=(MAXLINELEN-strlen(msg))/2; + int i; + for(i=0;iMAXLINELEN-1) + { + printf("Exceeded Max Line Length\n"); + } + c=getchar(); + } + instr[slen]='\0'; +} + + +void main() +{ + int k,baseLength; + int whichReply[NUMKEYWORDS]; + char lastinput[MAXLINELEN]; + char reply[MAXLINELEN]; + char *baseResponse, *token; + const char separator[2]=" "; + char inputstr[MAXLINELEN]; + int x,s; + char *location; + + // use the first reply for each keyword match the first time you see that keyword + for (x=0;x"); + readline(inputstr); + printf("\n"); + + // check for termination + if (strcmp(inputstr,"BYE")==0) + break; + + // check for repeated entries + if (strcmp(lastinput,inputstr)==0) + { + printf("PLEASE DON'T REPEAT YOURSELF!\n"); + continue; + } + strncpy(lastinput,inputstr,strlen(inputstr)+1); + + // see if any of the keywords is contained in the input + // if not, we use the last element of keywords as our default responses + strcpy(reply,""); + for(k=0;k + // but skip over the keyword itself + location+=strlen(keywords[k]); + // take them one word at a time, so that we can substitute pronouns + token = strtok(location, separator); + while(token != NULL) + { + for(s=0;s= ResponsesPerKeyword[k]) + whichReply[k] = 0; + } + printf( "GOODBYE! THANKS FOR VISITING WITH ME...\n"); +} diff --git a/presets/msx/msxbios.c b/presets/msx/msxbios.c index 7330a3a8..5241ce5a 100644 --- a/presets/msx/msxbios.c +++ b/presets/msx/msxbios.c @@ -1,9 +1,24 @@ +/* +http://map.grauw.nl/resources/msxbios.php +http://map.grauw.nl/resources/msxsystemvars.php +https://www.msx.org/wiki/System_variables_and_work_area +*/ + #include "msxbios.h" #define MSXUSR_LOAD_A() __asm__("ld a,l"); #define MSXUSR_LOAD_E() __asm__("ld e,h"); #define MSXUSR_RTN_A() __asm__("ld l,a"); +#define MSXUSR_RTN_Z()\ + __asm__("ld l,#0");\ + __asm__("ret nz");\ + __asm__("inc l"); +#define MSXUSR_RTN_C()\ + __asm__("ld l,#0");\ + __asm__("ret nc");\ + __asm__("inc l"); + union { struct { @@ -29,14 +44,14 @@ void LOAD_REGS() { void RDSLT(uint8_t slot, uint16_t addr) { REGS.b.a = slot; REGS.w.hl = addr; - MSXUSR(0x000c); + MSXUSR_LOAD_REGS(0x000c); } void WRSLT(uint8_t slot, uint16_t addr, uint8_t value) { REGS.b.a = slot; REGS.w.hl = addr; REGS.b.e = value; - MSXUSR(0x0014); + MSXUSR_LOAD_REGS(0x0014); } void DISSCR() __z88dk_fastcall { @@ -54,9 +69,9 @@ void WRTVDP(uint16_t reg_data) __z88dk_fastcall { MSXUSR(0x0047); } -void RDVRM(uint16_t addr) __z88dk_fastcall { +uint8_t RDVRM(uint16_t addr) __z88dk_fastcall { addr; - MSXUSR(0x0047); + MSXUSR(0x004a); MSXUSR_RTN_A(); } @@ -160,9 +175,7 @@ uint16_t WRTPSG(uint16_t reg_data) __z88dk_fastcall { uint8_t CHSNS() __z88dk_fastcall { MSXUSR(0x009c); - __asm__("ld hl,#0"); - __asm__("ret z"); - __asm__("inc hl"); + MSXUSR_RTN_Z(); } char CHGET() __z88dk_fastcall { @@ -228,6 +241,7 @@ uint8_t GTPDL(uint8_t index) __z88dk_fastcall { MSXUSR_RTN_A(); } +/* void RIGHTC() __z88dk_fastcall { MSXUSR(0x00fc); } @@ -240,11 +254,62 @@ void UPC() __z88dk_fastcall { MSXUSR(0x0102); } +uint8_t TUPC() __z88dk_fastcall { + MSXUSR(0x0105); + MSXUSR_RTN_C(); +} + void DOWNC() __z88dk_fastcall { MSXUSR(0x0108); } -void RDVDP() __z88dk_fastcall { +uint8_t TDOWNC() __z88dk_fastcall { + MSXUSR(0x010b); + MSXUSR_RTN_C(); +} + +void SCALXY() __z88dk_fastcall { + MSXUSR(0x010e); +} +*/ + +void MAPXY() __z88dk_fastcall { + MSXUSR(0x0111); +} + +uint16_t FETCHC_ADDR() __z88dk_fastcall { + MSXUSR(0x0114); +} + +/* +void STOREC(uint16_t addr, uint8_t mask) { + REGS.w.hl = addr; + REGS.b.a = mask; + MSXUSR_LOAD_REGS(0x0117); +} + +void SETATR(uint8_t attr) __z88dk_fastcall { + attr; + MSXUSR_LOAD_A(); + MSXUSR(0x011a); +} + +uint8_t READC() __z88dk_fastcall { + MSXUSR(0x011d); + MSXUSR_RTN_A(); +} + +void SETC() __z88dk_fastcall { + MSXUSR(0x0120); +} + +void NSETCX(uint16_t fillcount) __z88dk_fastcall { + fillcount; + MSXUSR(0x0123); +} +*/ + +uint8_t RDVDP() __z88dk_fastcall { MSXUSR(0x013e); MSXUSR_RTN_A(); } @@ -263,5 +328,12 @@ void KILBUF() __z88dk_fastcall { // for stdio.h int putchar(int ch) { CHPUT(ch); + if (ch == '\n') CHPUT('\r'); // convert CR to CRLF + return ch; +} +char getchar() { + char ch = CHGET(); + putchar(ch); // echo + if (ch == '\r') ch = '\n'; return ch; } diff --git a/presets/msx/msxbios.h b/presets/msx/msxbios.h index 20e0ad40..464816bc 100644 --- a/presets/msx/msxbios.h +++ b/presets/msx/msxbios.h @@ -62,6 +62,21 @@ uint8_t __at(0xf3ea) BAKCLR; // F3EB: code for the standard border color (ini:7) uint8_t __at(0xf3eb) BDRCLR; +//Pixel lcocation +uint16_t __at(0xf92a) CLOC; +//Pixel mask +uint8_t __at(0xf92c) CMASK; +//Attribute byte for SETC +uint8_t __at(0xf3f2) ATRBYT; +//Key scan timing +uint8_t __at(0xf3f6) SCNCNT; +//Key repeat timer +uint8_t __at(0xf3f7) REPCNT; +//Address in the keyboard buffer where a character will be written +uint8_t* __at(0xf3f8) PUTPNT; +//Address in the keyboard buffer where the next character is read +uint8_t* __at(0xf3fa) GETPNT; + /// FUNCTIONS // Reads the value of an address in another slot @@ -75,7 +90,7 @@ void ENASCR() __z88dk_fastcall; // write data in the VDP-register void WRTVDP(uint16_t reg_data) __z88dk_fastcall; // Reads the content of VRAM -void RDVRM(uint16_t addr) __z88dk_fastcall; +uint8_t RDVRM(uint16_t addr) __z88dk_fastcall; // Writes data in VRAM void WRTVRM(uint16_t addr, uint8_t data); // Enable VDP to read @@ -139,11 +154,25 @@ uint8_t GTPAD(uint8_t index) __z88dk_fastcall; // Returns currenct value of paddle uint8_t GTPDL(uint8_t index) __z88dk_fastcall; +/* void RIGHTC() __z88dk_fastcall; void LEFTC() __z88dk_fastcall; void UPC() __z88dk_fastcall; +uint8_t TUPC() __z88dk_fastcall; void DOWNC() __z88dk_fastcall; -void RDVDP() __z88dk_fastcall; +uint8_t TDOWNC() __z88dk_fastcall; +void SCALXY() __z88dk_fastcall; +*/ +void MAPXY() __z88dk_fastcall; +uint16_t FETCHC_ADDR() __z88dk_fastcall; +/* +void STOREC(uint16_t addr, uint8_t mask); +void SETATR(uint8_t attr) __z88dk_fastcall; +uint8_t READC() __z88dk_fastcall; +void SETC() __z88dk_fastcall; +void NSETCX(uint16_t fillcount) __z88dk_fastcall; +*/ +uint8_t RDVDP() __z88dk_fastcall; uint8_t SNSMAT(uint8_t row) __z88dk_fastcall; void KILBUF() __z88dk_fastcall; @@ -169,7 +198,7 @@ enum MSX1_Color { }; // joystick positions for GTSTCK -enum GTSTCK_Direction { +typedef enum GTSTCK_Direction { STCK_none = 0, STCK_N, STCK_NE, @@ -182,14 +211,14 @@ enum GTSTCK_Direction { }; // parameter for GTSTCK -enum GTSTCK_Param { +typedef enum GTSTCK_Param { STCK_Cursors, STCK_Joy1, STCK_Joy2 }; // parameter for GTTRIG -enum GTTRIG_Param { +typedef enum GTTRIG_Param { TRIG_Spacebar, TRIG_Joy1_A, TRIG_Joy2_A, @@ -197,4 +226,6 @@ enum GTTRIG_Param { TRIG_Joy2_B }; +#define VSYNC() __asm__("HALT"); + #endif diff --git a/presets/msx/redbook_40col.asm b/presets/msx/redbook_40col.asm new file mode 100644 index 00000000..a5d35fe9 --- /dev/null +++ b/presets/msx/redbook_40col.asm @@ -0,0 +1,166 @@ + ORG 04000H +; LOAD 04000H +; MSX cartridge header @ 0x4000 - 0x400f + dw 0x4241 + dw Start + dw Start + dw 0,0,0,0,0 + +; ****************************** +; * BIOS STANDARD ROUTINES * +; ****************************** + +RDSLT: EQU 000CH +CNVCHR: EQU 00ABH +MAPXYC: EQU 0111H +SETC: EQU 0120H + +; ****************************** +; * WORKSPACE VARIABLES * +; ****************************** + +FORCLR: EQU 0F3E9H +ATRBYT: EQU 0F3F2H +CGPNT: EQU 0F91FH +PATWRK: EQU 0FC40H +SCRMOD: EQU 0FCAFH +GRPACX: EQU 0FCB7H +GRPACY: EQU 0FCB9H + +; ****************************** +; * CONTROL CHARACTERS * +; ****************************** + +CR: EQU 13 + +Start: +GFORTY: CP 3 ; String type? + RET NZ ; + LD A,(SCRMOD) ; Mode + CP 2 ; Graphics? + RET NZ ; + EX DE,HL ; HL->Descriptor + LD B,(HL) ; B=String len + INC HL ; + LD E,(HL) ; Address LSB + INC HL ; + LD D,(HL) ; DE->String + INC B ; +GF2: DEC B ; Finished? + RET Z ; + LD A,(DE) ; A=Chr from string + CALL GPRINT ; Print it + INC DE ; + JR GF2 ; Next chr +GPRINT: PUSH AF ; + PUSH BC ; + PUSH DE ; + PUSH HL ; + PUSH IY ; + LD BC,(GRPACX) ; BC=X coord + LD DE,(GRPACY) ; DE=Y coord + CALL GDC ; Decode chr + LD (GRPACX),BC ; New X coord + LD (GRPACY),DE ; New Y coord + POP IY ; + POP HL ; + POP DE ; + POP BC ; + POP AF ; + RET ; + +GDC: CALL CNVCHR ; Check graphic + RET NC ; NC=Header + JR NZ,GD2 ; NZ=Converted + CP CR ; Carriage Return? + JR Z,GCRLF ; + CP 20H ; Other control? + RET C ; Ignore +GD2: LD L,A ; + LD H,0 ; HL=Chr code + ADD HL,HL ; + ADD HL,HL ; + ADD HL,HL ; HL=Chr*8 + PUSH BC ; X coord + PUSH DE ; Y coord + LD DE,(CGPNT+1) ; Character set + ADD HL,DE ; HL->Pattern + LD DE,PATWRK ; DE->Buffer + LD B,8 ; Eight byte pattern +GD3: PUSH BC ; + PUSH DE ; + LD A,(CGPNT) ; Slot ID + CALL RDSLT ; Get pattern + EI ; + POP DE ; + POP BC ; + LD (DE),A ; Put in buffer + INC DE ; + INC HL ; + DJNZ GD3 ; Next + POP DE ; + POP BC ; + LD A,(FORCLR) ; Current colour + LD (ATRBYT),A ; Set ink + LD IY,PATWRK ; IY->Patterns + PUSH DE ; + LD H,8 ; Max dot rows +GD4: BIT 7,D ; Pos Y coord? + JR NZ,GD8 ; + CALL BMDROW ; Bottom most row? + JR C,GD9 ; C=Y too large + PUSH BC ; + LD L,6 ; Max dot cols + LD A,(IY+0) ; A=Pattern row +GD5: BIT 7,B ; Pos X coord + JR NZ,GD6 ; + CALL RMDCOL ; Rightmost col? + JR C,GD7 ; C=X too large + BIT 7,A ; Pattern bit + JR Z,GD6 ; Z=0 Pixel + PUSH AF ; + PUSH DE ; + PUSH HL ; + CALL MAPXYC ; Map coords + CALL SETC ; Set pixel + POP HL ; + POP DE ; + POP AF ; +GD6: RLCA ; Shift pattern + INC BC ; X=X+1 + DEC L ; Finished dot cols? + JR NZ,GD5 ; +GD7: POP BC ; Initial X coord +GD8: INC IY ; Next pattern byte + INC DE ; Y=Y+1 + DEC H ; Finished dot rows? + JR NZ,GD4 ; +GD9: POP DE ; Initial Y coord + LD HL,6 ; Step + ADD HL,BC ; X=X+6 + LD B,H ; + LD C,L ; BC=New X coord + CALL RMDCOL ; Rightmost col? + RET NC ; + +GCRLF: LD BC,0 ; X=0 + LD HL,8 ; + ADD HL,DE ; + EX DE,HL ; Y=Y+8 + RET ; + +BMDROW: PUSH HL ; + LD HL,191 ; Bottom dot row + OR A ; + SBC HL,DE ; Check Y coord + POP HL ; + RET ; C=Below screen + +RMDCOL: PUSH HL ; + LD HL,239 ; Rightmost dot col + OR A ; + SBC HL,BC ; Check X coord + POP HL ; + RET ; C=Beyond right + + END \ No newline at end of file diff --git a/presets/msx/redbook_charedit.asm b/presets/msx/redbook_charedit.asm new file mode 100644 index 00000000..5246ad56 --- /dev/null +++ b/presets/msx/redbook_charedit.asm @@ -0,0 +1,450 @@ + ORG 04000H +; LOAD 04000H +; MSX cartridge header @ 0x4000 - 0x400f + dw 0x4241 + dw Start + dw Start + dw 0,0,0,0,0 + +; ****************************** +; * BIOS STANDARD ROUTINES * +; ****************************** + +RDSLT: EQU 000CH +RDVRM: EQU 004AH +WRTVRM: EQU 004AH +FILVRM: EQU 0056H +INIGRP: EQU 0072H +CHSNS: EQU 009CH +CHGET: EQU 009FH +MAPXYC: EQU 0111H +FETCHC: EQU 0114H +RSLREG: EQU 0138H + +; ****************************** +; * WORKSPACE VARIABLES * +; ****************************** + +GRPCOL: EQU 0F3D9H +FORCLR: EQU 0F3E9H +BAKCLR: EQU 0F3EAH +CGPNT: EQU 0F91FH +EXPTBL: EQU 0FCC1H +SLTTBL: EQU 0FCC5H + +; ****************************** +; * CONTROL CHARACTERS * +; ****************************** + +CR: EQU 13 +RIGHT: EQU 28 +LEFT: EQU 29 +UP: EQU 30 +DOWN: EQU 31 + +Start: +CHEDIT: CALL INIT ; Cold start +CH1: CALL CHRMAG ; Magnify chr + CALL CHRXY ; Chr coords + LD D,8 ; Cursor size + CALL GETKEY ; Get command + CP "Q" ; Quit + RET Z ; + LD HL,CH1 ; Set up return + PUSH HL ; + CP "A" ; Adopt + JP Z,ADOPT ; + CP CR ; Edit + JR Z,EDIT ; + LD C,1 ; C=Offset + CP RIGHT ; Right + JR Z,CH2 ; + LD C,0FFH ; + CP LEFT ; Left + JR Z,CH2 ; + LD C,0F0H ; + CP UP ; Up + JR Z,CH2 ; + LD C,16 ; + CP DOWN ; Down + RET NZ ; +CH2: LD A,(CHRNUM) ; Current chr + ADD A,C ; Add offset + LD (CHRNUM),A ; New chr + RET ; + +EDIT: CALL DOTXY ; Dot coords + LD D,2 ; Cursor size + CALL GETKEY ; Get command + CP CR ; Quit + RET Z ; + LD HL,EDIT ; Set up return + PUSH HL ; + LD BC,0FE00H ; AND/OR masks + CP " " ; Space + JR Z,ED3 ; + INC C ; New OR mask + CP "." ; Dot + JR Z,ED3 ; + CP RIGHT ; Right + JR Z,ED2 ; + LD C,0FFH ; C=Offset + CP LEFT ; Left + JR Z,ED2 ; + LD C,0F8H ; + CP UP ; Up + JR Z,ED2 ; + LD C,8 ; + CP DOWN ; Down + RET NZ ; +ED2: LD A,(DOTNUM) ; Current dot + ADD A,C ; Add offset + AND 63 ; Wrap round + LD (DOTNUM),A ; New dot + RET ; +ED3: CALL PATPOS ; IY->Pattern + LD A,(DOTNUM) ; Current dot + PUSH AF ; + RRCA ; + RRCA ; + RRCA ; + AND 7 ; A=Row + LD E,A ; + LD D,0 ; DE=Row + ADD IY,DE ; IY->Row + POP AF ; + AND 7 ; A=Column + INC A ; +ED4: RRC B ; AND mask + RRC C ; OR mask + DEC A ; Count columns + JR NZ,ED4 ; + LD A,(IY+0) ; A=Pattern + AND B ; Strip old bit + OR C ; New bit + LD (IY+0),A ; New pattern + CALL CHRMAG ; Update magnified + +CHROUT: CALL PATPOS ; IY->Pattern + CALL CHRXY ; Get coords + CALL MAP ; Map + LD B,8 ; Dot rows +CO1: PUSH DE ; + PUSH HL ; + LD A,8 ; Dot cols + LD E,(IY+0) ; E=Pattern + CALL SETROW ; Set row + POP HL ; HL=CLOC + POP DE ; D=CMASK + CALL DOWNP ; Down a pixel + INC IY ; + DJNZ CO1 ; + RET ; + +CHRMAG: CALL PATPOS ; IY->Pattern + LD C,191 ; Start X + LD E,7 ; Start Y + CALL MAP ; Map + LD B,8 ; Dot rows +CM1: LD C,5 ; Row mag +CM2: PUSH BC ; + PUSH DE ; + PUSH HL ; + LD B,8 ; Dot columns + LD A,(IY+0) ; A=Pattern +CM3: RLCA ; Test bit + PUSH AF ; + SBC A,A ; 0=00H, 1=FFH + LD E,A ; E=Mag pattern + LD A,5 ; Column mag + CALL SETROW ; Set row + CALL RIGHTP ; Right a pixel + CALL RIGHTP ; Skip grid + POP AF ; + DJNZ CM3 ; + POP HL ; HL=CLOC + POP DE ; D=CMASK + POP BC ; + CALL DOWNP ; Down a pixel + DEC C ; + JR NZ,CM2 ; + CALL DOWNP ; Skip grid + INC IY ; + DJNZ CM1 ; + RET ; + +INIT: LD BC,2048 ; Size + LD DE,CHRTAB ; Destination + LD HL,(CGPNT+1) ; Source +IN1: PUSH BC ; + PUSH DE ; + LD A,(CGPNT) ; Slot ID + CALL RDSLT ; Read chr pattern + EI ; + POP DE ; + POP BC ; + LD (DE),A ; Put in buffer + INC DE ; + INC HL ; + DEC BC ; + LD A,B ; + OR C ; + JR NZ,IN1 ; + CALL INIGRP ; SCREEN 2 + LD A,(FORCLR) ; Colour 1 + RLCA ; + RLCA ; + RLCA ; + RLCA ; + LD C,A ; C=Colour 1 + LD A,(BAKCLR) ; Colour 0 + OR C ; Mix + LD BC,6144 ; Colour table size + LD HL,(GRPCOL) ; Colour table + CALL FILVRM ; Fill colours + LD HL,177*256+11 ; + LD BC,0FFH*256+10 ; + LD E,6 ; + LD A,17 ; + CALL GRID ; Draw chr grid + LD HL,49*256+6 ; + LD BC,0AAH*256+190 ; + LD E,6 ; + LD A,9 ; + CALL GRID ; Draw mag grid + LD HL,49*256+48 ; + LD BC,0FFH*256+190 ; + LD E,6 ; + LD A,2 ; + CALL GRID ; Draw mag box + XOR A ; + LD (DOTNUM),A ; Current dot + LD HL,CHRNUM ; + LD (HL),A ; Current chr +IN2: PUSH HL ; + CALL CHROUT ; Display chr + POP HL ; + INC (HL) ; Next chr + JR NZ,IN2 ; Do 256 + RET ; + +GRID: PUSH AF ; + PUSH BC ; + PUSH HL ; + CALL MAP ; Map + POP BC ; B=Len,C=Step + POP AF ; + LD E,A ; E=Pattern + POP AF ; A=Count + PUSH AF ; + PUSH DE ; + PUSH HL ; +GR1: PUSH AF ; + PUSH BC ; + PUSH DE ; + PUSH HL ; + LD A,B ; A=Len + CALL SETROW ; Horizontal line + POP HL ; HL=CLOC + POP DE ; D=CMASK +GR3: CALL DOWNP ; Down a pixel + DEC C ; Done step? + JR NZ,GR3 ; + POP BC ; + POP AF ; A=Count + DEC A ; Done lines? + JR NZ,GR1 ; + POP HL ; HL=Initial CLOC + POP DE ; D=Initial CMASK + POP AF ; A=Count +GR4: PUSH AF ; + PUSH BC ; + PUSH DE ; + PUSH HL ; +GR5: LD A,1 ; Line width + CALL SETROW ; Thin line + CALL DOWNP ; Down a pixel + DJNZ GR5 ; Vertical len + POP HL ; HL=CLOC + POP DE ; D=CMASK +GR6: CALL RIGHTP ; Right a pixel + DEC C ; Done step? + JR NZ,GR6 ; + POP BC ; + POP AF ; A=Count + DEC A ; Done lines? + JR NZ,GR4 ; + RET ; + +MAP: LD B,0 ; X MSB + LD D,B ; Y MSB + CALL MAPXYC ; Map coords + CALL FETCHC ; HL=CLOC + LD D,A ; D=CMASK + RET ; + +RIGHTP: RRC D ; Shift CMASK + RET NC ; NC=Same cell +RP1: PUSH BC ; + LD BC,8 ; Offset + ADD HL,BC ; HL=Next cell + POP BC ; + RET ; + +DOWNP: INC HL ; CLOC down + LD A,L ; + AND 7 ; Select pixel row + RET NZ ; NZ=Same cell + PUSH BC ; + LD BC,00F8H ; Offset + ADD HL,BC ; HL=Next cell + POP BC ; + RET ; + +SETROW: PUSH BC ; + LD B,A ; B=Count +SE1: CALL RDVRM ; Get old pattern +SE2: LD C,A ; C=Old + LD A,D ; A=CMASK + CPL ; AND mask + AND C ; Strip old bit + RLC E ; Shift pattern + JR NC,SE3 ; NC=0 Pixel + OR D ; Set 1 Pixel +SE3: DEC B ; Finished? + JR Z,SE4 ; + RRC D ; CMASK right + JR NC,SE2 ; NC=Same cell + CALL WRTVRM ; Update cell + CALL RP1 ; Next cell + JR SE1 ; Start again +SE4: CALL WRTVRM ; Update cell + POP BC ; + RET ; + +DOTXY: LD A,(DOTNUM) ; Current dot + PUSH AF ; + AND 7 ; Column + RLCA ; + LD C,A ; C=Col*2 + RLCA ; A=Col*4 + ADD A,C ; A=Col*6 + ADD A,191 ; Grid atart + LD C,A ; C=X coord + POP AF ; + AND 38H ; Row*8 + RRCA ; + LD E,A ; E=Row*4 + RRCA ; A=Row*2 + ADD A,E ; A=Row*6 + ADD A,7 ; Grid start + LD E,A ; E=Y coord + RET ; + +CHRXY: LD A,(CHRNUM) ; Current chr + PUSH AF ; + CALL MULT11 ; Column*11 + ADD A,12 ; Grid start + LD C,A ; C=X coord + POP AF ; + RRCA ; + RRCA ; + RRCA ; + RRCA ; + CALL MULT11 ; Row*11 + ADD A,8 ; Grid start + LD E,A ; E=Y coord + RET ; + +MULT11: AND 0FH ; + LD D,A ; D=N + RLCA ; + LD B,A ; B=N*2 + RLCA ; + RLCA ; A=N*8 + ADD A,B ; + ADD A,D ; A=N*11 + RET ; + +PATPOS: LD A,(CHRNUM) ; Current chr + LD L,A ; + LD H,0 ; HL=Chr + ADD HL,HL ; + ADD HL,HL ; + ADD HL,HL ; HL=Chr*8 + EX DE,HL ; DE=Chr*8 + LD IY,CHRTAB ; Patterns + ADD IY,DE ; IY->Pattern + RET ; + +GETKEY: LD B,0 ; Cursor flag +GE1: PUSH BC ; C=X coord + PUSH DE ; E=Y coord + CALL INVERT ; Flip cursor + POP DE ; + POP BC ; + INC B ; Flip flag + LD HL,8000 ; Blink rate +GE2: CALL CHSNS ; Check KEYBUF + JR NZ,GE3 ; NZ=Got key + DEC HL ; + LD A,H ; + OR L ; + JR NZ,GE2 ; + JR GE1 ; Time for cursor +GE3: BIT 0,B ; Cursor state + CALL NZ,INVERT ; Remove cursor + JP CHGET ; Collect character + +INVERT: PUSH DE ; + CALL MAP ; Map coords + POP AF ; A=Cursor size + LD B,A ; B=Rows + LD E,A ; E=Cols +IV1: PUSH DE ; + PUSH HL ; +IV2: CALL RDVRM ; Old pattern + XOR D ; Flip a bit + CALL WRTVRM ; Put it back + CALL RIGHTP ; Right a pixel + DEC E ; + JR NZ,IV2 ; + POP HL ; HL=CLOC + POP DE ; D=CMASK + CALL DOWNP ; Down a pixel + DJNZ IV1 ; + RET ; + +ADOPT: LD BC,2048 ; Size + LD DE,0EB80H ; Destination + LD (CGPNT+1),DE ; + LD HL,CHRTAB ; Source + LDIR ; Copy up high + CALL RSLREG ; Read PSLOT reg + RLCA ; + RLCA ; + AND 3 ; Select Page 3 + LD C,A ; + LD B,0 ; BC=Page 3 PSLOT# + LD HL,EXPTBL ; Expanders + ADD HL,BC ; + BIT 7,(HL) ; PSLOT expanded? + JR Z,AD1 ; A=Normal + LD HL,SLTTBL ; Secondary regs + ADD HL,BC ; + LD A,(HL) ; A=Secondary reg + RLCA ; + RLCA ; + RLCA ; + RLCA ; + AND 0CH ; A=Page 3 SSLOT# + OR C ; Mix Page 3 PSLOT# + SET 7,A ; A=Slot ID +AD1: LD (CGPNT),A ; + RET ; + +CHRNUM: DEFB 0 ; Current chr +DOTNUM: DEFB 0 ; Current dot +CHRTAB: DEFS 2048 ; Patterns to EAA2H + + END diff --git a/presets/msx/redbook_kbd.asm b/presets/msx/redbook_kbd.asm new file mode 100644 index 00000000..3f922587 --- /dev/null +++ b/presets/msx/redbook_kbd.asm @@ -0,0 +1,59 @@ + ORG 04000H +; LOAD 04000H +; MSX cartridge header @ 0x4000 - 0x400f + dw 0x4241 + dw Start + dw Start + dw 0,0,0,0,0 + +; ****************************** +; * BIOS STANDARD ROUTINES * +; ****************************** + +INITXT: EQU 006CH +CHPUT: EQU 00A2H +SNSMAT: EQU 0141H +BREAKX: EQU 00B7H + +; ****************************** +; * WORKSPACE VARIABLES * +; ****************************** + +INTFLG: EQU 0FC9BH + +; ****************************** +; * CONTROL CHARACTERS * +; ****************************** + +LF: EQU 10 +HOME: EQU 11 +CR: EQU 13 + +Start: +MATRIX: CALL INITXT ; SCREEN 0 +MX1: LD A,HOME ; + CALL CHPUT ; Home Cursor + XOR A ; A=KBD row +MX2: PUSH AF ; + CALL SNSMAT ; Read a row + LD B,8 ; Eight cols +MX3: RLCA ; Select col + PUSH AF ; + AND 1 ; + ADD A,"0" ; Result + CALL CHPUT ; Display col + POP AF ; + DJNZ MX3 ; + LD A,CR ; Newline + CALL CHPUT ; + LD A,LF ; + CALL CHPUT ; + POP AF ; A=KBD row + INC A ; Next row + CP 11 ; Finished? + JR NZ,MX2 ; + CALL BREAKX ; CTRL-STOP + JR NC,MX1 ; Continue + XOR A ; + LD (INTFLG),A ; Clear possible STOP + RET ; Back to BASIC \ No newline at end of file diff --git a/presets/msx/siegegame.c b/presets/msx/siegegame.c new file mode 100644 index 00000000..e7024b21 --- /dev/null +++ b/presets/msx/siegegame.c @@ -0,0 +1,256 @@ + +#include +#include +#include + +#include "msxbios.h" +//#link "msxbios.c" + +typedef uint8_t byte; +typedef uint16_t word; +typedef uint8_t bool; + +void cursorxy(byte x, byte y) { + POSIT(y+1+(x<<8)); +} +void cputcxy(byte x, byte y, char ch) { + cursorxy(x,y); + CHPUT(ch); +} +void putstring(byte x, byte y, const char* str) { + cursorxy(x,y); + while (*str) { + CHPUT(*str++); + } +} +byte getchar(byte x, byte y) { + word addr = 0x1800 | (x+1) | y*32; // TODO: use variable for base address + byte result; + result = RDVRM(addr); + //LDIRMV(&result, addr, 1); + return result; +} +void vsync() { + __asm__("HALT"); +} +void delay(int x) { + while (x--) { + vsync(); + } +} + +#define CHAR(x) (x) + +#define COLS (LINL32) +#define ROWS (LINLEN-5) + +////////// GAME DATA + +typedef struct { + byte x; + byte y; + byte dir; + word score; + char head_attr; + char tail_attr; + char collided:1; + char human:1; +} Player; + +Player players[2]; + +byte credits = 0; +byte frames_per_move; + +#define START_SPEED 12 +#define MAX_SPEED 5 +#define MAX_SCORE 7 + +/////////// + +const char BOX_CHARS[8] = { + CHAR('+'), CHAR('+'), CHAR('+'), CHAR('+'), + CHAR('-'), CHAR('-'), CHAR('!'), CHAR('!') }; + +void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) { + byte x1 = x; + cputcxy(x, y, chars[2]); + cputcxy(x2, y, chars[3]); + cputcxy(x, y2, chars[0]); + cputcxy(x2, y2, chars[1]); + while (++x < x2) { + cputcxy(x, y, chars[5]); + cputcxy(x, y2, chars[4]); + } + while (++y < y2) { + cputcxy(x1, y, chars[6]); + cputcxy(x2, y, chars[7]); + } +} + +void draw_playfield() { + draw_box(0,1,COLS-1,ROWS-1,BOX_CHARS); + putstring(0,0,"Plyr1:"); + putstring(20,0,"Plyr2:"); + cputcxy(7,0,CHAR(players[0].score+'0')); + cputcxy(27,0,CHAR(players[1].score+'0')); +} + +typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t; +const char DIR_X[4] = { 1, 0, -1, 0 }; +const char DIR_Y[4] = { 0, 1, 0, -1 }; + +void init_game() { + memset(players, 0, sizeof(players)); + players[0].head_attr = CHAR('1'); + players[1].head_attr = CHAR('2'); + players[0].tail_attr = CHAR('@'); + players[1].tail_attr = CHAR('%'); + frames_per_move = START_SPEED; +} + +void reset_players() { + players[0].x = players[0].y = 5; + players[0].dir = D_RIGHT; + players[1].x = 25; + players[1].y = 19; + players[1].dir = D_LEFT; + players[0].collided = players[1].collided = 0; +} + +void draw_player(Player* p) { + cputcxy(p->x, p->y, p->head_attr); +} + +void move_player(Player* p) { + cputcxy(p->x, p->y, p->tail_attr); + p->x += DIR_X[p->dir]; + p->y += DIR_Y[p->dir]; + if (getchar(p->x, p->y) != CHAR(' ')) + p->collided = 1; + draw_player(p); +} + +void human_control(Player* p) { + byte dir = 0xff; + byte joystick = GTSTCK(STCK_Joy1); + if (!p->human) return; + if (joystick == STCK_W) dir = D_LEFT; + if (joystick == STCK_E) dir = D_RIGHT; + if (joystick == STCK_N) dir = D_UP; + if (joystick == STCK_S) dir = D_DOWN; + // don't let the player reverse + if (dir < 0x80 && dir != (p->dir ^ 2)) { + p->dir = dir; + } +} + +byte ai_try_dir(Player* p, dir_t dir, byte shift) { + byte x,y; + dir &= 3; + x = p->x + (DIR_X[dir] << shift); + y = p->y + (DIR_Y[dir] << shift); + if (x < 29 && y < 27 && getchar(x, y) == CHAR(' ')) { + p->dir = dir; + return 1; + } else { + return 0; + } +} + +void ai_control(Player* p) { + dir_t dir; + if (p->human) return; + dir = p->dir; + if (!ai_try_dir(p, dir, 0)) { + ai_try_dir(p, dir+1, 0); + ai_try_dir(p, dir-1, 0); + } else { + ai_try_dir(p, dir-1, 0) && ai_try_dir(p, dir-1, 1+(rand() & 3)); + ai_try_dir(p, dir+1, 0) && ai_try_dir(p, dir+1, 1+(rand() & 3)); + ai_try_dir(p, dir, rand() & 3); + } +} + +byte gameover; + +void flash_colliders() { + byte i; + // flash players that collided + for (i=0; i<56; i++) { + //cv_set_frequency(CV_SOUNDCHANNEL_0, 1000+i*8); + //cv_set_attenuation(CV_SOUNDCHANNEL_0, i/2); + if (players[0].collided) players[0].head_attr ^= 0x80; + if (players[1].collided) players[1].head_attr ^= 0x80; + delay(2); + draw_player(&players[0]); + draw_player(&players[1]); + } + //cv_set_attenuation(CV_SOUNDCHANNEL_0, 28); +} + +void make_move() { + byte i; + for (i=0; i MAX_SPEED) frames_per_move--; + // game over? + if (players[0].score != players[1].score) { + if (players[0].score >= MAX_SCORE) + declare_winner(0); + else if (players[1].score >= MAX_SCORE) + declare_winner(1); + } +} + +void play_game() { + gameover = 0; + init_game(); + players[0].human = 1; + while (!gameover) { + play_round(); + } +} + +void main() { + INIT32(); + play_game(); +} diff --git a/src/platform/msx.ts b/src/platform/msx.ts index 08da37b5..ed19dbe5 100644 --- a/src/platform/msx.ts +++ b/src/platform/msx.ts @@ -15,6 +15,9 @@ import { TMS9918A } from "../video/tms9918a"; var MSX_PRESETS = [ {id:'helloworld.asm', name:'Hello World (ASM)'}, + {id:'redbook_kbd.asm', name:'Redbook Keyboard Scanner (ASM)'}, + {id:'siegegame.c', name:'Siege Game'}, + {id:'eliza.c', name:'Eliza'}, ]; var MSX_KEYCODE_MAP = makeKeycodeMap([ diff --git a/src/worker/lib/msx-libcv/cvu_graphics.h b/src/worker/lib/msx-libcv/cvu_graphics.h index 12e64928..e3f94915 100644 --- a/src/worker/lib/msx-libcv/cvu_graphics.h +++ b/src/worker/lib/msx-libcv/cvu_graphics.h @@ -86,7 +86,8 @@ inline void cvu_set_sprite(const cv_vmemp base, uint_fast8_t number, const struc // Write sprite to display memory (in mode 4). Use the location of the sprite table as base. number should be in [0, 63]. #ifdef CV_SMS -inline void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite) +// TODO: sdcc doesn't like inline here +void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite) { cvu_voutb(sprite->y, base + number); cv_set_write_vram_address(base + 0x80 + number * 2); diff --git a/src/worker/lib/sms-sg1000-libcv/cvu_graphics.h b/src/worker/lib/sms-sg1000-libcv/cvu_graphics.h index 12e64928..e3f94915 100644 --- a/src/worker/lib/sms-sg1000-libcv/cvu_graphics.h +++ b/src/worker/lib/sms-sg1000-libcv/cvu_graphics.h @@ -86,7 +86,8 @@ inline void cvu_set_sprite(const cv_vmemp base, uint_fast8_t number, const struc // Write sprite to display memory (in mode 4). Use the location of the sprite table as base. number should be in [0, 63]. #ifdef CV_SMS -inline void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite) +// TODO: sdcc doesn't like inline here +void cvu_set_sprite4(const cv_vmemp base, uint_fast8_t number, const struct cvu_sprite4 *sprite) { cvu_voutb(sprite->y, base + number); cv_set_write_vram_address(base + 0x80 + number * 2);