implement serial port output
This commit is contained in:
parent
7e35407942
commit
259b7a4314
3 changed files with 83 additions and 3 deletions
2
Makefile
2
Makefile
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
79
src/serial.s
Normal 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
|
||||||
Loading…
Add table
Reference in a new issue