// 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 }