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)