From 259b7a4314e61d3ee148b8580ea3bc4a588a0361 Mon Sep 17 00:00:00 2001 From: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Sun, 4 Aug 2024 16:00:08 +0300 Subject: [PATCH] implement serial port output --- Makefile | 2 +- src/mbr_test.s | 5 ++-- src/serial.s | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/serial.s diff --git a/Makefile b/Makefile index 88eb605..7264c5b 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.s $(AS) $(ASFLAGS) -o $@ $< $(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) $(LD) -T src/mbr_test.ld -o $(BIN_DIR)/mbr_test.bin $(MBR_TEST_OBJ) diff --git a/src/mbr_test.s b/src/mbr_test.s index 4ad64a2..29e90f0 100644 --- a/src/mbr_test.s +++ b/src/mbr_test.s @@ -30,9 +30,10 @@ xor %sp, %sp .entry: - push $msg - call print + call serial_init + mov $msg, %si + call prints .halt: jmp .halt diff --git a/src/serial.s b/src/serial.s new file mode 100644 index 0000000..5cc2df7 --- /dev/null +++ b/src/serial.s @@ -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