81 lines
2.3 KiB
C
81 lines
2.3 KiB
C
// autostart.c - Program to be run by the Disk Basic DOS command.
|
|
// By Pierre Sarrazin <http://sarrazip.com/>
|
|
// 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 <Enter> 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 <coco.h>
|
|
|
|
#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
|
|
"LOADM\"CAPITAL.BIN\":EXEC"
|
|
#else
|
|
COMMAND
|
|
#endif
|
|
;
|
|
|
|
// Install function feedKeyboard() as CONSOLE IN routine.
|
|
//
|
|
oldHookInstr = * (byte *) RVEC4;
|
|
oldHookAddr = * (word *) (RVEC4 + 1);
|
|
|
|
* (byte *) RVEC4 = 0x7e; // JMP instruction
|
|
* (void **) (RVEC4 + 1) = (void *) 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
|
|
}
|