<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
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/


      
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>