mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-23 03:29:05 +00:00
cvu_set_sprite4() no more inline b/c sdcc barfs
This commit is contained in:
parent
151bc19e23
commit
a216997bd6
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <cv.h>
|
#include <cv.h>
|
||||||
@ -6,10 +6,7 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
//#link "common.c"
|
//#link "common.c"
|
||||||
|
|
||||||
#ifdef CV_SMS
|
|
||||||
//#link "fonts.s"
|
//#link "fonts.s"
|
||||||
#endif
|
|
||||||
|
|
||||||
#define XOFS 12 // sprite horiz. offset
|
#define XOFS 12 // sprite horiz. offset
|
||||||
|
|
||||||
@ -592,13 +589,17 @@ void play_scene() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setup_graphics() {
|
void setup_graphics() {
|
||||||
|
#ifndef CV_MSX
|
||||||
cvu_memtovmemcpy(PATTERN, (void *)(font_bitmap_0 - '0'*8), 0x800);
|
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*64, char_table, sizeof(char_table));
|
||||||
cvu_memtovmemcpy(PATTERN+8*128, static_sprite_table, sizeof(static_sprite_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, 0x30|BGCOL, 8); // set color for chars 0-63
|
||||||
cvu_vmemset(COLOR+8, 0x0|BGCOL, 32-8); // set chars 63-255
|
cvu_vmemset(COLOR+8, 0x0|BGCOL, 32-8); // set chars 63-255
|
||||||
cvu_vmemset(COLOR+16, 0xb0|BGCOL, 1); // set chars 128-128+8
|
cvu_vmemset(COLOR+16, 0xb0|BGCOL, 1); // set chars 128-128+8
|
||||||
|
#endif
|
||||||
|
|
||||||
cvu_memtovmemcpy(SPRITE_PATTERNS, sprite_table, sizeof(sprite_table));
|
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 + 512, (const byte*)sprite_table, sizeof(sprite_table));
|
||||||
|
367
presets/msx/eliza.c
Normal file
367
presets/msx/eliza.c
Normal file
@ -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 <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;i<numspaces;i++)
|
||||||
|
printf(" ");
|
||||||
|
printf("%s\n", msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_title () {
|
||||||
|
printf("\n\n");
|
||||||
|
print_center("*** ELIZA ***");
|
||||||
|
print_center("Original code by Weizenbaum, 1966");
|
||||||
|
print_center("To stop Eliza, type 'bye'");
|
||||||
|
printf("\n\n");
|
||||||
|
printf("HI! I'M ELIZA. WHAT'S YOUR PROBLEM?\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void readline(char *instr) {
|
||||||
|
char c;
|
||||||
|
int slen=0;
|
||||||
|
|
||||||
|
c=getchar();
|
||||||
|
while (c != '\n')
|
||||||
|
{
|
||||||
|
// removes punctuation and sets to uppercase
|
||||||
|
if(isalpha(c) || isspace(c))
|
||||||
|
instr[slen++]=toupper(c);
|
||||||
|
if(slen>MAXLINELEN-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<NUMKEYWORDS; x++) {
|
||||||
|
whichReply[x] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print a nice centered title screen
|
||||||
|
INITXT();
|
||||||
|
SCNCNT = 1; // set keyboard scan counter
|
||||||
|
print_title();
|
||||||
|
|
||||||
|
lastinput[0]='\0';
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
printf(">");
|
||||||
|
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<NUMKEYWORDS-1;k++)
|
||||||
|
{
|
||||||
|
location=strstr(inputstr, keywords[k]);
|
||||||
|
if(location != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build Eliza's response
|
||||||
|
// start with Eliza's canned response, based on the keyword match
|
||||||
|
baseResponse = (char *) responses[k][whichReply[k]];
|
||||||
|
baseLength = strlen(baseResponse);
|
||||||
|
|
||||||
|
if(baseResponse[baseLength-1] != '*')
|
||||||
|
{
|
||||||
|
// if we have a baseResponse without an asterix, just use it as-is
|
||||||
|
strcat(reply, baseResponse);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if we do have an asterix, fill in the remaining with the user input
|
||||||
|
// use all but the last character of the base response
|
||||||
|
strncat(reply, baseResponse, baseLength-1);
|
||||||
|
|
||||||
|
// now add in the rest of the user's input, starting at <location>
|
||||||
|
// 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<NUMSWAPS;s++)
|
||||||
|
{
|
||||||
|
if(strcmp(SWAPS[s][0], token) == 0)
|
||||||
|
{
|
||||||
|
token = (char *) SWAPS[s][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(reply," ");
|
||||||
|
strcat(reply, token);
|
||||||
|
token=strtok(NULL, separator);
|
||||||
|
};
|
||||||
|
strcat(reply, "?");
|
||||||
|
}
|
||||||
|
printf("%s\n", reply);
|
||||||
|
|
||||||
|
// next time, use the next appropriate reply for that keyword
|
||||||
|
whichReply[k]++;
|
||||||
|
if ( whichReply[k] >= ResponsesPerKeyword[k])
|
||||||
|
whichReply[k] = 0;
|
||||||
|
}
|
||||||
|
printf( "GOODBYE! THANKS FOR VISITING WITH ME...\n");
|
||||||
|
}
|
@ -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"
|
#include "msxbios.h"
|
||||||
|
|
||||||
#define MSXUSR_LOAD_A() __asm__("ld a,l");
|
#define MSXUSR_LOAD_A() __asm__("ld a,l");
|
||||||
#define MSXUSR_LOAD_E() __asm__("ld e,h");
|
#define MSXUSR_LOAD_E() __asm__("ld e,h");
|
||||||
#define MSXUSR_RTN_A() __asm__("ld l,a");
|
#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 {
|
union {
|
||||||
struct {
|
struct {
|
||||||
@ -29,14 +44,14 @@ void LOAD_REGS() {
|
|||||||
void RDSLT(uint8_t slot, uint16_t addr) {
|
void RDSLT(uint8_t slot, uint16_t addr) {
|
||||||
REGS.b.a = slot;
|
REGS.b.a = slot;
|
||||||
REGS.w.hl = addr;
|
REGS.w.hl = addr;
|
||||||
MSXUSR(0x000c);
|
MSXUSR_LOAD_REGS(0x000c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WRSLT(uint8_t slot, uint16_t addr, uint8_t value) {
|
void WRSLT(uint8_t slot, uint16_t addr, uint8_t value) {
|
||||||
REGS.b.a = slot;
|
REGS.b.a = slot;
|
||||||
REGS.w.hl = addr;
|
REGS.w.hl = addr;
|
||||||
REGS.b.e = value;
|
REGS.b.e = value;
|
||||||
MSXUSR(0x0014);
|
MSXUSR_LOAD_REGS(0x0014);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DISSCR() __z88dk_fastcall {
|
void DISSCR() __z88dk_fastcall {
|
||||||
@ -54,9 +69,9 @@ void WRTVDP(uint16_t reg_data) __z88dk_fastcall {
|
|||||||
MSXUSR(0x0047);
|
MSXUSR(0x0047);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RDVRM(uint16_t addr) __z88dk_fastcall {
|
uint8_t RDVRM(uint16_t addr) __z88dk_fastcall {
|
||||||
addr;
|
addr;
|
||||||
MSXUSR(0x0047);
|
MSXUSR(0x004a);
|
||||||
MSXUSR_RTN_A();
|
MSXUSR_RTN_A();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,9 +175,7 @@ uint16_t WRTPSG(uint16_t reg_data) __z88dk_fastcall {
|
|||||||
|
|
||||||
uint8_t CHSNS() __z88dk_fastcall {
|
uint8_t CHSNS() __z88dk_fastcall {
|
||||||
MSXUSR(0x009c);
|
MSXUSR(0x009c);
|
||||||
__asm__("ld hl,#0");
|
MSXUSR_RTN_Z();
|
||||||
__asm__("ret z");
|
|
||||||
__asm__("inc hl");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char CHGET() __z88dk_fastcall {
|
char CHGET() __z88dk_fastcall {
|
||||||
@ -228,6 +241,7 @@ uint8_t GTPDL(uint8_t index) __z88dk_fastcall {
|
|||||||
MSXUSR_RTN_A();
|
MSXUSR_RTN_A();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void RIGHTC() __z88dk_fastcall {
|
void RIGHTC() __z88dk_fastcall {
|
||||||
MSXUSR(0x00fc);
|
MSXUSR(0x00fc);
|
||||||
}
|
}
|
||||||
@ -240,11 +254,62 @@ void UPC() __z88dk_fastcall {
|
|||||||
MSXUSR(0x0102);
|
MSXUSR(0x0102);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t TUPC() __z88dk_fastcall {
|
||||||
|
MSXUSR(0x0105);
|
||||||
|
MSXUSR_RTN_C();
|
||||||
|
}
|
||||||
|
|
||||||
void DOWNC() __z88dk_fastcall {
|
void DOWNC() __z88dk_fastcall {
|
||||||
MSXUSR(0x0108);
|
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(0x013e);
|
||||||
MSXUSR_RTN_A();
|
MSXUSR_RTN_A();
|
||||||
}
|
}
|
||||||
@ -263,5 +328,12 @@ void KILBUF() __z88dk_fastcall {
|
|||||||
// for stdio.h
|
// for stdio.h
|
||||||
int putchar(int ch) {
|
int putchar(int ch) {
|
||||||
CHPUT(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;
|
return ch;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,21 @@ uint8_t __at(0xf3ea) BAKCLR;
|
|||||||
// F3EB: code for the standard border color (ini:7)
|
// F3EB: code for the standard border color (ini:7)
|
||||||
uint8_t __at(0xf3eb) BDRCLR;
|
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
|
/// FUNCTIONS
|
||||||
|
|
||||||
// Reads the value of an address in another slot
|
// Reads the value of an address in another slot
|
||||||
@ -75,7 +90,7 @@ void ENASCR() __z88dk_fastcall;
|
|||||||
// write data in the VDP-register
|
// write data in the VDP-register
|
||||||
void WRTVDP(uint16_t reg_data) __z88dk_fastcall;
|
void WRTVDP(uint16_t reg_data) __z88dk_fastcall;
|
||||||
// Reads the content of VRAM
|
// Reads the content of VRAM
|
||||||
void RDVRM(uint16_t addr) __z88dk_fastcall;
|
uint8_t RDVRM(uint16_t addr) __z88dk_fastcall;
|
||||||
// Writes data in VRAM
|
// Writes data in VRAM
|
||||||
void WRTVRM(uint16_t addr, uint8_t data);
|
void WRTVRM(uint16_t addr, uint8_t data);
|
||||||
// Enable VDP to read
|
// Enable VDP to read
|
||||||
@ -139,11 +154,25 @@ uint8_t GTPAD(uint8_t index) __z88dk_fastcall;
|
|||||||
// Returns currenct value of paddle
|
// Returns currenct value of paddle
|
||||||
uint8_t GTPDL(uint8_t index) __z88dk_fastcall;
|
uint8_t GTPDL(uint8_t index) __z88dk_fastcall;
|
||||||
|
|
||||||
|
/*
|
||||||
void RIGHTC() __z88dk_fastcall;
|
void RIGHTC() __z88dk_fastcall;
|
||||||
void LEFTC() __z88dk_fastcall;
|
void LEFTC() __z88dk_fastcall;
|
||||||
void UPC() __z88dk_fastcall;
|
void UPC() __z88dk_fastcall;
|
||||||
|
uint8_t TUPC() __z88dk_fastcall;
|
||||||
void DOWNC() __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;
|
uint8_t SNSMAT(uint8_t row) __z88dk_fastcall;
|
||||||
void KILBUF() __z88dk_fastcall;
|
void KILBUF() __z88dk_fastcall;
|
||||||
|
|
||||||
@ -169,7 +198,7 @@ enum MSX1_Color {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// joystick positions for GTSTCK
|
// joystick positions for GTSTCK
|
||||||
enum GTSTCK_Direction {
|
typedef enum GTSTCK_Direction {
|
||||||
STCK_none = 0,
|
STCK_none = 0,
|
||||||
STCK_N,
|
STCK_N,
|
||||||
STCK_NE,
|
STCK_NE,
|
||||||
@ -182,14 +211,14 @@ enum GTSTCK_Direction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// parameter for GTSTCK
|
// parameter for GTSTCK
|
||||||
enum GTSTCK_Param {
|
typedef enum GTSTCK_Param {
|
||||||
STCK_Cursors,
|
STCK_Cursors,
|
||||||
STCK_Joy1,
|
STCK_Joy1,
|
||||||
STCK_Joy2
|
STCK_Joy2
|
||||||
};
|
};
|
||||||
|
|
||||||
// parameter for GTTRIG
|
// parameter for GTTRIG
|
||||||
enum GTTRIG_Param {
|
typedef enum GTTRIG_Param {
|
||||||
TRIG_Spacebar,
|
TRIG_Spacebar,
|
||||||
TRIG_Joy1_A,
|
TRIG_Joy1_A,
|
||||||
TRIG_Joy2_A,
|
TRIG_Joy2_A,
|
||||||
@ -197,4 +226,6 @@ enum GTTRIG_Param {
|
|||||||
TRIG_Joy2_B
|
TRIG_Joy2_B
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define VSYNC() __asm__("HALT");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
166
presets/msx/redbook_40col.asm
Normal file
166
presets/msx/redbook_40col.asm
Normal file
@ -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
|
450
presets/msx/redbook_charedit.asm
Normal file
450
presets/msx/redbook_charedit.asm
Normal file
@ -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
|
59
presets/msx/redbook_kbd.asm
Normal file
59
presets/msx/redbook_kbd.asm
Normal file
@ -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
|
256
presets/msx/siegegame.c
Normal file
256
presets/msx/siegegame.c
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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<frames_per_move; i++) {
|
||||||
|
human_control(&players[0]);
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
ai_control(&players[0]);
|
||||||
|
ai_control(&players[1]);
|
||||||
|
// if players collide, 2nd player gets the point
|
||||||
|
move_player(&players[1]);
|
||||||
|
move_player(&players[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void play_game();
|
||||||
|
|
||||||
|
void declare_winner(byte winner) {
|
||||||
|
byte i;
|
||||||
|
CLS();
|
||||||
|
for (i=0; i<ROWS/2-3; i++) {
|
||||||
|
draw_box(i,i,COLS-1-i,ROWS-1-i,BOX_CHARS);
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
putstring(12,10,"WINNER:");
|
||||||
|
putstring(12,13,"PLAYER ");
|
||||||
|
cputcxy(12+7, 13, CHAR('1')+winner);
|
||||||
|
delay(75);
|
||||||
|
gameover = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void play_round() {
|
||||||
|
reset_players();
|
||||||
|
CLS();
|
||||||
|
draw_playfield();
|
||||||
|
while (1) {
|
||||||
|
make_move();
|
||||||
|
if (players[0].collided || players[1].collided) break;
|
||||||
|
}
|
||||||
|
flash_colliders();
|
||||||
|
// add scores to players that didn't collide
|
||||||
|
if (players[0].collided) players[1].score++;
|
||||||
|
if (players[1].collided) players[0].score++;
|
||||||
|
// increase speed
|
||||||
|
if (frames_per_move > 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();
|
||||||
|
}
|
@ -15,6 +15,9 @@ import { TMS9918A } from "../video/tms9918a";
|
|||||||
|
|
||||||
var MSX_PRESETS = [
|
var MSX_PRESETS = [
|
||||||
{id:'helloworld.asm', name:'Hello World (ASM)'},
|
{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([
|
var MSX_KEYCODE_MAP = makeKeycodeMap([
|
||||||
|
@ -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].
|
// 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
|
#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);
|
cvu_voutb(sprite->y, base + number);
|
||||||
cv_set_write_vram_address(base + 0x80 + number * 2);
|
cv_set_write_vram_address(base + 0x80 + number * 2);
|
||||||
|
@ -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].
|
// 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
|
#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);
|
cvu_voutb(sprite->y, base + number);
|
||||||
cv_set_write_vram_address(base + 0x80 + number * 2);
|
cv_set_write_vram_address(base + 0x80 + number * 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user