• Please review our updated Terms and Rules here

Choosing MP/M and CP/M disk sizes, vs. remaining RAM

That is absolutely fascinating. Though I note then it still executes from 0000h with RST0 at the end of the load - which I assume means it executes two random "bytes" that just happen to be in memory at the time of reset?

That seems like a serious omission in the strategy, or am I missing something?

It's a truly fascinating boot method. I only knew it superficially before and always assumed they read the boot sector from disk and used something like BUSRQ to allow access to the ram to write the bytes from the FDD to the RAM directly.
Where do you see the RST 0? The instruction stream from the printer controller finishes with JP 0 followed by OUT (0F8h),A. The first instruction sets PC to 0000h; the second switches to reading instructions from RAM and advances PC to 0002h. So the next instruction processed will be what's in RAM at 0002h, and that's exactly where the boot image has been generated.
 
Where do you see the RST 0? The instruction stream from the printer controller finishes with JP 0 followed by OUT (0F8h),A. The first instruction sets PC to 0000h; the second switches to reading instructions from RAM and advances PC to 0002h. So the next instruction processed will be what's in RAM at 0002h, and that's exactly where the boot image has been generated.

Sorry, not RST0, JP 0000 as you noted-

Ref:
0206 C3 JP 0000h
0207 00
0208 00

Ahh, I see, the bootstrap mode doesn't drop out until two more bytes of instructions are read from the stream following the jump - that makes sense. Seems very complex though.

Is there a practical reason why they didn't just LD DE,0 and write the bootstrap into ram from 0000h? Or DE,0100h and used A8 and M1 to trigger dropping out? Then no "JMP" needed, though I acknowledge it would cost them two bytes of bootstrap?
 
Sorry, not RST0, JP 0000 as you noted-

Ref:


Ahh, I see, the bootstrap mode doesn't drop out until two more bytes of instructions are read from the stream following the jump - that makes sense. Seems very complex though.

Is there a practical reason why they didn't just LD DE,0 and write the bootstrap into ram from 0000h? Or DE,0100h and used A8 and M1 to trigger dropping out? Then no "JMP" needed, though I acknowledge it would cost them two bytes of bootstrap?
No idea why they made the choices they did. On the surface it looks as if it could work with DE holding any value from 0000h-3E00h as long as the final jump was to that address minus 2. Maybe that's just how it emerged from the development process.
 
No idea why they made the choices they did. On the surface it looks as if it could work with DE holding any value from 0000h-3E00h as long as the final jump was to that address minus 2. Maybe that's just how it emerged from the development process.
Just studying the details of the PCW a little bit, it does not seem unreasonable to do what they did. Considering the intended market, constraints on PCB real estate, and the fact that they were already designing a custom ASIC, it seems like a perfectly respectable choice. Placing a "full citizen ROM" on the board would have been a waste. Regarding their choice of instructions used to boot, not having been in the trenches with them I don't presume to know better. The answer is probably in studying what they did without presuming to think something else is better. I would make the initial assumption that they knew what they were doing and our hindsight is inadequate to understand.
 
Injecting an entire bootstrap into the z80 by sending it bytes on obscured memory reads is pretty full on. It makes my previous ideas to add a coprocessor to a z80 seem simple by comparison.

It wouldn't take too much logic to encode that bootstrap. There's only a few discrete instructions, a basic state machine and a counter involved - and I'll guess that the printer chip also does some decoding of memory signals to make it all work.

But if even @JohnElliott doesn't know the reason, I doubt we will ever find out the full thinking behind it. :(
 
Not to drag this any further off topic, but looking at the Amstrad "forced code" I think it's a bit clearer. The force-fed code does not look at the address bus, but simply feeds the instruction stream to the CPU. I think that is the reason they do 256 LDI instructions instead of an LDIR. The LDIR operates by hold the PC at the instruction start and effectively repeating the LDIR instruction until B==0. But that won't work if the force-feed mechanism isn't watching the PC. Basically, until the OUT 0F8H instruction executes, the PC is irrelevant. I'm not sure how they are differentiating between the instruction byte fetches and the memory accesses of the LDIs, though. The M1 signal identifies the opcode bytes, but not the operand fetches for OUT, LD DE, and JP. So mysteries remain. Since this forced-code is coming from the main ASIC directly connected the CPU (while the code it loads is apparently coming from the printer controller ROM), it's possible that ASIC is aware of the exact byte stream to fetch and thus differentiates instruction bytes from data bytes that way (possibly "seeing" the LDI and enabling a separate mechanism for the subsequent data read - i.e. the next /MREQ+/RD after fetching the LDI is always to printer controller ROM).
 
The printer controller doesn't have to care whether the fetches are instructions or data. It just generates a stream of 779 bytes:
Code:
write_boot:
    mov    r2,#6        ; 0192 - ba 06    :.    ; Write 6 bytes
    mov    r3,#0beh    ; 0194 - bb be    ;>    ; starting at X00BE
    call    data2z80    ; 0196 - 34 ab    4+
    mov    r0,#0        ; 0198 - b8 00    8.    ; Write 256 bytes
write_image:
    mov    a,#0edh        ; 019a - 23 ed    #m    ; Write LDI
    call    byte2z80    ; 019c - 34 b3    43
    mov    a,#0a0h        ; 019e - 23 a0    # 
    call    byte2z80    ; 01a0 - 34 b3    43
    mov    a,r0        ; 01a2 - f8    x    ; followed by byte R0
    movp3    a,@a        ; 01a3 - e3    c    ; from page 3
    call    byte2z80    ; 01a4 - 34 b3    43
    inc    r0        ; 01a6 - 18    .
    djnz    r2,write_image    ; 01a7 - ea 9a    j.
    mov    r2,#5        ; 01a9 - ba 05    :.    ; Then write 5 bytes
data2z80:
    mov    a,r3        ; 01ab - fb    {
    movp    a,@a        ; 01ac - a3    #
    call    byte2z80    ; 01ad - 34 b3    43
    inc    r3        ; 01af - 1b    .
    djnz    r2,data2z80    ; 01b0 - ea ab    j+
    ret            ; 01b2 - 83    .
;
byte2z80:
    mov    r1,#0        ; 01b3 - b9 00    9.    ;Write the data byte
    movx    @r1,a        ; 01b5 - 91    .    ;to external RAM
    mov    a,#0ffh        ; 01b6 - 23 ff    #.    
    anld    p7,a        ; 01b8 - 9f    .        
    inc    r1        ; 01b9 - 19    .    ;
;
; Wait for the Z80 to acknowledge the byte. Do this by reading external RAM
; (address 1) and waiting for bit 0 to go (I think) low.
;
X01ba:    movx    a,@r1        ; 01ba - 81    .    ;Wait for Z80 to
    jb0    X01ba        ; 01bb - 12 ba    .:    ;swallow byte
    ret            ; 01bd - 83    .
;
;Z80 boot sequence
;
    db    0AFh        ; XOR A
    db    0D3h, 0F0h    ; OUT (0F0h), A
    db    11h, 2, 0    ; LD DE, 2
;
; Data transferred here
;
    db    0C3h, 0, 0    ; JP 0
    db    0D3h, 0F8h    ; OUT (0F8h),A ; end bootstrap;
;
Not depending on the address means that it doesn't matter what address the Z80 was executing from at the point the boot sequence was triggered. Obviously at a cold start it will be 0, but if it was triggered by an OUT 248,1 then the Z80 program counter could be anything.
 
Not to drag this any further off topic, but looking at the Amstrad "forced code" I think it's a bit clearer. The force-fed code does not look at the address bus, but simply feeds the instruction stream to the CPU. I think that is the reason they do 256 LDI instructions instead of an LDIR. The LDIR operates by hold the PC at the instruction start and effectively repeating the LDIR instruction until B==0. But that won't work if the force-feed mechanism isn't watching the PC. Basically, until the OUT 0F8H instruction executes, the PC is irrelevant. I'm not sure how they are differentiating between the instruction byte fetches and the memory accesses of the LDIs, though. The M1 signal identifies the opcode bytes, but not the operand fetches for OUT, LD DE, and JP. So mysteries remain. Since this forced-code is coming from the main ASIC directly connected the CPU (while the code it loads is apparently coming from the printer controller ROM), it's possible that ASIC is aware of the exact byte stream to fetch and thus differentiates instruction bytes from data bytes that way (possibly "seeing" the LDI and enabling a separate mechanism for the subsequent data read - i.e. the next /MREQ+/RD after fetching the LDI is always to printer controller ROM).

It's easier to understand by thinking of LDI not as LDI, but as "Read from RAM, Write to RAM" - HL is ignored, and as you note, BC is irrelevant, so neither have to be acknowledged.

M1+RD+MREQ indicates it's time to load the "LDI" onto the data bus. !M1+RD+MREQ Indicates it's time to load program data onto the bus. It could use the address bus, but as it's not connected to the system address but, it must use a counter that would exist internally.

But the printer IC can't see any of the signals it needs to do this.

ref: https://www.retroisle.com/amstrad/pcw/Technical/Hardware/pcw_cpu.gif

pcw_cpu.gif

Then needs to be something to maintain state - but the printer chip doesn't see M1, so it's clear this is happening within the gate array, and the gate array is also preventing RAM data being sent to the data bus while reading the bootstrap. It looks like extra signals are sent to the printer chip to set it up to transfer it's data sequentially. Given there are bidirectional data bus signals involved and both ICs are active during the bootstrap, it's entirely possible and quite likely that the LDI command isn't coming from the printer chip itself, but is a response from the gate array since it's controlling state - and 256 bytes of transfer might back onto some other counter within the gate array that is necessary for something else - which potentially eliminates the need for an additional counter dedicated to the bootstrap, though there must still be a counter in the printer IC to track which byte it's sending in the bootstrap code.

Also, the gate array would disable RAM reads, because it is the interface to the DRAM, effectively presenting the RAM data to the CPU - There is no direct connection between the RAM and the CPU - so tristating itself when it knows the printer chip is sending information isn't a huge imposition.

I always used to think the gate array ran the full bootstrap, but it's interesting to note they used the printer controller IC for the data rather than the gate array.

Amstrad was always looking to save a few dollars, so this might have been little more than a way to avoid paying for an EPROM when they had extra chip-based real-estate in the printer IC. It also would make it difficult to copy the PCW, which would have been an Amstrad concern at the time.

Though that's just conjecture.

On the topic of interesting use of LDI and block commands, and to get back to the original topic, when mapping RAM to DISK space through hardware via I/O, I mentioned earlier that you can only use OTDR and INDR and not OTIR and INIR -

This is because the counter is provided by the z80 then, and you can use the upper address lines A8 to A15 to transfer up to 256 bytes of memory using the z80 block commands -

The reason for this is that A8 to A15 reflect the state of the C register which is decremented during block commands, and if being used as an index to RAMDISK, you need to ensure the destination counter (DE) is locked to the C register.

This method contrasts to the Amstrad method by using the z80 address bus to indicate which byte in RAM is being selected through I/O commands.
 
M1+RD+MREQ indicates it's time to load the "LDI" onto the data bus. !M1+RD+MREQ Indicates it's time to load program data onto the bus. It could use the address bus, but as it's not connected to the system address but, it must use a counter that would exist internally.
It is not sufficient to simply assume !M1+RD+MREQ means fetch from printer controller, as that bus cycle is also used to fetch operand bytes from the instruction stream. The ASIC would have to know that a read cycle was not part of instruction fetch, which the Z80 gives no indication for. Also, the ASIC handles all I/O cycles as well, so it knows when the end of the pre-boot code is reached due to the OUT instruction there, and changes state back to actually fetching from memory.

Remember that the Z80 is still the one executing instructions, and so the LDI is still an LDI. Unless the ASIC understand that an LDI is being executed, it can't tell the difference between operand fetches (for example for the JP instruction that follows or the LD DE one that precedes) vs. printer controller data fetches (when the LDI reads (HL)). The LDI includes two M1 cycles, some number of internal cycles, and one read and one write cycle.

The ASIC has all the address lines, so we don't really know to what extent it looks at them. The hints are the JP 0000 instruction and the fact that the bootstrap code begins at 0002.
 
Seems pretty clear to me that in boot mode the address lines work normally when writing but are completely ignored when reading.
 
Yes, it's highly likely that the address lines go directly to the DRAM and I/O decode logic, and the boot logic gets none. The XOR A; OUT 0F0H probably resets the printer controller ROM address to 0 (perhaps some other things). And OUT 0F8H (with A=0) turns off "boot mode", which is likely turned on by RESET. I suspect the LDI instructions were detected by the ASIC so that the data read cycle could be redirected. As was previously noted, they could probably get by with never changing this and only the 256-byte block in the printer controller did the heavy lifting of booting off floppy and might need to change over time.
 
Seems pretty clear to me that in boot mode the address lines work normally when writing but are completely ignored when reading.

The address lines are working normally when reading as well, and the RAM is most likely responding with MREQ read to wherever HL is pointing as per normal LDI process.

But it would be trivial for the gate array to simply not place the RAM response onto the data bus when it knows the Printer Controller IC is responding, since it controls the boot signal, and also buffers the RAM-Data-BUS to the CPU-Data-Bus.

Yes, it's highly likely that the address lines go directly to the DRAM and I/O decode logic, and the boot logic gets none. The XOR A; OUT 0F0H probably resets the printer controller ROM address to 0 (perhaps some other things). And OUT 0F8H (with A=0) turns off "boot mode", which is likely turned on by RESET. I suspect the LDI instructions were detected by the ASIC so that the data read cycle could be redirected. As was previously noted, they could probably get by with never changing this and only the 256-byte block in the printer controller did the heavy lifting of booting off floppy and might need to change over time.

The address lines go to the DRAM only through the gate array, which includes the muxes for the DRAM, but there's little achieved through extra circuitry to stop the addresses getting sent to the DRAM. It's only conjecture, but from a hardware design perspective it's easier to just never place the data on the bus than it is to block the DRAM in the first place.

I suspect the ASIC doesn't detect the LDI instructions, but *generates* them. There is no need for the Printer Controller to generate the LDI - the state is controlled by the ASIC (Gate Array). All the Printer Controller would have to do is send the bytes when it's accessed.

It has two possible pins it can use to achieve that - NBOOT and NRESET.

NRESET could reset the counter for bytes out and NBOOT could be the result for !M1+MREQ+READ when it's in the mode for sending the bootstrap bytes - in which case it would know nothing about the LDI or other commands being formed - they would come from the ASIC.

I'm not sure how it could generate the full data stream - there's simple not enough signals going to it to manage state that way.

I'm guessing that NBOOT oscillates at boot, and it would be possible to connect NBOOT to an I/O address and "read" the entire bootstrap sequence via I/O commands also as a way of recording them without observing with test equipment.
 
I suspect the ASIC doesn't detect the LDI instructions, but *generates* them. There is no need for the Printer Controller to generate the LDI - the state is controlled by the ASIC (Gate Array). All the Printer Controller would have to do is send the bytes when it's accessed.
The printer controller does generate the LDI - check the code at write_image: in my disassembly in post #47.
 
The printer controller does generate the LDI - check the code at write_image: in my disassembly in post #47.

I was going off the line from the other site you referenced which made it unclear what was being generated where it says:
"This suggests that whatever is providing the data (gate array and/or printer controller) is ignoring the address lines for memory fetches,and returning a pre-ordered sequence of data for both program anddata fetches."

And I assumed it was being generated and stored in programmable logic ICs, but I was completely wrong...

I missed that it was a MCS-48 processor entirely - so it appears it's using it's own ROM to store the bootstrap and is sending this via the host bus for the data stream.... OK, then clearly the timing is pretty critical and I can understand why they do it that way now if it's a MCS-48 rather than a custom chip.

... So the printer chip doesn't care if it's an instruction read or a data read - It just knows that the read sequence from the z80 is going to expect a byte and it simply feeds the "byte" sequence - first the LDI, then the subsequent read for the memory - down to the z80...

That's a fascinating approach to take - Thank you for correcting me. I didn't pick up on the significance of the code not being z80 oriented at first and missed that completely.

In that case, how Amstrad approached the bootstrap makes a LOT of sense - An 8041 is pretty efficient cycles-wise and if it's running at 11MHz I can see why they took that approach entirely - the host interface would appear like a sequential ROM.

Thank you :)
 
The printer controller does generate the LDI - check the code at write_image: in my disassembly in post #47.
My point being that the ASIC must maintain some sort of "context" status based on whether the currently executing instruction is LDI or something else. The distinction between "detects LDI" and "detects that it is generating LDI" is non existent. It all depends on how much of this sequence is hard-code vs. a generic stream of bytes to be fed to the CPU - i.e. an implementation detail.

And don't focus on the printer controller chip as having to know that an LDI is being executed. There are signals between the ASIC and printer controller to tell it when to load the next byte from ROM, that's all that is needed. It is the ASIC that knows when a read cycle from the CPU needs to be passed to the printer controller vs. DRAM vs. boot sequence - and for that it must know the context of a particular read cycle from the CPU (e.g. LDI vs. other instructions).
 
My point being that the ASIC must maintain some sort of "context" status based on whether the currently executing instruction is LDI or something else. The distinction between "detects LDI" and "detects that it is generating LDI" is non existent. It all depends on how much of this sequence is hard-code vs. a generic stream of bytes to be fed to the CPU - i.e. an implementation detail.

And don't focus on the printer controller chip as having to know that an LDI is being executed. There are signals between the ASIC and printer controller to tell it when to load the next byte from ROM, that's all that is needed. It is the ASIC that knows when a read cycle from the CPU needs to be passed to the printer controller vs. DRAM vs. boot sequence - and for that it must know the context of a particular read cycle from the CPU (e.g. LDI vs. other instructions).

I don't see why the ASIC needs to know anything about the LDI instruction - and since there's an OUT command to finish things off, that the ASIC clearly decodes, it probably uses this as a signal that the transfer of ROM from the MCS-48 is complete, and allows the RAM to respond to reads again...

The boot only occurs post-reset, and the read sequence ( pure memory reads ) is determinate until completion - It never changes for a given sequence of bytes. There is no state transfer, only reads that are known in advance. State can be determined from that, but if it's just a "recording" that the MCS-48 plays back based on it's ROM data, then there's not even a need to know the state.

All that is required is for the Printer Controller chip to respond to reads and know that it should respond in a specific way.

Have a look at the 8041 code @JohnElliott posted earlier that is executing inside the printer chip... I missed that the first time I read it too. If you change any instruction then you'd also need to change how the code plays back, but functionally, it's just predicting what the CPU is expecting...

If there was any variation to this - eg, an interrupt or an NMI? Then it would absolutely break it. But as long as that doesn't occur ( and z80 disables maskable interrupt on reset ) then there's no problem.

I suspect it would be possible to change the code in the Printer Controller and as long as the read sequence is predicted, it will still work, even if you used something other than LDI - ie, you could probably send other instructions like;

LD HL,$0002
LD B,$00
LOOP:
LD A,(1234) ; Any random address will do.
<-- Insert byte to write into stream here...
LD (HL),A
DJNZ LOOP
XOR A
JMP $0000
OUT ($F8),A

It would be longer to boot and consume more 8041 memory... But would still work. So LDI is a very convenient instruction for this purpose.
 
I don't see why the ASIC needs to know anything about the LDI instruction - and since there's an OUT command to finish things off, that the ASIC clearly decodes, it probably uses this as a signal that the transfer of ROM from the MCS-48 is complete, and allows the RAM to respond to reads again...
...
The primary purpose of the ASIC is to decode the Z80 address and control signals and respond appropriately (in the case of reads, by placing data on the data bus - possibly after asserting /WAIT). During "boot", that decoding has to know whether to supply data from this "boot stream" or from the printer controller ROM. There is no way to differentiate the Z80 read cycle for the "0002" in "LD DE,0002" from the read cycle from (HL) in the "LDI". So, the ASIC probably has state information to understand what the next read cycle is. It is unlikely that the ASIC actually has 256 "LDI" instructions stored in it, so maybe it is more of a "256 x LDI" representation, in which case that state information is implied by the presence of this instruction multiplier. You have to remember that these ASICs of 1985 were not the kinds of megaliths we have today. They had to accomplish their functions with relatively simple logic (by comparison).
 
Last edited:
The primary purpose of the ASIC is to decode the Z80 address and control signals and respond appropriately (in the case of reads, by placing data on the data bus - possibly after asserting /WAIT). During "boot", that decoding has to know whether to supply data from this "boot stream" or from the printer controller ROM. There is no way to differentiate the Z80 read cycle for the "0002" in "LD DE,0002" from the read cycle from (HL) in the "LDI". So, the ASIC probably has state information to understand what the next read cycle is. It is unlikely that the ASIC actually has 256 "LDI" instructions stored in it, so maybe it is more of a "256 x LDI" representation, in which case that state information is implied by the presence of this instruction multiplier. You have to remember that these ASICs of 1985 were not the kinds of megaliths we have today. They had to accomplish their functions with relatively simple logic (by comparison).

I also thought this, until John gave me a subtle correction - then I realized otherwise - the actual solution is much simpler. I didn't get it at first either.

I'll try to explain it in a simpler way - though if you don't get it, it's probably just that I'm not as good at explaining it as I want to be.

So I'll do it as a table showing pure reads, ignoring M1 and other signals - just looking at how the ASIC sees RD and MREQ.

First, on reset, the z80 does a read. The ASIC is aware of the reset, so it switches ram READs off - likely by disabling the output buffer it controls between the RAM and the Data Bus. The Boot signal from the ASIC to the 8041 is likely what tells the 8041 to start sending bytes.

From the z80 perspective.

z80 reads an opcode. 8041 sends AF (XOR A)
z80 reads an opcode. 8041 sends 0A (Out)
z80 reads an operand. 8041 sends F0 (Port F0)
z80 reads an opcode. 8041 sends 11 (LD DE)
z80 reads an operand. 8041 sends 02
z80 reads an operand. 8041 sends 00
... The next four sequences are repeated 256 times.
z80 reads an opcode. 8041 sends ED (AfterED)
z80 reads an opcode2. 8041 sends A0 (LDI)
z80 reads an operand. 8041 sends a byte of BOOTSTRAP which it reads from it's code memory.
z80 writes an operand.8041 does nothing. RAM is written to the PC, which starts at 0002h and increments once per cycle.
... Then it closes.
z80 reads an opcode. 8041 sends C3 (JP )
z80 reads an operand. 8041 sends 00
z80 reads an operand. 8041 sends 00
z80 reads an opcode. 8041 sends D3 (out)
z80 reads an operand. 8041 sends F8 (Port F8)
... The ASIC likely sees this as the trigger to turn off the BOOTSTRAP loader and connect RAM for reads once again.
z80 executes code from RAM at location 0002h


Now consider this from the 8041 perspective. It has no idea what the z80 is doing. All reads during boot are an I/O read sent to the 8041, with BOOT set.
IO boot read. 8041 sends AF (XOR A)
IO boot read. 8041 sends 0A (Out)
IO boot read. 8041 sends F0 (Port&nbsp;F0)
IO boot read. 8041 sends 11 (LD DE)
IO boot read. 8041 sends 02
IO boot read. 8041 sends&nbsp;00
... The next three sequences are repeated 256 times.
IO boot read. 8041 sends ED (AfterED)
IO boot read. 8041 sends A0&nbsp;(LDI)
IO boot read. 8041 sends a byte of BOOTSTRAP which it reads from it's code&nbsp;memory.
... Then it closes.
IO boot read. 8041 sends C3 (JP )
IO boot read. 8041 sends&nbsp;00
IO boot read. 8041 sends 00
IO boot read. 8041 sends D3 (out)
IO boot read. 8041 sends F8 (Port F8)
... Boot trigger turns off. New reads and writes are probably related to the printer now.

There is zero requirement for state outside of knowing that the system is booting, and turning the boot sequence off, which probably is caused by the out (F8),A command.

The printer chip and the ASIC have no idea whether the z80 is doing an opcode or operand read. All they care about is that it's reading memory.... Like a mum feeding a hungry baby - she has no idea if the baby wants food or not - but every time the mouth opens, the spoon goes in... When the head turns away, feeding is complete.

It's not difficult to make the logic for this - The ASIC only needs a single bit latch, hanging off of a port, and when reset occurs, it disables it's bus output until it gets the final I/O access, and it just triggers the Printer Chip I/O RD for each Mem-RD it gets during this time.

The 8041 simply becomes a serial ROM.

This is actually a very elegant way of sending the bootstrap code... I love it - :) I completely misunderstood it before this.
 
I also thought this, until John gave me a subtle correction - then I realized otherwise - the actual solution is much simpler. I didn't get it at first either.

I'll try to explain it in a simpler way - though if you don't get it, it's probably just that I'm not as good at explaining it as I want to be.

So I'll do it as a table showing pure reads, ignoring M1 and other signals - just looking at how the ASIC sees RD and MREQ.
....
It sounds like you are in violent agreement with me, you just may not realize it. When you describe what the ASIC is doing when sending the LDI op codes to the Z80, and then knows it has to service the next read cycle differently than others, you are describing knowledge of a special state for the LDI vs. other instructions. That is what I've been saying. Your description is missing the fact that the ASIC only sees Z80 reads cycles and must have "context" in order to interpret those. Non-boot context results in reading from DRAM. Boot context results in "reading" the byte stream programmed into the ASIC, and "Boot + LDI" context means the next read cycle results in reading from the printer ROM.
 
It sounds like you are in violent agreement with me, you just may not realize it. When you describe what the ASIC is doing when sending the LDI op codes to the Z80, and then knows it has to service the next read cycle differently than others, you are describing knowledge of a special state for the LDI vs. other instructions. That is what I've been saying. Your description is missing the fact that the ASIC only sees Z80 reads cycles and must have "context" in order to interpret those. Non-boot context results in reading from DRAM. Boot context results in "reading" the byte stream programmed into the ASIC, and "Boot + LDI" context means the next read cycle results in reading from the printer ROM.

It's possible and I may be misunderstanding what you're explaining. To me it sounds like you're saying the ASIC follows state by monitoring the LDIs when I'm thinking that it doesn't care or can even see what byte the 8041 sends to the z80 or what read cycle the z80 is making. I don't think it monitors M1 for this either, or write for that matter. Just RD and MREQ.

I don't think it needs context of what the read cycle means since the sequence is deterministic.

I think it's just as John said. Post reset there are 779 reads before an "Out (F8),A" drops the ASIC out of boot mode. I think as long as you withhold the Out (F8),A you can send whatever opcodes and operands you like to the z80, as long as it's sequence is known.

The ASIC definitely sees z80 write cycles too, and redirects those to the DRAM. Otherwise the bootstrap won't be written. But the only bytes it sees during the bootstrap writing are z80 writes - and there's only 256 of those.


If what I said makes sense and sounds right to you, then you're correct that I'm in violent agreement with you and it's just my limitation in that I can't quite understand the way you're saying it.
 
Back
Top