[comp.os.minix] improvements and bug fixes

kjh@pollux.usc.edu (Kenneth J. Hendrickson) (07/27/90)

I have made the following changes/improvements/bug fixes to Minix:

Bug Fixes:
+	Corrected handling of colour, bold, underlined, blinking,
	and reverse video Screen Attributes (console.c).

	I hope these make it into the next release of Minix.

Improvements:
+	Separate bootblok.s files for each drive type.
	Now booting up won't beat your drive to death, trying to
	accommodate all drive types.  Booting is also faster.
+	Put the screen into 43-line mode if EGA (or VGA) (start.x)
	I really liked the 43-line mode under DOS, and I like it under
	Minix also.  Don't forget to modify your /etc/termcap file.
+	Put the screen into green/black if colour (start.x & console.s)
	If green/black isn't your favourite colours, then you can change
	the VIDATT parameter.  Documentation is included.

	I hope these make it into the next release of Minix.

Changes:
+	Use ^C for the SIGINT  character instead of DEL
+	Use ^U for the SIGKILL character instead of @
+	Erase the line on SIGKILL character, like on BSD

	This is more of a "religious" issue, like Andy says in his
	book.  Still, I hope the SIGKILL stuff makes it into the next
	release.

Ken Hendrickson N8DGN/6      kjh@usc.edu      ...!uunet!usc!pollux!kjh

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..
# Wrapped by kjh@pollux.usc.edu on Fri Jul 27 03:57:21 1990
echo x - /usr/src/local/kernel/Makefile.cdif
sed '/^X/s///' > /usr/src/local/kernel/Makefile.cdif << '/'
X*** /usr/src/minix/kernel/Makefile	Fri Jul 20 01:19:10 1990
X--- Makefile	Fri Jul 27 02:38:16 1990
X***************
X*** 3,13 ****
X  # The following nonstandard flags are used:
X  # -F:	run cpp and cem sequentially (used when memory is tight)
X  # -T.:	put temporaries in working directory (when RAM disk is small)
X! BIN		=.
X! CC		=cc
X! CFLAGS		=-F -T.
X! CPP		=/usr/lib/cpp
X! CPPFLAGS	=-DASLD -P
X  END		=/usr/lib/end.s
X  LD		=asld
X  LDFLAGS		=-i
X--- 3,14 ----
X  # The following nonstandard flags are used:
X  # -F:	run cpp and cem sequentially (used when memory is tight)
X  # -T.:	put temporaries in working directory (when RAM disk is small)
X! # -DEGA43	use 43-line mode on EGA (and VGA) displays
X! BIN		=.
X! CC		=cc
X! CFLAGS		=-F -T. -DEGA43
X! CPP		=/usr/lib/cpp
X! CPPFLAGS	=-DASLD -P -DEGA43
X  END		=/usr/lib/end.s
X  LD		=asld
X  LDFLAGS		=-i
/
echo x - /usr/src/local/kernel/console.c.cdif
sed '/^X/s///' > /usr/src/local/kernel/console.c.cdif << '/'
X*** /usr/src/minix/kernel/console.c	Fri Jul 20 01:19:12 1990
X--- console.c	Thu Jul 26 22:12:50 1990
X***************
X*** 12,20 ****
X  #define M_VID_MASK    0x0FFF	/* mask for  4K video RAM */
X  #define C_RETRACE     0x0300	/* how many characters to display at once */
X  #define M_RETRACE     0x7000	/* how many characters to display at once */
X! #define BLANK         0x0700	/* determines  cursor color on blank screen */
X! #define LINE_WIDTH        80	/* # characters on a line */
X! #define SCR_LINES         25	/* # lines on the screen */
X  #define SCR_BYTES	8000	/* size video RAM. multiple of 2*LINE_WIDTH */
X  #define GO_FORWARD         0	/* scroll forward */
X  #define GO_BACKWARD        1	/* scroll backward */
X--- 12,37 ----
X  #define M_VID_MASK    0x0FFF	/* mask for  4K video RAM */
X  #define C_RETRACE     0x0300	/* how many characters to display at once */
X  #define M_RETRACE     0x7000	/* how many characters to display at once */
X! 
X! #define BLANK         0x0200	/* determines cursor color on blank screen */
X! /* Bit 14 (0x400) is for background Red
X!  * Bit 13 (0x200) is for background Green
X!  * Bit 12 (0x100) is for background Blue
X!  * Bit 10 (0x400) is for foreground Red
X!  * Bit  9 (0x200) is for foreground Green
X!  * Bit  8 (0x100) is for foreground Blue
X!  * It is probably unwise to set bits 15 or 11 of BLANK.
X!  * Bit 15 (0x8000) is for foreground blinking
X!  * Bit 11 (0x0800) is for foreground intensity
X!  */
X! 
X! #define LINE_WIDTH        80	/* # characters on a line */
X! #ifdef EGA43
X! #define SCR_LINES         43	/* # lines on the screen */
X! #else
X! #define SCR_LINES         25    /* # lines on the screen */
X! #endif
X! 
X  #define SCR_BYTES	8000	/* size video RAM. multiple of 2*LINE_WIDTH */
X  #define GO_FORWARD         0	/* scroll forward */
X  #define GO_BACKWARD        1	/* scroll backward */
X***************
X*** 36,42 ****
X  /* Global variables used by the console driver. */
X  PUBLIC int vid_mask;		/* 037777 for color (16K) or 07777 for mono */
X  PUBLIC int vid_port;		/* I/O port for accessing 6845 */
X! PUBLIC int blank_color = 0x0700; /* display code for blank */
X  
X  /* Private variables used by the console driver. */
X  PRIVATE vid_retrace;		/* how many characters to display per burst */
X--- 53,59 ----
X  /* Global variables used by the console driver. */
X  PUBLIC int vid_mask;		/* 037777 for color (16K) or 07777 for mono */
X  PUBLIC int vid_port;		/* I/O port for accessing 6845 */
X! PUBLIC int blank_color = BLANK; /* display code for blank */
X  
X  /* Private variables used by the console driver. */
X  PRIVATE vid_retrace;		/* how many characters to display per burst */
X***************
X*** 348,354 ****
X   *   ESC [nM deletes n lines at cursor
X   *   ESC [nP deletes n chars at cursor
X   *   ESC [n@ inserts n chars at cursor
X!  *   ESC [nm enables rendition n (0=normal, 4=bold, 5=blinking, 7=reverse)
X   *   ESC M scrolls the screen backwards if the cursor is on the top line
X   */
X  
X--- 365,372 ----
X   *   ESC [nM deletes n lines at cursor
X   *   ESC [nP deletes n chars at cursor
X   *   ESC [n@ inserts n chars at cursor
X!  *   ESC [nm enables rendition n
X! 	(0=normal, 1=bold, 4=underlined, 5=blinking, 7=reverse)
X   *   ESC M scrolls the screen backwards if the cursor is on the top line
X   */
X  
X***************
X*** 529,564 ****
X  	   	    case 'm':		/* ESC [nm enables rendition n */
X  	 		switch (value) {
X   			    case 1: /*  BOLD  */
X! 				if (color)
X! 	 				one_con_attribute = /* red fg */
X! 					 	(attr & 0xf0ff) | 0x0400;
X! 				else
X! 		 			one_con_attribute |= 0x0800; /* inten*/
X   				break;
X   
X   			    case 4: /*  UNDERLINE */
X  				if (color)
X! 					one_con_attribute = /* blue fg */
X! 					 (attr & 0xf0ff) | 0x0100;
X  				else
X  					one_con_attribute = /* ul */
X  					 (attr & 0x8900);
X   				break;
X   
X   			    case 5: /*  BLINKING */
X! 				if (color) /* can't blink color */
X! 					one_con_attribute = /* magenta fg */
X! 					 (attr & 0xf0ff) | 0x0500;
X! 				else
X! 		 			one_con_attribute |= /* blink */
X! 					 0x8000;
X   				break;
X   
X   			    case 7: /*  REVERSE  (black on light grey)  */
X  				if (color)
X  	 				one_con_attribute = 
X! 					 ((attr & 0xf000) >> 4) |
X! 					 ((attr & 0x0f00) << 4);
X  				else if ((attr & 0x7000) == 0)
X  					one_con_attribute =
X  					 (attr & 0x8800) | 0x7000;
X--- 547,584 ----
X  	   	    case 'm':		/* ESC [nm enables rendition n */
X  	 		switch (value) {
X   			    case 1: /*  BOLD  */
X! 	 			one_con_attribute |= 0x0800; /* inten */
X   				break;
X   
X   			    case 4: /*  UNDERLINE */
X  				if (color)
X! 					if ((attr & 0x6000) == 0)
X! 						/* cyan on [black|blue] bg
X! 						 * This is not standard,
X! 						 * but it is easier to see.
X! 						 */
X! 						one_con_attribute =
X! 						(attr & 0xf8ff) | 0x0300;
X! 					else
X! 						/* blue on other bg */
X! 						one_con_attribute =
X! 						(attr & 0xf8ff) | 0x0100;
X  				else
X  					one_con_attribute = /* ul */
X  					 (attr & 0x8900);
X   				break;
X   
X   			    case 5: /*  BLINKING */
X! 				/* EGA, CGA, and MONO can all blink */
X! 	 			one_con_attribute |= 0x8000; /* blink */
X   				break;
X   
X   			    case 7: /*  REVERSE  (black on light grey)  */
X  				if (color)
X  	 				one_con_attribute = 
X! 					 ((attr & 0x7000) >> 4) |
X! 					 ((attr & 0x0700) << 4) |
X! 					 (attr & 0x8800);
X  				else if ((attr & 0x7000) == 0)
X  					one_con_attribute =
X  					 (attr & 0x8800) | 0x7000;
X***************
X*** 569,585 ****
X  
X   			    default: if (value >= 30 && value <= 37) {
X  					one_con_attribute = 
X! 					 (attr & 0xf0ff) |
X! 					 (ansi_colors[(value - 30)] << 8);
X! 					blank_color = 
X! 					 (blank_color & 0xf0ff) |
X  					 (ansi_colors[(value - 30)] << 8);
X  				} else if (value >= 40 && value <= 47) {
X  					one_con_attribute = 
X! 					 (attr & 0x0fff) |
X! 					 (ansi_colors[(value - 40)] << 12);
X! 					blank_color =
X! 					 (blank_color & 0x0fff) |
X  					 (ansi_colors[(value - 40)] << 12);
X  				} else
X  	 				one_con_attribute = blank_color;
X--- 589,605 ----
X  
X   			    default: if (value >= 30 && value <= 37) {
X  					one_con_attribute = 
X! 					 (attr & 0xf8ff) |
X! 					 (ansi_colors[(value - 30)] << 8);
X! 					blank_color = 
X! 					 (blank_color & 0xf8ff) |
X  					 (ansi_colors[(value - 30)] << 8);
X  				} else if (value >= 40 && value <= 47) {
X  					one_con_attribute = 
X! 					 (attr & 0x8fff) |
X! 					 (ansi_colors[(value - 40)] << 12);
X! 					blank_color =
X! 					 (blank_color & 0x8fff) |
X  					 (ansi_colors[(value - 40)] << 12);
X  				} else
X  	 				one_con_attribute = blank_color;
X***************
X*** 768,774 ****
X  	vid_retrace = C_VID_MASK + 1;
X    }
X  
X!   set_6845(CUR_SIZE, CURSOR_SHAPE);	/* set cursor shape */
X    set_6845(VID_ORG, 0);			/* use page 0 of video ram */
X    move_to(&tty_struct[0], 0, SCR_LINES-1); /* move cursor to lower left */
X  }
X--- 788,796 ----
X  	vid_retrace = C_VID_MASK + 1;
X    }
X  
X! #ifndef LINE_CURSOR
X!   set_6845(CUR_SIZE, CURSOR_SHAPE);	/* set cursor shape (block) */
X! #endif
X    set_6845(VID_ORG, 0);			/* use page 0 of video ram */
X    move_to(&tty_struct[0], 0, SCR_LINES-1); /* move cursor to lower left */
X  }
/
echo x - /usr/src/local/kernel/start.x.cdif
sed '/^X/s///' > /usr/src/local/kernel/start.x.cdif << '/'
X*** /usr/src/minix/kernel/start.x	Fri Jul 20 01:19:24 1990
X--- start.x	Thu Jul 26 06:24:56 1990
X***************
X*** 50,57 ****
X  #define SET_PROTECT_VEC		0x15	/* set protected mode */
X  #	define SET_PROTECT_FUNC 0x89
X  #define VIDEO			0x10
X! #	define ALTERNATE_SELECT	0x12
X! #	define A_S_INFO		0x10
X  
X  	.text
X  |*===========================================================================*
X--- 50,75 ----
X  #define SET_PROTECT_VEC		0x15	/* set protected mode */
X  #	define SET_PROTECT_FUNC 0x89
X  #define VIDEO			0x10
X! #	define ALTERNATE_SELECT	0x12	/* alternate select (Prt-Sc) */
X! #	define A_S_INFO		0x10
X! #	define SET_VID_MOD	0x00	/* set video mode function */
X! #	define TEXT80		0x03	/* 80x25 16-colour text mode */
X! #	define CHAR_GEN		0x11	/* character generator interface */
X! #	define LOAD_8x8		0x12	/* load the ROM BIOS 8x8 char set */
X! #	define CRTC_PORT	0x3d4	/* CRTC address for colour (EGA) */
X! #	define CUR_SVAL		0x06	/* cursor start value (underscore) */
X! #	define CUR_EVAL		0x00	/* cursor end value (underscore) */
X! #	define CUR_SREG		0x0a	/* cursor start register number */
X! #	define CUR_EREG		0x0b	/* cursor end register number */
X! #	define PRT_SC		0x20	/* select alternate Prt-Sc routine */
X! #	define SCRL_WINUP	0x06	/* scroll window up function */
X! #	define VIDATT		0x02	/* video attributes green/black */
X! #	define LINE_WIDTH	80	/* number of characters per line */
X! #	ifdef EGA43
X! #		define SCR_LINES 43	/* number of lines on the screen */
X! #	else
X! #		define SCR_LINES 25	/* number of lines on the screen */
X! #	endif
X  
X  	.text
X  |*===========================================================================*
X***************
X*** 174,179 ****
X--- 192,243 ----
X  	movb	al,bl		| success is determined by knowing
X  	movb	ah,#0		| a successful call will change bl
X  	sub	ax,#A_S_INFO	| nonzero means it is EGA
X+ 	push	ax		| save correct return value
X+ 
X+ #ifdef EGA43
X+ 	jz	no_43		| non-EGA can't do 43-line mode
X+ 
X+ | If the display is an EGA (or VGA),
X+ |	Then establish 43-line mode.
X+ |	We have to do this now, as we can't do it in protected mode.
X+ 
X+ 	movb	ah,#SET_VID_MOD	| set video mode function
X+ 	movb	al,#TEXT80	| 80x25 16-colour text mode
X+ 	int	VIDEO
X+ 
X+ 	movb	ah,#CHAR_GEN	| character generator interface function
X+ 	movb	al,#LOAD_8x8	| load the ROM BIOS 8x8 character set
X+ 	movb	bl,#0		| bl = block to load
X+ 	int	VIDEO		| load 8x8 characters into RAM
X+ 
X+ 				| set up for underscore cursor
X+ 				| console.c code will change to block cursor
X+ 				|	unless disabled by compiling with
X+ 				|	-DLINE_CURSOR
X+ 	mov	dx,#CRTC_PORT	| CRTC address port for colour
X+ 	movb	ah,#CUR_SVAL	| cursor start value
X+ 	movb	al,#CUR_SREG	| cursor start register number
X+ 	outw			| update CRTC Cursor Start register
X+ 	movb	ah,#CUR_EVAL	| cursor end value
X+ 	movb	al,#CUR_EREG	| cursor end register number
X+ 	outw			| update CRTC Cursor End register
X+ 
X+ 	movb	ah,#ALTERNATE_SELECT	| alternate select function
X+ 	movb	bl,#PRT_SC	| use alternate video BIOS Prt-Sc routine
X+ 	int	VIDEO		| update INT 5 vector (print screen)
X+ #endif
X+ 
X+ no_43:
X+ 				| Use scroll window to clear screen
X+ 	movb	ah,#SCRL_WINUP	| scroll window up
X+ 	movb	al,#0		| number of lines to scroll
X+ 	movb	bh,#VIDATT	| and set the video attributes
X+ 	xor	cx,cx
X+ 	movb	dh,#SCR_LINES-1	| number of lines on the screen
X+ 	movb	dl,#LINE_WIDTH-1 | number of characters per line
X+ 	int	VIDEO
X+ 
X+ 	pop	ax		| pass correct return value
X  	ret
X  
X  
/
echo x - /usr/src/local/kernel/tty.c.cdif
sed '/^X/s///' > /usr/src/local/kernel/tty.c.cdif << '/'
X*** /usr/src/minix/kernel/tty.c	Fri Jul 20 01:19:27 1990
X--- tty.c	Mon Jul 23 03:52:35 1990
X***************
X*** 281,289 ****
X  
X  		/* Now do kill processing (remove current line). */
X  		if (ch == tp->tty_kill && tp->tty_escaped == NOT_ESCAPED) {
X! 			while(chuck(tp) == OK)	/* keep looping */ ;
X! 			echo(tp, tp->tty_kill);
X! 			echo(tp, '\n');
X  			return;
X  		}
X  
X--- 281,291 ----
X  
X  		/* Now do kill processing (remove current line). */
X  		if (ch == tp->tty_kill && tp->tty_escaped == NOT_ESCAPED) {
X! 			while(chuck(tp) == OK)
X! 				/* keep looping */
X! 				back_over(tp);
X! 			/* echo(tp, tp->tty_kill); */
X! 			/* echo(tp, '\n'); */
X  			return;
X  		}
X  
/
echo x - /usr/src/local/kernel/tty.h.cdif
sed '/^X/s///' > /usr/src/local/kernel/tty.h.cdif << '/'
X*** /usr/src/minix/kernel/tty.h	Fri Jul 20 01:19:27 1990
X--- tty.h	Mon Jul 23 03:43:20 1990
X***************
X*** 9,17 ****
X  #define MAX_ESC_PARMS      2	/* number of escape sequence params allowed */
X  
X  #define ERASE_CHAR      '\b'	/* default erase character */
X! #define KILL_CHAR        '@'	/* default kill character */
X! #define INTR_CHAR (char)0177	/* default interrupt character */
X! #define QUIT_CHAR (char) 034	/* default quit character */
X  #define XOFF_CHAR (char) 023	/* default x-off character (CTRL-S) */
X  #define XON_CHAR  (char) 021	/* default x-on character (CTRL-Q) */
X  #define EOT_CHAR  (char) 004	/* CTRL-D */
X--- 9,17 ----
X  #define MAX_ESC_PARMS      2	/* number of escape sequence params allowed */
X  
X  #define ERASE_CHAR      '\b'	/* default erase character */
X! #define KILL_CHAR        025	/* default kill character ^U (was '@') */
X! #define INTR_CHAR        003	/* default interrupt character ^C (was 0177) */
X! #define QUIT_CHAR (char) 034	/* default quit character ^\ */
X  #define XOFF_CHAR (char) 023	/* default x-off character (CTRL-S) */
X  #define XON_CHAR  (char) 021	/* default x-on character (CTRL-Q) */
X  #define EOT_CHAR  (char) 004	/* CTRL-D */
X***************
X*** 75,82 ****
X  
X    /* User settable characters: erase, kill, interrupt, quit, x-on; x-off. */
X    char tty_erase;		/* char used to erase 1 char (init ^H) */
X!   char tty_kill;		/* char used to erase a line (init @) */
X!   char tty_intr;		/* char used to send SIGINT  (init DEL) */
X    char tty_quit;		/* char used for core dump   (init CTRL-\) */
X    char tty_xon;			/* char used to start output (init CTRL-Q)*/
X    char tty_xoff;		/* char used to stop output  (init CTRL-S) */
X--- 75,82 ----
X  
X    /* User settable characters: erase, kill, interrupt, quit, x-on; x-off. */
X    char tty_erase;		/* char used to erase 1 char (init ^H) */
X!   char tty_kill;		/* char used to erase a line (init ^U was @) */
X!   char tty_intr;		/* char used to send SIGINT  (init ^C was DEL) */
X    char tty_quit;		/* char used for core dump   (init CTRL-\) */
X    char tty_xon;			/* char used to start output (init CTRL-Q)*/
X    char tty_xoff;		/* char used to stop output  (init CTRL-S) */
/
echo x - /usr/src/local/commands/stty.c.cdif
sed '/^X/s///' > /usr/src/local/commands/stty.c.cdif << '/'
X*** /usr/src/minix/commands/stty.c	Fri Jul 20 00:15:35 1990
X--- stty.c	Mon Jul 23 03:17:56 1990
X***************
X*** 12,18 ****
X  #define STOPC	 023		/* CTRL-S */
X  #define QUITC	 034		/* CTRL-\ */
X  #define EOFC	 004		/* CTRL-D */
X! #define DELC	0177		/* DEL */
X  #define BYTE    0377
X  #define FD         0		/* which file descriptor to use */
X  
X--- 12,19 ----
X  #define STOPC	 023		/* CTRL-S */
X  #define QUITC	 034		/* CTRL-\ */
X  #define EOFC	 004		/* CTRL-D */
X! #define DELC	 003		/* CTRL-C */	/* 0177 DEL */
X! #define KILLC	 025		/* CTRL-U */	/* '@' */
X  #define BYTE    0377
X  #define FD         0		/* which file descriptor to use */
X  
X***************
X*** 262,268 ****
X  	args.sg_flags = ECHO | CRMOD | XTABS | BITS8;
X  	args.sg_ispeed = B1200;
X  	args.sg_ospeed = B1200;
X! 	args.sg_kill = '@';
X  	args.sg_erase = '\b';
X  	tch.t_intrc = DELC;
X  	tch.t_quitc = QUITC;
X--- 263,269 ----
X  	args.sg_flags = ECHO | CRMOD | XTABS | BITS8;
X  	args.sg_ispeed = B1200;
X  	args.sg_ospeed = B1200;
X! 	args.sg_kill = KILLC;
X  	args.sg_erase = '\b';
X  	tch.t_intrc = DELC;
X  	tch.t_quitc = QUITC;
/
echo x - /usr/src/local/tools/bootblok1200.s
sed '/^X/s///' > /usr/src/local/tools/bootblok1200.s << '/'
X| When the PC is powered on, it reads the first block from the floppy
X| disk into address 0x7C00 and jumps to it.  This boot block must contain
X| the boot program in this file.  The boot program first copies itself to
X| address 256K - 1536 (to get itself out of the way).  Then it loads the 
X| operating system from the boot diskette into memory, and then jumps to menu.
X| Loading is not trivial because the PC is unable to read a track into
X| memory across a 64K boundary, so the positioning of everything is critical.
X| The number of sectors to load is contained at address 504 of this block.
X| The value is put there by the build program after it has discovered how
X| big the operating system is.  When the bootblok program is finished loading,
X| it jumps indirectly to the program (menu) which address is given by the
X| last two words in the boot block. 
X|
X| Summary of the words patched into the boot block by build:
X| Word at 504: # sectors to load
X| Word at 506: # DS value for menu
X| Word at 508: # PC value for menu
X| Word at 510: # CS value for menu
X|
X| This version of the boot block must be assembled without separate I & D
X| space.  
X
X        LOADSEG = 0x0060         | here the boot block will start loading
X        BIOSSEG = 0x07C0         | here the boot block itself is loaded
X        BOOTSEG = 0x3FA0         | here it will copy itself (256K-1.5K)
X        DSKBASE = 120            | 120 = 4 * 0x1E = ptr to disk parameters
X
Xfinal   = 504
Xmenu_ds = 506
Xmenu_pc = 508
Xmenu_cs = 510
X
X
X.globl begtext, begdata, begbss, endtext, enddata, endbss  | asld needs these
X.text
Xbegtext:
X.data
Xbegdata:
X.bss
Xbegbss:
X.text
X
X| copy bootblock to bootseg
X        mov     ax,#BIOSSEG
X        mov     ds,ax
X        xor     si,si           | ds:si - original block
X        mov     ax,#BOOTSEG
X        mov     es,ax
X        xor     di,di           | es:di - new block
X        mov     cx,#256         | #  words to move
X	rep
X	movw			| copy loop
X    
X	
X| start boot procedure
X	jmpi	start, BOOTSEG	| set cs to BOOTSEG
X
Xstart:
X	mov     dx,cs
X        mov     ds,dx           | set ds to cs
X        xor     ax,ax
X        mov     es,ax           | set es to 0
X        mov     ss,dx           | set ss to cs i.e., stack in high core
X        mov     sp,#1536        | initialize sp to high core
X
X| print greeting
X	mov	ax,#2		| reset video
X	int	0x10
X
X        mov     ax,#0x0200	| BIOS call in put cursor in ul corner
X        xor     bx,bx
X        xor     dx,dx
X        int     0x10
X        mov     bx,#greet
X        call    print
X
X| Set up for 1.2M disk.
X
X	xor	ax,ax
X	mov	es,ax
X	mov	dx,ds
X	mov	ax,#atpar
X	seg	es
X	mov	DSKBASE,ax
X	seg	es
X	mov	DSKBASE+2,dx
X
X	xor	ax,ax		| reset drive
X	int	0x13
X
X| Load the operating system from diskette.
Xload:
X	call	setreg		| set up ah, cx, dx
X	mov	bx,disksec	| bx = number of next sector to read
X	add	bx,#2		| diskette sector 1 goes at 1536 ("sector" 3)
X	shl	bx,#1		| multiply sector number by 32
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	mov	es,bx		| core address is es:bx (with bx = 0)
X	xor	bx,bx		| see above
X	add	disksec,ax	| ax tells how many sectors to read
X	movb	ah,#2		| opcode for read
X	int	0x13		| call the BIOS for a read
X	jb	error		| jump on diskette error
X	mov	ax,disksec	| see if we are done loading
X	cmp	ax,final	| ditto
X	jb	load		| jump if there is more to load
X
X| Loading done.  Finish up.
X        mov     dx,#0x03F2      | kill the motor
X        mov     ax,#0x000C
X        out
X        cli
X	mov	bx,tracksiz	| menu expects # sectors/track in bx
X        mov     ax,menu_ds      | set segment registers
X        mov     ds,ax           | when sep I&D DS != CS
X        mov     es,ax           | otherwise they are the same.
X        mov     ss,ax           | words 504 - 510 are patched by build
X
X	seg cs
X	jmpi	@menu_pc	| jmp to menu
X
X| Given the number of the next disk block to read, disksec, compute the
X| cylinder, sector, head, and number of sectors to read as follows:
X| ah = # sectors to read;  cl = sector #;  ch = cyl;  dh = head; dl = 0
Xsetreg:	
X	mov	si,tracksiz	| 9 (PC) or 15 (AT) sectors per track
X	mov 	ax,disksec	| ax = next sector to read
X	xor	dx,dx		| dx:ax = 32-bit dividend
X	div	si		| divide sector # by track size
X	mov	cx,ax		| cx = track #; dx = sector (0-origin)
X	mov	bx,dx		| bx = sector number (0-origin)
X	mov	ax,disksec	| ax = next sector to read
X	add	ax,si		| ax = last sector to read + 1
X	dec	ax		| ax = last sector to read
X	xor	dx,dx		| dx:ax = 32-bit dividend
X	div	tracksiz	| divide last sector by track size
X	cmpb	al,cl		| is starting track = ending track
X	je	set1		| jump if whole read on 1 cylinder
X	sub	si,dx		| compute lower sector count
X	dec	si		| si = # sectors to read
X
X| Check to see if this read crosses a 64K boundary (128 sectors).
X| Such calls must be avoided.  The BIOS gets them wrong.
Xset1:	mov	ax,disksec	| ax = next sector to read
X	add	ax,#2		| disk sector 1 goes in core sector 3
X	mov	dx,ax		| dx = next sector to read
X	add	dx,si		| dx = one sector beyond end of read
X	dec	dx		| dx = last sector to read
X	shl	ax,#1		| ah = which 64K bank does read start at
X	shl	dx,#1		| dh = which 64K bank foes read end in
X	cmpb	ah,dh		| ah != dh means read crosses 64K boundary
X	je	set2		| jump if no boundary crossed
X	shrb	dl,#1		| dl = excess beyond 64K boundary
X	xorb	dh,dh		| dx = excess beyond 64K boundary
X	sub	si,dx		| adjust si
X	dec	si		| si = number of sectors to read
X
Xset2:	mov	ax,si		| ax = number of sectors to read
X	xor	dx,dx		| dh = head, dl = drive
X	movb	dh,cl		| dh = track
X	andb	dh,#0x01	| dh = head
X	movb	ch,cl		| ch = track to read
X	shrb	ch,#1		| ch = cylinder
X	movb	cl,bl		| cl = sector number (0-origin)
X	incb	cl		| cl = sector number (1-origin)
X	xorb	dl,dl		| dl = drive number (0)
X	ret			| return values in ax, cx, dx
X
X
X|-------------------------------+
X|    error & print routines     |
X|-------------------------------+
X
Xerror:
X        push    ax
X        mov     bx,#fderr
X        call    print           | print msg
X	xor	cx,cx
Xerr1:	mul	0		| delay
X	loop	err1
X	int	0x19
X
X
Xprint:                          | print string (bx)
X        movb	al,(bx)	        | al contains char to be printed
X        testb   al,al           | null char?
X        jne     prt1            | no
X        ret                     | else return
Xprt1:   movb    ah,#14          | 14 = print char
X        inc     bx              | increment string pointer
X        push    bx              | save bx
X        movb    bl,#1           | foreground color
X	xorb	bh,bh		| page 0
X        int     0x10            | call BIOS VIDEO_IO
X        pop     bx              | restore bx
X        jmp     print           | next character
X
X
Xdisksec:.word 1
Xpcpar:	.byte	0xDF, 0x02, 25, 2, 9, 0x2A, 0xFF, 0x50, 0xF6, 1, 3 | for pc
Xatpar:	.byte	0xDF, 0x02, 25, 2,15, 0x1B, 0xFF, 0x54, 0xF6, 1, 8 | for at
X
Xfderr:	.asciz "Read error.  Automatic reboot.\r\n"
Xgreet:	.asciz "\rBooting MINIX 1.5.  Copyright 1991 Prentice-Hall, Inc.\r\n"
Xtracksiz:.word 15	| changed to 9 for ps and pc
X
X| Don't forget that words 504 - 510 are filled in by build.  The regular
X| code had better not get that far.
X.text
Xendtext:
X.data
Xenddata:
X.bss
Xendbss:
/
echo x - /usr/src/local/tools/bootblok360.s
sed '/^X/s///' > /usr/src/local/tools/bootblok360.s << '/'
X| When the PC is powered on, it reads the first block from the floppy
X| disk into address 0x7C00 and jumps to it.  This boot block must contain
X| the boot program in this file.  The boot program first copies itself to
X| address 256K - 1536 (to get itself out of the way).  Then it loads the 
X| operating system from the boot diskette into memory, and then jumps to menu.
X| Loading is not trivial because the PC is unable to read a track into
X| memory across a 64K boundary, so the positioning of everything is critical.
X| The number of sectors to load is contained at address 504 of this block.
X| The value is put there by the build program after it has discovered how
X| big the operating system is.  When the bootblok program is finished loading,
X| it jumps indirectly to the program (menu) which address is given by the
X| last two words in the boot block. 
X|
X| Summary of the words patched into the boot block by build:
X| Word at 504: # sectors to load
X| Word at 506: # DS value for menu
X| Word at 508: # PC value for menu
X| Word at 510: # CS value for menu
X|
X| This version of the boot block must be assembled without separate I & D
X| space.  
X
X        LOADSEG = 0x0060         | here the boot block will start loading
X        BIOSSEG = 0x07C0         | here the boot block itself is loaded
X        BOOTSEG = 0x3FA0         | here it will copy itself (256K-1.5K)
X        DSKBASE = 120            | 120 = 4 * 0x1E = ptr to disk parameters
X
Xfinal   = 504
Xmenu_ds = 506
Xmenu_pc = 508
Xmenu_cs = 510
X
X
X.globl begtext, begdata, begbss, endtext, enddata, endbss  | asld needs these
X.text
Xbegtext:
X.data
Xbegdata:
X.bss
Xbegbss:
X.text
X
X| copy bootblock to bootseg
X        mov     ax,#BIOSSEG
X        mov     ds,ax
X        xor     si,si           | ds:si - original block
X        mov     ax,#BOOTSEG
X        mov     es,ax
X        xor     di,di           | es:di - new block
X        mov     cx,#256         | #  words to move
X	rep
X	movw			| copy loop
X    
X	
X| start boot procedure
X	jmpi	start, BOOTSEG	| set cs to BOOTSEG
X
Xstart:
X	mov     dx,cs
X        mov     ds,dx           | set ds to cs
X        xor     ax,ax
X        mov     es,ax           | set es to 0
X        mov     ss,dx           | set ss to cs i.e., stack in high core
X        mov     sp,#1536        | initialize sp to high core
X
X| print greeting
X	mov	ax,#2		| reset video
X	int	0x10
X
X        mov     ax,#0x0200	| BIOS call in put cursor in ul corner
X        xor     bx,bx
X        xor     dx,dx
X        int     0x10
X        mov     bx,#greet
X        call    print
X
X| Set up for 360K disk.
X
X	mov	tracksiz,#9
X	xor	ax,ax
X	mov	es,ax
X	mov	dx,ds
X	mov	ax,#pcpar
X	seg	es
X	mov	DSKBASE,ax
X	seg	es
X	mov	DSKBASE+2,dx
X	xor	ax,ax		| diskette reset
X	int	0x13
X
X| Load the operating system from diskette.
Xload:
X	call	setreg		| set up ah, cx, dx
X	mov	bx,disksec	| bx = number of next sector to read
X	add	bx,#2		| diskette sector 1 goes at 1536 ("sector" 3)
X	shl	bx,#1		| multiply sector number by 32
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	mov	es,bx		| core address is es:bx (with bx = 0)
X	xor	bx,bx		| see above
X	add	disksec,ax	| ax tells how many sectors to read
X	movb	ah,#2		| opcode for read
X	int	0x13		| call the BIOS for a read
X	jb	error		| jump on diskette error
X	mov	ax,disksec	| see if we are done loading
X	cmp	ax,final	| ditto
X	jb	load		| jump if there is more to load
X
X| Loading done.  Finish up.
X        mov     dx,#0x03F2      | kill the motor
X        mov     ax,#0x000C
X        out
X        cli
X	mov	bx,tracksiz	| menu expects # sectors/track in bx
X        mov     ax,menu_ds      | set segment registers
X        mov     ds,ax           | when sep I&D DS != CS
X        mov     es,ax           | otherwise they are the same.
X        mov     ss,ax           | words 504 - 510 are patched by build
X
X	seg cs
X	jmpi	@menu_pc	| jmp to menu
X
X| Given the number of the next disk block to read, disksec, compute the
X| cylinder, sector, head, and number of sectors to read as follows:
X| ah = # sectors to read;  cl = sector #;  ch = cyl;  dh = head; dl = 0
Xsetreg:	
X	mov	si,tracksiz	| 9 (PC) or 15 (AT) sectors per track
X	mov 	ax,disksec	| ax = next sector to read
X	xor	dx,dx		| dx:ax = 32-bit dividend
X	div	si		| divide sector # by track size
X	mov	cx,ax		| cx = track #; dx = sector (0-origin)
X	mov	bx,dx		| bx = sector number (0-origin)
X	mov	ax,disksec	| ax = next sector to read
X	add	ax,si		| ax = last sector to read + 1
X	dec	ax		| ax = last sector to read
X	xor	dx,dx		| dx:ax = 32-bit dividend
X	div	tracksiz	| divide last sector by track size
X	cmpb	al,cl		| is starting track = ending track
X	je	set1		| jump if whole read on 1 cylinder
X	sub	si,dx		| compute lower sector count
X	dec	si		| si = # sectors to read
X
X| Check to see if this read crosses a 64K boundary (128 sectors).
X| Such calls must be avoided.  The BIOS gets them wrong.
Xset1:	mov	ax,disksec	| ax = next sector to read
X	add	ax,#2		| disk sector 1 goes in core sector 3
X	mov	dx,ax		| dx = next sector to read
X	add	dx,si		| dx = one sector beyond end of read
X	dec	dx		| dx = last sector to read
X	shl	ax,#1		| ah = which 64K bank does read start at
X	shl	dx,#1		| dh = which 64K bank foes read end in
X	cmpb	ah,dh		| ah != dh means read crosses 64K boundary
X	je	set2		| jump if no boundary crossed
X	shrb	dl,#1		| dl = excess beyond 64K boundary
X	xorb	dh,dh		| dx = excess beyond 64K boundary
X	sub	si,dx		| adjust si
X	dec	si		| si = number of sectors to read
X
Xset2:	mov	ax,si		| ax = number of sectors to read
X	xor	dx,dx		| dh = head, dl = drive
X	movb	dh,cl		| dh = track
X	andb	dh,#0x01	| dh = head
X	movb	ch,cl		| ch = track to read
X	shrb	ch,#1		| ch = cylinder
X	movb	cl,bl		| cl = sector number (0-origin)
X	incb	cl		| cl = sector number (1-origin)
X	xorb	dl,dl		| dl = drive number (0)
X	ret			| return values in ax, cx, dx
X
X
X|-------------------------------+
X|    error & print routines     |
X|-------------------------------+
X
Xerror:
X        push    ax
X        mov     bx,#fderr
X        call    print           | print msg
X	xor	cx,cx
Xerr1:	mul	0		| delay
X	loop	err1
X	int	0x19
X
X
Xprint:                          | print string (bx)
X        movb	al,(bx)	        | al contains char to be printed
X        testb   al,al           | null char?
X        jne     prt1            | no
X        ret                     | else return
Xprt1:   movb    ah,#14          | 14 = print char
X        inc     bx              | increment string pointer
X        push    bx              | save bx
X        movb    bl,#1           | foreground color
X	xorb	bh,bh		| page 0
X        int     0x10            | call BIOS VIDEO_IO
X        pop     bx              | restore bx
X        jmp     print           | next character
X
X
Xdisksec:.word 1
Xpcpar:	.byte	0xDF, 0x02, 25, 2, 9, 0x2A, 0xFF, 0x50, 0xF6, 1, 3 | for pc
Xatpar:	.byte	0xDF, 0x02, 25, 2,15, 0x1B, 0xFF, 0x54, 0xF6, 1, 8 | for at
X
Xfderr:	.asciz "Read error.  Automatic reboot.\r\n"
Xgreet:	.asciz "\rBooting MINIX 1.5.  Copyright 1991 Prentice-Hall, Inc.\r\n"
Xtracksiz:.word 15	| changed to 9 for ps and pc
X
X| Don't forget that words 504 - 510 are filled in by build.  The regular
X| code had better not get that far.
X.text
Xendtext:
X.data
Xenddata:
X.bss
Xendbss:
/
echo x - /usr/src/local/tools/bootblok720.s
sed '/^X/s///' > /usr/src/local/tools/bootblok720.s << '/'
X| When the PC is powered on, it reads the first block from the floppy
X| disk into address 0x7C00 and jumps to it.  This boot block must contain
X| the boot program in this file.  The boot program first copies itself to
X| address 256K - 1536 (to get itself out of the way).  Then it loads the 
X| operating system from the boot diskette into memory, and then jumps to menu.
X| Loading is not trivial because the PC is unable to read a track into
X| memory across a 64K boundary, so the positioning of everything is critical.
X| The number of sectors to load is contained at address 504 of this block.
X| The value is put there by the build program after it has discovered how
X| big the operating system is.  When the bootblok program is finished loading,
X| it jumps indirectly to the program (menu) which address is given by the
X| last two words in the boot block. 
X|
X| Summary of the words patched into the boot block by build:
X| Word at 504: # sectors to load
X| Word at 506: # DS value for menu
X| Word at 508: # PC value for menu
X| Word at 510: # CS value for menu
X|
X| This version of the boot block must be assembled without separate I & D
X| space.  
X
X        LOADSEG = 0x0060         | here the boot block will start loading
X        BIOSSEG = 0x07C0         | here the boot block itself is loaded
X        BOOTSEG = 0x3FA0         | here it will copy itself (256K-1.5K)
X        DSKBASE = 120            | 120 = 4 * 0x1E = ptr to disk parameters
X
Xfinal   = 504
Xmenu_ds = 506
Xmenu_pc = 508
Xmenu_cs = 510
X
X
X.globl begtext, begdata, begbss, endtext, enddata, endbss  | asld needs these
X.text
Xbegtext:
X.data
Xbegdata:
X.bss
Xbegbss:
X.text
X
X| copy bootblock to bootseg
X        mov     ax,#BIOSSEG
X        mov     ds,ax
X        xor     si,si           | ds:si - original block
X        mov     ax,#BOOTSEG
X        mov     es,ax
X        xor     di,di           | es:di - new block
X        mov     cx,#256         | #  words to move
X	rep
X	movw			| copy loop
X    
X	
X| start boot procedure
X	jmpi	start, BOOTSEG	| set cs to BOOTSEG
X
Xstart:
X	mov     dx,cs
X        mov     ds,dx           | set ds to cs
X        xor     ax,ax
X        mov     es,ax           | set es to 0
X        mov     ss,dx           | set ss to cs i.e., stack in high core
X        mov     sp,#1536        | initialize sp to high core
X
X| print greeting
X	mov	ax,#2		| reset video
X	int	0x10
X
X        mov     ax,#0x0200	| BIOS call in put cursor in ul corner
X        xor     bx,bx
X        xor     dx,dx
X        int     0x10
X        mov     bx,#greet
X        call    print
X
X| Set up for 720K disk.
X
X	mov	tracksiz,#9
X	xor	ax,ax		| ps disk parameters are in ROM F01520
X	mov	es,ax
X	mov	ax,#0x1520
X	seg	es
X	mov	DSKBASE,ax
X	mov	ax,#0xF000	
X	seg	es
X	mov	DSKBASE+2,ax
X
X	xor	ax,ax		| diskette reset
X	int	0x13
X
X| Load the operating system from diskette.
Xload:
X	call	setreg		| set up ah, cx, dx
X	mov	bx,disksec	| bx = number of next sector to read
X	add	bx,#2		| diskette sector 1 goes at 1536 ("sector" 3)
X	shl	bx,#1		| multiply sector number by 32
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	shl	bx,#1		| ditto
X	mov	es,bx		| core address is es:bx (with bx = 0)
X	xor	bx,bx		| see above
X	add	disksec,ax	| ax tells how many sectors to read
X	movb	ah,#2		| opcode for read
X	int	0x13		| call the BIOS for a read
X	jb	error		| jump on diskette error
X	mov	ax,disksec	| see if we are done loading
X	cmp	ax,final	| ditto
X	jb	load		| jump if there is more to load
X
X| Loading done.  Finish up.
X        mov     dx,#0x03F2      | kill the motor
X        mov     ax,#0x000C
X        out
X        cli
X	mov	bx,tracksiz	| menu expects # sectors/track in bx
X        mov     ax,menu_ds      | set segment registers
X        mov     ds,ax           | when sep I&D DS != CS
X        mov     es,ax           | otherwise they are the same.
X        mov     ss,ax           | words 504 - 510 are patched by build
X
X	seg cs
X	jmpi	@menu_pc	| jmp to menu
X
X| Given the number of the next disk block to read, disksec, compute the
X| cylinder, sector, head, and number of sectors to read as follows:
X| ah = # sectors to read;  cl = sector #;  ch = cyl;  dh = head; dl = 0
Xsetreg:	
X	mov	si,tracksiz	| 9 (PC) or 15 (AT) sectors per track
X	mov 	ax,disksec	| ax = next sector to read
X	xor	dx,dx		| dx:ax = 32-bit dividend
X	div	si		| divide sector # by track size
X	mov	cx,ax		| cx = track #; dx = sector (0-origin)
X	mov	bx,dx		| bx = sector number (0-origin)
X	mov	ax,disksec	| ax = next sector to read
X	add	ax,si		| ax = last sector to read + 1
X	dec	ax		| ax = last sector to read
X	xor	dx,dx		| dx:ax = 32-bit dividend
X	div	tracksiz	| divide last sector by track size
X	cmpb	al,cl		| is starting track = ending track
X	je	set1		| jump if whole read on 1 cylinder
X	sub	si,dx		| compute lower sector count
X	dec	si		| si = # sectors to read
X
X| Check to see if this read crosses a 64K boundary (128 sectors).
X| Such calls must be avoided.  The BIOS gets them wrong.
Xset1:	mov	ax,disksec	| ax = next sector to read
X	add	ax,#2		| disk sector 1 goes in core sector 3
X	mov	dx,ax		| dx = next sector to read
X	add	dx,si		| dx = one sector beyond end of read
X	dec	dx		| dx = last sector to read
X	shl	ax,#1		| ah = which 64K bank does read start at
X	shl	dx,#1		| dh = which 64K bank foes read end in
X	cmpb	ah,dh		| ah != dh means read crosses 64K boundary
X	je	set2		| jump if no boundary crossed
X	shrb	dl,#1		| dl = excess beyond 64K boundary
X	xorb	dh,dh		| dx = excess beyond 64K boundary
X	sub	si,dx		| adjust si
X	dec	si		| si = number of sectors to read
X
Xset2:	mov	ax,si		| ax = number of sectors to read
X	xor	dx,dx		| dh = head, dl = drive
X	movb	dh,cl		| dh = track
X	andb	dh,#0x01	| dh = head
X	movb	ch,cl		| ch = track to read
X	shrb	ch,#1		| ch = cylinder
X	movb	cl,bl		| cl = sector number (0-origin)
X	incb	cl		| cl = sector number (1-origin)
X	xorb	dl,dl		| dl = drive number (0)
X	ret			| return values in ax, cx, dx
X
X
X|-------------------------------+
X|    error & print routines     |
X|-------------------------------+
X
Xerror:
X        push    ax
X        mov     bx,#fderr
X        call    print           | print msg
X	xor	cx,cx
Xerr1:	mul	0		| delay
X	loop	err1
X	int	0x19
X
X
Xprint:                          | print string (bx)
X        movb	al,(bx)	        | al contains char to be printed
X        testb   al,al           | null char?
X        jne     prt1            | no
X        ret                     | else return
Xprt1:   movb    ah,#14          | 14 = print char
X        inc     bx              | increment string pointer
X        push    bx              | save bx
X        movb    bl,#1           | foreground color
X	xorb	bh,bh		| page 0
X        int     0x10            | call BIOS VIDEO_IO
X        pop     bx              | restore bx
X        jmp     print           | next character
X
X
Xdisksec:.word 1
Xpcpar:	.byte	0xDF, 0x02, 25, 2, 9, 0x2A, 0xFF, 0x50, 0xF6, 1, 3 | for pc
Xatpar:	.byte	0xDF, 0x02, 25, 2,15, 0x1B, 0xFF, 0x54, 0xF6, 1, 8 | for at
X
Xfderr:	.asciz "Read error.  Automatic reboot.\r\n"
Xgreet:	.asciz "\rBooting MINIX 1.5.  Copyright 1991 Prentice-Hall, Inc.\r\n"
Xtracksiz:.word 15	| changed to 9 for ps and pc
X
X| Don't forget that words 504 - 510 are filled in by build.  The regular
X| code had better not get that far.
X.text
Xendtext:
X.data
Xenddata:
X.bss
Xendbss:
/
echo x - /usr/src/local/tools/config
sed '/^X/s///' > /usr/src/local/tools/config << '/'
Xprog=`basename $0`
X
Xcase $1 in
X	360)	drive=360;;
X
X	720)	drive=720;;
X
X	1200)	drive=1200;;
X
X	clean)	echo "rm -f bootblok.s"
X		rm -f bootblok.s
X		exit 0;;
X
X	*)	
X		echo "$prog: usage: $prog [ 360 | 720 | 1200 ]"
X		exit 1;;
X
Xesac
X
Xecho "cp bootblok$drive.s bootblok.s"
Xcp bootblok$drive.s bootblok.s
X
Xecho "Now set up to build a boot image for a" $drive "k disk."
X
Xexit 0
/

Ken Hendrickson N8DGN/6      kjh@usc.edu      ...!uunet!usc!pollux!kjh