Re: RS-232 on VIC-20

From: Christian Johansson (c64_at_comhem.se)
Date: 2004-06-21 19:08:56

> Has anyone ported the Hug RS-232 routines to the VIC?
> Also, has anyone built a 6551 cart for the VIC?
>
> I was going to do both for a prj I have in mind, but no sense
> re-inventing the wheel.
>
> Jim
>
Unfortunately, I don't have an answer to that question. However, I have a
similar question: Has anybody been able to use the Hug RS-232 routines to
get 4800 bps on the C128? I think it should be possible since if it is
possible to achieve 2400 bps on the C64 in 1 MHz with the routines, it
should also be possible to achieve 4800 bps on the C128 in 2 MHz (with the
built-in Kernal routines it is only possible to get 2400 bps in 2 MHz on the
C128 and 1200 bps in 1 MHz on the C64). I think it should mainly be a matter
of changing the bit times below to get 4800 bps working on the C128 in 2 MHz
mode but since I don't understand how the bit times have been calculated I
don't know what to set them to. Perhaps, the answer is in Transactor , Vol
9, Issue 3 but nobody has scanned it yet :-(. Apart from that, there is
already a flag for C128 mode.

Here is the code:

;       Start bit times.
;
strt24  .word   459     ; 2400
strt12  .word   1090    ; 1200
strt03  .word   4915    ;  300
;
;       Full bit times.
;
full24  .word   421     ; 2400
full12  .word   845     ; 1200
full03  .word   3410    ;  300

--------------------------------------------------------------
;
;  NEWMODEM.SRC
;
;  Routines by George Hug
;  Transactor, Vol 9, Issue 3
;
;  Modified 9-26-90 by Fuzzy Fox to
;  allow 7 bits plus parity to be
;  sent.  Multiple stops bits are
;  still not supported.
;
;-----------------------------------
;
;       Set the following flag to 1
;       for C128 mode.
;
c128    =       0
;
        .ifn    c128    ; C128 mode
;
ctrlreg1 =      $0a10
ctrlreg2 =      $0a11
ribuf   =       $c8
robuf   =       $ca
baudof  =       $0a16
ridbe   =       $0a18
ridbs   =       $0a19
rodbs   =       $0a1a
rodbe   =       $0a1b
enabl   =       $0a0f
rstkey  =       $fa4b
norest  =       $fa5f
return  =       $ff33
oldout  =       $ef79
oldchk  =       $f10e
ochrin  =       $ef06
ogetin  =       $eeeb
findfn  =       $f202
devnum  =       $f212
nofile  =       $f682
;
        *=      $1900   ; Start addr
;
        .else           ; C64 mode
;
ctrlreg1 =      $0293
ctrlreg2 =      $0294
ribuf   =       $f7
robuf   =       $f9
baudof  =       $0299
ridbe   =       $029b
ridbs   =       $029c
rodbs   =       $029d
rodbe   =       $029e
enabl   =       $02a1
rstkey  =       $fe56
norest  =       $fe72
return  =       $febc
oldout  =       $f1ca
oldchk  =       $f21b
ochrin  =       $f157
ogetin  =       $f13e
findfn  =       $f30f
devnum  =       $f31f
nofile  =       $f701
;
        *=      $cd00
;
        .endif
;
;-----------------------------------
;
;       Jump table.
;
xx00    jmp     setup
xx03    jmp     inable
xx06    jmp     disabl
xx09    jmp     rsget
xx0c    jmp     rsout
;
;       Start bit times.
;
strt24  .word   459     ; 2400
strt12  .word   1090    ; 1200
strt03  .word   4915    ;  300
;
;       Full bit times.
;
full24  .word   421     ; 2400
full12  .word   845     ; 1200
full03  .word   3410    ;  300
;
;-----------------------------------
;
setup
        .ifn    c128    ; C128 mode.
        lda     #<nmi128
        ldy     #>nmi128
        .else           ; C64 mode.
        lda     #<nmi64
        ldy     #>nmi64
        .endif
        sta     $0318
        sty     $0319
        lda     #<nchkin
        ldy     #>nchkin
        sta     $031e
        sty     $031f
        lda     #<nbsout
        ldy     #>nbsout
        sta     $0326
        sty     $0327
        lda     #<nchrin
        ldy     #>nchrin
        sta     $0324
        sty     $0325
        lda     #<ngetin
        ldy     #>ngetin
        sta     $032a
        sty     $032b
        rts
;
;-----------------------------------
;
        .ife    c128    ; C64 mode.
;
nmi64   pha             ; Must save registers
        txa             ;  on the C64.
        pha
        tya
        pha
        .endif
;
nmi128  cld
        ldx     $dd07   ; Sample timer B high byte.
        lda     #$7f    ; Disable CIA NMI's.
        sta     $dd0d
        lda     $dd0d   ; Read/clear flags.
        bpl     notcia  ; (Restore key).
        cpx     $dd07   ; Timer B timeout?
        ldy     $dd01   ; Sample pin C.
        bcs     mask    ; No Timer B timout.
        ora     #$02    ; Yes, set flag in Acc.
        ora     $dd0d   ; Read/clear flags again.
mask    and     enabl   ; Mask out non-enabled.
        tax             ; These must be serviced.
        lsr     a       ; Timer A? (Bit 0).
        bcc     ckflag  ; No
        lda     $dd00   ; Yes, put bit on pin M.
        and     #$fb
        ora     $b5
        sta     $dd00
ckflag  txa
        and     #$10    ; Flag NMI? (Bit 4).
        beq     nmion   ; No.
strtlo  lda     #$42    ; Yes, Start bit to Timer B.
        sta     $dd06
strthi  lda     #$04    ; These values are self-modifying.
        sta     $dd07
        lda     #$11    ; Start Timer B counting.
        sta     $dd0f
        lda     #$12    ; Flag NMI off, Timer B on.
        eor     enabl   ; Update mask.
        sta     enabl
        sta     $dd0d   ; Enable new configuration.
fulllo  lda     #$4d    ; Change reload latch.
        sta     $dd06   ;  to full-bit time.
fullhi  lda     #$03    ; These values are self-modifying.
        sta     $dd07
        lda     #$08    ; Number of bits to receive.
        sta     $a8
        bne     chktxd  ; Branch always.
notcia  ldy     #$00
        jmp     rstkey  ; or JMP NOREST to disable Restore.
nmion   lda     enabl   ; Re-enable NMI's.
        sta     $dd0d
        txa
        and     #$02    ; Timer B? (Bit 1).
        beq     chktxd  ; No.
        tya             ; Yes, sampled from way back when.
        lsr     a
        ror     $aa     ; RS232 is LSB first.
        dec     $a8     ; Byte finished?
        bne     txd     ; No.
        ldy     ridbe   ; Yes, put byte to buffer.
        lda     $aa
        sta     (ribuf),y ; (No over-run test!)
        inc     ridbe
        lda     #$00    ; Stop Timer B.
        sta     $dd0f
        lda     #$12    ; Timer B NMI off, Flag on.
switch  ldy     #$7f    ; Disable NMI's.
        sty     $dd0d
        sty     $dd0d   ; Twice.
        eor     enabl   ; Update mask.
        sta     enabl
        sta     $dd0d   ; Enable new config.
txd     txa
        lsr     a       ; Timer A?
chktxd  bcc     exit    ; No.
        dec     $b4     ; Yes, byte finished?
        bmi     char    ; Yes.
        lda     #$04    ; No, prep next bit.
        ror     $b6     ; (Fill with stop bits).
        bcs     store
low     lda     #$00
store   sta     $b5
exit    jmp     return  ; Restore regs, RTI.
char    ldy     rodbs
        cpy     rodbe   ; Buffer empty?
        beq     txoff   ; Yes.
getbuf  lda     (robuf),y ; No, prep next byte.
        inc     rodbs
        sta     $b6
        lda     #$09    ; Number of bits to send.
        sta     $b4
        bne     low     ; Always - do start bit.
txoff   ldx     #$00    ; Stop Timer A.
        stx     $dd0e
        lda     #$01    ; Disable Timer A NMI.
        bne     switch  ; Always.
;
;-----------------------------------
;
disabl  pha             ; Turns off modem port.
test    lda     enabl
        and     #$03    ; Any current activity?
        bne     test    ; Yes, test again.
        lda     #$10    ; No, disable Flag NMI.
        sta     $dd0d
        lda     #$02
        and     enabl   ; Currently receiving?
        bne     test    ; Yes, start over.
        sta     enabl   ; All off, update mask.
        pla
        rts
;
;-----------------------------------
;
nbsout  pha             ; New BSOUT.
        lda     $9a
        cmp     #$02
        bne     notmod
        pla
rsout   sta     $9e     ; Output to modem.
        sty     $97
;                       ---- Patch by Fox ----
        lda     #$20
        bit     ctrlreg2 ; Parity being generated?
        beq     point    ; No, so send the full 8 bits.
        php              ; Save flag settings.
        lda     $9e
        and     #$7f    ; Set byte to 7 bits.
        tay
        plp             ; Restore flags.
        bmi     10$     ; Mark/Space parity.
        lda     parity,y
10$     bvs     90$
        eor     #$80    ; Flip parity if wrong sense.
90$     sta     $9e     ; ---- End Patch ----
point   ldy     rodbe
        lda     $9e
        sta     (robuf),y ; Not official yet.
        iny
        cpy     rodbs   ; Buffer full?
        beq     fulbuf  ; Yes.
        sty     rodbe   ; No, bump pointer.
strtup  lda     enabl
        and     #$01    ; Transmitting now?
        bne     ret3    ; Yes.
        sta     $b5     ; No, prep start bit.
        lda     #$09
        sta     $b4     ; Number of bits to send.
        ldy     rodbs
        lda     (robuf),y
        sta     $b6     ; and next byte.
        inc     rodbs
        lda     baudof  ; Full Tx bit time to Timer A.
        sta     $dd04
        lda     baudof+1
        sta     $dd05
        lda     #$11    ; Start Timer A.
        sta     $dd0e
        lda     #$81    ; Enable Timer A NMI.
change  sta     $dd0d   ; NMI clears flag if set.
        php             ; Save IRQ status.
        sei             ; Disable IRQ's.
        ldy     #$7f    ; Disable NMI's.
        sty     $dd0d
        sty     $dd0d   ; Twice.
        ora     enabl   ; Update mask.
        sta     enabl
        sta     $dd0d   ; Enable new configuration.
        plp             ; Restore IRQ status.
ret3    clc
        ldy     $97
        lda     $9e
        rts
fulbuf  jsr     strtup
        jmp     point
notmod  pla             ; Back to old BSOUT.
        jmp     oldout
;
;-----------------------------------
;
nchkin  jsr     findfn  ; New CHKIN.
        bne     nosuch
        jsr     devnum
        lda     $ba
        cmp     #$02
        bne     back
        sta     $99
inable  sta     $9e     ; Enable RS232 input.
        sty     $97
baud    lda     baudof+1 ; Set receive to same
        and     #$06     ;  baud rate as xmit.
        tay
        lda     strt24,y
        sta     strtlo+1 ; Self-mod
        lda     strt24+1,y
        sta     strthi+1
        lda     full24,y
        sta     fulllo+1
        lda     full24+1,y
        sta     fullhi+1
        lda     enabl
        and     #$12    ; Flag or Timer B on?
        bne     ret1    ; Yes.
        sta     $dd0f   ; No, stop Timer B.
        lda     #$90    ; Turn on Flag NMI.
        jmp     change
nosuch  jmp     nofile
back    lda     $ba
        jmp     oldchk
;
;-----------------------------------
;
nchrin  lda     $99     ; New CHRIN.
        cmp     #$02
        beq     rsget
        jmp     ochrin
ngetin  lda     $99     ; New GETIN.
        cmp     #$02
        beq     rsget
        jmp     ogetin
;
rsget   sta     $9e     ; Input from modem.
        sty     $97
        ldy     ridbs
        cpy     ridbe   ; Buffer empty?
        beq     ret2    ; Yes.
        lda     (ribuf),y ; No, fetch character.
        sta     $9e
;                       ---- Patch by Fox ----
        ldy     ctrlreg2 ; Parity expected?
        cpy     #$20
        bcc     10$      ; No, so keep all 8 bits.
        and     #$7f    ; Otherwise reduce to 7 bits.
        sta     $9e
10$                     ; ---- End Patch ----
        inc     ridbs
ret1    clc             ; CC = char in acc.
ret2    ldy     $97
        lda     $9e
last    rts             ; CS = buffer empty.
;
;-----------------------------------
;
;       This table looks up the odd parity value for a byte between 0-7F.
;       If the parity to be sent is even parity, the high bit is simply
;       toggled.
;
parity  .byte   $00,$81,$82,$03,$84,$05,$06,$87
        .byte   $88,$09,$0a,$8b,$0c,$8d,$8e,$0f
        .byte   $90,$11,$12,$93,$14,$95,$96,$17
        .byte   $18,$99,$9a,$1b,$9c,$1d,$1e,$9f
        .byte   $a0,$21,$22,$a3,$24,$a5,$a6,$27
        .byte   $28,$a9,$aa,$2b,$ac,$2d,$2e,$af
        .byte   $30,$b1,$b2,$33,$b4,$35,$36,$b7
        .byte   $b8,$39,$3a,$bb,$3c,$bd,$be,$3f
        .byte   $c0,$41,$42,$c3,$44,$c5,$c6,$47
        .byte   $48,$c9,$ca,$4b,$cc,$4d,$4e,$cf
        .byte   $50,$d1,$d2,$53,$d4,$55,$56,$d7
        .byte   $d8,$59,$5a,$db,$5c,$dd,$de,$5f
        .byte   $60,$e1,$e2,$63,$e4,$65,$66,$e7
        .byte   $e8,$69,$6a,$eb,$6c,$ed,$ee,$6f
        .byte   $f0,$71,$72,$f3,$74,$f5,$f6,$77
        .byte   $78,$f9,$fa,$7b,$fc,$7d,$7e,$ff
;
        .end


       Message was sent through the cbm-hackers mailing list

Archive generated by hypermail pre-2.1.8.