Date : Sat, 21 Mar 2009 18:03:34 +0000 (GMT)
From : debounce@... (Greg Cook)
Subject: BBC register shuffling
On Friday, 20 March, 2009, 12:34 AM, Tom Seddon <tom@...>
wrote:
> The following should do the trick,
> though it's all off the cuff. It
> requires 1 byte of working storage and assuming your byte
> is in zero page
> it's (I think...) 7 bytes shorter. I label the bits as
> follows:
>
> B+: --RIDS10
> M128: --DS2R10
>
> R=reset, I=interrupt, D=density select, 2/1/0=drive select
> bits.
>
> So, with comments showing value in A ("."=0, "-"=unknown):
>
> PHA
> ; --RIDS10
> AND #%00000011 ;
> ......10
> STA TMP
> ; ......10
> PLA
> ; --RIDS10
> AND #%00101100 ;
> ..R.DS..
> ASL A
> ; .R.DS...
> ASL A
> ; R.DS....
> BPL FINALIZE
> ORA #%00000100 ;
> R.DS.R..
> .FINALIZE
> ORA TMP
> ; R.DS.R10
>
> This always leaves drive select 2 reset (for obvious
> reasons) and bit 7
> set to the old value of R (under the assumption the value
> doesn't matter).
By using EOR #%10000100 instead of ORA #%00000100 the top two bits can be
returned cleared.
Here is also a 16 byte routine that leaves bit 7 set to r but takes constant
time:
PHA \ ? ??ridsba
AND #&2C \ ? ..r.ds..
CMP #&20 \ r ..r.ds..
ADC #&00 \ . ..r.ds.r
ASL A
ASL A \ . r.ds.r..
STA tmp
PLA
AND #&03 \ . ......ba
ORA tmp \ . r.ds.rba
Also 16 bytes and constant time but not using bit shift instructions:
PHA \ ? ??ridsba
AND #&2C \ ? ..r.ds..
CMP #&20 \ r ..r.ds..
ADC #&40 \ . .1r.ds.r
STA tmp
PLA
AND #&03 \ . ......ba
.add ADC tmp
BCC add
Or you could go for a table-driven converter so that other controllers can
be supported later. The Opus interfaces show that one or other drive select
line can always be set and so the table only needs 8 entries, addressed by
%dsb, plus one for resetting.
AND #&2E \ ? ..r.dsb.
LSR A \ . ...r.dsb
STA tmp
CMP #&10 \ r ...r.dsb
LDA #&00
ADC #&17 \ . ...1rRRR
ORA tmp \ . ...1rdsb
STX tmp
TAX
LDA rtab-&17,X
LDX tmp
With branching and a free X register the code is no larger than the original:
AND #&2E \ ..r.dsb.
LSR
TAX
LDA #&01 \ reset
CPX #&10
BCC next
LDA ltab-&10,X
.next ...
\.rtab EQUB &01 \ reset
.ltab EQUB &05 \ double density, side 0, unit 0
EQUB &06 \ double density, side 0, unit 1
EQUB &15 \ double density, side 1, unit 0
EQUB &16 \ double density, side 1, unit 1
EQUB &25 \ single density, side 0, unit 0
EQUB &26 \ single density, side 0, unit 1
EQUB &35 \ single density, side 1, unit 0
EQUB &36 \ single density, side 1, unit 1
Thanks to 'bogax' on the 6502.org forums for revealing the power of ADC ;)
Greg Cook
debounce@...
http://homepages.tesco.net/rainstorm/