@nataliapc/mcp-openmsx
Version:
Model context protocol server for openMSX automation and control
1,159 lines (951 loc) • 127 kB
Markdown
# CHAPTER 4 - VDP AND DISPLAY SCREEN (Section 6)
## 6. VDP COMMAND USAGE
MSX-VIDEO can execute basic graphic operations, which are called VDP commands. These are done by accessing special harware and are available in the GRAPHIC 4 to GRAPHIC 7 modes. These graphic commands have been made easy to implement, requiring only that the necessary parameters be set in the proper registers before invoking them. This section describes these VDP commands.
<p> </p>
## Index
- [6. VDP COMMAND USAGE](#6-vdp-command-usage)
- [6.1 Coordinate System of VDP Commands](#61-coordinate-system-of-vdp-commands)
- [6.2 VDP Commands](#62-vdp-commands)
- [6.3 Logical Operations](#63-logical-operations)
- [6.4 Area Specification](#64-area-specification)
- [6.5 Use of Each Command](#65-use-of-each-command)
- [6.5.1 HMMC (CPU -> VRAM high-speed transfer)](#651-hmmc-cpu---vram-high-speed-transfer)
- [6.5.2 YMMM (high-speed transfer between VRAM in Y direction)](#652-ymmm-high-speed-transfer-between-vram-in-y-direction)
- [6.5.3 HMMM (high-speed transfer between VRAM)](#653--hmmm-high-speed-transfer-between-vram)
- [6.5.4 HMMV (painting the rectangle in high speed)](#654-hmmv-painting-the-rectangle-in-high-speed)
- [6.5.5 LMMC (CPU -> VRAM logical transfer)](#655-lmmc-cpu---vram-logical-transfer)
- [6.5.6 LMCM (VRAM - CPU logical transfer)](#656-lmcm-vram---cpu-logical-transfer)
- [6.5.7. LMMM (VRAM->VRAM logical transfer)](#657-lmmm-vram-vram-logical-transfer)
- [6.5.8 LMMV (VRAM logical paint)](#658-lmmv-vram-logical-paint)
- [6.5.9 LINE (drawing a line)](#659-line-drawing-a-line)
- [6.5.10 SRCH (colour code search)](#6510-srch-colour-code-search)
- [6.5.11 PSET (drawing a point)](#6511-pset-drawing-a-point)
- [6.5.12 POINT (reading a colour code)](#6512-point-reading-a-colour-code)
- [6.6 Speeding Up Commands](#66-speeding-up-commands)
- [6.7 Register Status at Command Termination](#67-register-status-at-command-termination)
- [Changes from the original](#changes-from-the-original)
<p> </p>
### 6.1 Coordinate System of VDP Commands
When VDP commands are executed, the location of the source and destination points are represented as (X, Y) coordinates as shown in [Figure 4.72](#figure-472--coordinate-system-of-vram). When commands are executed, there is no page division and the entire 128K bytes VRAM is placed in a large coordinate system.
##### _Figure 4.72 Coordinate system of VRAM_
```
GRAPHIC 4 (SCREEN 5) GRAPHIC 5 (SCREEN 6)
------------------------------ 00000H ------------------------------
| (0,0) (255,0) | | | (0,0) (511,0) |
| Page 0 | | | Page 0 |
| (0,255) (255,255) | | | (0,255) (511,255) |
|----------------------------| 08000H |----------------------------|
| (0,256) (255,256) | | | (0,256) (511,256) |
| Page 1 | | | Page 1 |
| (0,511) (255,511) | | | (0,511) (511,511) |
|----------------------------| 10000H |----------------------------|
| (0,512) (255,512) | | | (0,512) (511,512) |
| Page 2 | | | Page 2 |
| (0,767) (255,767) | | | (0,767) (511,767) |
|----------------------------| 18000H |----------------------------|
| (0,768) (255,768) | | | (0,768) (511,768) |
| Page 3 | | | Page 3 |
| (0,1023) (255,1023) | | | (0,1023) (511,1023) |
------------------------------ 1FFFFH ------------------------------
GRAPHIC 7 (SCREEN 8) GRAPHIC 6 (SCREEN 7)
------------------------------ 00000H ------------------------------
| (0,0) (255,0) | | | (0,0) (511,0) |
| Page 0 | | | Page 0 |
| (0,255) (255,255) | | | (0,255) (511,255) |
|----------------------------| 10000H |----------------------------|
| (0,256) (255,256) | | | (0,256) (511,256) |
| Page 1 | | | Page 1 |
| (0,511) (255,511) | | | (0,511) (511,511) |
------------------------------ 1FFFFH ------------------------------
```
<p> </p>
### 6.2 VDP Commands
There are 12 types of VDP commands which can be executed by MSX-VIDEO. These are shown in [Table 4.5](#table-45--list-of-vdp-commands).
##### _Table 4.5 List of VDP commands_
```
----------------------------------------------------------------------------
| Command name | Destination | Source | Units | Mnemonic | R#46 (4 hi ord) |
|--------------+-------------+--------+-------+----------+-----------------|
| | VRAM | CPU | bytes | HMMC | 1 1 1 1 |
| High speed | VRAM | VRAM | bytes | YMMM | 1 1 1 0 |
| move | VRAM | VRAM | bytes | HMMM | 1 1 0 1 |
| | VRAM | VDP | bytes | HMMV | 1 1 0 0 |
|--------------+-------------+--------+-------+----------+-----------------|
| | VRAM | CPU | dots | LMMC | 1 0 1 1 |
| Logical | CPU | VRAM | dots | LMCM | 1 0 1 0 |
| move | VRAM | VRAM | dots | LMMM | 1 0 0 1 |
| | VRAM | VDP | dots | LMMV | 1 0 0 0 |
|--------------+-------------+--------+-------+----------+-----------------|
| Line | VRAM | VDP | dots | LINE | 0 1 1 1 |
|--------------+-------------+--------+-------+----------+-----------------|
| Search | VRAM | VDP | dots | SRCH | 0 1 1 0 |
|--------------+-------------+--------+-------+----------+-----------------|
| Pset | VRAM | VDP | dots | PSET | 0 1 0 1 |
|--------------+-------------+--------+-------+----------+-----------------|
| Point | VDP | VRAM | dots | POINT | 0 1 0 0 |
|--------------+-------------+--------+-------+----------+-----------------|
| | ---- | ---- | ----- | ---- | 0 0 1 1 |
| Reserved | ---- | ---- | ----- | ---- | 0 0 1 0 |
| | ---- | ---- | ----- | ---- | 0 0 0 1 |
|--------------+-------------+--------+-------+----------+-----------------|
| Stop | ---- | ---- | ----- | ---- | 0 0 0 0 |
----------------------------------------------------------------------------
```
* When data is written in R#46 (Command register), MSX-VIDEO begins to execute the command after setting 1 to bit 0 (CE/Command Execute) of the status register S#2. Necessary parameters should be set in register R#32 to R#45 before the command is executed.
* When the execution of the command ends, CE becomes 0.
* To stop the execution of the command, execute STOP command.
* Actions of the commands are guaranteed only in the bitmap modes (GRAPHIC 4 to GRAPHIC 7).
<p> </p>
### 6.3 Logical Operations
When commands are executed, various logical operations can be done between data in VRAM and the specified data. Each operation will be done according to the rules listed in [Table 4.6](#table-46--list-of-logical-operations).
In the table, SC represents the source color and DC represents the destination colour. IMP, AND, OR, EOR and NOT write the result of each operation to the destination. In operations whose names are preceded by "T", dots which correspond with SC=0 are not the objects of the operations and remains as DC. Using these operations enables only colour portions of two figures to be overlapped, so they are especially effective for animations.
[List 4.7](#list-47--example-of-the-logical-operation-with-t) shows an example of these operations.
##### _Table 4.6 List of logical operations_
```
-------------------------------------------------------------------------
| Logical name | |L03 L02 L01 L00|
|--------------+----------------------------------------+---------------|
| | | |
| IMP | DC=SC | 0 0 0 0 |
| | | |
| AND | DC=SCxDC | 0 0 0 1 |
| | | |
| OR | DC=SC+DC | 0 0 1 0 |
| | __ __ | |
| EOR | DC=SCxDC+SCxDC | 0 0 1 1 |
| | __ | |
| NOT | DC=SC | 0 1 0 0 |
| | | |
| ---- | | 0 1 0 1 |
| | | |
| ---- | | 0 1 1 0 |
| | | |
| ---- | | 0 1 1 1 |
| | | |
|--------------+----------------------------------------+---------------|
| | | |
| TIMP | if SC=0 then DC=DC else DC=SC | 1 0 0 0 |
| | | |
| TAND | if SC=0 then DC=DC else DC=SCxDC | 1 0 0 1 |
| | | |
| TOR | if SC=0 then DC=DC else DC=SC+DC | 1 0 1 0 |
| | __ __ | |
| TEOR | if SC=0 then DC=DC else DC=SCxDC+SCxDC | 1 0 1 1 |
| | __ | |
| TNOT | if SC=0 then DC=DC else DC=SC | 1 1 0 0 |
| | | |
| ---- | | 1 1 0 1 |
| | | |
| ---- | | 1 1 1 0 |
| | | |
| ---- | | 1 1 1 1 |
| | | |
-------------------------------------------------------------------------
```
* SC = Source colour code
* DC = Destination colour code
* EOR = Exclusive OR
##### _List 4.7 Example of the logical operation with T_
```
1000 '***********************************************************
1010 ' List 4.7 logical operation with T
1020 '***********************************************************
1030 '
1040 SCREEN8 : COLOR 15,0,0 : CLS
1050 DIM A%(3587)
1060 '
1070 LINE (50,50)-(60,100),48,B : PAINT (51,51),156,48
1080 CIRCLE (55,30),30,255 : PAINT (55,30),240,255
1090 COPY(20,0)-(90,100) TO A%
1100 CLS
1110 '
1120 R=RND(-TIME)
1130 FOR Y=0 TO 100 STEP 3
1140 X=INT(RND(1)*186)
1150 COPY A% TO (X,Y),,TPSET
1160 NEXT
1170 '
1180 GOTO 1180
```
<p> </p>
### 6.4 Area Specification
AREA-MOVE commands are for transferring screen data inside areas surrounded by a rectangle. The area to be transferred is specified by one vertex and the length of each side of the rectangle as shown in [Figure 4.73](#figure-473--area-specification). SX and SY represent the basic point of the rectangle to be transferred and NX and NY represent the lengt of each side in dots. The two bits, DIX and DIY, are for the direction of transferring data (the meaning of DIX and DIY depends on the type of command). The point where the area is to be transferred is specified in DX and DY.
##### _Figure 4.73 Area specification_
```
----------------------------------------------------------------
| |
| (SX,SY) |
| x----------------- --> |
| | | DIX |
| | | |
| | | |
| | | |
| ------------------ --+ |
| | DIY | |
| V | |
| | (DX,DY) |
| +-> x----------------- |
| | | |
| | | |
| | | |
| | | |
| ------------------ |
| |
----------------------------------------------------------------
```
<p> </p>
### 6.5 Use of Each Command
Commands are clasified into three types, high-speed transfer commands, logical transfer commands, and drawing commands. This section describes the commands and their use.
<p> </p>
#### 6.5.1 HMMC (CPU -> VRAM high-speed transfer)
Data is transferred into the specified area of VRAM from the CPU (see [Figure 4.74](#figure-474--action-of-hmmc-command)). Logical operations cannot be specified. Data is transferred in bytes in high-speed transfer commands such as HMMC. Note that the low order bit of the X-coordinate is not referred to in GRAPHIC 4, or 6 modes. The two low order bits are not referred to in GRAPHIC 5 mode (see [Figure 4.75](#figure-475--dots-not-to-be-referred-to)).
Set the parameters as shown in [Figure 4.76](#figure-476--register-settings-of-hmmc-command) to the appropriate registers. At this point, write only the first byte of data to be transferred from the CPU in R#44. Writing the command code F0H in R#46 causes the command to be executed, and UMSX-VIDEO receives data from R#44 and writes it to VRAM, then waits for data from the CPU.
The CPU writes data after the second byte in R#44. Note that data should be transferred after MSX-VIDEO can receive data (in the case that TR bit is "1"), referring to TR bit of S#2. When the CE bit of S#2 is "0", this means that all data has been transferred (see figure 4.77). [List 4.8](#list-48--example-of-hmmc-command-execution) shows an example of using HMMC.
##### _Figure 4.74 Action of HMMC command_
```
VRAM or expansion RAM
---------------------------------------------------
| | MSX-VIDEO CPU
| | ------- -------
| (DX,DY) | | | | |
| x------------------------ --> DIX | | | | |
| | NX | | | | | |
| | NY |<----------------+----| |-----| |
| | | | | | | |
| ------------------------- | | | | |
| | DIY | | | | |
| V | | | | |
| | ------- -------
| |
---------------------------------------------------
MXD: select the destination memory 0 = VRAM, 1 = expansion RAM
NX: number of dots to be transferred in X direction (0 to 511)*
NY: number of dots to be transferred in Y direction (0 to 1023)
DIX: direction of NX from the origin 0 = right, 1 = left
DIY: direction of NY from the origin 0 = below, 1 = above
DX: destination origin X-coordinate (0 to 511)*
DY: destination origin Y-coordinate (0 to 1023)
CLR (R#44:Colour register): 1st byte of data to be transferred
* The one low-order bit for GRAPHIC 4 and 6 modes,
or two low-order bits for GRAPHIC 5 mode of the DX and NX registers are ignored.
```
##### _Figure 4.75 Dots not to be referred to_
```
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
GRAPHIC 4 | : : : | : : : |
-----------------------------------------
(1) (2)
Since 1 VRAM byte represents 2 dots, 1 low order bit of X-coordinate is not referred to.
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
GRAPHIC 5 | : | : | : | : |
-----------------------------------------
(1) (2) (3) (4)
Since 1 VRAM byte represents 4 dots, 2 low order bits of X-coordinate are not referred to.
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
GRAPHIC 6 | : : : | : : : |
-----------------------------------------
(1) (2)
Since 1 VRAM byte represents 2 dots, 1 low order bit of X-coordinate is not referred to.
```
##### _Figure 4.76 Register settings of HMMC command_
```
> HMMC register setup
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#36 | DX7| DX6| DX5| DX4| DX3| DX2| DX1| DX0|
----------------------------------------- DX ---+
R#37 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | DX8| |
----------------------------------------- |
| destination origin
----------------------------------------- |
R#38 | DY7| DY6| DY5| DY4| DY3| DY2| DY1| DY0| |
----------------------------------------- DY ---+
R#39 | 0 | 0 | 0 | 0 | 0 | 0 | DY9| DY8|
-----------------------------------------
-----------------------------------------
R#40 | NX7| NX6| NX5| NX4| NX3| NX2| NX1| NX0|
----------------------------------------- NX ⟶ Number of dots in X direction to be transferred
R#41 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NX8|
-----------------------------------------
-----------------------------------------
R#42 | NY7| NY6| NY5| NY4| NY3| NY2| NY1| NY0|
----------------------------------------- NY ⟶ Number of dots in Y direction to be transferred
R#43 | 0 | 0 | 0 | 0 | 0 | 0 | NY9| NY8|
-----------------------------------------
----------------------------------------- --+
R#44 | CR7| CR6| CR5| CR4| CR3| CR2| CR1| CR0| CLR (GRAPHIC 4,6) |
----------------------------------------- |
| | | |
+-------------------+-------------------+ |
X=2N X=2N+1 (N=0, 1, ..., 127) |
|
----------------------------------------- |
| CR7| CR6| CR5| CR4| CR3| CR2| CR1| CR0| CLR (GRAPHIC 5) | data to be transferred
----------------------------------------- |
| | | | | |
+---------+---------+---------+---------+ |
X=4N X=4N+1 X=4N+2 X=4N+3 (N=0, 1, ..., 127) |
|
----------------------------------------- |
| CR7| CR6| CR5| CR4| CR3| CR2| CR1| CR0| CLR (GRAPHIC 7) |
----------------------------------------- --+
1 byte per dot
-----------------------------------------
R#45 | 0 | -- | MXD| -- | DIY| DIX| -- | -- | ARG (Argument register)
-----------------------------------------
| | direction (X)
| |
| +-> direction (Y)
|
+-----------> select destination memory
> HMMC command execution
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#46 | 1 | 1 | 1 | 1 | -- | -- | -- | -- | CMR
-----------------------------------------
```
##### _Figure 4.77 HMMC command execution flow chart_
```
/-------------------\
| HMMC start |
\-------------------/
|
---------------------
| register setup |
---------------------
|
---------------------
| command execution |
---------------------
|
+---------------->|
| |
| ---------------------------
| | Read status register #2 |
| ---------------------------
| |
| //////////+\\\\\\\\\\ Yes (CE bit = 0)
| | command end? |-------------------+
| \\\\\\\\\\+////////// |
| | No (CE bit = 1) |
| //////////+\\\\\\\\\\ |
|<------| transfer? | |
| No \\\\\\\\\\+////////// |
| (TR bit=0) | Yes (TR bit = 1) |
| --------------------- |
| | transfer data | |
| --------------------- |
| | |
+-----------------+ |
|
+-----------------------------+
|
V
/--------------------\
| HMMC end |
\--------------------/
```
##### _List 4.8 Example of HMMC command execution_
```
;****************************************************************
; List 4.8 HMMC sample
; to use, set H, L, D, E, IX and go
; RAM (IX) ⟶ VRAM (H,L)-(D,E)
;****************************************************************
;
RDVDP: EQU 0006H
WRVDP: EQU 0007H
;----- program start -----
HMMC: DI ;disable interrupt
CALL WAIT.VDP ;wait end of command
LD A,(WRVDP)
LD C,A
INC C ;C := PORT#1's address
LD A,36
OUT (C),A
LD A,17+80H
OUT (C),A ;R#17 := 36
INC C
INC C ;C := PORT#3's address
XOR A
OUT (C),H ;DX
OUT (C),A
OUT (C),L ;DY
OUT (C),A
LD A,H ;make NX and DIX
SUB A
LD D,00000100B
JR NC,HMMC1
LD D,00000000B
NEG
HMMC1: LD H,A ;H := NX , D := DIX
LD A,L
SUB A
LD E,00001000B
JR NC,HMMC2
LD E,00000000B
NEG
HMMC2: LD L,A ;L := NY , E := DIY
XOR A
OUT (C),H ;NX
OUT (C),A
OUT (C),L ;NY
OUT (C),A
LD H,(IX+0)
OUT (C),H ;first DATA
LD A,D
OR E
OUT (C),A ;DIX and DIY
LD A,0F0H
OUT (C),A ;HMMC command
LD A,(WRVDP)
LD C,A ;C := PORT#1's address
INC C
LD A,44+80H
OUT (C),A
LD A,17+80H
OUT (C),A
INC C
INC C
LOOP: LD A,2
CALL GET.STATUS
BIT 0,A ;check CE bit
JR Z,EXIT
BIT 7,A ;check TR bit
JR Z,LOOP
INC IX
LD A,(IX+0)
OUT (C),A
JR LOOP
EXIT: LD A,0
CALL GET.STATUS ;when exit, you must select S#0
EI
RET
GET.STATUS: ;read status register specified by A
PUSH BC
LD BC,(WRVDP)
INC C
OUT (C),A
LD A,8FH
OUT (C),A
LD BC,(RDVDP)
INC C
IN A,(C)
POP BC
RET
WAIT.VDP: ;wait VDP ready
LD A,2
CALL GET.STATUS
AND 1
JR NZ,WAIT.VDP
XOR A
CALL GET.STATUS
RET
END
```
<p> </p>
#### 6.5.2 YMMM (high-speed transfer between VRAM in Y direction)
Data from a specified VRAM area is transferred into another area in VRAM. Note that transfers using this command can only be done in the Y direction (see [Figure 4.78](#figure-478--actions-of-ymmm-command)).
After setting the data as shown in [Figure 4.79](#figure-479--register-settings-of-ymmm-command) in the proper registers, writing command code E0H in R#46 causes the command to be executed. When the CE bit of S#2 is "1", it indicates that the command is currently being executed. [List 4.9](#list-49--example-of-ymmm-command-execution) shows an example of using YMMM.
##### _Figure 4.78 Actions of YMMM command_
```
VRAM or expansion RAM
---------------------------------------------------
| |
| (DX,DY) |
| x------------------------|
| | |
| | |
| | |
| -------------------------|
| ^ |
| | |
| | |
| (DX,SY) |
| x------------------------| ⟶ DIX
| | |
| | NY |
| | |
| -------------------------|
| | DIY |
| V |
---------------------------------------------------
MXD: select the destination memory 0 = VRAM, 1 = expansion RAM
SY: source origin Y-coordinate (0 to 1023)
NY: number of dots to be transferred in Y direction (0 to 1023)
DIX: set which to be transferred, to te right end or to the left end of the
screen from the source origin 0 = right, 1 = left
DIY: direction of NY from the origin 0 = below, 1 = above
DX: destination origin X-coordinate (0 to 511)*
DY: destination origin Y-coordinate (0 to 1023)
* The one low-order bit for GRAPHIC 4 and 6 modes,
or two low-order bits for GRAPHIC 5 mode of the DX register are ignored.
```
##### _Figure 4.79 Register settings of YMMM command_
```
> YMMM register setup
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#34 | SY7| SY6| SY5| SY4| SY3| SY2| SY1| SY0|
----------------------------------------- SY ⟶ source origin
R#35 | 0 | 0 | 0 | 0 | 0 | 0 | SY9| SY8|
-----------------------------------------
-----------------------------------------
R#36 | DX7| DX6| DX5| DX4| DX3| DX2| DX1| DX0|
----------------------------------------- DX ⟶ destination and source origin
R#37 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | DX8|
-----------------------------------------
-----------------------------------------
R#38 | DY7| DY6| DY5| DY4| DY3| DY2| DY1| DY0|
----------------------------------------- DY ⟶ destination origin
R#39 | 0 | 0 | 0 | 0 | 0 | 0 | DY9| DY8|
-----------------------------------------
-----------------------------------------
R#42 | NY7| NY6| NY5| NY4| NY3| NY2| NY1| NY0|
----------------------------------------- NY ⟶ number of dots to be transferred in Y direction
R#43 | 0 | 0 | 0 | 0 | 0 | 0 | NY9| NY8|
-----------------------------------------
-----------------------------------------
R#45 | 0 | -- | MXD| -- | DIY| DIX| -- | -- | ARG (Argument register)
-----------------------------------------
| | direction (X)
| |
| +-> direction (Y)
|
+-----------> select destination memory
> YMMM command execution
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#46 | 1 | 1 | 1 | 0 | -- | -- | -- | -- | CMR
-----------------------------------------
```
##### _List 4.9 Example of YMMM command execution_
```
;****************************************************************
; List 4.9 YMMM sample
; to use, set L, E, B, C, D(bit 2) and go
; VRAM (B,L)-(*,E) ⟶ VRAM (B,C)
; DIX must be set in D(bit 2)
;****************************************************************
;
RDVDP: EQU 0006H
WRVDP: EQU 0007H
;----- program start -----
YMMM: DI ;disable interrupt
PUSH BC ;save destination
CALL WAIT.VDP ;wait end of command
LD A,(WRVDP)
LD C,A
INC C ;C := PORT#1's address
LD A,34
OUT (C),A
LD A,17+80H
OUT (C),A ;R#17 := 34
INC C
INC C ;C := PORT#3's address
XOR A
OUT (C),L ;SY
OUT (C),A
LD A,L ;make NY and DIY
SUB A
LD E,00001000B
JP NC,YMMM1
LD E,00000000B
NEG
YMMM1: LD L,A ;L := NY , D := DIY
LD A,D
OR E
POP DE ;restore DX,DY
PUSH AF ;save DIX,DIY
XOR A
OUT (C),D ;DX
OUT (C),A
OUT (C),E ;DY
OUT (C),A
OUT (C),A ;dummy
OUT (C),A ;dummy
OUT (C),L ;NY
OUT (C),A
OUT (C),A ;dummy
POP AF
OUT (C),A ;DIX and DIY
LD A,11100000B ;YMMM command
OUT (C),A
EI
RET
GET.STATUS:
PUSH BC
LD BC,(WRVDP)
INC C
OUT (C),A
LD A,8FH
OUT (C),A
LD BC,(RDVDP)
INC C
IN A,(C)
POP BC
RET
WAIT.VDP:
LD A,2
CALL GET.STATUS
AND 1
JP NZ,WAIT.VDP
XOR A
CALL GET.STATUS
RET
END
```
<p> </p>
#### 6.5.3 HMMM (high-speed transfer between VRAM)
Data of specified VRAM area is transferred into another area in VRAM (see [Figure 4.80](#figure-480--actions-of-hmmm-command)).
After setting the parameters as shown in [Figure 4.81](#figure-481--register-settings-of-hmmm-command), writing D0H in R#46 causes the command to be executed. While the command is being executed, CE bit of S#2 is "1". [List 4.10](#list-410--example-of-hmmm-command-execution) shows an example of using HMMM.
##### _Figure 4.80 Actions of HMMM command_
```
VRAM or expansion RAM
----------------------------------------------------------------
| |
| (SX,SY) |
| ------------------ --> |
| | NX | DIX |
| | | |
| | NY | |
| | | |
| ------------------ --+ |
| | DIY | |
| V | |
| | (DX,DY) |
| +-> ------------------ |
| | | |
| | | |
| | | |
| | | |
| ------------------ |
| |
----------------------------------------------------------------
MXS: select the source memory 0 = VRAM, 1 = expansion RAM
MXD: select the destination memory 0 = VRAM, 1 = expansion RAM
SX: source origin X-coordinate (0 to 511)*
SY: source origin Y-coordinate (0 to 1023)
NX: number of dots to be transferred in X direction (0 to 511)*
NY: number of dots to be transferred in Y direction (0 to 1023)
DIX: direction of NX from the origin 0 = right, 1 = left
DIY: direction of NY from the origin 0 = below, 1 = above
DX: destination origin X-coordinate (0 to 511)*
DY: destination origin Y-coordinate (0 to 1023)
* The one low-order bit for GRAPHIC 4 and 6 modes,
or two low-order bits for GRAPHIC 5 mode of the SX, DX, and NX register are ignored.
```
##### _Figure 4.81 Register settings of HMMM command_
```
> HMMM register setup
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#32 | SX7| SX6| SX5| SX4| SX3| SX2| SX1| SX0|
|----+----+----+----+----+----+----+----| SX ---+
R#33 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | SX8| |
----------------------------------------- |
| source origin
----------------------------------------- |
R#34 | SY7| SY6| SY5| SY4| SY3| SY2| SY1| SY0| |
|----+----+----+----+----+----+----+----| SY ---+
R#35 | 0 | 0 | 0 | 0 | 0 | 0 | SY9| SY8|
-----------------------------------------
-----------------------------------------
R#36 | DX7| DX6| DX5| DX4| DX3| DX2| DX1| DX0|
|----+----+----+----+----+----+----+----| DX ---+
R#37 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | DX8| |
----------------------------------------- |
| destination origin
----------------------------------------- |
R#38 | DY7| DY6| DY5| DY4| DY3| DY2| DY1| DY0| |
|----+----+----+----+----+----+----+----| DY ---+
R#39 | 0 | 0 | 0 | 0 | 0 | 0 | DY9| DY8|
-----------------------------------------
-----------------------------------------
R#40 | NX7| NX6| NX5| NX4| NX3| NX2| NX1| NX0|
|----+----+----+----+----+----+----+----| NX ⟶ Number of dots in X direction to be transferred
R#41 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NX8|
-----------------------------------------
-----------------------------------------
R#42 | NY7| NY6| NY5| NY4| NY3| NY2| NY1| NY0|
|----+----+----+----+----+----+----+----| NY ⟶ Number of dots in Y direction to be transferred
R#43 | 0 | 0 | 0 | 0 | 0 | 0 | NY9| NY8|
-----------------------------------------
-----------------------------------------
R#45 | 0 | -- | MXD| MXS| DIY| DIX| -- | -- | ARG (Argument register)
-----------------------------------------
| | | direction (X)
| | |
| | +-> direction (Y)
| |
| +------> select source memory
|
+-----------> select destination memory
> HMMM command execution
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#46 | 1 | 1 | 0 | 1 | -- | -- | -- | -- | CMR
-----------------------------------------
```
##### _List 4.10 Example of HMMM command execution_
```
;****************************************************************
; List 4.10 HMMM sample
; to use, set H, L, D, E, B, C and go
; VRAM (H,L)-(D,E) ⟶ VRAM (B,C)
; DIX must be set in D(bit 2)
;****************************************************************
;
RDVDP: EQU 0006H
WRVDP: EQU 0007H
;----- program start -----
HMMM: DI ;disable interrupt
PUSH BC ;save destination
CALL WAIT.VDP ;wait end of command
LD A,(WRVDP)
LD C,A
INC C ;C := PORT#1's address
LD A,32
OUT (C),A
LD A,80H+17
OUT (C),A ;R#17 := 32
INC C
INC C ;C := PORT#3's address
XOR A
OUT (C),H ;SX
OUT (C),A
OUT (C),L ;SY
OUT (C),A
LD A,H ;make NX and DIX
SUB A
LD D,00000100B
JP NC,HMMM1
LD D,00000000B
NEG
HMMM1: LD H,A ;H := NX , D := DIX
LD A,L ;make NY and DIY
SUB A
LD E,00001000B
JP NC,HMMM2
LD E,00000000B
NEG
HMMM2: LD L,A ;L := NY , E := DIY
LD A,D
OR E
POP DE ;restore DX,DY
PUSH AF ;save DIX,DIY
XOR A
OUT (C),D ;DX
OUT (C),A
OUT (C),E ;DY
OUT (C),A
OUT (C),H ;NX
OUT (C),A
OUT (C),L ;NY
OUT (C),A
OUT (C),A ;dummy
POP AF
OUT (C),A ;DIX and DIY
LD A,11010000B ;HMMM command
OUT (C),A
EI
RET
GET.STATUS:
PUSH BC
LD BC,(WRVDP)
INC C
OUT (C),A
LD A,8FH
OUT (C),A
LD BC,(RDVDP)
INC C
IN A,(C)
POP BC
RET
WAIT.VDP:
LD A,2
CALL GET.STATUS
AND 1
JP NZ,WAIT.VDP
XOR A
CALL GET.STATUS
RET
END
```
<p> </p>
#### 6.5.4 HMMV (painting the rectangle in high speed)
Each byte of data in the specified VRAM area is painted by the specified colour code (see [Figure 4.82](#figure-482--actions-of-hmmc-command))
After setting the parameters as shown in [Figure 4.83](#figure-483--register-settings-of-hmmv-command), writing C0H in R#46 causes the command to be executed. While the command is being executed, the CE bit of S#2 is 1. [List 4.11](#list-411--example-of-hmmv-command-execution) shows an example of using HMMV.
##### _Figure 4.82 Actions of HMMC command_
```
VRAM or expansion RAM
---------------------------------------------------
| | MSX-VIDEO
| | -------
| (DX,DY) | | |
| x------------------------ --> DIX | | |
| | NX | | | |
| | NY |<----------------+----| |
| | | | | |
| ------------------------- | | |
| | DIY | | |
| V | | |
| | -------
| |
---------------------------------------------------
MXD: select memory 0 = VRAM, 1 = expansion RAM
NX: number of dots to be painted in X direction (0 to 511)*
NY: number of dots to be painted in Y direction (0 to 1023)
DIX: direction of NX from the origin 0 = right, 1 = left
DIY: direction of NY from the origin 0 = below, 1 = above
DX: origin X-coordinate (0 to 511)*
DY: origin Y-coordinate (0 to 1023)
CLR (R#44:Colour register): Painted data
* The one low-order bit for GRAPHIC 4 and 6 modes,
or two low-order bits for GRAPHIC 5 mode of the DX and NX registers are ignored.
```
##### _Figure 4.83 Register settings of HMMV command_
```
> HMMV register setup
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#36 | DX7| DX6| DX5| DX4| DX3| DX2| DX1| DX0|
|----+----+----+----+----+----+----+----| DX ---+
R#37 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | DX8| |
----------------------------------------- |
| origin
----------------------------------------- |
R#38 | DY7| DY6| DY5| DY4| DY3| DY2| DY1| DY0| |
|----+----+----+----+----+----+----+----| DY ---+
R#39 | 0 | 0 | 0 | 0 | 0 | 0 | DY9| DY8|
-----------------------------------------
-----------------------------------------
R#40 | NX7| NX6| NX5| NX4| NX3| NX2| NX1| NX0|
|----+----+----+----+----+----+----+----| NX ⟶ number of dots in X direction to be painted
R#41 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NX8|
-----------------------------------------
-----------------------------------------
R#42 | NY7| NY6| NY5| NY4| NY3| NY2| NY1| NY0|
|----+----+----+----+----+----+----+----| NY ⟶ number of dots inY direction to be painted
R#43 | 0 | 0 | 0 | 0 | 0 | 0 | NY9| NY8|
-----------------------------------------
----------------------------------------- --+
R#44 | CR7| CR6| CR5| CR4| CR3| CR2| CR1| CR0| CLR (GRAPHIC 4,6) |
----------------------------------------- |
| | | |
+-------------------+-------------------+ |
X=2N X=2N+1 (N=0, 1, ..., 127) |
|
----------------------------------------- |
| CR7| CR6| CR5| CR4| CR3| CR2| CR1| CR0| CLR (GRAPHIC 5) | data to be painted
----------------------------------------- |
| | | | | |
+---------+---------+---------+---------+ |
X=4N X=4N+1 X=4N+2 X=4N+3 (N=0, 1, ..., 127) |
|
----------------------------------------- |
| CR7| CR6| CR5| CR4| CR3| CR2| CR1| CR0| CLR (GRAPHIC 7) |
----------------------------------------- --+
1 byte / dot
-----------------------------------------
R#45 | 0 | -- | MXD| -- | DIY| DIX| -- | -- | ARG (Argument register)
-----------------------------------------
| | painting direction (X)
| |
| +-> painting direction (Y)
|
+-----------> memory selection
> HMMV command execution
MSB 7 6 5 4 3 2 1 0 LSB
-----------------------------------------
R#46 | 1 | 1 | 0 | 0 | -- | -- | -- | -- | CMR
-----------------------------------------
```
##### _List 4.11 Example of HMMV command execution_
```
;****************************************************************
; List 4.11 HMMV sample
; to use, set H, L, D, E, B and go
; B ⟶ VRAM (H,L)-(D,E) fill
;****************************************************************
;
RDVDP: EQU 0006H
WRVDP: EQU 0007H
;----- program start -----
HMMV: DI ;disable interrupt
CALL WAIT.VDP ;wait end of command
LD A,(WRVDP)
LD C,A
INC C ;C := PORT#1's address
LD A,36
OUT (C),A
LD A,80H+17
OUT (C),A ;R#17 := 36
INC C
INC C ;C := PORT#3's address
XOR A
OUT (C),H ;DX
OUT (C),A
OUT (C),L ;DY
OUT (C),A
LD A,H ;make NX and DIX
SUB A
LD D,00000100B
JP NC,HMMV1
LD D,00000000B
NEG
HMMV1: LD H,A ;H := NX
LD A,L ;make NY and DIY
SUB A
LD E,00001000B
JP NC,HMMV2
LD E,00000000B
NEG
HMMV2: OUT (C),H
LD H,A ;H := NY
XOR A
OUT (C),A
OUT (C),H
OUT (C),A
OUT (C),B ;fill data
XOR A
OR D
OR E
OUT (C),A ;DIX and DIY
LD A,11000000B ;HMMV command
OUT (C),A
EI
RET
GET.STATUS:
PUSH BC
LD BC,(WRVDP)
INC C
OUT (C),A
LD A,8FH
OUT (C),A
LD BC,(RDVDP)
INC C
IN A,(C)
POP BC
RET
WAIT.VDP:
LD A,2
CALL GET.STATUS
AND 1
JP NZ,WAIT.VDP
XOR A
CALL GET.STATUS
RET
END
```
<p> </p>
#### 6.5.5 LMMC (CPU -> VRAM logical transfer)
Data is transferred from the CPU to thespecified VRAM area in dots (see [Figure 4.84](#figure-484--action-of-lmmc-command)). Logical operations with the source can be specified. In the logical transfer commands, such as LMMC, data is transfered in dots and one byte is required for the information of one pixel in all screen modes.
After setting the data as shown in [Figure 4.85](#figure-485--register-settings-of-lmmc-command), write command code B0H in R#46. At this point, logical operations can be specified by using the 4 low order bits of the command register. Data is transferred with reference to the TR and CE bit of S#2, as in HMMC (see [Figure 4.86](#figure-486--lmmc-command-execution-flow-chart)). [List 4.12](#list-412--example-of-lmmc-command-execution) shows an example of using LMMC.
##### _Figure 4.84 Action of LMMC command_
```
VRAM or expansion RAM
-----------------------------------