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 listReceived on 2014-06-27 10:01:06
Archive generated by hypermail 2.2.0.