Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > REU detection problem
2019-03-21 14:05
Trash

Registered: Jan 2002
Posts: 122
REU detection problem

Hi all, I have a small problem with my REU-detectioncode.

It correctly detects REUs on all machines I have tested it on but if the REU is 1024kb or larger it reports 255 banks (16mb) in $fe instead of the correct number of banks. 128 -> 512 kb works just fine.

Can anybody see were I've got it wrong?

;----------------------------------------------------------
; Determines if we have a REU present or not
;----------------------------------------------------------
; Note:	interrupt-flag must be set (sei)
;	this trashes the content of the REU (transfers $0000 - $00ff to each bank of the REU)
;----------------------------------------------------------
; The MSB of $ff will be set if REU is present
; $ff == %1xxxxxxx - REU present
; $ff == %0xxxxxxx - REU not present
; $fe will contain the 0-based number of accessible banks
;----------------------------------------------------------
REU_PRESENT
;----------------------------------------------------------
		lda #$00
		sta $fe

		ldx #8
-		sta $df00, x	; Set address $0000 from c64, transfer length $0000 and $000000 to REU
		dex
		bpl -
		sta $df0a		; C64 not fixed, REU not fixed

		lda #66
		sta $df07		; We want to move 66 bytes in order for the operation to take more than 65 cycles (the maximum no of cycles on a rasterrow)

		lda #%10110000
		sta $df01

		lda $d012
-		cmp $d012
		beq -
		lda #$fb
-		cmp $d012
		bne -
		lda #%10110000
		sta $df01
		ldy $d012
		lda $ff
		and #%01111111
		cpy #$fb
		beq +			; No REU since the execution of the transfer took less than a rasterline
		ora #%10000000	; REU exists
+		sta $ff
		lda $ff
		bmi +			; REU exists, determine number of banks
		rts
+		lda #1
		sta $df07
		
		lda #<counter
		sta $df02
		lda #>counter
		sta $df03
		
		lda #%10110000
		ldx #0
-		stx $df06		; Set bank
		sta $df01		; Transfer 1 byte from c64 to REU
		dec counter		; Decrease counter
		inx				; Increase bank-number
		bne -
		
		lda #%10110001
		stx $df06
		sta $df01		; Transfer the first value from REU @ $000000 to address of counter
		
		ldx counter
		stx $fe

		rts
counter	.byte $ff
2019-03-21 14:15
chatGPZ

Registered: Dec 2001
Posts: 11386
$ff is not initialized?
2019-03-21 14:23
Trash

Registered: Jan 2002
Posts: 122
Quote: $ff is not initialized?

It is...
2019-03-21 14:32
chatGPZ

Registered: Dec 2001
Posts: 11386
where? (however, that doesnt seem to be the problem)

you gotta explain how the loop at the bottom is supposed to work, i somehow dont see it working at all :)
2019-03-21 14:37
Trash

Registered: Jan 2002
Posts: 122
Quote: where? (however, that doesnt seem to be the problem)

you gotta explain how the loop at the bottom is supposed to work, i somehow dont see it working at all :)


This code will always ensure that $ff contains a negative or a positive value in all outcomes. And you are right, that isn't the problem.

All REUs is detected to the level that it finds if a REU is plugged in or not so the problem is somewhere after the first rts.

	lda $ff
	and #%01111111
	cpy #$fb
	beq +
	ora #%10000000
+	sta $ff
2019-03-21 14:42
chatGPZ

Registered: Dec 2001
Posts: 11386
i think i got the idea of the last loop now... you are writing $ff, $fe etc into increasing bank numbers, then because of the wraparound after $100 iterations the first bank will contain the number of total banks.

i vaguely remember a problem with this... you might check the vice source. ie in some implementations of the REU (hardware i mean) the wraparound doesnt work that way, you will get "open" banks instead
2019-03-21 14:45
Trash

Registered: Jan 2002
Posts: 122
Correct, will check Vice sources tonight in order to understand how to solve the problem or just determine that I support up to 512kb with my detection code...

Thanks!
2019-03-21 15:07
chatGPZ

Registered: Dec 2001
Posts: 11386
did a quick check, apparently the sdram wraparound is indeed the same for all sizes >=1024. so to tell larger sizes apart you need to use a different way. which is a good idea in any case - because this is something that is completely undefined.
2019-03-30 12:01
tlr

Registered: Sep 2003
Posts: 1790
Yes, the wrapping as a bit strange as groepaz notes.
This is the detection code i use in Superfluid V0.6:(returns size >> 16 in Acc)
;************************************************************************* *
;*
;* NAME  detect_reu
;*
;* DESCRIPTION
;*   Detect REU presence and size (type)
;*
;*   We do this by checking the start of each power of 2 bank for the
;*   presence of ram (pattern $55 and $aa), and then verifying that the
;*   start of bank 0 wasn't affected (i.e aliasing).
;*
;******
detect_reu:
        php
        sei

        lda     #%00000001
dr_lp1:
        pha
        jsr     dr_testpage
        pla
        bcc     dr_ex1
        asl
        bne     dr_lp1

dr_ex1:
        ror
        beq     dr_ex2
; adjust to be mask
        sec
        sbc     #1
        rol
dr_ex2:
        plp
        rts


dr_testpage:
        tay
; preserve initial contents
        jsr     dr_from_reu
        pha

        lda     #$55
        jsr     dr_testpage2
        lda     #$aa
        jsr     dr_testpage2

; restore initial contents
        pla
        jsr     dr_to_reu

; check result
        lda     #%00001010
        bit     detect_res_zp
        bne     drt_fl1
        lsr
;       lda     #%00000101
        bit     detect_res_zp
        beq     drt_fl1

        sec
        rts

drt_fl1:
        clc
        rts


dr_testpage2:
        sty     detect_tmp_zp
        sta     detect_cmp_zp
        jsr     dr_to_reu

        jsr     drt2_common

        ldy     #0
drt2_common:
        jsr     dr_from_reu
        clc
        eor     detect_cmp_zp
        beq     drt2_skp1
        sec
drt2_skp1:
        rol     detect_res_zp

        ldy     detect_tmp_zp
        rts


; Acc = data, Y = page, C = direction (1 = REU -> C64)
dr_to_reu:
        sta     detect_data_zp
        clc
        dc.b    $24
dr_from_reu:
        sec
        ldx     #%00000000
        stx     $df0a           ; control
; set c64 address
        lda     #<detect_data_zp
        sta     $df02
        stx     $df03
; set REU address
        stx     $df04
        stx     $df05
        sty     $df06
; set len
        lda     #1
        sta     $df07
        stx     $df08
; commence
        lda     #%10010000 >> 1
        rol
        sta     $df01
        lda     detect_data_zp
        rts
2019-03-30 15:47
AlexC

Registered: Jan 2008
Posts: 299
Just a side note: SuperFluid 0.6 detection code work with 16mb reu in Ultimate64 with 1.10 firmware. Just make sure to reboot U64 after mounting cartridge.
2019-03-31 09:24
Walt

Registered: May 2004
Posts: 47
Hi...

Here is my detection routine, written in KickAss.

Tested on VICE 2.4 and 1541U2+ :)

You can of course skip the backup and restore parts if you want...

.const REUStatus		= $df00
.const REUCommand		= $df01
.const REUC64			= $df02
.const REUREU			= $df04
.const REUTransLen		= $df07
.const REUIRQMask		= $df09
.const REUAddrMode		= $df0a

.const REUStatusFault = 32		// Error during compare
.const REUCMDExecute = 128+16	// Start transfer/compare/swap without waiting for write to $ff00
.const REUCMDExecuteFF00 = 128	// Start transfer/compare/swap after write access to $ff00 (for using RAM below I/O area $d000-$dfff)
.const REUCMDAutoload = 32		// Restore address and length registers after execute
.const REUCMDTransToREU = 0		// Bit 0-1 : 00 = transfer C64 -> REU
.const REUCMDTransToC64 = 1 	// Bit 0-1 : 01 = transfer REU -> C64
.const REUCMDSwap = 2			// Bit 0-1 : 10 = swap C64 <-> REU
.const REUCMDCompare = 3		// Bit 0-1 : 11 = compare C64 - REU
.const REUAddrFixedC64 = 128	// Bit 7 : C64 ADDRESS CONTROL  (1 = fix C64 address)
.const REUAddrFixedREU = 64		// Bit 6 : REU ADDRESS CONTROL  (1 = fix REU address)


Byte:			.byte 0
REUFound:		.byte 0		// 0 = No REU
REUSize:		.byte 0		// Number of 64KB pages :
							// 2 = 128KB, 4 = 256KB, 8 = 512KB, 16 = 1MB, 32 = 2MB, 64 = 4MB, 128 = 8MB, 255=16MB

CheckREUSize:	lda #0
				tax
ClearREUOut:	sta REUOut,x
				sta REUCount,x
				inx
				bne ClearREUOut

				lda #0
				sta REUCommand
				sta REUIRQMask
				sta REUAddrMode		// No fixed addresses (increment both C64 and REU counters)
				lda REUStatus

				// Backup REU first byte of each 64K block ( $xx0000 )
				ldx #0
				ldy #0
BackupLoop:		stx REUC64		// Location of backup buffer, $100 aligned
				lda #>REUBackup
				sta REUC64+1

				sty REUREU		// REU address
				sty REUREU+1
				stx REUREU+2

				lda #1			// Tell REU to transfer 1 byte
				sta REUTransLen
				sty REUTransLen+1

				lda #REUCMDExecute+REUCMDTransToC64	// Do the transfer
				sta REUCommand

				inx
				bne BackupLoop

				// Write $00-$ff in $xx0000
WriteLoop:		lda #<Byte
				sta REUC64
				lda #>Byte
				sta REUC64+1

				sty REUREU
				sty REUREU+1
				stx REUREU+2

				lda #1
				sta REUTransLen
				sty REUTransLen+1

				stx Byte

				lda #REUCMDExecute+REUCMDTransToREU
				sta REUCommand

				inx
				bne WriteLoop

ReadLoop:		lda #<Byte
				sta REUC64
				lda #>Byte
				sta REUC64+1

				sty REUREU
				sty REUREU+1
				stx REUREU+2

				lda #1
				sta REUTransLen
				sty REUTransLen+1

				sty Byte

				lda #REUCMDExecute+REUCMDTransToC64
				sta REUCommand

				lda Byte
				sta REUOut,x

				inx
				bne ReadLoop

RestoreLoop:	stx REUC64		// Location of backup buffer, $100 aligned
				lda #>REUBackup
				sta REUC64+1

				sty REUREU		// REU address
				sty REUREU+1
				stx REUREU+2

				lda #1			// Tell REU to transfer 1 byte
				sta REUTransLen
				sty REUTransLen+1

				lda #REUCMDExecute+REUCMDTransToREU	// Do the transfer
				sta REUCommand

				inx
				bne RestoreLoop

				// Count

				lda #1
CountLoop1:		ldy REUOut,x
				sta REUCount,y
				inx
				bne CountLoop1

				inx				// Skip 0
				lda #0
CountLoop2:		clc
				adc REUCount,x
				inx
				bne CountLoop2
				sta REUSize

				lda REUCount+1
				ora REUCount+255
				sta REUFound

				rts

				.pc = $8000 "REU data" virtual
REUBackup:		.fill $100,0		// Backup of actual content at $xx0000
REUOut:			.fill $100,0		// Bytes read from $xx0000
REUCount:		.fill $100,0		// REUOut positions set to 1 in this table
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Brittle/Dentifrice^(?)
Freeze/Blazon
Guests online: 84
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 Layers  (9.6)
2 No Listen  (9.6)
3 Party Elk 2  (9.6)
4 Cubic Dream  (9.6)
5 Copper Booze  (9.6)
6 Rainbow Connection  (9.5)
7 Dawnfall V1.1  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top Original Suppliers
1 Derbyshire Ram  (9.7)
2 Fungus  (9.3)
3 Black Beard  (9.2)
4 Baracuda  (9.2)
5 hedning  (9.1)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.053 sec.