• Hello MLAers! We've re-enabled auto-approval for accounts. If you are still waiting on account approval, please check this thread for more information.

LC475 disable onboard RAM

Within my LC475 there is 70ns onboard RAM and a 60ns RAM SIMM and a programmable ROM module.
Due to speed reasons I like to disable the onboard RAM.
Prefered solution is changing the code in ROM so the onboard RAM is no longer used.

I am quite sure that I found the place in ROM that initialize all the RAM.

In my understanding I need to change 408A01D2: MOVEQ #$00,D6 to MOVEQ #$F0
This is shifted to least significant nibble in 408A01DC: ROR.L #4,D6
This (should) set all lanes of first memory block set to bad and is not reset in "CheckByteLanes"

As all lanes are set to bad, 408A0204: EOR.B D3,D6 reset the bits in D6 but leave the size of block as zero in D5 (size not called)

Rest of routine should work as before.

Unfortunately after the start-up chime I get two other chimes that I interpret as "Bad memory". Device does not start.

Anyone any clue what is wrong?

;SizeBanks
408A01C0: SIZEMEMORYPATCH+$01C0: MOVEA.L A1,A5 ; pointer to product info table
408A01C2: SIZEMEMORYPATCH+$01C2: ADDA.L $0004(A5),A5 ; point to the ram bank map info

;Continue
408A01C6: SIZEMEMORYPATCH+$01C6: MOVEQ #$00,D0 ; clear total RAM size
408A01C8: SIZEMEMORYPATCH+$01C8: SUBA.L A3,A3 ; initialize the "bank 8-15" information (that does not exist in 475)
408A01CA: SIZEMEMORYPATCH+$01CA: SUBQ.L #1,A3 ; ... to an improbable bank config value ($FFFFFFFF)

;SizeBanks2
408A01CC: SIZEMEMORYPATCH+$01CC: MOVEA.L A5,A7 ; keep running copy in a7
408A01CE: SIZEMEMORYPATCH+$01CE: ADDQ.L #4,A7 ; skip over chunk size
408A01D0: SIZEMEMORYPATCH+$01D0: MOVEQ #$00,D5 ; clear bank size nibbles
408A01D2: SIZEMEMORYPATCH+$01D2: MOVEQ #$00,D6 ; clear error bits
408A01D4: SIZEMEMORYPATCH+$01D4: MOVE.L #$54696E61,D1 ; setup signature 'Tina'

;nextBank
408A01DA: SIZEMEMORYPATCH+$01DA: ROR.L #4,D5 ; make room for next bank size nibble
408A01DC: SIZEMEMORYPATCH+$01DC: ROR.L #4,D6 ; make room for next bank error nibble
408A01DE: SIZEMEMORYPATCH+$01DE: MOVEA.L (A7)+,A0 ; get start of bank (or terminator)
408A01E0: SIZEMEMORYPATCH+$01E0: MOVE.L A0,D2 ; end of table?
408A01E2: SIZEMEMORYPATCH+$01E2: CMPI.L #$53616D42,D2 ; at end of 1st table? 'SamB'
408A01E8: SIZEMEMORYPATCH+$01E8: BEQ.S ^$408A0212 ; -> yes, check for errs then continue SIZEMEMORYPATCH+$212 = checkErr
408A01EA: SIZEMEMORYPATCH+$01EA: ADDQ.L #1,D2
408A01EC: SIZEMEMORYPATCH+$01EC: BEQ.S ^$408A0212 ; yes, check for any errors and quit SIZEMEMORYPATCH+$212 = checkErr
408A01EE: SIZEMEMORYPATCH+$01EE: MOVEA.L (A7)+,A1 ; get end+1 of bank
; any byte lanes valid at start?
408A01F0: SIZEMEMORYPATCH+$01F0: LEA ^$408A01F8,A6 ; SIZEMEMORYPATCH+$1F8 Load return address
408A01F4: SIZEMEMORYPATCH+$01F4: JMP ^$408A0282 ; SIZEMEMORYPATCH+$282 Gosub CheckByteLanes
408A01F8: SIZEMEMORYPATCH+$01F8: MOVEQ #$0F,D3 ; byte lane mask
408A01FA: SIZEMEMORYPATCH+$01FA: AND.B D6,D3 ; all byte lanes good here?
408A01FC: SIZEMEMORYPATCH+$01FC: BEQ.S ^$408A0208 ; yes, try next bank SIZEMEMORYPATCH+$208 = size
408A01FE: SIZEMEMORYPATCH+$01FE: CMPI.B #$0F,D3 ; were all byte lanes bad?
408A0202: SIZEMEMORYPATCH+$0202: BNE.S ^$408A01DA ; no, leave mask with bad bits SIZEMEMORYPATCH+$1DA = nextBank
408A0204: SIZEMEMORYPATCH+$0204: EOR.B D3,D6 ; yes, clear out bit mask
408A0206: SIZEMEMORYPATCH+$0206: BRA.S ^$408A01DA ; and go to SIZEMEMORYPATCH+$1DA = nextBank

;size
; find size of this bank
408A0208: SIZEMEMORYPATCH¹+$0208: LEA ^$408A0210,A6 ; SIZEMEMORYPATCH+$210 Load return address
408A020C: SIZEMEMORYPATCH¹+$020C: JMP ^$408A0240 ; SIZEMEMORYPATCH+$240 Gosub SizeBank
408A0210: SIZEMEMORYPATCH¹+$0210: BRA.S ^$408A01DA ; now size next bank... SIZEMEMORYPATCH+$1DA = nextBank

;checkErr
408A0212: SIZEMEMORYPATCH¹+$0212: MOVE.L A7,D2 ; Save A7
408A0214: SIZEMEMORYPATCH¹+$0214: SUB.L A5,D2 ; (table end + 8) - table start
408A0216: SIZEMEMORYPATCH¹+$0216: SUBQ.L #8,D2 ; #entries * 8
408A0218: SIZEMEMORYPATCH¹+$0218: LSR.W #1,D2 ; / 8 * 4 = # of nibbles to roll
408A021A: SIZEMEMORYPATCH¹+$021A: ROL.L D2,D5 ; d5 = ....dcba
408A021C: SIZEMEMORYPATCH¹+$021C: ROL.L D2,D6 ; d6 = ....dcba
408A021E: SIZEMEMORYPATCH¹+$021E: TST.L D6 ; any errors?
408A0220: SIZEMEMORYPATCH¹+$0220: BNE.S ^$408A023E ; -> Yes, return now SIZEMEMORYPATCH+$23E = badBanks
408A0222: SIZEMEMORYPATCH¹+$0222: MOVE.L A0,D2 ; get the terminator or extend flag in D2
408A0224: SIZEMEMORYPATCH¹+$0224: CMPI.L #$53616D42,D2 ; Extended flag? 'SamB'
408A022A: SIZEMEMORYPATCH¹+$022A: BNE.S ^$408A0232 ; -> Nope, we're done SIZEMEMORYPATCH¹+$232 = stitchEm
408A022C: SIZEMEMORYPATCH¹+$022C: MOVEA.L D5,A3 ; We have more to do, save D5 in A3
408A022E: SIZEMEMORYPATCH¹+$022E: MOVEA.L A7,A5 ; Point A5 at the 2nd half of RAMInfo
408A0230: SIZEMEMORYPATCH¹+$0230: BRA.S ^$408A01CC ; -> make the second pass SIZEMEMORYPATCH¹+$1CC = SizeBanks2
 
The ROM code for those machines won't start up if the on-board RAM is bad. That's why you get the death chimes when you mark them bad.
 
Thank you for the hint.

So I need to dig a little more into depths.
First I rewrote cy384's "ultra wombat hax tool" for MEMCjr in 475.

There are only 5 memory blocks accessible by MEMCjr:
bank 0 is 4MB onboard RAM (70ns)
bank1 and 2 are the 128MB SIMM (60ns)
As the SIMM is double sided it populate bank 1 and 2
bank 3 and 4 are available at the MEMCjr but not connected to anything.

Interleave is not available at MEMCjr.
 

Attachments

  • ultra 475 hax tool.jpg
    ultra 475 hax tool.jpg
    5.1 MB · Views: 25
If I am not able to mark internal RAM as bad maybe it is possible to set size to 0.
Code below is calculating size of each bank.

If memory is found, size and total size is set with
408A027C: SIZEMEMORYPATCH+$027C: OR.B D3,D5 ; 'OR' in 'n' (size of this bank)
408A027E: SIZEMEMORYPATCH+$027E: ADD.L A0,D0 ; add this banks RAM to total size
If something is wrong, these two lines are skipped.

So how about skipping these two lines for internal RAM?

;SizeBank
408A0240: SIZEMEMORYPATCH+$0240: MOVE.L A0,D4 ; save start of bank
408A0242: SIZEMEMORYPATCH+$0242: SUBQ.L #4,A1 ; point to end-4 of bank
;check
408A0244: SIZEMEMORYPATCH+$0244: MOVE.L (A1),D2 ; save original
408A0246: SIZEMEMORYPATCH+$0246: MOVE.L D1,(A1) ; write signature at top
;here
408A0248: SIZEMEMORYPATCH+$0248: TST.L ^$408A0248 ; Bus capacitance is a no, no. SIZEMEMORYPATCH¹+$248 = here
408A024C: SIZEMEMORYPATCH+$024C: CMP.L (A1),D1 ; any RAM there?
408A024E: SIZEMEMORYPATCH+$024E: BEQ.S ^$408A0258 ; yes, check for wrap SIZEMEMORYPATCH¹+$258 = foundRAM
408A0250: SIZEMEMORYPATCH+$0250: SUBA.L (A5),A1 ; step back to lower block
408A0252: SIZEMEMORYPATCH+$0252: CMPA.L A0,A1 ; stepped below start?
408A0254: SIZEMEMORYPATCH+$0254: BGT.S ^$408A0244 ; no, continue looking for RAM SIZEMEMORYPATCH¹+$244 = check
408A0256: SIZEMEMORYPATCH+$0256: BRA.S ^$408A0280 ; yes, exit SIZEMEMORYPATCH¹+$280 = exit
;foundRAM
408A0258: SIZEMEMORYPATCH+$0258: SUBQ.L #4,A0 ; go 4 bytes back from start
;loop
408A025A: SIZEMEMORYPATCH+$025A: ADDA.L (A5),A0 ; add in chunk size
408A025C: SIZEMEMORYPATCH+$025C: CMP.L (A0),D1 ; found lowest occurance of signature?
408A025E: SIZEMEMORYPATCH+$025E: BNE.S ^$408A025A ; no, check a little higher up SIZEMEMORYPATCH¹+$25A = loop
408A0260: SIZEMEMORYPATCH+$0260: MOVE.L D2,(A0)+ ; restore last four bytes we wiped out
;lenght
408A0262: SIZEMEMORYPATCH+$0262: SUBA.L D4,A0 ; leave a0 with size of bank
408A0264: SIZEMEMORYPATCH+$0264: MOVEQ #$00,D3 ; n=0
408A0266: SIZEMEMORYPATCH+$0266: MOVE.L A0,D2 ; any ram?
408A0268: SIZEMEMORYPATCH+$0268: BEQ.S ^$408A027C ; no, stuff n=0 into size register SIZEMEMORYPATCH¹+$27C = stuff
408A026A: SIZEMEMORYPATCH+$026A: MOVE.L (A5),D2 ; start with smallest chunk size (e.g. 1M)
;next
408A026C: SIZEMEMORYPATCH+$026C: ADDQ.W #1,D3 ; n=n+1
408A026E: SIZEMEMORYPATCH+$026E: CMPA.L D2,A0 ; (2^(n-1))*chunk size = bank size?
408A0270: SIZEMEMORYPATCH+$0270: BEQ.S ^$408A027C ; yes, stuff 'n' into d5 SIZEMEMORYPATCH+$27C = stuff
; ????If a0 < d2 then something is wrong! Stuff 0 into d3 and exit.
408A0272: SIZEMEMORYPATCH+$0272: CMPI.B #$0F,D3
408A0276: SIZEMEMORYPATCH+$0276: BEQ.S ^$408A027C ; ????Our loop has gone over a possible match, so better bailout ; SIZEMEMORYPATCH +$27C = stuff/NotAPowerofTwo
408A0278: SIZEMEMORYPATCH+$0278: ADD.L D2,D2 ; calculate next power of two
408A027A: SIZEMEMORYPATCH+$027A: BRA.S ^$408A026C ; SIZEMEMORYPATCH+$26C = next
;NotAPowerofTwo
;stuff
408A027C: SIZEMEMORYPATCH+$027C: OR.B D3,D5 ; 'OR' in 'n' (size of this bank)
408A027E: SIZEMEMORYPATCH+$027E: ADD.L A0,D0 ; add this banks RAM to total size
;exit
408A0280: SIZEMEMORYPATCH+$0280: JMP (A6) ; Return
 
Next I need to find some place for additional code.
As I am operating an LC 475 all code for Wombat boards is not used.

This check if board is a Wombat board as jump to the Wombat only routine if yes:
408A014A: SIZEMEMORYPATCH+$014A: MOVE.L $5FFFFFFC,D0
408A0150: SIZEMEMORYPATCH+$0150: CMPI.W #$2BAD,D0
408A0154: SIZEMEMORYPATCH+$0154: BEQ.S ^$408A0184 ;SIZEMEMORYPATCH+$184 = djMEMCSplit

So in my case the routine at $408A0184 is never used.
I replaced the routine with all NOPs and the BEQ at $408A0154 as well.

Next I put the last three lines of the original code into the new empty area, added a branch to immediate return if size of Bank is 4MB and replaced the original lines by a jump to this point.

This seems to work. First bank is set to size zero, memory starts with second bank now.
This should give me the opportunity no longer need to use the 80ns timing but switch to the 60ns as described in MEMCjr manual.

IT might also expand the maximum clock frequency above the current 52MHz limit.
 
Sounds like great progress! Are you willing to share your modified ROM? I have a PDS video card in my 475 to try and stretch the limits.
 
What's strange is that I have a 475 board which has problems. The onboard ram isn't recognized at all. Attempting to boot it up with no SIMM gets sad Mac chimes and black screen. Installing any size SIMM results in memory being reported as that SIMM size.

Video is also somehow affected, with white being replaced with a red. Like it's "mostly" color, but black and... red?

If you're interested in seeing this board in person @Mustermann , I'd be happy to ship it to you on loan or something.
 
This is really cool. I’ve been wanting to be able to do this on my 575/Mystic. Have you made more progress in your tests?
 
Back
Top