Files ker2006/bin/autoexec.bat and ker2007/bin/autoexec.bat are identical
Binary files ker2006/bin/command.com and ker2007/bin/command.com differ
Files ker2006/bin/config.sys and ker2007/bin/config.sys are identical
Files ker2006/bin/copying and ker2007/bin/copying are identical
Files ker2006/bin/install.bat and ker2007/bin/install.bat are identical
Binary files ker2006/bin/kernel.sys and ker2007/bin/kernel.sys differ
Binary files ker2006/bin/sys.com and ker2007/bin/sys.com differ
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/boot/boot.asm ker2007/boot/boot.asm
--- ker2006/boot/boot.asm	Thu Apr  1 01:23:20 1999
+++ ker2007/boot/boot.asm	Tue Apr 13 10:52:22 1999
@@ -26,10 +26,16 @@
 ; Cambridge, MA 02139, USA.
 ;
 
 
 ; $Log: BOOT.ASM,v $
+; Revision 1.4  1999/04/13 15:52:22  jprice
+; Moves boot sector to top of mem
+;
+; Revision 1.3  1999/04/06 22:53:36  jprice
+; Put back code to read multiple sectors at a time.
+;
 ; Revision 1.2  1999/04/01 07:23:20  jprice
 ; New boot loader
 ;
 ; Revision 1.1.1.1  1999/03/29 15:39:39  jprice
 ; New version without IPL.SYS
@@ -245,16 +251,17 @@
                 mov     bp, 7c00h
                 lea     sp, [bp-20h]
                 sti
 		int	13h		; reset drive
 		int	12h
-		dec	ah		; move boot sector to higher memory
-		mov	cx, 0106h
+		mov	cl, 6		; move boot sector to higher memory
 		shl	ax, cl
+		sub	ax, 07e0h
 		mov	es, ax
 		mov	si, bp
 		mov	di, bp
+		mov	cx, 256
 		rep	movsw
 		push	es
 		mov	bx, offset cont+7c00h
 		push	bx
 		retf
@@ -262,11 +269,11 @@
 cont:           mov     ds, ax
 		mov	ss, ax
                 mov     drive, dl       ; BIOS passes drive number in DL
 
                 call    print
-                db      "Loading FreeDOS...",13,10,"[root]",0
+                db      "Loading FreeDOS...",13,10,"ROOT",0
 
 IFDEF CALCPARAMS
                 GETDRIVEPARMS
 ENDIF
 
@@ -303,11 +310,11 @@
 
                 jc      boot_error      ; fail if not found
 ffDone:
 
                 call    print
-                db      " [fat]",0
+                db      " FAT",0
 
 
 
 ;       GETFATCHAIN:
 ;
@@ -395,20 +402,18 @@
 
                 push    cs
                 pop     ds
 
                 call    print
-                db      " [kernel]",0
+                db      " KERNEL",0
 
 ;       loadFile: Loads the file into memory, one cluster at a time.
 
                 mov     es, tempbuf     ; set ES:BX to load address
                 xor     bx, bx
 
                 mov     si, FATBUF      ; set DS:SI to the FAT chain
-;                push    cs
-;                pop     ds
 
 cluster_next:   lodsw                           ; AX = next cluster to read
                 or      ax, ax                  ; if EOF...
                 je      boot_success            ; ...boot was successful
 
@@ -423,11 +428,11 @@
                 call    readDisk
                 jnc     cluster_next
 
 
 boot_error:     call    print
-                db      13,10,"BOOT error. Please REBOOT!",0
+                db      13,10,"BOOT error!",0
 
                 jmp     $               ; sleep
 
 boot_success:   call    print
                 db      " GO!",13,10,0
@@ -515,74 +520,69 @@
                 sub     dl, cl
                 inc     cl                      ; sector offset from 1
                 or      cx, ax                  ; merge cylinder into sector
                 mov     al, dl                  ; al has # of sectors left
 
-;                ; Calculate how many sectors can be transfered in this read
-;                ; due to dma boundary conditions.
-;                push    dx
-;
-;                mov     si, di                  ; temp register save
-;                ; this computes remaining bytes because of modulo 65536
-;                ; nature of dma boundary condition
-;                mov     ax, bx                  ; get offset pointer
-;                neg     ax                      ; and convert to bytes
-;                jz      ax_min_1                ; started at seg:0, skip ahead
-;
-;                xor     dx, dx                  ; convert to sectors
-;                div     word ptr bsBytesPerSec
-;
-;                cmp     ax, di                  ; check remainder vs. asked
-;                jb      ax_min_1                ; less, skip ahead
-;                mov     si, ax                  ; transfer only what we can
-;
-;ax_min_1:       pop     dx
-
-;                ; Check that request sectors do not exceed track boundary
-;                mov     si, sectPerTrack
-;                inc     si
-;                mov     ax, cx                  ; get the sector/cyl byte
-;                and     ax, 03fh                ; and mask out sector
-;                sub     si, ax                  ; si has how many we can read
-;                mov     ax, di
-;                cmp     si, di                  ; see if asked <= available
-;                jge     ax_min_2
-;                mov     ax, si                  ; get what can be xfered
+                ; Calculate how many sectors can be transfered in this read
+                ; due to dma boundary conditions.
+                push    dx
+
+                mov     si, di                  ; temp register save
+                ; this computes remaining bytes because of modulo 65536
+                ; nature of dma boundary condition
+                mov     ax, bx                  ; get offset pointer
+                neg     ax                      ; and convert to bytes
+                jz      ax_min_1                ; started at seg:0, skip ahead
+
+                xor     dx, dx                  ; convert to sectors
+                div     word ptr bsBytesPerSec
+
+                cmp     ax, di                  ; check remainder vs. asked
+                jb      ax_min_1                ; less, skip ahead
+                mov     si, ax                  ; transfer only what we can
+
+ax_min_1:       pop     dx
+
+                ; Check that request sectors do not exceed track boundary
+                mov     si, sectPerTrack
+                inc     si
+                mov     ax, cx                  ; get the sector/cyl byte
+                and     ax, 03fh                ; and mask out sector
+                sub     si, ax                  ; si has how many we can read
+                mov     ax, di
+                cmp     si, di                  ; see if asked <= available
+                jge     ax_min_2
+                mov     ax, si                  ; get what can be xfered
 
-;ax_min_2:       mov     ah, 2
-                mov     ax, 0201h
+ax_min_2:       mov     ah, 2
                 mov     dl, drive
                 int     13h
                 jnc     read_ok                 ; jump if no error
                 pop     ax
                 pop     dx                      ; else...
                 jmp     read_next               ; read the same sector again
 
-read_ok:
-;                call    print
-;                db      ".",0
-
-;                push    bx
-;                xor     bh, bh
-;                mov     ax, 0E2Eh               ; show progress (print a dot)
-;                int     10h
-;                pop     bx
-
-                add     bx, word ptr bsBytesPerSec  ; add number of bytes read to BX
+read_ok:	cbw
+		mov	si, ax
+                mul     word ptr bsBytesPerSec  ; add number of bytes read to BX
+		add	bx, ax
                 jnc     no_incr_es              ; if overflow...
 
                 mov     ax, es
                 add     ah, 10h                 ; ...add 1000h to ES
                 mov     es, ax
 
 no_incr_es:     pop     ax
                 pop     dx                      ; DX:AX = last sector number
 
-                add     ax, 1
+;                call    print
+;                db      ".",0
+
+                add     ax, si
                 adc     dx, 0                   ; DX:AX = next sector to read
-                dec     di                      ; if there is anything left to read,
-                jnz     read_next               ; continue
+                sub	di,si                   ; if there is anything left to read,
+                jg      read_next               ; continue
 
                 clc
                 pop     si
                 ret
 readDisk        endp
Files ker2006/boot/boot.mak and ker2007/boot/boot.mak are identical
Files ker2006/bugs.txt and ker2007/bugs.txt are identical
Files ker2006/build.bat and ker2007/build.bat are identical
Files ker2006/build.txt and ker2007/build.txt are identical
Files ker2006/clean.bat and ker2007/clean.bat are identical
Files ker2006/config.mak and ker2007/config.mak are identical
Files ker2006/copying and ker2007/copying are identical
Files ker2006/drivers/console.asm and ker2007/drivers/console.asm are identical
Files ker2006/drivers/devend.asm and ker2007/drivers/devend.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/drivers/device.mak ker2007/drivers/device.mak
--- ker2006/drivers/device.mak	Mon Mar 29 11:08:32 1999
+++ ker2007/drivers/device.mak	Tue Apr 13 10:47:06 1999
@@ -1,11 +1,14 @@
 #
 # makefile for device.lib
 #
-# $Header: /home/cvsroot/fdkernel/DRIVERS/DEVICE.MAK,v 1.2 1999/03/29 17:08:31 jprice Exp $
+# $Header: /home/cvsroot/fdkernel/DRIVERS/DEVICE.MAK,v 1.3 1999/04/13 15:47:07 jprice Exp $
 #
 # $Log: DEVICE.MAK,v $
+# Revision 1.3  1999/04/13 15:47:07  jprice
+# no message
+#
 # Revision 1.2  1999/03/29 17:08:31  jprice
 # ror4 changes
 #
 # Revision 1.1.1.1  1999/03/29 15:40:23  jprice
 # New version without IPL.SYS
@@ -46,25 +49,20 @@
 CFLAGS = -c -m$(MODEL)
 AFLAGS = /Mx /Dmem$(MODEL)=1
 LIBFLAGS = /c
 TERM   =
 
-OBJS   = console.obj devend.obj eoi.obj floppy.obj fmemcmp.obj fmemcpy.obj \
-fmemset.obj inb.obj int86.obj intr.obj inw.obj keyboard.obj outb.obj \
-outw.obj getvec.obj spl.obj timer.obj rdpcclk.obj rdatclk.obj \
+OBJS   = devend.obj floppy.obj getvec.obj timer.obj rdpcclk.obj rdatclk.obj \
 wrpcclk.obj wratclk.obj
 
 #LIBOBJS1= +console +devend +eoi +floppy +fmemcmp +fmemcpy
 #LIBOBJS2= +fmemset +inb +int86 +intr +inw +keyboard +outb
 #LIBOBJS3= +outw +setvec +getvec +spl +timer +rdpcclk +rdatclk
 #LIBOBJS4= +wrpcclk +wratclk
 
 
-LIBOBJS1= +console +devend +eoi +floppy +fmemcmp +fmemcpy
-LIBOBJS2= +fmemset +inb +int86 +inw +keyboard +outb
-LIBOBJS3= +outw +getvec +spl +timer +rdpcclk +rdatclk
-LIBOBJS4= +wrpcclk +wratclk
+LIBOBJS= +devend +floppy +getvec +timer +rdpcclk +rdatclk +wrpcclk +wratclk
 
 
 
 # Build the LIBRARY
 # -----------------
@@ -78,14 +76,11 @@
 clean:
         ..\utils\rm -f device.lib *.obj *.bak *.crf *.xrf *.map *.lst status.me
 
 device.lib : $(OBJS)
         DEL device.lib
-        $(LIB) $(LIBFLAGS) device $(LIBOBJS1) $(TERM)
-        $(LIB) $(LIBFLAGS) device $(LIBOBJS2) $(TERM)
-        $(LIB) $(LIBFLAGS) device $(LIBOBJS3) $(TERM)
-        $(LIB) $(LIBFLAGS) device $(LIBOBJS4) $(TERM)
+        $(LIB) $(LIBFLAGS) device $(LIBOBJS) $(TERM)
 
 
 
 # RULES (DEPENDENCIES)
 # ----------------
Files ker2006/drivers/eoi.asm and ker2007/drivers/eoi.asm are identical
Files ker2006/drivers/floppy.asm and ker2007/drivers/floppy.asm are identical
Files ker2006/drivers/fmemcmp.asm and ker2007/drivers/fmemcmp.asm are identical
Files ker2006/drivers/fmemcpy.asm and ker2007/drivers/fmemcpy.asm are identical
Files ker2006/drivers/fmemset.asm and ker2007/drivers/fmemset.asm are identical
Files ker2006/drivers/getvec.asm and ker2007/drivers/getvec.asm are identical
Files ker2006/drivers/inb.asm and ker2007/drivers/inb.asm are identical
Files ker2006/drivers/int86.asm and ker2007/drivers/int86.asm are identical
Files ker2006/drivers/intr.asm and ker2007/drivers/intr.asm are identical
Files ker2006/drivers/inw.asm and ker2007/drivers/inw.asm are identical
Files ker2006/drivers/keyboard.asm and ker2007/drivers/keyboard.asm are identical
Files ker2006/drivers/outb.asm and ker2007/drivers/outb.asm are identical
Files ker2006/drivers/outw.asm and ker2007/drivers/outw.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/drivers/rdatclk.asm ker2007/drivers/rdatclk.asm
--- ker2006/drivers/rdatclk.asm	Mon Mar 29 11:08:32 1999
+++ ker2007/drivers/rdatclk.asm	Sun Apr 11 22:19:44 1999
@@ -25,13 +25,16 @@
 ; write to the Free Software Foundation, 675 Mass Ave,
 ; Cambridge, MA 02139, USA.
 ;
 ; $Logfile:   C:/dos-c/src/drivers/rdatclk.asv  $
 ;
-; $Header: /home/cvsroot/fdkernel/DRIVERS/RDATCLK.ASM,v 1.2 1999/03/29 17:08:31 jprice Exp $
+; $Header: /home/cvsroot/fdkernel/DRIVERS/RDATCLK.ASM,v 1.3 1999/04/12 03:19:44 jprice Exp $
 ;
 ; $Log: RDATCLK.ASM,v $
+; Revision 1.3  1999/04/12 03:19:44  jprice
+; more ror4 patches
+;
 ; Revision 1.2  1999/03/29 17:08:31  jprice
 ; ror4 changes
 ;
 ; Revision 1.1.1.1  1999/03/29 15:40:31  jprice
 ; New version without IPL.SYS
@@ -91,46 +94,14 @@
 ;
 ;
                 page    60,132
                 title   ReadATClock - sysclock support
 
-IFDEF ??version
-_TEXT           segment byte public 'CODE'
-DGROUP          group   _DATA,_BSS,_BSSEND              ; small model
-                assume  cs:DGROUP,ds:DGROUP,ss:DGROUP
-_TEXT           ends
-
-_DATA           segment word public 'DATA'
-_DATA           ends
-
-_BSS            segment word public 'BSS'
-_BSS            ends
-
-_BSSEND         segment byte public 'BSS'
-;_BSSEND         segment byte public 'STACK'
-_BSSEND         ends
-
-ELSE
-_TEXT           segment byte public 'CODE'
-_TEXT           ends
-
-_DATA           segment word public 'DATA'
-_DATA           ends
-
-_BSS            segment word public 'BSS'
-_BSS            ends
-
-_BSSEND         segment byte public 'BSS'
-;_BSSEND         segment byte public 'STACK'
-_BSSEND         ends
-
-DGROUP          group   _DATA,_BSS,_BSSEND        ; small/tiny model
-                assume  ds:DGROUP, ss:DGROUP
-ENDIF
+IGROUP		group	INIT_TEXT
+		assume	cs:IGROUP
 
-_TEXT           segment byte public 'CODE'
-                assume  cs:_TEXT
+INIT_TEXT	segment byte public 'INIT'
 
 
 ;
 ;COUNT ReadATClock(bcdDays, bcdHours, bcdMinutes, bcdSeconds)
 ;BYTE *bcdDays;
@@ -149,16 +120,14 @@
 ;               Seconds = -10
 ;               bcdSeconds = 10
 ;               bcdMinutes = 8
 ;               bcdHours = 6
 ;               bcdDays = 4
-                mov     cx,-1
                 mov     ah,2
                 int     26
-                cmp     cx,-1
-                jne     $RdAT1140
-                mov     ax,cx
+		jnc	$RdAT1140
+		sbb	ax,ax
                 mov     sp,bp
                 pop     bp
                 ret
                 nop
 $RdAT1140:
@@ -188,8 +157,8 @@
                 pop     bp
                 ret
                 nop
 
 _ReadATClock    ENDP
-_TEXT           ENDS
+INIT_TEXT	ENDS
                 END
 
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/drivers/rdpcclk.asm ker2007/drivers/rdpcclk.asm
--- ker2006/drivers/rdpcclk.asm	Mon Mar 29 11:08:32 1999
+++ ker2007/drivers/rdpcclk.asm	Sun Apr 11 22:19:44 1999
@@ -25,13 +25,16 @@
 ; write to the Free Software Foundation, 675 Mass Ave,
 ; Cambridge, MA 02139, USA.
 ;
 ; $Logfile:   C:/dos-c/src/drivers/rdpcclk.asv  $
 ;
-; $Header: /home/cvsroot/fdkernel/DRIVERS/RDPCCLK.ASM,v 1.2 1999/03/29 17:08:31 jprice Exp $
+; $Header: /home/cvsroot/fdkernel/DRIVERS/RDPCCLK.ASM,v 1.3 1999/04/12 03:19:44 jprice Exp $
 ;
 ; $Log: RDPCCLK.ASM,v $
+; Revision 1.3  1999/04/12 03:19:44  jprice
+; more ror4 patches
+;
 ; Revision 1.2  1999/03/29 17:08:31  jprice
 ; ror4 changes
 ;
 ; Revision 1.1.1.1  1999/03/29 15:40:32  jprice
 ; New version without IPL.SYS
@@ -97,31 +100,17 @@
 ;       BOOL ReadPCClock(Ticks)
 ;       ULONG *Ticks;
 ;
                 PUBLIC  _ReadPCClock
 _ReadPCClock    PROC NEAR
-                push    bp
-                mov     bp,sp
-                sub     sp,6
-;               _Ticks = -6
-;               retcode = -2
-;               Ticks = 4
                 xor     ah,ah
                 int     26
-                xor     ah,ah
-                mov     WORD PTR [bp-6],dx      ;_Ticks
-                mov     WORD PTR [bp-4],cx
-                mov     ax,WORD PTR [bp-6]      ;_Ticks
-                mov     dx,WORD PTR [bp-4]
-                mov     bx,WORD PTR [bp+4]      ;Ticks
-                mov     WORD PTR [bx],ax
-                mov     WORD PTR [bx+2],dx
-                mov     ax,WORD PTR [bp-2]      ;retcode
-                mov     sp,bp
-                pop     bp
+		mov	bx,sp
+		mov	bx,[bx+2]
+                mov     [bx],dx
+                mov     [bx+2],cx
+		cbw
                 ret
-                nop
-
 _ReadPCClock    ENDP
 _TEXT           ENDS
                 END
 
Files ker2006/drivers/spl.asm and ker2007/drivers/spl.asm are identical
Files ker2006/drivers/timer.asm and ker2007/drivers/timer.asm are identical
Files ker2006/drivers/wratclk.asm and ker2007/drivers/wratclk.asm are identical
Files ker2006/drivers/wrpcclk.asm and ker2007/drivers/wrpcclk.asm are identical
Files ker2006/hdr/cds.h and ker2007/hdr/cds.h are identical
Files ker2006/hdr/clock.h and ker2007/hdr/clock.h are identical
Files ker2006/hdr/date.h and ker2007/hdr/date.h are identical
Files ker2006/hdr/dcb.h and ker2007/hdr/dcb.h are identical
Files ker2006/hdr/device.h and ker2007/hdr/device.h are identical
Files ker2006/hdr/dhdr.h and ker2007/hdr/dhdr.h are identical
Files ker2006/hdr/dirmatch.h and ker2007/hdr/dirmatch.h are identical
Files ker2006/hdr/dosnames.h and ker2007/hdr/dosnames.h are identical
Files ker2006/hdr/error.h and ker2007/hdr/error.h are identical
Files ker2006/hdr/exe.h and ker2007/hdr/exe.h are identical
Files ker2006/hdr/fat.h and ker2007/hdr/fat.h are identical
Files ker2006/hdr/fcb.h and ker2007/hdr/fcb.h are identical
Files ker2006/hdr/file.h and ker2007/hdr/file.h are identical
Files ker2006/hdr/fnode.h and ker2007/hdr/fnode.h are identical
Files ker2006/hdr/kbd.h and ker2007/hdr/kbd.h are identical
Files ker2006/hdr/mcb.h and ker2007/hdr/mcb.h are identical
Files ker2006/hdr/pcb.h and ker2007/hdr/pcb.h are identical
Files ker2006/hdr/portab.h and ker2007/hdr/portab.h are identical
Files ker2006/hdr/process.h and ker2007/hdr/process.h are identical
Files ker2006/hdr/sft.h and ker2007/hdr/sft.h are identical
Files ker2006/hdr/stacks.inc and ker2007/hdr/stacks.inc are identical
Files ker2006/hdr/tail.h and ker2007/hdr/tail.h are identical
Files ker2006/hdr/time.h and ker2007/hdr/time.h are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/hdr/version.h ker2007/hdr/version.h
--- ker2006/hdr/version.h	Sun Apr  4 17:57:02 1999
+++ ker2007/hdr/version.h	Sat Apr 10 23:32:20 1999
@@ -26,11 +26,11 @@
 /* Cambridge, MA 02139, USA.                                    */
 /****************************************************************/
 
 #ifdef MAIN
 #ifdef VERSION_STRINGS
-static BYTE *date_hRcsId = "$Id: VERSION.H,v 1.3 1999/04/04 22:57:01 jprice Exp $";
+static BYTE *date_hRcsId = "$Id: VERSION.H,v 1.4 1999/04/11 04:32:20 jprice Exp $";
 #endif
 #endif
 
 #define MAJOR_RELEASE   3
 #define MINOR_RELEASE   31
@@ -38,7 +38,7 @@
 #define REV_NUMBER      0
 #define OEM_ID          0xfd    /* FreeDos version                      */
 
 #define REVISION_MAJOR  1
 #define REVISION_MINOR  1
-#define REVISION_SEQ    4
-#define BUILD           2006
+#define REVISION_SEQ    5
+#define BUILD           2007
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/history.txt ker2007/history.txt
--- ker2006/history.txt	Sun Apr  4 18:00:28 1999
+++ ker2007/history.txt	Tue Apr 13 10:51:46 1999
@@ -1,5 +1,60 @@
+1999 Apr 13 - Build 2007
+-------- ror4 (ror4@cryogen.com)
+* The boot sector now moves itself to the last 512 bytes of
+  conventional memory instead of a lower memory location.
+* The kernel startup code has also been modified so that it works
+  with the new boot sector.
+
+1999 Apr 12 - Build 2007
+-------- ror4 (ror4@cryogen.com)
+* The directory scanning functions (`findfirst'/`findnext') now also
+  recognize more flavours of the volume label attribute byte (namely
+  0x09, 0x28 and 0x29).
+* Subdirectories are now no longer assumed to have the same size as
+  the root directory.
+* `device/device.lib' is now included as a dependency in the kernel
+  makefile.
+* Removed several unused assembler modules from the `device/' branch
+  (see `device/device.mak').
+
+1999 Apr 11 - Build 2007
+-------- ror4 (ror4@cryogen.com)
+* The kernel now reads times from the system clock (0x40:0x6c)
+  instead of the RTC. The RTC is only used during startup to
+  initialize the system clock. (As a side effect of this,
+  `ReadATClock' has been moved from `_TEXT' to `INIT_TEXT'.)
+* Checking for leap years is now improved -- year numbers which are
+  divisible by 100 but not by 400 are not counted as leap years. (Not
+  that it matters for year 2000, though.)
+* The scaling factor used to convert the system time count to a
+  second count has been changed from 18.2 to the more accurate (?)
+  19663/1080.
+* Day numbers used by `clock$' are now 0-based (as in MSDOS) instead
+  of 1-based. Thus 1 Jan 1980 is now day number 0.
+
+1999 Apr 10 - Build 2007
+-------- ror4 (ror4@cryogen.com)
+* Added code to prevent the kernel from returning path names
+  containing double backslashes.
+
+1999 Apr 9 - Build 2007
+-------- ror4 (ror4@usa.net)
+* File handles are now cloned properly when a child process is spawned.
+* The `DosClose' function now also frees SFT entries corresponding to
+  devices, not only those entries corresponding to files.
+* Removed a (minor) memory corruption bug in the code for int 0x21,
+  ah = 0x09.
+
+1999 Apr 6 - Build 2007
+-------- ror4 (ror4@cryogen.com)
+* Functions ax = 0x5700 and 0x5701 (get/set file date and time) now
+  return the right values at the right times. (They used to return
+  success when there's an error, and return error when there's a
+  success.)
+* Removed the `/k' switch to the linker in `sys/sys.mak'.
+
 1999 Apr 4 - Build 2006
 -------- John Price (linux-guru@gcfl.net)
 * added "version=" directive so that you can change the version that
   the kernel reports.  Usage: version=<major>.<minor> (i.e.
   version=6.22)
Files ker2006/intfns.txt and ker2007/intfns.txt are identical
Files ker2006/kernel/001-437.nls and ker2007/kernel/001-437.nls are identical
Files ker2006/kernel/apisupt.asm and ker2007/kernel/apisupt.asm are identical
Files ker2006/kernel/asmsupt.asm and ker2007/kernel/asmsupt.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/blockio.c ker2007/kernel/blockio.c
--- ker2006/kernel/blockio.c	Sun Apr  4 14:25:24 1999
+++ ker2007/kernel/blockio.c	Mon Apr 12 18:41:52 1999
@@ -30,15 +30,25 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *blockioRcsId = "$Id: BLOCKIO.C,v 1.1.1.1 1999/03/29 15:41:43 jprice Exp $";
+static BYTE *blockioRcsId = "$Id: BLOCKIO.C,v 1.5 1999/04/12 23:41:53 jprice Exp $";
 #endif
 
 /*
  * $Log: BLOCKIO.C,v $
+ * Revision 1.5  1999/04/12 23:41:53  jprice
+ * Using getbuf to write data instead of getblock

+ * using getblock made it read the block before it wrote it
+ *
+ * Revision 1.4  1999/04/11 05:28:10  jprice
+ * Working on multi-block IO
+ *
+ * Revision 1.3  1999/04/11 04:33:38  jprice
+ * ror4 patches
+ *
  * Revision 1.1.1.1  1999/03/29 15:41:43  jprice
  * New version without IPL.SYS
  *
  * Revision 1.5  1999/02/09 02:54:23  jprice
  * Added Pat's 1937 kernel patches
@@ -119,10 +129,11 @@
 /*                                                                      */
 /* XXX: This should go into `INIT_TEXT'. -- ror4 */
 VOID FAR init_buffers(void)
 {
   REG WORD i;
+  REG WORD count;
 
   for (i = 0; i < Config.cfgBuffers; ++i)
   {
     buffers[i].b_unit = 0;
     buffers[i].b_flag = 0;
@@ -144,13 +155,15 @@
   /* There is an underlying assumption here that BUFFERSIZE is    */
   /* not 64k.  If it is, this code will fail but then again there */
   /* is no way to make it work because it means that every buffer */
   /* is on a 64k boundary!                                        */
   i = 0;
+  count = 0;
   if (Is64kBoundary(firstbuf->b_buffer))
   {
     firstbuf = &buffers[++i];
+    count++;
   }
 
   /* Now start from the (presumably) buffer[1] and link out any   */
   /* buffer that does straddle a boundary.                        */
   /* Note that i is either 0 or 1 based on the above test.        */
@@ -161,12 +174,14 @@
   {
     if (Is64kBoundary(buffers[i].b_buffer))
     {
       buffers[i - 1].b_next = buffers[i].b_next;
       ++i;
+      count++;
     }
   }
+  printf("%d buffers discarded because of boundary problems.\n",count);
 #endif
 }
 
 /*                                                                      */
 /*      Return the address of a buffer structure containing the         */
@@ -224,10 +239,21 @@
   else
     mbp = NULL;                 /* failure              */
   return (mbp);
 }
 
+/*
+      Return the address of a buffer structure for the
+      requested block.  This is for writing new data to a block, so
+      we really don't care what is in the buffer now.
+
+      returns:
+              TRUE = buffer available, flushed if necessary
+                parameter is filled with pointer to buffer
+              FALSE = there was an error flushing the buffer.
+                parameter is set to NULL
+*/
 BOOL getbuf(struct buffer FAR ** pbp, LONG blkno, COUNT dsk)
 {
   REG struct buffer FAR *bp;
   REG struct buffer FAR *lbp;
   REG struct buffer FAR *mbp;
@@ -260,19 +286,22 @@
       lbp = bp;
       bp = bp->b_next;
     }
   }
   /* The block we need is not in a buffer, we must make a buffer  */
-  /* available, and fill it with the desired block                */
+  /* available. */
 
   /* detach lru buffer                                            */
   if (mbp != NULL)
     mbp->b_next = NULL;
   lbp->b_next = firstbuf;
   firstbuf = lbp;
   if (flush1(lbp))              /* success              */
   {
+	  lbp->b_flag = 0;
+	  lbp->b_blkno = blkno;
+	  lbp->b_unit = dsk;
     *pbp = lbp;
     return TRUE;
   }
   else
     /* failure              */
@@ -280,10 +309,66 @@
     *pbp = NULL;
     return FALSE;
   }
 }
 
+/*    Read one or more blocks into a buffer specified by caller.
+
+      returns:
+              requested block with data
+      failure:
+              returns NULL
+*/
+//BOOL getblocks(LONG startblk, COUNT dsk, UCOUNT numblocks)
+//{
+//  REG struct buffer FAR *bp;
+//  REG struct buffer FAR *lbp;
+//  REG struct buffer FAR *mbp;
+//  REG WORD imsave;
+//
+//  /* Search through buffers to see if the required block  */
+//  /* is already in a buffer                               */
+//
+//  bp = firstbuf;
+//  lbp = NULL;
+//  mbp = NULL;
+//  while (bp != NULL)
+//  {
+//    if ((bp->b_flag & BFR_VALID) && (bp->b_unit == dsk)
+//        && (bp->b_blkno == blkno))
+//    {
+//      /* found it -- rearrange LRU links      */
+//      if (lbp != NULL)
+//      {
+//        lbp->b_next = bp->b_next;
+//        bp->b_next = firstbuf;
+//        firstbuf = bp;
+//      }
+//      return (bp);
+//    }
+//    else
+//    {
+//      mbp = lbp;                /* move along to next buffer */
+//      lbp = bp;
+//      bp = bp->b_next;
+//    }
+//  }
+//  /* The block we need is not in a buffer, we must make a buffer  */
+//  /* available, and fill it with the desired block                */
+//
+//  /* detach lru buffer                                            */
+//  if (mbp != NULL)
+//    mbp->b_next = NULL;
+//  lbp->b_next = firstbuf;
+//  firstbuf = lbp;
+//  if (flush1(lbp) && fill(lbp, blkno, dsk)) /* success             */
+//    mbp = lbp;
+//  else
+//    mbp = NULL;                 /* failure              */
+//  return (mbp);
+//}
+
 /*                                                                      */
 /*      Mark all buffers for a disk as not valid                        */
 /*                                                                      */
 VOID setinvld(REG COUNT dsk)
 {
@@ -328,19 +413,19 @@
   REG WORD ok;
 
   if ((bp->b_flag & BFR_VALID) && (bp->b_flag & BFR_DIRTY))
   {
     ok = dskxfer(bp->b_unit, bp->b_blkno,
-                 (VOID FAR *) bp->b_buffer, DSKWRITE);
+                 (VOID FAR *) bp->b_buffer, 1, DSKWRITE);
     if (bp->b_flag & BFR_FAT)
     {
       int i = bp->b_copies - 1;
 
       do
         ok &= dskxfer(bp->b_unit,
                       bp->b_blkno + i * bp->b_offset,
-                      (VOID FAR *) bp->b_buffer, DSKWRITE);
+                      (VOID FAR *) bp->b_buffer, 1, DSKWRITE);
       while (--i > 0);
     }
   }
   else
     ok = TRUE;
@@ -371,24 +456,26 @@
 }
 
 /*                                                                      */
 /*      Fill the indicated disk buffer with the current track and sector */
 /*                                                                      */
+/* This function assumes that the buffer is ready for use and that the
+   sector is not already in the buffer ring  */
 BOOL fill(REG struct buffer FAR * bp, LONG blkno, COUNT dsk)
 {
   REG WORD ok;
 
-  if ((bp->b_flag & BFR_VALID) && (bp->b_flag & BFR_DIRTY))
-    ok = flush1(bp);
-  else
-    ok = TRUE;
-
-  if (ok && (bp->b_flag & BFR_VALID) && (blkno == bp->b_blkno))
-    return OK;
+//  if ((bp->b_flag & BFR_VALID) && (bp->b_flag & BFR_DIRTY))
+//    ok = flush1(bp);
+//  else
+//    ok = TRUE;
+//
+//  if (ok && (bp->b_flag & BFR_VALID) && (blkno == bp->b_blkno))
+//    return OK;
 
-  if (ok)
-    ok = dskxfer(dsk, blkno, (VOID FAR *) bp->b_buffer, DSKREAD);
+//  if (ok)
+    ok = dskxfer(dsk, blkno, (VOID FAR *) bp->b_buffer, 1, DSKREAD);
   bp->b_flag = BFR_VALID | BFR_DATA;
   bp->b_blkno = blkno;
   bp->b_unit = dsk;
   return (ok);
 }
@@ -396,15 +483,14 @@
 /************************************************************************/
 /*                                                                      */
 /*              Device Driver Interface Functions                       */
 /*                                                                      */
 /************************************************************************/
-
 /*                                                                      */
-/* Transfer a block to/from disk                                        */
+/* Transfer one or more blocks to/from disk                             */
 /*                                                                      */
-BOOL dskxfer(COUNT dsk, LONG blkno, VOID FAR * buf, COUNT mode)
+BOOL dskxfer(COUNT dsk, LONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mode)
 {
   REG struct dpb *dpbp = &blk_devices[dsk];
 
   for (;;)
   {
@@ -415,11 +501,11 @@
         (verify_ena ? C_OUTVFY : C_OUTPUT)
         : C_INPUT;
     IoReqHdr.r_status = 0;
     IoReqHdr.r_meddesc = dpbp->dpb_mdb;
     IoReqHdr.r_trans = (BYTE FAR *) buf;
-    IoReqHdr.r_count = 1;
+    IoReqHdr.r_count = numblocks;
     if (blkno > MAXSHORT)
     {
       IoReqHdr.r_start = HUGECOUNT;
       IoReqHdr.r_huge = blkno - 1;
     }
Files ker2006/kernel/chario.c and ker2007/kernel/chario.c are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/config.c ker2007/kernel/config.c
--- ker2006/kernel/config.c	Sun Apr  4 17:57:48 1999
+++ ker2007/kernel/config.c	Sun Apr 11 22:21:16 1999
@@ -31,15 +31,21 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *RcsId = "$Id: CONFIG.C,v 1.2 1999/04/04 22:57:47 jprice Exp $";
+static BYTE *RcsId = "$Id: CONFIG.C,v 1.5 1999/04/12 03:21:17 jprice Exp $";
 #endif
 
 /*
  * $Log: CONFIG.C,v $
+ * Revision 1.5  1999/04/12 03:21:17  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
+ * Revision 1.4  1999/04/11 04:33:38  jprice
+ * ror4 patches
+ *
  * Revision 1.2  1999/04/04 22:57:47  jprice
  * no message
  *
  * Revision 1.1.1.1  1999/03/29 15:40:46  jprice
  * New version without IPL.SYS
@@ -498,11 +504,11 @@
   char *p;
 
   p = pLine;
   while(*p && *p != '.') p++;
 
-  if (!*p) return;
+  if (*p == '\0') return;
   *p++;
 
   /* Get major number */
   if (GetNumArg(pLine, &major) == (BYTE *) 0)
     return;
Files ker2006/kernel/console.asm and ker2007/kernel/console.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/dosfns.c ker2007/kernel/dosfns.c
--- ker2006/kernel/dosfns.c	Sun Apr  4 14:25:28 1999
+++ ker2007/kernel/dosfns.c	Sun Apr 11 22:21:16 1999
@@ -27,15 +27,21 @@
 /****************************************************************/
 
 #include "portab.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *dosfnsRcsId = "$Id: DOSFNS.C,v 1.2 1999/04/04 18:51:43 jprice Exp $";
+static BYTE *dosfnsRcsId = "$Id: DOSFNS.C,v 1.4 1999/04/12 03:21:17 jprice Exp $";
 #endif
 
 /*
  * $Log: DOSFNS.C,v $
+ * Revision 1.4  1999/04/12 03:21:17  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
+ * Revision 1.3  1999/04/11 04:33:38  jprice
+ * ror4 patches
+ *
  * Revision 1.2  1999/04/04 18:51:43  jprice
  * no message
  *
  * Revision 1.1.1.1  1999/03/29 15:41:52  jprice
  * New version without IPL.SYS
@@ -223,11 +229,11 @@
   else
     /* a block read                            */
   {
     COUNT rc;
 
-    ReadCount = rdwrblock(s->sft_status, bp, n, XFR_READ, &rc);
+    ReadCount = readblock(s->sft_status, bp, n, &rc);
     if (rc != SUCCESS)
     {
       *err = rc;
       return 0;
     }
@@ -404,11 +410,11 @@
   else
     /* a block write                           */
   {
     COUNT rc;
 
-    ReadCount = rdwrblock(s->sft_status, bp, n, XFR_WRITE, &rc);
+    ReadCount = writeblock(s->sft_status, bp, n, &rc);
     if (rc < SUCCESS)
     {
       *err = rc;
       return 0;
     }
@@ -606,11 +612,11 @@
 
   /* now that we have the system file table entry, get the fnode  */
   /* index, and increment the count, so that we've effectively    */
   /* cloned the file.                                             */
   sftp->sft_count += 1;
-  return hndl;
+  return SUCCESS;
 }
 
 COUNT DosDup(COUNT Handle)
 {
   psp FAR *p = MK_FP(cu_psp, 0);
@@ -727,10 +733,12 @@
         sftp->sft_flags =
             (dhp->dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF;
         sftp->sft_psp = cu_psp;
         fbcopy((BYTE FAR *) PriPathName, sftp->sft_name, FNAME_SIZE + FEXT_SIZE);
         sftp->sft_dev = dhp;
+	sftp->sft_date = dos_getdate();
+	sftp->sft_time = dos_gettime();
 
         if (cu_psp != DOS_PSP)
           p->ps_filetab[hndl] = sft_idx;
         return hndl;
       }
@@ -774,11 +782,11 @@
   /* now just drop the count if a device, else    */
   /* call file system handler                     */
   if (s->sft_flags & SFT_FDEVICE)
   {
     p->ps_filetab[hndl] = 0xff;
-
+    s->sft_count -= 1;
     return SUCCESS;
   }
   else
   {
     p->ps_filetab[hndl] = 0xff;
@@ -914,10 +922,18 @@
 
   /* If this is not opened another error          */
   if (s->sft_count == 0)
     return DE_ACCESS;
 
+  /* If SFT entry refers to a device, return the date and time of opening */
+  if (s->sft_flags & SFT_FDEVICE)
+  {
+    *dp = s->sft_date;
+    *tp = s->sft_time;
+    return SUCCESS;
+  }
+
   /* call file system handler                     */
   return dos_getftime(s->sft_status, dp, tp);
 }
 
 COUNT DosSetFtime(COUNT hndl, date FAR * dp, time FAR * tp)
@@ -934,10 +950,14 @@
     return DE_INVLDHNDL;
 
   /* If this is not opened another error          */
   if (s->sft_count == 0)
     return DE_ACCESS;
+
+  /* If SFT entry refers to a device, do nothing */
+  if (s->sft_flags & SFT_FDEVICE)
+    return SUCCESS;
 
   /* call file system handler                     */
   return dos_setftime(s->sft_status, dp, tp);
 }
 #endif
Files ker2006/kernel/dosnames.c and ker2007/kernel/dosnames.c are identical
Files ker2006/kernel/dsk.c and ker2007/kernel/dsk.c are identical
Files ker2006/kernel/entry.asm and ker2007/kernel/entry.asm are identical
Files ker2006/kernel/error.c and ker2007/kernel/error.c are identical
Files ker2006/kernel/execrh.asm and ker2007/kernel/execrh.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/fatdir.c ker2007/kernel/fatdir.c
--- ker2006/kernel/fatdir.c	Sun Apr  4 14:25:36 1999
+++ ker2007/kernel/fatdir.c	Tue Apr 13 10:48:20 1999
@@ -29,15 +29,21 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *fatdirRcsId = "$Id: FATDIR.C,v 1.2 1999/04/04 18:51:43 jprice Exp $";
+static BYTE *fatdirRcsId = "$Id: FATDIR.C,v 1.5 1999/04/13 15:48:20 jprice Exp $";
 #endif
 
 /*
  * $Log: FATDIR.C,v $
+ * Revision 1.5  1999/04/13 15:48:20  jprice
+ * no message
+ *
+ * Revision 1.4  1999/04/11 04:33:38  jprice
+ * ror4 patches
+ *
  * Revision 1.2  1999/04/04 18:51:43  jprice
  * no message
  *
  * Revision 1.1.1.1  1999/03/29 15:41:58  jprice
  * New version without IPL.SYS
@@ -278,11 +284,11 @@
 
   /* Determine if we hit the end of the directory. If we have,    */
   /* bump the offset back to the end and exit. If not, fill the   */
   /* dirent portion of the fnode, clear the f_dmod bit and leave, */
   /* but only for root directories                                */
-  if (!(fnp->f_flags.f_droot) && fnp->f_diroff >= fnp->f_dsize)
+  if (fnp->f_flags.f_droot && fnp->f_diroff >= fnp->f_dsize)
   {
     fnp->f_diroff -= DIRENT_SIZE;
     return 0;
   }
   else
@@ -501,15 +507,10 @@
   /* Start out by initializing the dirmatch structure.            */
   dmp->dm_drive = default_drive;
   dmp->dm_entry = 0;
   dmp->dm_cluster = 0;
 
-  /* JPP: attr is exactly D_VOLID, we should always return READ ONLY &
-      ARCHIVE files */
-  if (attr == D_VOLID)
-    dmp->dm_attr_srch = attr;
-  else
     dmp->dm_attr_srch = attr | D_RDONLY | D_ARCHIVE;
 
   /* Parse out the drive, file name and file extension.           */
   i = ParseDosName(name, &nDrive, &LocalPath[2],
                    SearchDir.dir_name, SearchDir.dir_ext, TRUE);
@@ -585,33 +586,22 @@
   /* Special handling - the volume id is only in the root         */
   /* directory and only searched for once.  So we need to open    */
   /* the root and return only the first entry that contains the   */
   /* volume id bit set.                                           */
 //JPP:  if (attr & D_VOLID)
-  if (attr == D_VOLID)
+  if ((attr & ~(D_RDONLY | D_ARCHIVE)) == D_VOLID)
   {
     /* Now open this directory so that we can read the      */
     /* fnode entry and do a match on it.                    */
     if ((fnp = dir_open((BYTE FAR *) "\\")) == NULL)
       return DE_PATHNOTFND;
 
     /* Now do the search                                    */
     while (dir_read(fnp) == DIRENT_SIZE)
     {
       /* Test the attribute and return first found    */
-
-/* JPP - bug fix - Windows long filenames also have their VOLID bit set, but
-   also R/O, SYS, and HID bits set.  A real volume ID has a cluster
-   number of zero, and a size of zero.  Win long filenames have a size
-   of 0xFFFFFFFF.
- */
-
-//JPP
-//      if ((fnp->f_dir.dir_attrib & D_VOLID) &&
-//          (fnp->f_dir.dir_start == 0) &&  /* JPP */
-//          (fnp->f_dir.dir_size == 0)) /* JPP */
-      if ((fnp->f_dir.dir_attrib == D_VOLID))
+      if ((fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE)) == D_VOLID)
       {
         pop_dmp(dmp, fnp);
         dir_close(fnp);
         return SUCCESS;
       }
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/fatfs.c ker2007/kernel/fatfs.c
--- ker2006/kernel/fatfs.c	Sun Apr  4 14:25:42 1999
+++ ker2007/kernel/fatfs.c	Mon Apr 12 18:41:54 1999
@@ -29,15 +29,25 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-BYTE *RcsId = "$Id: FATFS.C,v 1.2 1999/04/04 18:51:43 jprice Exp $";
+BYTE *RcsId = "$Id: FATFS.C,v 1.6 1999/04/12 23:41:54 jprice Exp $";
 #endif
 
 /*
  * $Log: FATFS.C,v $
+ * Revision 1.6  1999/04/12 23:41:54  jprice
+ * Using getbuf to write data instead of getblock

+ * using getblock made it read the block before it wrote it
+ *
+ * Revision 1.5  1999/04/12 03:21:17  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
+ * Revision 1.4  1999/04/11 04:33:38  jprice
+ * ror4 patches
+ *
  * Revision 1.2  1999/04/04 18:51:43  jprice
  * no message
  *
  * Revision 1.1.1.1  1999/03/29 15:42:07  jprice
  * New version without IPL.SYS
@@ -192,11 +202,10 @@
 COUNT FAR init_call_dos_open(BYTE FAR * path, COUNT flag)
 {
   return dos_open(path, flag);
 }
 
-#ifndef IPL
 BOOL fcmp(BYTE FAR * s1, BYTE FAR * s2, COUNT n)
 {
   while (n--)
     if (*s1++ != *s2++)
       return FALSE;
@@ -215,11 +224,10 @@
     if (*s1++ != *s2++)
       return FALSE;
   }
   return TRUE;
 }
-#endif
 
 COUNT dos_close(COUNT fd)
 {
   struct f_node FAR *fnp;
 
@@ -323,11 +331,10 @@
     }
   }
   return found;
 }
 
-#ifndef IPL
 COUNT dos_creat(BYTE FAR * path, COUNT attrib)
 {
   REG struct f_node FAR *fnp;
 
   /* first split the passed dir into comopnents (i.e. -   */
@@ -732,11 +739,10 @@
 /* dos_getdate for the file date                                */
 /*                                                              */
 date dos_getdate()
 {
 #ifndef NOTIME
-#ifndef IPL
   BYTE WeekDay,
     Month,
     MonthDay;
   COUNT Year;
   date Date;
@@ -753,16 +759,10 @@
 #else
 
   return 0;
 
 #endif
-
-#else
-
-  return 0;
-
-#endif
 }
 
 date FAR init_call_dos_getdate()
 {
   return dos_getdate();
@@ -772,11 +772,10 @@
 /* dos_gettime for the file time                                */
 /*                                                              */
 time dos_gettime()
 {
 #ifndef NOTIME
-#ifndef IPL
   BYTE Hour,
     Minute,
     Second,
     Hundredth;
   time Time;
@@ -792,25 +791,21 @@
   Time = TM_ENCODE(Hour, Minute, h);
   return Time;
 #else
   return 0;
 #endif
-#else
-  return 0;
-#endif
 }
 
 time FAR init_call_dos_gettime()
 {
   return dos_gettime();
 }
 
-#ifndef IPL
 /*                                                              */
 /* dos_getftime for the file time                               */
 /*                                                              */
-BOOL dos_getftime(COUNT fd, date FAR * dp, time FAR * tp)
+COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp)
 {
   struct f_node FAR *fnp;
 
   /* Translate the fd into an fnode pointer, since all internal   */
   /* operations are achieved through fnodes.                      */
@@ -818,23 +813,23 @@
 
   /* If the fd was invalid because it was out of range or the     */
   /* requested file was not open, tell the caller and exit        */
   /* note: an invalid fd is indicated by a 0 return               */
   if (fnp == (struct f_node FAR *)0 || fnp->f_count <= 0)
-    return FALSE;
+    return DE_INVLDHNDL;
 
   /* Get the date and time from the fnode and return              */
   *dp = fnp->f_dir.dir_date;
   *tp = fnp->f_dir.dir_time;
 
-  return TRUE;
+  return SUCCESS;
 }
 
 /*                                                              */
 /* dos_setftime for the file time                               */
 /*                                                              */
-BOOL dos_setftime(COUNT fd, date FAR * dp, time FAR * tp)
+COUNT dos_setftime(COUNT fd, date FAR * dp, time FAR * tp)
 {
   struct f_node FAR *fnp;
 
   /* Translate the fd into an fnode pointer, since all internal   */
   /* operations are achieved through fnodes.                      */
@@ -842,17 +837,17 @@
 
   /* If the fd was invalid because it was out of range or the     */
   /* requested file was not open, tell the caller and exit        */
   /* note: an invalid fd is indicated by a 0 return               */
   if (fnp == (struct f_node FAR *)0 || fnp->f_count <= 0)
-    return FALSE;
+    return DE_INVLDHNDL;
 
   /* Set the date and time from the fnode and return              */
   fnp->f_dir.dir_date = *dp;
   fnp->f_dir.dir_time = *tp;
 
-  return TRUE;
+  return SUCCESS;
 }
 
 /*                                                              */
 /* dos_getfsize for the file time                               */
 /*                                                              */
@@ -915,11 +910,10 @@
   /* Change the file size                                         */
   fnp->f_dir.dir_size = size;
   fnp->f_highwater = size;
   return TRUE;
 }
-#endif
 
 /*                                                              */
 /* Find free cluster in disk FAT table                          */
 /*                                                              */
 static UWORD find_fat_free(struct f_node FAR * fnp)
@@ -1118,18 +1112,16 @@
   fnp->f_flags.f_dmod = TRUE;
   dir_close(fnp);
 
   return SUCCESS;
 }
-#endif
 
 BOOL last_link(struct f_node FAR * fnp)
 {
   return (((UWORD) fnp->f_cluster == (UWORD) LONG_LAST_CLUSTER));
 }
 
-#ifndef IPL
 static BOOL extend(struct f_node FAR * fnp)
 {
   UWORD free_fat;
 
   /* get an empty cluster, so that we use it to extend the file.  */
@@ -1215,11 +1207,10 @@
 
   /* Mark the directory so that the entry is updated              */
   fnp->f_flags.f_dmod = TRUE;
   return TRUE;
 }
-#endif
 
 COUNT map_cluster(REG struct f_node FAR * fnp, COUNT mode)
 {
   ULONG idx;
   WORD clssize,
@@ -1230,19 +1221,17 @@
 
   /* The variable clssize will be used later.             */
   secsize = fnp->f_dpb->dpb_secsize;
   clssize = secsize * fnp->f_dpb->dpb_clssize;
 
-#ifndef IPL
   /* If someone did a seek, but no writes have occured, we will   */
   /* need to initialize the fnode.                                */
   if ((mode == XFR_WRITE) && (fnp->f_dir.dir_start == FREE))
   {
     if (!first_fat(fnp))
       return DE_HNDLDSKFULL;
   }
-#endif
 
   /* Now begin the linear search. The relative cluster is         */
   /* maintained as part of the set of physical indices. It is     */
   /* also the highest order index and is mapped directly into     */
   /* physical cluster. Our search is performed by pacing an index */
@@ -1260,11 +1249,10 @@
   {
     /* If this is a read and the next is a LAST_CLUSTER,    */
     /* then we are going to read past EOF, return zero read */
     if ((mode == XFR_READ) && last_link(fnp))
       return DE_SEEK;
-#ifndef IPL
 /* expand the list if we're going to write and have run into    */
 /* the last cluster marker.                                     */
     else if ((mode == XFR_WRITE) && last_link(fnp))
     {
 
@@ -1272,32 +1260,31 @@
       {
         dir_close(fnp);
         return DE_HNDLDSKFULL;
       }
     }
-#endif
     fnp->f_back = fnp->f_cluster;
     fnp->f_cluster = next_cluster(fnp->f_dpb, fnp->f_cluster);
   }
   return SUCCESS;
 }
 
-UCOUNT rdwrblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT mode, COUNT * err)
+/* Read block from disk */
+UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err)
 {
   REG struct f_node FAR *fnp;
   REG struct buffer FAR *bp;
-  UCOUNT xfr_cnt = 0,
-    ret_cnt = 0;
+  UCOUNT xfr_cnt = 0;
+  UCOUNT ret_cnt = 0;
   LONG idx;
   WORD secsize;
   UCOUNT to_xfer = count;
 
 #ifdef DEBUG
   if (bDumpRdWrParms)
   {
-    printf("rdwrblock: mode = %s\n",
-           mode == XFR_WRITE ? "WRITE" : "READ");
+    printf("readblock:\n");
     printf(" fd   buffer     count\n --   ------     -----\n");
     printf(" %02d   %04x:%04x   %d\n",
            fd, (COUNT) FP_SEG(buffer), (COUNT) FP_OFF(buffer), count);
   }
 #endif
@@ -1312,60 +1299,201 @@
   {
     *err = DE_INVLDHNDL;
     return 0;
   }
 
-  /* Test that we are really about to do a data transfer. If the  */
-  /* count is zero and the mode is XFR_READ, just exit. (Any      */
-  /* read with a count of zero is a nop).                         */
-  /*                                                              */
-  /* A write (mode is XFR_WRITE) is a special case.  It sets the  */
-  /* file length to the current length (truncates it).            */
-  /*                                                              */
+  /* Test that we are really about to do a data transfer. If the
+     count is zero, just exit. (Any read with a count of zero is a nop). */
+
   /* NOTE: doing this up front saves a lot of headaches later.    */
   if (count == 0)
   {
-    if (mode == XFR_WRITE)
-    {
-      fnp->f_highwater = fnp->f_offset;
-    }
-
     *err = SUCCESS;
     return 0;
   }
 
-  /* Another test is to check for a seek past EOF on an XFR_READ  */
-  /* operation.                                                   */
-  if (mode == XFR_READ
-      && !fnp->f_flags.f_ddir
-      && (fnp->f_offset >= fnp->f_dir.dir_size))
+  /* Another test is to check for a seek past EOF  */
+  if (!fnp->f_flags.f_ddir && (fnp->f_offset >= fnp->f_dir.dir_size))
   {
     *err = SUCCESS;
     return 0;
   }
 
   /* test that we have a valid mode for this fnode                */
-  switch (mode)
-  {
-    case XFR_READ:
       if (fnp->f_mode != RDONLY && fnp->f_mode != RDWR)
       {
         *err = DE_INVLDACC;
         return 0;
       }
-      break;
 
-#ifndef IPL
-    case XFR_WRITE:
-      if (fnp->f_mode != WRONLY && fnp->f_mode != RDWR)
+  /* The variable secsize will be used later.                     */
+  secsize = fnp->f_dpb->dpb_secsize;
+
+  /* Adjust the far pointer from user space to supervisor space   */
+  buffer = adjust_far((VOID FAR *) buffer);
+
+  /* Do the data transfer. Use block transfer methods so that we  */
+  /* can utilize memory management in future DOS-C versions.      */
+  while (ret_cnt < count)
       {
-        *err = DE_INVLDACC;
-        return 0;
+    /* Position the file to the fnode's pointer position. This is   */
+    /* done by updating the fnode's cluster, block (sector) and     */
+    /* byte offset so that read becomes a simple data move          */
+    /* out of the block data buffer.                                */
+    if (fnp->f_offset == 0l)
+    {
+      /* complete the common operations of            */
+      /* initializing to the starting cluster and     */
+      /* setting all offsets to zero.                 */
+      fnp->f_cluster = fnp->f_dir.dir_start;
+      fnp->f_back = LONG_LAST_CLUSTER;
+      fnp->f_sector = 0;
+      fnp->f_boff = 0;
       }
+
+    /* The more difficult scenario is the (more common)     */
+    /* file offset case. Here, we need to take the fnode's  */
+    /* offset pointer (f_offset) and translate it into a    */
+    /* relative cluster position, cluster block (sector)    */
+    /* offset (f_sector) and byte offset (f_boff). Once we  */
+    /* have this information, we need to translate the      */
+    /* relative cluster position into an absolute cluster   */
+    /* position (f_cluster). This is unfortunate because it */
+    /* requires a linear search through the file's FAT      */
+    /* entries. It made sense when DOS was originally       */
+    /* designed as a simple floppy disk operating system    */
+    /* where the FAT was contained in core, but now         */
+    /* requires a search through the FAT blocks.            */
+    /*                                                      */
+    /* The algorithm in this function takes advantage of    */
+    /* the blockio block buffering scheme to simplify the   */
+    /* task.                                                */
+    else
+      switch (map_cluster(fnp, XFR_READ))
+      {
+        case DE_SEEK:
+          *err = DE_SEEK;
+          dir_close(fnp);
+          return ret_cnt;
+
+        default:
+          dir_close(fnp);
+          *err = DE_HNDLDSKFULL;
+          return ret_cnt;
+
+        case SUCCESS:
       break;
+      }
+
+    /* Compute the block within the cluster and the offset  */
+    /* within the block.                                    */
+    fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
+    fnp->f_boff = fnp->f_offset & (secsize - 1);
+
+#ifdef DSK_DEBUG
+    printf("%d links; dir offset %ld, starting at cluster %d\n",
+           fnp->f_count,
+           fnp->f_diroff,
+           fnp->f_cluster);
 #endif
-    default:
+    /* Do an EOF test and return whatever was transferred   */
+    /* but only for regular files.                          */
+    if (!(fnp->f_flags.f_ddir)
+        && (fnp->f_offset >= fnp->f_dir.dir_size))
+    {
+      *err = SUCCESS;
+      return ret_cnt;
+    }
+
+    /* Get the block we need from cache                     */
+    bp = getblock(
+                   (LONG) clus2phys(fnp->f_cluster,
+                                    fnp->f_dpb->dpb_clssize,
+                                    fnp->f_dpb->dpb_data) + fnp->f_sector,
+                   fnp->f_dpb->dpb_unit);
+
+    if (bp == (struct buffer *)0)
+    {
+      *err = DE_BLKINVLD;
+      return ret_cnt;
+    }
+
+    /* transfer a block                                     */
+    /* Transfer size as either a full block size, or the    */
+    /* requested transfer size, whichever is smaller.       */
+    /* Then compare to what is left, since we can transfer  */
+    /* a maximum of what is left.                           */
+    if (fnp->f_flags.f_ddir)
+      xfr_cnt = min(to_xfer, secsize - fnp->f_boff);
+    else
+      xfr_cnt = min(min(to_xfer, secsize - fnp->f_boff),
+                    fnp->f_dir.dir_size - fnp->f_offset);
+
+    fbcopy((BYTE FAR *) & bp->b_buffer[fnp->f_boff], buffer, xfr_cnt);
+
+    /* update pointers and counters                         */
+    ret_cnt += xfr_cnt;
+    to_xfer -= xfr_cnt;
+    fnp->f_offset += xfr_cnt;
+    buffer = add_far((VOID FAR *) buffer, (ULONG) xfr_cnt);
+  }
+  *err = SUCCESS;
+  return ret_cnt;
+}
+
+/* Write block to disk */
+UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err)
+{
+  REG struct f_node FAR *fnp;
+  struct buffer FAR *bp;
+  UCOUNT xfr_cnt = 0;
+  UCOUNT ret_cnt = 0;
+  LONG idx;
+  WORD secsize;
+  UCOUNT to_xfer = count;
+
+#ifdef DEBUG
+  if (bDumpRdWrParms)
+  {
+    printf("writeblock:\n");
+    printf(" fd   buffer     count\n --   ------     -----\n");
+    printf(" %02d   %04x:%04x   %d\n",
+           fd, (COUNT) FP_SEG(buffer), (COUNT) FP_OFF(buffer), count);
+  }
+#endif
+  /* Translate the fd into an fnode pointer, since all internal   */
+  /* operations are achieved through fnodes.                      */
+  fnp = xlt_fd(fd);
+
+  /* If the fd was invalid because it was out of range or the     */
+  /* requested file was not open, tell the caller and exit        */
+  /* note: an invalid fd is indicated by a 0 return               */
+  if (fnp == (struct f_node FAR *)0 || fnp->f_count <= 0)
+  {
+    *err = DE_INVLDHNDL;
+    return 0;
+  }
+
+  /* Test that we are really about to do a data transfer. If the  */
+  /* count is zero and the mode is XFR_READ, just exit. (Any      */
+  /* read with a count of zero is a nop).                         */
+  /*                                                              */
+  /* A write (mode is XFR_WRITE) is a special case.  It sets the  */
+  /* file length to the current length (truncates it).            */
+  /*                                                              */
+  /* NOTE: doing this up front saves a lot of headaches later.    */
+  if (count == 0)
+  {
+    fnp->f_highwater = fnp->f_offset;
+
+    *err = SUCCESS;
+    return 0;
+  }
+
+  /* test that we have a valid mode for this fnode                */
+  if (fnp->f_mode != WRONLY && fnp->f_mode != RDWR)
+  {
       *err = DE_INVLDACC;
       return 0;
   }
 
   /* The variable secsize will be used later.                     */
@@ -1382,24 +1510,21 @@
     /* done by updating the fnode's cluster, block (sector) and     */
     /* byte offset so that read or write becomes a simple data move */
     /* into or out of the block data buffer.                        */
     if (fnp->f_offset == 0l)
     {
-#ifndef IPL
       /* For the write case, a newly created file     */
       /* will have a start cluster of FREE. If we're  */
       /* doing a write and this is the first time     */
       /* through, allocate a new cluster to the file. */
-      if ((mode == XFR_WRITE)
-          && (fnp->f_dir.dir_start == FREE))
+      if (fnp->f_dir.dir_start == FREE)
         if (!first_fat(fnp))
         {
           dir_close(fnp);
           *err = DE_HNDLDSKFULL;
           return ret_cnt;
         }
-#endif
       /* complete the common operations of            */
       /* initializing to the starting cluster and     */
       /* setting all offsets to zero.                 */
       fnp->f_cluster = fnp->f_dir.dir_start;
       fnp->f_back = LONG_LAST_CLUSTER;
@@ -1423,11 +1548,11 @@
     /*                                                      */
     /* The algorithm in this function takes advantage of    */
     /* the blockio block buffering scheme to simplify the   */
     /* task.                                                */
     else
-      switch (map_cluster(fnp, mode))
+      switch (map_cluster(fnp, XFR_WRITE))
       {
         case DE_SEEK:
           *err = DE_SEEK;
           dir_close(fnp);
           return ret_cnt;
@@ -1438,21 +1563,19 @@
           return ret_cnt;
 
         case SUCCESS:
           break;
       }
-#ifndef IPL
     /* XFR_WRITE case only - if we're at the end, the next  */
     /* FAT is an EOF marker, so just extend the file length */
-    if (mode == XFR_WRITE && last_link(fnp))
+    if (last_link(fnp))
       if (!extend(fnp))
       {
         dir_close(fnp);
         *err = DE_HNDLDSKFULL;
         return ret_cnt;
       }
-#endif
 
     /* Compute the block within the cluster and the offset  */
     /* within the block.                                    */
     fnp->f_sector =
         (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
@@ -1462,87 +1585,67 @@
     printf("%d links; dir offset %ld, starting at cluster %d\n",
            fnp->f_count,
            fnp->f_diroff,
            fnp->f_cluster);
 #endif
-    /* Do an EOF test and return whatever was transferred   */
-    /* but only for regular files in XFR_READ mode          */
-    if ((mode == XFR_READ) && !(fnp->f_flags.f_ddir)
-        && (fnp->f_offset >= fnp->f_dir.dir_size))
-    {
-      *err = SUCCESS;
-      return ret_cnt;
-    }
 
-    /* Get the block we need from cache                     */
-    bp = getblock(
+    /* get a buffer to store the block in */
+    if (!getbuf(&bp,
                    (LONG) clus2phys(fnp->f_cluster,
                                     fnp->f_dpb->dpb_clssize,
                                     fnp->f_dpb->dpb_data) + fnp->f_sector,
-                   fnp->f_dpb->dpb_unit);
-
-    if (bp == (struct buffer *)0)
+                   fnp->f_dpb->dpb_unit))
     {
       *err = DE_BLKINVLD;
       return ret_cnt;
     }
 
+//		/* Get the block we need from cache                     */
+//    bp = getblock(
+//                   (LONG) clus2phys(fnp->f_cluster,
+//                                    fnp->f_dpb->dpb_clssize,
+//                                    fnp->f_dpb->dpb_data) + fnp->f_sector,
+//                   fnp->f_dpb->dpb_unit);
+//
+//    if (bp == (struct buffer *)0)
+//    {
+//      *err = DE_BLKINVLD;
+//      return ret_cnt;
+//    }
+
+
     /* transfer a block                                     */
     /* Transfer size as either a full block size, or the    */
     /* requested transfer size, whichever is smaller.       */
     /* Then compare to what is left, since we can transfer  */
     /* a maximum of what is left.                           */
-    switch (mode)
-    {
-      case XFR_READ:
-        if (fnp->f_flags.f_ddir)
-          xfr_cnt = min(to_xfer,
-                        secsize - fnp->f_boff);
-        else
-          xfr_cnt = min(min(to_xfer,
-                            secsize - fnp->f_boff),
-                        fnp->f_dir.dir_size - fnp->f_offset);
-
-        fbcopy((BYTE FAR *) & bp->b_buffer[fnp->f_boff], buffer, xfr_cnt);
-        break;
-
-#ifndef IPL
-      case XFR_WRITE:
         xfr_cnt = min(to_xfer, secsize - fnp->f_boff);
-        fbcopy(buffer,
-               (BYTE FAR *) & bp->b_buffer[fnp->f_boff],
-               xfr_cnt);
-        bp->b_flag |= BFR_DIRTY;
-        break;
-#endif
-
-      default:
-        *err = DE_INVLDACC;
-        return ret_cnt;
-    }
+    fbcopy(buffer, (BYTE FAR *) & bp->b_buffer[fnp->f_boff], xfr_cnt);
+    bp->b_flag |= BFR_DIRTY | BFR_VALID;
 
     /* update pointers and counters                         */
     ret_cnt += xfr_cnt;
     to_xfer -= xfr_cnt;
     fnp->f_offset += xfr_cnt;
     buffer = add_far((VOID FAR *) buffer, (ULONG) xfr_cnt);
-    if (mode == XFR_WRITE && (fnp->f_offset > fnp->f_highwater))
+    if (fnp->f_offset > fnp->f_highwater)
     {
       fnp->f_highwater = fnp->f_offset;
       fnp->f_dir.dir_size = fnp->f_highwater;
     }
   }
   *err = SUCCESS;
   return ret_cnt;
 }
 
+
 COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count)
 {
   COUNT err,
     xfr;
 
-  xfr = rdwrblock(fd, buffer, count, XFR_READ, &err);
+  xfr = readblock(fd, buffer, count, &err);
   return err != SUCCESS ? err : xfr;
 }
 
 COUNT FAR init_call_dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count)
 {
@@ -1579,18 +1682,18 @@
   {
     ULONG lCount = fnp->f_offset - fnp->f_highwater;
 
     while (lCount > 0)
     {
-      rdwrblock(fd, buffer,
+      writeblock(fd, buffer,
                 lCount > 512l ? 512 : (UCOUNT) lCount,
-                XFR_WRITE, &err);
+                &err);
       lCount -= 512;
     }
   }
 
-  xfr = rdwrblock(fd, buffer, count, XFR_WRITE, &err);
+  xfr = writeblock(fd, buffer, count, &err);
   return err != SUCCESS ? err : xfr;
 }
 #endif
 
 /* Position the file pointer to the desired offset                      */
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/fattab.c ker2007/kernel/fattab.c
--- ker2006/kernel/fattab.c	Sun Apr  4 14:25:44 1999
+++ ker2007/kernel/fattab.c	Sat Apr 10 23:33:38 1999
@@ -28,15 +28,18 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *RcsId = "$Id: FATTAB.C,v 1.1.1.1 1999/03/29 15:42:09 jprice Exp $";
+static BYTE *RcsId = "$Id: FATTAB.C,v 1.3 1999/04/11 04:33:38 jprice Exp $";
 #endif
 
 /*
  * $Log: FATTAB.C,v $
+ * Revision 1.3  1999/04/11 04:33:38  jprice
+ * ror4 patches
+ *
  * Revision 1.1.1.1  1999/03/29 15:42:09  jprice
  * New version without IPL.SYS
  *
  * Revision 1.4  1999/02/09 02:54:23  jprice
  * Added Pat's 1937 kernel patches
Files ker2006/kernel/fcbfns.c and ker2007/kernel/fcbfns.c are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/globals.h ker2007/kernel/globals.h
--- ker2006/kernel/globals.h	Sun Apr  4 17:57:48 1999
+++ ker2007/kernel/globals.h	Sun Apr 11 22:21:16 1999
@@ -28,16 +28,22 @@
 /****************************************************************/
 
 /* $Logfile:   C:/usr/patv/dos-c/src/kernel/globals.h_v  $ */
 #ifdef VERSION_STRINGS
 #ifdef MAIN
-static BYTE *Globals_hRcsId = "$Id: GLOBALS.H,v 1.4 1999/04/04 22:57:47 jprice Exp $";
+static BYTE *Globals_hRcsId = "$Id: GLOBALS.H,v 1.7 1999/04/12 03:21:17 jprice Exp $";
 #endif
 #endif
 
 /*
  * $Log: GLOBALS.H,v $
+ * Revision 1.7  1999/04/12 03:21:17  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
+ * Revision 1.6  1999/04/11 04:33:39  jprice
+ * ror4 patches
+ *
  * Revision 1.4  1999/04/04 22:57:47  jprice
  * no message
  *
  * Revision 1.3  1999/04/04 18:51:43  jprice
  * no message
@@ -636,5 +642,6 @@
 #endif
 
 #ifdef I86
 #define setvec(n, isr)	(void)(*(VOID (INRPT FAR * FAR *)())(4 * (n)) = (isr))
 #endif
+#define is_leap_year(y)	((y) & 3 ? 0 : (y) % 100 ? 1 : (y) % 400 ? 1 : 0)
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/init-mod.h ker2007/kernel/init-mod.h
--- ker2006/kernel/init-mod.h	Sun Apr  4 17:58:04 1999
+++ ker2007/kernel/init-mod.h	Sun Apr 11 22:21:16 1999
@@ -29,6 +29,6 @@
 #define printf      init_call_printf
 #define scopy       init_call_scopy
 #define sti         init_call_sti
 #define strcmp      init_call_strcmp
 #define strlen      init_call_strlen
-
+#define WritePCClock	init_call_WritePCClock
Files ker2006/kernel/initoem.c and ker2007/kernel/initoem.c are identical
Files ker2006/kernel/int2f.asm and ker2007/kernel/int2f.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/inthndlr.c ker2007/kernel/inthndlr.c
--- ker2006/kernel/inthndlr.c	Sun Apr  4 17:57:48 1999
+++ ker2007/kernel/inthndlr.c	Sat Apr 10 23:33:38 1999
@@ -29,15 +29,18 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-BYTE *RcsId = "$Id: INTHNDLR.C,v 1.3 1999/04/04 22:57:47 jprice Exp $";
+BYTE *RcsId = "$Id: INTHNDLR.C,v 1.5 1999/04/11 04:33:39 jprice Exp $";
 #endif
 
 /*
  * $Log: INTHNDLR.C,v $
+ * Revision 1.5  1999/04/11 04:33:39  jprice
+ * ror4 patches
+ *
  * Revision 1.3  1999/04/04 22:57:47  jprice
  * no message
  *
  * Revision 1.2  1999/04/04 18:51:43  jprice
  * no message
@@ -349,11 +352,11 @@
         static COUNT scratch;
         BYTE FAR *p = MK_FP(r->DS, r->DX), FAR *q;
         q = p;
         while (*q != '$')
           ++q;
-        DosWrite(STDOUT, q - p, p, (COUNT FAR *)scratch);
+        DosWrite(STDOUT, q - p, p, (COUNT FAR *)&scratch);
       }
       r->AL = '$';
       break;
 
       /* Buffered Keyboard Input                                      */
@@ -1193,31 +1196,27 @@
       /* Get/Set File Date and Time                                   */
     case 0x57:
       switch (r->AL)
       {
         case 0x00:
-          if (!DosGetFtime(
+          rc = DosGetFtime(
                             (COUNT) r->BX,	/* Handle               */
                             (date FAR *) & r->DX,	/* FileDate             */
-                            (time FAR *) & r->CX))	/* FileTime             */
-          {
-            r->AX = -DE_INVLDHNDL;
-            r->FLAGS |= FLG_CARRY;
-          }
+                            (time FAR *) & r->CX);      /* FileTime             */
+          if (rc < SUCCESS)
+            goto error_exit;
           else
             r->FLAGS &= ~FLG_CARRY;
           break;
 
         case 0x01:
-          if (!DosSetFtime(
+          rc = DosSetFtime(
                             (COUNT) r->BX,	/* Handle               */
                             (date FAR *) & r->DX,	/* FileDate             */
-                            (time FAR *) & r->CX))	/* FileTime             */
-          {
-            r->AX = -DE_INVLDHNDL;
-            r->FLAGS |= FLG_CARRY;
-          }
+                            (time FAR *) & r->CX);      /* FileTime             */
+          if (rc < SUCCESS)
+            goto error_exit;
           else
             r->FLAGS &= ~FLG_CARRY;
           break;
 
         default:
Files ker2006/kernel/io.asm and ker2007/kernel/io.asm are identical
Files ker2006/kernel/io.inc and ker2007/kernel/io.inc are identical
Files ker2006/kernel/ioctl.c and ker2007/kernel/ioctl.c are identical
Files ker2006/kernel/irqstack.asm and ker2007/kernel/irqstack.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/kernel.asm ker2007/kernel/kernel.asm
--- ker2006/kernel/kernel.asm	Sun Apr  4 14:25:58 1999
+++ ker2007/kernel/kernel.asm	Tue Apr 13 10:52:56 1999
@@ -23,13 +23,16 @@
 ; You should have received a copy of the GNU General public
 ; License along with DOS-C; see the file COPYING.  If not,
 ; write to the Free Software Foundation, 675 Mass Ave,
 ; Cambridge, MA 02139, USA.
 ;
-; $Id: KERNEL.ASM,v 1.1.1.1 1999/03/29 15:41:14 jprice Exp $
+; $Id: KERNEL.ASM,v 1.2 1999/04/13 15:52:57 jprice Exp $
 ;
 ; $Log: KERNEL.ASM,v $
+; Revision 1.2  1999/04/13 15:52:57  jprice
+; changes for boot loader
+;
 ; Revision 1.1.1.1  1999/03/29 15:41:14  jprice
 ; New version without IPL.SYS
 ;
 ; Revision 1.4  1999/02/08 05:55:57  jprice
 ; Added Pat's 1937 kernel patches
@@ -122,10 +125,14 @@
                 page
                 ;
                 ; kernel start-up
                 ;
 kernel_start	label	far
+		mov	ax,DGROUP
+		cli
+		mov	ss,ax
+		mov	sp,offset DGROUP:tos
 		int	12h		; move the init code to higher memory
 		mov	cl,6
 		shl	ax,cl
 		mov	dx,offset IGROUP:init_end+15
 		mov	cl,4
@@ -142,26 +149,11 @@
 		rep	movsw
 		push	es
 		mov	ax,offset IGROUP:cont
 		push	ax
 		retf
-cont:		cli                     ; prevent interrupts while starting
-                mov     ax,DGROUP
-                mov     ss,ax
-                mov     sp,offset DGROUP:tos
-                ; inititalize entry stack for high water tests
-;               mov     di,seg stack_bottom
-;               mov     es,di
-;               mov     di,offset stack_bottom
-;               mov     ax,offset last
-;               sub     ax,di
-;               sar     ax,1
-;               mov     cx,ax
-;               mov     ax,09090h
-;               cld
-;               rep     stosw
-                ; inititalize api stacks for high water tests
+cont:		; inititalize api stacks for high water tests
                 mov     di,seg apistk_bottom
                 mov     es,di
                 mov     di,offset apistk_bottom
                 mov     ax,offset apistk_top
                 sub     ax,di
Files ker2006/kernel/kernel.cfg and ker2007/kernel/kernel.cfg are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/kernel.mak ker2007/kernel/kernel.mak
--- ker2006/kernel/kernel.mak	Sun Apr  4 14:26:00 1999
+++ ker2007/kernel/kernel.mak	Tue Apr 13 10:48:20 1999
@@ -1,11 +1,14 @@
 #
 # Makefile for Borland C++ 3.1 for kernel.exe
 #
-# $Id: KERNEL.MAK,v 1.1.1.1 1999/03/29 15:41:15 jprice Exp $
+# $Id: KERNEL.MAK,v 1.2 1999/04/13 15:48:21 jprice Exp $
 #
 # $Log: KERNEL.MAK,v $
+# Revision 1.2  1999/04/13 15:48:21  jprice
+# no message
+#
 # Revision 1.1.1.1  1999/03/29 15:41:15  jprice
 # New version without IPL.SYS
 #
 # Revision 1.7  1999/03/01 06:04:37  jprice
 # Fixed so it'll work with config.mak
@@ -144,11 +147,11 @@
                 del kernel.sys
 
 clean:
         ..\utils\rm -f *.obj *.bak *.crf *.xrf *.map *.lst *.las status.me
 
-kernel.exe: kernel.cfg $(EXE_dependencies)
+kernel.exe: kernel.cfg $(EXE_dependencies) $(LIBS)
   $(LINK) /m/c/L$(LIBPATH) @&&|
 kernel.obj+
 entry.obj+
 io.obj+
 blockio.obj+
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/main.c ker2007/kernel/main.c
--- ker2006/kernel/main.c	Sun Apr  4 17:57:48 1999
+++ ker2007/kernel/main.c	Sun Apr 11 22:21:16 1999
@@ -32,15 +32,21 @@
 #define MAIN
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *mainRcsId = "$Id: MAIN.C,v 1.3 1999/04/04 22:57:47 jprice Exp $";
+static BYTE *mainRcsId = "$Id: MAIN.C,v 1.6 1999/04/12 03:21:17 jprice Exp $";
 #endif
 
 /*
  * $Log: MAIN.C,v $
+ * Revision 1.6  1999/04/12 03:21:17  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
+ * Revision 1.5  1999/04/11 04:33:39  jprice
+ * ror4 patches
+ *
  * Revision 1.3  1999/04/04 22:57:47  jprice
  * no message
  *
  * Revision 1.2  1999/04/04 18:51:43  jprice
  * no message
@@ -102,12 +108,20 @@
  * Initial revision.
  */
 
 //JP: static COUNT BlockIndex = 0;
 
+extern UWORD DaysSinceEpoch;
+extern WORD days[2][13];
+
+INIT BOOL ReadATClock(BYTE *, BYTE *, BYTE *, BYTE *);
+VOID FAR init_call_WritePCClock(ULONG);
+
 INIT VOID configDone(VOID);
 INIT static void InitIO(void);
+INIT static COUNT BcdToByte(COUNT);
+INIT static COUNT BcdToDay(BYTE *);
 
 INIT static VOID init_kernel(VOID);
 INIT static VOID signon(VOID);
 INIT VOID kernel(VOID);
 INIT VOID FsConfig(VOID);
@@ -417,14 +431,57 @@
   lp->dh_next = dhp;
   init_device(dhp, cmdLine);
   return dhp;
 }
 
-static void InitIO(void)
+INIT static void InitIO(void)
 {
+  BYTE bcd_days[4], bcd_minutes, bcd_hours, bcd_seconds;
+  ULONG ticks;
+
   /* Initialize driver chain                                      */
   nul_dev.dh_next = (struct dhdr FAR *)&con_dev;
   setvec(0x29, int29_handler);  /* Requires Fast Con Driver     */
   init_device((struct dhdr FAR *)&con_dev, NULL);
   init_device((struct dhdr FAR *)&clk_dev, NULL);
   init_device((struct dhdr FAR *)&blk_dev, NULL);
+  /* If AT clock exists, copy AT clock time to system clock */
+  if (!ReadATClock(&bcd_days, &bcd_hours, &bcd_minutes, &bcd_seconds))
+  {
+    DaysSinceEpoch = BcdToDay(bcd_days);
+    /*
+     * This is a rather tricky calculation. The number of timer ticks per
+     * second is not exactly 18.2, but rather 0x1800b0 / 86400 = 19663 / 1080
+     * (the timer interrupt updates the midnight flag when the tick count
+     * reaches 0x1800b0). Fortunately, 86400 * 19663 = 1698883200 < ULONG_MAX,
+     * so we can simply multiply the number of seconds by 19663 without
+     * worrying about overflow. :) -- ror4
+     */
+    ticks = (3600ul * BcdToByte(bcd_hours) +
+	       60ul * BcdToByte(bcd_minutes) +
+		      BcdToByte(bcd_seconds)) * 19663ul / 1080ul;
+    WritePCClock(ticks);
+  }
+}
+
+INIT static COUNT BcdToByte(COUNT x)
+{
+  return ((((x) >> 4) & 0xf) * 10 + ((x) & 0xf));
+}
+
+INIT static COUNT BcdToDay(BYTE * x)
+{
+  UWORD mon, day, yr;
+
+  mon = BcdToByte(x[1]) - 1;
+  day = BcdToByte(x[0]) - 1;
+  yr = 100 * BcdToByte(x[3]) + BcdToByte(x[2]);
+  if (yr < 1980)
+    return 0;
+  else
+  {
+    day += days[is_leap_year(yr)][mon];
+    while (--yr >= 1980)
+      day += is_leap_year(yr) ? 366 : 365;
+    return day;
+  }
 }
Files ker2006/kernel/memmgr.c and ker2007/kernel/memmgr.c are identical
Files ker2006/kernel/misc.c and ker2007/kernel/misc.c are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/newstuff.c ker2007/kernel/newstuff.c
--- ker2006/kernel/newstuff.c	Sun Apr  4 14:26:04 1999
+++ ker2007/kernel/newstuff.c	Sat Apr 10 23:33:38 1999
@@ -24,15 +24,18 @@
 /* write to the Free Software Foundation, 675 Mass Ave,         */
 /* Cambridge, MA 02139, USA.                                    */
 /****************************************************************/
 
 #ifdef VERSION_STRINGS
-static BYTE *mainRcsId = "$Id: NEWSTUFF.C,v 1.2 1999/04/04 18:51:43 jprice Exp $";
+static BYTE *mainRcsId = "$Id: NEWSTUFF.C,v 1.3 1999/04/11 04:33:39 jprice Exp $";
 #endif
 
 /*
  * $Log: NEWSTUFF.C,v $
+ * Revision 1.3  1999/04/11 04:33:39  jprice
+ * ror4 patches
+ *
  * Revision 1.2  1999/04/04 18:51:43  jprice
  * no message
  *
  * Revision 1.1.1.1  1999/03/29 15:41:22  jprice
  * New version without IPL.SYS
@@ -210,11 +213,13 @@
     char c;
 
     switch ((c = *src++))
     {
       case '/':                /* convert to backslash */
+      case '\\':
 
+	if (bufp[-1] != '\\')
         *bufp++ = '\\';
         break;
 
         /* look for '.' and '..' dir entries */
       case '.':
@@ -232,24 +237,26 @@
             src++;
             if (bufp[-1] == ':')
               bufp++;
           }
           else if (*src == '/' || *src == '\\' || *src == 0)
-          {
-            if (*src != 0)
-              src++;            /* '.' directory: just skip it */
-          }
+	    --bufp;
         }
         else
           *bufp++ = c;
         break;
 
       default:
         *bufp++ = c;
         break;
     }
   }
+  /* remove trailing backslashes */
+  while (bufp[-1] == '\\')
+    --bufp;
+  if (bufp == buf + 2)
+    ++bufp;
   *bufp++ = 0;
   /* finally, uppercase everything */
   upString(buf);
 
   /* copy to user's buffer */
Files ker2006/kernel/nls.c and ker2007/kernel/nls.c are identical
Files ker2006/kernel/nlssupt.asm and ker2007/kernel/nlssupt.asm are identical
Files ker2006/kernel/prf.c and ker2007/kernel/prf.c are identical
Files ker2006/kernel/printer.asm and ker2007/kernel/printer.asm are identical
Files ker2006/kernel/procsupt.asm and ker2007/kernel/procsupt.asm are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/proto.h ker2007/kernel/proto.h
--- ker2006/kernel/proto.h	Sun Apr  4 17:58:04 1999
+++ ker2007/kernel/proto.h	Sun Apr 11 22:21:16 1999
@@ -26,16 +26,22 @@
 /* Cambridge, MA 02139, USA.                                    */
 /****************************************************************/
 
 #ifdef MAIN
 #ifdef VERSION_STRINGS
-static BYTE *Proto_hRcsId = "$Id: PROTO.H,v 1.2 1999/04/04 18:51:43 jprice Exp $";
+static BYTE *Proto_hRcsId = "$Id: PROTO.H,v 1.5 1999/04/12 03:21:17 jprice Exp $";
 #endif
 #endif
 
 /*
  * $Log: PROTO.H,v $
+ * Revision 1.5  1999/04/12 03:21:17  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
+ * Revision 1.4  1999/04/11 04:33:39  jprice
+ * ror4 patches
+ *
  * Revision 1.2  1999/04/04 18:51:43  jprice
  * no message
  *
  * Revision 1.1.1.1  1999/03/29 15:41:30  jprice
  * New version without IPL.SYS
@@ -108,11 +114,11 @@
 VOID setinvld(REG COUNT dsk);
 BOOL flush_buffers(REG COUNT dsk);
 BOOL flush1(struct buffer FAR * bp);
 BOOL flush(void);
 BOOL fill(REG struct buffer FAR * bp, LONG blkno, COUNT dsk);
-BOOL dskxfer(COUNT dsk, LONG blkno, VOID FAR * buf, COUNT mode);
+BOOL dskxfer(COUNT dsk, LONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mode);
 
 /* chario.c */
 VOID INRPT FAR handle_break(void);
 VOID cso(COUNT c);
 VOID sto(COUNT c);
@@ -197,19 +203,20 @@
 COUNT dos_delete(BYTE FAR * path);
 COUNT dos_rmdir(BYTE FAR * path);
 COUNT dos_rename(BYTE FAR * path1, BYTE FAR * path2);
 __FAR_WRAPPER(date, dos_getdate, (void))
 __FAR_WRAPPER(time, dos_gettime, (void))
-BOOL dos_getftime(COUNT fd, date FAR * dp, time FAR * tp);
-BOOL dos_setftime(COUNT fd, date FAR * dp, time FAR * tp);
+COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp);
+COUNT dos_setftime(COUNT fd, date FAR * dp, time FAR * tp);
 LONG dos_getcufsize(COUNT fd);
 LONG dos_getfsize(COUNT fd);
 BOOL dos_setfsize(COUNT fd, LONG size);
 COUNT dos_mkdir(BYTE FAR * dir);
 BOOL last_link(struct f_node FAR * fnp);
 COUNT map_cluster(REG struct f_node FAR * fnp, COUNT mode);
-UCOUNT rdwrblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT mode, COUNT * err);
+UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err);
+UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err);
 __FAR_WRAPPER(COUNT, dos_read, (COUNT fd, VOID FAR * buffer, UCOUNT count))
 COUNT dos_write(COUNT fd, VOID FAR * buffer, UCOUNT count);
 LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin);
 UWORD dos_free(struct dpb *dpbp);
 VOID dos_pwd(struct dpb *dpbp, BYTE FAR * s);
Files ker2006/kernel/segs.inc and ker2007/kernel/segs.inc are identical
Files ker2006/kernel/serial.asm and ker2007/kernel/serial.asm are identical
Files ker2006/kernel/strings.c and ker2007/kernel/strings.c are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/sysclk.c ker2007/kernel/sysclk.c
--- ker2006/kernel/sysclk.c	Sun Apr  4 14:26:10 1999
+++ ker2007/kernel/sysclk.c	Sun Apr 11 22:21:16 1999
@@ -28,15 +28,18 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *RcsId = "$Id: SYSCLK.C,v 1.1.1.1 1999/03/29 15:41:33 jprice Exp $";
+static BYTE *RcsId = "$Id: SYSCLK.C,v 1.2 1999/04/12 03:21:17 jprice Exp $";
 #endif
 
 /*
  * $Log: SYSCLK.C,v $
+ * Revision 1.2  1999/04/12 03:21:17  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
  * Revision 1.1.1.1  1999/03/29 15:41:33  jprice
  * New version without IPL.SYS
  *
  * Revision 1.5  1999/02/08 05:55:58  jprice
  * Added Pat's 1937 kernel patches
@@ -69,34 +72,32 @@
  *    Rev 1.0   02 Jul 1995  8:32:30   patv
  * Initial revision.
  */
 
 #ifdef PROTO
-COUNT ReadATClock(BYTE *, BYTE *, BYTE *, BYTE *);
 BOOL ReadPCClock(ULONG *);
 VOID WriteATClock(BYTE *, BYTE, BYTE, BYTE);
 VOID WritePCClock(ULONG);
 COUNT BcdToByte(COUNT);
 COUNT BcdToWord(BYTE *, UWORD *, UWORD *, UWORD *);
 COUNT ByteToBcd(COUNT);
-LONG WordToBcd(BYTE *, UWORD *, UWORD *, UWORD *);
+VOID DayToBcd(BYTE *, UWORD *, UWORD *, UWORD *);
 #else
-COUNT ReadATClock();
 BOOL ReadPCClock();
 VOID WriteATClock();
 VOID WritePCClock();
 COUNT BcdToByte();
 COUNT BcdToWord();
 COUNT ByteToBcd();
-LONG WordToBcd();
+VOID DayToBcd();
 #endif
 
 /*                                                                      */
 /* WARNING - THIS DRIVER IS NON-PORTABLE!!!!                            */
 /*                                                                      */
 
-static WORD days[2][13] =
+WORD days[2][13] =
 {
   {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
   {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
 };
 
@@ -110,58 +111,59 @@
 static BYTE bcdHours;
 static BYTE bcdHundredths;
 static BYTE bcdSeconds;
 
 static ULONG Ticks;
-static UWORD DaysSinceEpoch;
+UWORD DaysSinceEpoch = 0;
 
 WORD clk_driver(rqptr rp)
 {
   REG COUNT count,
     c;
   BYTE FAR *cp;
 
   switch (rp->r_command)
   {
     case C_INIT:
-      clk.clkDays = DaysSinceEpoch = 1;
-      clk.clkMinutes = 0;
-      clk.clkHours = 0;
-      clk.clkHundredths = 0;
-      clk.clkSeconds = 0;
       rp->r_endaddr = device_end();
       rp->r_nunits = 0;
       return S_DONE;
 
     case C_INPUT:
       count = rp->r_count;
       if (count > sizeof(struct ClockRecord))
           count = sizeof(struct ClockRecord);
-      if (!ReadATClock(bcdDays, &bcdHours, &bcdMinutes, &bcdSeconds))
       {
-        /* AT - deal with it                            */
-        clk.clkDays = BcdToWord(bcdDays, &Month, &Day, &Year);
-        clk.clkMinutes = BcdToByte(bcdMinutes);
-        clk.clkHours = BcdToByte(bcdHours);
-        clk.clkHundredths = BcdToByte(bcdHundredths);
-        clk.clkSeconds = BcdToByte(bcdSeconds);
-      }
-      else
-      {
-        /* PC - deal with it                            */
-        UCOUNT remainder;
-
-        if (!ReadPCClock(&Ticks))
+	ULONG remainder, hs;
+        if (ReadPCClock(&Ticks))
           ++DaysSinceEpoch;
         clk.clkDays = DaysSinceEpoch;
-        clk.clkHours = Ticks / 65520l;
-        remainder = Ticks % 65520l;
-        clk.clkMinutes = (remainder) / 1092;
-        remainder %= 1092;
-        clk.clkSeconds = (remainder * 10) / 182;
-        remainder %= 182;
-        clk.clkHundredths = (remainder * 100) / 182;
+	/*
+	 * Another tricky calculation (after the one in `main.c'). This time
+	 * we do have a problem with overflow, because we need to extract the
+	 * 1/100s portion too. The scaling factor is now
+	 * (100 x 86400) / 0x1800b0 = 108000 / 19663. -- ror4
+	 */
+	hs = 0;
+	if (Ticks >= 64*19663ul) { hs += 64*108000ul; Ticks -= 64*19663ul; }
+	if (Ticks >= 32*19663ul) { hs += 32*108000ul; Ticks -= 32*19663ul; }
+	if (Ticks >= 16*19663ul) { hs += 16*108000ul; Ticks -= 16*19663ul; }
+	if (Ticks >=  8*19663ul) { hs +=  8*108000ul; Ticks -=  8*19663ul; }
+	if (Ticks >=  4*19663ul) { hs +=  4*108000ul; Ticks -=  4*19663ul; }
+	if (Ticks >=  2*19663ul) { hs +=  2*108000ul; Ticks -=  2*19663ul; }
+	if (Ticks >=	19663ul) { hs +=    108000ul; Ticks -=    19663ul; }
+	/*
+	 * Now Ticks < 19663, so Ticks * 108000 < 2123604000 < ULONG_MAX.
+	 * *phew* -- ror4
+	 */
+	hs += Ticks * 108000ul / 19663ul;
+        clk.clkHours = hs / 360000ul;
+        remainder = hs % 360000ul;
+        clk.clkMinutes = remainder / 6000ul;
+        remainder %= 6000ul;
+        clk.clkSeconds = remainder / 100ul;
+        clk.clkHundredths = remainder % 100ul;
       }
       fbcopy((BYTE FAR *) & clk, rp->r_trans, count);
       return S_DONE;
 
     case C_OUTPUT:
@@ -171,22 +173,35 @@
       rp->r_count = count;
       fbcopy(rp->r_trans, (BYTE FAR *) & clk, count);
 
       /* Set PC Clock first                                   */
       DaysSinceEpoch = clk.clkDays;
-      Ticks = (LONG) clk.clkHours * 65520l
-          + (LONG) clk.clkMinutes * 1092l
-          + (LONG) clk.clkSeconds * 18l;
+      {
+	ULONG hs;
+	hs = 360000ul * clk.clkHours +
+	       6000ul * clk.clkMinutes +
+		100ul * clk.clkSeconds +
+			clk.clkHundredths;
+	Ticks = 0;
+	if (hs >= 64*108000ul) { Ticks += 64*19663ul; hs -= 64*108000ul; }
+	if (hs >= 32*108000ul) { Ticks += 32*19663ul; hs -= 32*108000ul; }
+	if (hs >= 16*108000ul) { Ticks += 16*19663ul; hs -= 16*108000ul; }
+	if (hs >=  8*108000ul) { Ticks +=  8*19663ul; hs -=  8*108000ul; }
+	if (hs >=  4*108000ul) { Ticks +=  4*19663ul; hs -=  4*108000ul; }
+	if (hs >=  2*108000ul) { Ticks +=  2*19663ul; hs -=  2*108000ul; }
+	if (hs >=    108000ul) { Ticks +=    19663ul; hs -=    108000ul; }
+	Ticks += hs * 19663ul / 108000ul;
+      }
       WritePCClock(Ticks);
 
       /* Now set AT clock                                     */
       /* Fix year by looping through each year, subtracting   */
       /* the appropriate number of days for that year.        */
       for (Year = 1980, c = clk.clkDays; c > 0;)
       {
-        count = !(Year & 0x3) ? 366 : 365;
-        if (c > count)
+        count = is_leap_year(Year) ? 366 : 365;
+        if (c >= count)
         {
           ++Year;
           c -= count;
         }
         else
@@ -197,15 +212,15 @@
       /* days for that year.  Use this to index the table.    */
       for (Month = 1; Month < 13; ++Month)
       {
         if (days[count == 366][Month] > c)
         {
-          Day = c - days[count == 366][Month - 1];
+          Day = c - days[count == 366][Month - 1] + 1;
           break;
         }
       }
-      WordToBcd((BYTE *) bcdDays, &Month, &Day, &Year);
+      DayToBcd((BYTE *) bcdDays, &Month, &Day, &Year);
       bcdMinutes = ByteToBcd(clk.clkMinutes);
       bcdHours = ByteToBcd(clk.clkHours);
       bcdSeconds = ByteToBcd(clk.clkSeconds);
       WriteATClock(bcdDays, bcdHours, bcdMinutes, bcdSeconds);
       return S_DONE;
@@ -221,33 +236,23 @@
     default:
       return failure(E_FAILURE);	/* general failure */
   }
 }
 
-COUNT BcdToByte(COUNT x)
-{
-  return ((((x) >> 4) & 0xf) * 10 + ((x) & 0xf));
-}
-
-COUNT BcdToWord(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr)
-{
-  *mon = BcdToByte(x[1]);
-  *day = BcdToByte(x[0]);
-  *yr = BcdToByte(x[3]) * 100 + BcdToByte(x[2]);
-  if (*yr < 1980)
-    return -1;
-  else
-    return *day + days[!(*yr & 0x3)][*mon - 1] + ((*yr - 1980) * 365) + ((*yr - 1980 + 3) / 4);
-}
-
 COUNT ByteToBcd(COUNT x)
 {
   return ((x / 10) << 4) | (x % 10);
 }
 
-LONG WordToBcd(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr)
+VOID DayToBcd(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr)
 {
   x[1] = ByteToBcd(*mon);
   x[0] = ByteToBcd(*day);
   x[3] = ByteToBcd(*yr / 100);
   x[2] = ByteToBcd(*yr % 100);
+}
+
+/* Used by `main.c'. */
+VOID FAR init_call_WritePCClock(ULONG ticks)
+{
+  WritePCClock(ticks);
 }
Files ker2006/kernel/syspack.c and ker2007/kernel/syspack.c are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/systime.c ker2007/kernel/systime.c
--- ker2006/kernel/systime.c	Sun Apr  4 14:26:12 1999
+++ ker2007/kernel/systime.c	Sun Apr 11 22:21:18 1999
@@ -30,15 +30,18 @@
 #include "time.h"
 #include "date.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *RcsId = "$Id: SYSTIME.C,v 1.1.1.1 1999/03/29 15:41:34 jprice Exp $";
+static BYTE *RcsId = "$Id: SYSTIME.C,v 1.2 1999/04/12 03:21:18 jprice Exp $";
 #endif
 
 /*
  * $Log: SYSTIME.C,v $
+ * Revision 1.2  1999/04/12 03:21:18  jprice
+ * more ror4 patches.  Changes for multi-block IO
+ *
  * Revision 1.1.1.1  1999/03/29 15:41:34  jprice
  * New version without IPL.SYS
  *
  * Revision 1.5  1999/02/08 05:55:58  jprice
  * Added Pat's 1937 kernel patches
@@ -129,12 +132,12 @@
   ClkRecord.clkMinutes = *mp;
   ClkRecord.clkSeconds = *sp;
   ClkRecord.clkHundredths = *hdp;
 
   YearsSince1980 = Year - 1980;
-  ClkRecord.clkDays = DayOfMonth
-      + days[!(Year & 0x3)][Month - 1]
+  ClkRecord.clkDays = DayOfMonth - 1
+      + days[is_leap_year(Year)][Month - 1]
       + ((YearsSince1980) * 365)
       + ((YearsSince1980 + 3) / 4);
 
   ClkReqHdr.r_length = sizeof(request);
   ClkReqHdr.r_command = C_OUTPUT;
@@ -165,12 +168,12 @@
   if (ClkReqHdr.r_status & S_ERROR)
     return;
 
   for (Year = 1980, c = ClkRecord.clkDays; c > 0;)
   {
-    count = !(Year & 0x3) ? 366 : 365;
-    if (c > count)
+    count = is_leap_year(Year) ? 366 : 365;
+    if (c >= count)
     {
       ++Year;
       c -= count;
     }
     else
@@ -181,11 +184,11 @@
   /* that year.  Use this to index the table.                     */
   for (Month = 1; Month < 13; Month++)
   {
     if (days[count == 366][Month] > c)
     {
-      DayOfMonth = c - days[count == 366][Month - 1];
+      DayOfMonth = c - days[count == 366][Month - 1] + 1;
       break;
     }
   }
 
   *mp = Month;
@@ -193,13 +196,11 @@
   *yp = Year;
 
   /* Day of week is simple. Take mod 7, add 2 (for Tuesday        */
   /* 1-1-80) and take mod again                                   */
 
-  DayOfWeek = (ClkRecord.clkDays - 1) % 7;
-  DayOfWeek += 2;
-  DayOfWeek %= 7;
+  DayOfWeek = (ClkRecord.clkDays + 2) % 7;
   *wdp = DayOfWeek;
 }
 
 COUNT DosSetDate(mp, mdp, yp)
 BYTE FAR *mp,
@@ -209,21 +210,21 @@
   Month = *mp;
   DayOfMonth = *mdp;
   Year = *yp;
   if (Year < 1980 || Year > 2099
       || Month < 1 || Month > 12
-      || DayOfMonth < 1 || DayOfMonth > ndays[!(Year & 0x3)][Month])
+      || DayOfMonth < 1 || DayOfMonth > ndays[is_leap_year(Year)][Month])
     return DE_INVLDDATA;
 
   DosGetTime((BYTE FAR *) & ClkRecord.clkHours,
              (BYTE FAR *) & ClkRecord.clkMinutes,
              (BYTE FAR *) & ClkRecord.clkSeconds,
              (BYTE FAR *) & ClkRecord.clkHundredths);
 
   YearsSince1980 = Year - 1980;
-  ClkRecord.clkDays = DayOfMonth
-      + days[!(Year & 0x3)][Month - 1]
+  ClkRecord.clkDays = DayOfMonth - 1
+      + days[is_leap_year(Year)][Month - 1]
       + ((YearsSince1980) * 365)
       + ((YearsSince1980 + 3) / 4);
 
   ClkReqHdr.r_length = sizeof(request);
   ClkReqHdr.r_command = C_OUTPUT;
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/kernel/task.c ker2007/kernel/task.c
--- ker2006/kernel/task.c	Sun Apr  4 14:26:12 1999
+++ ker2007/kernel/task.c	Sat Apr 10 23:33:38 1999
@@ -28,15 +28,18 @@
 
 #include "portab.h"
 #include "globals.h"
 
 #ifdef VERSION_STRINGS
-static BYTE *RcsId = "$Id: TASK.C,v 1.2 1999/03/29 17:05:09 jprice Exp $";
+static BYTE *RcsId = "$Id: TASK.C,v 1.3 1999/04/11 04:33:39 jprice Exp $";
 #endif
 
 /*
  * $Log: TASK.C,v $
+ * Revision 1.3  1999/04/11 04:33:39  jprice
+ * ror4 patches
+ *
  * Revision 1.2  1999/03/29 17:05:09  jprice
  * ror4 changes
  *
  * Revision 1.1.1.1  1999/03/29 15:41:41  jprice
  * New version without IPL.SYS
@@ -261,17 +264,12 @@
   {
     REG COUNT i;
 
     for (i = 0; i < 20; i++)
     {
-      REG COUNT ret;
-
-      if (q->ps_filetab[i] != 0xff
-          && ((ret = CloneHandle(q->ps_filetab[i])) >= 0))
-      {
-        p->ps_filetab[i] = ret;
-      }
+      if (q->ps_filetab[i] != 0xff && CloneHandle(i) >= 0)
+        p->ps_filetab[i] = q->ps_filetab[i];
       else
         p->ps_filetab[i] = 0xff;
     }
   }
   else
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/lib/libm.mak ker2007/lib/libm.mak
--- ker2006/lib/libm.mak	Mon Mar 29 09:39:36 1999
+++ ker2007/lib/libm.mak	Sun Apr 11 22:19:20 1999
@@ -1,9 +1,9 @@
 
 libm.lib: c:\tc\lib\cs.lib
-        tlib c:\tc\lib\cs.lib *H_LDIV *H_LLSH *H_LURSH *N_LXMUL *H_LRSH *H_SPUSH *N_SCOPY
-        tlib libm +H_LDIV +H_LLSH +H_LURSH +N_LXMUL +H_LRSH +H_SPUSH +N_SCOPY
+        tlib c:\tc\lib\cs.lib *H_LDIV *H_LLSH *H_LURSH *N_LXMUL *F_LXMUL *H_LRSH *H_SPUSH *N_SCOPY
+        tlib libm +H_LDIV +H_LLSH +H_LURSH +N_LXMUL +F_LXMUL +H_LRSH +H_SPUSH +N_SCOPY
         del *.OBJ
 
 
 clean:
         ..\utils\rm -f *.obj *.lib *.bak status.me
Files ker2006/makedist.bat and ker2007/makedist.bat are identical
Files ker2006/mkboot.txt and ker2007/mkboot.txt are identical
Files ker2006/readme.txt and ker2007/readme.txt are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/relnotes.txt ker2007/relnotes.txt
--- ker2006/relnotes.txt	Mon Mar 29 09:39:18 1999
+++ ker2007/relnotes.txt	Wed Dec 31 18:00:00 1969
@@ -1,134 +0,0 @@
-Release Notes for DOS-C version 1.0 Beta 2
-December 6, 1998
-
-Differences between DOS-C v1.0 Beta 2 and Beta 1
-------------------------------------------------
-1. Totally new IO subsystem.
-
-2. Drivers for printer and serial ports now supported.
-
-3. Complete rewrite of error subsystem.  Now matches
-
-4. IPL builds but will not run -- probably due to incorrect handling
-   of shared I/O subsystem (broken by kernel changes in shared files).
-
-5. Some bug fixes.
-
-NOTE: differences betweene 0.91a and 1.0 Beta 1 undcoumented.
-
-Differences between DOS-C v0.91 and DOS-C v0.91a
-------------------------------------------------
-1. IPL now builds and loads correctly.
-
-2. This release is built with Borland C++ v3.1 and needs MS-DOS exe2bin.
-Any deviations will require some work on your part.
-
-Differences between DOS-C v0.91 and DOS-C v0.91a
-------------------------------------------------
-1. Various changes in task handling that improved compatability.  DOS-C now
-runs DOOM, WordPerfect, MS-DOS applications such as QBASIC, etc.
-
-2. IPL does not build (broken by kernel changes in shared files).
-
-Differences between DOS-C v0.90a and DOS-C v0.91
-------------------------------------------------
-1. Added FreeDOS OEM ID (0xfd).
-
-2. Improved stack handling.  Now DOS-C uses three stacks: private kernel
-stack, character I/O stack and block I/O stack.  Error stack is still
-missing.  Now device drivers that do DOS system calls from within the
-driver work (e.g. - Logitech mouse.com).
-
-3. Added config.sys support.  The following config options are available:
-	- BUFFERS
-	- FILES
-	- COMMAND
-	- REM
-
-4. Improved int 2fh handler.  Now int 2fh is handled identically as MS-DOS
-with the exception of int 2hf 12XX calls.
-
-5. NLS functions are now supported, but NLSFUNC.EXE support is incomplete
-and untested.
-
-Differences between DOS-C v0.90 and DOS-C v0.90a
-------------------------------------------------
-1. Only ident strings for RCS and source placed under GPL.  All other
-functionality is identical.
-
-Differences between DOS-C and DOS/NT
-------------------------------------
-1. DOS-C is derived from DOS/NT.
-
-2. DOS-C contains FCB support, as well as other functionality not contained
-in DOS/NT.
-
-3. DOS-C is inteneded to work as a 100% DOS clone, although its initial
-release (0.90) still has some functionality missing.  See intfns.txt for
-details.
-
-Differences between release 1.03 and 1.02:
------------------------------------------
-1. Boot now knows about 1.2MB and 1.44MB drives.
-
-2. sys.exe error handler improved.  Now 5 retries are attempted on any disk
-operation before it exits.
-
-3. Kernel and ipl.sys exe loader bug fixed.  Kernel appears more stable as a
-result.
-
-4. "Production" code is now being distributed.  Symbol tables no longer in
-all exe files and remote debugger support no longer in kernel.
-
-Differences between release 1.02 and 1.0:
------------------------------------------
-1. Partitions >32 MB are now supported with this release.
-
-2. Undocumented get/set switchar is now supported.
-
-3. A new utility, sys.exe, is now supplied to create bootable floppies.
-
-
-The following differences exist between DOS/NT kernel and MS-DOS:
-
-1. The following interrupts are supported:
-	20h
-	21h
-	22h
-	23h
-	24h
-	27h
-	28h
-	2fh
-
-2. Interrupts 28h and 2fh are stubs in this version.
-
-3. A separate list, int21.txt, is provided to document the supported DOS int
-   21h functions.
-
-4. Directory updates do not occur until the final open handle to a file is
-   closed.
-
-5. Seeks past eof on files with write permission do not extend the file.
-
-6. Reading of config.sys is disabled for this release.
-
-7. Invalid function calls cause a register dump.
-
-7. There are no drivers for aux and lpt devices in this release.
-
-8. Command line editing does not support insert and delete.
-
-10. Error Handling is done entirely within the kernel.
-
-
-The following differences exist between DOS/NT command.com and MS-DOS:
-
-1. The command cls is not supported.
-
-2. Pipes are not supported.
-
-3. The dir command does not support the sort option.
-
-4. The copy command does not support append and device drivers.
-
Files ker2006/sys/bin2c.c and ker2007/sys/bin2c.c are identical
Binary files ker2006/sys/bin2c.exe and ker2007/sys/bin2c.exe differ
Files ker2006/sys/bin2c.mak and ker2007/sys/bin2c.mak are identical
Files ker2006/sys/sys.c and ker2007/sys/sys.c are identical
diff --new-file --recursive --ignore-space-change -U 5 --report-identical-files ker2006/sys/sys.mak ker2007/sys/sys.mak
--- ker2006/sys/sys.mak	Thu Apr  1 01:24:06 1999
+++ ker2007/sys/sys.mak	Sat Apr 10 23:37:06 1999
@@ -31,11 +31,11 @@
 
 b_fat16.h:      ..\boot\b_fat16.bin bin2c.exe
                 bin2c ..\boot\b_fat16.bin b_fat16.h b_fat16
 
 sys.exe:        sys.cfg $(EXE_dependencies)
-                $(LINK) /k/x/c/L$(LIBPATH) @&&|
+                $(LINK) /x/c/L$(LIBPATH) @&&|
 c0t.obj+
 sys.obj
 sys
 		# no map file
 $(LIBS)+
Files ker2006/utils/exe2bin.exe and ker2007/utils/exe2bin.exe are identical
Files ker2006/utils/exeflat.com and ker2007/utils/exeflat.com are identical
Files ker2006/utils/indent.exe and ker2007/utils/indent.exe are identical
Files ker2006/utils/indent.ini and ker2007/utils/indent.ini are identical
Files ker2006/utils/proto.bat and ker2007/utils/proto.bat are identical
Files ker2006/utils/rm.exe and ker2007/utils/rm.exe are identical
