To: INFO-IBMPC@usc-isib.ARPA Subject: Re: BOOTCODE.ASM Date: Tue, 28 Jan 86 14:38:52 -0500 From: Dan Grim I have discovered through my own sad experience that BOOTCODE.ASM is not able to deal with newer DOS partitions that use the 16-bit FAT format. BOOTCODE.ASM understands DOS with 12-bit FAT's (ID byte = 1) and Xenix (ID byte = 2). DOS with 16-bit FAT's has an ID byte = 4 which BOOTCODE doesn't recognize. The fix is trivial: simply change the line following the label 'lddos' from mov al,1 ;id for dos to mov al,4 ;id for dos with 16-bit FAT's Of course, once you do that BOOTCODE won't handle 12-bit FAT DOS any longer. Dan ORIGINAL CODE IS AS FOLLOWS: 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,1 ;id for dos mov si,offset dosnm+adjust ;dos name jmp short gotact1 ;continue ; xenix: mov al,2 ;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 ' xenixnm 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