Subj : Re: Plus 4 rom error - is there any place to report it?
To   : All
From : George
Date : Fri Nov 19 2021 05:29 pm

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 | Fido<>Usenet Gateway (3:770/3)