You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
2.0 KiB
133 lines
2.0 KiB
4 years ago
|
include "hardware.inc"
|
||
|
|
||
|
section "home/serial.asm@hram", hram
|
||
|
h_serial_len: dw
|
||
|
h_serial_send_ptr: dw
|
||
|
h_serial_recv_ptr: dw
|
||
|
|
||
|
section "home/serial.asm@int58", rom0[$58]
|
||
|
push af
|
||
|
push hl
|
||
|
push bc
|
||
|
push de
|
||
|
jp serial_shift_int
|
||
|
|
||
|
section "home/serial.asm", rom0
|
||
|
|
||
|
serial_shift_int:
|
||
|
call serial_shift
|
||
|
pop de
|
||
|
pop bc
|
||
|
pop hl
|
||
|
pop af
|
||
|
reti
|
||
|
|
||
|
serial_end:
|
||
|
|
||
|
serial_shift:
|
||
|
ldh a, [h_serial_len + 0]
|
||
|
ld c, a
|
||
|
ldh a, [h_serial_len + 1]
|
||
|
ld b, a
|
||
|
|
||
|
; End early if we're done
|
||
|
or c
|
||
|
ret z
|
||
|
|
||
|
ldh a, [h_serial_recv_ptr + 0]
|
||
|
ld e, a
|
||
|
ldh a, [h_serial_recv_ptr + 1]
|
||
|
ld d, a
|
||
|
|
||
|
; Store the last received byte
|
||
|
or e
|
||
|
jr z, .no_recv
|
||
|
ldh a, [r_sb]
|
||
|
ld [de], a
|
||
|
inc de
|
||
|
.no_recv
|
||
|
|
||
|
; We've transferred an entire byte in both directions
|
||
|
dec bc
|
||
|
|
||
|
ldh a, [h_serial_send_ptr + 0]
|
||
|
ld l, a
|
||
|
ldh a, [h_serial_send_ptr + 1]
|
||
|
ld h, a
|
||
|
|
||
|
; fallthrough
|
||
|
|
||
|
serial_queue:
|
||
|
; If the length is 0, not much should be done
|
||
|
ld a, b
|
||
|
or c
|
||
|
jr z, .empty
|
||
|
|
||
|
ld a, h
|
||
|
or l
|
||
|
ld a, -1
|
||
|
jr z, .no_send
|
||
|
ld a, [hli]
|
||
|
.no_send
|
||
|
ldh [r_sb], a
|
||
|
|
||
|
ldh a, [r_sc]
|
||
|
set r_sc_start_f, a
|
||
|
jr .store
|
||
|
|
||
|
.empty
|
||
|
ldh a, [r_sc]
|
||
|
res r_sc_start_f, a
|
||
|
|
||
|
.store
|
||
|
ldh [r_sc], a
|
||
|
|
||
|
ld a, c
|
||
|
ldh [h_serial_len + 0], a
|
||
|
ld a, b
|
||
|
ldh [h_serial_len + 1], a
|
||
|
|
||
|
ld a, e
|
||
|
ldh [h_serial_recv_ptr + 0], a
|
||
|
ld a, d
|
||
|
ldh [h_serial_recv_ptr + 1], a
|
||
|
|
||
|
ld a, l
|
||
|
ldh [h_serial_send_ptr + 0], a
|
||
|
ld a, h
|
||
|
ldh [h_serial_send_ptr + 1], a
|
||
|
|
||
|
ret
|
||
|
|
||
|
serial_finished::
|
||
|
; ret: z if done, nz if not done
|
||
|
ldh a, [r_sc]
|
||
|
bit r_sc_start_f, a
|
||
|
ret
|
||
|
|
||
|
serial_transfer::
|
||
|
; hl: Source buffer
|
||
|
; de: Destination buffer
|
||
|
; bc: Size
|
||
|
; ret: nz if previous transfer is still in transit
|
||
|
call serial_finished
|
||
|
ret nz
|
||
|
jp serial_queue
|
||
|
|
||
|
serial_init_master::
|
||
|
ld a, 1
|
||
|
db $fe ; CP A, n8
|
||
|
|
||
|
serial_init_slave::
|
||
|
xor a
|
||
|
|
||
|
; fallthrough
|
||
|
|
||
|
serial_init:
|
||
|
ldh [r_sc], a
|
||
|
|
||
|
ldh a, [r_ie]
|
||
|
set r_int_serial_f, a
|
||
|
ldh [r_ie], a
|
||
|
ret
|