Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

    module Uart
    assert $ > #8000 ;; Important keep it in FAST memory
init:
    di
    ld a, #07
    ld bc, #fffd
    out (c), a
    ld a, #fc
    ld b, #bf
    out (c), a ; Enable read mode
   
    ld a, #0e
    ld bc, #fffd
    out (c), a

    ld b, #bf
    in a, (c)
    and #fb
    out (c), a ; Make CTS low

    ei
    ld b, #ff
.flush
    halt
    djnz .flush
    ret


write:
    push hl, de, bc
    push af
    ld c, #fd ; prepare port addresses
    ld d, #ff
    ld e, #bf
    ld b, d
   
    ld a, #0e
    out (c), a ; Select AY's PORT A

    ld hl, (_baud)
    ld de, #0002
    or a
    sbc hl, de
    ex hl, de

    pop af
    cpl
    scf
    ld b, #0b ; Numbers of bits - 1 start, 8 data, 2 stop

    di ; Hard timing starts
transmitBit:
    push bc
    push af

    ld a, #fe
    ld h, d
    ld l, e
    ld bc, #bffd
    jp nc, transmitOne
; Transmit Zero:
    and #f7
    out (c), a
    jr transmitNext
transmitOne:
    or 8
    out (c), a
    jr transmitNext

transmitNext:
    dec hl
    ld a, h
    or l
    jr nz, transmitNext
   
    nop
    nop
    nop

    pop af
    pop bc
    or a
    rra
    djnz transmitBit
    exx
    ei
    pop bc, de, hl
    ret

read:
    push bc, de, hl
    call uartRead
    pop hl, de, bc
    ret c
    jr read

uartRead:
    ld hl, _isSecondByteAvail
    ld a, (hl)
    and a
    jr z, startReadByte
    ld (hl), 0
    inc hl
    ld a, (hl)
    scf
    ret
startReadByte:
    di
    xor a
    exx
    ld de, (_baud)
    ld hl, (_baud)
    srl h
    rr l  ; HL=_baud/2
    or a
    ld b, #FA ; Wait look length
    exx
    ld c, #fd
    ld d, #ff
    ld e, #bf
    ld b, d
    ld a, #0e
    out (c), a
    in a, (c)
    or #f0      ; Input lines is 1
    and #fb     ; CTS force to 0
    ld b, e     ; B = #BF
    out (c), a  ; Make CTS high
    ld h, a

waitStartBit:
    ld b, d
    in a, (c)
    and #80
    jr z, startBitFound
readTimeOut:
    exx
    dec b
    exx
    jr nz, waitStartBit
    xor a
    push af
    jr readFinish
startBitFound:
    in a, (c)
    and #80
    jr nz, readTimeOut

    in a, (c)
    and #80
    jr nz, readTimeOut
    ;; Start bit found!
   
    exx
    ld bc, #fffd
    ld a, #80
    ex af, af
readTune:
    add hl, de ; HL = 1.5 * _baud
    nop
    nop
    nop
    nop ; Fine tuning delay

bdDelay:
    dec hl
    ld a, h
    or l
    jr nz, bdDelay

    in a, (c)
    and #80
    jp z, zeroReceived
; One received:      
    ex af, af
    scf
    rra
    jr c, receivedByte
    ex af, af
    jp readTune
zeroReceived:
    ex af, af
    or a
    RRA
    jr c, receivedByte
    ex af, af
    jp readTune
receivedByte:
    scf
    push af
    exx
readFinish:
    ld a, h
    or #04
    ld b, e
    out (c), a
   
    exx
    ld h, d
    ld l, e

    ld bc, #0007
    or a
    sbc hl, bc

delayForStopBit:
    dec hl
    ld a, h
    or l
    jr nz, delayForStopBit

    ld bc, #fffd
    add hl, de
    add hl, de
    add hl, de

waitStartBitSecondByte:
    in a, (c)
    and #80
    jr z, secondStartBitFound
    dec hl
    ld a, h
    or l
    jr nz, waitStartBitSecondByte
    ; No second byte
    pop af
    ei
    ret

secondStartBitFound:
    in a, (c)
    and #80
    jr nz, waitStartBitSecondByte
    ld h, d
    ld l, e
    ld bc, #0002
    srl h
    rr l
    or a
    sbc hl, bc
    ld bc, #fffd
    ld a, #80
    ex af, af
secondByteTune:
    nop
    nop
    nop
    nop
    add hl, de

secondDelay:
    dec hl
    ld a, h
    or l
    jr nz, secondDelay

    in a, (c)
    and #80
    jr z, secondZeroReceived
; Second 1 received    
    ex af, af
    scf
    rra
    jr c, secondByteFinished
    ex af, af
    jp secondByteTune

secondZeroReceived:
    ex af, af
    or a
    rra
    jr c, secondByteFinished
    ex af, af
    jp secondByteTune
secondByteFinished:
    ld hl, _isSecondByteAvail
    ld (hl), 1
    inc hl
    ld (hl), a
    pop af
    ei
    ret


_baud dw 11 ; 54 - 2400 --- 25 - 4800 --- 11 - 9600
_isSecondByteAvail dw #0
_testByte dw #0

    endmodule