TIP: Click on subject to list as thread! ANSI
echo: cbm
to: All
from: George
date: 2021-11-19 17:29:00
subject: Re: Plus 4 rom error - is

Jim Brain says...

 > It might make sense to write up a bit more of the
 > disassembly with your notes to create clarity.

See below.

 > Ah, that clears things up for me.  So, if $34 $00 were
 > the data items, the data delivered to the +4 app would
 > be $34 $34

Yes, that's right.  I think regular BBS traffic probably
wouldn't have any nulls, so for that, this problem wouldn't
make any difference.  But I think file transfers might have
lots of nulls, including any two-byte block numbers, or
two-byte checksums. And of course any program with an ML
section would have nulls all over the place (LDA #$00, STA
$FD00, and such).

Below is the relevant section of somebody's kernel source
code, and on the right side the more raw version of the same
thing showing the actual hex values.

The error results from an attempt to work software flow
control (Xon/Xoff) into the ACIA IRQ servicing routines.  If
flow control is enabled, the values normally used for Xon
and Xoff ($11 and $13 respectively) will be stored at
locations $FC and $FD.  If flow control is disabled, those
locations will contain nulls.

If flow control is disabled, a received null byte must not
be compared to $FC or $FD because a false match would be
detected, and we would be halting and resuming transmission
for no reason.  So the code branches around all the Xon/Xoff
stuff if a null is received.  But it fails to save the null
in aintmp ($07D5) before branching.  So later, when the
value in aintmp is retrieved and added to the input queue,
another copy of the last non-null byte received is what will
go into the queue.

The solution is to reverse the two instructions, so the null
is saved into aintmp, then the BEQ is performed.  The Zero
flag will not be modified by the STA instruction, so the
branch will work correctly.

ain
       lda  astat       ; acia status reg prev. saved    LEA95   LDA   $07D4
       and  #$8         ; bit 3 set if char recd.                AND   #$08
       beq  rxfull      ; no char has been received              BEQ   LEAF0
       lda  astat       ; got one...reset stat bit               LDA   $07D4
       and  #$f7                                                 AND   #$F7
       sta  astat                                                STA   $07D4
       lda  acia        ; read byte                              LDA   $FD00
       beq  notacc      ; if null, skip xon/xoff                 BEQ   LEAC2

; it's a null, don't let thru for x-disable

       sta  aintmp      ; save char [unless it was a null]       STA   $07D5
       cmp  xon         ; is it a ~q                             CMP   $FC
       bne  trycs       ; nope                                   BNE   LEAB7

; got a ~q

       lda  #0                                                   LDA   #$00
       sta  alstop      ; tell local xmit to go                  STA   $07D6
       beq  rxfull      ; !bra, what character?                  BEQ   LEAF0

trycs
       cmp  xoff        ; is it a ~s                     LEAB7   CMP   $FD
       bne  notacc      ; nope                                   BNE   LEAC2

; got a ~s

       lda  #$ff                                                 LDA   #$FF
       sta  alstop      ; tell local xmit to stop                STA   $07D6
       bne  rxfull      ; !bra, i didn't see that...             BNE   LEAF0

notacc
       lda  inqcnt                                       LEAC2   LDA   $07D3
       cmp  #inpqln-1   ; is queue full                          CMP   #$3F
       beq  rxfull      ; yep                                    BEQ   LEAF0
       cmp  #hiwatr     ; high water mark                        CMP   #$38
       bne  nohw        ; nope                                   BNE   LEADC

; hit high water mark, tell sender to stop

       lda  xoff        ; x-sw is off                            LDA   $FD
       beq  nohw                                                 BEQ   LEADC
       sta  soutq       ; ~s                                     STA   $07CF
       lda  #$ff                                                 LDA   #$FF
       sta  soutfg      ; flag it present                        STA   $07D0
       sta  arstop      ; flag remote stopped                    STA   $07D7

nohw
                        ; not full, insert char
       ldx  inqfpt      ; do: inqfpt <- inqfpt+1 mod 64  LEADC   LDX   $07D1
       inx                                                       INX
       txa                                                       TXA
       and  #$3f                                                 AND   #$3F
       sta  inqfpt                                               STA   $07D1
       tax                                                       TAX
       lda  aintmp      ; get char to insert                     LDA   $07D5
       sta  inpque,x    ; insert it                              STA $03F7,x
       inc  inqcnt      ; another drop in the bucket             INC   $07D3
rxfull                  ; error exit
       rts              ; all ok                         LEAF0   RTS

--- SoupGate-Win32 v1.05
                                                                          
* Origin: Agency HUB, Dunedin - New Zealand | FidoUsenet Gateway (3:770/3)

SOURCE: echomail via QWK@pharcyde.org

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.