;; extended-IPL: ;; multi OS boot utility for IBM PC/AT and compatibles ;; Auther: takamiti@tsden.org ;; NULL equ 00h BELL equ 07h CR equ 0Dh LF equ 0Ah ENTER_SCAN equ 01Ch EXEC_KEY equ 4F00h ; END key VIDEOBIOS equ 10h DISKBIOS equ 13h KEYBIOS equ 16h BIOS_LOC equ 7C00h BOOT_LOC equ 0600h IPLMAGICVAL equ 0AA55h PART_TAB equ BOOT_LOC + 01BEh magicval equ BOOT_LOC + 01FEh kbd_stat equ 0417h fd_stat equ 043Fh nr_hdds equ 0475h DGROUP group _DATA, _BSS assume cs:_TEXT, ds:DGROUP _DATA segment word public 'DATA' _DATA ends _BSS segment word public 'BSS' _BSS ends _TEXT segment byte public 'CODE' assume cs:_TEXT ;======================================================= ; extendedIPL ;======================================================= public _extendedIPL _extendedIPL proc near base: cli xor ax,ax mov ss,ax mov es,ax mov ds,ax mov sp,BIOS_LOC mov si,sp sti cld mov di,BOOT_LOC mov cx,256 repnz movsw mov ax,offset start - base + BOOT_LOC push ax ret start: chk_pause: test byte ptr DGROUP:[kbd_stat],03h jnz chk_table test byte ptr DGROUP:[fd_stat],0Fh jnz chk_pause mov cx,4 mov di,PART_TAB mov dh,30h auto1: inc dh test byte ptr [di],80h jnz boot_1 add di,16 loop auto1 chk_table: call initCRT mov cx,4 mov di,PART_TAB mov dx,3130h mov si,offset guid_msg - base + BOOT_LOC call putstr chtabloop: inc dx test byte ptr [di],80h jz prntab mov dh,dl and byte ptr [di],7Fh prntab: mov ah,2 mov al,dl call putSPC mov bl,[di+4] or bl,bl jz nosys mov ax,0673h call putSPC xchg ax,bx call hex2 nosys: call putCRLF add di,16 loop chtabloop call putCRLF retry: mov si,offset sel_msg - base + BOOT_LOC call putstr keyin: mov al,dh call putch keyin1: xor ah,ah int KEYBIOS cmp al,30h jc sel_ok cmp al,34h ja keyin1 mov dh,al ; save jmp short retry sel_ok: cmp ax,EXEC_KEY jz boot_1 cmp ah,ENTER_SCAN ; scan code jnz keyin1 boot_1: mov di,dx sub dh,30h jz switch_HD xchg ax,bp dec dh mov al,16 mul dh add ax,PART_TAB xchg ax,si ; partition table address in si cmp byte ptr [si+4],0 jz wrong_sys mov dx,[si] mov dl,DGROUP:[drive - base + BOOT_LOC] add dl,050h mov cx,[si+2] push bp push di call HDread pop di pop ax cmp al,LF ; + jz exec_loader cmp word ptr [bx + 1feh],IPLMAGICVAL jz exec_loader wrong_sys: push ax mov al,BELL call putch mov dx,di pop ax cmp ax,offset start - base + BOOT_LOC jnz retry jmp chk_table exec_loader: mov [si],dl or al,al jnz skip cmp dl,080h jnz skip xor dh,dh mov cx,1 mov bp,0301h mov bx,BOOT_LOC call HDio skip: call initCRT db 0EAh dw BIOS_LOC dw 0 ; jmp far BIOS_LOC ; read IPL sector from next HD switch_HD: mov al,byte ptr DGROUP:[drive - base + BOOT_LOC] sub al,30h inc ax cmp al,byte ptr DGROUP:[nr_hdds] jc swhd1 xor ax,ax swhd1: push ax add al,30h mov DGROUP:[drive - base + BOOT_LOC],al pop dx or dl,80h xor dh,dh mov cx,1 call HDread mov si,BIOS_LOC + 1BEh mov di,PART_TAB mov cx,33 repnz movsw jmp chk_table HDread: mov bx,BIOS_LOC ; load address 0x7C00L mov bp,0201h ; read a sector in BIOS_LOC HDio: mov di,8 HDretry: mov ax,bp int DISKBIOS jnc exit_ dec di jns HDretry ; Disk BIOS error push ax mov ax,033fh call putSPC pop ax mov al,ah call hex2 hlt jmp $ putspace: mov al,20h putch: push bx mov ah,14 mov bx,1 int VIDEOBIOS pop bx exit_: ret putCRLF: mov si,offset crlf_msg - base + BOOT_LOC putstr: lodsb or al,al jz exit_ call putch jmp short putstr hex2: push ax push cx mov cl,4 shr al,cl pop cx call hex1 pop ax hex1: and al,0Fh add al,30h cmp al,3Ah jc pr_hex add al,7 pr_hex: jmp short putch putSPC: push ax push cx mov cl,ah p_spc_loop: call putspace loop p_spc_loop pop cx pop ax jmp short putch initCRT: mov ax,2 int VIDEOBIOS ret guid_msg: db "Part. System" crlf_msg: db CR, LF, NULL sel_msg: db CR db "Boot #" drive: db 30h db ":" db NULL db 20 dup(0ffh) _extendedIPL endp ;======================================================= ; FDtestIPL ;======================================================= public _FDtestIPL _FDtestIPL proc near Fbase: cli xor ax,ax mov ss,ax mov es,ax mov ds,ax mov sp,BIOS_LOC mov si,sp sti cld mov di,BOOT_LOC mov cx,256 repnz movsw mov ax,offset Fstart - Fbase + BOOT_LOC push ax ret Fstart: push ax mov dx,80h call Fgettable mov al,90h mov DGROUP:[fdhook - Fbase + BOOT_LOC],al ; ^^; pop ax Fchkpause: test byte ptr DGROUP:[kbd_stat],03h jnz Fchktable test byte ptr DGROUP:[fd_stat],0Fh jnz Fchkpause mov cx,4 mov di,PART_TAB mov dh,30h Fauto1: inc dh test byte ptr [di],80h jnz Fboot1 add di,16 loop Fauto1 Fchktable: call FinitCRT mov cx,4 mov di,PART_TAB mov dx,3130h mov si,offset Fguidmsg - Fbase + BOOT_LOC call Fputstr Fchtabloop: inc dx test byte ptr [di],80h jz Fprntab mov dh,dl and byte ptr [di],7Fh Fprntab: mov ah,2 mov al,dl call FputSPC mov bl,[di+4] or bl,bl jz Fnosys mov ax,0673h call FputSPC xchg ax,bx call Fhex2 Fnosys: call FputCRLF add di,16 loop Fchtabloop call FputCRLF Fretry: mov si,offset Fselmsg - Fbase + BOOT_LOC call Fputstr Fkeyin: mov al,dh call Fputch Fkeyin1: xor ah,ah int KEYBIOS cmp al,30h jc Fselok cmp al,34h ja Fkeyin1 mov dh,al ; save jmp short Fretry Fselok: cmp ax,EXEC_KEY jz Fboot1 cmp ah,ENTER_SCAN ; scan code jnz Fkeyin1 Fboot1: mov di,dx sub dh,30h jz FswitchHD xchg ax,bp dec dh mov al,16 mul dh add ax,PART_TAB xchg ax,si ; partition table address cmp byte ptr [si+4],0 jz Fwrongsys mov dx,[si] mov dl,byte ptr DGROUP:[Fdrive - Fbase + BOOT_LOC] add dl,50h mov cx,[si+2] push bp push di call FHDread pop di pop ax cmp al,LF ; + jz Fexecloader cmp word ptr [bx + 1feh],IPLMAGICVAL jz Fexecloader Fwrongsys: push ax mov al,BELL call Fputch mov dx,di pop ax cmp ax,offset Fstart - Fbase + BOOT_LOC jnz Fretry jmp Fchktable Fexecloader: mov byte ptr [si],dl call FinitCRT db 0EAh dw BIOS_LOC dw 0 ; jmp far BIOS_LOC ; read IPL sector from next HD FswitchHD: mov al,byte ptr DGROUP:[Fdrive - Fbase + BOOT_LOC] sub al,30h inc ax cmp al,byte ptr DGROUP:[nr_hdds] jc Fswhd1 xor ax,ax Fswhd1: push ax add al,30h mov DGROUP:[Fdrive - Fbase + BOOT_LOC],al pop dx or dl,80h xor dh,dh Fgettable: mov cx,1 call FHDread mov si,BIOS_LOC + 01BEh mov di,PART_TAB mov cx,33 repnz movsw fdhook: ret jmp Fchktable FHDread: mov bx,BIOS_LOC ; load address[0000:7C00] mov di,8 FHDretry: mov ax,0201h ; read a sector in BIOS_LOC int DISKBIOS jnc Fexit dec di jns FHDretry Ferror: push ax ; error starus mov ax,033fh call FputSPC pop ax mov al,ah call Fhex2 hlt jmp $ Fputspace: mov al,20h Fputch: push bx mov ah,14 mov bx,1 int VIDEOBIOS pop bx Fexit: ret FputSPC: push ax push cx mov cl,ah Fspcloop: call Fputspace loop Fspcloop pop cx pop ax jmp short Fputch FputCRLF: mov si,offset Fcrlfmsg - Fbase + BOOT_LOC Fputstr: lodsb or al,al jz Fexit call Fputch jmp short Fputstr Fhex2: push ax push cx mov cl,4 shr al,cl pop cx call Fhex1 pop ax Fhex1: and al,0Fh add al,30h cmp al,3Ah jc Fprhex add al,7 Fprhex: jmp short Fputch FinitCRT: mov ax,2 int VIDEOBIOS ret Fguidmsg: db "Part. System" Fcrlfmsg: db CR, LF, NULL Fselmsg: db CR db "Boot #" Fdrive: db 30h db ":" db NULL is1st: db 0 db 30 dup(0ffh) _FDtestIPL endp public _dmaoverrun _dmaoverrun proc near push bp mov bp,sp mov ax,ds mov cl,4 shl ax,cl add ax,[bp+4] mov bx,[bp+6] dec bx add ax,bx mov ax,0 jnc dma_ok inc ax dma_ok: pop bp ret _dmaoverrun endp ;; public _codecpy _codecpy proc near push bp mov bp,sp push ds push di push si mov di,[bp+4] mov ax,cs mov ds,ax mov si,[bp+6] mov cx,[bp+8] rep movsb pop si pop di pop ds pop bp ret _codecpy endp _TEXT ends end