[comp.os.minix] Resending code for BOOTCODE.ASM, ref.: Booting MINIX from harddisk

SINSB%NOBERGEN.BITNET@wiscvm.wisc.edu (10/22/87)

RESENDING CODE FOR BOOTCODE.ASM, REF BOOTING MINIX FROM HARDDISK

I just discovered that the code I sent for bootcode.asm somhow  had been
garbled, either by me or during transmission. So I'll give it another
try.


----------------  Start of code for BOOTCODE.ASM --------

    page 60,132
    title     Write prompting boot to hard disk
;
;   This program will write a new boot sector to drive C:
;   that prompts whether you wish to boot xenix
;   or dos:
;
;        X=Xenix, D=Dos
;
;   The reply is the one character first initial of the system.
;
;   This program is written as a .com file so it should be assembled
;   and linked, ignoring the missing stack segment message from the linker.
;   It should then be converted to a com file with exe2bin.
;
;
;   MASM BOOTCODE,,,;
;   LINK BOOTCODE;
;   EXE2BIN BOOTCODE.EXE BOOTCODE.COM
;   ERASE     BOOTCODE.EXE
;
;   Now the program is ready to run.  It produces a message at the
;   start telling you what it is going to do, to allow aborting before
;   touching your hard disk.
;
;   The boot only runs on an AT or a pc with Enhanced Graphics Adapter,
;   since it uses subfunction 19 of the video call, Write String.
;
;   Distribution of this program in any way is acceptable to me.
;
;        W.D. Cagle   75206,2701
;
code     segment 'code'
    assume    cs:code,ds:code
video    equ  10h
kbd equ  16h
diskio   equ  13h
basic    equ  18h
dos equ  21h
;
cr  equ  0dh
lf  equ  0ah
base     equ  $
bootloc equ   7c00h
;
    org  100h
writboot proc near
    jmp  start               ;jump around constants
bootsec proc  near
bcode    equ  $
adjust   equ  600h-103h      ;stupid adjustment
    cli                 ;disable interrupts
    xor  ax,ax               ;clear
    mov  ss,ax               ;place in stack segment
    mov  sp,offset bootloc   ;get my address
    mov  si,sp               ;place in source
    push ax             ;
    pop  es             ;put in extra segment
    push ax             ;now for ds
    pop  ds             ;load it
    sti                 ;enable interrupts
    cld                 ;make move direction positive
    mov  di,600h        ;place to move to
    mov  cx,100h        ;how many words to move
    rep  movsw               ;move it
    mov  ax,offset relboot+adjust ;this gets rid of exe2bin
    push ax             ;wanting a fixup, cs=0 anyway
    ret
;
relboot:
    mov  byte ptr p1+adjust,0
    mov  byte ptr p2+adjust,0
    mov  byte ptr p3+adjust,0
    mov  byte ptr p4+adjust,0
wrprmpt:
    mov  si,offset msg4+adjust    ;go ask question
    xor  ch,ch               ;clear
    lodsb                    ;get message length
    mov  cl,al               ;to cl
    mov  ax,1301h       ;say write message
    mov  bx,7           ;use normal attribute
    sub  dx,dx               ;row 0 col 0
    mov  bp,si               ;get location of message
    int  video               ;print message
    mov  al,' '                  ;blank out response
    mov  cx,1           ;1 byte
    mov  ah,10               ;say write char only
    int  video               ;do it
    mov  ah,0           ;get keyboard input
    int  kbd
    and  al,7fh-20h          ;make upper case
    push ax
    mov  ah,10               ;say write char
    mov  cx,1           ;1 byte
    int  video               ;let 'em see what they typed
    pop  ax
    cmp  al,'D'                  ;want dos?
    je   lddos               ;yes
    cmp  al,'X'                  ;want xenix
    je   xenix               ;yes
    jmp  wrprmpt        ;ask again
;
lddos:
    mov  al,4           ;id for dos with 16-bit FAT's
    mov  si,offset dosnm+adjust   ;dos name
    jmp  short gotact1       ;continue
;
xenix:
    mov  al,0           ;id for xenix
    mov  si,offset xenixnm+adjust ;xenix name
gotact1:
    mov  di,offset msg5nm+adjust ;put name in message
    mov  cx,6           ;length of name
    cld                 ;positive direction
    rep  movsb               ;move it
    mov  bl,4           ;max 4 to search
    mov  si,offset parttbl+adjust  ;point to first entry
getpart_a:
    cmp  byte ptr[si+4],al   ;is this the one
    je   gotact2        ;yes
    add  si,16               ;to next
    dec  bl             ;count em
    jnz  getpart_a      ;not end yet
    mov  si,offset msg5+adjust    ;
    xor  ch,ch               ;clear
    lodsb                    ;get message length
    mov  cl,al               ;to cl
    mov  ax,1301h       ;say write message
    mov  bx,7           ;use normal attribute
    sub  dx,dx               ;row 0 col 0
    mov  bp,si               ;get location of message
    int  video               ;print message
lupe1:   jmp  lupe1               ;and hang
;
gotact2:
    mov  byte ptr[si],80h    ;say active
    push si
    push bx
    mov  ax,0301h
    mov  bx,600h
    mov  cx,1
    mov  dx,80h
    int  diskio
    pop  bx
    pop  si
;
gotact:
    mov  dx,[si]        ;drive in dh, head in dl
    mov  cx,[si+2]      ;get track in ch, sector in cl
    mov  bp,si               ;save indicator
;
;
finis:
    mov  di,5           ;retry count
rdboot:
    mov  bx,bootloc          ;location for boot
    mov  ax,0201h       ;say read 1 sector
    push di             ;
    int  diskio              ;go do it
;
    pop  di             ;
    jnc  goodrd              ;good read
;
    xor  ax,ax               ;say recalibrate
    int  diskio              ;do it
    dec  di             ;count retries
    jnz  rdboot              ;continue trying
    mov  si,offset msg2+adjust    ;point to bad disk message
wrmsg:
    xor  ch,ch               ;clear
    lodsb                    ;get message length
    mov  cl,al               ;to cl
    mov  ax,1301h       ;say write message
    mov  bx,7           ;use normal attribute
    sub  dx,dx               ;row 0 col 0
    mov  bp,si               ;get location of message
    int  video               ;print message
lupe:    jmp  lupe           ;and hang
;
goodrd:
    mov  si,offset msg3+adjust    ;point to no boot rec msg
    cmp  word ptr bootsig,0aa55h ;see if boot signature
    jne  wrmsg
;
    mov  si,bp               ;restore partition table pointer
    mov  ax,offset bootloc   ;where partition boot start
    push ax
    ret
;
;
msg2     db   lmsg2,'Error loading operating system'
lmsg2    equ  ($-msg2)-1
msg3     db   lmsg3,'Missing operating system'
lmsg3    equ  ($-msg3)-1
msg4     db   lmsg4,'Enter X=Xenix, D=DOS '
lmsg4    equ  ($-msg4)-1
msg5     db   lmsg5,'Cannot find '
msg5nm   db   'xxxxx'
lmsg5    equ  ($-msg5)-1
dosnm    db   'DOS  '
minixnm db    'XENIX'
parttbl equ   byte ptr bcode+1beh
p1  equ  bcode+1beh
;
p2  equ  p1+16
;
p3  equ  p2+16
;
p4  equ  p3+16
;
signat   equ  p4+16
bootsig equ   base+7dfeh
    org  bcode+512
bootsec endp
diskbuf db    512 dup(?)
helloms db    cr,lf
    db   'Bootwriter - This program will read the boot sector',cr,lf
    db   'from disk C: and merge the partition table in with',cr,lf
    db   'the boot program which follows and write it all back',cr,lf
    db   'out to disk C: overlaying what is there.  The resultant',cr,lf
    db   'boot program will prompt for the desired system when',cr,lf
    db   'booting, Xenix or Dos.',cr,lf
    db   cr,lf
    db   'The original boot program will be saved in a file named',cr,lf
    db   'IBMBOOT.SVE in the default directory.',cr,lf
    db   cr,lf
    db   'If you do not wish to do this, you should control-c out',cr,lf
    db   'at the prompt.',cr,lf
    db   'Reply with the enter key to continue, or control-c to stop $'
crlf     db   cr,lf,'$'
ibmboot db    'IBMBOOT.SVE',0
okmsg    db   'Boot sector updated',cr,lf,'$'
ermsg1   db   'Error reading boot sector',cr,lf,'$'
ermsg2   db   'Cannot open save file',cr,lf,'$'
ermsg3   db   'Cannot write save file',cr,lf,'$'
ermsg4   db   'Cannot close save file',cr,lf,'$'
ermsg5   db   'Cannot write boot sector, boot sector creamed',cr,lf,'$'
boothdl dw    0
;
start:
    mov  dx,offset helloms   ;point to signon message
    mov  ah,9           ;print string
    int  dos            ;say print it
;
rdcns:   mov  ah,0ch              ;clear kb buffer
    mov  al,1           ;read keyboard input
    int  dos            ;do it
    cmp  al,cr               ;enter key?
    jne  rdcns               ;wait till it is
;
;   well, we continue
;
    mov  dx,offset crlf      ;echo the return
    mov  ah,9
    int  dos            ;write to console
;
    mov  si,5           ;set up for 5 retries
rddsk:
    push si             ;save retry counter
    mov  ah,2           ;say read disk
    mov  al,1           ;1 sector
    mov  bx,offset diskbuf   ;point to buffer
    mov  ch,0           ;say cylinder 0
    mov  cl,1           ;say sector 1
    mov  dh,0           ;say track 0
    mov  dl,80h              ;say hard drive 0
    int  diskio              ;do the io
    pop  si
    jnc  rdok           ;good read
    dec  si             ;any more tries?
    jnz  rddsk               ;yes, try again
    mov  dx,offset ermsg1    ;point to trouble message
    mov  ah,9           ;say console write
    int  dos            ;can't read boot sector
    mov  ah,4ch              ;say terminate
    mov  al,1           ;error return code
    int  dos            ;does not return
;
rdok:
    mov  dx,offset ibmboot   ;get file name
    mov  ah,3ch              ;say create it
    sub  cx,cx               ;zero attribute
    int  dos
    jnc  openok              ;file opened
    mov  dx,offset ermsg2    ;can't open save file
    mov  ah,9
    int  dos            ;tell 'em
    mov  ah,4ch              ;say terminate
    mov  al,2           ;reason
    int  dos            ;
;
openok:
    mov  boothdl,ax          ;save handle
    mov  bx,ax               ;and put in bx
    mov  ah,40h              ;say write to file
    mov  dx,offset diskbuf   ;get location
    mov  cx,512              ;say 1 sector
    int  dos            ;ask to have it done
    jnc  wrtok               ;good write
    mov  dx,offset ermsg3    ;can't write to save file
    mov  ah,9
    int  dos            ;tell 'em
    mov  ah,4ch              ;say terminate
    mov  al,3           ;reason
    int  dos            ;
;
wrtok:
    mov  ah,3eh              ;say close file
    mov  bx,boothdl          ;
    int  dos            ;
    jnc  closok              ;closed ok
    mov  dx,offset ermsg4    ;can't close save file
    mov  ah,9
    int  dos            ;tell 'em
    mov  ah,4ch              ;say terminate
    mov  al,4           ;reason
    int  dos            ;
;
closok:
    push si
    mov  si,offset diskbuf+1beh   ;start of partition table
    mov  di,offset bootsec+1beh   ;ditto for new sector
    cld                 ;make direction positive
    mov  cx,4*16+2      ;how many bytes to move
    rep  movsb               ;move em
    mov  si,5           ;5 retries
wrtboot:
    push si
    mov  ah,3           ;say write to disk
    mov  al,1           ;say 1 sector
    mov  bx,offset bootsec   ;point to sector to write
    mov  cx,1           ;say sector 1
    mov  dx,80h              ;
    int  diskio              ;do the io
    pop  si
    jnc  updok               ;good write to boot sector
    dec  si             ;count retries
    jnz  wrtboot        ;try again
;
    mov  dx,offset ermsg5    ;can't write boot sector file
    mov  ah,9
    int  dos            ;tell 'em
    mov  ah,4ch              ;say terminate
    mov  al,5           ;reason
    int  dos            ;
;
updok:
    mov  dx,offset okmsg     ;say we did it
    mov  ah,9
    int  dos            ;tell 'em
    mov  ah,4ch              ;say terminate
    mov  al,0           ;good return code
    int  dos            ;
writboot endp
;
;   new boot code follows
;
code     ends
    end  writboot

--------------------  end of BOOTCODE.ASM ----------------------