GWRAM.SYSTEM/ram2gs_asm.s

383 lines
5.8 KiB
ArmAsm

.setcpu "65816"
.autoimport on
.importzp sp
.export _ram2gs_cmd
.export _ram2gs_getsize
.export _ram2gs_detect
.export _ram2gs_flashled1
.macro A8
sep #$20 ; put the 65C816 in 8-bit accumulator mode
.A8
.endmacro
.macro I8
sep #$10 ; put the 65C816 in 8-bit index register mode
.I8
.endmacro
.macro AI8
sep #$30 ; put the 65C816 in 8-bit accumulator and index register mode
.A8
.I8
.endmacro
.macro A16
rep #$20 ; put the 65C816 in 8-bit accumulator mode
.A16
.endmacro
.macro I16
rep #$10 ; put the 65C816 in 8-bit index register mode
.I16
.endmacro
.macro AI16
rep #$30 ; put the 65C816 in 8-bit accumulator and index register mode
.A16
.I16
.endmacro
.segment "CODE"
.proc _thrash: near
.A8
.I8
; Preamble
php ; Push status
AI16
phb ; Push bank
pha ; Push accumulator
pha ; Push X
phy ; Push Y
; Read 0x100000-0x11FFFF
AI8
lda #$20 ; A = 0x10 (bank)
_thrash_loop:
pha ; Switch to bank stored in A
plb
AI16
lda #$0000 ; Get index in A
clc ; Clear carry in preparation to add in loop
; Read loop
_thrash_loop0:
tax ; Get index from A into X to do LDYs
ldy $0100,X ; Read 64 bytes
ldy $0102,X ; ...
ldy $0104,X
ldy $0106,X
ldy $0108,X
ldy $010A,X
ldy $010C,X
ldy $010E,X
ldy $0110,X
ldy $0112,X
ldy $0114,X
ldy $0116,X
ldy $0118,X
ldy $011A,X
ldy $011C,X
ldy $011E,X
ldy $0120,X
ldy $0122,X
ldy $0124,X
ldy $0126,X
ldy $0128,X
ldy $012A,X
ldy $012C,X
ldy $012E,X
ldy $0130,X
ldy $0132,X
ldy $0134,X
ldy $0136,X
ldy $0138,X
ldy $013A,X
ldy $013C,X
ldy $013E,X
adc #$0040 ; Add 64 to index in A
cmp #0
bne _thrash_loop0 ; Repeat if we haven't passed 0xFFFF
; Bank increment
AI8
phb ; Transfer bank to A
pla
inc ; Increment bank
cmp #$21 ; Stop after bank 0x20
bne _thrash_loop
; Postamble
AI16
ply ; Restore Y
plx ; Restore X
pla ; Restore accumulator
plb ; Restore bank
AI8
plp ; Restore status
rts
.endproc
.proc _ram2gs_cmd: near
.A8
.I8
; Preamble
php ; Push status
sei ; Disable interrupts
clc ; Clear carry
xce ; Clear emulation bit
php ; Push status again, reflecting emulation bit
phb ; Push bank
pha ; Push command in accumulator
AI8
; Switch to bank 0xFB
lda #$FB
pha
plb
; Submit C1AD
lda #$C1
sta $FFFE
lda #$AD
sta $FFFF
; Pull and submit command
pla
sta $FFFD
; Postamble
plb ; Restore bank
plp ; Restore status
xce ; Restore emulation bit
plp ; Pull status again to pull I flag
rts
.endproc
.proc _unswap: near
.A8
.I8
tya
ora #$00
jmp _ram2gs_cmd
.endproc
.proc _swap: near
.A8
.I8
tya
ora #$01
jmp _ram2gs_cmd
.endproc
.proc _ram2gs_getsize: near
.A8
.I8
; Preamble
php ; Push status
sei ; Disable interrupts
clc ; Clear carry
xce ; Clear emulation bit
php ; Push status again, reflecting emulation bit
phb ; Push bank
AI8
; Go to bank 3F
ldy #$3F
phy
plb
; Save 3F/3456
lda $3456
pha
; Go to bank 7F
ldy #$7F
phy
plb
; Save and then invert 7F/3456
lda $3456
pha
eor #$FF
sta $3456
; Go to bank 3F
ldy #$3F
phy
plb
; Has 3F/3456 changed?
jsr _thrash
plx ; X = saved 7F/3456
pla ; A = saved 3F/3456
cmp $3456
php ; Push to save processor status
; Go to bank 7F
ldy #$7F
phy
plb
; Restore 3F/3456
sta $3456
; Go to bank 7F
ldy #$7F
phy
plb
; Restore 7F/3456
stx $3456
; Check result
lda #$80
plp
beq _ram2gs_getsize_return
lda #$40
; Postamble
_ram2gs_getsize_return:
plb ; Restore bank
plp ; Restore status
xce ; Restore emulation bit
plp ; Pull status again to pull I flag
rts
.endproc
.proc _ram2gs_detect_internal: near
.A8
.I8
; Switch to bank 0x3F
lda #$3F
pha
plb
; Unswap
jsr _unswap
; Save unswapped 3F/8000
jsr _thrash
lda $8000
pha
; Swap
jsr _swap
; Save swapped 3F/8000
jsr _thrash
lda $8000
pha
; Store 0xFF in swapped
lda #$FF
sta $8000
; Verify 0xFF stored
jsr _thrash
lda $8000
cmp #$FF
bne _ram2gs_detect_fail
; Unswap
jsr _unswap
; Store 0x00 in unswapped
lda #$00
sta $8000
; Verify 0x00 stored
jsr _thrash
lda $8000
cmp #$00
bne _ram2gs_detect_fail
; Swap
jsr _swap
; Verify 0xFF stored
jsr _thrash
lda $8000
cmp #$FF
bne _ram2gs_detect_fail
; Get success return value and jump to postamble
ldx #$01 ; Get success falue
bne _ram2gs_detect_done ; Jump to postamble
; Fail
_ram2gs_detect_fail:
ldx #$00 ; Get fail value
; Done, now put back clobbered bytes
_ram2gs_detect_done:
jsr _swap ; Swap
pla ; Get value to restore to swapped bank 3F
sta $8000 ; Restore
jsr _unswap ; Unswap
pla ; Get value to restore to unswapped bank 3F
sta $8000 ; Restore
; Return
rts
.endproc
.proc _ram2gs_detect: near
.A8
.I8
; Preamble
phx ; Push X
phy ; Push Y
php ; Push status
sei ; Disable interrupts
clc ; Clear carry
xce ; Clear emulation bit
php ; Push status again, reflecting emulation bit
phb ; Push bank
AI8
; Transfer typecode (shifted) to Y register
and #$0E
tay
jsr _ram2gs_detect_internal
; Postamble
txa ; Get return value
plb ; Restore bank
plp ; Restore status
xce ; Restore emulation bit
plp ; Pull status again to pull I flag
ply ; Pull X
plx ; Pull Y
rts
.endproc
.proc _ram2gs_flashled1: near
.A8
.I8
; Preamble
phx ; Push X
phy ; Push Y
php ; Push status
sei ; Disable interrupts
clc ; Clear carry
xce ; Clear emulation bit
php ; Push status again, reflecting emulation bit
phb ; Push bank
AI8
lda #$20
pha
plb
ldx #0
_ram2gs_flashled1_loop:
lda $3456
lda $3456
lda $3456
lda $3456
lda $3456
lda $3456
lda $3456
lda $3456
inx
cpx #0
bne _ram2gs_flashled1_loop
; Postamble
plb ; Restore bank
plp ; Restore status
xce ; Restore emulation bit
plp ; Pull status again to pull I flag
ply ; Pull X
plx ; Pull Y
rts
.endproc