continuing with serial driver in dsa.
This commit is contained in:
+97
-44
@@ -1,57 +1,74 @@
|
||||
dw uart: 0x40000
|
||||
// ------------------------------------------
|
||||
// reads up to rg1 bytes into buffer at rg2
|
||||
// args: buf_size @ bpr+8, buf_addr @ bpr+12
|
||||
// returns: 0 in bpr+8 on success, 1 on nullptr error
|
||||
buf_read: func
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
push rg3
|
||||
ldw bpr, rg1, 8 // buf size
|
||||
ldw bpr, rg2, 12 // buf addr
|
||||
jez rg2, _buf_read_err // return err if nullptr
|
||||
_buf_read_loop:
|
||||
jez rg1, _buf_read_end
|
||||
call read_byte
|
||||
ldw bpr, rg3, 8 // read return value from frame
|
||||
stb rg3, rg2 // store into buffer
|
||||
addi rg2, 1, rg2
|
||||
subi rg1, 1, rg1
|
||||
jmp _buf_read_loop
|
||||
_buf_read_end:
|
||||
stw zero, bpr, 8 // return 0 (success)
|
||||
pop rg3
|
||||
pop rg2
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
_buf_read_err:
|
||||
lli 1, rg0
|
||||
stw rg0, bpr, 8 // return 1 (error)
|
||||
pop rg3
|
||||
pop rg2
|
||||
pop rg1
|
||||
pop rg0
|
||||
// Serial port address in MMIO
|
||||
dw UART: 0x40000
|
||||
|
||||
// Reserve space for our read buffer
|
||||
resb SERIAL_BUFFER: 1024
|
||||
dw SER_READ_PTR: 0
|
||||
dw SER_WRITE_PTR: 0
|
||||
|
||||
serial_init: func
|
||||
lwi SERIAL_BUFFER, rg0
|
||||
stw rg0, SER_READ_PTR, 0
|
||||
stw rg0, SER_WRITE_PTR, 0
|
||||
return
|
||||
|
||||
serial_isr:
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
|
||||
ldw UART, rg0
|
||||
ldb rg0, rg1, 2 // load ser_in_valid flag
|
||||
|
||||
// no serial input
|
||||
jez rg1, _serial_isr_end
|
||||
|
||||
// we should have a valid byte to read at offset 3
|
||||
ldb rg0, rg1, 3 // data byte
|
||||
|
||||
// write data to ptr and increment
|
||||
ldw SER_WRITE_PTR, rg2
|
||||
stb rg1, rg2
|
||||
addi rg2, 1
|
||||
|
||||
// load buff+1024
|
||||
lwi SERIAL_BUFFER, rg0
|
||||
addi rg0, 1024, rg1
|
||||
|
||||
// if ptr != buff+1024, nowrap.
|
||||
ine rg1, rg2, rg1
|
||||
jnz rg1, _serial_isr_nowrap
|
||||
|
||||
lwi SERIAL_BUFFER, rg2 // set the pointer
|
||||
|
||||
_serial_isr_nowrap:
|
||||
stw rg2, SER_WRITE_PTR
|
||||
|
||||
_serial_isr_end:
|
||||
pop rg0
|
||||
pop rg1
|
||||
pop rg2
|
||||
iret
|
||||
|
||||
|
||||
|
||||
// read_byte: emulator → kernel
|
||||
// reads data from base+0x00, valid flag at base+0x01
|
||||
read_byte: func
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
ldw uart, rg1
|
||||
ldw UART, rg1
|
||||
_serial_read_wait:
|
||||
ldb rg1, rg0, 1 // base+0x01 = read valid flag
|
||||
ldb rg1, rg0, 2 // base+0x02 = read valid flag
|
||||
lli 0x01, rg2
|
||||
ieq rg0, rg2, rg2
|
||||
jnz rg2, _serial_read_ready
|
||||
hlt
|
||||
jmp _serial_read_wait
|
||||
_serial_read_ready:
|
||||
ldb rg1, rg0, 0 // base+0x00 = data byte
|
||||
stb zero, rg1, 1 // clear read valid flag
|
||||
ldb rg1, rg0, 3 // base+0x03 = data byte
|
||||
stb zero, rg1, 2 // clear read valid flag
|
||||
stb rg0, bpr, 8 // return byte
|
||||
pop rg2
|
||||
pop rg1
|
||||
@@ -59,22 +76,22 @@ _serial_read_ready:
|
||||
return
|
||||
|
||||
// _serial_send: kernel → emulator
|
||||
// writes data to base+0x02, valid flag to base+0x03
|
||||
// writes data to base+0x01, valid flag to base+0x00
|
||||
_serial_send:
|
||||
push rg0
|
||||
push rg2
|
||||
push rg3
|
||||
push rg4
|
||||
push rg5
|
||||
ldw uart, rg5
|
||||
ldw UART, rg5
|
||||
_serial_wait:
|
||||
ldb rg5, rg2, 3 // base+0x03 = write valid flag
|
||||
ldb rg5, rg2, 0 // base+0x00 = ser_out_valid
|
||||
lli 0x01, rg3
|
||||
ieq rg2, rg3, rg4
|
||||
jnz rg4, _serial_wait // wait while emulator hasn't consumed yet
|
||||
stb rg0, rg5, 2 // base+0x02 = data byte
|
||||
stb rg0, rg5, 1 // base+0x01 = ser_out_data
|
||||
lli 0x01, rg2
|
||||
stb rg2, rg5, 3 // base+0x03 = set valid flag
|
||||
stb rg2, rg5, 0 // base+0x00 = ser_out_valid = 1
|
||||
pop rg5
|
||||
pop rg4
|
||||
pop rg3
|
||||
@@ -114,3 +131,39 @@ print_byte: func
|
||||
// ------------------------------------------
|
||||
_serial_end:
|
||||
return
|
||||
|
||||
// ------------------------------------------
|
||||
// reads up to rg1 bytes into buffer at rg2
|
||||
// args: buf_size @ bpr+8, buf_addr @ bpr+12
|
||||
// returns: 0 in bpr+8 on success, 1 on nullptr error
|
||||
buf_read: func
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
push rg3
|
||||
ldw bpr, rg1, 8 // buf size
|
||||
ldw bpr, rg2, 12 // buf addr
|
||||
jez rg2, _buf_read_err // return err if nullptr
|
||||
_buf_read_loop:
|
||||
jez rg1, _buf_read_end
|
||||
call read_byte
|
||||
ldw bpr, rg3, 8 // read return value from frame
|
||||
stb rg3, rg2 // store into buffer
|
||||
addi rg2, 1, rg2
|
||||
subi rg1, 1, rg1
|
||||
jmp _buf_read_loop
|
||||
_buf_read_end:
|
||||
stw zero, bpr, 8 // return 0 (success)
|
||||
pop rg3
|
||||
pop rg2
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
_buf_read_err:
|
||||
lli 1, rg0
|
||||
stw rg0, bpr, 8 // return 1 (error)
|
||||
pop rg3
|
||||
pop rg2
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user