flat assembler
Message board for the users of flat assembler.

Index > OS Construction > help optimizing bootsector

Author
Thread Post new topic Reply to topic
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Hello all optimizing gurus! Smile
Could you take a look on this bootsector and help me to optimize it?
I need to fit in a couple of more things..

This is what i want to do:
The progress var should actually be only 2 dots, and then i want to print it seven times between every chunk of data i read.
I want to try each read 3 times, and if that failes, it should call error...

here's the code:
Code:
;----------------------------------------------------;
;                   BOS bootsector                   ;
;----------------------------------------------------;
; FAT12 compatible. Sets pmode & A20. Kernel must be ;
;   the first thing on disk after the bootsector.    ;
;                                                    ;
; TODO:   optimize enought for error checking when   ;
;       loading sectors and print 2 progress dots    ;
;      for each "bunch" of sectors loaded correctly. ;
;                                                    ;
;          by: Christoffer Bubach, 2004              ;
;----------------------------------------------------;
use16
org 0x7C00

boot:     jmp     near fix
          nop

;-----------------------------------------;
;  Standard BIOS Parameter Block, "BPB."  ;
;-----------------------------------------;
          bpbOEM          db  'BOS 0.03'
          bpbSectSize     dw  512
          bpbClustSize    db  1
          bpbReservedSec  dw  1
          bpbFats         db  2
          bpbRootSize     dw  224
          bpbTotalSect    dw  2880
          bpbMedia        db  240
          bpbFatSize      dw  9
          bpbTrackSect    dw  18
          bpbHeads        dw  2
          bpbHiddenSect   dd  0
          bpbLargeSect    dd  0
;-----------------------------------------------;
; extended BIOS Parameter Block for FAT12/FAT16 ;
;-----------------------------------------------;
          bpbDriveNo      db  0
          bpbReserved     db  0
          bpbSignature    db  41
          bpbID           dd  1
          bpbVolumeLabel  db  'BOOT FLOPPY'
          bpbFileSystem   db  'FAT12   '

;-----------------;
;   code area     ;
;-----------------;
fix:
          jmp     0x0000:start
start:

          cli

          mov     ax, cs
          mov     ds, ax
          mov     es, ax
          mov     gs, ax
          mov     fs, ax

          mov     ax, 0x9000
          mov     ss, ax
          mov     sp, 0x8000

          mov     [bpbDriveNo], dl

          sti

     ;------------------------;
     ; set textmode/font size ;
     ;------------------------;
          mov     ax, [text_mode_no]
          mov     bl, 0
          int     0x10

     ;--------------------;
     ; print loading mess ;
     ;--------------------;
          mov     bp, loading
          mov     ax, 0x1301
          mov     bx, 0x0007
          mov     cx, 12
          mov     dx, 0x0102
          int     0x10


;----------------;
; set A20 ver. 1 ;
;----------------;
          call    .out
          call    .cmd_wait
          mov     al, 0xd1
          out     0x64, al
          call    .cmd_wait
          mov     al, 0xdf
          out     0x60, al
          call    .cmd_wait
          jmp     .done
     .cmd_wait:
          in      al, 0x64
          test    al, 0x02
          jnz     .cmd_wait
          ret
     .out:
          in      al, 0x64
          test    al, 0x01
          jnz     .read
          ret
     .read:
          in     al, 0x60
          jmp    .out
     .done:

     ;-------------;
     ; test if set ;
     ;-------------;
          call     a20test
          jz       pre_read

;----------------;
; set A20 ver. 2 ;
;----------------;
          in      al, 0x92
          or      al, 0x02
          out     0x92, al

     ;-------------;
     ; test if set ;
     ;-------------;
          call     a20test
          jz       pre_read
          jmp      error



;-----------------------------;
; print progress dots (faked) ;
;-----------------------------;
pre_read:
          mov     bp, progress
          mov     ax, 0x1301
          mov     bx, 0x0002
          mov     cx, 14
          mov     dx, 0x0201
          int     0x10


;--------------------------------------;
;      read a 50 kb file to mem.       ;
;--------------------------------------;
read:
          push    es
     ;-------------;
     ; reset drive ;
     ;-------------;
          xor     ax, ax
          mov     dl, [bpbDriveNo]
          int     0x13 
          jc      read

     ;---------------------------------------------------;
     ; set es and hope that bios does not mess with it.. ;
     ;---------------------------------------------------;
          mov     ax, 0xffff
          mov     es, ax

     ;-----------------;
     ; read 17 sectors ;
     ;-----------------;
          mov     bx, 0x10
          mov     ah, 2
          mov     al, 17
          mov     ch, 0
          mov     cl, 2
          mov     dh, 0
          int     0x13
          jc      read 

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x2210
          mov     ah, 2
          mov     al, 18
          mov     ch, 0
          mov     cl, 1
          mov     dh, 1
          int     0x13

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x4610
          mov     ah, 2
          mov     al, 18
          mov     ch, 1
          mov     cl, 1
          mov     dh, 0
          int     0x13

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x6A10
          mov     ah, 2
          mov     al, 18
          mov     ch, 1
          mov     cl, 1
          mov     dh, 1
          int     0x13

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x8E10
          mov     ah, 2
          mov     al, 18
          mov     ch, 2
          mov     cl, 1
          mov     dh, 0
          int     0x13

     ;------------------;
     ; read the last 11 ;
     ;------------------;
          mov     bx, 0xB210
          mov     ah, 2
          mov     al, 11
          mov     ch, 2
          mov     cl, 1
          mov     dh, 1
          int     0x13


     ;------------;
     ; stop motor ;
     ;------------;
          mov     dx, 0x3F2
          mov     al, 0x0C
          out     dx, al

          pop     es

          jmp     pmode




;----------------------------;
;  some functions and data   ;
;----------------------------;
     ;----------------;
     ;   variables    ;
     ;----------------;
          loading         db  'Starting BOS'
          progress        db  '..............'

          msg_error       db  'I/O error, press any key to restart..'

          text_mode_no    dw  3

     ;----------;
     ; test A20 ;
     ;----------;
     a20test:
          mov     al, byte [fs:0]
          mov     ah, al
          not     al
          xchg    al, byte [gs:10h]
          cmp     ah, byte [fs:0]
          mov     [gs:10h], al
          ret

     ;------------;
     ; error..    ;
     ;------------;
     error:
          mov     bp, msg_error
          mov     ax, 0x1301
          mov     bx, 0x0004
          mov     cx, 37
          mov     dx, 0x0401
          int     0x10

          mov     ah, 0
          int     0x16
          int     0x19
;--------------------------------;
; end of functions and data area ;
;--------------------------------;



;----------------------------;
;    set pmode               ;
;----------------------------;
pmode:
          cli

          lgdt    [gdtr]

          mov     eax, cr0
          or      eax, 1
          mov     cr0, eax

          jmp     0x08:flush



;---------------------------------------------------------;
; start of 32-bit area. flush segments and jump to kernel ;
;---------------------------------------------------------;
use32
flush:
;-------------------------------;
; refresh all segment registers ;
;-------------------------------;
          mov     eax, 0x10
          mov     ds, eax
          mov     es, eax
          mov     fs, eax
          mov     gs, eax
          mov     ss, eax
          mov     esp, 0xfffc

;---------------------;
; jump to loaded file ;
;---------------------;
          jmp     0x08:0x100000




;--------------------------------;
;  global descriptor table (gdt) ;
;--------------------------------;
gdt:                      dw  0x0000, 0x0000, 0x0000, 0x0000
codesel:                  dw  0xFFFF, 0x0000, 0x9800, 0x00CF
datasel:                  dw  0xFFFF, 0x0000, 0x9200, 0x00CF
gdt_end:

gdtr:                     dw  gdt_end - gdt - 1
                          dd  gdt


;-------------------------------------;
; set the BOOT-signature at byte 510. ;
;-------------------------------------;
          rb boot+512-2-$
          dw 0xAA55    

so what do you think, is it possible to fit that in?
any other suggestions?

/ Christoffer

_________________
BOS homepage: http://bos.asmhackers.net/


Last edited by bubach on 13 Feb 2012, 14:29; edited 1 time in total
Post 07 Nov 2004, 17:26
View user's profile Send private message Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4
Your read sector would be smaller if you read a sector at a time in a loop you inc sector number until it gets to 19, you make it 1, then you cmp head to 0 or 1, if 1 you make 0 and inc track number, if 0 you inc it to 1 ,and you keep loop and checking until you come to the end address.

Also y fill in gs, fs, in realmode ?.

And yes you should be able to fit more in, theres space for a cdplayer in there Laughing.

\\\\||////
(@@)
ASHLEY4.

Batteries not included, Some assembly required.
Post 07 Nov 2004, 18:25
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Hmm.. i tried to make a loop, but every time it changes almost every param. register, but i guess i could try again.
But a cdplayer? don't think so...

PS: when i use this with a test kernel, it says that it takes up 1,07 mb of the floppy, why? how can i fix that? bootsector+kernel = 5kb
hmm.. if i had more space i could try to make it load a real file from the root dir... Smile

/ Christoffer


Last edited by bubach on 13 Feb 2012, 14:30; edited 1 time in total
Post 07 Nov 2004, 18:33
View user's profile Send private message Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4
Y do you not do what i do, that is use bootprog http://alexfru.chat.ru/epm.html
any demos i have sent you that uses win image will have it on the disk, just delete the exe or com on the demo disk put a exe or com of the same name, you can use this to test your program as a exe or com, when it works right start making it smaller to fit the boot sector and then put it on the boot sector.

\\\\||////
(@@)
ASHLEY4.

Batteries not included, Some assembly required.
Post 07 Nov 2004, 18:53
View user's profile Send private message Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1171
Location: Overflow
Matrix
435 bytes and i was not radical Smile
its already 62 bytes shorter, you should try to think more about that progress bar thingy, i whouldn't do that.

Code:
;----------------------------------------------------;
;                   BOS bootsector                   ;
;----------------------------------------------------;
; FAT12 compatible. Sets pmode & A20. Kernel must be ;
;   the first thing on disk after the bootsector.    ;
;                                                    ;
; TODO:   optimize enought for error checking when   ;
;       loading sectors and print 2 progress dots    ;
;      for each "bunch" of sectors loaded correctly. ;
;                                                    ;
;          by: Christoffer Bubach, 2004              ;
;----------------------------------------------------;
use16
org 0x7C00

boot:     jmp     near fix
          nop

;-----------------------------------------;
;  Standard BIOS Parameter Block, "BPB."  ;
;-----------------------------------------;
          bpbOEM          db  'BOS 0.03'
          bpbSectSize     dw  512
          bpbClustSize    db  1
          bpbReservedSec  dw  1
          bpbFats         db  2
          bpbRootSize     dw  224
          bpbTotalSect    dw  2880
          bpbMedia        db  240
          bpbFatSize      dw  9
          bpbTrackSect    dw  18
          bpbHeads        dw  2
          bpbHiddenSect   dd  0
          bpbLargeSect    dd  0
;-----------------------------------------------;
; extended BIOS Parameter Block for FAT12/FAT16 ;
;-----------------------------------------------;
          bpbDriveNo      db  0
          bpbReserved     db  0
          bpbSignature    db  41
          bpbID           dd  1
          bpbVolumeLabel  db  'BOOT FLOPPY'
          bpbFileSystem   db  'FAT12   '

;-----------------;
;   code area     ;
;-----------------;
fix:
          jmp     0x0000:start
start:
;          cli ; i guess its not needed comment out for 2 bytes
          mov     ax, cs
          mov     ds, ax
          mov     es, ax
          mov     gs, ax
          mov     fs, ax

          push 0x9000 ; i have not tested this yet, but its intresting no? Smile
          pop ss
;          mov     ax, 0x9000
;          mov     ss, ax
          mov     sp, 0x8000

          mov     [bpbDriveNo], dl

;          sti
     ;------------------------;
     ; set textmode/font size ;
     ;------------------------;
          mov     ax, [text_mode_no]
          mov     bl, 0
          int     0x10
     ;--------------------;
     ; print loading mess ;
     ;--------------------;
          mov     bp, loading
          mov     ax, 0x1301
          mov     bx, 0x0007
          mov     cx, 12
          mov     dx, 0x0102
          int     0x10
;----------------;
; set A20 ver. 1 ;
;----------------;
          call    .out
          call    .cmd_wait
          mov     al, 0xd1
          out     0x64, al
          call    .cmd_wait
          mov     al, 0xdf
          out     0x60, al
          call    .cmd_wait
          jmp     .done
     .cmd_wait:
          in      al, 0x64
          test    al, 0x02
          jnz     .cmd_wait
          ret
     .out:
          in      al, 0x64
          test    al, 0x01
          jnz     .read
          ret
     .read:
          in     al, 0x60
          jmp    .out
     .done:
     ;-------------;
     ; test if set ;
     ;-------------;
          call     a20test
          jz       pre_read
;----------------;
; set A20 ver. 2 ;
;----------------;
          in      al, 0x92
          or      al, 0x02
          out     0x92, al
     ;-------------;
     ; test if set ;
     ;-------------;
          call     a20test
          jz       pre_read
          jmp      error
;-----------------------------;
; print progress dots (faked) ;
;-----------------------------;
pre_read:
          mov     bp, progress
          mov     ax, 0x1301
          mov     bx, 0x0002
          mov     cx, 14
          mov     dx, 0x0201
          int     0x10
;--------------------------------------;
;      read a 50 kb file to mem.       ;
;--------------------------------------;
read:
          push    es
     ;-------------;
     ; reset drive ;
     ;-------------;
          xor     ax, ax
          mov     dl, [bpbDriveNo]
          int     0x13
          jc      read
     ;---------------------------------------------------;
     ; set es and hope that bios does not mess with it.. ;
     ;---------------------------------------------------;
          push $ffff ;          mov     ax, 0xffff
          pop es     ;          mov     es, ax
     ;-----------------;
     ; read 17 sectors ;
     ;-----------------;
          mov     bx, 0x10
          xor     dh,dh
          mov ax,$0211   ;mov     ah, 2
                         ;mov     al, 17
          mov cx,2       ;   mov     ch, 0
                         ;   mov     cl, 2
          int     0x13
          jc      read

; read 18 sectors block
          mov     bx, 0x2210
          mov     dh,1
          mov cx,1     ;mov     ch, 0
                       ;mov     cl, 1
    call readsector_common  ; read 18 more ;

          mov     bx,0x4610
          xor     dh,dh
          mov     cx,$0101
          push cx
    call readsector_common  ; read 18 more ;

          mov     bx,0x6A10
          pop cx
;          mov     cx,$0101
          mov     dh,1
    call readsector_common  ; read 18 more ;

          mov     bx,0x8E10
          xor     dh,dh
          mov     cx,$0201
          push cx
    call readsector_common  ; read 18 more ;
     ; read the last 11 ;
          mov     bx,0xB210
          mov     ax,$020b
          pop cx
;          mov     cx,$0201
          mov     dh,1
          int     0x13
     ; stop motor ;
          mov     dx,0x3F2
          mov     al,0x0C
          out     dx,al

          pop     es

          jmp     pmode

readsector_common:
          mov ax,$0212 ;mov     ah, 2
                       ;mov     al, 18
          int     0x13
      ret

;----------------------------;
;  some functions and data   ;
;----------------------------;
     ;----------------;
     ;   variables    ;
     ;----------------;
          loading         db  'Starting BOS'
          progress        db  '.' ;.............'

          msg_error       db  'I/O error' ;, press any key to restart..'

          text_mode_no    dw  3

     ;----------;
     ; test A20 ;
     ;----------;
     a20test:
          mov     al,byte [fs:0]
          mov     ah,al
          not     al
          xchg    al,byte [gs:10h]
          cmp     ah,byte [fs:0]
          mov     [gs:10h], al
          ret
     ;------------;
     ; error..    ;
     ;------------;
     error:
          mov     bp, msg_error
          mov     ax, 0x1301
          mov     bx, 0x0004
          mov     cx, 37
          mov     dx, 0x0401
          int     0x10

          mov     ah, 0
          int     0x16
          int     0x19
;--------------------------------;
; end of functions and data area ;
;--------------------------------;
;----------------------------;
;    set pmode               ;
;----------------------------;
pmode:
          cli
          lgdt    [gdtr]
          mov     eax, cr0
          or      eax, 1
          mov     cr0, eax
          jmp     0x08:flush

;---------------------------------------------------------;
; start of 32-bit area. flush segments and jump to kernel ;
;---------------------------------------------------------;
use32
flush:
;-------------------------------;
; refresh all segment registers ;
;-------------------------------;
          mov     eax, 0x10
          mov     ds, eax
          mov     es, eax
          mov     fs, eax
          mov     gs, eax
          mov     ss, eax
          mov     esp, 0xfffc
;---------------------;
; jump to loaded file ;
;---------------------;
          jmp     0x08:0x100000


;--------------------------------;
;  global descriptor table (gdt) ;
;--------------------------------;
gdt:                      dw  0x0000, 0x0000, 0x0000, 0x0000
codesel:                  dw  0xFFFF, 0x0000, 0x9800, 0x00CF
datasel:                  dw  0xFFFF, 0x0000, 0x9200, 0x00CF
gdt_end:

gdtr:                     dw  gdt_end - gdt - 1
                          dd  gdt


;-------------------------------------;
; set the BOOT-signature at byte 510. ;
;-------------------------------------;
;          rb boot+512-2-$
;          dw 0xAA55

    
Post 07 Nov 2004, 19:14
View user's profile Send private message Visit poster's website Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1171
Location: Overflow
Matrix
instead of squeezing everything into the bootsector you could put more sectors on the disk which whould be read and called @ boot time.
Post 07 Nov 2004, 19:18
View user's profile Send private message Visit poster's website Reply with quote
bogdanontanu



Joined: 07 Jan 2004
Posts: 403
Location: Sol. Earth. Europe. Romania. Bucuresti
bogdanontanu
IMHO you should NOT attempt to squezze too much things into the boot sector, you will always run low on space there.

For booting from a real floppy the only optimization thing in there should be an attempt to read multiple sectors at a time (not trivial) as this should speed up the loading process.

Otherwise use a simple loop for one sector on a time. You can see that kind of loop in SolOS boot sector source code. The nex SolOS release will also have the "fast boot" version for reading one track at a time.

IMHO the boot sector shoul do ONLY some simple tasks:
1) Startup PC
2) READ the folowing sectors (2nd stage application) into memory and give it control

You can put much more complex setup code in this 2nd stage application. I use this approach.

Please consider that you will have to boot from HDD, CD-ROM, USB, etc/whatever also and placing all the code for this in a small 512bytes sector is not an option IMHO.

Also reading propretary filesystems like FAT12/FAT32 directly from the boot sector is not a good option IMHO.
Post 07 Nov 2004, 20:42
View user's profile Send private message Visit poster's website Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4
Bogdanontanu, I do not think "bubach" is trying to make a OS boot loader as such.
I think he is trying to make a pmode exe/com file loader. like bootprog, but for pmode, i may be wrong (did i realy say that) Wink.

PS: like your OS.

\\\\||////
(@@)
ASHLEY4.

Batteries not included, Some assembly required.
Post 07 Nov 2004, 23:11
View user's profile Send private message Reply with quote
beppe85



Joined: 23 Oct 2004
Posts: 181
beppe85
Most of job already is done. But you still can get unbelieved 6(if I coded correctly) bytes by reorganizing the A20 stuff:

Code:
          jmp     .out
     .cmd_wait:
          in      al, 0x64
          test    al, 0x02
          jnz     .cmd_wait
          ret
     .read:
          in      al, 0x60
     .out:
          in      al, 0x64
          test    al, 0x01
          jnz     .read

          call    .cmd_wait
          mov     al, 0xd1
          out     0x64, al

          call    .cmd_wait
          mov     al, 0xdf
          out     0x60, al

          call    .cmd_wait

     .done:
    


I guess it's not what were you asking for, but, here is... Very Happy
Post 08 Nov 2004, 00:08
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
I have my own FAT12 bootloader and second stage loader, but they are for nasm, and i thought that when i am going to rewrite it anyway, i could test and see how much i can squize in.

It's like a experiment for me.. Smile

Ashley4: i know about bootprg, and i have it, but i prefer code that is written by myself.. Wink
ps: no need for com&exe support, bin style is enought...

Thanks for the help. Now maybe i could fit in some extra function if i do something about the loading dots..? Wink

/ Christoffer


Last edited by bubach on 13 Feb 2012, 14:31; edited 2 times in total
Post 08 Nov 2004, 08:37
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
one more thing:
do i really need to test if the A20 is set between the 2 functions?
it can't harm to set it twice, can it?


Last edited by bubach on 13 Feb 2012, 14:32; edited 1 time in total
Post 08 Nov 2004, 08:40
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Hello, i have done some more work on it now.
Matrix: all those calls to read_common, takes up space.. I managed to get the size down even more without that.. Wink

Here is my newest version, originaly 411 bytes, but i added a check for 386 processor and memory 4mb.. Smile
Now it's 510 bytes, but i would like to have enought space to send drive no. and memory size to the loaded file, so if anyone can think of a way to save some more bytes.....

Code:
;----------------------------------------------------;
;                   BOS bootsector                   ;
;----------------------------------------------------;
; FAT12 compatible. Sets pmode & A20. Kernel must be ;
;   the first thing on disk after the bootsector.    ;
;                                                    ;
;     size: 510 bytes (with bootsignature)  :-p      ;
;                                                    ;
;    my old size before cpu, mem and better error    ;
;             checking was 411 bytes.                ;
;                                                    ;
; TODO: pass bpbDriveNo & memory_size to loaded file ;
;                                                    ;
;          by: Christoffer Bubach, 2004              ;
;----------------------------------------------------;
use16
org 0x7C00

boot:     jmp     near fix
          nop

;-----------------------------------------;
;  Standard BIOS Parameter Block, "BPB."  ;
;-----------------------------------------;
          bpbOEM          db  'BOS 0.03'
          bpbSectSize     dw  512
          bpbClustSize    db  1

     ;----------------------------------------;
     ; setting this to 20 reserves ~48kb, and ;
     ; setting it to 21 reserves ~200kb ! (?) ;
     ;----------------------------------------;
          bpbReservedSec  dw  1

          bpbFats         db  2
          bpbRootSize     dw  224
          bpbTotalSect    dw  2880
          bpbMedia        db  240
          bpbFatSize      dw  9
          bpbTrackSect    dw  18
          bpbHeads        dw  2
          bpbHiddenSect   dd  0
          bpbLargeSect    dd  0
;-----------------------------------------------;
; extended BIOS Parameter Block for FAT12/FAT16 ;
;-----------------------------------------------;
          bpbDriveNo      db  0
          bpbReserved     db  0

     ;--------------------------------------------------;
     ; extended boot signature. if it is not 29h (41d), ;
     ; then the following three fields is not present.  ;
     ;--------------------------------------------------;
          bpbSignature    db  0

     ;------------------------;
     ; saving some bytes. =)  ;
     ;------------------------;
     ;    bpbID           dd  1
     ;    bpbVolumeLabel  db  'BOOT FLOPPY'
     ;    bpbFileSystem   db  'FAT12   '


;-----------------;
;   "fix"-jump    ;
;-----------------;
fix:
          jmp     0x0000:start



;-----------------------;
;      variables        ;
;-----------------------;
          loading         db  'Starting BOS'

          ram_error       db  ' RAM'
          a20_error       db  ' A20'
          cpu_error       db  ' CPU'
          read_error      db  'Read'

          msg_error       db  ' error, press any key to restart..'

          memory_size     dw  0x0000

     ;----------------------------------;
     ;   set to 0x1112 for 80x50 mode   ;
     ;----------------------------------;
          text_mode_no    dw  3



;-----------------------------------------------;
;   "real" starting point of bootsector code    ;
;-----------------------------------------------;
start:
          mov     ax, cs
          mov     ds, ax
          mov     es, ax

          mov     ax, 0x9000
          mov     ss, ax
          mov     sp, 0x8000

          mov     [bpbDriveNo], dl


;--------------------;
;  clear the screen  ;
;--------------------;
          mov     ax, 3
          mov     bl, 0
          int     0x10

     ;------------------------;
     ; set textmode/font size ;
     ;------------------------;
          mov     ax, [text_mode_no]
          int     0x10

     ;--------------------;
     ; print loading mess ;
     ;--------------------;
          mov     bp, loading
          mov     ax, 0x1301
          mov     bx, 0x0007
          mov     cx, 12
          mov     dx, 0x0102
          int     0x10

     ;---------------------;
     ; set cursor location ;
     ;---------------------;
          mov     bx, 0x0002
          mov     ah, 2
          mov     dx, 0x0201
          int     0x10

     ;------------;
     ; print dots ;
     ;------------;
          mov     ah, 0x09
          mov     al, '.'
          mov     cx, 14
          int     0x10


;----------------------------------------------;
; 386 check, i have room for such luxury.. =)  ;
;----------------------------------------------;
          pushf
          pop     ax
          mov     dx, ax
          xor     ax, 0x4000
          push    ax
          popf
          pushf
          pop     ax
          and     ax, 0x4000
          and     dx, 0x4000
          cmp     ax, dx
          jnz     mem

          mov     bp, cpu_error
          jmp     error

;-------------------------------------;
;   memory check, only up to 64 mb    ;
;-------------------------------------;
mem:
          mov     ah, 0x88
          int     0x15
          mov     [memory_size], ax
          cmp     ax, 3072
          jae     a20

          mov     bp, ram_error
          jmp     error

;----------------;
; set A20 ver. 1 ;
;----------------;
a20:
          jmp     .out
     .cmd_wait:
          in      al, 0x64
          test    al, 0x02
          jnz     .cmd_wait
          ret
     .read:
          in      al, 0x60
     .out:
          in      al, 0x64
          test    al, 0x01
          jnz     .read

          call    .cmd_wait
          mov     al, 0xd1
          out     0x64, al

          call    .cmd_wait
          mov     al, 0xdf
          out     0x60, al

          call    .cmd_wait

;----------------;
; set A20 ver. 2 ;
;----------------;
          in      al, 0x92
          or      al, 0x02
          out     0x92, al

     ;-----------------;
     ; test if A20 set ;
     ;-----------------;
          mov     al, byte [fs:0]
          mov     ah, al
          not     al
          xchg    al, byte [gs:10h]
          cmp     ah, byte [fs:0]
          mov     [gs:10h], al

          jz      read

     ;------------------;
     ;   a20 error..    ;
     ;------------------;
          mov     bp, a20_error

     ;------------;
     ; error..    ;
     ;------------;
     error:
          mov     ax, 0x1301
          mov     bx, 0x0004
          mov     cx, 4
          mov     dx, 0x0401
          int     0x10

          mov     bp, msg_error
          mov     cx, 34
          mov     dx, 0x0405
          int     0x10

          mov     ah, 0
          int     0x16
          int     0x19




;-----------------------------------------------------------;
;   read the first 50 kb of the disk to to memory at 1mb.   ;
;-----------------------------------------------------------;
read:
          push    es

     ;--------------------------------------------------;
     ; error checking. we can fail a total of 10 times. ;
     ;--------------------------------------------------;
          xor     cx, cx
          push    cx
     .reset:
          pop     cx
          inc     cx
          cmp     cx, 11
          jne     .cont

          mov     bp, read_error
          jmp     error

     .cont:
          push    cx

     ;-------------;
     ; reset drive ;
     ;-------------;
          xor     ax, ax
          mov     dl, [bpbDriveNo]
          int     0x13
          jc      .reset

     ;---------------------------------------------------;
     ; set es and hope that bios does not mess with it.. ;
     ;---------------------------------------------------;
          push    0xffff
          pop     es

     ;-----------------;
     ; read 17 sectors ;
     ;-----------------;
          mov     bx, 0x10
          mov     ax, 0x0211
          mov     cx, 2
          mov     dh, 0
          int     0x13
          jc      .reset

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x2210
          inc     al
          mov     cx, 1
          mov     dh, 1
          int     0x13
          jc      .reset

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x4610
          mov     cx, 0x0101
          mov     dh, 0
          int     0x13
          jc      .reset

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x6A10
          mov     dh, 1
          int     0x13
          jc      .reset

     ;--------------;
     ; read 18 more ;
     ;--------------;
          mov     bx, 0x8E10
          mov     cx, 0x0201
          mov     dh, 0
          int     0x13
          jc      .reset

     ;------------------;
     ; read the last 11 ;
     ;------------------;
          mov     bx, 0xB210
          mov     ax, 0x020B
          mov     dh, 1
          int     0x13
          jc      .reset

     ;------------;
     ; stop motor ;
     ;------------;
          mov     dx, 0x3F2
          mov     al, 0x0C
          out     dx, al

          pop     cx
          pop     es


;----------------------------------;
;   set protected mode (32-bit)    ;
;----------------------------------;
          cli

          lgdt    [gdtr]

          mov     eax, cr0
          or      eax, 1
          mov     cr0, eax

          jmp     0x08:flush



;---------------------------------------------------------;
; start of 32-bit area. flush segments and jump to kernel ;
;---------------------------------------------------------;
use32
flush:
;-------------------------------;
; refresh all segment registers ;
;-------------------------------;
          mov     eax, 0x10
          mov     ds, eax
          mov     es, eax
          mov     fs, eax
          mov     gs, eax
          mov     ss, eax
          mov     esp, 0xfffc


;-----------------------------------;
; jump to loaded file (1mb in mem)  ;
;-----------------------------------;
          jmp     0x08:0x100000




;--------------------------------;
;  global descriptor table (gdt) ;
;--------------------------------;
gdt:                      dw  0x0000, 0x0000, 0x0000, 0x0000
codesel:                  dw  0xFFFF, 0x0000, 0x9800, 0x00CF
datasel:                  dw  0xFFFF, 0x0000, 0x9200, 0x00CF
gdt_end:

gdtr:                     dw  gdt_end - gdt - 1
                          dd  gdt


;-------------------------------------;
; set the BOOT-signature at byte 510. ;
;-------------------------------------;
          rb boot+512-2-$
          dw 0xAA55    


Last edited by bubach on 13 Feb 2012, 14:32; edited 1 time in total
Post 09 Nov 2004, 09:21
View user's profile Send private message Reply with quote
beppe85



Joined: 23 Oct 2004
Posts: 181
beppe85
Some byte savings:

On the 386 check:
- can you put 0x4000 on a register, say, cx?
- change the last jnz/mov/jmp to mov/jnz, I guess there's no need to preserve bp

On the sectors load:
- instead of cx, use di if you can
- jne/mov/jmp -> mov/jne, same as 386
Post 09 Nov 2004, 11:26
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Ok, thanks.
What other things do u want in a bootloader? I could fit in some more, with less error checking and without my "custom" error messages... Wink

Some questions:
How can i make the FAT system to behave like it should, when i am writing a file after the bootsector? As it is now, i could overwrite it if the floppy is full, becasue i can´t make the "reserved_sector" field to work...
and now XP reports that the used space is 1,07mb instead of boots. 512b and kernel~5kb. i guess that it´s becasue i overwrite one of the FAT´s? the one that should be right after the bootsector?

Can i make the file (that is going to be loaded), visible on the floppy, as a normal file, even thou it´s "hard-written" to specific sectors?

/ Christoffer
Post 09 Nov 2004, 13:39
View user's profile Send private message Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1171
Location: Overflow
Matrix
Smile
that's because MS dos and windos stuff has many bugs in there own patented codes and algorithms like for example ignoring the reserved sectors, not using some parameters given in drive info block Smile ...

yeah, you can do such things, you only have to put a valid fat and directory entry on the floppy.
Post 09 Nov 2004, 13:42
View user's profile Send private message Visit poster's website Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
But when i read the MS Fat document they wrote that MS-code is almost the only ones that do check correctly.. I guess that isn't true.

So now i have to figure out how to make a tool, wich does the copying and updates the FAT.. (links to info & source please.. Smile )

But to make it 100% FAT compatible i need to move the file a bit, right? into a fixed location of the FAT data area.. (where?)
again, some links to info&snippets on this would be great.. Wink

/ Christoffer


Last edited by bubach on 13 Feb 2012, 14:33; edited 1 time in total
Post 09 Nov 2004, 14:40
View user's profile Send private message Reply with quote
beppe85



Joined: 23 Oct 2004
Posts: 181
beppe85
The challenge is still open?

I have figured out a way to squeeze even more bytes(dozens of it).

I'm posting a snippet. As this was done two weeks or so ago, I'm not sure if I changed more than I remember. But the idea is to work out the geometry of the floppy. First read the cylinder, head ^= 1, increment cylinder on head goes zero. Note that you'll reread the boot sector. so the target code is plus 0x200.

Code:
     ;---------------------------------------------------;
     ; set es and hope that bios does not mess with it.. ;
     ;---------------------------------------------------;
       mov     ax, 0xffff
          mov     es, ax

     ;-----------------------;
     ; prepare for disk read ;
     ;-----------------------;

        mov     bx, 0x10              ; buffer start
        xor     dh, dh                ; head 0
      mov     cx, 1                 ; cilinder 0, sector 1

     ;---------------------------;
     ; read 18 sectors each turn ;
     ;---------------------------;
     .track:
      mov     ax, 2 shl 8 or 18     ; read sectors function
       int     0x13
;          jc      .track
   add     bh, 0x24              ; update buffer pointer = bx += 0x2400
        add     ch, dh                ; increment cilinder on dh = 1
        btc     dx, 0
       cmp     ch, 3                 ; past cilinder 3?
    jbe     .track    


If I did any mistake(I have _not_ tested), plz point them out to me.
Post 18 Dec 2004, 23:44
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
somtething like
Code:
mov ax,cs
mov ds,ax
mov es,ax
    

can be
[code]
push cs cs
pop es ds
[code]
another not-so-nice trick: You could group most-often used data in 256 bytes, point some addressing register on it (now i am not sure if at beginning ar in the middle) and istead of absolute addressing use register + byte displacement which is one byte shorter (in most case, i think). But this way it will be hardly readable.
Post 19 Dec 2004, 12:44
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.