fixup conio.c some more. also includes merge of upstream/master because git is retarded.
This commit is contained in:
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<article>
|
<article>
|
||||||
<title>ca65 Users Guide
|
<title>ca65 Users Guide
|
||||||
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">
|
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
|
||||||
<date>2015-08-01
|
<url url="mailto:greg.king5@verizon.net" name="Greg King">
|
||||||
|
<date>2015-11-17
|
||||||
|
|
||||||
<abstract>
|
<abstract>
|
||||||
ca65 is a powerful macro assembler for the 6502, 65C02, and 65816 CPUs. It is
|
ca65 is a powerful macro assembler for the 6502, 65C02, and 65816 CPUs. It is
|
||||||
@@ -3960,10 +3961,10 @@ When using macro parameters, macros can be even more useful:
|
|||||||
.macro inc16 addr
|
.macro inc16 addr
|
||||||
clc
|
clc
|
||||||
lda addr
|
lda addr
|
||||||
adc #$01
|
adc #<$0001
|
||||||
sta addr
|
sta addr
|
||||||
lda addr+1
|
lda addr+1
|
||||||
adc #$00
|
adc #>$0001
|
||||||
sta addr+1
|
sta addr+1
|
||||||
.endmacro
|
.endmacro
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
@@ -3981,10 +3982,10 @@ will be expanded to
|
|||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
clc
|
clc
|
||||||
lda $1000
|
lda $1000
|
||||||
adc #$01
|
adc #<$0001
|
||||||
sta $1000
|
sta $1000
|
||||||
lda $1000+1
|
lda $1000+1
|
||||||
adc #$00
|
adc #>$0001
|
||||||
sta $1000+1
|
sta $1000+1
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
@@ -4019,7 +4020,7 @@ Look at this example:
|
|||||||
.endmacro
|
.endmacro
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
This macro may be called as follows:
|
That macro may be called as follows:
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
ldaxy 1, 2, 3 ; Load all three registers
|
ldaxy 1, 2, 3 ; Load all three registers
|
||||||
@@ -4029,9 +4030,9 @@ This macro may be called as follows:
|
|||||||
ldaxy , , 3 ; Load y only
|
ldaxy , , 3 ; Load y only
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
There's another helper command for determining, which macro parameters are
|
There's another helper command for determining which macro parameters are
|
||||||
valid: <tt><ref id=".PARAMCOUNT" name=".PARAMCOUNT"></tt> This command is
|
valid: <tt><ref id=".PARAMCOUNT" name=".PARAMCOUNT"></tt>. That command is
|
||||||
replaced by the parameter count given, <em/including/ intermediate empty macro
|
replaced by the parameter count given, <em/including/ explicitly empty
|
||||||
parameters:
|
parameters:
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
@@ -4056,10 +4057,10 @@ case of a macro parameter).
|
|||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
In the first case, the macro is called with two parameters: '<tt/($00/'
|
In the first case, the macro is called with two parameters: '<tt/($00/'
|
||||||
and 'x)'. The comma is not passed to the macro, since it is part of the
|
and '<tt/x)/'. The comma is not passed to the macro, because it is part of the
|
||||||
calling sequence, not the parameters.
|
calling sequence, not the parameters.
|
||||||
|
|
||||||
In the second case, '($00,x)' is passed to the macro, this time
|
In the second case, '<tt/($00,x)/' is passed to the macro; this time,
|
||||||
including the comma.
|
including the comma.
|
||||||
|
|
||||||
|
|
||||||
@@ -4112,15 +4113,15 @@ Macros may be used recursively:
|
|||||||
.macro push r1, r2, r3
|
.macro push r1, r2, r3
|
||||||
lda r1
|
lda r1
|
||||||
pha
|
pha
|
||||||
.if .paramcount > 1
|
.ifnblank r2
|
||||||
push r2, r3
|
push r2, r3
|
||||||
.endif
|
.endif
|
||||||
.endmacro
|
.endmacro
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
There's also a special macro to help writing recursive macros: <tt><ref
|
There's also a special macro command to help with writing recursive macros:
|
||||||
id=".EXITMACRO" name=".EXITMACRO"></tt> This command will stop macro expansion
|
<tt><ref id=".EXITMACRO" name=".EXITMACRO"></tt>. That command will stop macro
|
||||||
immediately:
|
expansion immediately:
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
.macro push r1, r2, r3, r4, r5, r6, r7
|
.macro push r1, r2, r3, r4, r5, r6, r7
|
||||||
@@ -4135,7 +4136,7 @@ immediately:
|
|||||||
.endmacro
|
.endmacro
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
When expanding this macro, the expansion will push all given parameters
|
When expanding that macro, the expansion will push all given parameters
|
||||||
until an empty one is encountered. The macro may be called like this:
|
until an empty one is encountered. The macro may be called like this:
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
@@ -4154,10 +4155,10 @@ Have a look at the inc16 macro above. Here is it again:
|
|||||||
.macro inc16 addr
|
.macro inc16 addr
|
||||||
clc
|
clc
|
||||||
lda addr
|
lda addr
|
||||||
adc #$01
|
adc #<$0001
|
||||||
sta addr
|
sta addr
|
||||||
lda addr+1
|
lda addr+1
|
||||||
adc #$00
|
adc #>$0001
|
||||||
sta addr+1
|
sta addr+1
|
||||||
.endmacro
|
.endmacro
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
@@ -4288,7 +4289,7 @@ don't like that, use classic macros instead:
|
|||||||
.endmacro
|
.endmacro
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
(This is an example where a problem can be solved with both macro types).
|
(That is an example where a problem can be solved with both macro types).
|
||||||
|
|
||||||
|
|
||||||
<sect1>Characters in macros<p>
|
<sect1>Characters in macros<p>
|
||||||
@@ -4308,7 +4309,7 @@ be sure to take the translation into account.
|
|||||||
<sect1>Deleting macros<p>
|
<sect1>Deleting macros<p>
|
||||||
|
|
||||||
Macros can be deleted. This will not work if the macro that should be deleted
|
Macros can be deleted. This will not work if the macro that should be deleted
|
||||||
is currently expanded as in the following non working example:
|
is currently expanded as in the following non-working example:
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
.macro notworking
|
.macro notworking
|
||||||
@@ -4348,6 +4349,7 @@ argument to <tt>.UNDEFINE</tt> is not allowed to come from another
|
|||||||
different commands increases flexibility.
|
different commands increases flexibility.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<sect>Macro packages<label id="macropackages"><p>
|
<sect>Macro packages<label id="macropackages"><p>
|
||||||
|
|
||||||
Using the <tt><ref id=".MACPACK" name=".MACPACK"></tt> directive, predefined
|
Using the <tt><ref id=".MACPACK" name=".MACPACK"></tt> directive, predefined
|
||||||
@@ -4862,6 +4864,3 @@ freely, subject to the following restrictions:
|
|||||||
|
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -51,13 +51,9 @@ soft80_init:
|
|||||||
jmp soft80_kclrscr
|
jmp soft80_kclrscr
|
||||||
|
|
||||||
soft80_shutdown:
|
soft80_shutdown:
|
||||||
lda #$1b
|
|
||||||
sta VIC_CTRL1
|
jsr $fda3 ; Initialise I/O
|
||||||
lda #$03
|
jmp $ff5b ; Initialize screen editor
|
||||||
sta CIA2_PRA
|
|
||||||
lda #$15
|
|
||||||
sta VIC_VIDEO_ADR
|
|
||||||
rts
|
|
||||||
|
|
||||||
.segment "INIT"
|
.segment "INIT"
|
||||||
firstinit:
|
firstinit:
|
||||||
|
|||||||
@@ -262,6 +262,21 @@ void WriteFiles (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void WriteEscaped (FILE* F, const char* Name)
|
||||||
|
/* Write a file name to a dependency file escaping spaces */
|
||||||
|
{
|
||||||
|
while (*Name) {
|
||||||
|
if (*Name == ' ') {
|
||||||
|
/* Escape spaces */
|
||||||
|
fputc ('\\', F);
|
||||||
|
}
|
||||||
|
fputc (*Name, F);
|
||||||
|
++Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void WriteDep (FILE* F, FileType Types)
|
static void WriteDep (FILE* F, FileType Types)
|
||||||
/* Helper function. Writes all file names that match Types to the output */
|
/* Helper function. Writes all file names that match Types to the output */
|
||||||
{
|
{
|
||||||
@@ -285,9 +300,9 @@ static void WriteDep (FILE* F, FileType Types)
|
|||||||
fputc (' ', F);
|
fputc (' ', F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the dependency */
|
/* Print the dependency escaping spaces */
|
||||||
Filename = GetStrBuf (E->Name);
|
Filename = GetStrBuf (E->Name);
|
||||||
fprintf (F, "%*s", SB_GetLen (Filename), SB_GetConstBuf (Filename));
|
WriteEscaped (F, SB_GetConstBuf (Filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +320,8 @@ static void CreateDepFile (const char* Name, FileType Types)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print the output file followed by a tab char */
|
/* Print the output file followed by a tab char */
|
||||||
fprintf (F, "%s:\t", OutFile);
|
WriteEscaped (F, OutFile);
|
||||||
|
fputs (":\t", F);
|
||||||
|
|
||||||
/* Write out the dependencies for the output file */
|
/* Write out the dependencies for the output file */
|
||||||
WriteDep (F, Types);
|
WriteDep (F, Types);
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ static int DoMacAbort = 0;
|
|||||||
/* Counter to create local names for symbols */
|
/* Counter to create local names for symbols */
|
||||||
static unsigned LocalName = 0;
|
static unsigned LocalName = 0;
|
||||||
|
|
||||||
/* Define style macros disabled if != 0 */
|
/* Define-style macros disabled if != 0 */
|
||||||
static unsigned DisableDefines = 0;
|
static unsigned DisableDefines = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -422,8 +422,8 @@ void MacDef (unsigned Style)
|
|||||||
EnterRawTokenMode ();
|
EnterRawTokenMode ();
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* If we have a DEFINE style macro, we may have parameters in braces,
|
/* If we have a DEFINE-style macro, we may have parameters in parentheses;
|
||||||
** otherwise we may have parameters without braces.
|
** otherwise, we may have parameters without parentheses.
|
||||||
*/
|
*/
|
||||||
if (Style == MAC_STYLE_CLASSIC) {
|
if (Style == MAC_STYLE_CLASSIC) {
|
||||||
HaveParams = 1;
|
HaveParams = 1;
|
||||||
@@ -475,7 +475,7 @@ void MacDef (unsigned Style)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For class macros, we expect a separator token, for define style macros,
|
/* For classic macros, we expect a separator token, for define-style macros,
|
||||||
** we expect the closing paren.
|
** we expect the closing paren.
|
||||||
*/
|
*/
|
||||||
if (Style == MAC_STYLE_CLASSIC) {
|
if (Style == MAC_STYLE_CLASSIC) {
|
||||||
@@ -485,9 +485,9 @@ void MacDef (unsigned Style)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Preparse the macro body. We will read the tokens until we reach end of
|
/* Preparse the macro body. We will read the tokens until we reach end of
|
||||||
** file, or a .endmacro (or end of line for DEFINE style macros) and store
|
** file, or a .endmacro (or end of line for DEFINE-style macros) and store
|
||||||
** them into an token list internal to the macro. For classic macros, there
|
** them into a token list internal to the macro. For classic macros,
|
||||||
** the .LOCAL command is detected and removed at this time.
|
** the .LOCAL command is detected and removed, at this time.
|
||||||
*/
|
*/
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
@@ -752,11 +752,11 @@ ExpandParam:
|
|||||||
FreeTokNode (Mac->Final);
|
FreeTokNode (Mac->Final);
|
||||||
Mac->Final = 0;
|
Mac->Final = 0;
|
||||||
|
|
||||||
/* Problem: When a .define style macro is expanded within the call
|
/* Problem: When a .define-style macro is expanded within the call
|
||||||
** of a classic one, the latter may be terminated and removed while
|
** of a classic one, the latter may be terminated and removed while
|
||||||
** the expansion of the .define style macro is still active. Because
|
** the expansion of the .define-style macro is still active. Because
|
||||||
** line info slots are "stacked", this runs into a CHECK FAILED. For
|
** line info slots are "stacked", this runs into a CHECK FAILED. For
|
||||||
** now, we will fix that by removing the .define style macro expansion
|
** now, we will fix that by removing the .define-style macro expansion
|
||||||
** immediately, once the final token is placed. The better solution
|
** immediately, once the final token is placed. The better solution
|
||||||
** would probably be to not require AllocLineInfoSlot/FreeLineInfoSlot
|
** would probably be to not require AllocLineInfoSlot/FreeLineInfoSlot
|
||||||
** to be called in FIFO order, but this is a bigger change.
|
** to be called in FIFO order, but this is a bigger change.
|
||||||
@@ -790,9 +790,11 @@ static void StartExpClassic (MacExp* E)
|
|||||||
/* Skip the macro name */
|
/* Skip the macro name */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Read the actual parameters */
|
/* Does this invocation have any arguments? */
|
||||||
while (!TokIsSep (CurTok.Tok)) {
|
if (!TokIsSep (CurTok.Tok)) {
|
||||||
|
|
||||||
|
/* Read the actual parameters */
|
||||||
|
while (1) {
|
||||||
TokNode* Last;
|
TokNode* Last;
|
||||||
|
|
||||||
/* Check for maximum parameter count */
|
/* Check for maximum parameter count */
|
||||||
@@ -801,13 +803,12 @@ static void StartExpClassic (MacExp* E)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The macro may optionally be enclosed in curly braces */
|
/* The macro argument optionally may be enclosed in curly braces */
|
||||||
Term = GetTokListTerm (TOK_COMMA);
|
Term = GetTokListTerm (TOK_COMMA);
|
||||||
|
|
||||||
/* Read tokens for one parameter, accept empty params */
|
/* Read tokens for one parameter, accept empty params */
|
||||||
Last = 0;
|
Last = 0;
|
||||||
while (CurTok.Tok != Term && CurTok.Tok != TOK_SEP) {
|
while (CurTok.Tok != Term && CurTok.Tok != TOK_SEP) {
|
||||||
|
|
||||||
TokNode* T;
|
TokNode* T;
|
||||||
|
|
||||||
/* Check for end of file */
|
/* Check for end of file */
|
||||||
@@ -853,6 +854,7 @@ static void StartExpClassic (MacExp* E)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We must be at end of line now, otherwise something is wrong */
|
/* We must be at end of line now, otherwise something is wrong */
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
@@ -864,9 +866,9 @@ static void StartExpClassic (MacExp* E)
|
|||||||
|
|
||||||
|
|
||||||
static void StartExpDefine (MacExp* E)
|
static void StartExpDefine (MacExp* E)
|
||||||
/* Start expanding a DEFINE style macro */
|
/* Start expanding a DEFINE-style macro */
|
||||||
{
|
{
|
||||||
/* A define style macro must be called with as many actual parameters
|
/* A define-style macro must be called with as many actual parameters
|
||||||
** as there are formal ones. Get the parameter count.
|
** as there are formal ones. Get the parameter count.
|
||||||
*/
|
*/
|
||||||
unsigned Count = E->M->ParamCount;
|
unsigned Count = E->M->ParamCount;
|
||||||
@@ -876,10 +878,9 @@ static void StartExpDefine (MacExp* E)
|
|||||||
|
|
||||||
/* Read the actual parameters */
|
/* Read the actual parameters */
|
||||||
while (Count--) {
|
while (Count--) {
|
||||||
|
|
||||||
TokNode* Last;
|
TokNode* Last;
|
||||||
|
|
||||||
/* The macro may optionally be enclosed in curly braces */
|
/* The macro argument optionally may be enclosed in curly braces */
|
||||||
token_t Term = GetTokListTerm (TOK_COMMA);
|
token_t Term = GetTokListTerm (TOK_COMMA);
|
||||||
|
|
||||||
/* Check if there is really a parameter */
|
/* Check if there is really a parameter */
|
||||||
@@ -892,7 +893,6 @@ static void StartExpDefine (MacExp* E)
|
|||||||
/* Read tokens for one parameter */
|
/* Read tokens for one parameter */
|
||||||
Last = 0;
|
Last = 0;
|
||||||
do {
|
do {
|
||||||
|
|
||||||
TokNode* T;
|
TokNode* T;
|
||||||
|
|
||||||
/* Get the next token in a node */
|
/* Get the next token in a node */
|
||||||
@@ -936,7 +936,7 @@ static void StartExpDefine (MacExp* E)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Macro expansion will overwrite the current token. This is a problem
|
/* Macro expansion will overwrite the current token. This is a problem
|
||||||
** for define style macros since these are called from the scanner level.
|
** for define-style macros since these are called from the scanner level.
|
||||||
** To avoid it, remember the current token and re-insert it, once macro
|
** To avoid it, remember the current token and re-insert it, once macro
|
||||||
** expansion is done.
|
** expansion is done.
|
||||||
*/
|
*/
|
||||||
@@ -1007,8 +1007,8 @@ Macro* FindMacro (const StrBuf* Name)
|
|||||||
|
|
||||||
|
|
||||||
Macro* FindDefine (const StrBuf* Name)
|
Macro* FindDefine (const StrBuf* Name)
|
||||||
/* Try to find the define style macro with the given name and return it. If no
|
/* Try to find the define-style macro with the given name; and, return it.
|
||||||
** such macro was found, return NULL.
|
** If no such macro was found, return NULL.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Macro* M;
|
Macro* M;
|
||||||
@@ -1034,7 +1034,7 @@ int InMacExpansion (void)
|
|||||||
|
|
||||||
|
|
||||||
void DisableDefineStyleMacros (void)
|
void DisableDefineStyleMacros (void)
|
||||||
/* Disable define style macros until EnableDefineStyleMacros is called */
|
/* Disable define-style macros until EnableDefineStyleMacros() is called */
|
||||||
{
|
{
|
||||||
++DisableDefines;
|
++DisableDefines;
|
||||||
}
|
}
|
||||||
@@ -1042,8 +1042,8 @@ void DisableDefineStyleMacros (void)
|
|||||||
|
|
||||||
|
|
||||||
void EnableDefineStyleMacros (void)
|
void EnableDefineStyleMacros (void)
|
||||||
/* Re-enable define style macros previously disabled with
|
/* Re-enable define-style macros previously disabled with
|
||||||
** DisableDefineStyleMacros.
|
** DisableDefineStyleMacros().
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PRECONDITION (DisableDefines > 0);
|
PRECONDITION (DisableDefines > 0);
|
||||||
|
|||||||
20
testcode/assembler/paramcount.s
Normal file
20
testcode/assembler/paramcount.s
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
; Test ca65's handling of the .paramcount read-only variable.
|
||||||
|
; .paramcount should see all given arguments, even when they are empty.
|
||||||
|
|
||||||
|
.macro push r1, r2, r3, r4, r5, r6
|
||||||
|
.out .sprintf(" .paramcount = %u", .paramcount)
|
||||||
|
.if .paramcount <> 0
|
||||||
|
.ifblank r1
|
||||||
|
.warning "r1 is blank!"
|
||||||
|
.exitmacro
|
||||||
|
.endif
|
||||||
|
lda r1
|
||||||
|
pha
|
||||||
|
|
||||||
|
push r2, r3, r4, r5, r6
|
||||||
|
.endif
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
push 1, , {}
|
||||||
|
push 1, ,
|
||||||
|
push 1
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <joystick.h>
|
||||||
|
|
||||||
#if defined(__GAMATE__)
|
#if defined(__GAMATE__)
|
||||||
/* there is not enough screen space to show all 256 characters at the bottom */
|
/* there is not enough screen space to show all 256 characters at the bottom */
|
||||||
@@ -35,13 +36,16 @@ void main(void)
|
|||||||
{
|
{
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
unsigned char xsize, ysize, tcol, bgcol, bcol, inpos = 0;
|
unsigned char xsize, ysize, tcol, bgcol, bcol, inpos = 0;
|
||||||
|
#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__)
|
||||||
|
unsigned char joy;
|
||||||
|
|
||||||
|
joy_install(joy_static_stddrv);
|
||||||
|
#endif
|
||||||
clrscr();
|
clrscr();
|
||||||
screensize(&xsize, &ysize);
|
screensize(&xsize, &ysize);
|
||||||
cputs("cc65 conio test\n\r");
|
cputs("cc65 conio test\n\r");
|
||||||
#if !defined(__NES__) && !defined(__PCE__) && !defined(__GAMATE__)
|
|
||||||
cputs("Input:[ ]");
|
cputs("Input:[ ]");
|
||||||
#endif
|
|
||||||
cputsxy(0, 2, "Colors:" );
|
cputsxy(0, 2, "Colors:" );
|
||||||
tcol = textcolor(0); /* remember original textcolor */
|
tcol = textcolor(0); /* remember original textcolor */
|
||||||
bgcol = bgcolor(0); /* remember original background color */
|
bgcol = bgcolor(0); /* remember original background color */
|
||||||
@@ -99,6 +103,8 @@ void main(void)
|
|||||||
cursor(1);
|
cursor(1);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
|
/* do the "rvs" blinking */
|
||||||
|
i = textcolor(COLOR_BLACK);
|
||||||
gotoxy(8, 2);
|
gotoxy(8, 2);
|
||||||
j = n >> 4 & 1;
|
j = n >> 4 & 1;
|
||||||
revers(j);
|
revers(j);
|
||||||
@@ -106,9 +112,18 @@ void main(void)
|
|||||||
revers(j ^ 1);
|
revers(j ^ 1);
|
||||||
cputs(" rvs");
|
cputs(" rvs");
|
||||||
revers(0);
|
revers(0);
|
||||||
|
textcolor(i);
|
||||||
|
|
||||||
#if !defined(__NES__) && !defined(__PCE__) && !defined(__GAMATE__)
|
gotoxy(7 + inpos,1);
|
||||||
gotoxy(8 + inpos,1);
|
|
||||||
|
#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__)
|
||||||
|
/* not all targets have waitvblank */
|
||||||
|
waitvblank();
|
||||||
|
/* for targets that do not have a keyboard, read the first
|
||||||
|
joystick */
|
||||||
|
joy = joy_read(JOY_1);
|
||||||
|
cprintf("%02x", joy);
|
||||||
|
#else
|
||||||
i = cgetc();
|
i = cgetc();
|
||||||
if ((i >= '0') && (i<='9')) {
|
if ((i >= '0') && (i<='9')) {
|
||||||
textcolor(i - '0');
|
textcolor(i - '0');
|
||||||
@@ -133,13 +148,6 @@ void main(void)
|
|||||||
inpos = (inpos + 1) & 7;
|
inpos = (inpos + 1) & 7;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* not all targets have waitvblank() */
|
|
||||||
#if defined(__NES__) || defined(__PCE__) || defined(__GAMATE__)
|
|
||||||
waitvblank();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(;;);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,35 +5,9 @@
|
|||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#include <em.h>
|
#include <em.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined(__C64__)
|
|
||||||
#define DRIVERNAME "c64-ram.emd"
|
|
||||||
#elif defined(__C128__)
|
|
||||||
#define DRIVERNAME "c128-ram.emd"
|
|
||||||
#elif defined(__C16__)
|
|
||||||
#define DRIVERNAME "c16-ram.emd"
|
|
||||||
#elif defined(__CBM510__)
|
|
||||||
#define DRIVERNAME "cbm510-ram.emd"
|
|
||||||
#elif defined(__CBM610__)
|
|
||||||
#define DRIVERNAME "cbm610-ram.emd"
|
|
||||||
#elif defined(__APPLE2ENH__)
|
|
||||||
#define DRIVERNAME "a2e.auxmem.emd"
|
|
||||||
#elif defined(__APPLE2__)
|
|
||||||
#define DRIVERNAME "a2.auxmem.emd"
|
|
||||||
#elif defined(__ATARIXL__)
|
|
||||||
#define DRIVERNAME "atrx130.emd"
|
|
||||||
#elif defined(__ATARI__)
|
|
||||||
#define DRIVERNAME "atr130.emd"
|
|
||||||
#else
|
|
||||||
#define DRIVERNAME "unknown"
|
|
||||||
#error "Unknown target system"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define FORCE_ERROR1 0
|
#define FORCE_ERROR1 0
|
||||||
#define FORCE_ERROR2 0
|
#define FORCE_ERROR2 0
|
||||||
|
|
||||||
|
|
||||||
#define PAGE_SIZE 128 /* Size in words */
|
#define PAGE_SIZE 128 /* Size in words */
|
||||||
#define BUF_SIZE (PAGE_SIZE + PAGE_SIZE/2)
|
#define BUF_SIZE (PAGE_SIZE + PAGE_SIZE/2)
|
||||||
static unsigned buf[BUF_SIZE];
|
static unsigned buf[BUF_SIZE];
|
||||||
@@ -75,7 +49,65 @@ static void cmp (unsigned page, register const unsigned* buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct emd_test_s {
|
||||||
|
char key;
|
||||||
|
char *displayname;
|
||||||
|
char *drivername;
|
||||||
|
} emd_test_t;
|
||||||
|
|
||||||
|
static emd_test_t drivers[] = {
|
||||||
|
|
||||||
|
#if defined(__APPLE2__)
|
||||||
|
{ '0', "Apple II auxiliary memory", "a2.auxmem.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__APPLE2ENH__)
|
||||||
|
{ '0', "Apple II auxiliary memory", "a2e.auxmem.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__ATARI__)
|
||||||
|
{ '0', "Atari 130XE memory", "atr130.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__ATARIXL__)
|
||||||
|
{ '0', "Atari 130XE memory", "atrx130.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__C16__)
|
||||||
|
{ '0', "C16 RAM above $8000", "c16-ram.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__C64__)
|
||||||
|
{ '0', "C64 RAM above $D000", "c64-ram.emd" },
|
||||||
|
{ '1', "C64 256K", "c64-c256k.emd" },
|
||||||
|
{ '2', "Double Quick Brown Box", "c64-dqbb.emd" },
|
||||||
|
{ '3', "GEORAM", "c64-georam.emd" },
|
||||||
|
{ '4', "Isepic", "c64-isepic.emd" },
|
||||||
|
{ '5', "RamCart", "c64-ramcart.emd" },
|
||||||
|
{ '6', "REU", "c64-reu.emd" },
|
||||||
|
{ '7', "C128 VDC (in C64 mode)", "c64-vdc.emd" },
|
||||||
|
{ '8', "C64DTV himem", "dtv-himem.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__C128__)
|
||||||
|
{ '0', "C128 RAM in bank 1", "c128-ram.emd" },
|
||||||
|
{ '1', "C128 RAM in banks 1, 2 & 3", "c128-ram2.emd" },
|
||||||
|
{ '2', "GEORAM", "c128-georam.emd" },
|
||||||
|
{ '3', "RamCart", "c128-ramcart.emd" },
|
||||||
|
{ '4', "REU", "c128-reu.emd" },
|
||||||
|
{ '5', "VDC", "c128-vdc.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CBM510__)
|
||||||
|
{ '0', "CBM5x0 RAM in bank 2", "cbm510-ram.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CBM610__)
|
||||||
|
{ '0', "CBM6x0/7x0 RAM in bank 2", "cbm610-ram.emd" },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
@@ -85,9 +117,27 @@ int main (void)
|
|||||||
unsigned PageCount;
|
unsigned PageCount;
|
||||||
unsigned char X, Y;
|
unsigned char X, Y;
|
||||||
struct em_copy c;
|
struct em_copy c;
|
||||||
|
unsigned index;
|
||||||
|
signed char valid_key = -1;
|
||||||
|
char key;
|
||||||
|
|
||||||
clrscr ();
|
clrscr ();
|
||||||
Res = em_load_driver (DRIVERNAME);
|
cputs ("Which RAM exp to test?\r\n\r\n");
|
||||||
|
for (index = 0; drivers[index].key; ++index) {
|
||||||
|
cprintf("%c: %s\r\n", drivers[index].key, drivers[index].displayname);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (valid_key < 0) {
|
||||||
|
key = cgetc();
|
||||||
|
for (index = 0; drivers[index].key && valid_key < 0; ++index) {
|
||||||
|
if (key == drivers[index].key) {
|
||||||
|
valid_key = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clrscr ();
|
||||||
|
Res = em_load_driver (drivers[valid_key].drivername);
|
||||||
if (Res != EM_ERR_OK) {
|
if (Res != EM_ERR_OK) {
|
||||||
cprintf ("Error in em_load_driver: %u\r\n", Res);
|
cprintf ("Error in em_load_driver: %u\r\n", Res);
|
||||||
cprintf ("os: %u, %s\r\n", _oserror, _stroserror (_oserror));
|
cprintf ("os: %u, %s\r\n", _oserror, _stroserror (_oserror));
|
||||||
|
|||||||
Reference in New Issue
Block a user