stefano wrote:IIRC I was able to do it on the spectrum. As said the zx81 interptreter loop is less flexible (gosub and other things behave differently, as far as I remember)
I think a "zx_getcommandline" to fetch user input from keyboard (incl. BASIC tokens) would be sufficient to do such a "shell" inside a C program:
Code: Select all
do
{
zx_getcommandline(buffer);
zx_line_without_linenumber(buffer);
}
while (strcmp(buffer, "RETURN"))
GOTO/GOSUB/FOR/NEXT are (currently
) not necessary
by the way zx_line and family are basic portions should get back to the c caller after their execution, have you tried something?
Yes. This code executes line 2000-2100 to execute an external asm or C program (called by BASIC):
Code: Select all
unsigned int __CALLEE__ exec_BASIC_lines(unsigned int start, unsigned int end)
{
err = 0;
zx_cls();
for (line_no = start; line_no <= end; line_no++)
{
in_WaitForNoKey();
zx_fast();
err = zx_line(line_no);
if ((err > 0) && (err != 0xffff) && (err != 9))
{
break;
}
}
zx_cls();
zx_slow();
in_WaitForNoKey();
return err;
}
Then the total result of that action is read (to handle a new e-mail attachment, loaded into ram at "addr"):
Code: Select all
att_length = (unsigned int) zx_getint("len");
att_ptr = (unsigned char *) zx_getint("addr");
And this code fetches a BASIC variable, set by "LET A$="alias=e-mailaddr" inside a BASIC line:
Code: Select all
void __FASTCALL__ conv_alias(unsigned char * alias)
{
static char * email;
static unsigned int len;
len = strlen(alias);
for (line_no = 1000; line_no <= 1100; line_no++)
{
err = zx_line(line_no);
if ((err > 0) && (err != 0xffff))
{
printk("err %u in BASIC line %u\n", err, line_no);
}
else
{
/* "temp_buf_60fer" is currently not used for other things */
*temp_buf_60 = 0; /* workaround Z88DK problem */
err = zx_getstr('A', temp_buf_60);
if (!err)
{
....
Siggi