Changes

V9990

2,974 bytes added, 13:44, 11 May 2021
LD BC,&FF64
LD A,14
OUT (C),CA
LD BC,&FF63
LD A,0
LD BC,&FF64
LD A,14
OUT (C),CA
LD BC,&FF63
LD A,3
LD BC,&FF64
LD A,14
OUT (C),CA
LD BC,&FF63
LD A,3
LD BC,&FF64
LD A,14
OUT (C),CA
LD BC,&FF63
LD A,2
* The 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 P#0 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.
For a vram size of 512KB this gives image space heights of &1000,&800,&400,&200,&100 and &80.
 
* Confirmed with PSET, BMLX and LMMC. When calculating the logical vram address of each line:
1) P1 mode is always 256 pixels wide, 4bpp (width (XIMM) and bpp (CLRM) settings with R6 are ignored). Therefore logical vram address of Y is defined as: (256/2)*y.
2) P2 mode is always 512 pixels wide, 4bpp (width (XIMM) and bpp (CLRM) settings with R6 are ignored). Therefore logical vram address of Y is defined as: (512/2)*y
3) In bitmap mode width (XIMM) and bpp (CLRM) settings are used. HSCN and C25M are ignored. Therefore logical vram address of Y is defined as: XIMM/4 when 2bpp, XIMM/2 when 4bpp, XIMM when 8bpp and XIMM*2 when 16bpp.
4) For the command-engine, standby mode is identical in operation to the bitmap mode.
5) Although the logical vram address of each line is calculated this way, a lot of the operations act as if it is in bitmap mode and when plotting pixels take into account the bpp setting from CLRM.
=== Registers ===
So you need to know when each mask register is used and you need to understand the logical->physical VRAM mapping.
 
===== Write Mask in P1 mode =====
 
* Document states "In P1 mode, writing is prohibited on the side not specified as the transfer destination. (Layer "A":R#46, Layer "B":R#47)". I haven't discovered what this actually means yet.
===== Write Mask in bitmap and standby modes =====
* 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.
 
* CE will be set to 1 in status when operation has started. CE will be set to 0 in status when operation has completed. CE will be set to 1 in interrupt when operation has completed.
==== Command Recommendations ====
* Always set NX,NY before using LMMV especially in P1 mode. If you don't do this then the command may hang.
 
==== CMMC ====
 
* Data written by CPU is byte by byte and it is 1 bit per pixel. Each byte therefore represents 8 pixels. If the value of a bit is 0 then background colour register is used for pixel, if bit is 1 then foreground colour register is used for pixel. Data is used bit 7 first, 6 is next, all the way down to bit 0.
 
* Font is defined left to right, top to bottom, line by line. It doesn't follow the same form as Kanji ROM.
 
* If NX is not a multiple of 8, then unused bits are used on the next line. i.e. the command uses all 8 bits until they are exhausted at which point another byte is fetched and so on.
 
* Pixels are written according to physical vram. Foreground low byte is for physical VRAM0. Background low bytes is for physical VRAM 1. Foreground high byte is for physical VRAM1, and background high byte is for physical VRAM 1.
 
* To draw a font in the same colour ensure the same colour is repeated for all pixels in FC and BC (i.e. for 8 bit mode set FC upper and lower byte to the same, and set BC upper and lower byte to the same.)
 
* For LOP, SC comes from background colour or foreground colour depending on the value of the bit.
 
* NX and NY can be any size, they are not restricted to 16x16.
 
==== CMMM ====
 
* This is similar to CMMC except data is read from VRAM and not from the CPU.
 
==== CMMK ====
 
* This command is similar in operation to CMMM.
 
* This command will operate without Kanji ROM.
 
* It is not clear where the pixel data is coming from when no Kanji ROM is connected. It is not forced to ff or 0. It also doesn't come from vram. What is often seen is that the first 2 bytes are different from the rest, then the remainder of the bytes are the same and look to be based on BC low byte bit value.
==== POINT ====
==== 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 stablisedpredicted or forced.
* 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 ====
 
* To know if a match has been found always look at the status bit. BD will be 1 for a match and 0 for no match. The border x coordinate is always set to something even if there is no match.
* When searching sx and sy are masked before use. If the width is 256, then sx is masked with 255 before use.
* When searching forwards, if no match is found then a multiple of the width is reported depending on sx. If sx<width then width is reported, if width<sx<width*2 then width*2 is reported etc. The "match" flag will not be set as expected.
 
==== BMLX ====
 
* When DIX=1, under some conditions the two bytes at the start of the first line are in a different order than expected.
==== BMXL ====
* 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.
 
==== LMMC ====
 
* A new byte is fetched only when the pixels for that byte have been exhausted. Therefore for 2bpp is NX is not a multiple of 4 and for 2bpp NX is not a multiple of 2 then the remaining pixels from the byte will be used on the next line.
==== LMMV ====
- The internal X and Y coordinates are incremented or decremented based on AXE, AXM, AYE and AYM. The internal x and y will wrap within the width and height of the display. The width is wrapped using masking. e.g. When the screen is 256 pixels wide, x is 0 and is decremented it will wrap to 255 and if x is 255 and is incremented it will wrap to 0. The same is true of the Y coordinate.
* With the command engine, tested on PSET currently (but to be confirmed for other commands):
1) P1 mode is always 256 pixels wide, 4bpp (width (XIMM) and bpp (CLRM) settings with R6 are ignored). Therefore logical vram address of Y is defined as: (256/2)*y.
2) P2 mode is always 512 pixels wide, 4bpp (width (XIMM) and bpp (CLRM) settings with R6 are ignored). Therefore logical vram address of Y is defined as: (512/2)*y
3) In bitmap mode width (XIMM) and bpp (CLRM) settings are used. HSCN and C25M are ignored. Therefore logical vram address of Y is defined as: XIMM/4 when 2bpp, XIMM/2 when 4bpp, XIMM when 8bpp and XIMM*2 when 16bpp.
4) For the command-engine, standby mode is identical in operation to the bitmap mode.
[[Category:HardwareElectronic Component]]
897
edits