//---------------------------------------------------------------- // newipl86.cpp // // This utility creates 'boilerplate' source-text for a new // bootsector program, written in 'as86' assembly language. // // usage: $ newipl86 // // programmer: ALLAN CRUSE // written on: 10 FEB 2004 //---------------------------------------------------------------- #include // for fprintf(), fopen(), etc #include // for strncpy(), strncat() #include // for time(), localtime() char authorname[] = "ALLAN CRUSE"; // substitute YOUR name char monthlist[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; int main( int argc, char *argv[] ) { // check for module-name as command-line argument if ( argc == 1 ) { fprintf( stderr, "Must specify module-name\n" ); return -1; } // prepare program name char appname[33] = ""; strncpy( appname, argv[1], 28 ); // prepare code-file name char srcname[33] = ""; strncpy( srcname, argv[1], 28 ); strncat( srcname, ".s", 22 ); // announce this program's purpose printf( "\nCreating skeleton for program " ); printf( "named \'%s\' \n", srcname ); // insure source-file doesn't already exist FILE *fp = fopen( srcname, "rb" ); if ( fp != NULL ) { fclose( fp ); fprintf( stderr, "File \'%s\' already exists\n", srcname ); return -1; } // create the new source-file fp = fopen( srcname, "wb" ); if ( fp == NULL ) { fprintf( stderr, "Cannot create source-file\n" ); return -1; } // obtain today's date (in DD MMM YYYY format) time_t now = time( (time_t *)NULL ); struct tm *t = localtime( &now ); char month[4] = ""; strncpy( month, monthlist+3*t->tm_mon, 3 ); month[3] = '\0'; char when[16] = ""; sprintf( when, "%02d %3s %04d", t->tm_mday, month, 1900+t->tm_year ); char border[68] = ""; memset( border, '-', 65 ); fprintf( fp, ";//%s\n", border+2 ); fprintf( fp, ";//\t%s\n", srcname ); fprintf( fp, ";//\n" ); fprintf( fp, ";//\n" ); fprintf( fp, ";//\n" ); fprintf( fp, ";//\t assemble with: " ); fprintf( fp, "$ as86 %s -b %s.b \n", srcname, appname ); fprintf( fp, ";//\t install using: " ); fprintf( fp, "$ dd if=%s.b of=/dev/fd0 \n", appname ); fprintf( fp, ";//\n" ); fprintf( fp, ";//\tNOTE: This code begins executing " ); fprintf( fp, "with CS:IP = 0000:7C00. \n" ); fprintf( fp, ";//\n" ); fprintf( fp, ";//\tprogrammer: %s\n", authorname ); fprintf( fp, ";//\tdate begun: %s\n", when ); fprintf( fp, ";//%s\n", border+2 ); fprintf( fp, "\n" ); fprintf( fp, "\n\t.SECT\t.TEXT\n" ); fprintf( fp, ";%s\n", border ); fprintf( fp, "start:" ); fprintf( fp, "\tcli\t\t\t\t" ); fprintf( fp, "; enter critical section \n" ); fprintf( fp, "\tmov\tax, cs\t\t\t" ); fprintf( fp, "; address zero segment \n" ); fprintf( fp, "\tmov\tss, ax\t\t\t" ); fprintf( fp, "; with SS register \n" ); fprintf( fp, "\tmov\tsp, #0x7C00\t\t" ); fprintf( fp, "; stacktop at BOOT_LOCN \n" ); fprintf( fp, "\tsti\t\t\t\t" ); fprintf( fp, "; leave critical section \n" ); fprintf( fp, "\tjmpf\t#main, #0x07C0\t\t" ); fprintf( fp, "; re-normalize CS and IP \n" ); fprintf( fp, ";%s\n", border ); fprintf( fp, ";%s\n", border ); fprintf( fp, "main:\t \n" ); fprintf( fp, "\t; setup sement-registers " ); fprintf( fp, "to address our program data \n" ); fprintf( fp, "\n" ); fprintf( fp, "\tmov\tax, cs \t\t\t; address this segment \n" ); fprintf( fp, "\tmov\tds, ax \t\t\t; with DS register \n" ); fprintf( fp, "\tmov\tes, ax \t\t\t; also ES register \n" ); fprintf( fp, "\n" ); fprintf( fp, "\n\t; await user keypress \n" ); fprintf( fp, "\n" ); fprintf( fp, "\txor\tah, ah \t\t\t; get_keyboard_input \n" ); fprintf( fp, "\tint\t0x16 \t\t\t; invoke BIOS service \n" ); fprintf( fp, "\tint\t0x19 \t\t\t; then reboot machine \n" ); fprintf( fp, ";%s\n", border ); fprintf( fp, ";%s\n", border ); fprintf( fp, "\t.ORG\t510\t\t\t; boot-signature's offset \n " ); fprintf( fp, "\t.BYTE\t0x55, 0xAA\t\t; value of boot-signature \n " ); fprintf( fp, ";%s\n", border ); fprintf( fp, "\tEND\n" ); printf( "\n" ); }