// autostart.c - Program to be run by the Disk Basic DOS command.
// By Pierre Sarrazin
// This file is in the public domain.
//
// Reference: Roger Schrag, "A Special Use For The DOS Command",
// The Rainbow, November 1984, p.140.
//
// To compile: cmoc --dos autostart.c
// To install on CoCo disk image: install-coco-boot-loader some-image.dsk autostart.bin
// To run on CoCo: type DOS and to automatically run *.BAS.
//
// Version history:
// 0.1.0 2016-01-16 Use of legacy.h discontinued.
// 0.1.1 2018-04-03 Adapted to CMOC 0.1.51 (const).
// 0.1.2 2018-08-04 Basic line now forced to be uppercase.
#include
#define ENDFLG 0x00 // STOP/END FLAG: POSITIVE=STOP, NEG=END
#define CINBFL 0x70 // CONSOLE IN BUFFER FLAG: 00=NOT EMPTY, $FF=EMPTY
#define RVEC4 0x016a // RAM hook: CONSOLE IN
byte oldHookInstr;
word oldHookAddr;
const char *basicLineReader;
void feedKeyboard()
{
word preservedX;
asm("stx", preservedX);
* (byte *) CINBFL = 0; // console in buffer now not empty
char nextBasicByte = (char) toupper(*basicLineReader);
++basicLineReader;
if (nextBasicByte == 0) // if finished returning Basic line
{
* (byte *) RVEC4 = oldHookInstr;
* (word *) (RVEC4 + 1) = oldHookAddr;
nextBasicByte = '\r'; // return "Enter" to cause execution of Basic line
}
asm {
lda nextBasicByte
ldx preservedX
tfr u,s // discard stack frame
leas 4,s // discard previous stack frame ptr and return addr
rts // return to caller of CONSOLE IN
}
}
int main()
{
* (byte *) ENDFLG = - * (byte *) ENDFLG; // why?
basicLineReader =
#ifndef COMMAND
"RUN\"*.BAS\""
#else
COMMAND
#endif
;
// Install function feedKeyboard() as CONSOLE IN routine.
//
oldHookInstr = * (byte *) RVEC4;
oldHookAddr = * (word *) (RVEC4 + 1);
* (byte *) RVEC4 = 0x7e; // JMP instruction
* (word *) (RVEC4 + 1) = feedKeyboard;
* (word *) 0x2600 = 0; // overwrite "OS" marker with two null bytes
asm("jmp", "$ac7c"); // go interpret a Basic line (which is read from console)
return 0; // avoids compiler error
}