Re: ROM Dump of Amiga Keyboard controller

From: Marko Mäkelä <msmakela_at_gmail.com>
Date: Fri, 27 Jun 2014 12:52:41 +0300
Message-ID: <20140627095241.GA1692@x60s>
On Thu, Jun 26, 2014 at 08:42:21PM +0200, Gerrit Heitsch wrote:
>To write a program for that, you need to supply the next byte the CPU 
>expects to Port C. This means you don't have to care about the program 
>counter, but you will need the exact timing for every 6502 instruction 
>you plan on using and remember the rudimentary pipelining. So better 
>stick to simple commands and forget about branches and stack operations 
>in the loader. To get a ROM dumper into the RAM, you'll mostly need
>
>NOP
>NOP
>NOP
>SEI

Well, keep in mind that the current instruction length is between 2 and 
something like 9 cycles.

For the record, I wrote two test programs for the Commodore 64 some 20 
years ago. The first one ran in the unmapped address space $de00-$dfff 
(running the data that was left on the bus by the video chip).

The second one ("dadb") required more effort, because it ran in the 
4-bit color RAM, getting only the high nibbles from the video chip. Most 
of the time, it would execute RTS, and most of the colour RAM was filled 
with 0. It took me a week to write the program, even though all it does 
is changing the border colour when you keep the SPACE button down.

I pointed out earlier that NOP is not a sufficient choice, because you 
will still have uncertainty which cycle you are executing. You do not 
know if the 0xea was a dummy fetch, or if it was fetched for the 
instruction decode.

Because of this, you need a final synchronization with a 3-cycle 
instruction followed by a 2-cycle instruction. The start could indeed 
look like what you suggested:

0xea 0xea (two bytes emitted for one NOP; it is 2 cycles)
0xea 0xea
...
0xea 0xea
0x68 0xea 0xea 3-cycle PHA, or 2-cycle NOP if the 0x68 was a dummy fetch
0x78 0x78 (SEI)

I am too lazy to check now, but I think that PHA and PHP are 3 cycles.  
I quoted the opcode from memory.

Actually, I think you can synchronize with just alternating 0xea 0x68, 
and it will stabilize to executing the 0xea:

... executes something, for example LDA $EA68
[0x68 0xea 0x68 optional: executes PHA]
0xea 0x68 (NOP)
0xea 0x68 (NOP)

>LDA #$xx    ; first byte of ROM dumper
>STA $00
>LDA #$yy    ; second byte of ROM dumper
>STA $01
>[...]       ; continue until last byte...
>JMP $0000
>
>The idea I have is to unroll the program into the byte sequence the 
>CPU expects. This will not necessarily be the sequence produced by an 
>assembler from your program so there is work by hand involved.

Right, you will have to supply some dummy data also while the write 
cycle of STA is executing. So, you could obtain the byte sequence with 
an assembler by just appending some single-byte instruction such as NOP 
after each STA above.

>Now, how to hand the control to the program just loaded into RAM?  
>Easiest idea would be to make sure the last byte of JMP $0000 is 
>located on a page border so that an address bit that was 0 all the time 
>before switches to 1

Could we use this idea for synchronizing the instruction fetch when we 
are in the +10V mode? For example, wait for A15 to be 0, and to get back 
to 1 while you are in the "ea 68" mode. Then, start sending the copy 
routine. When A15 gets back to 0, you know that it executed the JMP.

For the start, a simple test could be to use 1-byte instructions of 
different lengths. A 2-cycle NOP should advance the address lines faster 
than a 3-cycle PHA. Also the PHA will show "spikes" to the 0x100 page.  
You could also try BRK and watch the address lines.

If R/W is available, then you could use it for detecting if the CPU is 
executing NOP or PHA in my 0xea 0x68 example.

	Marko

       Message was sent through the cbm-hackers mailing list
Received on 2014-06-27 10:01:06

Archive generated by hypermail 2.2.0.