nulldc-360/plugins/nullExtDev/modem.cpp

584 lines
10 KiB
C++

/*
This is just wasting space on your hard drive
Nothing really emulated
*/
#include "modem.h"
#pragma pack(1)
union modemreg_t
{
u8 ptr[0x21];
struct
{
//00 Receive Data Buffer (RBUFFER)/Voice Receive Data Buffer (VBUFR)
u8 reg00;
//01 VOLUME VPAUSE - - TXHF RXHF RXP
struct
{
u8 RXP:1;
u8 RXHF:1;
u8 TXHF:1;
u8 nil2:2;
u8 VPAUSE:1;
u8 VOLUME:2;
} reg01;
//02 TDE SQDIS S511 - RTSDE V54TE V54AE V54PE
// DCDEN CDEN - - CODBITS
struct
{
union
{
struct
{
u8 V54PE:1;
u8 V54AE:1;
u8 V54TE:1;
u8 RTSDE:1;
u8 nil1:1;
u8 S511:1;
} v0;
struct
{
u8 CODBITS:2;
u8 nil2:2;
u8 CDEN:1;
u8 DCDEN:1;
} v1;
struct
{
u8 nila:6;
u8 TDE:1;
u8 SQDIS:1;
};
};
} reg02;
//03 EPT SEPT SRCEN RLSDE - - GTE GTS
struct
{
u8 GTS:1;
u8 GTE:1;
u8 nil2:2;
u8 RLSDE:1;
u8 SRCEN:1;
u8 SEPT:1;
u8 EPT:1;
} reg03;
//04 RB - - FIFOEN - NRZIEN/VAGC TOD STRN
struct
{
u8 STRN:1;
u8 TOD:1;
u8 NRZIEN_VAGC:1;
u8 nil1_1:1;
u8 FIFOEN:1;
u8 nil1:2;
u8 RB:1;
} reg04;
//05 - - - TXSQ CEQ - STOFF -
struct
{
u8 nil1_2:1;
u8 STOFF:1;
u8 nil1_1:1;
u8 CEQ:1;
u8 TXSQ:1;
u8 nil1:3;
} reg05;
//06 - EXOS - HDLC PEN STB WDSZ/DECBITS
struct
{
u8 WDSZ_DECBITS:2;
u8 STB:1;
u8 PEN:1;
u8 HDLC:1;
u8 nil1_1:1;
u8 EXOS:1;
u8 nil1:1;
} reg06;
//07 RDLE RDL L2ACT - L3ACT - RA MHLD
struct
{
u8 MHLD:1;
u8 RA:1;
u8 nil1_1:1;
u8 L3ACT:1;
u8 nil1:1;
u8 L2ACT:1;
u8 RDL:1;
u8 RDLE:1;
} reg07;
//08 ASYN TPDM V21S V54T V54A V54P RTRN RTS
struct
{
u8 RTS:1;
u8 RTRN:1;
u8 V54P:1;
u8 V54A:1;
u8 V54T:1;
u8 V21S:1;
u8 TPDM:1;
u8 ASYN:1;
} reg08;
//09 NV25 CC DTMF ORG LL DATA RRTSE DTR
struct
{
u8 DTR:1;
u8 RRTSE:1;
u8 DATA:1;
u8 LL:1;
u8 ORG:1;
u8 DTMF:1;
u8 CC:1;
u8 NV25:1;
} reg09;
//0A PNSUC FLAGDT PE FE OE CRCS FLAGS SYNCD
struct
{
u8 SYNCD:1;
u8 FLAGS:1;
u8 CRCS:1;
u8 OE:1;
u8 FE:1;
u8 PE:1;
u8 FLAGDT:1;
u8 PNSUC:1;
} reg0a;
//0B TONEA TONEB TONEC ATV25 ATBEL - DISDET EQMAT
struct
{
u8 EQMAT:1;
u8 DISDET:1;
u8 nil:1;
u8 ATBEL:1;
u8 ATV25:1;
u8 TONEC:1;
u8 TONEB:1;
u8 TONEA:1;
} reg0b;
//0C AADET ACDET CADET CCDET SDET SNDET RXFNE RSEQ
struct
{
u8 RSEQ:1;
u8 RXFNE:1;
u8 SNDET:1;
u8 SDET:1;
u8 CCDET:1;
u8 CADET:1;
u8 ACDET:1;
u8 AADET:1;
} reg0c;
//0D P2DET PNDET S1DET SCR1 U1DET - TXFNF -
struct
{
u8 nil2:1;
u8 TXFNF:1;
u8 nil1:1;
u8 U1DET:1;
u8 SCR1:1;
u8 S1DET:1;
u8 PNDET:1;
u8 P2DET:1;
} reg0d;
//0E RTDET BRKD RREDT SPEED
struct
{
u8 SPEED:5;
u8 RREDT:1;
u8 BRKD:1;
u8 RTDET:1;
} reg0e;
//0F RLSD FED CTS DSR RI TM RTSDT V54DT
struct
{
u8 V54DT:1;
u8 RTSDT:1;
u8 TM:1;
u8 RI:1;
u8 DSR:1;
u8 CTS:1;
u8 FED:1;
u8 RLSD:1;
} reg0f;
//10 Transmit Data Buffer (TBUFFER)/Voice Transmit Buffer (VBUFT)
u8 reg10;
//11 BRKS PARSL TXV RXV V23HDX TEOF TXP
struct
{
u8 TXP:1;
u8 TEOF:1;
u8 V23HDX:1;
u8 RXV:1;
u8 TXV:1;
u8 PARSL:2;
u8 BRKS:1;
} reg11;
//12 Configuration (CONF)
u8 reg12;
//13 TLVL RTH TXCLK
struct
{
u8 TLVL:4;
u8 RTH:2;
u8 TXCLK:2;
} reg13;
//14 ABCODE
u8 reg14;
//15 SLEEP - RDWK HWRWK AUTO RREN EXL3 EARC
struct
{
u8 EARC:1;
u8 EXL3:1;
u8 RREN:1;
u8 AUTO:1;
u8 HWRWK:1;
u8 RDWK:1;
u8 nil:1;
u8 SLEEP:1;
} reg15;
//16 Secondary Receive Data Buffer/V.34 Receive Status (SECRXB)
u8 reg16;
//17 Secondary Transmit Data Buffer/V.34 Transmit Status(SECTXB)
u8 reg17;
//18 Memory Access Data LSB B7-B0 (MEDAL)
//19 Memory Access Data MSB B15-B8 (MEDAM)
u16 reg18_19;
//1A SFRES RIEN RION DMAE - SCOBF SCIBE SECEN
struct
{
u8 SECEN:1;
u8 SCIBE:1;
u8 SCOBF:1;
u8 nil:1;
u8 DMAE:1;
u8 RION:1;
u8 RIEN:1;
u8 SFRES:1;
} reg1a;
//1B EDET DTDET OTS DTMFD DTMFW
struct
{
u8 DTMFW:4;
u8 DTMFD:1;
u8 OTS:1;
u8 DTDET:1;
u8 EDET:1;
} reg1b;
//1C Memory Access Address Low B7-B0 (MEADDL)
//1D MEACC - MEMW MEMCR Memory Access Address High B11-B8 (MEADDH)
struct
{
u8 MEMADD_l:8; //anything else exept u8 breaks it ? WTFH ?
u8 MEMADD_h:4;
u8 MEMCR:1;
u8 MEMW:1;
u8 nil:1;
u8 MEACC:1;
} reg1c_1d;
//1E TDBIA RDBIA TDBIE - TDBE RDBIE - RDBF
struct
{
u8 RDBF:1;
u8 nil:1;
u8 RDBIE:1;
u8 TDBE:1;
u8 nil2:1;
u8 TDBIE:1;
u8 RDBIA:1;
u8 TDBIA:1;
} reg1e;
//1F NSIA NCIA - NSIE NEWS NCIE - NEWC
struct
{
u8 NEWC:1;
u8 nil:1;
u8 NCIE:1;
u8 NEWS :1;
u8 NSIE:1;
u8 nil2:1;
u8 NCIA:1;
u8 NSIA:1;
} reg1f;
};
};
#define MODEM_COUNTRY_RES 0
#define MODEM_COUNTRY_JAP 1
#define MODEM_COUNTRY_USA 2
#define MODEM_MAKER_SEGA 0
#define MODEM_MAKER_ROCKWELL 1
#define MODEM_DEVICE_TYPE_336K 0
u32 MODEM_ID[2] =
{
MODEM_COUNTRY_RES,
(MODEM_MAKER_ROCKWELL<<4) | (MODEM_DEVICE_TYPE_336K),
};
modemreg_t modem_regs;
enum ModemStates
{
MS_INVALID, //needs reset
MS_RESET, //reset is low
MS_RESETING, //reset is hi
MS_ST_CONTROLER, //Controller self test
MS_ST_DSP, //DSP self test
MS_NORMAL, //Normal operation
};
void SetBits(u32 reg,u32 v)
{
modem_regs.ptr[reg]|=v;
}
void ResetBits(u32 reg,u32 v)
{
modem_regs.ptr[reg]&=v;
}
void SetMask(u32 reg,u32 v,u32 m)
{
ResetBits(reg,m);
SetBits(reg,v);
}
ModemStates state=MS_INVALID;
void NormalDefaultRegs()
{
verify(state==MS_NORMAL);
//det default values for normal state
}
void DSPTestEnd()
{
verify(state==MS_ST_DSP);
state=MS_NORMAL;
printf("DSPTestEnd\n");
printf("Tests Ended -- starting normal operation\n");
NormalDefaultRegs();
}
void DSPTestStart()
{
verify(state==MS_ST_DSP);
state=MS_ST_DSP;
printf("DSPTestStart\n");
//Set valid DSP test values sometime
modem_regs.reg1e.TDBE=1;
SetUpdateCallback(DSPTestEnd,5);
}
void ControllerTestEnd()
{
verify(state==MS_ST_CONTROLER);
state=MS_ST_DSP;
warn(modem_regs.reg1e.TDBE==0);//This _has_ to be done
printf("ControllerTestEnd\n");
SetUpdateCallback(DSPTestStart,5);
}
#define SetReg16(rh,rl,v) {modem_regs.ptr[rh]=(v)>>8;modem_regs.ptr[rl]=(v)&0xFF; }
//End the reset and start internal tests
void ControllerTestStart()
{
verify(state==MS_RESETING);
//Set Self test values :)
state=MS_ST_CONTROLER;
//k, lets set values
//1E:3 -> set
modem_regs.reg1e.TDBE=1;
/*
RAM1 Checksum = 0xEA3C or 0x451
RAM2 Checksum = 0x5536 or 0x49A5
ROM1 Checksum = 0x5F4C
ROM2 Checksum = 0x3835 or 0x3836
Timer/ROM/RAM = 0x801 or 0xDE00
Part Number = 0x3730 or 0x3731
Revision Level = 0x4241
*/
SetReg16(0x1D,0x1C,0xEA3C);
SetReg16(0x1B,0x1A,0x5536);
SetReg16(0x19,0x18,0x5F4C);
SetReg16(0x17,0x16,0x3835);
SetReg16(0x15,0x14,0x801);
SetReg16(0x13,0x12,0x3730);
SetReg16(0x11,0x0,0x4241);
printf("ControllerTestStart\n");
SetUpdateCallback(ControllerTestEnd,5);
}
void modem_reset(u32 v)
{
if (v==0)
{
memset(&modem_regs,0,sizeof(modem_regs));
state=MS_RESET;
printf("Modem reset start ...\n");
}
else
{
memset(&modem_regs,0,sizeof(modem_regs));
state=MS_RESETING;
modem_regs.ptr[0x20]=1;
SetUpdateCallback(ControllerTestStart,10);
printf("Modem reset end ...\n");
}
}
void ModemNormalWrite(u32 reg,u32 data)
{
// u32 old=modem_regs.ptr[reg];
modem_regs.ptr[reg]=data;
switch(reg)
{
//Data Write Regs, for transfers to DSP
case 0x18:
case 0x19:
break;
//Address low
case 0x1C:
break;
case 0x1D:
if (modem_regs.reg1c_1d.MEACC)
{
modem_regs.reg1c_1d.MEACC=0;
printf("DSP write %0X=%0X\n",modem_regs.reg1c_1d.MEMADD_l || (modem_regs.reg1c_1d.MEMADD_h<<8),modem_regs.reg18_19 );
}
break;
case 0x1F:
if (modem_regs.reg1f.NEWC)
{
if(modem_regs.reg1a.SFRES)
{
printf("Soft Reset SET && NEWC, executing reset and init\n");
modem_reset(1);
}
else
{
modem_regs.reg1f.NEWC=0;//accept the settings anyway
printf("NEWC w/o Reset ?!\n");
}
}
break;
default:
printf("ModemNormalWrite : undef %03X=%X\n",reg,data);
}
}
void ModemCRSTWrite(u32 reg,u32 data)
{
switch(reg)
{
default:
printf("ModemCRSTWrite : undef %03X=%X\n",reg,data);
}
}
u32 FASTCALL ModemReadMem_A0_006(u32 addr ,u32 size)
{
u32 reg=addr&0x7FF;
verify((reg&3)==0);
reg>>=2;
if (reg<0x100)
{
verify(reg<=1);
return MODEM_ID[reg];
}
else
{
reg-=0x100;
if (reg<0x21)
{
if (state==MS_NORMAL)
{
//if (reg==0xF)
{
modem_regs.reg0f.CTS=1;
modem_regs.reg0b.ATBEL=1;
modem_regs.reg0b.TONEA=1;
modem_regs.reg0b.TONEB=1;
modem_regs.reg0b.TONEC=1;
modem_regs.reg0d.TXFNF=1;
modem_regs.reg0c.RXFNE=1;
}
return modem_regs.ptr[reg];
}
else if (state==MS_ST_CONTROLER || state==MS_ST_DSP)
{
if (reg==0x10)
{
modem_regs.reg1e.TDBE=0;
return 0;
}
else
{
//printf("modem reg %03X read -- reset/test state\n",reg);
return modem_regs.ptr[reg];
}
}
else if (state==MS_RESETING)
{
return 0; //still reset
}
else
{
printf("modem reg %03X read -- undef state %d\n",reg,state);
return 0xDEADC0DE;
}
}
else
{
printf("modem reg %03X read -- wtf is it ?\n",reg);
return 0;
}
}
}
void FASTCALL ModemWriteMem_A0_006(u32 addr,u32 data,u32 size)
{
u32 reg=addr&0x7FF;
verify((reg&3)==0);
reg>>=2;
if (reg<0x100)
{
verify(reg<=1);
printf("modem reg %03X write -- MODEM ID?!\n",reg);
}
else
{
reg-=0x100;
if (reg<0x20)
{
if (state==MS_NORMAL)
{
ModemNormalWrite(reg,data);
}
else
{
printf("modem reg %03X write %X -- undef state?\n",reg,data);
}
return;
}
else if (reg==0x20)
{
//Hard reset (?)
modem_reset(data);
}
else
{
printf("modem reg %03X write %X -- wtf is it?\n",reg,data);
return;
}
}
}