/* RM 380Z video code */ #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 (int r=y;r<(y+mx);r++) { for (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) { // 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& chr,UINT8& attrib) { UINT8 ch1=m_vramchars[pos]; UINT8 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() { rm380z_state *state = machine().driver_data(); int lineWidth=0x80; if (m_videomode==RM380Z_VIDEOMODE_40COL) { lineWidth=0x40; } // scroll up one row of videoram for (int row=1;rowm_vram[destaddr]=state->m_vram[sourceaddr]; state->m_vramchars[destaddr]=state->m_vramchars[sourceaddr]; state->m_vramattribs[destaddr]=state->m_vramattribs[sourceaddr]; } } // the last line is filled with spaces for (int c=0;cm_vram[((RM380Z_SCREENROWS-1)*lineWidth)+c]=0x20; state->m_vramchars[((RM380Z_SCREENROWS-1)*lineWidth)+c]=0x20; state->m_vramattribs[((RM380Z_SCREENROWS-1)*lineWidth)+c]=0x00; } } void rm380z_state::check_scroll_register() { UINT8 r[3]; r[0]=m_old_old_fbfd; r[1]=m_old_fbfd; r[2]=m_fbfd; if ( ((r[1]&0x20)==0) && ((r[2]&0x20)==0) ) { // it's a scroll command if (r[2]>r[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 ) { rm380z_state *state = machine().driver_data(); //printf("vramw [%2.2x][%2.2x] port0 [%2.2x] fbfd [%2.2x] fbfe [%2.2x] PC [%4.4x]\n",offset,data,state->m_port0,m_fbfd,m_fbfe,machine().device("maincpu")->safe_pc()); 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 (!(state->m_port0&0x40)) { m_vramchars[realA%RM380Z_SCREENSIZE]=data; } else { m_vramattribs[realA%RM380Z_SCREENSIZE]=data; } // state->m_mainVideoram[offset]=data; } READ8_MEMBER( rm380z_state::videoram_read ) { rm380z_state *state = machine().driver_data(); return state->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;row