How do I createa bootable floppy disk?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: How do I createa bootable floppy disk?

Post by Antti »

So far, there has been a kind of threshold, i.e. I did not want to use "just a little bit" extra space if I could fit it into first sector and have the "standard disk layout". Decisions are not always based on pure logic.
Octocontrabass wrote:It's much easier to debug and improve your second stage when you just have to replace a file on the disk instead of directly accessing sectors.
Yes, modifying files in a file system has turned out to be quite handy, especially with real floppies that are very slow. I was thinking that reserved sectors would be just an "extended boot sector" that would read the second stage from the file system without any restrictions, like "must be the first entry in the root directory" or "first three sectors must be contiguous". I managed to get rid of these restrictions and still using a single sector but error messages are quite terse if something unexpected happens, e.g. FAT data structures are corrupted. In any case, it handles everything safely, i.e. no divide-by-zeros or jumping into code without verifying the checksum. Read errors are not unexpected so there is a proper message for them. I admit that the lack of proper error messages is a huge drawback. If this turns out to be a bad decision, I will just rewrite this early boot code and use extra reserved sectors.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: How do I createa bootable floppy disk?

Post by Brendan »

Hi,

For fun; here's an analysis of my floppy boot loader's first sector. Note that my floppy boot loader is many sectors (currently about 20 KiB).

First, a hexdump:

Code: Select all

00000000  eb 22 00 00 00 00 00 00  00 00 00 00 02 01 40 0b  |."............@.|
00000010  00 00 00 40 0b 00 00 00  12 00 02 00 40 0b 00 00  |...@........@...|
00000020  40 0b 00 00 31 c0 8e c0  8e d8 fa 8e d0 bc 00 20  |@...1.......... |
00000030  fb fc be 00 7c 89 e7 b9  00 01 f3 a5 ea 41 20 00  |....|........A .|
00000040  00 88 16 12 20 b4 1a f9  cd 10 3c 1a 75 34 c6 06  |.... .....<.u4..|
00000050  10 20 01 b8 00 1b 31 db  bf 00 22 cd 10 3c 1b 75  |. ....1..."..<.u|
00000060  12 81 7d 04 03 50 75 0b  8a 45 22 3c 19 74 09 3c  |..}..Pu..E"<.t.<|
00000070  18 74 05 b8 03 00 cd 10  30 ff b4 0f cd 10 88 3e  |.t......0......>|
00000080  11 20 be c2 21 e8 c8 00  b9 02 00 30 f6 bb 00 22  |. ..!......0..."|
00000090  e8 fd 00 73 0d 38 36 0a  20 74 4b fe c6 e8 f0 00  |...s.86. tK.....|
000000a0  72 44 b8 00 bb cd 1a 85  c0 74 03 e9 ba 02 81 fb  |rD.......t......|
000000b0  54 43 74 03 e9 b1 02 81  f9 02 01 73 03 e9 a8 02  |TCt........s....|
000000c0  66 31 c3 66 81 fb 54 43  50 41 0f 85 9a 02 bf 68  |f1.f..TCPA.....h|
000000d0  23 66 31 c9 66 31 d2 66  31 f6 b5 02 b2 09 b8 07  |#f1.f1.f1.......|
000000e0  bb cd 1a e9 88 02 be f0  21 eb 7d 3c 01 74 55 3c  |........!.}<.tU<|
000000f0  03 74 57 50 53 51 52 56  57 55 8a 3e 11 20 3c 0a  |.tWPSQRVWU.>. <.|
00000100  74 2c 3c 20 74 2e 3c 09  74 2a b4 09 b9 01 00 8a  |t,< t.<.t*......|
00000110  1e fd 21 cd 10 b4 03 8a  3e 11 20 cd 10 fe c2 80  |..!.....>. .....|
00000120  fa 50 74 0a b4 02 8a 3e  11 20 cd 10 eb 0e b4 0e  |.Pt....>. ......|
00000130  cd 10 b0 0d b4 0e 8a 3e  11 20 cd 10 5d 5f 5e 5a  |.......>. ..]_^Z|
00000140  59 5b 58 c3 c6 06 fd 21  0f c3 c6 06 fd 21 07 c3  |Y[X....!.....!..|
00000150  80 3e 10 20 00 75 01 c3  50 56 fc eb 03 e8 8b ff  |.>. .u..PV......|
00000160  ac 84 c0 75 f8 5e 58 c3  e8 e5 ff be df 21 e8 df  |...u.^X......!..|
00000170  ff b0 b6 fa e6 43 eb 00  eb 00 b0 d1 e6 42 eb 00  |.....C.......B..|
00000180  eb 00 b0 11 e6 42 fb e4  61 0c 03 e6 61 f4 eb fd  |.....B..a...a...|
00000190  31 c0 a2 13 20 8e c0 8a  16 12 20 53 51 52 b8 01  |1... ..... SQR..|
000001a0  02 fe 06 13 20 cd 13 73  15 80 3e 13 20 03 73 0d  |.... ..s..>. .s.|
000001b0  30 e4 8a 16 12 20 cd 13  5a 59 5b eb de f9 5a 59  |0.... ..ZY[...ZY|
000001c0  5b c3 0a 01 42 43 4f 53  20 46 6c 6f 70 70 79 20  |[...BCOS Floppy |
000001d0  42 6f 6f 74 20 4c 6f 61  64 65 72 03 0a 0a 00 0a  |Boot Loader.....|
000001e0  0a 01 42 6f 6f 74 20 61  62 6f 72 74 65 64 2e 00  |..Boot aborted..|
000001f0  0a 44 69 73 6b 20 65 72  72 6f 72 2e 00 07 55 aa  |.Disk error...U.|

Code: Select all

00000000  eb 22
This is just a "JMP" because the BPB is in the way.

Code: Select all

00000000        00 00 00 00 00 00  00 00 00
These are "special" variables (e.g. "starting LBA of Boot Image") that are set by my utility that creates floppy images.

Code: Select all

00000000                                    00 02 01 40 0b
00000010  00 00 00 40 0b 00 00 00  12 00 02 00 40 0b 00 00
00000020  40 0b 00 00
This is the BPB. I use some fields (e.g. "sectors per track") which are also set by my utility that creates floppy images.

Code: Select all

00000020              31 c0 8e c0  8e d8 fa 8e d0 bc 00 20
00000030  fb fc
Code to setup initial segment registers and stack.

Code: Select all

00000030        be 00 7c 89 e7 b9  00 01 f3 a5 ea 41 20 00
00000040  00 
Code to copy the boot sector from 0x7C00 to 0x2000 and jump to the copy.

Code: Select all

00000040     88 16 12 20 b4 1a f9  cd 10 3c 1a 75 34 c6 06
00000050  10 20 01 b8 00 1b 31 db  bf 00 22 cd 10 3c 1b 75
00000060  12 81 7d 04 03 50 75 0b  8a 45 22 3c 19 74 09 3c
00000070  18 74 05 b8 03 00 cd 10  30 ff b4 0f cd 10 88 3e
00000080  11 20
Code to check if a video card exists, check if the video mode is 80*25 text mode, and set 80*25 text mode if necessary. This is mostly to ensure that any error messages that are display are actually visible.

Code: Select all

00000080        be c2 21 e8 c8 00
Code to print the "BCOS Floppy Boot Loader" string (so that if something goes wrong the user at least knows the boot sector started).

Code: Select all

00000080                           b9 02 00 30 f6 bb 00 22
00000090  e8 fd 00 73 0d 38 36 0a  20 74 4b fe c6 e8 f0 00
000000a0  72
Code to load the next sector of the boot loader (which mostly just calls a lower level "load sectors with retries" wrapper). Note that I support "redundant floppies". Essentially, if my "floppy image creator" utility decided there's enough space for redundancy it stores 2 copies of everything on the disk. If this code can't read the next sector, and if the "redundant floppy" flag is set, it tries to get the same data from the alternative copy.

Code: Select all

000000a0        b8 00 bb cd 1a 85  c0 74 03 e9 ba 02 81 fb
000000b0  54 43 74 03 e9 b1 02 81  f9 02 01 73 03 e9 a8 02
000000c0  66 31 c3 66 81 fb 54 43  50 41 0f 85 9a 02 bf 68
000000d0  23 66 31 c9 66 31 d2 66  31 f6 b5 02 b2 09 b8 07
000000e0  bb cd 1a
This code checks if "Trusted Computing Group" functions are present and (if they are) uses it to get TPM chip to extend a platform key with a hash of the sector that was loaded. I do this mostly for "remote attestation" - so that other computers will be able to tell if the computer being booted has been tampered with (which is a little more important for me because the OS is intended for a distributed cluster).

Code: Select all

000000e0           e9 88 02
A jump to the code in the second sector.

Code: Select all

000000e0                    be f0  21 eb 7d
Code to print "disk error" and abort boot if the second sector couldn't be loaded.

Code: Select all

000000e0                                    3c 01 74 55 3c
000000f0  03 74 57 50 53 51 52 56  57 55 8a 3e 11 20 3c 0a
00000100  74 2c 3c 20 74 2e 3c 09  74 2a b4 09 b9 01 00 8a
00000110  1e fd 21 cd 10 b4 03 8a  3e 11 20 cd 10 fe c2 80
00000120  fa 50 74 0a b4 02 8a 3e  11 20 cd 10 eb 0e b4 0e
00000130  cd 10 b0 0d b4 0e 8a 3e  11 20 cd 10 5d 5f 5e 5a
00000140  59 5b 58 c3 c6 06 fd 21  0f c3 c6 06 fd 21 07 c3
00000150  80 3e 10 20 00 75 01 c3  50 56 fc eb 03 e8 8b ff
00000160  ac 84 c0 75 f8 5e 58 c3
This is my "print character" routine and "print ASCIIZ string" routine. It's mostly a wrapper around the BIOS "print character" function; except it handles a few special characters (to switch between "highlight" and "normal" mode) and expands "\n" into "\r\n". It also doesn't bother printing anything if earlier code didn't detect that a video card is present. It's a little excessive for the boot sector alone, but this is used by later code too.

Code: Select all

00000160                           e8 e5 ff be df 21 e8 df
00000170  ff b0 b6 fa e6 43 eb 00  eb 00 b0 d1 e6 42 eb 00
00000180  eb 00 b0 11 e6 42 fb e4  61 0c 03 e6 61 f4 eb fd
This is code to abort boot. For computers that don't have a video card (e.g. server rooms) my OS uses a "continuous beep" for failures that occur during early boot, and "repeated short beeps" for things that go wrong later in boot. This code mostly displays a "boot aborted" error message and then configures the PC speaker for that "continuous beep" before doing HLT in a loop waiting for user to reset the computer.

Code: Select all

00000190  31 c0 a2 13 20 8e c0 8a  16 12 20 53 51 52 b8 01
000001a0  02 fe 06 13 20 cd 13 73  15 80 3e 13 20 03 73 0d
000001b0  30 e4 8a 16 12 20 cd 13  5a 59 5b eb de f9 5a 59
000001c0  5b c3
This is the low level "read sectors" wrapper. It's a fairly standard "retry several times and reset disk system after each failure" thing.

Code: Select all

000001c0        0a 01 42 43 4f 53  20 46 6c 6f 70 70 79 20  |[...BCOS Floppy |
000001d0  42 6f 6f 74 20 4c 6f 61  64 65 72 03 0a 0a 00 0a  |Boot Loader.....|
000001e0  0a 01 42 6f 6f 74 20 61  62 6f 72 74 65 64 2e 00  |..Boot aborted..|
000001f0  0a 44 69 73 6b 20 65 72  72 6f 72 2e 00 07 55 aa  |.Disk error...U.|
This is all just data. Note that there's only one pathetic "Disk error" string for read errors (I simply don't have room for anything good unless I sacrifice something else to make room).

The boot loader's second sector contains a better "load sectors" wrapper that handles LBA and redundant floppies properly; and also does much better error messages (literally, a different error string for each possible error the BIOS could return). It relies on routines in the first sector for printing things and aborting boot. It loads the third sector, does the "diddle with TPM for remote attestation" stuff, and jumps to code in the third sector.

The third sector loads the rest of the boot loader and diddles with TPM again (using routines in the first and second sectors for disk, printing and aborting boot). Once that's done the boot loader can start doing useful things.

Basically it's a painful "pull yourself up by your bootstraps" sequence that takes almost 3 carefully planned sectors just to get the boot loader into memory.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: How do I createa bootable floppy disk?

Post by Antti »

I probably will regret this later because I do know that most of the people here do not like this. But here is my floppy boot sector disassembled. The features are listed below:
  • Sector sizes. 512, 1024, 2048, 4096, 8192, 16384 and 32768 are supported. Although it is mostly theoretical to find other sizes than 512 or 1024. Boot code checks that Bios Parameter Block contains one of the valid values.
  • Bios Parameter Block. FAT12 or FAT16. Most of the values are indirectly tested that definitely non-valid values are not used (mostly zeros). Divide-by-zeros are impossible.
  • Safe entry. Only 16-bit code passes through, 32-bit or 64-bit code hangs (defined behavior).
  • Location. Boot code makes sure it is executed at 0x00007C00. The exact cs and ip values do not matter.
  • Diskette Parameter Table. Boot code copies the table and modifies values "sector size" and "last sector on a track" according to values in Boot Parameter Block.
  • Disk access. INT 0x13, AH=0x02 is used. If it fais, there is a special pattern of "retry retry reset retry retry". A disk reset is not immediately done after a fail.
  • Error message. The correct video page is used when teletyping the error message. There is a beep character.
  • Second Stage Loader. The file is LOADER.512 in the FAT12/FAT16 root directory and its size is exactly 512 bytes (checked). Boot code does not read file allocation tables. The file can be anywhere in the root directory and the directory is read a sector at a time until the file is found. The second stage loader must have a correct checksum (checked).
  • Read Sector Routine. Boot code gives a read sector routine address to the second stage loader.
  • Other features. Something that I forgot to list.
Bios routines are assumed to trash all the general purpose registers. I finished this in February but it took one month to write this. Last but not least, look at the over-aligned code structure! It has never failed so far and I have booted this quite many times when testing second stage loaders.

Code: Select all

Copyright (C) 2015 Antti Tiihala
All rights reserved.

ONLY FOR VIEWING PURPOSES!

7C00  EB 3C 90 00 00 00 00 00-00 00 00 00 00 00 00 00   .<..............
7C10  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
7C20  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
7C30  00 00 00 00 00 00 00 00-00 00 00 00 00 00 33 F6   ..............3.
7C40  8E C6 8E DE B9 0F 00 8C-C8 BD 00 7C EB 0A EB F0   ...........|....
7C50  8B 7E FE 85 F9 B1 04 C3-FA 8E D6 8B E5 E8 F0 FF   .~..............
7C60  75 DE D3 EF 03 C7 3D C6-07 75 D5 EA 70 7C 00 00   u.....=..u..p|..
7C70  FB 88 56 24 FC F6 C2 80-75 23 55 C7 46 FE A0 7D   ..V$....u#U.F..}
7C80  BB 78 00 BF E4 0F C5 37-8B EF 89 76 FC 8C 5E FE   .x.....7...v..^.
7C90  2E A1 1C 7C 2E 8B 0E 1E-7C 0B C1 74 03 E9 E0 00   ...|....|..t....
7CA0  B1 0B F3 A4 B1 11 F3 AA-8E D8 B4 02 8B 3E 0B 7C   .............>.|
7CB0  FE C1 3B C7 74 06 D1 E0-74 06 EB F4 02 2E 18 7C   ..;.t...t......|
7CC0  74 78 38 06 1A 7C 74 72-41 39 4E 03 89 4E 03 FA   tx8..|trA9N..N..
7CD0  74 0A 89 6F 00 8C 5F 02-B4 00 CD 13 FB BD 00 7C   t..o.._........|
7CE0  B1 05 A1 11 7C D3 E0 33-D2 F7 76 0B 85 C0 74 4A   ....|..3..v...tJ
7CF0  85 D2 75 46 50 8A 46 10-B4 00 F7 66 16 03 46 0E   ..uFP.F....f..F.
7D00  50 01 46 FC 50 33 D2 BD-48 02 E8 93 00 BD 48 02   P.F.P3..H.....H.
7D10  A1 0B 7C BF 00 80 03 C7-B9 0B 00 BE F0 7D 38 05   ..|..........}8.
7D20  74 5E 57 F3 A6 5F 74 14-83 C7 20 3B F8 72 E9 58   t^W.._t... ;.r.X
7D30  05 01 00 50 3B 06 FC 7B-72 CB EB 44 F6 45 0B 18   ...P;..{r..D.E..
7D40  75 3E 8B 45 1A 2D 02 00-72 36 02 0E 0D 7C 74 30   u>.E.-..r6...|t0
7D50  F7 E1 03 06 FC 7B 81 7D-1C 00 02 75 23 0B 55 1E   .....{.}...u#.U.
7D60  75 1E E8 3B 00 BC FE 7B-33 ED B9 00 01 BE 00 80   u..;...{3.......
7D70  AD 03 E8 49 75 FA 5B 3B-EC 75 05 EA 00 80 00 00   ...Iu.[;.u......
7D80  B4 0F CD 10 B3 07 33 F6-2E 8A 84 DE 7D 83 C6 01   ......3.....}...
7D90  53 56 B4 0E CD 10 5E 5B-83 FE 12 72 EB F4 EB FD   SV....^[...r....
7DA0  50 52 F7 36 18 7C 8B DA-B1 08 33 D2 F7 36 1A 7C   PR.6.|....3..6.|
7DB0  D3 E0 D3 E2 8D 4F 01 8A-EC BB 00 80 8A 16 24 7C   .....O........$|
7DC0  D1 ED 55 74 BB 72 0D F9-B8 01 02 CD 13 FB 72 09   ..Ut.r........r.
7DD0  5D 5A 58 C3 B4 00 CD 13-FB 5D 5A 58 EB C2 0D 0A   ]ZX......]ZX....
7DE0  21 20 44 49 53 4B 20 45-52 52 4F 52 07 07 07 0D   ! DISK ERROR....
7DF0  4C 4F 41 44 45 52 20 20-35 31 32 00 00 00 55 AA   LOADER  512...U.


7C00 EB3C          JMP     7C3E
7C02 90            NOP

7C3E 33F6          XOR     SI,SI
7C40 8EC6          MOV     ES,SI
7C42 8EDE          MOV     DS,SI
7C44 B90F00        MOV     CX,000F
7C47 8CC8          MOV     AX,CS
7C49 BD007C        MOV     BP,7C00
7C4C EB0A          JMP     7C58
7C4E EBF0          JMP     7C40

7C50 8B7EFE        MOV     DI,[BP-02]
7C53 85F9          TEST    CX,DI
7C55 B104          MOV     CL,04
7C57 C3            RET
7C58 FA            CLI
7C59 8ED6          MOV     SS,SI
7C5B 8BE5          MOV     SP,BP
7C5D E8F0FF        CALL    7C50

7C60 75DE          JNZ     7C40
7C62 D3EF          SHR     DI,CL
7C64 03C7          ADD     AX,DI
7C66 3DC607        CMP     AX,07C6
7C69 75D5          JNE     7C40
7C6B EA707C0000    JMP     0000:7C70

7C70 FB            STI
7C71 885624        MOV     [BP+24],DL
7C74 FC            CLD
7C75 F6C280        TEST    DL,80
7C78 7523          JNZ     7C9D
7C7A 55            PUSH    BP
7C7B C746FEA07D    MOV     WORD PTR [BP-02],7DA0

7C80 BB7800        MOV     BX,0078
7C83 BFE40F        MOV     DI,0FE4
7C86 C537          LDS     SI,[BX]
7C88 8BEF          MOV     BP,DI
7C8A 8976FC        MOV     [BP-04],SI
7C8D 8C5EFE        MOV     [BP-02],DS

7C90 2E            CS:
7C91 A11C7C        MOV     AX,[7C1C]
7C94 2E            CS:
7C95 8B0E1E7C      MOV     CX,[7C1E]
7C99 0BC1          OR      AX,CX
7C9B 7403          JZ      7CA0
7C9D E9E000        JMP     7D80

7CA0 B10B          MOV     CL,0B
7CA2 F3            REPZ
7CA3 A4            MOVSB
7CA4 B111          MOV     CL,11
7CA6 F3            REPZ
7CA7 AA            STOSB
7CA8 8ED8          MOV     DS,AX
7CAA B402          MOV     AH,02
7CAC 8B3E0B7C      MOV     DI,[7C0B]

7CB0 FEC1          INC     CL
7CB2 3BC7          CMP     AX,DI
7CB4 7406          JZ      7CBC
7CB6 D1E0          SHL     AX,1
7CB8 7406          JZ      7CC0
7CBA EBF4          JMP     7CB0
7CBC 022E187C      ADD     CH,[7C18]

7CC0 7478          JZ      7D3A
7CC2 38061A7C      CMP     [7C1A],AL
7CC6 7472          JZ      7D3A
7CC8 41            INC     CX
7CC9 394E03        CMP     [BP+03],CX
7CCC 894E03        MOV     [BP+03],CX
7CCF FA            CLI

7CD0 740A          JZ      7CDC
7CD2 896F00        MOV     [BX+00],BP
7CD5 8C5F02        MOV     [BX+02],DS
7CD8 B400          MOV     AH,00
7CDA CD13          INT     13      (BIOS Disk)
7CDC FB            STI
7CDD BD007C        MOV     BP,7C00

7CE0 B105          MOV     CL,05
7CE2 A1117C        MOV     AX,[7C11]
7CE5 D3E0          SHL     AX,CL
7CE7 33D2          XOR     DX,DX
7CE9 F7760B        DIV     WORD PTR [BP+0B]
7CEC 85C0          TEST    AX,AX
7CEE 744A          JZ      7D3A

7CF0 85D2          TEST    DX,DX
7CF2 7546          JNZ     7D3A
7CF4 50            PUSH    AX
7CF5 8A4610        MOV     AL,[BP+10]
7CF8 B400          MOV     AH,00
7CFA F76616        MUL     WORD PTR [BP+16]
7CFD 03460E        ADD     AX,[BP+0E]

7D00 50            PUSH    AX
7D01 0146FC        ADD     [BP-04],AX
7D04 50            PUSH    AX
7D05 33D2          XOR     DX,DX
7D07 BD4802        MOV     BP,0248
7D0A E89300        CALL    7DA0
7D0D BD4802        MOV     BP,0248

7D10 A10B7C        MOV     AX,[7C0B]
7D13 BF0080        MOV     DI,8000
7D16 03C7          ADD     AX,DI
7D18 B90B00        MOV     CX,000B
7D1B BEF07D        MOV     SI,7DF0
7D1E 3805          CMP     [DI],AL

7D20 745E          JZ      7D80
7D22 57            PUSH    DI
7D23 F3            REPZ
7D24 A6            CMPSB
7D25 5F            POP     DI
7D26 7414          JZ      7D3C
7D28 83C720        ADD     DI,+20
7D2B 3BF8          CMP     DI,AX
7D2D 72E9          JB      7D18
7D2F 58            POP     AX

7D30 050100        ADD     AX,0001
7D33 50            PUSH    AX
7D34 3B06FC7B      CMP     AX,[7BFC]
7D38 72CB          JB      7D05
7D3A EB44          JMP     7D80
7D3C F6450B18      TEST    BYTE PTR [DI+0B],18

7D40 753E          JNZ     7D80
7D42 8B451A        MOV     AX,[DI+1A]
7D45 2D0200        SUB     AX,0002
7D48 7236          JB      7D80
7D4A 020E0D7C      ADD     CL,[7C0D]
7D4E 7430          JZ      7D80

7D50 F7E1          MUL     CX
7D52 0306FC7B      ADD     AX,[7BFC]
7D56 817D1C0002    CMP     WORD PTR [DI+1C],0200
7D5B 7523          JNZ     7D80
7D5D 0B551E        OR      DX,[DI+1E]

7D60 751E          JNZ     7D80
7D62 E83B00        CALL    7DA0
7D65 BCFE7B        MOV     SP,7BFE
7D68 33ED          XOR     BP,BP
7D6A B90001        MOV     CX,0100
7D6D BE0080        MOV     SI,8000

7D70 AD            LODSW
7D71 03E8          ADD     BP,AX
7D73 49            DEC     CX
7D74 75FA          JNZ     7D70
7D76 5B            POP     BX
7D77 3BEC          CMP     BP,SP
7D79 7505          JNZ     7D80
7D7B EA00800000    JMP     0000:8000

7D80 B40F          MOV     AH,0F
7D82 CD10          INT     10      (BIOS Video)
7D84 B307          MOV     BL,07
7D86 33F6          XOR     SI,SI
7D88 2E            CS:
7D89 8A84DE7D      MOV     AL,[SI+7DDE]
7D8D 83C601        ADD     SI,+01

7D90 53            PUSH    BX
7D91 56            PUSH    SI
7D92 B40E          MOV     AH,0E
7D94 CD10          INT     10      (BIOS Video)
7D96 5E            POP     SI
7D97 5B            POP     BX
7D98 83FE12        CMP     SI,+12
7D9B 72EB          JB      7D88
7D9D F4            HLT
7D9E EBFD          JMP     7D9D

7DA0 50            PUSH    AX
7DA1 52            PUSH    DX
7DA2 F736187C      DIV     WORD PTR [7C18]
7DA6 8BDA          MOV     BX,DX
7DA8 B108          MOV     CL,08
7DAA 33D2          XOR     DX,DX
7DAC F7361A7C      DIV     WORD PTR [7C1A]

7DB0 D3E0          SHL     AX,CL
7DB2 D3E2          SHL     DX,CL
7DB4 8D4F01        LEA     CX,[BX+01]
7DB7 8AEC          MOV     CH,AH
7DB9 BB0080        MOV     BX,8000
7DBC 8A16247C      MOV     DL,[7C24]

7DC0 D1ED          SHR     BP,1
7DC2 55            PUSH    BP
7DC3 74BB          JZ      7D80
7DC5 720D          JC      7DD4
7DC7 F9            STC
7DC8 B80102        MOV     AX,0201
7DCB CD13          INT     13      (BIOS Disk)
7DCD FB            STI
7DCE 7209          JC      7DD9

7DD0 5D            POP     BP
7DD1 5A            POP     DX
7DD2 58            POP     AX
7DD3 C3            RET
7DD4 B400          MOV     AH,00
7DD6 CD13          INT     13      (BIOS Disk)
7DD8 FB            STI
7DD9 5D            POP     BP
7DDA 5A            POP     DX
7DDB 58            POP     AX
7DDC EBC2          JMP     7DA0
Post Reply