mirror of
https://github.com/holub/mame
synced 2025-07-01 00:09:18 +03:00
(MESS) cat.c: Implemented watchdog counter readback, more documentation [Lord Nightmare]
This commit is contained in:
parent
4d411b439f
commit
f9372ec51c
@ -281,14 +281,11 @@ ToDo:
|
||||
data, though track 0 is just a disk "unique" identifier for the cat
|
||||
meaning 404480 usable bytes
|
||||
* (Once the floppy is working I'd declare the system working)
|
||||
- Beeper/speaker; this is connected to the DUART 'user output' pin OP3 and
|
||||
probably depends on an accurate implementation of the duart counters/timers
|
||||
- Centronics port
|
||||
- WIP: Centronics port (need to hook up prn_ack_ff and correctly invert centronics busy
|
||||
- RS232C port and Modem "port" connected to the DUART's two ports
|
||||
- DTMF generator chip (connected to DUART 'user output' pins OP4,5,6,7)
|
||||
- Correctly hook the duart interrupt to the 68k, including autovector using
|
||||
the vector register on the duart; this is currently hacked around.
|
||||
- Watchdog timer/powerfail at 0x85xxxx
|
||||
- WIP: Watchdog timer/powerfail at 0x85xxxx (watchdog NMI needs to actually
|
||||
fire if wdt goes above a certain number, possibly 3, 7 or F?)
|
||||
- Canon Cat released versions known: 1.74 US (dumped), 2.40 US (dumped both
|
||||
original compile, and Dwight's recompile from the released source code),
|
||||
2.42 (NEED DUMP)
|
||||
@ -308,6 +305,7 @@ ToDo:
|
||||
happens inside an asic) for the SVROMS (or the svram or the code roms, for
|
||||
that matter!)
|
||||
- Hook Battery Low input to a dipswitch.
|
||||
- Hook pfail to a dipswitch?
|
||||
- Hook the floppy control register readback up properly, things seem to get
|
||||
confused.
|
||||
|
||||
@ -340,8 +338,8 @@ ToDo:
|
||||
#undef DEBUG_FLOPPY_DATA_R
|
||||
#undef DEBUG_FLOPPY_STATUS_R
|
||||
|
||||
#define DEBUG_PRINTER_DATA_W 1
|
||||
#define DEBUG_PRINTER_CONTROL_W 1
|
||||
#undef DEBUG_PRINTER_DATA_W
|
||||
#undef DEBUG_PRINTER_CONTROL_W
|
||||
|
||||
#undef DEBUG_MODEM_R
|
||||
#undef DEBUG_MODEM_W
|
||||
@ -457,6 +455,7 @@ public:
|
||||
DECLARE_WRITE16_MEMBER(cat_modem_w);
|
||||
DECLARE_READ16_MEMBER(cat_6ms_counter_r);
|
||||
DECLARE_WRITE16_MEMBER(cat_opr_w);
|
||||
DECLARE_READ16_MEMBER(cat_wdt_r);
|
||||
DECLARE_WRITE16_MEMBER(cat_tcb_w);
|
||||
DECLARE_READ16_MEMBER(cat_2e80_r);
|
||||
DECLARE_READ16_MEMBER(cat_0080_r);
|
||||
@ -488,16 +487,30 @@ public:
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(write_acia_clock);
|
||||
|
||||
UINT8 m_duart_inp;
|
||||
/* gate array 2 has a 16-bit counter inside which counts at 10mhz and
|
||||
rolls over at FFFF->0000; on roll-over (or maybe at FFFF terminal count)
|
||||
it triggers the KTDBF output. It does this every 6.5535ms, which causes
|
||||
a 74LS74 d-latch at IC100 to switch the state of the DUART IP2 line;
|
||||
rolls over at FFFF->0000; on roll-over (or likely at FFFF terminal count)
|
||||
it triggers the KTOBF output. It does this every 6.5535ms, which causes
|
||||
a 74LS74 d-latch at IC100 to invert the state of the DUART IP2 line;
|
||||
this causes the DUART to fire an interrupt, which makes the 68000 read
|
||||
the keyboard.
|
||||
The watchdog counter and the 6ms counter are both incremented
|
||||
every time the KTOBF pulses.
|
||||
*/
|
||||
UINT8 m_duart_irq_state;
|
||||
UINT16 m_6ms_counter;
|
||||
UINT8 m_wdt_counter;
|
||||
UINT8 m_duart_ktobf_ff;
|
||||
/* the /ACK line from the centronics printer port goes through a similar
|
||||
flipflop to the ktobf line as well, so duart IP4 inverts on /ACK rising edge
|
||||
*/
|
||||
UINT8 m_duart_prn_ack_ff;
|
||||
/* Gate array 2 is in charge of serializing the video for display to the screen;
|
||||
Gate array 1 is in charge of vblank/hblank timing, and in charge of refreshing
|
||||
dram and indicating to GA2, using the /LDPS signal, what times the address it is
|
||||
writing to ram it is intending to be used by GA2 to read 16 bits of data to be
|
||||
shifted out to the screen. (it is obviously not active during hblank and vblank)
|
||||
GA2 then takes: ((output_bit XNOR video_invert) AND video enable), and serially
|
||||
bangs the result to the analog display circuitry.
|
||||
*/
|
||||
UINT8 m_video_enable;
|
||||
UINT8 m_video_invert;
|
||||
UINT16 m_pr_cont;
|
||||
@ -682,10 +695,12 @@ READ16_MEMBER( cat_state::cat_keyboard_r )
|
||||
case 0x80: retVal = m_y7->read() << 8; break;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if ((m_pr_cont != 0x0800) && (m_pr_cont != 0x0900) && (m_pr_cont != 0x0a00))
|
||||
{
|
||||
fprintf(stderr,"Read from keyboard in %06X with unexpected pr_cont %04X\n", 0x80000a+(offset<<1), m_pr_cont);
|
||||
}
|
||||
#endif
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -749,41 +764,67 @@ WRITE16_MEMBER( cat_state::cat_modem_w )
|
||||
#endif
|
||||
}
|
||||
|
||||
// 0x830000: 6ms counter (used for KTDBF)
|
||||
// 0x830000: 6ms counter (counts KTOBF pulses and does not reset; 16 bits wide)
|
||||
READ16_MEMBER( cat_state::cat_6ms_counter_r )
|
||||
{
|
||||
return m_6ms_counter;
|
||||
}
|
||||
|
||||
/* 0x840001: 'opr' or 'ga2opr' Output Port Register
|
||||
* writing 0x1c (or probably anything with bit 3 set) here resets the watchdog
|
||||
* if the watchdog expires an NMI is sent to the cpu
|
||||
/* 0x840001: 'opr' or 'ga2opr' Output Port Register (within GA2)
|
||||
* writing anything with bit 3 set here resets the watchdog
|
||||
* if the watchdog expires /NMI (and maybe /RESET) are asserted to the cpu
|
||||
* watchdog counter (counts KTOBF pulses and is reset on any ga2opr write with bit 3 set; <9 bits wide)
|
||||
*/
|
||||
WRITE16_MEMBER( cat_state::cat_opr_w )
|
||||
{
|
||||
/*
|
||||
* 76543210 (FEDCBA98 are ignored)
|
||||
* |||||||\-- ?
|
||||
* ||||||\--- ?
|
||||
* |||||||\-- OFFHOOK pin (pin 3) output control (1 = puts phone off hook by energizing relay K2)
|
||||
* ||||||\--- PHONE pin (pin 4) output control (1 = connects phone and line together by energizing relay K1)
|
||||
* |||||\---- Video enable (1 = video on, 0 = video off/screen black)
|
||||
* ||||\----- Watchdog reset?
|
||||
* ||||\----- Watchdog reset (the watchdog is reset whenever this bit is written with a 1)
|
||||
* |||\------ Video invert (1 = black-on-white video; 0 = white-on-black)
|
||||
* ||\------- ?
|
||||
* |\-------- ?
|
||||
* \--------- ?
|
||||
* ||\------- (unused?)
|
||||
* |\-------- (unused?)
|
||||
* \--------- (unused?)
|
||||
*/
|
||||
#ifdef DEBUG_VIDEO_ENABLE_W
|
||||
fprintf(stderr, "Video enable reg write: offset %06X, data %04X\n", 0x840000+(offset<<1), data);
|
||||
#ifdef DEBUG_GA2OPR_W
|
||||
fprintf(stderr, "GA2 OPR (video ena/inv, watchdog, and phone relay) reg write: offset %06X, data %04X\n", 0x840000+(offset<<1), data);
|
||||
#endif
|
||||
if (data&0x08) m_wdt_counter = 0;
|
||||
m_video_enable = BIT( data, 2 );
|
||||
m_video_invert = 1-BIT( data, 4 );
|
||||
}
|
||||
|
||||
// 0x850000: 'wdt' watchdog timer/video status
|
||||
// implement me!
|
||||
// 0x850000: 'wdt' "watchdog timer and power fail", read only?
|
||||
/* NOTE: BELOW IS A GUESS based on seeing what the register reads as,
|
||||
* the cat code barely touches this stuff at all, despite the fact
|
||||
* that the service manual states that PFAIL is supposed to be checked
|
||||
* before each write to SVRAM, the forth code does NOT actually do that!
|
||||
*
|
||||
* 76543210
|
||||
* ??????\\-- Watchdog count? (counts upward? if this reaches <some unknown number greater than 2> the watchdog fires? writing bit 3 set to opr above resets this)
|
||||
*
|
||||
* FEDCBA98
|
||||
* |||||||\-- PFAIL state (1 = 5v detector near svram says power ok for saving; 0 = 5v detector shows power fail or unstable, hence do not write to svram!)
|
||||
* ||||||\--- (always 0?)
|
||||
* |||||\---- (always 0?)
|
||||
* ||||\----- (always 0?)
|
||||
* |||\------ (always 0?)
|
||||
* ||\------- (always 0?)
|
||||
* |\-------- (always 0?)
|
||||
* \--------- (always 0?)
|
||||
*/
|
||||
READ16_MEMBER( cat_state::cat_wdt_r )
|
||||
{
|
||||
uint16 Retval = 0x0100; // set pfail to 1; should this be a dipswitch?
|
||||
return Retval | m_wdt_counter;
|
||||
}
|
||||
|
||||
// 0x860000: 'tcb' test regitser
|
||||
// the power fail status reset bit also lives here somewhere?
|
||||
// 0x860000: 'tcb' "test control bits" test mode register; what the bits do is
|
||||
// unknown. 0x0000 is written here to disable test mode, and that is the extent
|
||||
// of the cat touching this register.
|
||||
// it is possible that writing ANYTHING here will set the PFAIL state from 0 to 1, assuming the guessed information about pfail above is correct.
|
||||
WRITE16_MEMBER( cat_state::cat_tcb_w )
|
||||
{
|
||||
#ifdef DEBUG_TEST_W
|
||||
@ -843,7 +884,7 @@ a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4
|
||||
1 0 0 x x 0 1 1 x x x x x x x x x x x x x x x * R {'timer'} Read: Fixed 16-bit counter from ga2. increments every 6.5535ms when another 16-bit counter clocked at 10mhz overflows
|
||||
1 0 0 x x 1 0 0 x x x x x x x x x x x x x x x * W {'opr'} Output Port (Video/Sync enable and watchdog reset?) register (screen enable on bit 3?) (reads as 0x2e80)
|
||||
1 0 0 x x 1 0 1 x x x x x x x x x x x x x x x * R {'wdt'} Watchdog timer reads as 0x0100 0x0101 or 0x0102, some sort of test register or video status register?
|
||||
1 0 0 x x 1 1 0 x x x x x x x x x x x x x x x * R?W {'tcb'} test control bits: powerfail status in bit <?> (reads as 0x0000)
|
||||
1 0 0 x x 1 1 0 x x x x x x x x x x x x x x x * R?W {'tcb'} test control bits (reads as 0x0000)
|
||||
1 0 0 x x 1 1 1 x x x x x x x x x x x x x x x * ? Unknown (reads as 0x2e80)
|
||||
|
||||
1 0 1 x x x x x x x x x x x x x x x x x x x x x O OPEN BUS (reads as 0x2e80) [68k DTACK is asserted by gate array 1 when accessing this area, for testing?] On real IAI shadow rom board, at least 0x40000 of ram lives here.
|
||||
@ -871,7 +912,7 @@ static ADDRESS_MAP_START(cat_mem, AS_PROGRAM, 16, cat_state)
|
||||
AM_RANGE(0x820000, 0x82003f) AM_READWRITE(cat_modem_r,cat_modem_w) AM_MIRROR(0x18FFC0) // AMI S35213 Modem Chip, all access is on bit 7
|
||||
AM_RANGE(0x830000, 0x830001) AM_READ(cat_6ms_counter_r) AM_MIRROR(0x18FFFE) // 16bit 6ms counter clocked by output of another 16bit counter clocked at 10mhz
|
||||
AM_RANGE(0x840000, 0x840001) AM_READWRITE(cat_2e80_r,cat_opr_w) AM_MIRROR(0x18FFFE) // GA2 Output port register (video enable, invert, watchdog reset, phone relays)
|
||||
//AM_RANGE(0x850000, 0x850001) AM_READ(cat_wdt_r) AM_MIRROR(0x18FFFE) // watchdog and power fail state read
|
||||
AM_RANGE(0x850000, 0x850001) AM_READ(cat_wdt_r) AM_MIRROR(0x18FFFE) // watchdog and power fail state read
|
||||
AM_RANGE(0x860000, 0x860001) AM_READWRITE(cat_0000_r, cat_tcb_w) AM_MIRROR(0x18FFFE) // Test mode
|
||||
AM_RANGE(0x870000, 0x870001) AM_READ(cat_2e80_r) AM_MIRROR(0x18FFFE) // Open bus?
|
||||
AM_RANGE(0xA00000, 0xA00001) AM_READ(cat_2e80_r) AM_MIRROR(0x1FFFFE) // Open bus/dtack? The 0xA00000-0xA3ffff area is ram used for shadow rom storage on cat developer machines, which is either banked over top of, or jumped to instead of the normal rom
|
||||
@ -1005,11 +1046,11 @@ void cat_state::device_timer(emu_timer &timer, device_timer_id id, int param, vo
|
||||
|
||||
TIMER_CALLBACK_MEMBER(cat_state::counter_6ms_callback)
|
||||
{
|
||||
// This is effectively also the KTDBF line 'clock' output to the d-latch before the duart
|
||||
// Hence, invert the d-latch on the duart's input ports.
|
||||
// n68681 now properly generates interrupts when this bit changes, the previous hack is no longer necessary.
|
||||
m_duart_inp ^= 0x04;
|
||||
m_duart->ip2_w((m_duart_inp>>2)&1);
|
||||
// This is effectively also the KTOBF (guessed: acronym for "Keyboard Timer Out Bit Flip")
|
||||
// line connected in such a way to invert the d-flipflop connected to the duart IP2
|
||||
m_duart_ktobf_ff ^= 1;
|
||||
m_duart->ip2_w(m_duart_ktobf_ff);
|
||||
m_wdt_counter++;
|
||||
m_6ms_counter++;
|
||||
}
|
||||
|
||||
@ -1021,9 +1062,10 @@ IRQ_CALLBACK_MEMBER(cat_state::cat_int_ack)
|
||||
|
||||
MACHINE_START_MEMBER(cat_state,cat)
|
||||
{
|
||||
m_duart_inp = 0;
|
||||
m_duart_irq_state = 0;
|
||||
m_duart_ktobf_ff = 0;
|
||||
m_duart_prn_ack_ff = 0;
|
||||
m_6ms_counter = 0;
|
||||
m_wdt_counter = 0;
|
||||
m_video_enable = 1;
|
||||
m_video_invert = 0;
|
||||
m_6ms_timer = timer_alloc(TIMER_COUNTER_6MS);
|
||||
@ -1033,9 +1075,10 @@ MACHINE_START_MEMBER(cat_state,cat)
|
||||
MACHINE_RESET_MEMBER(cat_state,cat)
|
||||
{
|
||||
m_maincpu->set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(cat_state::cat_int_ack),this));
|
||||
m_duart_inp = 0;
|
||||
m_duart_irq_state = 0;
|
||||
m_duart_ktobf_ff = 0;
|
||||
m_duart_prn_ack_ff = 0;
|
||||
m_6ms_counter = 0;
|
||||
m_wdt_counter = 0;
|
||||
m_floppy_control = 0;
|
||||
m_6ms_timer->adjust(attotime::zero, 0, attotime::from_hz((XTAL_19_968MHz/2)/65536));
|
||||
}
|
||||
@ -1072,7 +1115,7 @@ UINT32 cat_state::screen_update_cat(screen_device &screen, bitmap_ind16 &bitmap,
|
||||
}
|
||||
|
||||
/* The duart is the only thing actually connected to the cpu IRQ pin
|
||||
* The KTDBF output of the gate array 2 (itself the terminal count output
|
||||
* The KTOBF output of the gate array 2 (itself the terminal count output
|
||||
* of a 16-bit counter clocked at ~10mhz, hence 6.5536ms period) goes to a
|
||||
* d-latch and inputs on ip2 of the duart, causing the duart to fire an irq;
|
||||
* this is used by the cat to read the keyboard.
|
||||
@ -1084,7 +1127,6 @@ WRITE_LINE_MEMBER(cat_state::cat_duart_irq_handler)
|
||||
#ifdef DEBUG_DUART_IRQ_HANDLER
|
||||
fprintf(stderr, "Duart IRQ handler called: state: %02X, vector: %06X\n", state, irqvector);
|
||||
#endif
|
||||
m_duart_irq_state = state;
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_1, state, irqvector);
|
||||
}
|
||||
|
||||
@ -1098,7 +1140,7 @@ WRITE_LINE_MEMBER(cat_state::cat_duart_txa)
|
||||
/* mc68681 DUART Input pins:
|
||||
* IP0: CTS [using the DUART builtin hardware-CTS feature?]
|
||||
* IP1: Centronics /ACK (pin 10) positive edge detect (IP1 changes state 0->1 or 1->0 on the rising edge of /ACK using a 74ls74a d-flipflop)
|
||||
* IP2: KTDBF (IP2 changes state 0->1 or 1->0 on the rising edge of KTDBF using a 74ls74a d-flipflop; KTDBF is a 6.5536ms-period squarewave generated by one of the gate arrays, I need to check with a scope to see whether it is a single spike/pulse every 6.5536ms or if from the gate array it inverts every 6.5536ms, documentation isn't 100% clear but I suspect the former) [uses the Delta IP2 state change detection feature to generate an interrupt; I'm not sure if IP2 is used as a counter clock source but given the beep frequency of the real unit I very much doubt it, 6.5536ms is too slow]
|
||||
* IP2: KTOBF (IP2 changes state 0->1 or 1->0 on the rising edge of KTOBF using a 74ls74a d-flipflop; KTOBF is a 6.5536ms-period squarewave generated by one of the gate arrays, I need to check with a scope to see whether it is a single spike/pulse every 6.5536ms or if from the gate array it inverts every 6.5536ms, documentation isn't 100% clear but I suspect the former) [uses the Delta IP2 state change detection feature to generate an interrupt; I'm not sure if IP2 is used as a counter clock source but given the beep frequency of the real unit I very much doubt it, 6.5536ms is too slow]
|
||||
* IP3: RG ("ring" input)
|
||||
* IP4: Centronics BUSY (pin 11), inverted
|
||||
* IP5: DSR
|
||||
|
Loading…
Reference in New Issue
Block a user