Changes

Jump to: navigation, search

V9990

804 bytes added, 20:28, 19 January 2019
- Register 27 (PRIORITY CONTROL): Mask is &FF
* VRAM read/write via registers, 0,1,2 and 3,4,5 and port 0 use *logical* addresses and not physical addresses. Writing in one mode, and then reading back in another can yield different data in a different order because the addresses are translated from physical to logical to physical based on the mode.
* Register index is masked with &3f. This means reading "register 64 " is the same as reading register 0.
=== Interrupts ===
* After rest all registers are reset to 0.
* The elected selected register (port 4) is set to 0 and port read and write increment is not inhibited.
* If reset is held using the "software reset" then reading or writing to the VRAM data port will cause the CPC to hang. I believe the V9990 is continuously asserting /WAIT to the Z80 but I can't confirm through code.
* Reset will stop any commands in progress and will clear pending interrupts.
* If reset is held: 3,4,7,8,9,10,11,12,13,14 and 15 reads databus, port 1 reads 0, port 5 and 6 read status,.
=== VRAM ===
* In terms of physical addresses, if you consider physical address 0-&3ffff to be VRAM0 and physical address &40000-&7ffff to be VRAM1, then in P1 mode, the physical address equals logical address and in bitmap modes, every even address maps to &0-&3ffff (ever every even is VRAM0) and every odd address maps to &40000-&7ffff (VRAM 1). This is described in the PDF.
* setting a partial vram write address is ok(not setting completed address with r0,r1 and r2 ). e.g. set r0,r1,r2 to &80000, now set r1 to 1. Write will go to 000001. Now set r2 to 2. Write will go to 000201. Now set R3 to 3. Write will go to 030201. There doesn't appear to be a write buffer.
* v9990 seems to have a 1 byte read buffer. Setting a partial address (not setting complete address with r3,r4 and r5) and the reading vram from port 0 will return the data from the previous address for the first read, but further reads returns correct values. This is only true of r3 and r4. e.g. set r3,r4,r5 to &80000. Now set r3 to 1. First read will come from &000000, second and subsequent reads now come from &000001. Now set r4 to 2. First read comes from &000001, second and subsequent reads come from &000201. Now set r5 to 3. First read comes from &030201, subsequent reads come from &030201.
* If vram size is set to 128KB a byte is written through port 0 and then vram size is set to 512KB you can read throught port 0 the same byte in multiple locations. The written data is effectively mirrored in the address space. The PDF describes part of this because it describes recommended addresses to use where the location is common to all vram sizes.
== Command Engine ==
=== VRAM '11' ===
* When VRAM size is set to '11' ('10' is 512KB), the result appears to be the same as for resulting operations and vram size act like a vram size of 512KBwas set.
=== 'Stand-by mode' ===
* "Stand-by mode" where both bits of DSPM are 1 appear to be identical in operation to the bitmap mode when display is enabled. The vram is read/write just like in vram mode. The PDF claims that Kanji ROM is accessible. I didn't see with the CPC Powergraph.
=== Coordinates ===
height = vram size bytes / image space width in bytes;
For a vram size of 512 512KB this gives image space heights of &1000,&800,&400,&200,&100 and &80.
=== Registers ===
* R46 (Write mask) is used when writing to physical VRAM0.
* R47 (Write mask) is used when writing to physical VRAM1.
* Testing indicates write mask takes effect just before the write to VRAM is committed.
So you need to know when each mask register is used and you need to understand the logical->physical VRAM mapping.
* Registers specific to each command can be initialized in any order. "op" register (R52) should be written last so that it uses the correct register settings.
* To ensure full and correct operation it is advised to set ALL registers that a command uses. Repeat execution of a command and only setting the registers once can give incorrect operation sometimes. * Always setup DY before commands that use it. There is a bug where pixels may not be committed to the expected vram location. Seen with lmmv LMMV instruction. * Always set NX,NY before using LMMV especially in P1 mode. If you don't do this the command may hang.
==== POINT ====
x = 0
aaxxxxx in 2bpp and 4bpp bitmap modes where pixels may not be committed to vram if DY is not always set.It seems related to DX=1, not setting DY, NX is less than 2 bytes worth of data. 
x = 1
bbxxxxx
ddxxxxx
* The undefined 'x' bits are from the upper byte when doing of a proceeding 16-bit pixel readPOINT command. If the data in vram is &34,&12. A 16-bit pixel is &1234. A read in 2bpp/4bpp will use the bits from &12 from that operation. Therefore to force these bits do a 16-bit read of a known value, then do the 2bpp/4bpp read.
==== BMLL ====
* If source and destination ranges overlap then there can be some unexpected data written. You should avoid overlapped areas or keep them at least 2 bytes apart. Result of overlapping areas can differ between runs. Investigation is going on to determine how this data can be stablised.
* When DIX=0, then both source and destination vram addresses are incremented. When DIX=1, then both source and destination vram addresses are decremented.
* I can't currently see what DIY does in respect of BMLL. It seems it has no effect. This may be an error in the documentation.
==== SRCH ====
* When the vram address is calculated from dx and dy, dx and dy are masked before use.
This means that transfer wraps within the same line and column. i.e. if drawing in reverse and overlapping x=0, and width is 256, then pixels will wrap to 256-x on the same line and if overlapping x=256 then pixels will wrap to 0.
==== LMMV ====
 
As recommended in the PDF set FC so that the same pixel is in all bits for the chosen mode, otherwise the result may not be what you expect.
* LMMV seems to operate as if it is in bitmap mode all the time.
* For LOP, SC comes from FC when applied to LOP.* When DIX=0, then FC low then FC high are used. The value restarts each row line and FC high/low are not directly related to physical VRAM like WM is.e.g. When 8bpp, fc=&1234, DIX=0 and nx=4 then after LMMV has executed we will see the bytes in vram: &34,&12,&34,&12.* When DIX=1, then the result is a bit strange, it depends . The order FC is used switches depending on the DX value.
===== LMMV - P1 mode =====
* In P1 mode, LMMV seems to operate as if in bitmap mode.
* For 2bpp,4bpp and 8bpp, low byte of FC is always read for the colour. FC high byte remains from the last bitmap LMMV command. i.e. To set define the upper byte of FC for subsequent LMMV commands in P1 mode, set bitmap mode, setup LMMV, set FC, set NX>1 and do execute LMMV command. If x is even, you must set nx to 2, if x is odd nx is min 1. All of these explain why it is best that FC is filled with the same data for each pixelNow execute commands in P1 mode.
==== ADVN ====
==== PSET ====
* For LOP, SC comes from FC when applied to LOP.
* The internal x and y coordinates are validated masked before use by masking them. When width is 256 then mask is 0x0ff, when 512 the mask is 0x01ff, when 1024 the mask is 0x03ff and when 2048 the mask is 0x07ff. Therefore attempting to write to x=300 on a 256 width wide screen actually writes to pixel x=0x02c because it is masked before use.
* During testing I found that the 'advance' part of the PSET command differs slightly from the official document.
- The document claims that when AXE and AXM bits of the command are 0 then both DX and DY registers are read and the internal x and y are updated. I didn't find this. I found that when AXE and AXM are 0 then only the DX register is read and the internal x coordinate is updated from it. DY is not read at this time. Testing also shows this happens at the start of PSET command execution.
- If DY register is written the internal y coordinate is updated immediately. Writing to both register 38 and 39 update the internal y coordinate.
2,541
edits