Switching RAM in page 2 from a ROM

Page 2/2
1 |

By Metalion

Paragon (1616)

Metalion's picture

05-12-2022, 20:55

I modified the search RAM routine from the wiki, to make it more compact (SJASM syntax, not tested).

;===============================================================================
; search for RAM on a page
; (in)	hl = 0000h,4000h or 8000h
; (out)	'carry' = 0, a = 0000_00PP (not extended) / E000_SSPP (extended)
;	'carry' = 1, no RAM found
; (mod)	all,all'
;===============================================================================
search_RAM:
; hl'= hl
	push	hl
	exx			; (alt)
	pop	hl

;-------------------------------------------------------------------------------
; loop on primary slots
;-------------------------------------------------------------------------------
	ld	b,4		; primary slot counter
.loop1	ld	a,b
	dec	a
	xor	3
	ld	(primary_slot),a
	ld	e,a		; e = 0000_00PP

	push	hl
	ld	hl,BIOS.exptbl
	ld	d,0
	add	hl,de
	bit	7,(hl)		; bit 7 = 1 if primary slot is extended
	pop	hl
	
	exx			; (std)
	ld	b,1
	ld	a,(primary_slot)
	jr	z,.test		; no secondary slot

;-------------------------------------------------------------------------------
; loop on secondary slots
;-------------------------------------------------------------------------------
	ld	b,4		; secondary slot counter
.loop2	ld	a,b
	dec	a
	xor	3
[2]	rlca
	ld	c,a		; c = 0000_SS00
	ld	a,(primary_slot)
	or	c		; a = 0000_SSPP
	or	128		; a = E000_SSPP

.test	push	bc
	ld	(current_slot),a
	call	BIOS.rdslt	; read first byte
	cp	"A"
	jr	nz,.ram
	inc	hl
	ld	a,(current_slot)
	call	BIOS.rdslt	; read second byte
	dec	hl
	cp	"B"
	jr	z,.next

.ram	ld	a,(current_slot)
	ld	e,"A"
	call	BIOS.wrslt	; write first byte
	ld	a,(current_slot)
	call	BIOS.rdslt	; read first byte
	cp	"A"
	jr	z,.found

.next	pop	bc
	djnz	.loop2
	exx			; (alt)
	djnz	.loop1
	scf			; ram not found: set carry
	ret

.found	pop	bc
	ld	a,(current_slot)
	and	a		; ram found: reset carry
	ret

By Metalion

Paragon (1616)

Metalion's picture

06-12-2022, 08:58

One more pass to make it more compact (and tested). However, I think I found a bug: if the first byte in the slot tested is "A", but the second byte is not "B", then we could have a false ram detection. Because it will read back "A" after trying to write it.

;===============================================================================
; search for RAM on a page
; (in)	hl = 0000h,4000h or 8000h
; (out)	carry=0, a = 0000_00PP (not extended)
;		     E000_SSPP (extended)
;	carry=1, no RAM found
; (mod)	all,all'
;===============================================================================
search_RAM:
; hl'= hl
	push	hl
	exx			; (alt)
	pop	hl

;-------------------------------------------------------------------------------
; loop on primary slots
;-------------------------------------------------------------------------------
	ld	bc,4:-1		; primary slot counter
.loop1	inc	c
	ld	a,c
	ld	(primary),a	; a = 0000_00PP

	ld	de,BIOS.exptbl
	add	e
	ld	e,a
	ld	a,(de)
	rlca			; bit 7 = 1 if primary slot is extended

	exx			; (std)
	ld	b,1
	ld	a,(primary)
	jr	nc,.test	; no secondary slot

;-------------------------------------------------------------------------------
; loop on secondary slots
;-------------------------------------------------------------------------------
	ld	bc,4:128-4	; secondary slot counter
.loop2 	ld	a,c
	add	4
	ld	c,a		; c = E000_SS00
	ld	a,(primary)
	or	c		; a = E000_SSPP

.test	push	bc
	ld	(slot),a
	call	BIOS.rdslt	; read first byte
	cp	"A"
	jr	nz,.ram
	inc	hl
	ld	a,(slot)
	call	BIOS.rdslt	; read second byte
	dec	hl
	cp	"B"
	jr	z,.next

.ram	ld	a,(slot)
	ld	e,"A"
	call	BIOS.wrslt	; write first byte
	ld	a,(slot)
	call	BIOS.rdslt	; read first byte
	cp	"A"
	jr	z,.found

.next	pop	bc
	djnz	.loop2
	exx			; (alt)
	djnz	.loop1
	scf			; ram not found: set carry
	ret

.found	pop	bc
	ld	a,(slot)
	and	a		; ram found: reset carry
	ret

By gdx

Enlighted (5994)

gdx's picture

06-12-2022, 09:25

The routines I put in the wiki does not modify the RAM. They put slot numbers at RAMAD0-RAMAD3 for the example but of course these four values should be placed elsewhere depending on your program.

The explanations for Turbo R of the wiki must be more detailed (because the ST behaves a bit differently than the GT for example). About the routine for Turbo R, now i'm not sure if it needs to be improved or not, but it lacks detail too.

Metalion wrote:

May be a dumb question, but when a 32K ROM starts, at first only the page 1 is switched to the ROM.
So it means that the page 2 is still switched to RAM, before being switched to ROM (by the ROM).

It's explained in the wiki. This depends on the location of the header and the INIT address.

aoineko wrote:

Oh. I didn't catch that when I read the wiki.

What is not said in the wiki is that the Turbo R does the search differently when disks and turbo mode are used. In fact, I didn't have time to put all the details. I say that from memory. I think the Turbo R actually always chooses internal memory on page 3. For the other pages, it depends if the Disk-ROM is present or not and if it is v1.xx or v2.3x. For the rest, the wiki is correct.

By Metalion

Paragon (1616)

Metalion's picture

06-12-2022, 09:36

Metalion wrote:

However, I think I found a bug: if the first byte in the slot tested is "A", but the second byte is not "B", then we could have a false ram detection. Because it will read back "A" after trying to write it.

gdx, what do you think about this ?

By gdx

Enlighted (5994)

gdx's picture

06-12-2022, 09:40

I think this condition is useless.

Page 2/2
1 |