cc65/libsrc/c64/emd/c64-rrr.s

364 lines
10 KiB
ArmAsm
Raw Normal View History

2016-02-28 22:37:04 +00:00
;
2022-07-24 00:47:02 +00:00
; Extended Memory Driver for the Action Replay/Retro Replay RAM
2016-02-28 22:37:04 +00:00
;
2022-07-21 01:43:54 +00:00
; original Version 1.0 by Johannes Braun 2006-08-22 <hannenz@freenet.de>
; ------------------------------------------------------------------------
2016-02-28 22:37:04 +00:00
2022-07-21 01:43:54 +00:00
.include "zeropage.inc"
.include "em-kernel.inc"
.include "em-error.inc"
.macpack generic
.macpack module
; ------------------------------------------------------------------------
c64_ram = ptr1 ; use some more expressive identifiers...
rr_ram = ptr2
len = ptr3
aux = ptr4
temp = tmp1
Lo_Mem = $0100 ; location of Lo_Code (must be below $1000 or above $e000)
2016-02-28 22:37:04 +00:00
2022-07-24 00:47:02 +00:00
RRMODE_OFF = $02
RRMODE_CART_RAM = $23
2022-07-21 01:43:54 +00:00
; ------------------------------------------------------------------------
; Header. Includes jump table
2016-02-28 22:37:04 +00:00
2022-07-21 01:43:54 +00:00
module_header _c64_rrr_emd
2016-02-28 22:37:04 +00:00
2022-07-21 01:43:54 +00:00
; Driver signature
2016-02-28 22:37:04 +00:00
2022-07-21 01:43:54 +00:00
.byte $65, $6d, $64 ; "emd"
.byte EMD_API_VERSION ; EM API version number
2016-02-28 22:37:04 +00:00
2022-07-21 01:43:54 +00:00
; Library reference
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr PAGECOUNT
.addr MAP
.addr USE
.addr COMMIT
.addr COPYFROM
.addr COPYTO
2022-07-21 01:45:40 +00:00
; ------------------------------------------------------------------------
2022-07-24 00:47:02 +00:00
; Data.
2016-02-28 22:37:04 +00:00
.bss
2022-07-24 00:47:02 +00:00
window: .res 256 ; the memory window (256 bytes)
pagecount: .res 1 ; Number of available pages
2016-02-28 22:37:04 +00:00
.rodata
2022-07-21 01:43:54 +00:00
dummy:
.word window ; a "pseudo"-em_copy_struct, used by em_map/ em_commit
.byte 0 ; to pass over to COPYTO/COPYFROM
curpage:
.byte $ff ; just this byte is changed according to the desired page
2022-07-21 01:30:47 +00:00
.byte 0
.word 256
2016-02-28 22:37:04 +00:00
.code
;----------------------------------------------------------------------------------------
;unsigned char __fastcall__ em_install(void *driver);
;returns an error code
;----------------------------------------------------------------------------------------
INSTALL:
2022-07-21 01:30:47 +00:00
ldx #c2-c1
: lda c1,x
sta Lo_Mem,x
dex
bpl :-
2022-07-24 00:47:02 +00:00
;ldx #$ff
stx curpage ; invalidate current page
2022-07-21 01:30:47 +00:00
2022-07-24 00:47:02 +00:00
ldy #RRMODE_OFF
sei
jmp Lo_Mem+8 ; jump to the code below
; copied to Lo_Mem
c1:
;detectmodes:
.byte RRMODE_CART_RAM | $00
.byte RRMODE_CART_RAM | $08
.byte RRMODE_CART_RAM | $10
.byte RRMODE_CART_RAM | $18
.byte RRMODE_CART_RAM | $80
.byte RRMODE_CART_RAM | $88
.byte RRMODE_CART_RAM | $90
.byte RRMODE_CART_RAM | $98
; first save c64 memory
2022-07-21 01:30:47 +00:00
lda $8888
pha
2022-07-24 00:47:02 +00:00
; tag c64 memory
lda #$00
sta $8888
ldx #$07
:
; try accessing rr-ram
;lda detectmodes, x
lda Lo_Mem, x
sta $de00
; tag (hopefully) rr memory
txa
ora #$80
sta $8888
dex
bpl :-
;ldy #RRMODE_OFF
sty $de00
; now if C64 memory is $80, there is no AR/RR
; if C64 memory is $00, there is a AR/RR.
lda $8888
beq detectpages
lda #0
beq hasnopages
detectpages:
; we can now read the highest available bank nr from the highest bank :)
lda #RRMODE_CART_RAM | $98
sta $de00
ldx $8888
inx
txa
; 8k = 32 pages
asl
asl
asl
asl
2022-07-21 01:30:47 +00:00
asl
2022-07-24 00:47:02 +00:00
hasnopages:
2022-07-21 01:30:47 +00:00
2022-07-24 00:47:02 +00:00
;ldy #RRMODE_OFF
sty $de00 ; c64 ram again
sta pagecount
; restore c64 memory
2022-07-21 01:30:47 +00:00
pla
sta $8888
cli
2022-07-24 00:47:02 +00:00
ldx pagecount
beq no
; no error
2022-07-21 01:30:47 +00:00
lda #0
2022-07-24 00:47:02 +00:00
tax
2022-07-21 01:30:47 +00:00
rts
2022-07-24 00:47:02 +00:00
no:
lda #4 ; return #4: error code for "device not present"
2022-07-21 01:30:47 +00:00
rts
2016-02-28 22:37:04 +00:00
c2:
2022-07-24 00:47:02 +00:00
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;void em_uninstall(void);
;----------------------------------------------------------------------------------------
UNINSTALL:
return_null:
2022-07-24 00:47:02 +00:00
lda #$00
tax
rts
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;unsigned __fastcall__ em_pagecount(void);
;----------------------------------------------------------------------------------------
PAGECOUNT:
2022-07-24 00:47:02 +00:00
lda pagecount ; always return 32kb (128 pages)
2022-07-21 01:30:47 +00:00
ldx #$00
rts
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;void* __fastcall__ em_use(unsigned page);
;----------------------------------------------------------------------------------------
2022-07-21 01:30:47 +00:00
USE:
2022-07-21 01:43:54 +00:00
cmp #$80 ; valid page?
bcs return_null ; no, return NULL pointer
sta curpage ; set to current page
return_win:
lda #<window ; return pointer to window
2022-07-21 01:30:47 +00:00
ldx #>window
2022-07-21 01:43:54 +00:00
return: rts
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;void* __fastcall__ em_map(unsigned page);
;----------------------------------------------------------------------------------------
2022-07-21 01:30:47 +00:00
MAP:
2022-07-24 00:47:02 +00:00
cmp pagecount
2022-07-21 01:30:47 +00:00
bcs return_null
sta curpage
2022-07-21 01:43:54 +00:00
lda #<dummy ; load .A/.X with adress of data for COPYFROM-call (which expects the
ldx #>dummy ; adress in .A/.X)
2022-07-21 01:30:47 +00:00
jsr COPYFROM
2022-07-21 01:43:54 +00:00
bcs return_win ; function returns pointer to window (returns always with carry set!)
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;void __fastcall__ em_commit(void);
;----------------------------------------------------------------------------------------
2022-07-21 01:30:47 +00:00
COMMIT:
lda curpage
2022-07-24 00:47:02 +00:00
cmp pagecount
2022-07-21 01:30:47 +00:00
bcs return
2022-07-21 01:43:54 +00:00
lda #<dummy ; load .A/.X with adress of data for COPYTO-call (which expects the
ldx #>dummy ; adress in .A/.X)
2022-07-21 01:30:47 +00:00
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;void __fastcall__ em_copyto (struct em_copy *copy_data);
;----------------------------------------------------------------------------------------
COPYTO:
2022-07-21 01:30:47 +00:00
jsr get_struct_data ;read the parameters passed in the em_struct pointed to by .A/.X upon call
;copy the main copyto routine into Lo_Mem
ldy #Lo_Code1_End - Lo_Code1
2022-07-21 01:43:54 +00:00
: lda Lo_Code1-1,y
2022-07-21 01:30:47 +00:00
sta Lo_Mem-1,y
dey
bne :-
2016-02-28 22:37:04 +00:00
COMMON:
2022-07-21 01:30:47 +00:00
sei
jmp Lo_Mem
2016-02-28 22:37:04 +00:00
2022-07-21 01:30:47 +00:00
;this part will be executed in Lo_Mem (!) by COPYFROM
2016-02-28 22:37:04 +00:00
Lo_Code2:
2022-07-24 00:47:02 +00:00
; copy byte rr -> c64
2022-07-21 01:43:54 +00:00
stx $de00 ;map in rr-ram
lda (rr_ram),y ;get byte from rr-ram
sty $de00 ;RR-ROM will be mapped to $8000-$a000 but write access will go to c64-ram anyway!!
sta (c64_ram),y ;and write to c64-ram
nop ;pad to same size as Lo_Code1
2022-07-21 01:30:47 +00:00
nop
2016-02-28 22:37:04 +00:00
Lo_Code2_End:
2022-07-21 01:30:47 +00:00
;this part will be executed in Lo_Mem (!) by COPYTO
2016-02-28 22:37:04 +00:00
Lo_Code1:
2022-07-24 00:47:02 +00:00
; copy byte c64 -> rr
2022-07-21 01:43:54 +00:00
lda (c64_ram),y ;read 1 byte from c64-ram
stx $de00 ;map in rr-ram
sta (rr_ram),y ;write byte to rr-ram
2022-07-21 01:30:47 +00:00
lda #$02 ;map in c64-ram again
sta $de00
2022-07-21 01:43:54 +00:00
;12 bytes
2022-07-21 01:30:47 +00:00
;this part is common for both COPYFROM/COPYTO and executed in Lo_Mem, too
2016-02-28 22:37:04 +00:00
Lo_Code_Common:
2022-07-21 01:43:54 +00:00
inc c64_ram ;increase pointers
2022-07-21 01:30:47 +00:00
bne :+
inc c64_ram+1
2022-07-21 01:43:54 +00:00
: inc rr_ram
2022-07-21 01:30:47 +00:00
bne @skip
inc rr_ram+1
lda rr_ram+1
2022-07-21 01:43:54 +00:00
cmp #$a0 ;wrap around 16k boundary in rr-ram window ($8000-$a000)
2022-07-21 01:30:47 +00:00
bne @skip
2022-07-21 01:43:54 +00:00
lda #$80 ;reset pointer to $8000
2022-07-21 01:30:47 +00:00
sta rr_ram+1
2022-07-21 01:43:54 +00:00
txa ;adjust value in .X to map in next 16k-bank in rr-ram
adc #7 ;carry is set because of former CMP, so it adds 8
2022-07-21 01:30:47 +00:00
tax
;27 bytes
2022-07-21 01:43:54 +00:00
@skip: lda c64_ram
2022-07-21 01:30:47 +00:00
cmp len
lda c64_ram+1
sbc len+1
bcc Lo_Code1
2022-07-21 01:43:54 +00:00
lda #2 ;CHANGE to LDA #0 if driver is called from ROM
2022-07-21 01:30:47 +00:00
sta $de00
cli
2022-07-21 01:43:54 +00:00
rts ;17 bytes = 56 bytes Lo_Code ($38)
2022-07-21 01:30:47 +00:00
Lo_Code1_End:
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;void __fastcall__ em_copyfrom(struct em_copy *copy_data);
;copy from extended memory into linear memory
;----------------------------------------------------------------------------------------
COPYFROM:
2022-07-21 01:30:47 +00:00
jsr get_struct_data
ldy #Lo_Code2_End - Lo_Code2 ;copy routine into Lo_Mem
2022-07-21 01:43:54 +00:00
: lda Lo_Code2-1,y
2022-07-21 01:30:47 +00:00
sta Lo_Mem-1,y
dey
bne :-
ldy #Lo_Code1_End-Lo_Code_Common
2022-07-21 01:43:54 +00:00
: lda Lo_Code_Common-1,y
2022-07-21 01:30:47 +00:00
sta Lo_Mem+11,y
dey
bne :-
2022-07-21 01:43:54 +00:00
beq COMMON ;and execute...
2016-02-28 22:37:04 +00:00
;----------------------------------------------------------------------------------------
;read the struct data located at (.A/.X)
;and setup parameters for stash/ fetch operation
;----------------------------------------------------------------------------------------
get_struct_data:
2022-07-21 01:30:47 +00:00
;read and process the values from the em_copy struct passed to as parameters rameter to the
;functions em_copyto and em_copyfrom
2022-07-21 01:43:54 +00:00
sta aux ;store adress of struct (passed in .A/.X) into a zp pointer
2022-07-21 01:30:47 +00:00
stx aux+1
2022-07-21 01:43:54 +00:00
ldy #0 ;index 0
2022-07-21 01:30:47 +00:00
2022-07-21 01:43:54 +00:00
lda (aux),y ;read c64-adress lo
2022-07-21 01:30:47 +00:00
sta c64_ram
iny
2022-07-21 01:43:54 +00:00
lda (aux),y ;read c64-adress hi
sta c64_ram+1 ;(c64_ram) --> points to c64-adress space
2022-07-21 01:30:47 +00:00
iny
2022-07-21 01:43:54 +00:00
lda (aux),y ;read rr-adress lo
2022-07-21 01:30:47 +00:00
sta rr_ram
iny
2022-07-21 01:43:54 +00:00
lda (aux),y ;rr-adress hi
pha ;remember
2022-07-21 01:30:47 +00:00
and #$1f
ora #$80 ;adjust into 16k-window ($8000-$a000)
sta rr_ram+1
2022-07-21 01:43:54 +00:00
pla ;re-get hi byte of rr-adress
2022-07-21 01:30:47 +00:00
and #$60 ;isolate bits 5 and 6
lsr
2022-07-21 01:43:54 +00:00
lsr ;shift into bits 3 and 4
2022-07-21 01:30:47 +00:00
ora #$23 ;set bit 5 (select ram) and 1+2 (game/exrom setting for ULTIMAX-mode)
2022-07-21 01:43:54 +00:00
tax ;.X has now the value to write into $de00 to acess rr-ram at desired 16k-bank
2022-07-21 01:30:47 +00:00
iny
2022-07-21 01:43:54 +00:00
iny ;skip unused byte
lda (aux),y ;read length lo-byte
2022-07-21 01:30:47 +00:00
clc
2022-07-21 01:43:54 +00:00
adc c64_ram ;add to c64-addres
2022-07-21 01:30:47 +00:00
sta len
iny
2022-07-21 01:43:54 +00:00
lda (aux),y ;length hi-byte
2022-07-21 01:30:47 +00:00
adc c64_ram+1
2022-07-21 01:43:54 +00:00
sta len+1 ;tmp2: length, tmp3 contains end adress of transfer in c64-ram.
rts
;55 bytes
2016-02-28 22:37:04 +00:00