flat assembler
Message board for the users of flat assembler.

Index > OS Construction > [solved] Qemu BIOS and Serial

Author
Thread Post new topic Reply to topic
jemo07



Joined: 03 Apr 2024
Posts: 2
jemo07 03 Apr 2024, 14:20
Hello, I'm trying to learn FASM and x86 ... I though I create a simple bios that echoes my input on the screen. however, this is not going as plan... I have tried several iterations of the code, but I can't seem to print correctly, I'm getting a "0" for every keystroke from the serial0 console on qemu or running it with -serial stdio,

Here is my full listing and I would appreciate to learn where my mistakes might be...
Rolling EyesRolling EyesRolling Eyes
boot.fasm:

Code:
; boot.fasm

use16
org 0x7C00

start:
    cli             ; Disable interrupts
    mov ax, 0x07C0  ; Set up the stack
    mov ss, ax
    mov sp, 0x1000
    sti             ; Enable interrupts

    call init_uart  ; Initialize UART for serial communication

    ; Set video mode to 80x25 text mode
    mov ah, 0x00
    mov al, 0x03
    int 0x10

    ; Main loop to echo characters
main_loop:
    call read_byte_from_com1  ; Read a byte from COM1
    call print_char           ; Print the received character
    jmp main_loop             ; Repeat indefinitely

; Include the serial communication routines
include 'com.fasm'

; Print the ASCII character representation of the byte in AL to the screen
print_char:
    push ax                    ; Save the register values
    push bx
    push cx
    push dx

    mov ah, 0x0E               ; BIOS teletype output
    mov bh, 0x00               ; Page number
    mov bl, 0x07               ; Attribute (light grey on black)
    mov cl, al                 ; Move the byte value to CL
    and cl, 0x7F               ; Mask off the high bit (non-ASCII values)
    cmp cl, 0x20               ; Check if the byte is a printable ASCII character
    jl non_printable           ; If not, print a '.' instead
    jmp print_char_loop
non_printable:
    mov cl, '.'                ; Print a '.' for non-printable characters

print_char_loop:
    int 0x10                   ; Call BIOS video interrupt
    pop dx                     ; Restore the register values
    pop cx
    pop bx
    pop ax
    ret
        
times 510-($-$$) db 0  ; Pad the bootloader to 510 bytes
dw 0xAA55              ; Boot signature
    


and com.fasm
Code:
 

; com.fasm 
use16

PORT equ 0x3F8  ; COM1 Base Port

; Initialize UART for serial communication
init_uart:
    pusha                      ; Save all general-purpose registers

    ; Disable all UART interrupts
    mov dx, PORT + 1           ; Interrupt Enable Register
    mov al, 0x00               ; Disable all interrupts
    out dx, al

    ; Set baud rate to 9600
    mov dx, PORT + 3           ; Line Control Register
    mov al, 0x80               ; Enable DLAB (Divisor Latch Access Bit)
    out dx, al
    mov ax, 0x000C             ; Divisor for 9600 baud rate (12)
    mov dx, PORT               ; Divisor latch low byte
    out dx, al
    mov dx, PORT + 1           ; Divisor latch high byte
    mov al, ah
    out dx, al

    ; Set line control register: 8 bits, no parity, 1 stop bit
    mov dx, PORT + 3
    mov al, 0x03               ; 8 bits, no parity, one stop bit
    out dx, al

    ; Enable FIFO, clear them, with 1-byte threshold (optional, for simplicity)
    ;mov dx, PORT + 2
    ;mov al, 0x01               ; Enable FIFO & set 1-byte threshold
    ;out dx, al

    popa                       ; Restore all general-purpose registers
    ret

; Send a byte to COM1
send_byte_to_com1:
    push ax
    push dx

    mov dx, PORT + 5           ; Line Status Register
wait_for_transmit_empty:
    in al, dx
    test al, 0x20              ; Wait for the transmitter to be empty
    jz wait_for_transmit_empty

    pop dx
    mov dx, PORT
    pop ax
    out dx, al
    ret

; Read a byte from COM1
read_byte_from_com1:
    push ax
    push dx

    mov dx, PORT + 5           ; Line Status Register
wait_for_data_ready:
    in al, dx
    test al, 0x01              ; Check if data is available
    jz wait_for_data_ready

    mov dx, PORT
    in al, dx                  ; Read the byte

    pop dx
    pop ax
    ret
    

_________________
Thank you!

jemo
Post 03 Apr 2024, 14:20
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 03 Apr 2024, 14:26
Here
Code:
read_byte_from_com1:
    push ax
;...
    pop ax
    ret    
It always return AL unchanged.
Post 03 Apr 2024, 14:26
View user's profile Send private message Visit poster's website Reply with quote
jemo07



Joined: 03 Apr 2024
Posts: 2
jemo07 03 Apr 2024, 17:25
Shocked

Dohhhhh Thank you!!!... man, was down a rat hole before I got here and just not see that...

_________________
Thank you!

jemo
Post 03 Apr 2024, 17:25
View user's profile Send private message Reply with quote
SeproMan



Joined: 11 Oct 2009
Posts: 70
Location: Belgium
SeproMan 04 Apr 2024, 19:15
@revolution showed you the mistake regarding the serial access.
Additionally there's something wrong in the print_char subroutine. The BIOS.Teletype function always uses the AL register. The masked and/or substituted value in the CL register is never going to be printed!

Code:
print_char:
    push ax             ; Save the register values
    push bx
    mov ah, 0x0E        ; BIOS teletype output
    mov bx, 0x0007      ; Page number and Attribute (light grey on black)
    and al, 0x7F        ; Mask off the high bit (non-ASCII values)
    cmp al, 0x20        ; Check if the byte is a printable ASCII character
    jnb .print
    mov al, '.'         ; Print a '.' for non-printable characters
.print:
    int 0x10            ; Call BIOS video interrupt
    pop bx              ; Restore the register values
    pop ax
    ret
    

_________________
Real Address Mode.
Post 04 Apr 2024, 19:15
View user's profile Send private message 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.