ZX Spectrum > PROGRAMOWANIE

RS-232 w Spectrum +3

<< < (2/2)

matofesi:
Z rzutu okiem w procedury obsługi RSa w obu ROMach - jest dokładnie tak samo. W +3 jest tylko na początku sprawdzenie, czy procedura (ta bardziej ogólna) ma czytać/pisać z/do RSa czy z/do Centronicsa, ale dalej sam fizyczny odczyt i zapis jest realizowany identycznym kodem.

To jest odczyt bajtu (tablica na początku to baudrate'y):


--- Kod: ---.l1e50  defw    $0032,$0aa5     ; 50
        defw    $006e,$04d4     ; 110
        defw    $012c,$01c3     ; 300
        defw    $0258,$00e0     ; 600
        defw    $04b0,$006e     ; 1200
        defw    $0960,$0036     ; 2400
        defw    $12c0,$0019     ; 4800
        defw    $2580,$000b     ; 9600

        di     
        exx     
        ld      de,(BAUD) ; DE=BAUD
        ld      hl,(BAUD)
        srl     h
        rr      l ; HL=BAUD/2
        or      a
        ld      b,$fa ; B=timing constant
        exx     
        ld      c,$fd
        ld      d,$ff
        ld      e,$bf
        ld      b,d
        ld      a,$0e
        out     (c),a ; select AY register 14
        in      a,(c) ; get RS232/AUX value
        or      $f0
        and     $fb ; set CTS low
        ld      b,e
        out     (c),a ; output CTS low
        ld      h,a ; save RS232/AUX value with CTS low
.l1eb2  ld      b,d
        in      a,(c) ; get RS232/AUX value
        and     $80
        jr      z,l1ec2         ; move on if TXD was low (ie data ready)
.l1eb9  exx
        dec     b ; decrement timer
        exx     
        jr      nz,l1eb2        ; loop back
        xor     a ; carry reset for no data
        push    af
        jr      l1efb           ; move on if no data received
.l1ec2  in      a,(c)
        and     $80
        jr      nz,l1eb9        ; back if TXD high
        in      a,(c)
        and     $80
        jr      nz,l1eb9 ; back if TXD high
        exx     
        ld      bc,$fffd
        ld      a,$80 ; A'=char to build (carry will be set when
        ex      af,af' ; all 8 bits have been read)
.l1ed5  add     hl,de
        nop     
        nop     
        nop     
        nop     
.l1eda  dec     hl
        ld      a,h
        or      l
        jr      nz,l1eda ; baud rate timing loop
        in      a,(c) ; get RS232/AUX data
        and     $80 ; mask data bit
        jp      z,l1eef ; move on if zero
        ex      af,af'
        scf     
        rra ; rotate a 1 bit in     
        jr      c,l1ef8 ; move on if byte complete
        ex      af,af'
        jp      l1ed5 ; loop back for more bits
.l1eef  ex      af,af'
        or      a
        rra      ; rotate a 0 bit in
        jr      c,l1ef8 ; move on if byte complete
        ex      af,af'
        jp      l1ed5 ; loop back for more bits
.l1ef8  scf ; carry set for data received
        push    af
        exx     
.l1efb  ld      a,h
        or      $04
        ld      b,e
        out     (c),a ; set RS232 CTS high
        exx     
        ld      h,d
        ld      l,e ; HL=BAUD
        ld      bc,$0007
        or      a
        sbc     hl,bc
.l1f0a  dec     hl
        ld      a,h
        or      l
        jr      nz,l1f0a ; timing loop
        ld      bc,$fffd
        add     hl,de
        add     hl,de
        add     hl,de
.l1f15  in      a,(c)
        and     $80
        jr      z,l1f23 ; move on if TXD low (2nd byte available)
        dec     hl
        ld      a,h
        or      l
        jr      nz,l1f15 ; timing loop
        pop     af ; restore value
        ei     
        ret      ; exit
.l1f23  in      a,(c)
        and     $80
        jr      nz,l1f15 ; move back if TXD high
        in      a,(c)
        and     $80
        jr      nz,l1f15 ; move back if TXD high
        ld      h,d
        ld      l,e
        ld      bc,$0002
        srl     h
        rr      l
        or      a
        sbc     hl,bc
        ld      bc,$fffd
        ld      a,$80 ; prepare 2nd byte in A'
        ex      af,af'
.l1f41  nop
        nop     
        nop     
        nop     
        add     hl,de
.l1f46  dec     hl
        ld      a,h
        or      l
        jr      nz,l1f46 ; timing loop
        in      a,(c)
        and     $80 ; test bit
        jp      z,l1f5b ; move on if zero
        ex      af,af'
        scf     
        rra      ; rotate a 1 bit in
        jr      c,l1f64 ; move on if byte complete
        ex      af,af'
        jp      l1f41 ; back for more bits
.l1f5b  ex      af,af'
        or      a
        rra      ; rotate a 0 bit in
        jr      c,l1f64 ; move on if byte complete
        ex      af,af'
        jp      l1f41 ; back for more bits
.l1f64  ld      hl,SERFL
        ld      (hl),$01 ; flag "2nd byte available"
        inc     hl
        ld      (hl),a ; store 2nd byte
        pop     af ; restore the 1st byte
        ei     
        ret      ; done

--- Koniec kodu ---

Wysłanie bajtu:


--- Kod: ---
        in      a,(c)           ; read RS232/AUX
        and     $40
        jr      nz,l2067        ; loop until DTR low
        ld      hl,(BAUD)
        ld      de,$0002
        or      a
        sbc     hl,de
        ex      de,hl           ; DE=BAUD-2
        pop     af              ; restore character
        cpl                     ; invert it
        scf                     ; set carry for initial bit
        ld      b,$0b           ; 11 bits to output
        di                      ; disable interrupts
.l2080  push    bc              ; save registers
        push    af
        ld      a,$fe
        ld      h,d             ; HL=BAUD-2
        ld      l,e
        ld      bc,$bffd
        jp      nc,l2092        ; move on to output a one bit
        and     $f7             ; mask RS232 RXD off
        out     (c),a           ; output zero bit to RS232
        jr      l2098
.l2092  or      $08             ; set RS232 RXD on
        out     (c),a           ; output one bit to RS232
        jr      l2098
.l2098  dec     hl
        ld      a,h
        or      l
        jr      nz,l2098        ; timing loop for baud rate
        nop                     ; more timing values
        nop     
        nop     
        pop     af              ; restore registers
        pop     bc
        or      a               ; clear carry (for stop bits)
        rra                     ; rotate next bit
        djnz    l2080           ; loop back for more
        ei     
        ret     

--- Koniec kodu ---

Oba kawałki wyrwane z romu +3. I oczywiście dobre o ile się nie walnąłem ;)

Gryzor:
Na WoS jest watek o programowaniu RS-232 i max speed do PC.
Ktos robil testy ile da sie wyciagnac.
Szkoda, ze +3 nie ma dwukierunkowego Centronicsa, wtedy moznaby uzyc kabla typu LapLink.

Duddie:
Gryzor, podasz linka? Nie mogę tego znaleźć....

Gryzor:
http://www.worldofspectrum.org/forums/showthread.php?t=34291

Nawigacja

[0] Indeks wiadomości

[*] Poprzednia strona

Idź do wersji pełnej