Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > alt.comp.bios > #4

Re: How to use BIOS int 13h ah=48h ?

From "Benjamin David Lunt" <zfysz@fysnet.net>
Newsgroups alt.comp.bios, alt.os.development
Subject Re: How to use BIOS int 13h ah=48h ?
Date 2016-04-05 12:53 -0700
Organization Aioe.org NNTP Server
Message-ID <ne1541$17fa$1@gioia.aioe.org> (permalink)
References <ndqsef$9r8$1@dont-email.me> <20160403173650.55074eb8@_> <ne0b78$m2g$1@dont-email.me>

Cross-posted to 2 groups.

Show all headers | View raw


"bilsch" <king621@comcast.net> wrote in message 
news:ne0b78$m2g$1@dont-email.me...
> On 04/03/2016 02:36 PM, Rod Pemberton wrote:

Hi bilsch, Hi guys,

I just have a few comments on your code, if you don't mind.

> <code>
> ;kern1.asm nasm -f bin kern1.asm -o kern1.bin
>
> ;reads an 8 byte buffer containing number of sectors info; buffer begins 
> at ds:si + 0x10
>
> org 0x7c00
> bits 16
> SECTION .text
>
>    mov ax, 0  ; set up segments

; in boot sectors, space is sometimes an issue.  Every byte
; counts, so I would change the above to
;    xor  ax,ax     ; saves a byte

>    mov ds, ax
>    mov es, ax
>    mov ss, ax     ; setup stack
>    mov sp, 0x7C00 ; stack grows downwards from 0x7C00
>
>    mov si,msg41
>    call print_string
>    mov bx,0x55aa
>    mov dl, 0x80
>    mov ah,0x41
>    int 0x13

; on return:
;  carry set if error
;    jc  short to_some_error_handler
;  carry clear if successful
;    cmp bx,0xAA55
;    jne short to_some_error_handler

>    push cx
>    push ax
>    cmp ah,0x10 ;ver 1.x
>    mov word[bsiz],0x1a
>    cmp ah,0x20 ;ver 2.0
>    mov word[bsiz],0x1e
>    cmp ah,0x21 ;ver 2.1
>    mov word[bsiz],0x1e
>    cmp ah,0x30 ;ver 3.0
>    mov word[bsiz],0x42

; the above code will *always* put a value of 0x42 in the
;  [bsiz] address.  You need some 'jcc' in there somewhere.

>    mov si,ahmsg41 ;'ah41 = '
>    call print_string

>    mov bx,i2xt
>    xor cx,cx ;cx counts to 1
>    pop ax
> lup1: ;here ax is data from ah=0x41
>    rol ax,4 ;put hi hex digit on right
>    push ax ;rol'd version
>    and al,0x0f ;digit in al, is index into i2xt
>    xlat ;table result in al, bx already points i2xt
>    mov ah,0xe int 0x10 ;write
>    pop ax
>    cmp cx,1
>    je api ;cx=1 then done w/ah
>    inc cx
>    jmp lup1

; I noticed that you use this print code a few times
;  within your listing here.  Can you call a routine
;  to do this?  Rather than listing it numerous times,
;  which takes up space, you can just call a function
;  to do it.  Also, I would change it a bit.
;
; first comment:
;  Setting CX to 0, then comparing it with a non-zero
;  value adds code, specifically an extra 'cmp' and 'jcc'
;  instruction.  Slower and larger.
;
;       mov  cx,2
;  @@:
;       ; do something here
;
;       dec  cx
;       jnz  short @b
; or change the above to just the 'loop' instruction
;       loop @b
;
; Saves time and space.

; the code above now becomes
;    mov  bx,i2xt
;    mov  cx,2      ; printing 2 nibbles
;    pop  ax
; lup1:             ; here ax is data from ah=0x41
;    rol  ax,4      ; put hi hex digit on right
;    push ax        ; rol'd version
;    and  al,0x0f   ; digit in al, is index into i2xt
;    xlat           ; table result in al, bx already points i2xt
;    mov  ah,0xe
;    int  0x10      ; write
;    pop  ax
;    loop lup1
;
; (It is easier on the eyes if you align the colums of code
;  and comments.  i.e.: which is easier to read, your code
;  above, or my code here?)
;
; Second comment:
;  printing hex digits is something everyone has done so
;  there is a lot of code around.  A few years ago, more than
;  I would like to admit, a regular in c.l.a.x passed away.
;  However, he left us with a very nice hex printing routine.
;    http://www.fysnet.net/prthex.htm#crayne
;  It uses 32-bit registers and prints to a string, but you
;  should be able to modify it to use 16-bit registers and
;  directly to the screen.
;
> api:
>    mov si,apimsg ;'api = '
>    call print_string
>    pop cx
>    mov al,cl

;  As you probably know, the push instruction does push
;  the register, it pushes the contents of the register.
;  Therefore, you don't have to use the same register
;  when you pop the value.  You can easily use a different
;  register.  Changing the above to
;    pop  ax
;  removes the 'mov' instruction.  Save space and time!

>    xlat ;table result in al, bx already points i2xt
>    mov ah,0xe int 0x10 ;write
>
>    mov si, msg48 ;display BIOS call
>    call print_string
>    clc ;clear CF
>    mov si,sxbuf ;bufr for BIOS to fill
>    mov di,word[bsiz]
>    mov [sxbuf],di ;bufr size for BIOS call
>    mov ah,0x48
>    mov dl,0x80 ;bit 7 = hd
>    int 0x13 push ax
>
>    jc cf1
>    mov si, cfzro
>    call print_string
>    jmp ah48
> cf1:
>    mov si, cfone
>    call print_string
> ah48:
>    mov si,ahmsg48 ;'ah='
>    call print_string
>    xor cx,cx ;cx counts to 1
>    pop ax
> lup2: ;here ax is data from ah=0x48
>    rol ax,4 ;put hi hex digit on right
>    push ax ;rol'd version
>    and al,0x0f ;digit in al, is index into i2xt
>    xlat ;table result in al, bx already points i2xt
>    mov ah,0xe int 0x10 ;write
>    pop ax
>    cmp cx,1
>    je dsxinfo ;cx=1 then done w/ah
>    inc cx
>    jmp lup2
>
> dsxinfo:
>    mov si, sxmsg ;'hex # sectors = '
>    call print_string
>    xor cx,cx
>    xor dx,dx
>    xor di,di
>    add di,0x10 ;offset into sxbuf

;    mov  di,0x10
;   (but I'm sure you are not worried about it at the
;    moment.  You just want the value printed)

> get4hex:
>    add di,dx
>    add di,dx ;di=2*dx, dx counts words, di counts bytes
>    mov ax,[sxbuf+di] outdig:
>    rol ax,4 ;put hi hex digit on right
>    push ax ;save rol'd ax
>    and al,0x0f ;digit in al, is index into i2xt
>    xlat ;table result in al
>    mov ah,0xe int 0x10 ;write
>    pop ax ;rol'd version of ax
>    inc cx
>    cmp cx,4 ;cx is inner loop counter
>    jne outdig ;4 digit loop - 1 nibble/loop
>    xor cx,cx
>    inc dx ;dx counts words
>    cmp dx,4 ;4 word loop - 1 word/loop
>    je nend
>    jmp get4hex ;get next 4 hex digits


; I would change the above to use SI and 'lodsb'
;    mov  cx,8     ; 8 bytes
;    lea  si,[sxbuf+0x10]
; @@:
;    lodsb
;    call hexdb    ; Crayne's print nibble
;    loop @b

Please note that your code all prints the hex digits
backwards.  Which through your comments, I think you
realize this. :-)

Anyway, just a few comments.

I know it is C code instead of assembly, but I have
source code at
 http://www.fysnet.net/syscore_help.htm
that will show you how to get all of the information from
the drive, including total sector count.

Hope this helps,
Ben

Back to alt.comp.bios | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

How to use BIOS int 13h ah=48h ? bilsch <king621@comcast.net> - 2016-04-03 03:52 -0700
  Re: How to use BIOS int 13h ah=48h ? Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-04-03 17:36 -0400
    Re: How to use BIOS int 13h ah=48h ? bilsch <king621@comcast.net> - 2016-04-05 05:34 -0700
      Re: How to use BIOS int 13h ah=48h ? "Benjamin David Lunt" <zfysz@fysnet.net> - 2016-04-05 12:53 -0700
      Re: How to use BIOS int 13h ah=48h ? Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-04-06 00:10 -0400
  THANKS FOR INFO & SUGGESTIONS bilsch <king621@comcast.net> - 2016-04-08 07:49 -0700

csiph-web