and3rson wrote:
This thread totally nerd-sniped me. I decided to go for time efficiency and implement a solution similar to Chromatix's idea of a decision-based algorithm that picks one of 8 cases (2 of which are invalid).
I was tempted to do some self-modifying code magic (opcodes of "STY/STA/STX zp" and "LDY/LDA/LDX zp" are dangerously close to each other, and they all differ only with 2 lowest bits!
) - but I didn't have guts to make any use of that...
I was tempted to do some self-modifying code magic (opcodes of "STY/STA/STX zp" and "LDY/LDA/LDX zp" are dangerously close to each other, and they all differ only with 2 lowest bits!
Code: Select all
STA .addr_low
.addr_low = *+1
JMP (.table)and3rson wrote:
EDIT: Turns out `reorder` macro can be easily improved:
Code: Select all
!macro reorder .aa, .bb, .cc {
!if .aa != zp0 {
LDA zp0
}
!if .cc != zp2 {
LDX zp2
}
!if .aa != zp0 {
STA .aa
}
!if .bb != zp1 {
; Y is already loaded with zp1
STY .bb
}
!if .cc != zp2 {
STX .cc
}
}
EDIT: Actually, using the 6502 indirect jump leaves X register free which we can use to store zp0, reducing the size of the reorder operations. 75 bytes, ~48 cycles average.
Revised version for reference:
Code: Select all
zp0 = $02
zp1 = $03
zp2 = $04
!macro reorder .aa, .bb, .cc {
!if .cc != zp2 {
LDA zp2
}
!if .aa != zp0 {
STX .aa
}
!if .bb != zp1 {
STY .bb
}
!if .cc != zp2 {
STA .cc
}
}
* = $0200
; table at start of page
.table
!word .swap0 ; zp0 < zp1, zp0 < zp2, zp1 < zp2
!word .swap2 ; zp0 < zp1, zp0 < zp2, zp1 >= zp2
!word 0 ; zp0 < zp1, zp0 >= zp2, zp1 < zp2 - not possible
!word .swap3 ; zp0 < zp1, zp0 >= zp2, zp1 >= zp2
!word .swap4 ; zp0 >= zp1, zp0 < zp2, zp1 < zp2
!word 0 ; zp0 >= zp1, zp0 < zp2, zp1 >= zp2 - not possible
!word .swap5 ; zp0 >= zp1, zp0 >= zp2, zp1 < zp2
!word .swap7 ; zp0 >= zp1, zp0 >= zp2, zp1 >= zp2
.sort
LDA #0
LDX zp0
CPX zp1
ROL ; 1 if zp0 >= zp1
CPX zp2
ROL ; 1 if zp0 >= zp2
LDY zp1
CPY zp2
ROL ; 1 if zp1 >= zp2
ASL
STA .addr_low
.addr_low = *+1
JMP (.table)
.swap2
+reorder zp0, zp2, zp1
.swap0
RTS
.swap3
+reorder zp1, zp2, zp0
RTS
.swap4
+reorder zp1, zp0, zp2
RTS
.swap5
+reorder zp2, zp0, zp1
RTS
.swap7
+reorder zp2, zp1, zp0
RTS