;//--------------------------------------------------------------- ;// trackldr.s ;// ;// The function of this 'bootsector' program is to transfer ;// a number of consecutive sectors from the outermost track ;// of a floppy diskette to a designated segment of physical ;// memory, then transfer control to a specified location in ;// that memory-segment. This will allow us to build larger ;// programs than could fit within a diskette's boot-sector. ;// ;// assemble with: $ as86 trackldr.s -b trackldr.b ;// install using: $ dd if=trackldr.b of=/dev/fd0 ;// ;// NOTE: This code begins executing with CS:IP = 0000:7C00. ;// ;// programmer: ALLAN CRUSE ;// written on: 10 FEB 2004 ;//--------------------------------------------------------------- .SECT .TEXT ;----------------------------------------------------------------- start: cli ; enter critical section mov ax, cs ; address zero segment mov ss, ax ; with SS register mov sp, #0x7C00 ; stacktop at BOOT_LOCN sti ; leave critical section jmpf #main, #0x07C0 ; re-normalize CS and IP ;----------------------------------------------------------------- ldaddr: .WORD 0x0000, 0x1000 ; where to load the data ;----------------------------------------------------------------- main: ; load diskette sectors #1-17 into memory at 1000:0000 mov ax, cs ; address this segment mov ds, ax ; with DS register les bx, ldaddr ; point ES:BX to dest'n mov bp, #5 ; maximum no. retries retry: xor ah, ah ; reset_controller int 0x13 ; request BIOS service ESEG mov [bx], #0x0000 ; clear starting word mov cx, #0x0002 ; cyln = 0, recd = 2 mov dx, #0x0000 ; head = 0, dev = fd0 mov ax, #0x0211 ; read_disk (17 sectors) int 0x13 ; request BIOS service jnc rdok ; success? can proceed dec bp ; else adjust counter jne retry ; and try reading again jmp rderr ; exhausted? show ermsg rdok: ; check for our special programming signature ESEG cmp [bx], #0xABCD ; a valid program there? jne inval ; no, report the problem ; transfer control to the newly loaded code callf #0x0002, #0x1000 ; transfer to entry-point mov ax, cs ; address this segment mov ds, ax ; with DS register lea bp, msg0 ; string's offset in BP mov cx, len0 ; string's length in CX showmsg: push cx ; preserve length count mov ah, #0x0F ; display-page into BH int 0x10 ; request BIOS service mov ah, #0x03 ; cursor-locn in DH,DL int 0x10 ; request BIOS service pop cx ; recover length count mov ax, ds ; address this segment mov es, ax ; with ES register mov bl, #0x0F ; message-colors in BL mov ax, #0x1301 ; write_string function int 0x10 ; request BIOS service ; await user keypress xor ah, ah ; get_keyboard_input int 0x16 ; invoke BIOS service int 0x19 ; then reboot machine ;----------------------------------------------------------------- rderr: lea bp, msg1 ; string's offset in BP mov cx, len1 ; string's length in CX jmp showmsg ; write string to screem ;----------------------------------------------------------------- inval: lea bp, msg2 ; string's offset in BP mov cx, len2 ; string's length in CX jmp showmsg ; write string to screen ;----------------------------------------------------------------- msg0: .ASCII "Hit any key to reboot system\n\r" len0: .WORD * - msg0 msg1: .ASCII "Unable to read from diskette\n\r" len1: .WORD * - msg1 msg2: .ASCII "Diskette program was invalid\n\r" len2: .WORD * - msg2 ;----------------------------------------------------------------- .ORG 510 ; boot-signature's offset .BYTE 0x55, 0xAA ; value of boot-signature ;----------------------------------------------------------------- END