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
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
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.
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.
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.
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 ?
I think this condition is useless.