English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. General (https://eab.abime.net/forumdisplay.php?f=37)
-   -   RESET without jumping into Kickstart? (https://eab.abime.net/showthread.php?t=34348)

mark_k 19 January 2008 00:51

RESET without jumping into Kickstart?
 
Hi,

I know the normal software reset method is to (for example) load A0 appropriately (pointing to e.g. 2 or $FC0002 etc.), then do RESET / JMP (A0), where the RESET instruction is longword aligned. That's because memory probably goes away at reset; the JMP opcode is prefetched before reset occurs. (Chip memory disappears to be replaced by an image of the Kickstart ROM, and autoconfig fast memory goes away too. $C00000 memory probably remains accessible however.)

What I'm curious to know is... can something similar be done, but to remove the ROM overlay? In other words, can code execution continue after reset, even from chip RAM? Like this:
Code:

; Code in chip memory (not autoconfig fast RAM)
; (Disable interrupts first)
    LEA    ($BFE001).L,A0
    MOVE.B  (A0),D0
    BCLR.B  #0,D0 ;Clear OVL bit (will be clear anyway)
    BRA.W  .DoIt
    CNOP    0,4
.DoIt:
    RESET
    MOVE.B  D0,(A0)
    [Some more code here]

Will the code after the MOVE.B D0,(A0) execute? Or will the CPU try to prefetch the word after the MOVE.B before the overlay bit has been cleared, so the next word executed would be some random ROM word?

I'm guessing this isn't possible, since I seem to remember Dave Haynie having to do something funky with the instruction cache in the SetCPU source code...

-- M

Toni Wilen 19 January 2008 09:35

It is possible, Double Dragon 2 protection did it :)

Code:

0003ffd8 46fc 2700                MV2SR.W #$2700
0003ffdc 7003                    MOVE.L #$00000003,D0
0003ffde 4df9 96df f000          LEA.L $96dff000,A6
0003ffe4 4bf9 23bf e201          LEA.L $23bfe201,A5
0003ffea 49f9 45bf e001          LEA.L $45bfe001,A4
0003fff0 41f9 0090 0000          LEA.L $00900000,A0
0003fff6 43e8 0001                LEA.L (A0,$0001) == $00900001,A1
0003fffa 51d4                    SF .B (A4) == 0003fffc
0003fffc 4e70                    RESET.L
0003fffe 1a80                    MOVE.B D0,(A5)
00040000 4e71                    NOP.L
00040002 51d4                    SF .B (A4) == 00040004
00040004 3d7c 7fff 069a          MOVE.W #$7fff,(A6,$069a) == $96dff69a

btw, long word alignment is not needed, there is nothing in prefetch logic that cares about long alignment..

Photon 23 January 2008 22:16

Nice, a disassembler that gives different binary when you assemble it again ;) Not to mention generating sources that don't use the syntax in the CPU Programmer's manual ;) (Referring to the moveq #3,d0 and reset instructions, respectively.)

Overall, that disassembly looks n.a.s.t.y. :)

Um, what is the purpose of executing code after reset? Either it resets or it doesnt? Explain please :)

Toni Wilen 23 January 2008 22:26

Quote:

Originally Posted by Photon (Post 390196)
Nice, a disassembler that gives different binary when you assemble it again ;) Not to mention generating sources that don't use the syntax in the CPU Programmer's manual ;) (Referring to the moveq #3,d0 and reset instructions, respectively.)

Overall, that disassembly looks n.a.s.t.y. :)

Um, what is the purpose of executing code after reset? Either it resets or it doesnt? Explain please :)

You can fix the disassembler first before I'll answer I guess :)
Sources are that way ->

Photon 24 January 2008 00:25

Hm. I thought the disasm came from that cartridge thingy you emulate? Sorry, didn't think you coded it. Doesn't mean I'll retract my surly comments though, after all they are correct ;)

If the disasm is open source, I can help you if I can use a nicer OOP language than cpp!

Toni Wilen 24 January 2008 00:36

Quote:

Originally Posted by Photon (Post 390245)
Hm. I thought the disasm came from that cartridge thingy you emulate? Sorry, didn't think you coded it. Doesn't mean I'll retract my surly comments though, after all they are correct ;)

If the disasm is open source, I can help you if I can use a nicer OOP language than cpp!

No, it is UAE debugger's disassembler (no, I didn't write it) and it is a bit weird but I guess it has to be because it uses same m68k instruction meta data as 68k emulation code generator.. (if you want to see weird, try movem)

Quote:

Um, what is the purpose of executing code after reset? Either it resets or it doesnt? Explain please
I guess it was made to kill/confuse some hardware debuggers.

mark_k 24 January 2008 01:56

Quote:

Originally Posted by Toni Wilen (Post 388739)
btw, long word alignment is not needed, there is nothing in prefetch logic that cares about long alignment..

Is that definitely the case for 32-bit CPUs running in 32-bit-wide memory? If so, I wonder why CBM made a point of saying the RESET opcode has to be longword-aligned?

-- M

meynaf 24 January 2008 16:27

On some accelerator boards (e.g. Blizzard 1230-IV like mine), executing the reset instruction resets everything, cpu included. The instruction after the reset isn't even executed. Hence your code would be doomed on such a machine.

Btw that DD2 protection code is awful :shocked
(Commodore said : do not put anything in the upper bits of an address !!!)

mr.spiv 14 April 2020 07:53

Mind some necromancy here.. I tried reset codes for fun last night and just did not get them working as I hoped for on my A3000 (with CS2 040). The intention was to keep the code in Chip RAM. If the code is in the RAM that does not disappear or get OVLed during the reset (beyond $80000) it works as expected but if located lower in the Chip RAM it seems the code after the reset instruction never got executed. Am I obviously missing something should-be-known-stupid here?

Toni Wilen 14 April 2020 09:27

ROM gets overlayed on top of chip RAM when reset is executed. You need to set CIA overlay bit immediately after the RESET. Because 68020+ pipeline is 3 words + 1 long word input buffer, it should be much easier to handle than with 68000 (which has only 2 word pipeline = RESET + CIA modification instruction must fit in 2 words)

It probably is best to prepare data and address registers for OVL setting, execute RESET, set CIA OVL bit (I think it is enough to set OVL data direction), then execute bra.s (or jmp (an)) to force pipeline refill because at least input buffer will now have long word loaded from ROM which you don't want to execute.

mr.spiv 14 April 2020 10:09

Quote:

Originally Posted by Toni Wilen (Post 1391809)
ROM gets overlayed on top of chip RAM when reset is executed. You need to set CIA overlay bit immediately after the RESET. Because 68020+ pipeline is 3 words + 1 long word input buffer, it should be much easier to handle than with 68000 (which has only 2 word pipeline = RESET + CIA modification instruction must fit in 2 words)

It probably is best to prepare data and address registers for OVL setting, execute RESET, set CIA OVL bit (I think it is enough to set OVL data direction), then execute bra.s (or jmp (an)) to force pipeline refill because at least input buffer will now have long word loaded from ROM which you don't want to execute.

This is what I did more or less.. Also setting data direction seemed to be enough to "clear" OVL and swap RAM in. My code is basically:
Code:

    reset
    move.b  d0,(a5)    ; D0=3, A5=$bfe201
    jmp    (a4)      ; A4 points to a code 4k further in Chip RAM


Toni Wilen 14 April 2020 11:23

Does it work if your JMP jumps to RAM that does not disappear? (=confirms that CPU does not immediately jump somewhere unknown, at least immediately)

Do you see color bars if you do something like loop: move.w (a0),(a1); bra.s loop) after the reset-instruction, A0=dff006 and A1=dff180?

Make sure CPU instruction cache is enabled.

It also could be some accelerator board side-effect, for example if board has maprom support, it requires some logic to handle also overlay. Perhaps it is only reset when board detects hardware reset.

Thomas Richter 14 April 2020 12:41

All of this cannot really work on a 040. Note that the 040 *requires* a running MMU, and that the RAM the MMU tables are located in may go away on a reset if it is autoconfig-RAM. Thus, at least you should also ensure that the MMU is either disabled (mmu.library WithoutMMU()) or ensure that the MMU tables are in chip-mem as well in a location without ROM overlay (you can create a custom MMU table with the library, and ensure by the memory allocation bits that it is in chip). You also could try that the reset, and CIA modification and jmp are in a a cache-line, i.e. aligned to a 16-byte boundary. One way or another, this type of stunt requires a bit more care on the higher processors, and it is in general advisable to rely on the os function ColdReboot() (or the patches installed therein) to do the right thing for you.

mr.spiv 14 April 2020 13:38

Quote:

Originally Posted by Toni Wilen (Post 1391839)
Does it work if your JMP jumps to RAM that does not disappear? (=confirms that CPU does not immediately jump somewhere unknown, at least immediately)

Do you see color bars if you do something like loop: move.w (a0),(a1); bra.s loop) after the reset-instruction, A0=dff006 and A1=dff180?

Make sure CPU instruction cache is enabled.

It also could be some accelerator board side-effect, for example if board has maprom support, it requires some logic to handle also overlay. Perhaps it is only reset when board detects hardware reset.

I went through quite a few iterations (with visual stimulus and/or dumping ROM & RAM from the same memory locations). I get e.g. this working when reset+OVL+JMP is in RAM that does not disappear (e.g. $80000 in my case) and the code where I jump is in RAM that did disappear but got put back with OVL clearing (e.g. in $71000 in my case) - which was expected. Also tried with and without CPU caches. Alignment was also taken care of. MMU I did not touch, since I have zero experience with 68-line MMUs but I did try AFAIR with and without mapped ROMs. I probably need to redo the maprom stuff.

mr.spiv 14 April 2020 16:41

Quote:

Originally Posted by Thomas Richter (Post 1391854)
All of this cannot really work on a 040. Note that the 040 *requires* a running MMU, and that the RAM the MMU tables are located in may go away on a reset if it is autoconfig-RAM. Thus, at least you should also ensure that the MMU is either disabled (mmu.library WithoutMMU()) or ensure that the MMU tables are in chip-mem as well in a location without ROM overlay (you can create a custom MMU table with the library, and ensure by the memory allocation bits that it is in chip). You also could try that the reset, and CIA modification and jmp are in a a cache-line, i.e. aligned to a 16-byte boundary. One way or another, this type of stunt requires a bit more care on the higher processors, and it is in general advisable to rely on the os function ColdReboot() (or the patches installed therein) to do the right thing for you.

I see. Thanks for the insight. Cache line alignment I already had. I'll have a look at toying with MMU.


All times are GMT +2. The time now is 10:45.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.04887 seconds with 11 queries