diff options
author | 2021-10-10 21:26:32 +0100 | |
---|---|---|
committer | 2021-10-10 16:26:32 -0400 | |
commit | a8ffd2235a167702cc9a06d0917d545e7ed14bee (patch) | |
tree | bfeeb7b9ed7a4a60d39cbae48c6950833ae2c0fd /src | |
parent | fc906d7a1783f93578cedd1c162015d6182d8e3b (diff) |
RM Nimbus updates: (#8684)
* Updated mouse handling so it mostly works
* Updated SASI/SCSI code so that formatting disks with HDFORM works for ST125N and ST225N.
* Added documentation of the video code drawn from the Nimbus Service manual.
Diffstat (limited to 'src')
-rw-r--r-- | src/mame/includes/rmnimbus.h | 13 | ||||
-rw-r--r-- | src/mame/machine/rmnimbus.cpp | 241 | ||||
-rw-r--r-- | src/mame/video/rmnimbus.cpp | 231 |
3 files changed, 315 insertions, 170 deletions
diff --git a/src/mame/includes/rmnimbus.h b/src/mame/includes/rmnimbus.h index f483a7b1da9..091473398c7 100644 --- a/src/mame/includes/rmnimbus.h +++ b/src/mame/includes/rmnimbus.h @@ -121,7 +121,7 @@ private: uint8_t m_last_playmode; uint8_t m_ay8910_a; uint16_t m_x, m_y, m_yline; - uint8_t m_colours, m_mode, m_op; + uint8_t m_colours, m_mode, m_upmode; uint32_t m_debug_video; uint8_t m_vector; uint8_t m_eeprom_bits; @@ -189,13 +189,15 @@ private: void rmni_sound_reset(); void mouse_js_reset(); void check_scsi_irq(); - + void set_scsi_drqlat(bool clock, bool clear); + int m_scsi_iena; int m_scsi_msg; int m_scsi_bsy; int m_scsi_io; int m_scsi_cd; int m_scsi_req; + int m_scsi_reqlat; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; @@ -222,12 +224,9 @@ private: /* Mouse/Joystick */ struct { - uint8_t m_mouse_px; - uint8_t m_mouse_py; + int8_t m_mouse_x; + int8_t m_mouse_y; - uint8_t m_mouse_x; - uint8_t m_mouse_y; - uint8_t m_mouse_pc; uint8_t m_mouse_pcx; uint8_t m_mouse_pcy; diff --git a/src/mame/machine/rmnimbus.cpp b/src/mame/machine/rmnimbus.cpp index 0f8cab8c56a..d5448d4571e 100644 --- a/src/mame/machine/rmnimbus.cpp +++ b/src/mame/machine/rmnimbus.cpp @@ -109,12 +109,16 @@ chdman createhd -o ST125N.chd -chs 41921,1,1 -ss 512 #define MOUSE_INT_ENABLE 0x08 #define PC8031_INT_ENABLE 0x10 -enum -{ - MOUSE_PHASE_STATIC = 0, - MOUSE_PHASE_POSITIVE, - MOUSE_PHASE_NEGATIVE -}; +#define MOUSE_NONE 0x00 +#define MOUSE_LEFT 0x01 +#define MOUSE_RIGHT 0x02 +#define MOUSE_DOWN 0x04 +#define MOUSE_UP 0x08 +#define MOUSE_LBUTTON 0x10 +#define MOUSE_RBUTTON 0x20 + +// Frequency in Hz to poll for mouse movement. +#define MOUSE_POLL_FREQUENCY 5000 #define MOUSE_INT_ENABLED(state) (((state)->m_iou_reg092 & MOUSE_INT_ENABLE) ? 1 : 0) @@ -1064,7 +1068,7 @@ uint8_t rmnimbus_state::scsi_r(offs_t offset) result |= m_scsi_cd << 6; result |= m_scsi_io << 5; result |= m_scsi_bsy << 4; - result |= !m_scsi_msg << 3; + result |= m_scsi_msg << 3; if(floppy) { result |= FDC_MOTOR() << 2; @@ -1100,7 +1104,7 @@ uint8_t rmnimbus_state::scsi_r(offs_t offset) */ void rmnimbus_state::fdc_ctl_w(uint8_t data) { - uint8_t reg400_old = m_nimbus_drives.reg400; + uint8_t old_drq = m_nimbus_drives.reg400 & HDC_DRQ_MASK; char drive[5]; floppy_image_device *floppy; @@ -1117,8 +1121,8 @@ void rmnimbus_state::fdc_ctl_w(uint8_t data) } // if we enable hdc drq with a pending condition, act on it - if((data & HDC_DRQ_MASK) && (~reg400_old & HDC_DRQ_MASK)) - hdc_drq(true); + if((data & HDC_DRQ_MASK) && (!old_drq)) + set_scsi_drqlat(false, false); } /* @@ -1157,8 +1161,18 @@ void rmnimbus_state::hdc_reset() m_scsi_io = 0; m_scsi_cd = 0; m_scsi_req = 0; + + // Latched req, IC11b + m_scsi_reqlat = 0; } +/* + The SCSI code outputs a 1 to indicate an active line, even though it is active low + The inputs on the RM schematic are fed through inverters, but because of the above + we don't need to invert them, unless the schematic uses the signal directly + For consistency we will invert msg before latching. +*/ + void rmnimbus_state::check_scsi_irq() { nimbus_fdc_intrq_w(m_scsi_io && m_scsi_cd && m_scsi_req && m_scsi_iena); @@ -1170,10 +1184,27 @@ WRITE_LINE_MEMBER(rmnimbus_state::write_scsi_iena) check_scsi_irq(); } +// This emulates the 74LS74 latched version of req +void rmnimbus_state::set_scsi_drqlat(bool clock, bool clear) +{ + if (clear) + m_scsi_reqlat = 0; + else if (clock) + m_scsi_reqlat = 1; + + if(m_scsi_reqlat) + hdc_drq(true); + else + hdc_drq(false); +} + void rmnimbus_state::hdc_post_rw() { if(m_scsi_req) m_scsibus->write_ack(1); + + // IC17A, IC17B, latched req cleared by SCSI data read or write, or C/D= command + set_scsi_drqlat(false, true); } void rmnimbus_state::hdc_drq(bool state) @@ -1189,6 +1220,10 @@ WRITE_LINE_MEMBER( rmnimbus_state::write_scsi_bsy ) WRITE_LINE_MEMBER( rmnimbus_state::write_scsi_cd ) { m_scsi_cd = state; + + // IC17A, IC17B, latched req cleared by SCSI data read or write, or C/D= command + set_scsi_drqlat(false, !m_scsi_cd); + check_scsi_irq(); } @@ -1205,26 +1240,23 @@ WRITE_LINE_MEMBER( rmnimbus_state::write_scsi_io ) WRITE_LINE_MEMBER( rmnimbus_state::write_scsi_msg ) { - m_scsi_msg = state; + m_scsi_msg = !state; } WRITE_LINE_MEMBER( rmnimbus_state::write_scsi_req ) { - int last = m_scsi_req; + // Detect rising edge on req, IC11b, clock + int rising = ((m_scsi_req == 0) && (state == 1)); + + // This is the state of the actual line from the SCSI m_scsi_req = state; - - if (state) - { - if (!m_scsi_cd && !last) - { - hdc_drq(true); - } - } - else - { - hdc_drq(false); + + // Latched req, is forced low by C/D being set to command + set_scsi_drqlat(rising, m_scsi_cd); + + if (!m_scsi_reqlat) m_scsibus->write_ack(0); - } + check_scsi_irq(); } @@ -1500,18 +1532,13 @@ WRITE_LINE_MEMBER(rmnimbus_state::nimbus_msm5205_vck) external_int(EXTERNAL_INT_MSM5205,state); } -static const int MOUSE_XYA[3][4] = { { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 } }; -static const int MOUSE_XYB[3][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 } }; -//static const int MOUSE_XYA[4] = { 1, 1, 0, 0 }; -//static const int MOUSE_XYB[4] = { 0, 1, 1, 0 }; +static const int MOUSE_XYA[4] = { 1, 1, 0, 0 }; +static const int MOUSE_XYB[4] = { 0, 1, 1, 0 }; void rmnimbus_state::mouse_js_reset() { - m_nimbus_mouse.m_mouse_px=0; - m_nimbus_mouse.m_mouse_py=0; m_nimbus_mouse.m_mouse_x=128; m_nimbus_mouse.m_mouse_y=128; - m_nimbus_mouse.m_mouse_pc=0; m_nimbus_mouse.m_mouse_pcx=0; m_nimbus_mouse.m_mouse_pcy=0; m_nimbus_mouse.m_intstate_x=0; @@ -1519,114 +1546,88 @@ void rmnimbus_state::mouse_js_reset() m_nimbus_mouse.m_reg0a4=0xC0; // Setup timer to poll the mouse - m_nimbus_mouse.m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(1000)); + m_nimbus_mouse.m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(MOUSE_POLL_FREQUENCY)); } void rmnimbus_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - uint8_t x = 0; - uint8_t y = 0; -// int pc=m_maincpu->pc(); - - uint8_t intstate_x; - uint8_t intstate_y; - int xint; + int mouse_x = 0; // Current mouse X and Y + int mouse_y = 0; + int xdiff = 0; // Difference from previous X and Y + int ydiff = 0; + + uint8_t intstate_x; // Used to calculate if we should trigger interrupt + uint8_t intstate_y; + int xint; // X and Y interrupts to trigger int yint; - m_nimbus_mouse.m_reg0a4 = m_io_mouse_button->read() | 0xC0; - x = m_io_mousex->read(); - y = m_io_mousey->read(); - - uint8_t mxa; + uint8_t mxa; // Values of quadrature encoders for X and Y uint8_t mxb; uint8_t mya; uint8_t myb; - //logerror("poll_mouse()\n"); - - if (x == m_nimbus_mouse.m_mouse_x) - { - m_nimbus_mouse.m_mouse_px = MOUSE_PHASE_STATIC; - } - else if (x > m_nimbus_mouse.m_mouse_x) - { - m_nimbus_mouse.m_mouse_px = MOUSE_PHASE_POSITIVE; - } - else if (x < m_nimbus_mouse.m_mouse_x) - { - m_nimbus_mouse.m_mouse_px = MOUSE_PHASE_NEGATIVE; - } - - if (y == m_nimbus_mouse.m_mouse_y) - { - m_nimbus_mouse.m_mouse_py = MOUSE_PHASE_STATIC; - } - else if (y > m_nimbus_mouse.m_mouse_y) - { - m_nimbus_mouse.m_mouse_py = MOUSE_PHASE_POSITIVE; - } - else if (y < m_nimbus_mouse.m_mouse_y) - { - m_nimbus_mouse.m_mouse_py = MOUSE_PHASE_NEGATIVE; - } - - switch (m_nimbus_mouse.m_mouse_px) - { - case MOUSE_PHASE_STATIC : break; - case MOUSE_PHASE_POSITIVE : m_nimbus_mouse.m_mouse_pcx++; break; - case MOUSE_PHASE_NEGATIVE : m_nimbus_mouse.m_mouse_pcx--; break; - } + // Read mouse buttons + m_nimbus_mouse.m_reg0a4 = m_io_mouse_button->read(); + + // Read mose positions and calculate difference from previous value + mouse_x = m_io_mousex->read(); + mouse_y = m_io_mousey->read(); + + xdiff = m_nimbus_mouse.m_mouse_x - mouse_x; + ydiff = m_nimbus_mouse.m_mouse_y - mouse_y; + + // check and compensate for wrap..... + if (xdiff > 0x80) + xdiff -= 0x100; + else if (xdiff < -0x80) + xdiff += 0x100; + + if (ydiff > 0x80) + ydiff -= 0x100; + else if (ydiff < -0x80) + ydiff += 0x100; + + // convert movement into emulated movement of quadrature encoder in mouse. + if (xdiff < 0) + m_nimbus_mouse.m_mouse_pcx++; + else if (xdiff > 0) + m_nimbus_mouse.m_mouse_pcx--; + + if (ydiff < 0) + m_nimbus_mouse.m_mouse_pcy++; + else if (ydiff > 0) + m_nimbus_mouse.m_mouse_pcy--; + + // Compensate for quadrature wrap. m_nimbus_mouse.m_mouse_pcx &= 0x03; - - switch (m_nimbus_mouse.m_mouse_py) - { - case MOUSE_PHASE_STATIC : break; - case MOUSE_PHASE_POSITIVE : m_nimbus_mouse.m_mouse_pcy++; break; - case MOUSE_PHASE_NEGATIVE : m_nimbus_mouse.m_mouse_pcy--; break; - } m_nimbus_mouse.m_mouse_pcy &= 0x03; -// mxb = MOUSE_XYB[state.m_mouse_px][state->m_mouse_pcx]; // XB -// mxa = MOUSE_XYA[state.m_mouse_px][state->m_mouse_pcx]; // XA -// mya = MOUSE_XYA[state.m_mouse_py][state->m_mouse_pcy]; // YA -// myb = MOUSE_XYB[state.m_mouse_py][state->m_mouse_pcy]; // YB - - mxb = MOUSE_XYB[1][m_nimbus_mouse.m_mouse_pcx]; // XB - mxa = MOUSE_XYA[1][m_nimbus_mouse.m_mouse_pcx]; // XA - mya = MOUSE_XYA[1][m_nimbus_mouse.m_mouse_pcy]; // YA - myb = MOUSE_XYB[1][m_nimbus_mouse.m_mouse_pcy]; // YB - - if ((m_nimbus_mouse.m_mouse_py!=MOUSE_PHASE_STATIC) || (m_nimbus_mouse.m_mouse_px!=MOUSE_PHASE_STATIC)) - { -// logerror("mouse_px=%02X, mouse_py=%02X, mouse_pcx=%02X, mouse_pcy=%02X\n", -// state.m_mouse_px,state->m_mouse_py,state->m_mouse_pcx,state->m_mouse_pcy); - -// logerror("mxb=%02x, mxa=%02X (mxb ^ mxa)=%02X, (ay8910_a & 0xC0)=%02X, (mxb ^ mxa) ^ ((ay8910_a & 0x80) >> 7)=%02X\n", -// mxb,mxa, (mxb ^ mxa) , (state.m_ay8910_a & 0xC0), (mxb ^ mxa) ^ ((state->m_ay8910_a & 0x40) >> 6)); - } + // get value of mouse quadrature encoders for this wheel position + mxa = MOUSE_XYA[m_nimbus_mouse.m_mouse_pcx]; // XA + mxb = MOUSE_XYB[m_nimbus_mouse.m_mouse_pcx]; // XB + mya = MOUSE_XYA[m_nimbus_mouse.m_mouse_pcy]; // YA + myb = MOUSE_XYB[m_nimbus_mouse.m_mouse_pcy]; // YB + // calculate interrupt state intstate_x = (mxb ^ mxa) ^ ((m_ay8910_a & 0x40) >> 6); intstate_y = (myb ^ mya) ^ ((m_ay8910_a & 0x80) >> 7); + // Generate interrupts if enabled, otherwise return values in + // mouse register if (MOUSE_INT_ENABLED(this)) { if ((intstate_x==1) && (m_nimbus_mouse.m_intstate_x==0)) -// if (intstate_x!=state.m_intstate_x) { - xint=mxa ? EXTERNAL_INT_MOUSE_XR : EXTERNAL_INT_MOUSE_XL; + xint=mxa ? EXTERNAL_INT_MOUSE_XL : EXTERNAL_INT_MOUSE_XR; external_int(xint, true); - -// logerror("Xint:%02X, mxb=%02X\n",xint,mxb); } if ((intstate_y==1) && (m_nimbus_mouse.m_intstate_y==0)) -// if (intstate_y!=state.m_intstate_y) { - yint=myb ? EXTERNAL_INT_MOUSE_YU : EXTERNAL_INT_MOUSE_YD; + yint=myb ? EXTERNAL_INT_MOUSE_YD : EXTERNAL_INT_MOUSE_YU; external_int(yint, true); -// logerror("Yint:%02X, myb=%02X\n",yint,myb); } } else @@ -1638,15 +1639,11 @@ void rmnimbus_state::device_timer(emu_timer &timer, device_timer_id id, int para m_nimbus_mouse.m_reg0a4 |= ( myb & 0x01) << 0; // YB } - m_nimbus_mouse.m_mouse_x = x; - m_nimbus_mouse.m_mouse_y = y; - - if ((m_nimbus_mouse.m_mouse_py!=MOUSE_PHASE_STATIC) || (m_nimbus_mouse.m_mouse_px!=MOUSE_PHASE_STATIC)) - { -// logerror("pc=%05X, reg0a4=%02X, reg092=%02X, ay_a=%02X, x=%02X, y=%02X, px=%02X, py=%02X, intstate_x=%02X, intstate_y=%02X\n", -// pc,state.m_reg0a4,state->m_iou_reg092,state->m_ay8910_a,state->m_mouse_x,state->m_mouse_y,state->m_mouse_px,state->m_mouse_py,intstate_x,intstate_y); - } + // Update current mouse position + m_nimbus_mouse.m_mouse_x = mouse_x; + m_nimbus_mouse.m_mouse_y = mouse_y; + // and interrupt state m_nimbus_mouse.m_intstate_x=intstate_x; m_nimbus_mouse.m_intstate_y=intstate_y; } @@ -1672,21 +1669,25 @@ uint8_t rmnimbus_state::nimbus_mouse_js_r() if (m_io_config->read() & 0x01) { - result=m_nimbus_mouse.m_reg0a4; + result=m_nimbus_mouse.m_reg0a4 | 0xC0; //logerror("mouse_js_r: pc=%05X, result=%02X\n",pc,result); } else { - result = m_io_joystick0->read(); + result = m_io_joystick0->read() | 0xC0; } return result; } +// Clear mose latches void rmnimbus_state::nimbus_mouse_js_w(uint8_t data) { + m_nimbus_mouse.m_reg0a4 = 0x00; + //logerror("clear mouse latches\n"); } + /********************************************************************** Parallel printer / User port. The Nimbus parallel printer port card is almost identical to the circuit diff --git a/src/mame/video/rmnimbus.cpp b/src/mame/video/rmnimbus.cpp index b779d31bd15..a4e6004c219 100644 --- a/src/mame/video/rmnimbus.cpp +++ b/src/mame/video/rmnimbus.cpp @@ -21,7 +21,13 @@ MB61H201 Fujitsu RML 12835 GCV, I have had to determine most of its operation by disassembling the Nimbus bios and by writing experemental code on the real machine. + + 2021-09-29, P.Harvey-Smith. + + I now have access to the service manual for the Nimbus, this documents to facilities provided + by the video chip, which will hopefully allow a much more accurate implementation. */ + #include "emu.h" #include "includes/rmnimbus.h" @@ -30,6 +36,140 @@ #include <functional> +/* + Acording to the service manual the Nimbus should be capable of the following modes : + + 320 x 200 4bpp + 640 x 200 2bpp + 400 x 200 4bpp + 800 x 200 2bpp + 320 x 250 4bpp + 640 x 250 2bpp + 400 x 250 4bpp + 800 x 250 2bpp +*/ + +/* + From the service manual the registers are defined as follows : + +Ports 0x00-0x1E are the registers used to update the display RAM thus : + +Addr m_x m_y Update memory on write? +0x00 nop nop no +0x02 load nop no +0x04 nop inc no +0x06 load inc no +0x08 nop nop no +0x0A inc nop no +0x0C nop load no +0x0E inc load no +0x10 nop nop yes +0x12 load nop yes +0x14 nop inc yes +0x16 load inc yes +0x18 nop nop yes +0x1A inc nop yes +0x1C nop load yes +0x1E inc load yes + +0x20 scroll port, contains 8 bit scroll address + +0x22 Update mode control port (up_mode), controls how data is written to display ram. + see UPMODE_ constants below + +0x24h Intensity port, provides current logical intensities for update operations + bits 0..3 Foreground + bits 4..7 Background + +0x26 Display mode (m_mode) current display mode and border colour. + see MODE_ constants below + +For READ. +Ports 0x28, 0x2A, 0x2C and 0x2E have different read and write functions : + +0x28 Timing / status, all bits active high + bit 0 line blank + bit 1 line display + bit 2 frame blank + bit 3 frame display + +0x2A X address status, returns current value of X counter (m_x) + +0x2C Y address status, returns current value of Y counter (m_y) + +For Write + +0x28, 0x2A, 0x2C, 0x2E Colour look up table : + + Logic colour +Port Bits Low res High Res +0x28 0..3 0 0 +0x28 4..7 1 0 +0x28 8..11 2 0 +0x28 12..15 3 0 + +0x2A 0..3 3 1 +0x2A 4..7 5 1 +0x2A 8..11 6 1 +0x2A 12..15 7 1 + +0x2C 0..3 8 2 +0x2C 4..7 9 2 +0x2C 8..11 10 2 +0x2C 12..15 11 2 + +0x2E 0..3 12 3 +0x2E 4..7 13 3 +0x2E 8..11 14 3 +0x2E 12..15 15 3 + + +*/ + +// In following definitions ports are the WORD offset, the RM manual +// lists them by the byte offset so they are 2* the value + +#define P_SCROLL 0x10 +#define P_UPDATE_MODE 0x11 +#define P_INTENSITY 0x12 +#define P_MODE 0x13 +#define P_STATUS 0x14 +#define P_X_COUNT 0x15 +#define P_Y_COUNT 0x16 + +#define P_COLOUR03 0x14 +#define P_COLOUR47 0x15 +#define P_COLOUR8B 0x16 +#define P_COLOURCF 0x17 + +// From the service manual, Reg022 update mode constants : +// The first 8 are NON XOR writes +#define UPMODE_40_TEXT 0x00 // 40 character text +#define UPMODE_80_TEXT 0x01 // 80 character text +#define UPMODE_LO_PIXEL 0x02 // Low res pixel +#define UPMODE_HI_PIXEL 0x03 // Hi res pixel +#define UPMODE_ANIMATION 0x04 // Animation (mask + data) +#define UPMODE_SCROLL 0x05 // Scroll mode +#define UPMODE_DIRECT 0x06 // Direct write to video ram +#define UPMODE_ILLEGAL7 0x07 + +// The second 8 are XOR writes +#define UPMODE_40_TEXT_X 0x08 +#define UPMODE_80_TEXT_X 0x09 +#define UPMODE_LO_PIXEL_X 0x0A +#define UPMODE_HI_PIXEL_X 0x0B +#define UPMODE_ANIMATION_X 0x0C +#define UPMODE_SCROLL_X 0x0D +#define UPMODE_DIRECT_X 0x0E +#define UPMODE_ILLEGALF 0x0F + +#define UP_XOR_MASK 0x08 + +// port 026, display mode (m_mode) +#define MODE_BORDER 0x0F // bits 0..3, Border colour number +#define MODE_RESOLUTION 0x10 // bit 4, 0=low res (40 col), high = high res (80 col) +#define MODE_WIDTH 0x20 // bit 5, 0=narrow, 1=wide +#define MODE_HEIGHT 0x40 // bit 6, 0=625 lines, 1=562 #define WIDTH_MASK 0x07 @@ -38,8 +178,8 @@ #define SELECT_COL(x,c) (IS_80COL ? ((((x) & 1) ? ((c) << 2) : (c)) & 0xC) : (c)) #define FILL_WORD(c) (((c) << 12) | ((c) << 8) | ((c) << 4) | (c)) -#define IS_80COL (m_mode&0x10) -#define IS_XOR (m_op&8) +#define IS_80COL (m_mode & MODE_RESOLUTION) +#define IS_XOR (m_upmode & UP_XOR_MASK) #define DEBUG_TEXT 0x01 #define DEBUG_DB 0x02 @@ -66,27 +206,28 @@ uint16_t rmnimbus_state::nimbus_video_io_r(offs_t offset, uint16_t mem_mask) result = read_pixel_data(++m_x, m_y); break; - case 0x10: + case P_SCROLL: result = m_yline; break; - case 0x11: - result = m_op; + case P_UPDATE_MODE: + result = m_upmode; break; - case 0x12: + case P_INTENSITY: result = m_colours; break; - case 0x13: + case P_MODE: result = m_mode; break; - case 0x14: + case P_STATUS: result = m_screen->vpos() % 0xb; // TODO: verify break; - case 0x15: + case P_X_COUNT: result = m_x; break; - case 0x16: + case P_Y_COUNT: result = m_y; break; + default: logerror("nimbus: unknown video reg read %02x\n", offset); break; @@ -139,11 +280,11 @@ uint16_t rmnimbus_state::read_pixel_data(uint16_t x, uint16_t y) uint16_t result=0; if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) - logerror("read_pixel_data(x=%d, y=%d), reg022=%04X\n",x,y,m_op); + logerror("read_pixel_data(x=%d, y=%d), reg022=%04X\n",x,y,m_upmode); if(IS_80COL) { - switch (m_op & WIDTH_MASK) + switch (m_upmode & WIDTH_MASK) { case 0x00 : break; @@ -168,7 +309,7 @@ uint16_t rmnimbus_state::read_pixel_data(uint16_t x, uint16_t y) } else /* 40 Col */ { - switch (m_op & WIDTH_MASK) + switch (m_upmode & WIDTH_MASK) { case 0x00 : break; @@ -260,27 +401,27 @@ void rmnimbus_state::nimbus_video_io_w(offs_t offset, uint16_t data, uint16_t me m_x++; break; - case 0x10: + case P_SCROLL: m_yline = data; return; - case 0x11: - m_op = data; + case P_UPDATE_MODE: + m_upmode = data; return; - case 0x12: + case P_INTENSITY: m_colours = data; return; - case 0x13: + case P_MODE: /* bits 0..3 of reg026 contain the border colour. bit 5 contains the 40/80 column (320/640 pixel) flag. */ m_mode = data; return; - case 0x14: - case 0x15: - case 0x16: - case 0x17: - change_palette(offset - 0x14, data); + case P_COLOUR03: + case P_COLOUR47: + case P_COLOUR8B: + case P_COLOURCF: + change_palette(offset - P_COLOUR03, data); return; default: @@ -382,84 +523,88 @@ void rmnimbus_state::move_pixel_line(uint16_t x, uint16_t y, uint8_t pixels) void rmnimbus_state::write_pixel_data(uint16_t x, uint16_t y, uint16_t data) { if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) - logerror("write_pixel_data(x=%d, y=%d, data=%04X), reg022=%04X\n",x,y,data,m_op); + logerror("write_pixel_data(x=%d, y=%d, data=%04X), reg022=%04X\n",x,y,data,m_upmode); if(IS_80COL) { - switch (m_op & WIDTH_MASK) + switch (m_upmode & WIDTH_MASK) { - case 0x00: + case UPMODE_40_TEXT: write_pixel_line(x,y,data,16,1); break; - case 0x01: + case UPMODE_80_TEXT: write_pixel_line(x,y,data,8,1); break; - case 0x02: + case UPMODE_LO_PIXEL: write_pixel_line(x,y,data,8,1); break; - case 0x03: + case UPMODE_HI_PIXEL: set_pixel(x,y,SELECT_COL(x, FG_COLOUR)); break; - case 0x04: + case UPMODE_ANIMATION: write_pixel_line(x,y,(((data & 0xFF00)>>8) & (data & 0xFF)) | (~((data & 0xFF00)>>8) & read_pixel_line(x,y,4,2)),4,2); break; - case 0x05: + case UPMODE_SCROLL: move_pixel_line(x,y,16); break; - case 0x06: + case UPMODE_DIRECT: write_pixel_line(x,y,data,8,2); break; - case 0x07: + case UPMODE_ILLEGAL7: set_pixel(x,y,SELECT_COL(x, FG_COLOUR)); break; } } else /* 40 Col */ { - switch (m_op & WIDTH_MASK) + switch (m_upmode & WIDTH_MASK) { - case 0x00: + case UPMODE_40_TEXT: write_pixel_line(x,y,data,8,1); break; - case 0x01: + case UPMODE_80_TEXT: write_pixel_line(x,y,data,4,2); break; - case 0x02: + case UPMODE_LO_PIXEL: set_pixel40(x,y,FG_COLOUR); break; - case 0x03: + case UPMODE_HI_PIXEL: set_pixel(x,y,FG_COLOUR); break; - case 0x04: + case UPMODE_ANIMATION: write_pixel_line(x,y,(((data & 0xFF00)>>8) & (data & 0xFF)) | (~((data & 0xFF00)>>8) & read_pixel_line(x,y,2,4)),2,4); break; - case 0x05: + case UPMODE_SCROLL: move_pixel_line(x,y,16); break; - case 0x06: + case UPMODE_DIRECT: write_pixel_line(x,y,data,4,4); break; - case 0x07: + case UPMODE_ILLEGAL7: set_pixel(x,y,FG_COLOUR); break; } } } +// Colours are encoded as follows : +// Each nibble contains a colour encoded as igrb +// so we shift through the specified colours and extract the bits, to set the palette. +// void rmnimbus_state::change_palette(uint8_t bank, uint16_t colours) { // loop over changing colours @@ -507,7 +652,7 @@ void rmnimbus_state::video_reset() m_mode = 0; m_x = 0; m_y = 0; - m_op = 0; + m_upmode = 0; m_yline = 0; } |