summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/xavix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/xavix.cpp')
-rw-r--r--src/mame/video/xavix.cpp730
1 files changed, 730 insertions, 0 deletions
diff --git a/src/mame/video/xavix.cpp b/src/mame/video/xavix.cpp
new file mode 100644
index 00000000000..6c576f8eb8d
--- /dev/null
+++ b/src/mame/video/xavix.cpp
@@ -0,0 +1,730 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#include "emu.h"
+#include "includes/xavix.h"
+
+inline void xavix_state::set_data_address(int address, int bit)
+{
+ m_tmp_dataaddress = address;
+ m_tmp_databit = bit;
+}
+
+inline uint8_t xavix_state::get_next_bit()
+{
+ uint8_t bit = m_rgn[m_tmp_dataaddress & (m_rgnlen - 1)];
+ bit = bit >> m_tmp_databit;
+ bit &= 1;
+
+ m_tmp_databit++;
+
+ if (m_tmp_databit == 8)
+ {
+ m_tmp_databit = 0;
+ m_tmp_dataaddress++;
+ }
+
+ return bit;
+}
+
+inline uint8_t xavix_state::get_next_byte()
+{
+ uint8_t dat = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ dat |= (get_next_bit() << i);
+ }
+ return dat;
+}
+
+inline int xavix_state::get_current_address_byte()
+{
+ return m_tmp_dataaddress;
+}
+
+
+void xavix_state::video_start()
+{
+}
+
+
+double xavix_state::hue2rgb(double p, double q, double t)
+{
+ if (t < 0) t += 1;
+ if (t > 1) t -= 1;
+ if (t < 1 / 6.0f) return p + (q - p) * 6 * t;
+ if (t < 1 / 2.0f) return q;
+ if (t < 2 / 3.0f) return p + (q - p) * (2 / 3.0f - t) * 6;
+ return p;
+}
+
+
+void xavix_state::handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // not verified
+ int offs = 0;
+ for (int index = 0; index < 256; index++)
+ {
+ uint16_t dat = m_palram1[offs];
+ dat |= m_palram2[offs]<<8;
+ offs++;
+
+ int l_raw = (dat & 0x1f00) >> 8;
+ int sl_raw =(dat & 0x00e0) >> 5;
+ int h_raw = (dat & 0x001f) >> 0;
+
+ //if (h_raw > 24)
+ // logerror("hraw >24 (%02x)\n", h_raw);
+
+ //if (l_raw > 17)
+ // logerror("lraw >17 (%02x)\n", l_raw);
+
+ //if (sl_raw > 7)
+ // logerror("sl_raw >5 (%02x)\n", sl_raw);
+
+ double l = (double)l_raw / 17.0f;
+ double s = (double)sl_raw / 7.0f;
+ double h = (double)h_raw / 24.0f;
+
+ double r, g, b;
+
+ if (s == 0) {
+ r = g = b = l; // greyscale
+ }
+ else {
+ double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
+ double p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1 / 3.0f);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1 / 3.0f);
+ }
+
+ int r_real = r * 255.0f;
+ int g_real = g * 255.0f;
+ int b_real = b * 255.0f;
+
+ m_palette->set_pen_color(index, r_real, g_real, b_real);
+
+ }
+}
+
+void xavix_state::draw_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which)
+{
+ int alt_tileaddressing = 0;
+ int alt_tileaddressing2 = 0;
+
+ int ydimension = 0;
+ int xdimension = 0;
+ int ytilesize = 0;
+ int xtilesize = 0;
+ int offset_multiplier = 0;
+ int opaque = 0;
+
+ uint8_t* tileregs;
+ address_space& mainspace = m_maincpu->space(AS_PROGRAM);
+
+ if (which == 0)
+ {
+ tileregs = m_tmap1_regs;
+ opaque = 1;
+ }
+ else
+ {
+ tileregs = m_tmap2_regs;
+ opaque = 0;
+ }
+
+ switch (tileregs[0x3] & 0x30)
+ {
+ case 0x00:
+ ydimension = 32;
+ xdimension = 32;
+ ytilesize = 8;
+ xtilesize = 8;
+ break;
+
+ case 0x10:
+ ydimension = 32;
+ xdimension = 16;
+ ytilesize = 8;
+ xtilesize = 16;
+ break;
+
+ case 0x20: // guess
+ ydimension = 16;
+ xdimension = 32;
+ ytilesize = 16;
+ xtilesize = 8;
+ break;
+
+ case 0x30:
+ ydimension = 16;
+ xdimension = 16;
+ ytilesize = 16;
+ xtilesize = 16;
+ break;
+ }
+
+ offset_multiplier = (ytilesize * xtilesize)/8;
+
+ if (tileregs[0x7] & 0x10)
+ alt_tileaddressing = 1;
+ else
+ alt_tileaddressing = 0;
+
+ if (tileregs[0x7] & 0x02)
+ alt_tileaddressing2 = 1;
+
+ static int hackx = 1;
+
+ if (machine().input().code_pressed_once(KEYCODE_Q))
+ {
+ hackx--;
+ logerror("%02x\n", hackx);
+ }
+
+ if (machine().input().code_pressed_once(KEYCODE_W))
+ {
+ hackx++;
+ logerror("%02x\n", hackx);
+ }
+
+ if (tileregs[0x7] & 0x80)
+ {
+ //logerror("draw tilemap %d, regs base0 %02x base1 %02x base2 %02x tilesize,bpp %02x scrollx %02x scrolly %02x pal %02x mode %02x\n", which, tileregs[0x0], tileregs[0x1], tileregs[0x2], tileregs[0x3], tileregs[0x4], tileregs[0x5], tileregs[0x6], tileregs[0x7]);
+
+ // there's a tilemap register to specify base in main ram, although in the monster truck test mode it points to an unmapped region
+ // and expected a fixed layout, we handle that in the memory map at the moment
+ int count;
+
+ count = 0;// ;
+ for (int y = 0; y < ydimension; y++)
+ {
+ for (int x = 0; x < xdimension; x++)
+ {
+ int bpp, pal, scrolly, scrollx;
+ int tile = 0;
+ int extraattr = 0;
+
+ // the register being 0 probably isn't the condition here
+ if (tileregs[0x0] != 0x00) tile |= mainspace.read_byte((tileregs[0x0] << 8) + count);
+ if (tileregs[0x1] != 0x00) tile |= mainspace.read_byte((tileregs[0x1] << 8) + count) << 8;
+
+ // at the very least boxing leaves unwanted bits set in ram after changing between mode 0x8a and 0x82, expecting them to not be used
+ if (tileregs[0x7] & 0x08)
+ extraattr = mainspace.read_byte((tileregs[0x2] << 8) + count);
+
+ count++;
+
+ bpp = (tileregs[0x3] & 0x0e) >> 1;
+ bpp++;
+ pal = (tileregs[0x6] & 0xf0) >> 4;
+ scrolly = tileregs[0x5];
+ scrollx = tileregs[0x4];
+
+ int basereg;
+ int flipx = 0;
+ int flipy = 0;
+ int gfxbase;
+
+ // tile 0 is always skipped, doesn't even point to valid data packets in alt mode
+ // this is consistent with the top layer too
+ // should we draw as solid in solid layer?
+ if (tile == 0)
+ continue;
+
+ const int debug_packets = 0;
+ int test = 0;
+
+ if (!alt_tileaddressing)
+ {
+ if (!alt_tileaddressing2)
+ {
+ basereg = 0;
+ gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+
+ tile = tile * (offset_multiplier * bpp);
+ tile += gfxbase;
+ }
+ else
+ {
+ tile = tile * 8;
+ basereg = (tile & 0x70000) >> 16;
+ tile &= 0xffff;
+ gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+ tile += gfxbase;
+
+ if (tileregs[0x7] & 0x08)
+ {
+ // make use of the extraattr stuff?
+ pal = (extraattr & 0xf0)>>4;
+ // low bits are priority?
+ }
+ }
+ }
+ else
+ {
+ if (debug_packets) logerror("for tile %04x (at %d %d): ", tile, (((x * 16) + scrollx) & 0xff), (((y * 16) + scrolly) & 0xff));
+
+
+ basereg = (tile & 0xf000) >> 12;
+ tile &= 0x0fff;
+ gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+
+ tile += gfxbase;
+ set_data_address(tile, 0);
+
+ // there seems to be a packet stored before the tile?!
+ // the offset used for flipped sprites seems to specifically be changed so that it picks up an extra byte which presumably triggers the flipping
+ uint8_t byte1 = 0;
+ int done = 0;
+ int skip = 0;
+
+ do
+ {
+ byte1 = get_next_byte();
+
+ if (debug_packets) logerror(" %02x, ", byte1);
+
+ if (skip == 1)
+ {
+ skip = 0;
+ //test = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x01)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x03)
+ {
+ // causes next byte to be skipped??
+ skip = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x05)
+ {
+ // the upper bits are often 0x00, 0x10, 0x20, 0x30, why?
+ flipx = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x06) // there must be other finish conditions too because sometimes this fails..
+ {
+ // tile data will follow after this, always?
+ pal = (byte1 & 0xf0) >> 4;
+ done = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x07)
+ {
+ // causes next byte to be skipped??
+ skip = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x09)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x0a)
+ {
+ // not seen
+ }
+ else if ((byte1 & 0x0f) == 0x0b)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x0c)
+ {
+ // not seen
+ }
+ else if ((byte1 & 0x0f) == 0x0d)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x0e)
+ {
+ // not seen
+ }
+ else if ((byte1 & 0x0f) == 0x0f)
+ {
+ // used
+ }
+
+ } while (done == 0);
+ if (debug_packets) logerror("\n");
+ tile = get_current_address_byte();
+ }
+
+ if (test == 1) pal = machine().rand() & 0xf;
+
+
+ draw_tile(screen, bitmap, cliprect, tile, bpp, (x * xtilesize) + scrollx, ((y * ytilesize) - 16) - scrolly, ytilesize, xtilesize, flipx, flipy, pal, opaque);
+ draw_tile(screen, bitmap, cliprect, tile, bpp, (x * xtilesize) + scrollx, (((y * ytilesize) - 16) - scrolly) + 256, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-y
+ draw_tile(screen, bitmap, cliprect, tile, bpp, ((x * xtilesize) + scrollx) - 256, ((y * ytilesize) - 16) - scrolly, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-x
+ draw_tile(screen, bitmap, cliprect, tile, bpp, ((x * xtilesize) + scrollx) - 256, (((y * ytilesize) - 16) - scrolly) + 256, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-y and x
+ }
+ }
+ }
+}
+
+void xavix_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ //logerror("frame\n");
+ // priority doesn't seem to be based on list order, there are bad sprite-sprite priorities with either forward or reverse
+
+ for (int i = 0xff; i >= 0; i--)
+ {
+ /* attribute 0 bits
+ pppp bbb- p = palette, b = bpp
+
+ attribute 1 bits
+ ---- ss-f s = size, f = flipx
+ */
+
+ int ypos = m_spr_ypos[i];
+ int xpos = m_spr_xpos[i];
+ int tile = (m_spr_addr_hi[i] << 16) | (m_spr_addr_md[i] << 8) | m_spr_addr_lo[i];
+ int attr0 = m_spr_attr0[i];
+ int attr1 = m_spr_attr1[i];
+
+ int pal = (attr0 & 0xf0) >> 4;
+ int flipx = (attr1 & 0x01);
+
+ int drawheight = 16;
+ int drawwidth = 16;
+
+ tile &= (m_rgnlen - 1);
+
+ // taito nostalgia 1 also seems to use a different addressing, is it selectable or is the chip different?
+ // taito nost attr1 is 84 / 80 / 88 / 8c for the various elements of the xavix logo. monster truck uses ec / fc / dc / 4c / 5c / 6c (final 6 sprites ingame are 00 00 f0 f0 f0 f0, radar?)
+
+ if ((attr1 & 0x0c) == 0x0c)
+ {
+ drawheight = 16;
+ drawwidth = 16;
+ if (m_alt_addressing == 1)
+ tile = tile * 128;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+ else if ((attr1 & 0x0c) == 0x08)
+ {
+ drawheight = 16;
+ drawwidth = 8;
+ xpos += 4;
+ if (m_alt_addressing == 1)
+ tile = tile * 64;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+ else if ((attr1 & 0x0c) == 0x04)
+ {
+ drawheight = 8;
+ drawwidth = 16;
+ ypos -= 4;
+ if (m_alt_addressing == 1)
+ tile = tile * 64;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+ else if ((attr1 & 0x0c) == 0x00)
+ {
+ drawheight = 8;
+ drawwidth = 8;
+ xpos += 4;
+ ypos -= 4;
+ if (m_alt_addressing == 1)
+ tile = tile * 32;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+
+ if (m_alt_addressing != 0)
+ {
+ int basereg = (tile & 0xf0000) >> 16;
+ tile &= 0xffff;
+ int gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+ tile+= gfxbase;
+ }
+
+ ypos = 0x100 - ypos;
+
+ xpos -= 136;
+ ypos -= 152;
+
+ xpos &= 0xff;
+ ypos &= 0xff;
+
+ if (ypos >= 192)
+ ypos -= 256;
+
+ int bpp = 1;
+
+ bpp = (attr0 & 0x0e) >> 1;
+ bpp += 1;
+
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos, ypos, drawheight, drawwidth, flipx, 0, pal, 0);
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos - 256, ypos, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-x
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos, ypos - 256, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-y
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos - 256, ypos - 256, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-x,y
+
+ /*
+ if ((m_spr_ypos[i] != 0x81) && (m_spr_ypos[i] != 0x80) && (m_spr_ypos[i] != 0x00))
+ {
+ logerror("sprite with enable? %02x attr0 %02x attr1 %02x attr3 %02x attr5 %02x attr6 %02x attr7 %02x\n", m_spr_ypos[i], m_spr_attr0[i], m_spr_attr1[i], m_spr_xpos[i], m_spr_addr_lo[i], m_spr_addr_md[i], m_spr_addr_hi[i] );
+ }
+ */
+ }
+}
+
+void xavix_state::draw_tile(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int tile, int bpp, int xpos, int ypos, int drawheight, int drawwidth, int flipx, int flipy, int pal, int opaque)
+{
+ // set the address here so we can increment in bits in the draw function
+ set_data_address(tile, 0);
+
+ for (int y = 0; y < drawheight; y++)
+ {
+ int row;
+ if (flipy)
+ {
+ row = ypos + (drawheight-1) - y;
+ }
+ else
+ {
+ row = ypos + y;
+ }
+
+ for (int x = 0; x < drawwidth; x++)
+ {
+
+ int col;
+
+ if (flipx)
+ {
+ col = xpos + (drawwidth-1) - x;
+ }
+ else
+ {
+ col = xpos + x;
+ }
+
+ uint8_t dat = 0;
+
+ for (int i = 0; i < bpp; i++)
+ {
+ dat |= (get_next_bit() << i);
+ }
+
+ if ((row >= cliprect.min_y && row <= cliprect.max_y) && (col >= cliprect.min_x && col <= cliprect.max_x))
+ {
+ uint16_t* rowptr;
+
+ rowptr = &bitmap.pix16(row);
+
+ if (opaque)
+ {
+ rowptr[col] = (dat + (pal << 4)) & 0xff;
+ }
+ else
+ {
+ if (dat)
+ rowptr[col] = (dat + (pal << 4)) & 0xff;
+ }
+ }
+ }
+ }
+}
+
+uint32_t xavix_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ handle_palette(screen, bitmap, cliprect);
+
+ bitmap.fill(0, cliprect);
+
+ draw_tilemap(screen,bitmap,cliprect,0);
+ draw_sprites(screen,bitmap,cliprect);
+ draw_tilemap(screen,bitmap,cliprect,1);
+
+ //popmessage("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", m_75fx[0],m_75fx[1],m_75fx[2],m_75fx[3],m_75fx[4],m_75fx[5],m_75fx[6],m_75fx[7],m_75fx[8],m_75fx[9],m_75fx[10],m_75fx[11],m_75fx[12],m_75fx[13],m_75fx[14],m_75fx[15]);
+
+ return 0;
+}
+
+
+WRITE8_MEMBER(xavix_state::vid_dma_params_1_w)
+{
+ m_vid_dma_param1[offset] = data;
+}
+
+WRITE8_MEMBER(xavix_state::vid_dma_params_2_w)
+{
+ m_vid_dma_param2[offset] = data;
+}
+
+WRITE8_MEMBER(xavix_state::vid_dma_trigger_w)
+{
+ uint16_t len = data & 0x07;
+ uint16_t src = (m_vid_dma_param1[1]<<8) | m_vid_dma_param1[0];
+ uint16_t dst = (m_vid_dma_param2[0]<<8);
+ dst += 0x6000;
+
+ uint8_t unk = m_vid_dma_param2[1];
+
+ logerror("%s: vid_dma_trigger_w with trg %02x size %04x src %04x dest %04x unk (%02x)\n", machine().describe_context(), data & 0xf8, len,src,dst,unk);
+
+ if (unk)
+ {
+ fatalerror("m_vid_dma_param2[1] != 0x00 (is %02x)\n", m_vid_dma_param2[1]);
+ }
+
+ if (len == 0x00)
+ {
+ len = 0x08;
+ logerror(" (length was 0x0, assuming 0x8)\n");
+ }
+
+ len = len << 8;
+
+ address_space& dmaspace = m_maincpu->space(AS_PROGRAM);
+
+ if (data & 0x40)
+ {
+ for (int i = 0; i < len; i++)
+ {
+ uint8_t dat = dmaspace.read_byte(src + i);
+ dmaspace.write_byte(dst + i, dat);
+ }
+ }
+}
+
+READ8_MEMBER(xavix_state::vid_dma_trigger_r)
+{
+ // expects bit 0x40 to clear in most cases
+ return 0x00;
+}
+
+READ8_MEMBER(xavix_state::pal_ntsc_r)
+{
+ // only seen 0x10 checked in code
+ // in monster truck the tile base address gets set based on this, there are 2 copies of the test screen in rom, one for pal, one for ntsc, see 1854c
+ // likewise card night has entirely different tilesets for each region title
+ return m_region->read();
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6fc0_w) // also related to tilemap 1?
+{
+ logerror("%s: xavix_6fc0_w data %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::tmap1_regs_w)
+{
+ /*
+ 0x0 pointer to address where tile data is
+ it gets set to 0x40 in monster truck test mode, which is outside of ram but test mode requires a fixed 'column scan' layout
+ so that might be special
+
+ 0x1 pointer to middle tile bits (if needed, depends on mode) (usually straight after the ram needed for above)
+
+ 0x2 pointer to tile highest tile bits (if needed, depends on mode) (usually straight after the ram needed for above)
+
+ 0x3 --tt bbb- - = ? tt = tile/tilemap size b = bpp (0x36 xavix logo, 0x3c title screen, 0x36 course select)
+
+ 0x4 and 0x5 are scroll
+
+ 0x6 pppp ---- p = palette - = ? (0x02 xavix logo, 0x01 course select)
+
+ 0x7 could be mode (16x16, 8x8 etc.)
+ 0x00 is disabled?
+ 0x80 means 16x16 tiles
+ 0x81 might be 8x8 tiles
+ 0x93 course / mode select bg / ingame (weird addressing?)
+
+
+ */
+
+ /*
+ 6aff base registers
+ -- ingame
+
+ ae 80
+ 02 80
+ 02 90
+ 02 a0
+ 02 b0
+ 02 c0
+ 02 d0
+ 02 e0
+
+ 02 00
+ 04 80
+ 04 90
+ 04 a0
+ 04 b0
+ 04 c0
+ 04 d0
+ 04 e0
+
+ -- menu
+ af 80
+ 27 80
+ 27 90
+ 27 a0
+ 27 b0
+ 27 c0
+ 27 d0
+ 27 e0
+
+ 27 00
+ 00 80
+ 00 90
+ 00 a0
+ 00 b0
+ 00 c0
+ 00 d0
+ 00 e0
+ */
+
+
+ if ((offset != 0x4) && (offset != 0x5))
+ {
+ logerror("%s: tmap1_regs_w offset %02x data %02x\n", machine().describe_context(), offset, data);
+ }
+
+ COMBINE_DATA(&m_tmap1_regs[offset]);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6fd8_w) // also related to tilemap 2?
+{
+ // possibly just a mirror of tmap2_regs_w, at least it writes 0x04 here which would be the correct
+ // base address to otherwise write at tmap2_regs_w offset 0
+// tmap2_regs_w(space,offset,data);
+
+ logerror("%s: xavix_6fd8_w data %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::tmap2_regs_w)
+{
+ // same as above but for 2nd tilemap
+ if ((offset != 0x4) && (offset != 0x5))
+ {
+ //logerror("%s: tmap2_regs_w offset %02x data %02x\n", machine().describe_context(), offset, data);
+ }
+
+ COMBINE_DATA(&m_tmap2_regs[offset]);
+}
+
+READ8_MEMBER(xavix_state::tmap2_regs_r)
+{
+ // does this return the same data or a status?
+
+ logerror("%s: tmap2_regs_r offset %02x\n", offset, machine().describe_context());
+ return m_tmap2_regs[offset];
+}
+
+READ8_MEMBER(xavix_state::xavix_4000_r)
+{
+ if (offset < 0x100)
+ {
+ return ((offset>>4) | (offset<<4));
+ }
+ else
+ {
+ return 0x00;
+ }
+}
+