name             size   date     time   chap page   notes

DOC2             5632   3-13-88   8:02p             This file. See (1)
SIMPLE   ASM     5888   2-21-88   3:52p    3   87   Revised. See (2)
TONE     ASM      768  11-02-86   2:16a    4  112
CONSOLE  ASM    14592  11-02-86   2:17a    4  121
IOCTL    ASM     5120  11-09-86  11:14a    5  139
IOCTL    COM      743  11-08-86  10:31p    5  139   .com file for above
PRINTER  ASM    17536  11-15-86  12:15a    5  166
CLK      ASM    25472   3-08-88   4:14p    6  217   Revised. See (3)
RAMDISK  ASM    18048  11-29-86   1:40p    8  306
STRUC24  ASM     9856  12-25-86  11:47p    9  331   See (4)
PROTO    ASM    19328   3-07-88   2:50p   10  386   Revised. See (5)
SHOWSEG  ASM      512   1-01-86   3:58p   10  400
HEX2ASC  ASM      896  10-12-86   3:05p   10  401
DUMP     ASM     5760   1-01-86   5:25p   10  402
PRTMSG   ASM      640   9-21-86   9:18p   10  406   See (6)
NEWSTACK ASM      896  12-31-86  11:45a   10  408
INT29H   ASM      640  12-31-86  11:35a   10  409
SETCMD   ASM     1024  12-30-86   7:06p   10  411   See (7)
STRAT    ASM     1280  10-13-87   9:41p   10  412   See (7)
SETATT   ASM     1408  12-30-86   7:05p   10  413

notes

1. Due to the changes that are made at the last minute, some comments
in the book do not appear in these sources. They are, however, cosme-
tic items such as author, date, and purpose: the code is the same.

2. Changes to the Simple Device Driver

Page 87:

The attribute word in the Device Header is incorrect and should be:

        attribute       dw      8000h           ;character device

Pages 85,89:

For many versions of DOS, the Simple Device Driver as listed in the
book booted correctly. However, for other versions of MS-DOS, the
Simple Device Driver hung the system during the boot. In order to
ensure that the Simple Device Driver work with all versions of DOS,
the Break Address code needs to be added. The following code is added
right after the label 'exit2' (shown):

        exit2:                          ; Set done flag and no error
                lea     ax,exit         ;address of end of simple
                mov     es:[bx]+0eh,ax  ;tell DOS next free location
                push    cs              ;same for segment address
                pop     ax              ; now in ax
                mov     es:[bx]+10h,ax  ;return to DOS
                mov     es:word ptr 3[bx],0100h

Page 86,89:

The label 'exit' is placed just before the End of Program Section and
is after the last code address of the Simple Device Driver. This Break
Address tells DOS that memory locations following  'exit' are not part
of the Simple Device Driver and are eligible for use by DOS. The code
should look like:

        exit:
        ;***********************************************************
        ;*      END OF PROGRAM                                     *
        ;***********************************************************


3. Changes to the Clock Device Driver:

Although the book indicates to name the file 'clock.asm', some ver-
sions of MS-DOS do not allow the use of 'clock'. For example, the MS-
DOS version 2.11 supplied with the Toshiba 1100 has a built-in clock
and no disk files may be named 'clock'. This is a gross error. For PC-
DOS you may rename this file to 'clock.asm'.

Pages 190, 217:

The timer segment should look like:

timer           segment at      0h      ;int 1c segment
                org     1ch*4
timer_int       label   dword           ;* revised to double word
timer           ends

Pages 194,220:

The screen attribute for the time string variable 'time' was omitted.
The value '0b' yields a blue character:

time           dw        8 dup (0b3ah)  ;time display

Pages 199,223:

The 'clkint' procedure should be moving 16 bytes of the time string.
Change the 10 to 16 in the second instruction before the label 'hlow':


        mov     cx,16           ;move 16 bytes
        cli                     ;clear interrupts
hlow:                           ;wait for horizontal scan

Pages 205,226:

Just before the label 'curr_days' in the code for the Input command, a
check for the current year being a leap year was missing. The
following code:

;BX has total days and cl has leap year indicator
        mov     ah,0                    ;set up for add
        add     bx,ax                   ;add leap days to total

should be changed to:

;BX has total days and cl has leap year indicator
        mov     ah,0                    ;set up for add
        push    cx                      ;* save for later use
        cmp     cl,0                    ;* check for year is leap year
        je      leapadj                 ;* maybe not past leap
        inc     ax                      ;* past leap year => add 1
leapadj:
        add     bx,ax                   ;add leap days to total

The code for converting months to elapsed days is incorrectly adding
an extra months worth of days. The following code just before the
label 'cvt2days':

        push    cx                      ;save for leap year check
        mov     bh,0                    ;clear hi-order
cvt2days:

should be changed to:

        push    cx                      ;save for leap year check
        dec     cx                      ;* elapsed up to current month
        mov     bh,0                    ;clear hi-order
cvt2days:

Pages 206,227:

The code at the end of the Input command processing did not account
for a leap year when adjusting past 2/29. In addition, the days in the
current month was not read from the clock chip. The following code:

        add     ax,bx                   ;add to days in current year
        cmp     cl,3                    ;past March?
        jl      leapyr                  ;no
        inc     ax                      ;yes - add 1 for 2/29
leapyr: pop     bx                      ;restore DOS date offset
        pop     es                      ;restore DOS date segment
        mov     es:[bx].dos_day,ax      ;return days since 1/1/80
        mov     ax,0                    ;status ok
        mov     bx,6                    ;count of 6
        jmp     load_status             ;restore es:bx exit

should be modified to look like:

        add     ax,bx                   ;add to days in current year
        pop     bx                      ;* leap indicator?
        cmp     bl,0                    ;* is current year leap?
        jne     leapyr                  ;* no
        cmp     cl,3                    ;past March?
        jl      leapyr                  ;no
        inc     ax                      ;yes - add 1 for 2/29
leapyr:
        xchg    ax,cx                   ;* save days in cx
        dec     dx                      ;* base+6 is
        in      al,dx                   ;* days in current month
        call    bcd2hex                 ;* convert to hex
        mov     ah,0                    ;* clear hi for next add
        add     cx,ax                   ;* add days in this month
        dec     cx                      ;* subtract 1 for elapsed days
        xchg    ax,cx                   ;* total days in ax
        pop     bx                      ;restore DOS date offset
        pop     es                      ;restore DOS date segment
        mov     es:[bx].dos_day,ax      ;return days since 1/1/80
        mov     ax,0                    ;status ok
        mov     bx,6                    ;count of 6
        jmp     load_status             ;restore es:bx exit

Pages 208,228:

In the conversion from DOS date format to chip date format, the days
since 1/1/80 was not incremented by 1 for elapsed days. The code
between the labels 'out_years' and 'out1' should look like:

out_years:
        mov     ax,cs:dosdays           ;get days since 1/1/80
        cmp     ax,0                    ;date not set?
        je      out8                    ;skip everything
        inc     ax                      ;* add 1 for elapsed days
        mov     bx,0                    ;BX = year count
out1:   cmp     ax,365                  ;day count within a year?


Pages 215,232:

The code to switch the timer interrupt to point to our 'clkint' rou-
tine should be changed to reflect the change in the timer interrupt
definition. The code just after the label 'calc' should look like:

calc:   call    display                 ;setup initial time
        cli                             ;clear interrupts
        assume  es:timer                ;new directive
        mov     ax,timer                ;get segment addr
        mov     es,ax                   ;set ES
        mov     ax,es:timer_int         ;get old timer offset
        mov     cs:old1c_ofs,ax         ;save it
        mov     ax,es:timer_int[2]      ;get old timer segment
        mov     cs:old1c_seg,ax         ;save it
        lea     ax,clkint               ;get new offset
        mov     es:timer_int,ax         ;set new offset
        mov     es:timer_int[2],cs      ;also segment
        assume  es:cseg                 ;restore directive
        sti                             ;restore interrupts

4. 'STRUC24.ASM' contains the definitions for all of the strucs. You
may include this file in any device driver, it may be more efficient
to break out each struc into separate files and to include them only
as needed.

5. Changes to the prototype program 'Proto.asm' are identical to those
made for the Clock Device Driver.

6. 'PRTMSG.ASM' can be used in any program and uses the printer BIOS
routine.

7. 'SETCMD.ASM' is named 'dosver' in the source. If this code is used
in the Initialization Command code, then the STRATEGY procedure must
be replaced by the version in 'STRAT.ASM'. The bold-face type for the
changed statements in 'STRAT.ASM' didn't make it to printing. The two
statements are:

        cmp     al,cs:max_cmd
        ja      unknown
                                                      