FR0 = $d4 ; float48 PORTB = $d301 EXTENDED_RAM = $4000 ; 16KiB bank on the XE ; lookup table for top byte -> PORTB value for bank-switch .align 256 bankswitch: .repeat 256, i .byte ((i & $c0) >> 5) | $c1 .endrepeat ; 58-77 cycles ; clobbers x, y, dest to dest + 3 .macro imul8xe dest, arg1, arg2 .local done .local output .local ptr output = dest ptr = dest + 2 ; scratch space assumed ; bottom 14 bits except the LSB are the per-bank table index ; add $4000 for the bank pointer lda arg1 ; 3 cyc and #$fe ; 2 cyc sta ptr ; 3 cyc lda arg2 ; 3 cyc and #$3f ; 2 cyc clc ; 2 cyc adc #$40 ; 2 cyc sta ptr + 1 ; 3 cyc ; top 2 bits are the table bank selector ldx arg2 ; 3 cyc lda bank_switch,x ; 4 cyc sta PORTB ; 4 cyc ; copy the entry into output ldy #0 ; 2 cyc lda (ptr),y ; 5 cyc sta output ; 3 cyc iny ; 2 cyc lda (ptr),y ; 5 cyc sta output+1 ; 3 cyc ; note: we are not restoring memory to save 6 cycles! ; this means those 16kb have to be switched back to base RAM ; if we need to use them anywhere else ;;; restore memory ;;lda #$81 ; 2 cyc - disabled ;;sta PORTB ; 4 cyc - disabled ; check that 1 bit we skipped to fit into space lda arg1 ; 3 cyc and #1 ; 2 cyc beq done ; 2 cyc ; add the second param one last time for the skipped bit clc ; 2 cyc lda arg2 ; 3 cyc adc output ; 3 cyc sta output ; 3 cyc lda #0 ; 2 cyc adc output+1 ; 3 cyc sta output+1 ; 3 cyc done: .endmacro proc imul8xe_init rts endproc