.set noreorder .include "hwregs_a.h" .section .text # Currently implemented serial control functions: # # cmd(a0) sub(a1) # 0 0 Get serial status # 0 1 Get control line status # 0 2 Get serial mode # 0 3 Get baud rate # 0 4 Read 1 byte # 1 1 Set serial control # 1 2 Set serial mode # 1 3 Set baud rate # 1 4 Write 1 byte # 2 0 Reset serial # 2 1 Acknowledge serial .global _sio_control .type _sio_control, @function _sio_control: # a0 - command # a1 - subcommand # a2 - argument lui $a3, IOBASE beq $a0, $0, .Lcmd0 nop beq $a0, 1, .Lcmd1 nop beq $a0, 2, .Lcmd2 nop jr $ra nop .Lcmd0: beq $a1, $0, .Lcmd0arg0 nop beq $a1, 1, .Lcmd0arg1 nop beq $a1, 2, .Lcmd0arg2 nop beq $a1, 3, .Lcmd0arg3 nop beq $a1, 4, .Lcmd0arg4 nop jr $ra nop .Lcmd0arg0: # Get SIO status lhu $v0, SIO_STAT($a3) nop jr $ra andi $v0, 0x3FF .Lcmd0arg1: # Get control line status lhu $v1, SIO_CTRL($a3) nop srl $v0, $v1, 1 andi $v0, 0x1 srl $v1, 4 andi $v1, 0x2 jr $ra or $v0, $v1 .Lcmd0arg2: # Get serial mode lhu $v0, SIO_MODE($a3) nop jr $ra andi $v0, 0xFF .Lcmd0arg3: lui $v1, 0x1f lhu $v0, SIO_BAUD($a3) ori $v1, 0xa400 div $v1, $v0 nop nop mflo $v0 jr $ra nop .Lcmd0arg4: # Serial RX read lbu $v0, SIO_TXRX($a3) nop jr $ra nop .Lcmd1: beq $a1, 1, .Lcmd1arg1 nop beq $a1, 2, .Lcmd1arg2 nop beq $a1, 3, .Lcmd1arg3 nop beq $a1, 4, .Lcmd1arg4 nop jr $ra nop .Lcmd1arg1: andi $v0, $a2, 0x1CFF sh $a2, SIO_CTRL($a3) jr $ra nop .Lcmd1arg2: sh $a2, SIO_MODE($a3) jr $ra nop .Lcmd1arg3: lui $v0, 0x1f ori $v0, 0xa400 divu $v0, $a2 bnez $a2, .Lgood_baud nop jr $ra nop .Lgood_baud: mflo $v0 sh $v0, SIO_BAUD($a3) nop jr $ra nop .Lcmd1arg4: sb $a2, SIO_TXRX($a3) nop jr $ra nop .Lcmd2: beq $a1, $0 , .Lcmd2arg0 li $v0, 1 beq $a1, $v0, .Lcmd2arg1 nop jr $ra nop .Lcmd2arg0: li $v0, 0x40 sh $v0, SIO_CTRL($a3) sh $0 , SIO_MODE($a3) sh $0 , SIO_BAUD($a3) nop jr $ra nop .Lcmd2arg1: lhu $v0, SIO_CTRL($a3) nop ori $v0, 0x10 sh $v0, SIO_CTRL($a3) jr $ra nop