implement serial port output

This commit is contained in:
mykola2312 2024-08-04 16:00:08 +03:00
parent 7e35407942
commit 259b7a4314
3 changed files with 83 additions and 3 deletions

View file

@ -97,7 +97,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.s
$(AS) $(ASFLAGS) -o $@ $< $(AS) $(ASFLAGS) -o $@ $<
$(OBJCOPY) --remove-section .note.gnu.property $@ $(OBJCOPY) --remove-section .note.gnu.property $@
MBR_TEST_OBJ = obj/mbr_test.o obj/print.o MBR_TEST_OBJ = obj/mbr_test.o obj/serial.o
mbr_test: $(MBR_TEST_OBJ) $(DISK) mbr_test: $(MBR_TEST_OBJ) $(DISK)
$(LD) -T src/mbr_test.ld -o $(BIN_DIR)/mbr_test.bin $(MBR_TEST_OBJ) $(LD) -T src/mbr_test.ld -o $(BIN_DIR)/mbr_test.bin $(MBR_TEST_OBJ)

View file

@ -30,9 +30,10 @@
xor %sp, %sp xor %sp, %sp
.entry: .entry:
push $msg call serial_init
call print
mov $msg, %si
call prints
.halt: .halt:
jmp .halt jmp .halt

79
src/serial.s Normal file
View file

@ -0,0 +1,79 @@
.section .text
.code16
.globl serial_init
.globl serial_putc
.globl prints
.equ CONFIG_DIVISOR, 1 # we want maximum baud rate
.equ CONFIG_DATA_BITS, 8
.equ CONFIG_STOP_BITS, 1
.equ CONFIG_PORT, 0x3F8
.equ SERIAL_R_BUFFER, CONFIG_PORT + 0
.equ SERIAL_W_BUFFER, CONFIG_PORT + 0
.equ SERIAL_RW_IER, CONFIG_PORT + 1
.equ SERIAL_DLAB_L, CONFIG_PORT + 0
.equ SERIAL_DLAB_H, CONFIG_PORT + 0
.equ SERIAL_R_II, CONFIG_PORT + 2
.equ SERIAL_W_FIFO, CONFIG_PORT + 2
.equ SERIAL_RW_LCR, CONFIG_PORT + 3
.equ SERIAL_RW_MCR, CONFIG_PORT + 4
.equ SERIAL_R_LSR, CONFIG_PORT + 5
.equ SERIAL_MSR, CONFIG_PORT + 6
.equ SERIAL_RW_SCRATCH, CONFIG_PORT + 7
# arg 1 - serial port base
serial_init:
# enable DLAB to setup baud divisor
mov $(1 << 7), %al
mov $SERIAL_RW_LCR, %dx
out %al, %dx
# divisor low byte
mov $(CONFIG_DIVISOR & 0xFF), %al
mov $SERIAL_DLAB_L, %dx
out %al, %dx
# divisor high byte
mov $(CONFIG_DIVISOR >> 8), %al
mov $SERIAL_DLAB_H, %dx
out %al, %dx
# config port, but also keep high bit zero to clear DLAB
mov $((CONFIG_STOP_BITS << 2) | (CONFIG_DATA_BITS & 0b11)), %al
mov $SERIAL_RW_LCR, %dx
out %al, %dx
ret
# al - data byte
# dx overwritten
serial_putc:
# write byte
mov $SERIAL_W_BUFFER, %dx
out %al, %dx
# poll state
mov $SERIAL_R_LSR, %dx
.poll:
in %dx, %al
and $(1 << 6), %al
jz .poll
ret
# ds:si - asciz
prints:
push %dx
cld
.putc:
lodsb
or %al, %al
jz .end
call serial_putc
jmp .putc
.end:
pop %dx
ret