// license:BSD-3-Clause // copyright-holders:Wilbert Pol,Gabriele D'Antona /* RM 380Z video code */ #include "emu.h" #include "includes/rm380z.h" void rm380z_state::put_point(int charnum,int x,int y,int col) { int mx=3; if (y==6) mx=4; for (unsigned int r=y;r<(y+mx);r++) { for (unsigned int c=x;c<(x+3);c++) { m_graphic_chars[charnum][c+(r*(RM380Z_CHDIMX+1))]=col; } } } void rm380z_state::init_graphic_chars() { for (int c=0;c<0x3f;c++) { if (c&0x01) put_point(c,0,0,1); else put_point(c,0,0,0); if (c&0x02) put_point(c,3,0,1); else put_point(c,3,0,0); if (c&0x04) put_point(c,0,3,1); else put_point(c,0,3,0); if (c&0x08) put_point(c,3,3,1); else put_point(c,3,3,0); if (c&0x10) put_point(c,0,6,1); else put_point(c,0,6,0); if (c&0x20) put_point(c,3,6,1); else put_point(c,3,6,0); } } void rm380z_state::config_videomode() { if (m_port0&0x20&m_port0_mask) { // 80 cols m_videomode=RM380Z_VIDEOMODE_80COL; } else { // 40 cols m_videomode=RM380Z_VIDEOMODE_40COL; } if (m_old_videomode!=m_videomode) { m_old_videomode=m_videomode; } } // char attribute bits in COS 4.0 // 0=alternate charset // 1=underline // 2=dim // 3=reverse void rm380z_state::decode_videoram_char(int pos,uint8_t& chr,uint8_t& attrib) { uint8_t ch1=m_vramchars[pos]; uint8_t ch2=m_vramattribs[pos]; // "special" (unknown) cases first if ((ch1==0x80)&&(ch2==0x04)) { // blank out chr=0x20; attrib=0; return; } else if ((ch1==0)&&(ch2==8)) { // cursor chr=0x20; attrib=8; return; } else if ((ch1==0)&&(ch2==0)) { // delete char (?) chr=0x20; attrib=0; return; } else if ((ch1==4)&&(ch2==4)) { // reversed cursor? chr=0x20; attrib=0; return; } else if ((ch1==4)&&(ch2==8)) { // normal cursor chr=0x20; attrib=8; return; } else { chr=ch1; attrib=ch2; //printf("unhandled character combination [%x][%x]\n",ch1,ch2); } } void rm380z_state::scroll_videoram() { int lineWidth=0x80; if (m_videomode==RM380Z_VIDEOMODE_40COL) { lineWidth=0x40; } // scroll up one row of videoram for (int row=1;rowr[1]) { scroll_videoram(); } else if ((r[2]==0x00)&&(r[1]==0x17)) { // wrap-scroll scroll_videoram(); } } } // after ctrl-L (clear screen?): routine at EBBD is executed // EB30??? next line? // memory at FF02 seems to hold the line counter (same as FBFD) // // basics: // 20e2: prints "Ready:" // 0195: prints "\n" WRITE8_MEMBER( rm380z_state::videoram_write ) { //printf("%s vramw [%2.2x][%2.2x] port0 [%2.2x] fbfd [%2.2x] fbfe [%2.2x]\n",machine().describe_context().c_str(),offset,data,m_port0,m_fbfd,m_fbfe); int lineWidth=0x80; if (m_videomode==RM380Z_VIDEOMODE_40COL) { lineWidth=0x40; } int rowadder=(m_fbfe&0x0f)*2; if (m_videomode==RM380Z_VIDEOMODE_40COL) rowadder=0; // FBFE register is not used in VDU-40 int lineAdder=rowadder*lineWidth; int realA=(offset+lineAdder); // we suppose videoram is being written as character/attribute couple // fbfc 6th bit set=attribute, unset=char if (!(m_port0&0x40)) { m_vramchars[realA%RM380Z_SCREENSIZE]=data; } else { m_vramattribs[realA%RM380Z_SCREENSIZE]=data; } // m_mainVideoram[offset]=data; } READ8_MEMBER( rm380z_state::videoram_read ) { return m_mainVideoram[offset]; } void rm380z_state::putChar(int charnum,int attribs,int x,int y,bitmap_ind16 &bitmap,unsigned char* chsb,int vmode) { //bool attrDim=false; bool attrRev=false; bool attrUnder=false; if (attribs&0x02) attrUnder=true; //if (attribs&0x04) attrDim=true; if (attribs&0x08) attrRev=true; if ((charnum>0)&&(charnum<=0x7f)) { // normal chars (base set) if (vmode==RM380Z_VIDEOMODE_80COL) { int basex=RM380Z_CHDIMX*(charnum/RM380Z_NCY); int basey=RM380Z_CHDIMY*(charnum%RM380Z_NCY); for (int r=0;rbase(); int lineWidth=0x80; int ncols=80; if (m_videomode==RM380Z_VIDEOMODE_40COL) { lineWidth=0x40; ncols=40; } // blank screen bitmap.fill(0); for (int row=0;rowbase(); uint8_t y,ra,chr,gfx; uint16_t sy=0,ma=0,x; for (y = 0; y < RM380Z_SCREENROWS; y++) { for (ra = 0; ra < 11; ra++) { uint16_t *p = &bitmap.pix16(sy++); for (x = ma; x < ma + 64; x++) { gfx = 0; if (ra < 10) { chr = m_vramchars[x]; gfx = chargen[(chr<<4) | ra ]; } /* Display a scanline of a character */ *p++ = BIT(gfx, 7); *p++ = BIT(gfx, 6); *p++ = BIT(gfx, 5); *p++ = BIT(gfx, 4); *p++ = BIT(gfx, 3); *p++ = BIT(gfx, 2); *p++ = BIT(gfx, 1); *p++ = BIT(gfx, 0); } } ma+=64; } return 0; }