mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
584 lines
10 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|
|
|