Initial import of ViperOS

This commit is contained in:
Viper
2026-07-19 12:38:20 +08:00
commit 6813947181
104 changed files with 26710 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
import platform.pch.pic as pic
import su8250
import t, c
# 串口初始化
def init():
# 初始化COM1端口
su8250.init(su8250.COM1_PORT)
# 启用COM1中断IRQ4
pic.clearMask(4)
# 发送一个字符到COM1
def putc(cr: t.CChar):
su8250.putchar(su8250.COM1_PORT, cr)
def putchar(cr: t.CChar):
su8250.putchar(su8250.COM1_PORT, cr)
# 从COM1读取一个字符
def getchar() -> t.CChar:
return su8250.getchar(su8250.COM1_PORT)
# 发送一个字符串到COM1
def puts(s: str):
# 逐个字符发送直接复用putchar的逻辑
for i in s:
putchar(i)
# 检查COM1是否有数据可读
def isDataAvailable() -> t.CInt:
return su8250.isDataAvailable(su8250.COM1_PORT)
# 检查COM1发送缓冲区是否为空
def isTransmitEmpty() -> t.CInt:
return su8250.isTransmitEmpty(su8250.COM1_PORT)
# 发送32位十六进制值到COM1
def put_hex32(value: t.CUInt32T):
hex_digits: t.CArray[t.CChar, None] = ["0123456789ABCDEF"]
buffer: t.CArray[t.CChar, 9]
for i in range(7, -1, -1):
buffer[i] = hex_digits[value & 0xF]
value >>= 4
buffer[8] = '\0'
puts(buffer)

View File

@@ -0,0 +1,116 @@
import platform.pch as pch
import asm
import t, c
# 串口端口定义
COM1_PORT: t.CDefine = 0x3F8 # COM1端口地址
COM2_PORT: t.CDefine = 0x2F8 # COM2端口地址
# 8250/16550 UART寄存器偏移
UART_RBR: t.CDefine = 0 # 接收缓冲区寄存器(读)
UART_THR: t.CDefine = 0 # 发送保持寄存器(写)
UART_DLL: t.CDefine = 0 # 除数锁存低位DLAB=1
UART_IER: t.CDefine = 1 # 中断使能寄存器
UART_DLM: t.CDefine = 1 # 除数锁存高位DLAB=1
UART_FCR: t.CDefine = 2 # FIFO控制寄存器
UART_IIR: t.CDefine = 2 # 中断识别寄存器(读)
UART_LCR: t.CDefine = 3 # 线路控制寄存器
UART_MCR: t.CDefine = 4 # 调制解调器控制寄存器
UART_LSR: t.CDefine = 5 # 线路状态寄存器
UART_MSR: t.CDefine = 6 # 调制解调器状态寄存器
UART_SCR: t.CDefine = 7 # scratch register
UART_LSR_THRE: t.CDefine = 0x20 # THRE发送保持寄存器空
UART_LSR_TEMT: t.CDefine = 0x40 # TEMT发送移位寄存器空真正的发送完成
# 线路控制寄存器位定义
UART_LCR_DLAB: t.CDefine = 0x80 # 除数锁存访问位
UART_LCR_8BIT: t.CDefine = 0x03 # 8位数据位
# 线路状态寄存器位定义
UART_LSR_DR: t.CDefine = 0x01 # 数据就绪
UART_LSR_THRE: t.CDefine = 0x20 # 发送保持寄存器空
# 波特率除数115200 bps
BAUD_115200: t.CDefine = 1
# 初始化UART 8250/16550
def init(port: t.CUInt16T):
# 1. 禁用中断
asm.outb(port + UART_IER, 0x00)
delay(1000)
# 2. 设置波特率除数115200 bps
asm.outb(port + UART_LCR, UART_LCR_DLAB) # 设置DLAB位
delay(1000)
asm.outb(port + UART_DLL, 0x01) # 除数低位 (115200 bps)
delay(1000)
asm.outb(port + UART_DLM, 0x00) # 除数高位
delay(1000)
# 3. 设置线路控制8位数据位1位停止位无校验
asm.outb(port + UART_LCR, UART_LCR_8BIT)
delay(1000)
# 4. 初始化FIFO
asm.outb(port + UART_FCR, 0x07) # 启用FIFO清除接收和发送FIFO
delay(1000)
# 5. 设置调制解调器控制
asm.outb(port + UART_MCR, 0x03) # 启用DTR、RTS
delay(1000)
# 6. 清除任何待处理的中断
asm.inb(port + UART_IIR)
delay(1000)
asm.inb(port + UART_RBR)
delay(1000)
# 7. 等待一段时间让设备稳定
delay(10000)
# 延迟函数
def delay(count: t.CInt):
for i in range(count): c.Asm("nop")
# 检查发送缓冲区是否为空
def isTransmitEmpty(port: t.CUInt16T) -> t.CInt:
return asm.inb(port + UART_LSR) & UART_LSR_THRE
def putchar(port: t.CUInt16T, cr: t.CChar):
# 1. 处理换行符:串口终端需要\r\n才会正确换行只发\n会错位
if cr == '\n':
# 直接发送\r避免递归调用
timeout: t.CUInt32T = 1000000
while ((asm.inb(port + UART_LSR) & UART_LSR_THRE) == 0) and timeout:
c.Asm("nop")
timeout -= 1
if timeout == 0: return
asm.outb(port + UART_THR, '\r')
timeout = 1000000
while ((asm.inb(port + UART_LSR) & UART_LSR_TEMT) == 0) and timeout:
c.Asm("nop")
timeout -= 1
# 2. 等待发送缓冲区为空
timeout: t.CUInt32T = 1000000
while ((asm.inb(port + UART_LSR) & UART_LSR_THRE) == 0) and timeout:
c.Asm("nop")
timeout -= 1
if timeout == 0: return
# 3. 发送字符
asm.outb(port + UART_THR, cr)
# 4. 等待发送完成
timeout = 1000000
while ((asm.inb(port + UART_LSR) & UART_LSR_TEMT) == 0) and timeout:
c.Asm("nop")
timeout -= 1
# 检查是否有数据可读
def isDataAvailable(port: t.CUInt16T) -> t.CInt:
return asm.inb(port + UART_LSR) & UART_LSR_DR
# 读取一个字符
def getchar(port: t.CUInt16T) -> t.CChar:
# 等待数据可用
while not isDataAvailable(port): pass
# 读取字符
return asm.inb(port + UART_RBR)