diff options
author | fulivi <fulivi@users.noreply.github.com> | 2018-08-19 15:18:53 +0200 |
---|---|---|
committer | Vas Crabb <cuavas@users.noreply.github.com> | 2018-08-20 02:06:33 +1000 |
commit | 66b9e9c18f2eea57026e60bfed40434111e6891a (patch) | |
tree | dc551184afcded20a18f6403690cd1c8680f82d3 /src/devices | |
parent | d5b28b8ad7c6ea470c3a8e530ce9d5c42d5b7e08 (diff) |
hp_ipc: implemented bit offset in RDWIN/WRWIN commands of GPU
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/video/hp1ll3.cpp | 127 | ||||
-rw-r--r-- | src/devices/video/hp1ll3.h | 1 |
2 files changed, 118 insertions, 10 deletions
diff --git a/src/devices/video/hp1ll3.cpp b/src/devices/video/hp1ll3.cpp index 7e8d2f2f0a4..5f34138f940 100644 --- a/src/devices/video/hp1ll3.cpp +++ b/src/devices/video/hp1ll3.cpp @@ -22,6 +22,105 @@ - interrupt generation - realistic timing? - &c. + + This table summarizes the GPU commands. + "Code" is the hex code of command. + "Impl" shows whether the command is implemented in this driver or not. + "Parameter" reports the I/O data exchanged by the command. Each line + is a 16-bit word which is read from/written to the GPU by a pair of + 8-bit accesses to data register (MSB first). + "I" is an input parameter (sent before command code) + "D" is an input data word (sent after command code) + "O" is an output data word. + + | *Cmd* | *Code* | *Impl.* | *Parameter* | *Description* | + |-----------+--------+---------+---------------------+-----------------------------------| + | NOP | 00 | Y | - | No operation. Used to close | + | | | | | RDMEM/WRMEM/RDWIN/WRWIN commands. | + | CONF | 02 | Y | D@0: H. timing 0 | Configure GPU | + | | | | D@1: H. timing 1 | | + | | | | D@2: H. timing 2 | | + | | | | D@3: H. timing 3 | | + | | | | D@4: V. timing 0 | | + | | | | D@5: V. timing 1 | | + | | | | D@6: V. timing 2 | | + | | | | D@7: V. timing 3 | | + | | | | D@8: Words per line | | + | | | | D@9: Lines | | + | | | | D@10: Option bits | | + | DISVID | 03 | Y | - | Disable video | + | ENVID | 04 | Y | - | Enable video | + | ? | 06 | Y | - | Unknown | + | | | | | My guess is interrupt enable | + | | | | | 05 is probably int. disable | + | | | | | It's only used by diagb ROM | + | WRMEM | 07 | Y | I@0: RAM address | Write video RAM. Keep writing | + | | | | D@0: RAM word | words with auto-incremented addr | + | | | | ... | until terminated by NOP. | + | RDMEM | 08 | Y | I@0: RAM address | Read video RAM. Read words until | + | | | | O@0: RAM word | terminated by NOP. | + | | | | ... | | + | WRSAD | 09 | Y | I@0: Start address | Set screen start address | + | WRORG | 0a | Y | I@0: Start address | Set raster start address | + | WRDAD | 0b | Y | I@0: Start address | Set data start address | + | WRRR | 0c | Y | I@0: RR | Set replacement rule | + | MOVEP | 0d | Y | I@0: X | Set pen position | + | | | | I@1: Y | | + | IMOVEP | 0e | Y | I@0: delta X | Set pen position (incremental) | + | | | | I@1: delta Y | | + | DRAWP | 0f | Y | I@0: X | Draw a line and move pen | + | | | | I@1: Y | | + | IDRAWP | 10 | N | I@0: delta X | Draw a line (incremental) | + | | | | I@1: delta Y | | + | RDP | 11 | Y | O@0: pen X pos | Read current pen position | + | | | | O@1: pen Y pos | | + | WRUDL | 12 | Y | I@0: UDL | Set user-defined line pattern | + | WRWINSIZ | 13 | Y | I@0: Window width | Set window size | + | | | | I@1: Window height | | + | WRWINORG | 14 | Y | I@0: Origin X | Set window origin (UL corner) | + | | | | I@1: Origin Y | | + | COPY | 15 | Y | I@0: Dest. origin X | Copy a window. Parameter sets | + | | | | I@1: Dest. origin Y | the UL corner of the dest. win. | + | FILL | 16 | Y | I@0: Pattern no. | Fill a window | + | FRAME | 17 | N | - | Draw a frame (rectangle) | + | SCROLUP | 18 | Y | I@0: Fill pattern | Scroll a window upwards | + | | | | I@1: Scroll amount | | + | SCROLDN | 19 | Y | I@0: Fill pattern | Scroll a window downwards | + | | | | I@1: Scroll amount | | + | SCROLLF | 1a | N | I@0: Fill pattern | Scroll a window to the left | + | | | | I@1: Scroll amount | | + | SCROLLF | 1b | N | I@0: Fill pattern | Scroll a window to the right | + | | | | I@1: Scroll amount | | + | RDWIN | 1c | Y | I@0: bit offset | Read a window. Terminated by NOP. | + | | | | O@0: data word | | + | | | | ... | | + | WRWIN | 1d | Y | I@0: bit offset | Write a window. Terminated by NOP.| + | | | | D@0: data word | | + | | | | ... | | + | RDWINPARM | 1e | Y | O@0: Win. origin X | Read current window parameters | + | | | | O@1: Win. origin Y | | + | | | | O@2: Window width | | + | | | | O@3: Window height | | + | CR | 1f | N | - | Carriage return: move pen to | + | | | | | start of line | + | CRLF | 20 | Y | - | CRLF: move pen to start of next | + | | | | | text row | + | LABEL | 24 | Y | I@0: character code | Write a character and move pen | + | ENSP | 26 | Y | I@0: sprite pattern | Enable sprite | + | DISSP | 27 | Y | - | Disable sprite | + | MOVESP | 28 | Y | I@0: Sprite X pos | Move sprite | + | | | | I@1: Sprite Y pos | | + | IMOVESP | 29 | N | I@0: Sprite delta X | Move sprite (incremental) | + | | | | I@1: Sprite delta Y | | + | RDSP | 2a | Y | O@0: Sprite X pos | Read sprite position | + | | | | O@1: Sprite Y pos | | + | DRAWPX | 2b | Y | I@0: X | Write a pixel | + | | | | I@1: Y | | + | WRFAD | 2c | Y | I@0: Font address | Set address of font data | + | ENCURS | 2d | Y | I@0: cursor pattern | Enable cursor | + | | | | I@1: cursor offset | | + | DISCURS | 2e | Y | - | Disable cursor | + | ID | 3f | Y | O@0: ID | Read hw ID | */ #include "emu.h" @@ -794,13 +893,17 @@ READ8_MEMBER( hp1ll3_device::read ) } else { - unsigned w = std::min(WS, unsigned(width)); + unsigned discarded_bits = 0; + // Insert "m_rw_win_off" dummy bits in the first word of each line + if (m_rw_win_x == m_window.org_x) + discarded_bits = m_rw_win_off; + unsigned w = std::min(WS - discarded_bits, unsigned(width)); - m_io_word = rd_video(addr) << bit; + m_io_word = (rd_video(addr) << bit) >> discarded_bits; if ((bit + w) > WS) - m_io_word |= rd_video(addr + 1) >> (WS - bit); + m_io_word |= rd_video(addr + 1) >> (WS - bit + discarded_bits); - m_io_word &= ~0 << (WS - w); + m_io_word &= ~0 << (WS - w - discarded_bits); m_rw_win_x += w; if (m_rw_win_x >= (m_window.width + m_window.org_x)) { @@ -920,20 +1023,24 @@ WRITE8_MEMBER( hp1ll3_device::write ) m_command = NOP; else { - unsigned w = std::min(WS, unsigned(width)); + unsigned discarded_bits = 0; + // Remove "m_rw_win_off" bits from the first word of each line + if (m_rw_win_x == m_window.org_x) + discarded_bits = m_rw_win_off; + unsigned w = std::min(WS - discarded_bits, unsigned(width)); glob_mask >>= bit; if ((bit + w) < WS) glob_mask &= ~0 << (WS - (bit + w)); - rmw_rop(addr, m_io_word >> bit, glob_mask, rop_masks); - DBG_LOG(3, 0, ("WRWIN (%u,%u) %d %04x %04x\n", m_rw_win_x, m_rw_win_y, width, m_io_word >> bit, glob_mask)); + rmw_rop(addr, (m_io_word << discarded_bits) >> bit, glob_mask, rop_masks); + DBG_LOG(3, 0, ("WRWIN (%u,%u) %d %04x %04x->%04x\n", m_rw_win_x, m_rw_win_y, width, (m_io_word << discarded_bits) >> bit, glob_mask, rd_video(addr))); if ((bit + w) > WS) { - unsigned pad = WS - bit; + unsigned pad = WS - bit + discarded_bits; glob_mask = ~0 << (2 * WS - bit - w); rmw_rop(addr + 1, uint16_t(m_io_word << pad), glob_mask, rop_masks); - DBG_LOG(3, 0, ("WRWIN %u %04x %04x\n", pad, m_io_word << pad, glob_mask)); + DBG_LOG(3, 0, ("WRWIN %u %04x %04x->%04x\n", pad, m_io_word << pad, glob_mask, rd_video(addr + 1))); } m_rw_win_x += w; if (m_rw_win_x >= (m_window.width + m_window.org_x)) @@ -1081,9 +1188,9 @@ void hp1ll3_device::command(int command) case RDWIN: DBG_LOG(2,"HPGPU",("command: %s [%d, 0x%x] offset=%u size(%d,%d)\n", command == RDWIN ? "RDWIN":"WRWIN", command, command, m_input[0], m_window.width, m_window.height)); - // m_input[0] is offset (to be implemented) m_rw_win_x = m_window.org_x; m_rw_win_y = m_window.org_y; + m_rw_win_off = m_input[0] % WS; disable_cursor(); disable_sprite(); break; diff --git a/src/devices/video/hp1ll3.h b/src/devices/video/hp1ll3.h index cc4146a9033..8719168a882 100644 --- a/src/devices/video/hp1ll3.h +++ b/src/devices/video/hp1ll3.h @@ -105,6 +105,7 @@ private: unsigned m_vram_size; uint16_t m_ram_addr_mask; uint16_t m_rw_win_x, m_rw_win_y; + uint8_t m_rw_win_off; bool m_busy; |