diff --git a/harness/mame/DUART_REPORT.md b/harness/mame/DUART_REPORT.md index 379a320..61dbfac 100644 --- a/harness/mame/DUART_REPORT.md +++ b/harness/mame/DUART_REPORT.md @@ -965,3 +965,95 @@ Two corrections: carries adjacent frame data as well as flags — so "return == 0" is stricter than "all checks pass" unless that word is zero. Worth confirming before treating `L3FA71BC0`'s return as a pure flag word. + +--- + +# LAST AUTHORISED TIMING CHANGE — tested, did not move the symptom, reverted + +## Mechanism quantified first (as required) + +Per-byte, same 5-byte burst, current tree (`hp_lat.log` / `hp_lat.out`). Character start += first transmitted bit (`VTCHSTART`); THRA write = `VT1200_DUARTLOG`: + +| byte | THRA write | char start | start latency | +|---|---|---|---| +| 0 | 44592939 | 44595544 | **2605** | +| 1 | 44598330 | 44613772 | **15442** | +| 2 | 44611350 | 44632002 | **20652** | +| 3 | 44629580 | 44650230 | **20650** | +| 4 | 44647808 | 44668460 | **20652** | + +So the transmit-start latency does **not accumulate**: it is 1 bit for the *idle* byte 0 +only, then constant (~1.13 char) because every later character is pinned by the *previous* +character's end (the buffered path). The owner's magnitude argument therefore predicted +the deviation could not be the cause, and this measurement confirms it. + +## The change, tested + +Implemented as authorised, contained to the idle path: `write_TX`'s idle branch calls +`transmit_register_setup(data, true)`, which schedules the first bit immediately instead of +at the next 1x tick (new `start_now` parameter in `emu/diserial.{h,cpp}`); the buffered +path and the whole receive side untouched. Citations recorded in the edit: SCN2681 +"The clock outputs from the BRG are at 16X the actual baud rate", the 1x/16x external clock +note, `CSRA` = receiver/transmitter clock select, and the receiver's "each 16X clock for +7-1/2 clocks" sampling note. + +Result (`hp_lat2.log`, `hp_lat2.out`): byte 0's start latency went 2605 -> **5** cycles, and +**nothing else changed** — bytes 1-4 stayed 15442/20652/20650/20652, the receive completions +moved with the writes, and the outcome was **identical**: + +``` +flag-set sites that fire: BC0/c6 x3, BC0/cE (summary) x1, RX/c0 x1, RX/c1 x1 (unchanged) +returns: L3FA71BC0 = 0x00900040, L3FA753D0 = 3, L3FA767E0 = 0, L3FA6E4B0 = 6 +console: 'LEVEL1/2 ERROR -> HOST PORT - 15' (unchanged) +``` + +## Decision: REVERTED (not kept) + +The deviation is real and datasheet-backed, but the change does **not** move the symptom, +and it is only a *partial* fidelity fix — a fully faithful model would clock the transmitter +at 16x (the real part), which is a much larger change, and the buffered path would still +quantise to a bit. Keeping a partial change that buys nothing adds noise to the tree, so it +is reverted; the deviation and its citations are recorded here instead. The MAME tree is +back to: **edit 2 (overrun latch) only**, plus the inline refutation note for edit 1. +`emu/diserial.{h,cpp}` are **unmodified**. + +# HANDOVER — full picture + +**Established.** +* Root cause of the original missing transmit: the DUART IRQ was unwired; wiring + DUART1 -> INT1 makes THRA get written (0 -> 20/run) and fixes the direct SRA/RHRA checks. +* The quantity to zero is `L3FA6E4B0`'s return, verified at the call site and at the + handler (`0x400` -> HOST PORT). +* Exactly **three** checks still fail, all reading the DUART ISR's own SRA snapshots + (writers confirmed by proxy: ISR TxRDYA path `3FA79E30`/`3FA7A3A0` for `+0x3c0`/`+0x3d0`, + ISR RxRDYA path `3FA79690` for `struct[i].0x60`): + - `L3FA71BC0` `c6` (`3FA73970`): the ISR's received status has SRA bit 5 = **PARITY + ERROR** in 3 combinations (`0x0021`), clean (`0x0001`) otherwise. + - `L3FA753D0` `c1`/`c0` (`3FA760E0`/`3FA76050`): the index4/index5 snapshots lack + **FFULL**/**OVR** — a receive-count lag at the snapshot boundary. +* The direct loopback **data** path is correct (RHRA compares pass; received bytes + `0x0A,0x1F,0x0A` as expected). + +**Ruled out.** external responder; FIFO depth (faithful); loopback-clock deviation as a +cause; the counter/COUNTER_READY lead; INT1-vs-INT2 and the OP interrupt outputs; frame +width; CSRA rate mismatch; and now the transmit-start latency (real, but non-accumulating +and provably not the cause). + +**Remaining discrepancy.** The ISR's SRA snapshots differ from the firmware's expectation +in two ways: a ~1-byte receive-count lag, and a parity error in 3 parity-enabled +combinations. Both are sub-bit phase/sampling artifacts, not data-path failures. + +**Open MAME deviations.** (1) transmit-start 16x quantisation — real, tested, not the cause; +(2) loopback receive clock (SCN2681 p.12 item 2) — real, phase-only, not the cause; +(3) `write_CR` bit1 clears `RxRDY` where the datasheet preserves FIFO status — minor; +(4) `COUNTER_READY` set at the Start-Counter read — not biting; (5) pre-existing `tms34010` +REFCNT local edit. + +**Acceptance:** `LEVEL1/2 ERROR -> HOST PORT - 15` — still present; no next gate. +**Regression:** holds (`PC=3FDCE400 samples=199`). + +**Suggested next step (not this gate).** The renderer is independent of this gate; the +remaining host-port discrepancy is a sub-bit phase artifact in the DUART ISR's SRA +snapshots and would need either a 16x-clock transmit model or a receive-phase rework to +chase further. diff --git a/harness/mame/hp_lat.log b/harness/mame/hp_lat.log new file mode 100644 index 0000000..5903378 --- /dev/null +++ b/harness/mame/hp_lat.log @@ -0,0 +1,443 @@ +# win kind reg val pc -- every DUART access (not de-duplicated) +1 W reg=D val=0000 pc=3F2000B0 cyc=7 +1 R reg=F val=00FF pc=3F200100 cyc=12 +1 W reg=F val=00FF pc=3F200100 cyc=12 +1 R reg=E val=00FF pc=3F200150 cyc=15 +1 W reg=E val=000F pc=3F200150 cyc=15 +1 R reg=F val=00FF pc=3F200250 cyc=29 +1 W reg=F val=0001 pc=3F200250 cyc=29 +1 R reg=D val=00F0 pc=3F200380 cyc=46 +1 R reg=D val=00F0 pc=3F200A20 cyc=2123 +1 R reg=D val=00F0 pc=3F202650 cyc=2715 +1 R reg=D val=00F0 pc=3F2045A0 cyc=465049 +1 R reg=E val=00FF pc=3F2042D0 cyc=576004 +1 W reg=E val=0001 pc=3F2042D0 cyc=576004 +1 R reg=D val=00F0 pc=3F204300 cyc=576005 +1 W reg=D val=0000 pc=3FDF1150 cyc=576167 +1 W reg=F val=0001 pc=3FDF1190 cyc=576171 +1 R reg=D val=00F0 pc=3FDF7DE0 cyc=1297177 +1 R reg=D val=00F0 pc=3F2045A0 cyc=1897379 +1 W reg=2 val=00CA pc=3FA90A00 cyc=3737622 +1 W reg=2 val=002A pc=3FA90AB0 cyc=3737945 +1 W reg=2 val=003A pc=3FA90B60 cyc=3738268 +1 W reg=2 val=004A pc=3FA90C10 cyc=3738591 +1 W reg=2 val=005A pc=3FA90CC0 cyc=3738914 +1 W reg=2 val=001A pc=3FA90D60 cyc=3739236 +1 W reg=A val=00CA pc=3FA90E10 cyc=3739559 +1 W reg=A val=002A pc=3FA90EC0 cyc=3739882 +1 W reg=A val=003A pc=3FA90F70 cyc=3740205 +1 W reg=A val=004A pc=3FA91020 cyc=3740528 +1 W reg=A val=005A pc=3FA910D0 cyc=3740851 +1 W reg=A val=001A pc=3FA91170 cyc=3741173 +1 W reg=F val=0080 pc=3FA7C330 cyc=3744820 +1 R reg=D val=00F0 pc=3F2045A0 cyc=10040220 +1 R reg=D val=00F0 pc=3F2045A0 cyc=15792800 +1 R reg=D val=00F0 pc=3F2045A0 cyc=15926711 +1 R reg=D val=00F0 pc=3F2045A0 cyc=34826663 +1 W reg=2 val=00FA pc=3FA778D0 cyc=43724635 +1 W reg=2 val=00CA pc=3FA77990 cyc=43724961 +1 W reg=2 val=002A pc=3FA77A30 cyc=43725282 +1 W reg=2 val=003A pc=3FA77AD0 cyc=43725603 +1 W reg=2 val=004A pc=3FA77B70 cyc=43725924 +1 W reg=2 val=005A pc=3FA77C10 cyc=43726245 +1 W reg=2 val=001A pc=3FA77CA0 cyc=43726565 +1 W reg=A val=00CA pc=3FA77990 cyc=43726956 +1 W reg=A val=002A pc=3FA77A30 cyc=43727277 +1 W reg=A val=003A pc=3FA77AD0 cyc=43727598 +1 W reg=A val=004A pc=3FA77B70 cyc=43727919 +1 W reg=A val=005A pc=3FA77C10 cyc=43728240 +1 W reg=A val=001A pc=3FA77CA0 cyc=43728560 +1 W reg=2 val=00FA pc=3FA778D0 cyc=43735282 +1 W reg=2 val=00CA pc=3FA77990 cyc=43735608 +1 W reg=2 val=002A pc=3FA77A30 cyc=43735929 +1 W reg=2 val=003A pc=3FA77AD0 cyc=43736250 +1 W reg=2 val=004A pc=3FA77B70 cyc=43736571 +1 W reg=2 val=005A pc=3FA77C10 cyc=43736892 +1 W reg=2 val=001A pc=3FA77CA0 cyc=43737212 +1 W reg=A val=00CA pc=3FA77990 cyc=43737603 +1 W reg=A val=002A pc=3FA77A30 cyc=43737924 +1 W reg=A val=003A pc=3FA77AD0 cyc=43738245 +1 W reg=A val=004A pc=3FA77B70 cyc=43738566 +1 W reg=A val=005A pc=3FA77C10 cyc=43738887 +1 W reg=A val=001A pc=3FA77CA0 cyc=43739207 +1 W reg=5 val=0007 pc=3FA78B40 cyc=43739320 +1 W reg=D val=0000 pc=3FA704E0 cyc=43739379 +1 W reg=4 val=0060 pc=3FA71CB0 cyc=43739476 +1 W reg=2 val=003A pc=3FA71F20 cyc=43739539 +1 W reg=2 val=002A pc=3FA71FD0 cyc=43739862 +1 W reg=2 val=004A pc=3FA72080 cyc=43740185 +1 W reg=2 val=001A pc=3FA72120 cyc=43740507 +1 W reg=1 val=0088 pc=3FA72220 cyc=43740837 +1 W reg=0 val=0012 pc=3FA73090 cyc=43745391 +1 W reg=0 val=0080 pc=3FA731B0 cyc=43745728 +1 W reg=2 val=0005 pc=3FA73260 cyc=43805849 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43805931 +1 R reg=1 val=000C pc=3FA79E50 cyc=43806012 +1 W reg=3 val=00AA pc=3FA79F00 cyc=43806034 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43806056 +1 W reg=E val=0000 pc=3FA7A060 cyc=43806078 +1 W reg=F val=0000 pc=3FA7A110 cyc=43806100 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43806122 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43806156 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43810019 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43810100 +1 W reg=3 val=00FF pc=3FA79F00 cyc=43810122 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43810144 +1 W reg=E val=0000 pc=3FA7A060 cyc=43810166 +1 W reg=F val=0000 pc=3FA7A110 cyc=43810188 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43810210 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43810244 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43828249 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43828330 +1 W reg=3 val=00AA pc=3FA79F00 cyc=43828352 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43828374 +1 W reg=E val=0000 pc=3FA7A060 cyc=43828396 +1 W reg=F val=0000 pc=3FA7A110 cyc=43828418 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43828440 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43828474 +1 R reg=5 val=000A pc=3FA78E30 cyc=43829551 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43829633 +1 R reg=3 val=002A pc=3FA79780 cyc=43829655 +1 R reg=1 val=0000 pc=3FA79830 cyc=43829677 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43829699 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43829733 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43851686 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43851767 +1 W reg=3 val=0055 pc=3FA79F00 cyc=43851789 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43851811 +1 W reg=E val=0000 pc=3FA7A060 cyc=43851833 +1 W reg=F val=0000 pc=3FA7A110 cyc=43851855 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43851877 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43851911 +1 R reg=5 val=000A pc=3FA78E30 cyc=43852988 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43853070 +1 R reg=3 val=007F pc=3FA79780 cyc=43853092 +1 R reg=1 val=0000 pc=3FA79830 cyc=43853114 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43853136 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43853170 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43875123 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43875204 +1 W reg=3 val=0000 pc=3FA79F00 cyc=43875226 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43875248 +1 W reg=E val=0000 pc=3FA7A060 cyc=43875270 +1 W reg=F val=0000 pc=3FA7A110 cyc=43875292 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43875314 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43875348 +1 R reg=5 val=000A pc=3FA78E30 cyc=43876425 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43876507 +1 R reg=3 val=002A pc=3FA79780 cyc=43876529 +1 R reg=1 val=0000 pc=3FA79830 cyc=43876551 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43876573 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43876607 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43898560 +1 R reg=1 val=0004 pc=3FA7A3C0 cyc=43898630 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=43898636 +1 R reg=1 val=0000 pc=3FA7A440 cyc=43898644 +1 R reg=5 val=000A pc=3FA78E30 cyc=43899863 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43899945 +1 R reg=3 val=0055 pc=3FA79780 cyc=43899967 +1 R reg=1 val=0000 pc=3FA79830 cyc=43899989 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43900011 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43900045 +1 R reg=5 val=000A pc=3FA78E30 cyc=43923301 +1 R reg=1 val=0009 pc=3FA796D0 cyc=43923383 +1 R reg=3 val=0000 pc=3FA79780 cyc=43923405 +1 R reg=1 val=0008 pc=3FA79830 cyc=43923427 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43923449 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43923483 +1 W reg=2 val=000A pc=3FA73420 cyc=43931657 +1 W reg=2 val=002A pc=3FA74BE0 cyc=43933007 +1 W reg=2 val=002B pc=3FA74C80 cyc=43933329 +1 W reg=2 val=004A pc=3FA74D10 cyc=43933650 +1 W reg=2 val=0065 pc=3FA74DA0 cyc=43933971 +1 R reg=5 val=000F pc=3FA78E30 cyc=43934053 +1 R reg=1 val=008D pc=3FA78FD0 cyc=43934094 +1 W reg=2 val=0055 pc=3FA79010 cyc=43934101 +1 W reg=2 val=0075 pc=3FA790C0 cyc=43934424 +1 R reg=1 val=008D pc=3FA79AE0 cyc=43934494 +1 R reg=3 val=0000 pc=3FA79B00 cyc=43934499 +1 W reg=2 val=0002 pc=3FA79B60 cyc=43934508 +1 R reg=1 val=000C pc=3FA79BB0 cyc=43934516 +1 R reg=5 val=000D pc=3FA78E30 cyc=43934741 +1 W reg=2 val=005A pc=3FA79110 cyc=43934780 +1 W reg=2 val=007A pc=3FA74E60 cyc=43995061 +1 W reg=2 val=0050 pc=3FA74F10 cyc=43995384 +1 W reg=2 val=003A pc=3FA71F20 cyc=43995432 +1 W reg=2 val=002A pc=3FA71FD0 cyc=43995755 +1 W reg=2 val=004A pc=3FA72080 cyc=43996078 +1 W reg=2 val=001A pc=3FA72120 cyc=43996400 +1 W reg=1 val=0088 pc=3FA72220 cyc=43996730 +1 W reg=0 val=0013 pc=3FA73090 cyc=44001284 +1 W reg=0 val=0080 pc=3FA731B0 cyc=44001621 +1 W reg=2 val=0005 pc=3FA73260 cyc=44061742 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44061824 +1 R reg=1 val=000C pc=3FA79E50 cyc=44061905 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44061927 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44061949 +1 W reg=E val=0000 pc=3FA7A060 cyc=44061971 +1 W reg=F val=0000 pc=3FA7A110 cyc=44061993 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44062015 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44062049 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44067214 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44067295 +1 W reg=3 val=00FF pc=3FA79F00 cyc=44067317 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44067339 +1 W reg=E val=0000 pc=3FA7A060 cyc=44067361 +1 W reg=F val=0000 pc=3FA7A110 cyc=44067383 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44067405 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44067439 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44088048 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44088129 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44088151 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44088173 +1 W reg=E val=0000 pc=3FA7A060 cyc=44088195 +1 W reg=F val=0000 pc=3FA7A110 cyc=44088217 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44088239 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44088273 +1 R reg=5 val=000A pc=3FA78E30 cyc=44089350 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44089432 +1 R reg=3 val=00AA pc=3FA79780 cyc=44089454 +1 R reg=1 val=0000 pc=3FA79830 cyc=44089476 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44089498 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44089532 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44114090 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44114171 +1 W reg=3 val=0055 pc=3FA79F00 cyc=44114193 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44114215 +1 W reg=E val=0000 pc=3FA7A060 cyc=44114237 +1 W reg=F val=0000 pc=3FA7A110 cyc=44114259 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44114281 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44114315 +1 R reg=5 val=000A pc=3FA78E30 cyc=44115392 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44115474 +1 R reg=3 val=00FF pc=3FA79780 cyc=44115496 +1 R reg=1 val=0000 pc=3FA79830 cyc=44115518 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44115540 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44115574 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44140131 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44140212 +1 W reg=3 val=0000 pc=3FA79F00 cyc=44140234 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44140256 +1 W reg=E val=0000 pc=3FA7A060 cyc=44140278 +1 W reg=F val=0000 pc=3FA7A110 cyc=44140300 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44140322 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44140356 +1 R reg=5 val=000A pc=3FA78E30 cyc=44141433 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44141515 +1 R reg=3 val=00AA pc=3FA79780 cyc=44141537 +1 R reg=1 val=0000 pc=3FA79830 cyc=44141559 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44141581 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44141615 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44166172 +1 R reg=1 val=0004 pc=3FA7A3C0 cyc=44166242 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=44166248 +1 R reg=1 val=0000 pc=3FA7A440 cyc=44166256 +1 R reg=5 val=000A pc=3FA78E30 cyc=44167474 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44167556 +1 R reg=3 val=0055 pc=3FA79780 cyc=44167578 +1 R reg=1 val=0000 pc=3FA79830 cyc=44167600 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44167622 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44167656 +1 R reg=5 val=000A pc=3FA78E30 cyc=44193517 +1 R reg=1 val=0009 pc=3FA796D0 cyc=44193599 +1 R reg=3 val=0000 pc=3FA79780 cyc=44193621 +1 R reg=1 val=0008 pc=3FA79830 cyc=44193643 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44193665 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44193699 +1 W reg=2 val=000A pc=3FA73420 cyc=44197687 +1 W reg=2 val=002A pc=3FA74BE0 cyc=44199037 +1 W reg=2 val=002B pc=3FA74C80 cyc=44199359 +1 W reg=2 val=004A pc=3FA74D10 cyc=44199680 +1 W reg=2 val=0065 pc=3FA74DA0 cyc=44200001 +1 R reg=5 val=000F pc=3FA78E30 cyc=44200083 +1 R reg=1 val=008D pc=3FA78FD0 cyc=44200124 +1 W reg=2 val=0055 pc=3FA79010 cyc=44200131 +1 W reg=2 val=0075 pc=3FA790C0 cyc=44200454 +1 R reg=1 val=008D pc=3FA79AE0 cyc=44200524 +1 R reg=3 val=0000 pc=3FA79B00 cyc=44200529 +1 W reg=2 val=0002 pc=3FA79B60 cyc=44200538 +1 R reg=1 val=000C pc=3FA79BB0 cyc=44200546 +1 R reg=5 val=000D pc=3FA78E30 cyc=44200771 +1 W reg=2 val=005A pc=3FA79110 cyc=44200810 +1 W reg=2 val=007A pc=3FA74E60 cyc=44261091 +1 W reg=2 val=0050 pc=3FA74F10 cyc=44261414 +1 W reg=2 val=003A pc=3FA71F20 cyc=44261487 +1 W reg=2 val=002A pc=3FA71FD0 cyc=44261810 +1 W reg=2 val=004A pc=3FA72080 cyc=44262133 +1 W reg=2 val=001A pc=3FA72120 cyc=44262455 +1 W reg=1 val=0088 pc=3FA72220 cyc=44262785 +1 W reg=0 val=0002 pc=3FA73090 cyc=44267339 +1 W reg=0 val=0080 pc=3FA731B0 cyc=44267676 +1 W reg=2 val=0005 pc=3FA73260 cyc=44327797 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44327879 +1 R reg=1 val=000C pc=3FA79E50 cyc=44327960 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44327982 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44328004 +1 W reg=E val=0000 pc=3FA7A060 cyc=44328026 +1 W reg=F val=0000 pc=3FA7A110 cyc=44328048 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44328070 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44328104 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44333269 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44333350 +1 W reg=3 val=00FF pc=3FA79F00 cyc=44333372 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44333394 +1 W reg=E val=0000 pc=3FA7A060 cyc=44333416 +1 W reg=F val=0000 pc=3FA7A110 cyc=44333438 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44333460 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44333494 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44354103 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44354184 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44354206 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44354228 +1 W reg=E val=0000 pc=3FA7A060 cyc=44354250 +1 W reg=F val=0000 pc=3FA7A110 cyc=44354272 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44354294 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44354328 +1 R reg=5 val=000A pc=3FA78E30 cyc=44355405 +1 R reg=1 val=0021 pc=3FA796D0 cyc=44355487 +1 R reg=3 val=002A pc=3FA79780 cyc=44355509 +1 R reg=1 val=0000 pc=3FA79830 cyc=44355531 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44355553 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44355587 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44380145 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44380226 +1 W reg=3 val=0055 pc=3FA79F00 cyc=44380248 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44380270 +1 W reg=E val=0000 pc=3FA7A060 cyc=44380292 +1 W reg=F val=0000 pc=3FA7A110 cyc=44380314 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44380336 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44380370 +1 R reg=5 val=000A pc=3FA78E30 cyc=44381447 +1 R reg=1 val=0021 pc=3FA796D0 cyc=44381529 +1 R reg=3 val=007F pc=3FA79780 cyc=44381551 +1 R reg=1 val=0000 pc=3FA79830 cyc=44381573 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44381595 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44381629 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44406186 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44406267 +1 W reg=3 val=0000 pc=3FA79F00 cyc=44406289 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44406311 +1 W reg=E val=0000 pc=3FA7A060 cyc=44406333 +1 W reg=F val=0000 pc=3FA7A110 cyc=44406355 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44406377 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44406411 +1 R reg=5 val=000A pc=3FA78E30 cyc=44407488 +1 R reg=1 val=0021 pc=3FA796D0 cyc=44407570 +1 R reg=3 val=002A pc=3FA79780 cyc=44407592 +1 R reg=1 val=0000 pc=3FA79830 cyc=44407614 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44407636 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44407670 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44432227 +1 R reg=1 val=0004 pc=3FA7A3C0 cyc=44432297 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=44432303 +1 R reg=1 val=0000 pc=3FA7A440 cyc=44432311 +1 R reg=5 val=000A pc=3FA78E30 cyc=44433529 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44433611 +1 R reg=3 val=0055 pc=3FA79780 cyc=44433633 +1 R reg=1 val=0000 pc=3FA79830 cyc=44433655 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44433677 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44433711 +1 R reg=5 val=000A pc=3FA78E30 cyc=44459572 +1 R reg=1 val=0009 pc=3FA796D0 cyc=44459654 +1 R reg=3 val=0000 pc=3FA79780 cyc=44459676 +1 R reg=1 val=0008 pc=3FA79830 cyc=44459698 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44459720 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44459754 +1 W reg=2 val=000A pc=3FA73420 cyc=44463742 +1 W reg=2 val=002A pc=3FA74BE0 cyc=44465104 +1 W reg=2 val=002B pc=3FA74C80 cyc=44465426 +1 W reg=2 val=004A pc=3FA74D10 cyc=44465747 +1 W reg=2 val=0065 pc=3FA74DA0 cyc=44466068 +1 R reg=5 val=000F pc=3FA78E30 cyc=44466150 +1 R reg=1 val=008D pc=3FA78FD0 cyc=44466191 +1 W reg=2 val=0055 pc=3FA79010 cyc=44466198 +1 W reg=2 val=0075 pc=3FA790C0 cyc=44466521 +1 R reg=1 val=008D pc=3FA79AE0 cyc=44466591 +1 R reg=3 val=0000 pc=3FA79B00 cyc=44466596 +1 W reg=2 val=0002 pc=3FA79B60 cyc=44466605 +1 R reg=1 val=000C pc=3FA79BB0 cyc=44466613 +1 R reg=5 val=000D pc=3FA78E30 cyc=44466838 +1 W reg=2 val=005A pc=3FA79110 cyc=44466877 +1 W reg=2 val=007A pc=3FA74E60 cyc=44527158 +1 W reg=2 val=0050 pc=3FA74F10 cyc=44527481 +1 W reg=5 val=0000 pc=3FA78D10 cyc=44527649 +1 W reg=5 val=0001 pc=3FA78B40 cyc=44527781 +1 W reg=2 val=003A pc=3FA75570 cyc=44527906 +1 W reg=2 val=002A pc=3FA75620 cyc=44528229 +1 W reg=2 val=004A pc=3FA756D0 cyc=44528552 +1 W reg=2 val=001A pc=3FA75770 cyc=44528874 +1 W reg=1 val=0088 pc=3FA75870 cyc=44529204 +1 W reg=0 val=0010 pc=3FA75BC0 cyc=44532296 +1 W reg=0 val=0080 pc=3FA75CE0 cyc=44532633 +1 W reg=2 val=0005 pc=3FA75D90 cyc=44592754 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44592836 +1 R reg=1 val=000C pc=3FA79E50 cyc=44592917 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44592939 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44592961 +1 W reg=E val=0000 pc=3FA7A060 cyc=44592983 +1 W reg=F val=0000 pc=3FA7A110 cyc=44593005 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44593027 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44593061 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44598227 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44598308 +1 W reg=3 val=00FF pc=3FA79F00 cyc=44598330 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44598352 +1 W reg=E val=0000 pc=3FA7A060 cyc=44598374 +1 W reg=F val=0000 pc=3FA7A110 cyc=44598396 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44598418 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44598452 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44611247 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44611328 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44611350 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44611372 +1 W reg=E val=0000 pc=3FA7A060 cyc=44611394 +1 W reg=F val=0000 pc=3FA7A110 cyc=44611416 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44611438 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44611472 +1 R reg=5 val=000B pc=3FA78E30 cyc=44629477 +1 R reg=1 val=0005 pc=3FA79E50 cyc=44629558 +1 W reg=3 val=0055 pc=3FA79F00 cyc=44629580 +1 R reg=1 val=0001 pc=3FA79FB0 cyc=44629602 +1 W reg=E val=0000 pc=3FA7A060 cyc=44629624 +1 W reg=F val=0000 pc=3FA7A110 cyc=44629646 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44629668 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44629702 +1 R reg=5 val=000B pc=3FA78E30 cyc=44647705 +1 R reg=1 val=0005 pc=3FA79E50 cyc=44647786 +1 W reg=3 val=0000 pc=3FA79F00 cyc=44647808 +1 R reg=1 val=0001 pc=3FA79FB0 cyc=44647830 +1 W reg=E val=0000 pc=3FA7A060 cyc=44647852 +1 W reg=F val=0000 pc=3FA7A110 cyc=44647874 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44647896 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44647930 +1 R reg=5 val=000B pc=3FA78E30 cyc=44665934 +1 R reg=1 val=0007 pc=3FA7A3C0 cyc=44666004 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=44666010 +1 R reg=1 val=0003 pc=3FA7A440 cyc=44666018 +1 W reg=2 val=000A pc=3FA76010 cyc=44715338 +1 R reg=1 val=0012 pc=3FA761B0 cyc=44715379 +1 R reg=3 val=000A pc=3FA76360 cyc=44715419 +1 R reg=1 val=0012 pc=3FA761B0 cyc=44715444 +1 R reg=3 val=001F pc=3FA76360 cyc=44715484 +1 R reg=1 val=0010 pc=3FA761B0 cyc=44715509 +1 R reg=3 val=000A pc=3FA76360 cyc=44715549 +1 W reg=5 val=0000 pc=3FA78D10 cyc=44715718 +1 W reg=5 val=0007 pc=3FA78B40 cyc=44715843 +1 W reg=5 val=0000 pc=3FA78D10 cyc=44716071 +1 W reg=2 val=00FA pc=3FA778D0 cyc=44716176 +1 W reg=2 val=00CA pc=3FA77990 cyc=44716502 +1 W reg=2 val=002A pc=3FA77A30 cyc=44716823 +1 W reg=2 val=003A pc=3FA77AD0 cyc=44717144 +1 W reg=2 val=004A pc=3FA77B70 cyc=44717465 +1 W reg=2 val=005A pc=3FA77C10 cyc=44717786 +1 W reg=2 val=001A pc=3FA77CA0 cyc=44718106 +1 W reg=A val=00CA pc=3FA77990 cyc=44718497 +1 W reg=A val=002A pc=3FA77A30 cyc=44718818 +1 W reg=A val=003A pc=3FA77AD0 cyc=44719139 +1 W reg=A val=004A pc=3FA77B70 cyc=44719460 +1 W reg=A val=005A pc=3FA77C10 cyc=44719781 +1 W reg=A val=001A pc=3FA77CA0 cyc=44720101 +1 W reg=F val=0080 pc=3FA850F0 cyc=44720336 +1 R reg=D val=00F0 pc=3F2045A0 cyc=44720804 +1 W reg=D val=0000 pc=3F208830 cyc=44995716 +1 W reg=F val=00FF pc=3F208880 cyc=44995721 diff --git a/harness/mame/hp_lat2.log b/harness/mame/hp_lat2.log new file mode 100644 index 0000000..aa7e609 --- /dev/null +++ b/harness/mame/hp_lat2.log @@ -0,0 +1,443 @@ +# win kind reg val pc -- every DUART access (not de-duplicated) +1 W reg=D val=0000 pc=3F2000B0 cyc=7 +1 R reg=F val=00FF pc=3F200100 cyc=12 +1 W reg=F val=00FF pc=3F200100 cyc=12 +1 R reg=E val=00FF pc=3F200150 cyc=15 +1 W reg=E val=000F pc=3F200150 cyc=15 +1 R reg=F val=00FF pc=3F200250 cyc=29 +1 W reg=F val=0001 pc=3F200250 cyc=29 +1 R reg=D val=00F0 pc=3F200380 cyc=46 +1 R reg=D val=00F0 pc=3F200A20 cyc=2123 +1 R reg=D val=00F0 pc=3F202650 cyc=2715 +1 R reg=D val=00F0 pc=3F2045A0 cyc=465049 +1 R reg=E val=00FF pc=3F2042D0 cyc=576004 +1 W reg=E val=0001 pc=3F2042D0 cyc=576004 +1 R reg=D val=00F0 pc=3F204300 cyc=576005 +1 W reg=D val=0000 pc=3FDF1150 cyc=576167 +1 W reg=F val=0001 pc=3FDF1190 cyc=576171 +1 R reg=D val=00F0 pc=3FDF7DE0 cyc=1297177 +1 R reg=D val=00F0 pc=3F2045A0 cyc=1897379 +1 W reg=2 val=00CA pc=3FA90A00 cyc=3737622 +1 W reg=2 val=002A pc=3FA90AB0 cyc=3737945 +1 W reg=2 val=003A pc=3FA90B60 cyc=3738268 +1 W reg=2 val=004A pc=3FA90C10 cyc=3738591 +1 W reg=2 val=005A pc=3FA90CC0 cyc=3738914 +1 W reg=2 val=001A pc=3FA90D60 cyc=3739236 +1 W reg=A val=00CA pc=3FA90E10 cyc=3739559 +1 W reg=A val=002A pc=3FA90EC0 cyc=3739882 +1 W reg=A val=003A pc=3FA90F70 cyc=3740205 +1 W reg=A val=004A pc=3FA91020 cyc=3740528 +1 W reg=A val=005A pc=3FA910D0 cyc=3740851 +1 W reg=A val=001A pc=3FA91170 cyc=3741173 +1 W reg=F val=0080 pc=3FA7C330 cyc=3744820 +1 R reg=D val=00F0 pc=3F2045A0 cyc=10040220 +1 R reg=D val=00F0 pc=3F2045A0 cyc=15792800 +1 R reg=D val=00F0 pc=3F2045A0 cyc=15926711 +1 R reg=D val=00F0 pc=3F2045A0 cyc=34826663 +1 W reg=2 val=00FA pc=3FA778D0 cyc=43724635 +1 W reg=2 val=00CA pc=3FA77990 cyc=43724961 +1 W reg=2 val=002A pc=3FA77A30 cyc=43725282 +1 W reg=2 val=003A pc=3FA77AD0 cyc=43725603 +1 W reg=2 val=004A pc=3FA77B70 cyc=43725924 +1 W reg=2 val=005A pc=3FA77C10 cyc=43726245 +1 W reg=2 val=001A pc=3FA77CA0 cyc=43726565 +1 W reg=A val=00CA pc=3FA77990 cyc=43726956 +1 W reg=A val=002A pc=3FA77A30 cyc=43727277 +1 W reg=A val=003A pc=3FA77AD0 cyc=43727598 +1 W reg=A val=004A pc=3FA77B70 cyc=43727919 +1 W reg=A val=005A pc=3FA77C10 cyc=43728240 +1 W reg=A val=001A pc=3FA77CA0 cyc=43728560 +1 W reg=2 val=00FA pc=3FA778D0 cyc=43735282 +1 W reg=2 val=00CA pc=3FA77990 cyc=43735608 +1 W reg=2 val=002A pc=3FA77A30 cyc=43735929 +1 W reg=2 val=003A pc=3FA77AD0 cyc=43736250 +1 W reg=2 val=004A pc=3FA77B70 cyc=43736571 +1 W reg=2 val=005A pc=3FA77C10 cyc=43736892 +1 W reg=2 val=001A pc=3FA77CA0 cyc=43737212 +1 W reg=A val=00CA pc=3FA77990 cyc=43737603 +1 W reg=A val=002A pc=3FA77A30 cyc=43737924 +1 W reg=A val=003A pc=3FA77AD0 cyc=43738245 +1 W reg=A val=004A pc=3FA77B70 cyc=43738566 +1 W reg=A val=005A pc=3FA77C10 cyc=43738887 +1 W reg=A val=001A pc=3FA77CA0 cyc=43739207 +1 W reg=5 val=0007 pc=3FA78B40 cyc=43739320 +1 W reg=D val=0000 pc=3FA704E0 cyc=43739379 +1 W reg=4 val=0060 pc=3FA71CB0 cyc=43739476 +1 W reg=2 val=003A pc=3FA71F20 cyc=43739539 +1 W reg=2 val=002A pc=3FA71FD0 cyc=43739862 +1 W reg=2 val=004A pc=3FA72080 cyc=43740185 +1 W reg=2 val=001A pc=3FA72120 cyc=43740507 +1 W reg=1 val=0088 pc=3FA72220 cyc=43740837 +1 W reg=0 val=0012 pc=3FA73090 cyc=43745391 +1 W reg=0 val=0080 pc=3FA731B0 cyc=43745728 +1 W reg=2 val=0005 pc=3FA73260 cyc=43805849 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43805931 +1 R reg=1 val=000C pc=3FA79E50 cyc=43806012 +1 W reg=3 val=00AA pc=3FA79F00 cyc=43806034 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43806056 +1 W reg=E val=0000 pc=3FA7A060 cyc=43806078 +1 W reg=F val=0000 pc=3FA7A110 cyc=43806100 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43806122 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43806156 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43808717 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43808798 +1 W reg=3 val=00FF pc=3FA79F00 cyc=43808820 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43808842 +1 W reg=E val=0000 pc=3FA7A060 cyc=43808864 +1 W reg=F val=0000 pc=3FA7A110 cyc=43808886 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43808908 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43808942 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43826946 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43827027 +1 W reg=3 val=00AA pc=3FA79F00 cyc=43827049 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43827071 +1 W reg=E val=0000 pc=3FA7A060 cyc=43827093 +1 W reg=F val=0000 pc=3FA7A110 cyc=43827115 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43827137 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43827171 +1 R reg=5 val=000A pc=3FA78E30 cyc=43828249 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43828331 +1 R reg=3 val=002A pc=3FA79780 cyc=43828353 +1 R reg=1 val=0000 pc=3FA79830 cyc=43828375 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43828397 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43828431 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43850384 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43850465 +1 W reg=3 val=0055 pc=3FA79F00 cyc=43850487 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43850509 +1 W reg=E val=0000 pc=3FA7A060 cyc=43850531 +1 W reg=F val=0000 pc=3FA7A110 cyc=43850553 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43850575 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43850609 +1 R reg=5 val=000A pc=3FA78E30 cyc=43851686 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43851768 +1 R reg=3 val=007F pc=3FA79780 cyc=43851790 +1 R reg=1 val=0000 pc=3FA79830 cyc=43851812 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43851834 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43851868 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43873821 +1 R reg=1 val=0004 pc=3FA79E50 cyc=43873902 +1 W reg=3 val=0000 pc=3FA79F00 cyc=43873924 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=43873946 +1 W reg=E val=0000 pc=3FA7A060 cyc=43873968 +1 W reg=F val=0000 pc=3FA7A110 cyc=43873990 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=43874012 +1 R reg=D val=00F0 pc=3FA7A320 cyc=43874046 +1 R reg=5 val=000A pc=3FA78E30 cyc=43875123 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43875205 +1 R reg=3 val=002A pc=3FA79780 cyc=43875227 +1 R reg=1 val=0000 pc=3FA79830 cyc=43875249 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43875271 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43875305 +1 R reg=5 val=0009 pc=3FA78E30 cyc=43897258 +1 R reg=1 val=0004 pc=3FA7A3C0 cyc=43897328 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=43897334 +1 R reg=1 val=0000 pc=3FA7A440 cyc=43897342 +1 R reg=5 val=000A pc=3FA78E30 cyc=43898561 +1 R reg=1 val=0001 pc=3FA796D0 cyc=43898643 +1 R reg=3 val=0055 pc=3FA79780 cyc=43898665 +1 R reg=1 val=0000 pc=3FA79830 cyc=43898687 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43898709 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43898743 +1 R reg=5 val=000A pc=3FA78E30 cyc=43921999 +1 R reg=1 val=0009 pc=3FA796D0 cyc=43922081 +1 R reg=3 val=0000 pc=3FA79780 cyc=43922103 +1 R reg=1 val=0008 pc=3FA79830 cyc=43922125 +1 R reg=D val=00F0 pc=3FA798E0 cyc=43922147 +1 R reg=D val=00F0 pc=3FA79A20 cyc=43922181 +1 W reg=2 val=000A pc=3FA73420 cyc=43931657 +1 W reg=2 val=002A pc=3FA74BE0 cyc=43933007 +1 W reg=2 val=002B pc=3FA74C80 cyc=43933329 +1 W reg=2 val=004A pc=3FA74D10 cyc=43933650 +1 W reg=2 val=0065 pc=3FA74DA0 cyc=43933971 +1 R reg=5 val=000F pc=3FA78E30 cyc=43934053 +1 R reg=1 val=008D pc=3FA78FD0 cyc=43934094 +1 W reg=2 val=0055 pc=3FA79010 cyc=43934101 +1 W reg=2 val=0075 pc=3FA790C0 cyc=43934424 +1 R reg=1 val=008D pc=3FA79AE0 cyc=43934494 +1 R reg=3 val=0000 pc=3FA79B00 cyc=43934499 +1 W reg=2 val=0002 pc=3FA79B60 cyc=43934508 +1 R reg=1 val=000C pc=3FA79BB0 cyc=43934516 +1 R reg=5 val=000D pc=3FA78E30 cyc=43934741 +1 W reg=2 val=005A pc=3FA79110 cyc=43934780 +1 W reg=2 val=007A pc=3FA74E60 cyc=43995061 +1 W reg=2 val=0050 pc=3FA74F10 cyc=43995384 +1 W reg=2 val=003A pc=3FA71F20 cyc=43995432 +1 W reg=2 val=002A pc=3FA71FD0 cyc=43995755 +1 W reg=2 val=004A pc=3FA72080 cyc=43996078 +1 W reg=2 val=001A pc=3FA72120 cyc=43996400 +1 W reg=1 val=0088 pc=3FA72220 cyc=43996730 +1 W reg=0 val=0013 pc=3FA73090 cyc=44001284 +1 W reg=0 val=0080 pc=3FA731B0 cyc=44001621 +1 W reg=2 val=0005 pc=3FA73260 cyc=44061742 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44061824 +1 R reg=1 val=000C pc=3FA79E50 cyc=44061905 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44061927 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44061949 +1 W reg=E val=0000 pc=3FA7A060 cyc=44061971 +1 W reg=F val=0000 pc=3FA7A110 cyc=44061993 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44062015 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44062049 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44064610 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44064691 +1 W reg=3 val=00FF pc=3FA79F00 cyc=44064713 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44064735 +1 W reg=E val=0000 pc=3FA7A060 cyc=44064757 +1 W reg=F val=0000 pc=3FA7A110 cyc=44064779 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44064801 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44064835 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44085444 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44085525 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44085547 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44085569 +1 W reg=E val=0000 pc=3FA7A060 cyc=44085591 +1 W reg=F val=0000 pc=3FA7A110 cyc=44085613 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44085635 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44085669 +1 R reg=5 val=000A pc=3FA78E30 cyc=44086746 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44086828 +1 R reg=3 val=00AA pc=3FA79780 cyc=44086850 +1 R reg=1 val=0000 pc=3FA79830 cyc=44086872 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44086894 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44086928 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44111485 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44111566 +1 W reg=3 val=0055 pc=3FA79F00 cyc=44111588 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44111610 +1 W reg=E val=0000 pc=3FA7A060 cyc=44111632 +1 W reg=F val=0000 pc=3FA7A110 cyc=44111654 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44111676 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44111710 +1 R reg=5 val=000A pc=3FA78E30 cyc=44112787 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44112869 +1 R reg=3 val=00FF pc=3FA79780 cyc=44112891 +1 R reg=1 val=0000 pc=3FA79830 cyc=44112913 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44112935 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44112969 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44137527 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44137608 +1 W reg=3 val=0000 pc=3FA79F00 cyc=44137630 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44137652 +1 W reg=E val=0000 pc=3FA7A060 cyc=44137674 +1 W reg=F val=0000 pc=3FA7A110 cyc=44137696 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44137718 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44137752 +1 R reg=5 val=000A pc=3FA78E30 cyc=44138829 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44138911 +1 R reg=3 val=00AA pc=3FA79780 cyc=44138933 +1 R reg=1 val=0000 pc=3FA79830 cyc=44138955 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44138977 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44139011 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44163568 +1 R reg=1 val=0004 pc=3FA7A3C0 cyc=44163638 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=44163644 +1 R reg=1 val=0000 pc=3FA7A440 cyc=44163652 +1 R reg=5 val=000A pc=3FA78E30 cyc=44164871 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44164953 +1 R reg=3 val=0055 pc=3FA79780 cyc=44164975 +1 R reg=1 val=0000 pc=3FA79830 cyc=44164997 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44165019 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44165053 +1 R reg=5 val=000A pc=3FA78E30 cyc=44190913 +1 R reg=1 val=0009 pc=3FA796D0 cyc=44190995 +1 R reg=3 val=0000 pc=3FA79780 cyc=44191017 +1 R reg=1 val=0008 pc=3FA79830 cyc=44191039 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44191061 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44191095 +1 W reg=2 val=000A pc=3FA73420 cyc=44197687 +1 W reg=2 val=002A pc=3FA74BE0 cyc=44199037 +1 W reg=2 val=002B pc=3FA74C80 cyc=44199359 +1 W reg=2 val=004A pc=3FA74D10 cyc=44199680 +1 W reg=2 val=0065 pc=3FA74DA0 cyc=44200001 +1 R reg=5 val=000F pc=3FA78E30 cyc=44200083 +1 R reg=1 val=008D pc=3FA78FD0 cyc=44200124 +1 W reg=2 val=0055 pc=3FA79010 cyc=44200131 +1 W reg=2 val=0075 pc=3FA790C0 cyc=44200454 +1 R reg=1 val=008D pc=3FA79AE0 cyc=44200524 +1 R reg=3 val=0000 pc=3FA79B00 cyc=44200529 +1 W reg=2 val=0002 pc=3FA79B60 cyc=44200538 +1 R reg=1 val=000C pc=3FA79BB0 cyc=44200546 +1 R reg=5 val=000D pc=3FA78E30 cyc=44200771 +1 W reg=2 val=005A pc=3FA79110 cyc=44200810 +1 W reg=2 val=007A pc=3FA74E60 cyc=44261091 +1 W reg=2 val=0050 pc=3FA74F10 cyc=44261414 +1 W reg=2 val=003A pc=3FA71F20 cyc=44261487 +1 W reg=2 val=002A pc=3FA71FD0 cyc=44261810 +1 W reg=2 val=004A pc=3FA72080 cyc=44262133 +1 W reg=2 val=001A pc=3FA72120 cyc=44262455 +1 W reg=1 val=0088 pc=3FA72220 cyc=44262785 +1 W reg=0 val=0002 pc=3FA73090 cyc=44267339 +1 W reg=0 val=0080 pc=3FA731B0 cyc=44267676 +1 W reg=2 val=0005 pc=3FA73260 cyc=44327797 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44327879 +1 R reg=1 val=000C pc=3FA79E50 cyc=44327960 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44327982 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44328004 +1 W reg=E val=0000 pc=3FA7A060 cyc=44328026 +1 W reg=F val=0000 pc=3FA7A110 cyc=44328048 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44328070 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44328104 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44330665 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44330746 +1 W reg=3 val=00FF pc=3FA79F00 cyc=44330768 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44330790 +1 W reg=E val=0000 pc=3FA7A060 cyc=44330812 +1 W reg=F val=0000 pc=3FA7A110 cyc=44330834 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44330856 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44330890 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44351499 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44351580 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44351602 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44351624 +1 W reg=E val=0000 pc=3FA7A060 cyc=44351646 +1 W reg=F val=0000 pc=3FA7A110 cyc=44351668 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44351690 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44351724 +1 R reg=5 val=000A pc=3FA78E30 cyc=44352801 +1 R reg=1 val=0021 pc=3FA796D0 cyc=44352883 +1 R reg=3 val=002A pc=3FA79780 cyc=44352905 +1 R reg=1 val=0000 pc=3FA79830 cyc=44352927 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44352949 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44352983 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44377540 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44377621 +1 W reg=3 val=0055 pc=3FA79F00 cyc=44377643 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44377665 +1 W reg=E val=0000 pc=3FA7A060 cyc=44377687 +1 W reg=F val=0000 pc=3FA7A110 cyc=44377709 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44377731 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44377765 +1 R reg=5 val=000A pc=3FA78E30 cyc=44378842 +1 R reg=1 val=0021 pc=3FA796D0 cyc=44378924 +1 R reg=3 val=007F pc=3FA79780 cyc=44378946 +1 R reg=1 val=0000 pc=3FA79830 cyc=44378968 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44378990 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44379024 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44403582 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44403663 +1 W reg=3 val=0000 pc=3FA79F00 cyc=44403685 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44403707 +1 W reg=E val=0000 pc=3FA7A060 cyc=44403729 +1 W reg=F val=0000 pc=3FA7A110 cyc=44403751 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44403773 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44403807 +1 R reg=5 val=000A pc=3FA78E30 cyc=44404884 +1 R reg=1 val=0021 pc=3FA796D0 cyc=44404966 +1 R reg=3 val=002A pc=3FA79780 cyc=44404988 +1 R reg=1 val=0000 pc=3FA79830 cyc=44405010 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44405032 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44405066 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44429623 +1 R reg=1 val=0004 pc=3FA7A3C0 cyc=44429693 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=44429699 +1 R reg=1 val=0000 pc=3FA7A440 cyc=44429707 +1 R reg=5 val=000A pc=3FA78E30 cyc=44430926 +1 R reg=1 val=0001 pc=3FA796D0 cyc=44431008 +1 R reg=3 val=0055 pc=3FA79780 cyc=44431030 +1 R reg=1 val=0000 pc=3FA79830 cyc=44431052 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44431074 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44431108 +1 R reg=5 val=000A pc=3FA78E30 cyc=44456968 +1 R reg=1 val=0009 pc=3FA796D0 cyc=44457050 +1 R reg=3 val=0000 pc=3FA79780 cyc=44457072 +1 R reg=1 val=0008 pc=3FA79830 cyc=44457094 +1 R reg=D val=00F0 pc=3FA798E0 cyc=44457116 +1 R reg=D val=00F0 pc=3FA79A20 cyc=44457150 +1 W reg=2 val=000A pc=3FA73420 cyc=44463742 +1 W reg=2 val=002A pc=3FA74BE0 cyc=44465104 +1 W reg=2 val=002B pc=3FA74C80 cyc=44465426 +1 W reg=2 val=004A pc=3FA74D10 cyc=44465747 +1 W reg=2 val=0065 pc=3FA74DA0 cyc=44466068 +1 R reg=5 val=000F pc=3FA78E30 cyc=44466150 +1 R reg=1 val=008D pc=3FA78FD0 cyc=44466191 +1 W reg=2 val=0055 pc=3FA79010 cyc=44466198 +1 W reg=2 val=0075 pc=3FA790C0 cyc=44466521 +1 R reg=1 val=008D pc=3FA79AE0 cyc=44466591 +1 R reg=3 val=0000 pc=3FA79B00 cyc=44466596 +1 W reg=2 val=0002 pc=3FA79B60 cyc=44466605 +1 R reg=1 val=000C pc=3FA79BB0 cyc=44466613 +1 R reg=5 val=000D pc=3FA78E30 cyc=44466838 +1 W reg=2 val=005A pc=3FA79110 cyc=44466877 +1 W reg=2 val=007A pc=3FA74E60 cyc=44527158 +1 W reg=2 val=0050 pc=3FA74F10 cyc=44527481 +1 W reg=5 val=0000 pc=3FA78D10 cyc=44527649 +1 W reg=5 val=0001 pc=3FA78B40 cyc=44527781 +1 W reg=2 val=003A pc=3FA75570 cyc=44527906 +1 W reg=2 val=002A pc=3FA75620 cyc=44528229 +1 W reg=2 val=004A pc=3FA756D0 cyc=44528552 +1 W reg=2 val=001A pc=3FA75770 cyc=44528874 +1 W reg=1 val=0088 pc=3FA75870 cyc=44529204 +1 W reg=0 val=0010 pc=3FA75BC0 cyc=44532296 +1 W reg=0 val=0080 pc=3FA75CE0 cyc=44532633 +1 W reg=2 val=0005 pc=3FA75D90 cyc=44592754 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44592836 +1 R reg=1 val=000C pc=3FA79E50 cyc=44592917 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44592939 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44592961 +1 W reg=E val=0000 pc=3FA7A060 cyc=44592983 +1 W reg=F val=0000 pc=3FA7A110 cyc=44593005 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44593027 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44593061 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44595623 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44595704 +1 W reg=3 val=00FF pc=3FA79F00 cyc=44595726 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44595748 +1 W reg=E val=0000 pc=3FA7A060 cyc=44595770 +1 W reg=F val=0000 pc=3FA7A110 cyc=44595792 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44595814 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44595848 +1 R reg=5 val=0009 pc=3FA78E30 cyc=44608643 +1 R reg=1 val=0004 pc=3FA79E50 cyc=44608724 +1 W reg=3 val=00AA pc=3FA79F00 cyc=44608746 +1 R reg=1 val=0000 pc=3FA79FB0 cyc=44608768 +1 W reg=E val=0000 pc=3FA7A060 cyc=44608790 +1 W reg=F val=0000 pc=3FA7A110 cyc=44608812 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44608834 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44608868 +1 R reg=5 val=000B pc=3FA78E30 cyc=44626873 +1 R reg=1 val=0005 pc=3FA79E50 cyc=44626954 +1 W reg=3 val=0055 pc=3FA79F00 cyc=44626976 +1 R reg=1 val=0001 pc=3FA79FB0 cyc=44626998 +1 W reg=E val=0000 pc=3FA7A060 cyc=44627020 +1 W reg=F val=0000 pc=3FA7A110 cyc=44627042 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44627064 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44627098 +1 R reg=5 val=000B pc=3FA78E30 cyc=44645101 +1 R reg=1 val=0005 pc=3FA79E50 cyc=44645182 +1 W reg=3 val=0000 pc=3FA79F00 cyc=44645204 +1 R reg=1 val=0001 pc=3FA79FB0 cyc=44645226 +1 W reg=E val=0000 pc=3FA7A060 cyc=44645248 +1 W reg=F val=0000 pc=3FA7A110 cyc=44645270 +1 R reg=D val=00F0 pc=3FA7A1C0 cyc=44645292 +1 R reg=D val=00F0 pc=3FA7A320 cyc=44645326 +1 R reg=5 val=000B pc=3FA78E30 cyc=44663330 +1 R reg=1 val=0007 pc=3FA7A3C0 cyc=44663400 +1 W reg=2 val=0008 pc=3FA7A3F0 cyc=44663406 +1 R reg=1 val=0003 pc=3FA7A440 cyc=44663414 +1 W reg=2 val=000A pc=3FA76010 cyc=44715338 +1 R reg=1 val=0012 pc=3FA761B0 cyc=44715379 +1 R reg=3 val=000A pc=3FA76360 cyc=44715419 +1 R reg=1 val=0012 pc=3FA761B0 cyc=44715444 +1 R reg=3 val=001F pc=3FA76360 cyc=44715484 +1 R reg=1 val=0010 pc=3FA761B0 cyc=44715509 +1 R reg=3 val=000A pc=3FA76360 cyc=44715549 +1 W reg=5 val=0000 pc=3FA78D10 cyc=44715718 +1 W reg=5 val=0007 pc=3FA78B40 cyc=44715843 +1 W reg=5 val=0000 pc=3FA78D10 cyc=44716071 +1 W reg=2 val=00FA pc=3FA778D0 cyc=44716176 +1 W reg=2 val=00CA pc=3FA77990 cyc=44716502 +1 W reg=2 val=002A pc=3FA77A30 cyc=44716823 +1 W reg=2 val=003A pc=3FA77AD0 cyc=44717144 +1 W reg=2 val=004A pc=3FA77B70 cyc=44717465 +1 W reg=2 val=005A pc=3FA77C10 cyc=44717786 +1 W reg=2 val=001A pc=3FA77CA0 cyc=44718106 +1 W reg=A val=00CA pc=3FA77990 cyc=44718497 +1 W reg=A val=002A pc=3FA77A30 cyc=44718818 +1 W reg=A val=003A pc=3FA77AD0 cyc=44719139 +1 W reg=A val=004A pc=3FA77B70 cyc=44719460 +1 W reg=A val=005A pc=3FA77C10 cyc=44719781 +1 W reg=A val=001A pc=3FA77CA0 cyc=44720101 +1 W reg=F val=0080 pc=3FA850F0 cyc=44720336 +1 R reg=D val=00F0 pc=3F2045A0 cyc=44720804 +1 W reg=D val=0000 pc=3F208830 cyc=44995716 +1 W reg=F val=00FF pc=3F208880 cyc=44995721 diff --git a/harness/mame/mame_edits/mc68681.cpp.pre_latfit b/harness/mame/mame_edits/mc68681.cpp.pre_latfit new file mode 100644 index 0000000..0d254d5 --- /dev/null +++ b/harness/mame/mame_edits/mc68681.cpp.pre_latfit @@ -0,0 +1,1936 @@ +// license:BSD-3-Clause +// copyright-holders:Mariusz Wojcieszek, R. Belmont, Joseph Zatarski +/* + 2681 DUART + 68681 DUART + 28C94 QUART + 68340 serial module + XR68C681 DUART (backwards compatible with 68681 with some improvements) + + Written by Mariusz Wojcieszek + Updated by Jonathan Gevaryahu AKA Lord Nightmare + Improved interrupt handling by R. Belmont + Rewrite and modernization in progress by R. Belmont + Addition of the duart compatible 68340 serial module support by Edstrom + Support for the Exar XR68C681 by Joseph Zatarski (July of 2018) + Support for Freescale/NXP ColdFire UART module by NaokiS (June 2025) + + The main incompatibility between the 2681 and 68681 (Signetics and Motorola each + manufactured both versions of the chip) is that the 68681 has a R/W input and + generates a 68000-compatible DTACK signal, instead of using generic RD and WR + strobes as the 2681 does. The 68681 also adds a programmable interrupt vector, + with an IACK input replacing IP6. + + The command register addresses should never be read from. Doing so may place + the baud rate generator into a test mode which drives the parallel outputs with + internal counters and causes serial ports to operate at uncontrollable rates. + + Exar XR68C681 + + The XR68C681 is an improvement upon the MC68681 which supports more baud + rates, adds an additional MISR (masked ISR) register, and adds a low-power + standby mode. There may be other differences, but these are the most + notable. + + The extra baud rates are implemented by an 'X' bit for each channel. The X + bit chooses between two baud rate tables, in addition to the ACR[7] bit. + The X bit is changed by additional commands that are written to CRA and CRB. + + The MISR is a read only register that takes the place of the 'BRG Test' + register on the MC68681. + + The low power standby mode is entered and left by a command written to CRA + or CRB registers. Writing the commands to either register affects the whole + DUART, not just one channel. Resetting the DUART also leaves low power mode. + + On the ColdFire MCF5206e, the UART modules are essentially just a pair of + MC68681s with only the A port visible and no counter/timer. The ACR on the + coldfire uarts shoud be updated to reflect this. Additionally, the + Baud Rate Generator prescaler reg should be used to set the baud. +*/ + +#include "emu.h" +#include "mc68681.h" + +#include + +//#define VERBOSE 1 +//#define LOG_OUTPUT_FUNC printf +#include "logmacro.h" + + +static const char *const duart68681_reg_read_names[0x10] = +{ + "MRA", "SRA", "BRG Test", "RHRA", "IPCR", "ISR", "CTU", "CTL", "MRB", "SRB", "1X/16X Test", "RHRB", "IVR", "Input Ports", "Start Counter", "Stop Counter" +}; + +static const char *const duart68681_reg_write_names[0x10] = +{ + "MRA", "CSRA", "CRA", "THRA", "ACR", "IMR", "CTUR", "CTLR", "MRB", "CSRB", "CRB", "THRB", "IVR", "OPCR", "Set OP Bits", "Reset OP Bits" +}; + +static const char *const mcf5206e_duart_reg_read_names[0x10] = +{ + "UMR", "USR", "NO ACCESS", "URB", "UIPCR", "UISR", "UBG1", "UBG2", "NO ACCESS", "NO ACCESS", "NO ACCESS", "NO ACCESS", "UIVR", "UIP Input Ports", "NO ACCESS", "NO ACCESS" +}; + +static const char *const mcf5206e_duart_reg_write_names[0x10] = +{ + "UMR", "UCSR", "UCRA", "UTB", "UACR", "UIMR", "UBG1", "UBG2", "NO ACCESS", "NO ACCESS", "NO ACCESS", "NO ACCESS", "IVR", "NO ACCESS", "Set OP Bits", "Reset OP Bits" +}; + +static const int baud_rate_ACR_0[] = { 50, 110, 134, 200, 300, 600, 1200, 1050, 2400, 4800, 7200, 9600, 38400, 0, 0, 0 }; /* xr68c681 X=0 */ +static const int baud_rate_ACR_0_X_1[] = { 75, 110, 134, 150, 3600, 14400, 28800, 57600, 115200, 4800, 1800, 9600, 19200, 0, 0, 0 }; +static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000, 2400, 4800, 1800, 9600, 19200, 0, 0, 0 }; /* xr68c681 X=0 */ +static const int baud_rate_ACR_1_X_1[] = { 50, 110, 134, 200, 3600, 14400, 28800, 57600, 115200, 4800, 7200, 9600, 38400, 0, 0, 0 }; + +static const int baud_rate_ACR_0_340[] = { 50, 110, 134, 200, 300, 600, 1200, 1050, 2400, 4800, 7200, 9600, 38400, 76800, 0, 0 }; /* xr68c681 ACR:7=0 */ +static const int baud_rate_ACR_1_340[] = { 75, 110, 134, 150, 300, 600, 1200, 2000, 2400, 4800, 1800, 9600, 19200, 38400, 0, 0 }; /* xr68c681 ACR:7=1 */ + +#define INT_INPUT_PORT_CHANGE 0x80 +#define INT_DELTA_BREAK_B 0x40 +#define INT_RXRDY_FFULLB 0x20 +#define INT_TXRDYB 0x10 +#define INT_COUNTER_READY 0x08 +#define INT_DELTA_BREAK_A 0x04 +#define INT_RXRDY_FFULLA 0x02 +#define INT_TXRDYA 0x01 + +#define STATUS_RECEIVED_BREAK 0x80 +#define STATUS_FRAMING_ERROR 0x40 +#define STATUS_PARITY_ERROR 0x20 +#define STATUS_OVERRUN_ERROR 0x10 +#define STATUS_TRANSMITTER_EMPTY 0x08 +#define STATUS_TRANSMITTER_READY 0x04 +#define STATUS_FIFO_FULL 0x02 +#define STATUS_RECEIVER_READY 0x01 + +#define MODE_RX_INT_SELECT_BIT 0x40 +#define MODE_BLOCK_ERROR 0x20 + +#define CHANA_TAG "cha" +#define CHANB_TAG "chb" +#define CHANC_TAG "chc" +#define CHAND_TAG "chd" + +// device type definition +DEFINE_DEVICE_TYPE(SCN2681, scn2681_device, "scn2681", "SCN2681 DUART") +DEFINE_DEVICE_TYPE(MC68681, mc68681_device, "mc68681", "MC68681 DUART") +DEFINE_DEVICE_TYPE(MCF5206E_UART, mcf5206e_uart_device, "mcf5206euart", "MCF5206e UART") +DEFINE_DEVICE_TYPE(SC28C94, sc28c94_device, "sc28c94", "SC28C94 QUART") +DEFINE_DEVICE_TYPE(MC68340_DUART, mc68340_duart_device, "mc68340duart", "MC68340 DUART") +DEFINE_DEVICE_TYPE(XR68C681, xr68c681_device, "xr68c681", "XR68C681 DUART") +DEFINE_DEVICE_TYPE(DUART_CHANNEL, duart_channel, "duart_channel", "DUART channel") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +duart_base_device::duart_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + m_chanA(*this, CHANA_TAG), + m_chanB(*this, CHANB_TAG), + m_chanC(*this, CHANC_TAG), + m_chanD(*this, CHAND_TAG), + write_irq(*this), + write_a_tx(*this), + write_b_tx(*this), + write_c_tx(*this), + write_d_tx(*this), + read_inport(*this, 0), + write_outport(*this), + ip3clk(0), + ip4clk(0), + ip5clk(0), + ip6clk(0), + ACR(0), + IP_last_state(0) +{ +} + +scn2681_device::scn2681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, SCN2681, tag, owner, clock) +{ +} + +mc68681_device::mc68681_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, type, tag, owner, clock) + , m_read_vector(false) +{ +} + +mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mc68681_device(mconfig, MC68681, tag, owner, clock) +{ +} + +mcf5206e_uart_device::mcf5206e_uart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, type, tag, owner, clock) + , m_read_vector(false) +{ +} + +mcf5206e_uart_device::mcf5206e_uart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, MCF5206E_UART, tag, owner, clock) +{ +} + + +sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, SC28C94, tag, owner, clock) +{ +} + +//-------------------------------------------------------------------------------------------------------------------- +// The read and write methods are meant to catch all differences in the register model between 68681 and 68340 +// serial module. Eg some registers are (re)moved into the 68340 like the vector register. There are also no counter +// in the 68340. The CSR clock register is also different for the external clock modes. The implementation assumes +// that the code knows all of this and will not warn if those registers are accessed as it could be ported code. +// TODO: A lot of subtle differences and also detect misuse of unavailable registers as they should be ignored +//-------------------------------------------------------------------------------------------------------------------- +mc68340_duart_device::mc68340_duart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, type, tag, owner, clock) +{ +} + +mc68340_duart_device::mc68340_duart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mc68340_duart_device(mconfig, MC68340_DUART, tag, owner, clock) +{ +} + +xr68c681_device::xr68c681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mc68681_device(mconfig, XR68C681, tag, owner, clock) + , m_XTXA(false) + , m_XRXA(false) + , m_XTXB(false) + , m_XRXB(false) +{ +} + +//------------------------------------------------- +// set_clocks - configuration helper to set +// the external clocks +//------------------------------------------------- + +void duart_base_device::set_clocks(int clk3, int clk4, int clk5, int clk6) +{ + ip3clk = clk3; + ip4clk = clk4; + ip5clk = clk5; + ip6clk = clk6; +} + +/*------------------------------------------------- + device start callback +-------------------------------------------------*/ + +void duart_base_device::device_start() +{ + duart_timer = timer_alloc(FUNC(duart_base_device::duart_timer_callback), this); + + save_item(NAME(ACR)); + save_item(NAME(IMR)); + save_item(NAME(ISR)); + save_item(NAME(OPCR)); + save_item(NAME(OPR)); + save_item(NAME(CTR)); + save_item(NAME(IPCR)); + save_item(NAME(IP_last_state)); + save_item(NAME(half_period)); + save_item(NAME(m_irq_state)); +} + +void mc68681_device::device_start() +{ + duart_base_device::device_start(); + + save_item(NAME(m_read_vector)); + save_item(NAME(IVR)); +} + +void mcf5206e_uart_device::device_start() +{ + duart_base_device::device_start(); + + save_item(NAME(m_read_vector)); + save_item(NAME(IVR)); + save_item(NAME(UBG)); +} + +void xr68c681_device::device_start() +{ + mc68681_device::device_start(); + + save_item(NAME(m_XTXA)); + save_item(NAME(m_XRXA)); + save_item(NAME(m_XTXB)); + save_item(NAME(m_XRXB)); +} + +/*------------------------------------------------- + device reset callback +-------------------------------------------------*/ + +void duart_base_device::device_reset() +{ + ACR = 0; /* Interrupt Vector Register */ + IMR = 0; /* Interrupt Mask Register */ + ISR = 0; /* Interrupt Status Register */ + OPCR = 0; /* Output Port Conf. Register */ + OPR = 0; /* Output Port Register */ + CTR.d = 0; /* Counter/Timer Preset Value */ + // "reset clears internal registers (SRA, SRB, IMR, ISR, OPR, OPCR) puts OP0-7 in the high state, stops the counter/timer, and puts channels a/b in the inactive state" + IPCR = 0; + + m_irq_state = false; + write_irq(CLEAR_LINE); + write_outport(OPR ^ 0xff); +} + +void mc68681_device::device_reset() +{ + duart_base_device::device_reset(); + + IVR = 0x0f; /* Interrupt Vector Register */ + m_read_vector = false; +} + +void mcf5206e_uart_device::device_reset() +{ + duart_base_device::device_reset(); + + IVR = 0x0f; /* Interrupt Vector Register */ + UBG = 0x00; /* UART Baud Rate Generator Register */ + m_read_vector = false; +} + +void xr68c681_device::device_reset() +{ + mc68681_device::device_reset(); + + m_XTXA = m_XRXA = m_XTXB = m_XRXB = false; +} + +void duart_base_device::device_add_mconfig(machine_config &config) +{ + DUART_CHANNEL(config, CHANA_TAG); + DUART_CHANNEL(config, CHANB_TAG); +} + +void sc28c94_device::device_add_mconfig(machine_config &config) +{ + DUART_CHANNEL(config, CHANA_TAG); + DUART_CHANNEL(config, CHANB_TAG); + DUART_CHANNEL(config, CHANC_TAG); + DUART_CHANNEL(config, CHAND_TAG); +} + +void mc68340_duart_device::device_add_mconfig(machine_config &config) +{ + DUART_CHANNEL(config, CHANA_TAG); + DUART_CHANNEL(config, CHANB_TAG); +} + +void mcf5206e_uart_device::device_add_mconfig(machine_config &config) +{ + DUART_CHANNEL(config, CHANA_TAG); + DUART_CHANNEL(config, CHANB_TAG); +} + +void duart_base_device::update_interrupts() +{ + /* update SR state and update interrupt ISR state for the following bits: + SRn: bits 7-4: handled elsewhere. + SRn: bit 3 (TxEMTn) (we can assume since we're not actually emulating the delay/timing of sending bits, that as long as TxRDYn is set, TxEMTn is also set since the transmit byte has 'already happened', therefore TxEMTn is always 1 assuming tx is enabled on channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined) + SRn: bit 2 (TxRDYn) (we COULD assume since we're not emulating delay and timing output, that as long as tx is enabled on channel n, TxRDY is 1 for channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined; however, tx_ready is already nicely handled for us elsewhere, so we can use that instead for now, though we may need to retool that code as well) + SRn: bit 1 (FFULLn) (this bit we actually emulate; if the receive fifo for channel n is full, this bit is 1, otherwise it is 0. the receive fifo should be three words long.) + SRn: bit 0 (RxRDYn) (this bit we also emulate; the bit is always asserted if the receive fifo is not empty) + ISR: bit 7: Input Port change; this should be handled elsewhere, on the input port handler + ISR: bit 6: Delta Break B; this should be handled elsewhere, on the data receive handler + ISR: bit 5: RxRDYB/FFULLB: this is handled here; depending on whether MSR1B bit 6 is 0 or 1, this bit holds the state of SRB bit 0 or bit 1 respectively + ISR: bit 4: TxRDYB: this is handled here; it mirrors SRB bit 2 + ISR: bit 3: Counter ready; this should be handled by the timer generator + ISR: bit 2: Delta Break A; this should be handled elsewhere, on the data receive handler + ISR: bit 1: RxRDYA/FFULLA: this is handled here; depending on whether MSR1A bit 6 is 0 or 1, this bit holds the state of SRA bit 0 or bit 1 respectively + ISR: bit 0: TxRDYA: this is handled here; it mirrors SRA bit 2 + */ + if ((ISR & IMR) != 0) + { + if (!m_irq_state) + { + m_irq_state = true; + LOG("Interrupt line active (IMR & ISR = %02X)\n", (ISR & IMR)); + write_irq(ASSERT_LINE); + } + } + else + { + if (m_irq_state) + { + m_irq_state = false; + LOG("Interrupt line not active (IMR & ISR = %02X)\n", ISR & IMR); + write_irq(CLEAR_LINE); + } + } + if (OPCR & 0xf0) + { + if (BIT(OPCR, 4)) + { + if (BIT(ISR, 1)) + OPR |= 0x10; + else + OPR &= ~0x10; + } + if (BIT(OPCR, 5)) + { + if (BIT(ISR, 5)) + OPR |= 0x20; + else + OPR &= ~0x20; + } + if (BIT(OPCR, 6)) + { + if (BIT(ISR, 0)) + OPR |= 0x40; + else + OPR &= ~0x40; + } + if (BIT(OPCR, 7)) + { + if (BIT(ISR, 4)) + OPR |= 0x80; + else + OPR &= ~0x80; + } + write_outport(OPR ^ 0xff); + } +} + +void mc68681_device::update_interrupts() +{ + duart_base_device::update_interrupts(); + + if (!irq_pending()) + m_read_vector = false; // clear IACK too +} + +uint8_t mc68681_device::get_irq_vector() +{ + if (!machine().side_effects_disabled()) + m_read_vector = true; + + return IVR; +} + +void mcf5206e_uart_device::update_interrupts() +{ + duart_base_device::update_interrupts(); + + if (!irq_pending()) + m_read_vector = false; // clear IACK too +} + +uint8_t mcf5206e_uart_device::get_irq_vector() +{ + if (!machine().side_effects_disabled()) + m_read_vector = true; + + return IVR; +} + +uint32_t duart_base_device::get_ct_rate() +{ + uint32_t rate = 0; + + if (ACR & 0x40) + { + // Timer mode + switch ((ACR >> 4) & 3) + { + case 0: // IP2 + case 1: // IP2 / 16 + //logerror( "68681 (%s): Unhandled timer/counter mode %d\n", duart68681->tag(), (duart68681->ACR >> 4) & 3); + rate = clock(); + break; + case 2: // X1/CLK + rate = clock(); + break; + case 3: // X1/CLK / 16 + rate = clock() / 16; + break; + } + } + else + { + // Counter mode + switch ((ACR >> 4) & 3) + { + case 0: // IP2 + //logerror( "68681 (%s): Unhandled timer/counter mode %d\n", device->tag(), (duart68681->ACR >> 4) & 3); + rate = clock(); + break; + case 1: // TxCA + rate = m_chanA->get_tx_rate(); + break; + case 2: // TxCB + rate = m_chanB->get_tx_rate(); + break; + case 3: // X1/CLK / 16 + rate = clock() / 16; + break; + } + } + + return rate; +} + +uint16_t duart_base_device::get_ct_count() +{ + uint32_t clock = get_ct_rate(); + return duart_timer->remaining().as_ticks(clock); +} + +void duart_base_device::start_ct(int count) +{ + uint32_t clock = get_ct_rate(); + duart_timer->adjust(attotime::from_ticks(count, clock), 0); +} + +TIMER_CALLBACK_MEMBER(duart_base_device::duart_timer_callback) +{ + if (ACR & 0x40) + { + // Timer mode + half_period ^= 1; + + // timer output to bit 3? + if ((OPCR & 0xc) == 0x4) + { + OPR ^= 0x8; + write_outport(OPR ^ 0xff); + } + + // timer driving any serial channels? + uint8_t csr = m_chanA->get_chan_CSR(); + + if ((csr & 0x0f) == 0x0d) // tx is timer driven + { + m_chanA->tx_16x_clock_w(half_period); + } + if ((csr & 0xf0) == 0xd0) // rx is timer driven + { + m_chanA->rx_16x_clock_w(half_period); + } + + csr = m_chanB->get_chan_CSR(); + if ((csr & 0x0f) == 0x0d) // tx is timer driven + { + m_chanB->tx_16x_clock_w(half_period); + } + if ((csr & 0xf0) == 0xd0) // rx is timer driven + { + m_chanB->rx_16x_clock_w(half_period); + } + + if (!half_period) + set_ISR_bits(INT_COUNTER_READY); + + int count = std::max(CTR.w.l, uint16_t(1)); + start_ct(count); + } + else + { + // assert OP3 counter ready + if ((OPCR & 0xc) == 0x4) + OPR |= 0x8; + + // Counter mode + set_ISR_bits(INT_COUNTER_READY); + start_ct(0xffff); + } + +} + +uint8_t mc68681_device::read(offs_t offset) +{ + if (offset == 0x0c) + return IVR; + + uint8_t r = duart_base_device::read(offset); + + if (offset == 0x0d) + { + // bit 6 is /IACK (note the active-low) + if (m_read_vector) + r &= ~0x40; + else + r |= 0x40; + } + + return r; +} + +// TODO: move me out of here, it's one channel per UART not 2 +uint8_t mcf5206e_uart_device::read(offs_t offset) +{ + uint8_t r = 0xff; + + switch (offset) + { + case 0x00: /* UMR1/UMR2 */ + case 0x01: /* USR */ + case 0x03: /* URBA Receive Buffer Register */ + case 0x04: /* UIPCR */ + case 0x05: /* UISR */ + case 0x0d: /* UIP */ + r = duart_base_device::read(offset); + break; + + case 0x06: /* UBG Baud Generator Prescale MSB */ + LOG("%s: Reading mcf5206e (%s) reg %x (%s)\n", this->machine().describe_context(), tag(), offset, mcf5206e_duart_reg_read_names[offset]); + r = (UBG & 0xFF00) >> 8; + break; + case 0x07: /* UBG Baud Generator Prescale LSB */ + LOG("%s: Reading mcf5206e (%s) reg %x (%s)\n", this->machine().describe_context(), tag(), offset, mcf5206e_duart_reg_read_names[offset]); + r = (UBG & 0x00FF); + break; + + case 0x0c: /* UIVR */ + LOG("%s: Reading mcf5206e (%s) reg %x (%s)\n", this->machine().describe_context(), tag(), offset, mcf5206e_duart_reg_read_names[offset]); + r = IVR; + break; + + default: + LOG("Reading unhandled mcf5206e reg %x\n", offset); + break; + } + LOG("returned %02x\n", r); + + return r; +} + +uint8_t mc68340_duart_device::read(offs_t offset) +{ + uint8_t r = 0; + + switch (offset) + { + case 0x00: /* MR1A - does not share register address with MR2A */ + r = m_chanA->read_MR1(); + break; + case 0x08: /* MR1B - does not share register address with MR2B */ + r = m_chanB->read_MR1(); + break; + case 0x10: /* MR2A - does not share register address with MR1A */ + r = m_chanA->read_MR2(); + break; + case 0x11: /* MR2B - does not share register address with MR1B */ + r = m_chanB->read_MR2(); + break; + default: + r = duart_base_device::read(offset); + } + return r; +} + +uint8_t sc28c94_device::read(offs_t offset) +{ + uint8_t r = 0; + offset &= 0x1f; + + if (offset < 0x10) + { + return duart_base_device::read(offset); + } + + switch (offset) + { + case 0x10: /* MR1A/MR2C */ + case 0x11: /* SRC */ + case 0x13: /* Rx Holding Register C */ + r = m_chanC->read_chan_reg(offset & 3); + break; + + case 0x18: /* MR1D/MR2D */ + case 0x19: /* SRD */ + case 0x1b: /* RHRD */ + r = m_chanD->read_chan_reg(offset & 3); + break; + } + + return r; +} + +uint8_t xr68c681_device::read(offs_t offset) +{ + if (offset == 0x02) + { + LOG("Reading XR68C681 (%s) reg 0x02 (MISR)\n", tag()); + return ISR & IMR; + } + else + return mc68681_device::read(offset); +} + +uint8_t duart_base_device::read(offs_t offset) +{ + uint8_t r = 0xff; + + offset &= 0xf; + + LOG("%s: Reading 68681 (%s) reg %x (%s)\n", this->machine().describe_context(), tag(), offset, duart68681_reg_read_names[offset]); + + switch (offset) + { + case 0x00: /* MR1A/MR2A */ + case 0x01: /* SRA */ + case 0x03: /* Rx Holding Register A */ + r = m_chanA->read_chan_reg(offset & 3); + break; + + case 0x04: /* IPCR */ + r = IPCR; + + // reading this clears all the input change bits + IPCR &= 0x0f; + clear_ISR_bits(INT_INPUT_PORT_CHANGE); + break; + + case 0x05: /* ISR */ + r = ISR; + break; + + case 0x06: /* CUR */ + r = get_ct_count() >> 8; + break; + + case 0x07: /* CLR */ + r = get_ct_count() & 0xff; + break; + + case 0x08: /* MR1B/MR2B */ + case 0x09: /* SRB */ + case 0x0b: /* RHRB */ + r = m_chanB->read_chan_reg(offset & 3); + break; + + case 0x0a: /* 1X/16X Test */ + r = 0x61; // the old 68681 returned this and it makes Apollo happy + break; + + case 0x0d: /* IP */ + if (!read_inport.isunset()) + { + r = read_inport(); // TODO: go away + } + else + { + r = IP_last_state; + } + + r |= 0x80; // bit 7 is always set + break; + + case 0x0e: /* Start counter command */ + { + if (ACR & 0x40) + { + // Reset the timer + half_period = 0; + } + + int count = std::max(CTR.w.l, uint16_t(1)); + start_ct(count); + break; + } + + case 0x0f: /* Stop counter command */ + + // Stop the counter only + if (!(ACR & 0x40)) + { + duart_timer->enable(false); + + // clear OP3 counter ready + if ((OPCR & 0xc) == 0x4) + OPR &= ~0x8; + } + + clear_ISR_bits(INT_COUNTER_READY); + break; + + default: + LOG("Reading unhandled 68681 reg %x\n", offset); + break; + } + LOG("returned %02x\n", r); + + return r; +} + +void mc68681_device::write(offs_t offset, uint8_t data) +{ + if (offset == 0x0c) + IVR = data; + else + duart_base_device::write(offset, data); +} + +void mcf5206e_uart_device::write(offs_t offset, uint8_t data) +{ + switch (offset) + { + case 0x00: /* UMR */ + case 0x01: /* UCSR */ + case 0x03: /* UTB */ + case 0x04: /* ACR */ // <-- TODO: This needs changing as ACR on ColdFire only handles interrupt enable for CTS + case 0x05: /* IMR */ + case 0x0e: /* Set Output Port (RTS) Bit */ + case 0x0f: /* Reset Output Port (RTS) Bit */ + duart_base_device::write(offset, data); + break; + + case 0x02: /* UCR */ + // monomach uses 0x02 0x03 0x01 0x08 0x0c 0x04 at POST + // 3 and c are "Do Not Use" according to datasheet + // (already a good reason about not deriving from here ...) + if (data != 0xc && data != 0x3) + duart_base_device::write(offset, data); + break; + + case 0x06: /* UBG1 */ + LOG("%s: Writing mcf5206e (%s) reg %x (%s) with %02x\n", this->machine().describe_context(), tag(), offset, mcf5206e_duart_reg_write_names[offset], data); + UBG = (UBG & 0x00ff) | (data << 8); + break; + case 0x07: /* UBG2 */ + LOG("%s: Writing mcf5206e (%s) reg %x (%s) with %02x\n", this->machine().describe_context(), tag(), offset, mcf5206e_duart_reg_write_names[offset], data); + UBG = (UBG & 0xff00) | data; + m_chanA->baud_updated(); + m_chanA->update_interrupts(); + break; + + case 0x0c: /* UIVR */ + LOG("%s: Writing mcf5206e (%s) reg %x (%s) with %02x\n", this->machine().describe_context(), tag(), offset, mcf5206e_duart_reg_write_names[offset], data); + IVR = data; + break; + + default: break; + } +} + +void mc68340_duart_device::write(offs_t offset, uint8_t data) +{ + //printf("Duart write %02x -> %02x\n", data, offset); + + switch(offset) + { + case 0x00: /* MR1A - does not share register address with MR2A */ + m_chanA->write_MR1(data); + break; + case 0x08: /* MR1B - does not share register address with MR2B */ + m_chanB->write_MR1(data); + break; + case 0x10: /* MR2A - does not share register address with MR1A */ + m_chanA->write_MR2(data); + break; + case 0x11: /* MR2B - does not share register address with MR1B */ + m_chanB->write_MR2(data); + break; + default: + duart_base_device::write(offset, data); + } +} + +void sc28c94_device::write(offs_t offset, uint8_t data) +{ + offset &= 0x1f; + + if (offset < 0x10) + { + duart_base_device::write(offset, data); + } + + switch (offset) + { + case 0x10: /* MRC */ + case 0x11: /* CSRC */ + case 0x12: /* CRC */ + case 0x13: /* THRC */ + m_chanC->write_chan_reg(offset&3, data); + break; + + case 0x18: /* MRC */ + case 0x19: /* CSRC */ + case 0x1a: /* CRC */ + case 0x1b: /* THRC */ + m_chanD->write_chan_reg(offset&3, data); + break; + } +} + +void xr68c681_device::write(offs_t offset, uint8_t data) +{ + if (offset == 0x02) /* CRA */ + switch (data >> 4) + { + case 0x08: /* set RX extend bit */ + m_XRXA = true; + m_chanA->baud_updated(); + data &= 0x0f; /* disable command before we send it off to 68681 */ + break; + + case 0x09: /* clear RX extend bit */ + m_XRXA = false; + m_chanA->baud_updated(); + data &= 0x0f; + break; + + case 0x0a: /* set TX extend bit */ + m_XTXA = true; + m_chanA->baud_updated(); + data &= 0x0f; + break; + + case 0x0b: /* clear TX extend bit */ + m_XTXA = false; + m_chanA->baud_updated(); + data &= 0x0f; + break; + + case 0x0c: /* enter low power mode TODO: unimplemented */ + case 0x0d: /* leave low power mode */ + case 0x0e: /* reserved */ + case 0x0f: /* reserved */ + data &= 0x0f; + break; + } + + else if (offset == 0x0a) /* CRB */ + switch (data >> 4) + { + case 0x08: /* set RX extend bit */ + m_XRXB = true; + m_chanB->baud_updated(); + data &= 0x0f; + break; + + case 0x09: /* clear RX extend bit */ + m_XRXB = false; + m_chanB->baud_updated(); + data &= 0x0f; + break; + + case 0x0a: /* set TX extend bit */ + m_XTXB = true; + m_chanB->baud_updated(); + data &= 0x0f; + break; + + case 0x0b: /* clear TX extend bit */ + m_XTXB = false; + m_chanB->baud_updated(); + data &= 0x0f; + break; + + case 0x0c: /* enter low power mode TODO: unimplemented */ + case 0x0d: /* leave low power mode */ + case 0x0e: /* reserved */ + case 0x0f: /* reserved */ + data &= 0x0f; + break; + } + + mc68681_device::write(offset, data); /* pass on 68681 command */ +} + +void duart_base_device::write(offs_t offset, uint8_t data) +{ + offset &= 0x0f; + LOG("%s: Writing 68681 (%s) reg %x (%s) with %02x\n", this->machine().describe_context(), tag(), offset, duart68681_reg_write_names[offset], data); + switch (offset) + { + case 0x00: /* MRA */ + case 0x01: /* CSRA */ + case 0x02: /* CRA */ + case 0x03: /* THRA */ + m_chanA->write_chan_reg(offset&3, data); + break; + + case 0x04: /* ACR */ + { + uint8_t old_acr = ACR; + ACR = data; + + // bits 6-4: Counter/Timer Mode And Clock Source Select + // bits 3-0: IP3-0 Change-Of-State Interrupt Enable + if ((old_acr ^ data) & 0x40) + { + if (data & 0x40) + { + // Entering timer mode + uint16_t count = std::max(CTR.w.l, uint16_t(1)); + half_period = 0; + + start_ct(count); + } + else + { + // Leaving timer mode (TODO: is this correct?) + duart_timer->adjust(attotime::never); + } + } + + // check for pending input port delta interrupts + if ((((IPCR>>4) & data) & 0x0f) != 0) + set_ISR_bits(INT_INPUT_PORT_CHANGE); + + m_chanA->baud_updated(); + m_chanB->baud_updated(); + m_chanA->update_interrupts(); + m_chanB->update_interrupts(); + break; + } + case 0x05: /* IMR */ + IMR = data; + update_interrupts(); + break; + + case 0x06: /* CTUR */ + CTR.b.h = data; + break; + + case 0x07: /* CTLR */ + CTR.b.l = data; + break; + + case 0x08: /* MRB */ + case 0x09: /* CSRB */ + case 0x0a: /* CRB */ + case 0x0b: /* THRB */ + m_chanB->write_chan_reg(offset&3, data); + break; + + case 0x0d: /* OPCR */ + if (((data & 0xf) != 0x00) && ((data & 0xc) != 0x4)) + logerror("68681 (%s): Unhandled OPCR value: %02x\n", tag(), data); + OPCR = data; + break; + + case 0x0e: /* Set Output Port Bits */ + OPR |= data; + write_outport(OPR ^ 0xff); + break; + + case 0x0f: /* Reset Output Port Bits */ + OPR &= ~data; + write_outport(OPR ^ 0xff); + break; + } +} + +void duart_base_device::ip0_w(int state) +{ + uint8_t newIP = (IP_last_state & ~0x01) | ((state == ASSERT_LINE) ? 1 : 0); + + if (newIP != IP_last_state) + { + IPCR &= ~0x0f; + IPCR |= (newIP & 0x0f); + IPCR |= 0x10; + + if (ACR & 1) + set_ISR_bits(INT_INPUT_PORT_CHANGE); + } + + IP_last_state = newIP; +} + +void duart_base_device::ip1_w(int state) +{ + uint8_t newIP = (IP_last_state & ~0x02) | ((state == ASSERT_LINE) ? 2 : 0); + + if (newIP != IP_last_state) + { + IPCR &= ~0x0f; + IPCR |= (newIP & 0x0f); + IPCR |= 0x20; + + if (ACR & 2) + set_ISR_bits(INT_INPUT_PORT_CHANGE); + } + + IP_last_state = newIP; +} + +void duart_base_device::ip2_w(int state) +{ + uint8_t newIP = (IP_last_state & ~0x04) | ((state == ASSERT_LINE) ? 4 : 0); + + if (newIP != IP_last_state) + { + IPCR &= ~0x0f; + IPCR |= (newIP & 0x0f); + IPCR |= 0x40; + + if (ACR & 4) + set_ISR_bits(INT_INPUT_PORT_CHANGE); + } + + IP_last_state = newIP; +} + +void duart_base_device::ip3_w(int state) +{ + uint8_t newIP = (IP_last_state & ~0x08) | ((state == ASSERT_LINE) ? 8 : 0); + + if (newIP != IP_last_state) + { + IPCR &= ~0x0f; + IPCR |= (newIP & 0x0f); + IPCR |= 0x80; + + if (ACR & 8) + set_ISR_bits(INT_INPUT_PORT_CHANGE); + } + + IP_last_state = newIP; +} + +void duart_base_device::ip4_w(int state) +{ + uint8_t newIP = (IP_last_state & ~0x10) | ((state == ASSERT_LINE) ? 0x10 : 0); +// TODO: special mode for ip4 (Ch. A Rx clock) + IP_last_state = newIP; +} + +void duart_base_device::ip5_w(int state) +{ + uint8_t newIP = (IP_last_state & ~0x20) | ((state == ASSERT_LINE) ? 0x20 : 0); +// TODO: special mode for ip5 (Ch. B Tx clock) + IP_last_state = newIP; +} + +void duart_base_device::ip6_w(int state) +{ + uint8_t newIP = (IP_last_state & ~0x40) | ((state == ASSERT_LINE) ? 0x40 : 0); +// TODO: special mode for ip6 (Ch. B Rx clock) + IP_last_state = newIP; +} + +duart_channel *duart_base_device::get_channel(int chan) +{ + if (chan == 0) + { + return m_chanA; + } + + return m_chanB; +} + +int duart_base_device::calc_baud(int ch, bool rx, uint8_t data) +{ + int baud_rate; + + if (BIT(ACR, 7) == 0) + { + baud_rate = baud_rate_ACR_0[data & 0x0f]; + + if (ch == 0) + { + if ((data & 0xf) == 0xe) + { + baud_rate = ip3clk/16; + } + else if ((data & 0xf) == 0xf) + { + baud_rate = ip3clk; + } + } + else if (ch == 1) + { + if ((data & 0xf) == 0xe) + { + baud_rate = ip5clk/16; + } + else if ((data & 0xf) == 0xf) + { + baud_rate = ip5clk; + } + } + } + else + { + baud_rate = baud_rate_ACR_1[data & 0x0f]; + } + + if ((baud_rate == 0) && ((data & 0xf) != 0xd)) + { + LOG("Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data); + } + + //printf("%s ch %d setting baud to %d\n", tag(), ch, baud_rate); + return baud_rate; +} + +int mc68340_duart_device::calc_baud(int ch, bool rx, uint8_t data) +{ + int baud_rate; + + if (BIT(ACR, 7) == 0) + { + baud_rate = baud_rate_ACR_0_340[data & 0x0f]; + + if (ch == 0) + { + if ((data & 0xf) == 0xe) + { + baud_rate = ip3clk/16; + } + else if ((data & 0xf) == 0xf) + { + baud_rate = ip3clk; + } + } + else if (ch == 1) + { + if ((data & 0xf) == 0xe) + { + baud_rate = ip5clk/16; + } + else if ((data & 0xf) == 0xf) + { + baud_rate = ip5clk; + } + } + } + else + { + baud_rate = baud_rate_ACR_1_340[data & 0x0f]; + + if (ch == 0) + { + if ((data & 0xf) == 0xe) + { + baud_rate = ip3clk/16; + } + else if ((data & 0xf) == 0xf) + { + baud_rate = ip3clk; + } + } + else if (ch == 1) + { + if ((data & 0xf) == 0xe) + { + baud_rate = ip5clk/16; + } + else if ((data & 0xf) == 0xf) + { + baud_rate = ip5clk; + } + } + } + + if ((baud_rate == 0) && ((data & 0xf) != 0xd)) + { + LOG("Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data); + } + + //printf("%s ch %d setting baud to %d\n", tag(), ch, baud_rate); + return baud_rate; +} + +int xr68c681_device::calc_baud(int ch, bool rx, uint8_t data) +{ + int baud_rate; + + + baud_rate = baud_rate_ACR_0[data & 0x0f]; + + if (ch == 0) + { + if ((data & 0x0f) == 0x0e) + baud_rate = ip3clk/16; + else if ((data & 0x0f) == 0x0f) + baud_rate = ip3clk; + else if ((rx && m_XRXA) || (!rx && m_XTXA)) /* X = 1 */ + baud_rate = BIT(ACR, 7) == 0 ? baud_rate_ACR_0_X_1[data & 0x0f] : baud_rate_ACR_1_X_1[data & 0x0f]; + else /* X = 0 */ + baud_rate = BIT(ACR, 7) == 0 ? baud_rate_ACR_0[data & 0x0f] : baud_rate_ACR_1[data & 0x0f]; + } + else if (ch == 1) + { + if ((data & 0x0f) == 0x0e) + baud_rate = ip5clk/16; + else if ((data & 0x0f) == 0x0f) + baud_rate = ip5clk; + else if ((rx && m_XRXB) || (!rx && m_XTXB)) /* X = 1 */ + baud_rate = BIT(ACR, 7) == 0 ? baud_rate_ACR_0_X_1[data & 0x0f] : baud_rate_ACR_1_X_1[data & 0x0f]; + else /* X = 0 */ + baud_rate = BIT(ACR, 7) == 0 ? baud_rate_ACR_0[data & 0x0f] : baud_rate_ACR_1[data & 0x0f]; + } + + if ((baud_rate == 0) && ((data & 0xf) != 0xd)) + { + LOG("Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data); + } + + //printf("%s ch %d setting baud to %d\n", tag(), ch, baud_rate); + return baud_rate; +} + +int mcf5206e_uart_device::calc_baud(int ch, bool rx, uint8_t data) +{ + int baud_rate = 0; + u16 ubg_temp = 1; + + if(UBG > 0) ubg_temp = UBG; + + switch (data & 0xf){ + case 0xe: baud_rate = ip3clk/16; break; + case 0xf: baud_rate = ip3clk; break; + case 0xd: baud_rate = (this->clock()/32) / ubg_temp; break; + default: LOG("Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data); break; + } + + //printf("%s ch %d setting baud to %d\n", tag(), ch, baud_rate); + return baud_rate; +} + +void duart_base_device::clear_ISR_bits(int mask) +{ + if (ISR & mask) + { + ISR &= ~mask; + update_interrupts(); + } +} + +void duart_base_device::set_ISR_bits(int mask) +{ + if (!(ISR & mask)) + { + ISR |= mask; + update_interrupts(); + } +} + +// DUART channel class stuff + +duart_channel::duart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DUART_CHANNEL, tag, owner, clock) + , device_serial_interface(mconfig, *this) + , MR1(0) + , MR2(0) + , SR(0) + , rx_enabled(0) + , rx_fifo_num(0) + , m_rx_line(true) + , m_tx_data_in_buffer(false) + , m_tx_break(false) + , m_bits_transmitted(255) + , m_tx_enabled(false) +{ + std::fill_n(&rx_fifo[0], MC68681_RX_FIFO_SIZE + 1, 0); +} + +void duart_channel::device_start() +{ + m_uart = downcast(owner()); + m_ch = m_uart->get_ch(this); // get our channel number + + save_item(NAME(CR)); + save_item(NAME(CSR)); + save_item(NAME(MR1)); + save_item(NAME(MR2)); + save_item(NAME(MR_ptr)); + save_item(NAME(SR)); + save_item(NAME(rx_baud_rate)); + save_item(NAME(tx_baud_rate)); + save_item(NAME(rx_enabled)); + save_item(NAME(rx_fifo)); + save_item(NAME(rx_fifo_read_ptr)); + save_item(NAME(rx_fifo_write_ptr)); + save_item(NAME(rx_fifo_num)); + save_item(NAME(m_tx_data)); + save_item(NAME(m_tx_data_in_buffer)); + save_item(NAME(m_tx_break)); + save_item(NAME(m_bits_transmitted)); + save_item(NAME(m_tx_enabled)); + save_item(NAME(m_rx_line)); +} + +// VT1200 NOTE (local change, not upstream): the datasheet latches the overrun +// error "upon receipt of the start bit of the new (overrunning) character", +// i.e. while the FIFO is full and the previous character is still held in the +// receive shift register. MAME's rx_fifo_push() latches it only when that +// character is fully received, a whole character late. Watching the RxD line +// here reproduces the earlier latch time. Revert: delete this override, delete +// the m_rx_line member, and restore the device_serial_interface::rx_w calls in +// mc68681.h's rx_a_w/rx_b_w/rx_c_w/rx_d_w. +void duart_channel::rx_w(int state) +{ + if (state == 0 && m_rx_line && (rx_fifo_num == MC68681_RX_FIFO_SIZE + 1)) + { + SR |= STATUS_OVERRUN_ERROR; + update_interrupts(); + } + m_rx_line = (state != 0); + device_serial_interface::rx_w(state); +} + +void duart_channel::device_reset() +{ + write_CR(0x10); // reset MR + write_CR(0x20); // reset Rx + write_CR(0x30); // reset Tx + write_CR(0x40); // reset errors + + set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); + + tx_baud_rate = rx_baud_rate = 0; + CSR = 0; + m_tx_break = false; +} + +// serial device virtual overrides +void duart_channel::rcv_complete() +{ + receive_register_extract(); + + //printf("%s ch %d rcv complete\n", tag(), m_ch); + + if (rx_enabled || (MR2 & 0xc0) == 0x80) + { + uint8_t errors = 0; + if (is_receive_framing_error()) + errors |= STATUS_FRAMING_ERROR; + if (is_receive_parity_error()) + errors |= STATUS_PARITY_ERROR; + rx_fifo_push(get_received_char(), errors); + } +} + +void duart_channel::rx_fifo_push(uint8_t data, uint8_t errors) +{ + if (rx_fifo_num == (MC68681_RX_FIFO_SIZE + 1)) + { + logerror("68681: FIFO overflow\n"); + SR |= STATUS_OVERRUN_ERROR; + // In case of overrun the FIFO tail entry is overwritten + // Back rx_fifo_write_ptr up by one position + if (rx_fifo_write_ptr) + rx_fifo_write_ptr--; + else + rx_fifo_write_ptr = MC68681_RX_FIFO_SIZE; + } + + rx_fifo[rx_fifo_write_ptr++] = data | (errors << 8); + if (rx_fifo_write_ptr > MC68681_RX_FIFO_SIZE) + rx_fifo_write_ptr = 0; + + if (rx_fifo_num <= MC68681_RX_FIFO_SIZE) + { + rx_fifo_num++; + } + + if (rx_fifo_num == 1) + { + SR |= STATUS_RECEIVER_READY; + if (!(MR1 & MODE_BLOCK_ERROR)) + SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR); + SR |= errors; + } + if (rx_fifo_num == MC68681_RX_FIFO_SIZE) + SR |= STATUS_FIFO_FULL; + update_interrupts(); +} + +void duart_channel::tra_complete() +{ + // The transmit shift register has just emptied. If another character is + // waiting in the THR, transfer it to the shift register and assert TxRDY: + // per the datasheet the THR->shift transfer is where the TxRDY conditions + // are re-asserted, providing "one full character time of buffering". If the + // THR is empty the transmitter is now idle, so set TxEMT (TxRDY is already + // set from the previous transfer). + // + // Asserting TxRDY here, at the transfer -- rather than in the idle branch -- + // both prevents the transmitter from deadlocking when TxRDY would otherwise + // fail to re-assert on a CPU-write / final-bit-time race, and preserves the + // one-character buffering window that firmware polling or pipelining on TxRDY + // relies on. + if (m_tx_data_in_buffer) + { + transmit_register_setup(m_tx_data); + m_bits_transmitted = 0; + m_tx_data_in_buffer = false; + SR |= STATUS_TRANSMITTER_READY; + update_interrupts(); + } + else + { + SR |= STATUS_TRANSMITTER_EMPTY; + update_interrupts(); + } +} + +void duart_channel::tra_callback() +{ + // don't actually send in loopback mode + if ((MR2 & 0xc0) != 0x80) + { + int bit = transmit_register_get_data_bit(); + //printf("%s ch %d transmit %d\n", tag(), m_ch, bit); + if (m_ch == 0) + { + m_uart->write_a_tx(bit); + } + else if (m_ch == 1) + { + m_uart->write_b_tx(bit); + } + else if (m_ch == 2) + { + m_uart->write_c_tx(bit); + } + else if (m_ch == 3) + { + m_uart->write_d_tx(bit); + } + } + else + { + // loop back transmitted bit + rx_w(transmit_register_get_data_bit()); + } + + // TxRDY is not set until the end of start bit time. + // + // VT1200 NOTE: verified faithful to the fitted part (Signetics SCN2681 + // product specification, p.22 "Transmitter Disable Note": "TxRDY sets at + // the end of the 'start bit' time. It is during the start bit that the + // data in the transmit holding register is transferred to the transmit + // shift register."). An earlier local VT1200 edit asserted TxRDY at + // tra_complete() instead; that edit was REFUTED by this sentence (the + // citation it used, p.7, describes the THR->TSR transfer but says nothing + // about when TxRDY is set) and has been reverted. Do not re-apply it. + if (++m_bits_transmitted > 1 && !m_tx_data_in_buffer && m_tx_enabled) + { + SR |= STATUS_TRANSMITTER_READY; + update_interrupts(); + } +} + +void duart_channel::update_interrupts() +{ + // Handle the TxEMT and TxRDY bits based on mode + switch (MR2 & 0xc0) // what mode are we in? + { + case 0x00: // normal mode + break; + case 0x40: // automatic echo mode + SR &= ~STATUS_TRANSMITTER_READY; + break; + case 0x80: // local loopback mode + break; + case 0xc0: // remote loopback mode + SR &= ~STATUS_TRANSMITTER_READY; + break; + } + + // now handle the ISR bits + if (SR & STATUS_TRANSMITTER_READY) + { + if (m_ch == 0) + m_uart->set_ISR_bits(INT_TXRDYA); + else + m_uart->set_ISR_bits(INT_TXRDYB); + } + else + { + if (m_ch == 0) + m_uart->clear_ISR_bits(INT_TXRDYA); + else + m_uart->clear_ISR_bits(INT_TXRDYB); + } + //logerror("DEBUG: 68681 int check: before receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR); + if (MR1 & MODE_RX_INT_SELECT_BIT) + { + if (SR & STATUS_FIFO_FULL) + { + m_uart->set_ISR_bits((m_ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB); + } + else + { + m_uart->clear_ISR_bits((m_ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB); + } + } + else + { + if (SR & STATUS_RECEIVER_READY) + { + m_uart->set_ISR_bits((m_ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB); + } + else + { + m_uart->clear_ISR_bits((m_ch == 0) ? INT_RXRDY_FFULLA : INT_RXRDY_FFULLB); + } + } + + //logerror("DEBUG: 68681 int check: after receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR); +} + +uint8_t duart_channel::read_rx_fifo() +{ + uint8_t rv; + + //printf("read_rx_fifo: rx_fifo_num %d\n", rx_fifo_num); + + if (rx_fifo_num == 0) + { + LOG("68681 channel: rx fifo underflow\n"); + update_interrupts(); + return 0; + } + + rv = rx_fifo[rx_fifo_read_ptr++]; + if (rx_fifo_read_ptr > MC68681_RX_FIFO_SIZE) + { + rx_fifo_read_ptr = 0; + } + + rx_fifo_num--; + if (rx_fifo_num == (MC68681_RX_FIFO_SIZE - 1)) + { + SR &= ~STATUS_FIFO_FULL; + } + + if (!(MR1 & MODE_BLOCK_ERROR)) + SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR); + if (rx_fifo_num == 0) + SR &= ~STATUS_RECEIVER_READY; + else + SR |= rx_fifo[rx_fifo_read_ptr] >> 8; + update_interrupts(); + + //printf("Rx read %02x\n", rv); + + return rv; +} + +uint8_t duart_channel::read_chan_reg(int reg) +{ + uint8_t rv = 0xff; + + switch (reg) + { + case 0: // MR1/MR2 + if (MR_ptr == 0) + { + rv = MR1; + MR_ptr = 1; + } + else + { + rv = MR2; + } + break; + + case 1: // SRA + rv = SR; + break; + + case 2: // CSRA: reading this is prohibited + break; + + case 3: // Rx holding register A + rv = read_rx_fifo(); + break; + } + + return rv; +} + +void duart_channel::write_chan_reg(int reg, uint8_t data) +{ + switch (reg) + { + case 0x00: /* MRA */ + write_MR(data); + break; + + case 0x01: /* CSR */ + CSR = data; + tx_baud_rate = m_uart->calc_baud(m_ch, false, data & 0xf); + rx_baud_rate = m_uart->calc_baud(m_ch, true, (data>>4) & 0xf); + //printf("%s ch %d CSR %02x Tx baud %d Rx baud %d\n", tag(), m_ch, data, tx_baud_rate, rx_baud_rate); + set_rcv_rate(rx_baud_rate); + set_tra_rate(tx_baud_rate); + break; + + case 0x02: /* CR */ + write_CR(data); + break; + + case 0x03: /* THR */ + write_TX(data); + break; + } +} + +void duart_channel::write_MR(uint8_t data) +{ + if (MR_ptr == 0) + { + MR1 = data; + MR_ptr = 1; + } + else + { + MR2 = data; + } + recalc_framing(); + update_interrupts(); +} + +void duart_channel::recalc_framing() +{ + parity_t parity = PARITY_NONE; + switch ((MR1 >> 3) & 3) + { + case 0: // with parity + if (MR1 & 4) + parity = PARITY_ODD; + else + parity = PARITY_EVEN; + break; + + case 1: // force parity + if (MR1 & 4) + parity = PARITY_MARK; + else + parity = PARITY_SPACE; + break; + + case 2: // no parity + parity = PARITY_NONE; + break; + + case 3: // multidrop mode + // fatalerror("68681: multidrop parity not supported\n"); + // Apollo DEX CPU will test this; omit to abort the emulation + logerror("68681: multidrop parity not supported\n"); + break; + } + + stop_bits_t stopbits = STOP_BITS_0; + switch ((MR2 >> 2) & 3) + { + case 0: + case 1: + stopbits = STOP_BITS_1; + break; + + case 2: // "1.5 async, 2 sync" + stopbits = STOP_BITS_1_5; + break; + + case 3: + stopbits = STOP_BITS_2; + break; + } + + //printf("%s ch %d MR1 %02x MR2 %02x => %d bits / char, %d stop bits, parity %d\n", tag(), m_ch, MR1, MR2, (MR1 & 3)+5, stopbits, parity); + + set_data_frame(1, (MR1 & 3) + 5, parity, stopbits); +} + +void duart_channel::write_CR(uint8_t data) +{ + switch ((data >> 4) & 0x07) + { + case 0: /* No command */ + break; + case 1: /* Reset MR pointer. Causes the channel MR pointer to point to MR1 */ + MR_ptr = 0; + break; + case 2: /* Reset channel receiver (disable receiver and flush fifo) */ + rx_enabled = 0; + SR &= ~STATUS_RECEIVER_READY; + SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR); + SR &= ~STATUS_OVERRUN_ERROR; // is this correct? + rx_fifo_read_ptr = 0; + rx_fifo_write_ptr = 0; + rx_fifo_num = 0; + receive_register_reset(); + break; + case 3: /* Reset channel transmitter */ + SR &= ~(STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY); + if (m_ch == 0) + { + m_uart->write_a_tx(1); + m_uart->clear_ISR_bits(INT_TXRDYA); + } + else + { + m_uart->write_b_tx(1); + m_uart->clear_ISR_bits(INT_TXRDYB); + } + transmit_register_reset(); + m_bits_transmitted = 255; + m_tx_data_in_buffer = false; + m_tx_enabled = false; + break; + case 4: /* Reset Error Status */ + SR &= ~(STATUS_RECEIVED_BREAK | STATUS_FRAMING_ERROR | STATUS_PARITY_ERROR | STATUS_OVERRUN_ERROR); + break; + case 5: /* Reset Channel break change interrupt */ + if (m_ch == 0) + m_uart->clear_ISR_bits(INT_DELTA_BREAK_A); + else + m_uart->clear_ISR_bits(INT_DELTA_BREAK_B); + break; + case 6: /* Start Tx break */ + if (!m_tx_break) + { + m_tx_break = true; + if ((MR2 & 0xc0) == 0x80) + { + // Local loopback mode: set delta break in ISR, simulate break rx + if (m_ch == 0) + m_uart->set_ISR_bits(INT_DELTA_BREAK_A); + else + m_uart->set_ISR_bits(INT_DELTA_BREAK_B); + rx_fifo_push(0 , STATUS_RECEIVED_BREAK); + } + // TODO: Actually send break signal + } + break; + case 7: /* Stop tx break */ + if (m_tx_break) + { + m_tx_break = false; + if ((MR2 & 0xc0) == 0x80) + { + // Local loopback mode: set delta break in ISR + if (m_ch == 0) + m_uart->set_ISR_bits(INT_DELTA_BREAK_A); + else + m_uart->set_ISR_bits(INT_DELTA_BREAK_B); + } + } + break; + default: + LOG("68681: Unhandled command (%x) in CR%d\n", (data >> 4) & 0x07, m_ch); + break; + } + + if (BIT(data, 0)) + { + rx_enabled = 1; + } + if (BIT(data, 1)) + { + rx_enabled = 0; + SR &= ~STATUS_RECEIVER_READY; + } + + if (!BIT(CR, 2) && BIT(data, 2)) + { + SR |= STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY; + m_tx_data_in_buffer = false; + m_tx_enabled = true; + if (m_ch == 0) + m_uart->set_ISR_bits(INT_TXRDYA); + else + m_uart->set_ISR_bits(INT_TXRDYB); + } + if (BIT(data, 3)) + { + SR &= ~(STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY); + m_tx_data_in_buffer = false; + m_tx_enabled = false; + if (m_ch == 0) + m_uart->clear_ISR_bits(INT_TXRDYA); + else + m_uart->clear_ISR_bits(INT_TXRDYB); + } + + update_interrupts(); + CR = data; +} + +void duart_channel::write_TX(uint8_t data) +{ + if (!(SR & STATUS_TRANSMITTER_READY)) + { + logerror("write_tx transmitter not ready (data 0x%02x discarded)\n", data); + return; + } + + SR &= ~(STATUS_TRANSMITTER_READY | STATUS_TRANSMITTER_EMPTY); + if (!is_transmit_register_empty()) + { + m_tx_data = data; + m_tx_data_in_buffer = true; + } + else + { + transmit_register_setup(data); + m_bits_transmitted = 0; + } + + update_interrupts(); +} + +void duart_channel::baud_updated() +{ + write_chan_reg(1, CSR); +} + +uint8_t duart_channel::get_chan_CSR() +{ + return CSR; +} + +void duart_channel::tx_16x_clock_w(bool state) +{ + if (state) + { + m_tx_prescaler--; + if (m_tx_prescaler == 8) + { + tx_clock_w(true); + } + else if (m_tx_prescaler == 0) + { + m_tx_prescaler = 16; + tx_clock_w(false); + } + } +} + +void duart_channel::rx_16x_clock_w(bool state) +{ + if (!is_receive_register_synchronized()) + { + // Skip over the start bit once synchonization is achieved + m_rx_prescaler = 32; + rx_clock_w(true); + } + else if (state) + { + m_rx_prescaler--; + if (m_rx_prescaler == 8) + { + rx_clock_w(false); + } + else if (m_rx_prescaler == 0) + { + m_rx_prescaler = 16; + rx_clock_w(true); + } + } +}