ZX81: "DOS BOX" or "shell" possible?

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

ZX81: "DOS BOX" or "shell" possible?

Post by siggi »

Sometimes I would like to leave a C program temporarily to go to BASIC fo enter some direct BASIC commands and then return to the C program and continue there.
Example:
I am running a C program and want to LPRINT something, but have forgotten to load the network printer driver, which forwards lprinted data to my TNFS server. So I would call a "shell" in my C program and enter the BASIC commands

Code: Select all

- LOAD "DRV/PRINT2FL"            (load the printer driver into high ram)
- POKE 0,4                               (page in ram@8K for ZeddyNet buffers)
- RETURN                                 ( go back into C program to LPRINT there)
Is that somehow possible?

I did such things at BASIC level in TASWORD2:

Code: Select all

50 GOSUB 1000 /* go into DOS BOX */

1000 REM DOS BOX
1001 <force BASIC error to go to command promt>

...
enter BASIC commands (except NEW ;) )
...

RETURN (go back to TASWORD line 51)
Maybe the zx_line() function or similar code could be used for that?

Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

I thinkt the only function that is missing is something like
zx_getcommandline(char * buffer)

where the user could type in characters (incl. ZX81 keyword-tokens and ZX81 5-byte-float numbers) like when the BASIC interpreters waits for input of a direct command (and reads input into the ELINE buffer).
Then this bytes (in buffer) could be passed to the zx_line() function, which could handle that bytes like a BASIC line without line number (does not need to search that line in BASIC ram by its line number).

Siggi
stefano
Well known member
Posts: 1637
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

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) by the way zx_line and family are basic portions should get back to the c caller after their execution, have you tried something?
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

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
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

siggi wrote:Yes. This code executes line 2000-2100 to execute an external asm or C program (called by BASIC):
This are some typical lines, executed by the function:

Code: Select all

          2000 POKE 0,2
          2005 PRINT "LOAD FILE TO 32768"
          2010 RAND USR 8198
          2020 LET ADDR=32768
          2030 LET LEN=PEEK 16438+256*PEEK 16439
          2050 POKE 0,4
          2099 STOP
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

And the BASIC lines 2000-2100 as given above are also a good example, what should be handled by a "shell" (if this commands are entered manually)
stefano
Well known member
Posts: 1637
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

now what you are asking for is clearer. I'll experiment a bit but the zx81 is so delicate..
Post Reply