mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-22 12:29:06 +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 <string.h>
|
||||
#include <cv.h>
|
||||
@ -6,10 +6,7 @@
|
||||
|
||||
#include "common.h"
|
||||
//#link "common.c"
|
||||
|
||||
#ifdef CV_SMS
|
||||
//#link "fonts.s"
|
||||
#endif
|
||||
|
||||
#define XOFS 12 // sprite horiz. offset
|
||||
|
||||
@ -592,13 +589,17 @@ 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));
|
||||
|
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"
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -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
|
||||
|
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 = [
|
||||
{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([
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user