;Implementation of SoftMMU - xpage ;================================= .global xpage ;----- xpage: ;----- ; Do a page swap, either by changing the pointer in the memory ; structure, or banking/copying memory into the page to which ; the pointer points. ; ; <- X = zero page pointer to memory struct ; ; Memory struct (5 bytes): ; $00,X = physical 6502 pointer to memory window page ; $02,X = offset into memory chunk, in pages ; $04,X = single-byte pointer into TSP chunk descriptor ; Uses temporary zero page variables: #define banklo tmpzp+2 #define bankhi tmpzp+3 pha ;3 tya ;2 pha ;3 ldy $04,x ;4 ;get tsp pointer ;== 12 #ifndef always_sane txa ;2 cmp (lk_tsp),y ;5 bne insane ;2 ;== 9 #endif ;find the physical offset sei ;2 ;can't have anything changing clc ;2 iny ;2 lda (lk_tsp),y ;5 ;take the start of chunk adc $02,x ;4 ;add to the zeropage request sta banklo ;3 iny ;2 lda (lk_tsp),y ;5 adc $03,x ;4 sta bankhi ;3 ;== 32 ;check for segmentation fault iny ;2 lda (lk_tsp),y ;5 ;compare end of chunk cmp banklo ;3 ;to calculated physical offset iny ;2 lda (lk_tsp),y ;5 sbc bankhi ;3 bpl error_seg_fault ;2 ;== 22 ;dispatch to proper hardware routine iny ;2 lda (lk_tsp),y ;5 ;get memory source tay ;2 lda sm_xpagelo,y ;4 ;read the xpage jump table sta tmpzp ;3 lda sm_xpagehi,y ;4 sta tmpzp+1 ;3 jmp (tmpzp) ;5 ;== 28 ;== Total time to dispatch: 103 cycles ; 94 cycles w/o sanity check ;-------------- ;Error handlers ;-------------- #ifndef always_sane insane: pla pla jmp catcherr #endif error_seg_fault: pla pla jmp catcherr