mac_via.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. /*
  2. * QEMU m68k Macintosh VIA device support
  3. *
  4. * Copyright (c) 2011-2018 Laurent Vivier
  5. * Copyright (c) 2018 Mark Cave-Ayland
  6. *
  7. * Some parts from hw/misc/macio/cuda.c
  8. *
  9. * Copyright (c) 2004-2007 Fabrice Bellard
  10. * Copyright (c) 2007 Jocelyn Mayer
  11. *
  12. * some parts from linux-2.6.29, arch/m68k/include/asm/mac_via.h
  13. *
  14. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  15. * See the COPYING file in the top-level directory.
  16. */
  17. #include "qemu/osdep.h"
  18. #include "qemu-common.h"
  19. #include "migration/vmstate.h"
  20. #include "hw/sysbus.h"
  21. #include "hw/irq.h"
  22. #include "qemu/timer.h"
  23. #include "hw/misc/mac_via.h"
  24. #include "hw/misc/mos6522.h"
  25. #include "hw/input/adb.h"
  26. #include "sysemu/runstate.h"
  27. #include "qapi/error.h"
  28. #include "qemu/cutils.h"
  29. /*
  30. * VIAs: There are two in every machine,
  31. */
  32. #define VIA_SIZE (0x2000)
  33. /*
  34. * Not all of these are true post MacII I think.
  35. * CSA: probably the ones CHRP marks as 'unused' change purposes
  36. * when the IWM becomes the SWIM.
  37. * http://www.rs6000.ibm.com/resource/technology/chrpio/via5.mak.html
  38. * ftp://ftp.austin.ibm.com/pub/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf
  39. *
  40. * also, http://developer.apple.com/technotes/hw/hw_09.html claims the
  41. * following changes for IIfx:
  42. * VIA1A_vSccWrReq not available and that VIA1A_vSync has moved to an IOP.
  43. * Also, "All of the functionality of VIA2 has been moved to other chips".
  44. */
  45. #define VIA1A_vSccWrReq 0x80 /*
  46. * SCC write. (input)
  47. * [CHRP] SCC WREQ: Reflects the state of the
  48. * Wait/Request pins from the SCC.
  49. * [Macintosh Family Hardware]
  50. * as CHRP on SE/30,II,IIx,IIcx,IIci.
  51. * on IIfx, "0 means an active request"
  52. */
  53. #define VIA1A_vRev8 0x40 /*
  54. * Revision 8 board ???
  55. * [CHRP] En WaitReqB: Lets the WaitReq_L
  56. * signal from port B of the SCC appear on
  57. * the PA7 input pin. Output.
  58. * [Macintosh Family] On the SE/30, this
  59. * is the bit to flip screen buffers.
  60. * 0=alternate, 1=main.
  61. * on II,IIx,IIcx,IIci,IIfx this is a bit
  62. * for Rev ID. 0=II,IIx, 1=IIcx,IIci,IIfx
  63. */
  64. #define VIA1A_vHeadSel 0x20 /*
  65. * Head select for IWM.
  66. * [CHRP] unused.
  67. * [Macintosh Family] "Floppy disk
  68. * state-control line SEL" on all but IIfx
  69. */
  70. #define VIA1A_vOverlay 0x10 /*
  71. * [Macintosh Family] On SE/30,II,IIx,IIcx
  72. * this bit enables the "Overlay" address
  73. * map in the address decoders as it is on
  74. * reset for mapping the ROM over the reset
  75. * vector. 1=use overlay map.
  76. * On the IIci,IIfx it is another bit of the
  77. * CPU ID: 0=normal IIci, 1=IIci with parity
  78. * feature or IIfx.
  79. * [CHRP] En WaitReqA: Lets the WaitReq_L
  80. * signal from port A of the SCC appear
  81. * on the PA7 input pin (CHRP). Output.
  82. * [MkLinux] "Drive Select"
  83. * (with 0x20 being 'disk head select')
  84. */
  85. #define VIA1A_vSync 0x08 /*
  86. * [CHRP] Sync Modem: modem clock select:
  87. * 1: select the external serial clock to
  88. * drive the SCC's /RTxCA pin.
  89. * 0: Select the 3.6864MHz clock to drive
  90. * the SCC cell.
  91. * [Macintosh Family] Correct on all but IIfx
  92. */
  93. /*
  94. * Macintosh Family Hardware sez: bits 0-2 of VIA1A are volume control
  95. * on Macs which had the PWM sound hardware. Reserved on newer models.
  96. * On IIci,IIfx, bits 1-2 are the rest of the CPU ID:
  97. * bit 2: 1=IIci, 0=IIfx
  98. * bit 1: 1 on both IIci and IIfx.
  99. * MkLinux sez bit 0 is 'burnin flag' in this case.
  100. * CHRP sez: VIA1A bits 0-2 and 5 are 'unused': if programmed as
  101. * inputs, these bits will read 0.
  102. */
  103. #define VIA1A_vVolume 0x07 /* Audio volume mask for PWM */
  104. #define VIA1A_CPUID0 0x02 /* CPU id bit 0 on RBV, others */
  105. #define VIA1A_CPUID1 0x04 /* CPU id bit 0 on RBV, others */
  106. #define VIA1A_CPUID2 0x10 /* CPU id bit 0 on RBV, others */
  107. #define VIA1A_CPUID3 0x40 /* CPU id bit 0 on RBV, others */
  108. /*
  109. * Info on VIA1B is from Macintosh Family Hardware & MkLinux.
  110. * CHRP offers no info.
  111. */
  112. #define VIA1B_vSound 0x80 /*
  113. * Sound enable (for compatibility with
  114. * PWM hardware) 0=enabled.
  115. * Also, on IIci w/parity, shows parity error
  116. * 0=error, 1=OK.
  117. */
  118. #define VIA1B_vMystery 0x40 /*
  119. * On IIci, parity enable. 0=enabled,1=disabled
  120. * On SE/30, vertical sync interrupt enable.
  121. * 0=enabled. This vSync interrupt shows up
  122. * as a slot $E interrupt.
  123. */
  124. #define VIA1B_vADBS2 0x20 /* ADB state input bit 1 (unused on IIfx) */
  125. #define VIA1B_vADBS1 0x10 /* ADB state input bit 0 (unused on IIfx) */
  126. #define VIA1B_vADBInt 0x08 /* ADB interrupt 0=interrupt (unused on IIfx)*/
  127. #define VIA1B_vRTCEnb 0x04 /* Enable Real time clock. 0=enabled. */
  128. #define VIA1B_vRTCClk 0x02 /* Real time clock serial-clock line. */
  129. #define VIA1B_vRTCData 0x01 /* Real time clock serial-data line. */
  130. /*
  131. * VIA2 A register is the interrupt lines raised off the nubus
  132. * slots.
  133. * The below info is from 'Macintosh Family Hardware.'
  134. * MkLinux calls the 'IIci internal video IRQ' below the 'RBV slot 0 irq.'
  135. * It also notes that the slot $9 IRQ is the 'Ethernet IRQ' and
  136. * defines the 'Video IRQ' as 0x40 for the 'EVR' VIA work-alike.
  137. * Perhaps OSS uses vRAM1 and vRAM2 for ADB.
  138. */
  139. #define VIA2A_vRAM1 0x80 /* RAM size bit 1 (IIci: reserved) */
  140. #define VIA2A_vRAM0 0x40 /* RAM size bit 0 (IIci: internal video IRQ) */
  141. #define VIA2A_vIRQE 0x20 /* IRQ from slot $E */
  142. #define VIA2A_vIRQD 0x10 /* IRQ from slot $D */
  143. #define VIA2A_vIRQC 0x08 /* IRQ from slot $C */
  144. #define VIA2A_vIRQB 0x04 /* IRQ from slot $B */
  145. #define VIA2A_vIRQA 0x02 /* IRQ from slot $A */
  146. #define VIA2A_vIRQ9 0x01 /* IRQ from slot $9 */
  147. /*
  148. * RAM size bits decoded as follows:
  149. * bit1 bit0 size of ICs in bank A
  150. * 0 0 256 kbit
  151. * 0 1 1 Mbit
  152. * 1 0 4 Mbit
  153. * 1 1 16 Mbit
  154. */
  155. /*
  156. * Register B has the fun stuff in it
  157. */
  158. #define VIA2B_vVBL 0x80 /*
  159. * VBL output to VIA1 (60.15Hz) driven by
  160. * timer T1.
  161. * on IIci, parity test: 0=test mode.
  162. * [MkLinux] RBV_PARODD: 1=odd,0=even.
  163. */
  164. #define VIA2B_vSndJck 0x40 /*
  165. * External sound jack status.
  166. * 0=plug is inserted. On SE/30, always 0
  167. */
  168. #define VIA2B_vTfr0 0x20 /* Transfer mode bit 0 ack from NuBus */
  169. #define VIA2B_vTfr1 0x10 /* Transfer mode bit 1 ack from NuBus */
  170. #define VIA2B_vMode32 0x08 /*
  171. * 24/32bit switch - doubles as cache flush
  172. * on II, AMU/PMMU control.
  173. * if AMU, 0=24bit to 32bit translation
  174. * if PMMU, 1=PMMU is accessing page table.
  175. * on SE/30 tied low.
  176. * on IIx,IIcx,IIfx, unused.
  177. * on IIci/RBV, cache control. 0=flush cache.
  178. */
  179. #define VIA2B_vPower 0x04 /*
  180. * Power off, 0=shut off power.
  181. * on SE/30 this signal sent to PDS card.
  182. */
  183. #define VIA2B_vBusLk 0x02 /*
  184. * Lock NuBus transactions, 0=locked.
  185. * on SE/30 sent to PDS card.
  186. */
  187. #define VIA2B_vCDis 0x01 /*
  188. * Cache control. On IIci, 1=disable cache card
  189. * on others, 0=disable processor's instruction
  190. * and data caches.
  191. */
  192. /* interrupt flags */
  193. #define IRQ_SET 0x80
  194. /* common */
  195. #define VIA_IRQ_TIMER1 0x40
  196. #define VIA_IRQ_TIMER2 0x20
  197. /*
  198. * Apple sez: http://developer.apple.com/technotes/ov/ov_04.html
  199. * Another example of a valid function that has no ROM support is the use
  200. * of the alternate video page for page-flipping animation. Since there
  201. * is no ROM call to flip pages, it is necessary to go play with the
  202. * right bit in the VIA chip (6522 Versatile Interface Adapter).
  203. * [CSA: don't know which one this is, but it's one of 'em!]
  204. */
  205. /*
  206. * 6522 registers - see databook.
  207. * CSA: Assignments for VIA1 confirmed from CHRP spec.
  208. */
  209. /* partial address decode. 0xYYXX : XX part for RBV, YY part for VIA */
  210. /* Note: 15 VIA regs, 8 RBV regs */
  211. #define vBufB 0x0000 /* [VIA/RBV] Register B */
  212. #define vBufAH 0x0200 /* [VIA only] Buffer A, with handshake. DON'T USE! */
  213. #define vDirB 0x0400 /* [VIA only] Data Direction Register B. */
  214. #define vDirA 0x0600 /* [VIA only] Data Direction Register A. */
  215. #define vT1CL 0x0800 /* [VIA only] Timer one counter low. */
  216. #define vT1CH 0x0a00 /* [VIA only] Timer one counter high. */
  217. #define vT1LL 0x0c00 /* [VIA only] Timer one latches low. */
  218. #define vT1LH 0x0e00 /* [VIA only] Timer one latches high. */
  219. #define vT2CL 0x1000 /* [VIA only] Timer two counter low. */
  220. #define vT2CH 0x1200 /* [VIA only] Timer two counter high. */
  221. #define vSR 0x1400 /* [VIA only] Shift register. */
  222. #define vACR 0x1600 /* [VIA only] Auxilary control register. */
  223. #define vPCR 0x1800 /* [VIA only] Peripheral control register. */
  224. /*
  225. * CHRP sez never ever to *write* this.
  226. * Mac family says never to *change* this.
  227. * In fact we need to initialize it once at start.
  228. */
  229. #define vIFR 0x1a00 /* [VIA/RBV] Interrupt flag register. */
  230. #define vIER 0x1c00 /* [VIA/RBV] Interrupt enable register. */
  231. #define vBufA 0x1e00 /* [VIA/RBV] register A (no handshake) */
  232. /* from linux 2.6 drivers/macintosh/via-macii.c */
  233. /* Bits in ACR */
  234. #define VIA1ACR_vShiftCtrl 0x1c /* Shift register control bits */
  235. #define VIA1ACR_vShiftExtClk 0x0c /* Shift on external clock */
  236. #define VIA1ACR_vShiftOut 0x10 /* Shift out if 1 */
  237. /*
  238. * Apple Macintosh Family Hardware Refenece
  239. * Table 19-10 ADB transaction states
  240. */
  241. #define ADB_STATE_NEW 0
  242. #define ADB_STATE_EVEN 1
  243. #define ADB_STATE_ODD 2
  244. #define ADB_STATE_IDLE 3
  245. #define VIA1B_vADB_StateMask (VIA1B_vADBS1 | VIA1B_vADBS2)
  246. #define VIA1B_vADB_StateShift 4
  247. #define VIA_TIMER_FREQ (783360)
  248. #define VIA_ADB_POLL_FREQ 50 /* XXX: not real */
  249. /* VIA returns time offset from Jan 1, 1904, not 1970 */
  250. #define RTC_OFFSET 2082844800
  251. static void via1_VBL_update(MOS6522Q800VIA1State *v1s)
  252. {
  253. MOS6522State *s = MOS6522(v1s);
  254. /* 60 Hz irq */
  255. v1s->next_VBL = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 16630) /
  256. 16630 * 16630;
  257. if (s->ier & VIA1_IRQ_VBLANK) {
  258. timer_mod(v1s->VBL_timer, v1s->next_VBL);
  259. } else {
  260. timer_del(v1s->VBL_timer);
  261. }
  262. }
  263. static void via1_one_second_update(MOS6522Q800VIA1State *v1s)
  264. {
  265. MOS6522State *s = MOS6522(v1s);
  266. v1s->next_second = (qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000) /
  267. 1000 * 1000;
  268. if (s->ier & VIA1_IRQ_ONE_SECOND) {
  269. timer_mod(v1s->one_second_timer, v1s->next_second);
  270. } else {
  271. timer_del(v1s->one_second_timer);
  272. }
  273. }
  274. static void via1_VBL(void *opaque)
  275. {
  276. MOS6522Q800VIA1State *v1s = opaque;
  277. MOS6522State *s = MOS6522(v1s);
  278. MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
  279. s->ifr |= VIA1_IRQ_VBLANK;
  280. mdc->update_irq(s);
  281. via1_VBL_update(v1s);
  282. }
  283. static void via1_one_second(void *opaque)
  284. {
  285. MOS6522Q800VIA1State *v1s = opaque;
  286. MOS6522State *s = MOS6522(v1s);
  287. MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
  288. s->ifr |= VIA1_IRQ_ONE_SECOND;
  289. mdc->update_irq(s);
  290. via1_one_second_update(v1s);
  291. }
  292. static void via1_irq_request(void *opaque, int irq, int level)
  293. {
  294. MOS6522Q800VIA1State *v1s = opaque;
  295. MOS6522State *s = MOS6522(v1s);
  296. MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
  297. if (level) {
  298. s->ifr |= 1 << irq;
  299. } else {
  300. s->ifr &= ~(1 << irq);
  301. }
  302. mdc->update_irq(s);
  303. }
  304. static void via2_irq_request(void *opaque, int irq, int level)
  305. {
  306. MOS6522Q800VIA2State *v2s = opaque;
  307. MOS6522State *s = MOS6522(v2s);
  308. MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
  309. if (level) {
  310. s->ifr |= 1 << irq;
  311. } else {
  312. s->ifr &= ~(1 << irq);
  313. }
  314. mdc->update_irq(s);
  315. }
  316. static void via1_rtc_update(MacVIAState *m)
  317. {
  318. MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
  319. MOS6522State *s = MOS6522(v1s);
  320. if (s->b & VIA1B_vRTCEnb) {
  321. return;
  322. }
  323. if (s->dirb & VIA1B_vRTCData) {
  324. /* send bits to the RTC */
  325. if (!(v1s->last_b & VIA1B_vRTCClk) && (s->b & VIA1B_vRTCClk)) {
  326. m->data_out <<= 1;
  327. m->data_out |= s->b & VIA1B_vRTCData;
  328. m->data_out_cnt++;
  329. }
  330. } else {
  331. /* receive bits from the RTC */
  332. if ((v1s->last_b & VIA1B_vRTCClk) &&
  333. !(s->b & VIA1B_vRTCClk) &&
  334. m->data_in_cnt) {
  335. s->b = (s->b & ~VIA1B_vRTCData) |
  336. ((m->data_in >> 7) & VIA1B_vRTCData);
  337. m->data_in <<= 1;
  338. m->data_in_cnt--;
  339. }
  340. }
  341. if (m->data_out_cnt == 8) {
  342. m->data_out_cnt = 0;
  343. if (m->cmd == 0) {
  344. if (m->data_out & 0x80) {
  345. /* this is a read command */
  346. uint32_t time = m->tick_offset +
  347. (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
  348. NANOSECONDS_PER_SECOND);
  349. if (m->data_out == 0x81) { /* seconds register 0 */
  350. m->data_in = time & 0xff;
  351. m->data_in_cnt = 8;
  352. } else if (m->data_out == 0x85) { /* seconds register 1 */
  353. m->data_in = (time >> 8) & 0xff;
  354. m->data_in_cnt = 8;
  355. } else if (m->data_out == 0x89) { /* seconds register 2 */
  356. m->data_in = (time >> 16) & 0xff;
  357. m->data_in_cnt = 8;
  358. } else if (m->data_out == 0x8d) { /* seconds register 3 */
  359. m->data_in = (time >> 24) & 0xff;
  360. m->data_in_cnt = 8;
  361. } else if ((m->data_out & 0xf3) == 0xa1) {
  362. /* PRAM address 0x10 -> 0x13 */
  363. int addr = (m->data_out >> 2) & 0x03;
  364. m->data_in = v1s->PRAM[addr];
  365. m->data_in_cnt = 8;
  366. } else if ((m->data_out & 0xf3) == 0xa1) {
  367. /* PRAM address 0x00 -> 0x0f */
  368. int addr = (m->data_out >> 2) & 0x0f;
  369. m->data_in = v1s->PRAM[addr];
  370. m->data_in_cnt = 8;
  371. } else if ((m->data_out & 0xf8) == 0xb8) {
  372. /* extended memory designator and sector number */
  373. m->cmd = m->data_out;
  374. }
  375. } else {
  376. /* this is a write command */
  377. m->cmd = m->data_out;
  378. }
  379. } else {
  380. if (m->cmd & 0x80) {
  381. if ((m->cmd & 0xf8) == 0xb8) {
  382. /* extended memory designator and sector number */
  383. int sector = m->cmd & 0x07;
  384. int addr = (m->data_out >> 2) & 0x1f;
  385. m->data_in = v1s->PRAM[sector * 8 + addr];
  386. m->data_in_cnt = 8;
  387. }
  388. } else if (!m->wprotect) {
  389. /* this is a write command */
  390. if (m->alt != 0) {
  391. /* extended memory designator and sector number */
  392. int sector = m->cmd & 0x07;
  393. int addr = (m->alt >> 2) & 0x1f;
  394. v1s->PRAM[sector * 8 + addr] = m->data_out;
  395. m->alt = 0;
  396. } else if (m->cmd == 0x01) { /* seconds register 0 */
  397. /* FIXME */
  398. } else if (m->cmd == 0x05) { /* seconds register 1 */
  399. /* FIXME */
  400. } else if (m->cmd == 0x09) { /* seconds register 2 */
  401. /* FIXME */
  402. } else if (m->cmd == 0x0d) { /* seconds register 3 */
  403. /* FIXME */
  404. } else if (m->cmd == 0x31) {
  405. /* Test Register */
  406. } else if (m->cmd == 0x35) {
  407. /* Write Protect register */
  408. m->wprotect = m->data_out & 1;
  409. } else if ((m->cmd & 0xf3) == 0xa1) {
  410. /* PRAM address 0x10 -> 0x13 */
  411. int addr = (m->cmd >> 2) & 0x03;
  412. v1s->PRAM[addr] = m->data_out;
  413. } else if ((m->cmd & 0xf3) == 0xa1) {
  414. /* PRAM address 0x00 -> 0x0f */
  415. int addr = (m->cmd >> 2) & 0x0f;
  416. v1s->PRAM[addr] = m->data_out;
  417. } else if ((m->cmd & 0xf8) == 0xb8) {
  418. /* extended memory designator and sector number */
  419. m->alt = m->cmd;
  420. }
  421. }
  422. }
  423. m->data_out = 0;
  424. }
  425. }
  426. static int adb_via_poll(MacVIAState *s, int state, uint8_t *data)
  427. {
  428. if (state != ADB_STATE_IDLE) {
  429. return 0;
  430. }
  431. if (s->adb_data_in_size < s->adb_data_in_index) {
  432. return 0;
  433. }
  434. if (s->adb_data_out_index != 0) {
  435. return 0;
  436. }
  437. s->adb_data_in_index = 0;
  438. s->adb_data_out_index = 0;
  439. s->adb_data_in_size = adb_poll(&s->adb_bus, s->adb_data_in, 0xffff);
  440. if (s->adb_data_in_size) {
  441. *data = s->adb_data_in[s->adb_data_in_index++];
  442. qemu_irq_raise(s->adb_data_ready);
  443. }
  444. return s->adb_data_in_size;
  445. }
  446. static int adb_via_send(MacVIAState *s, int state, uint8_t data)
  447. {
  448. switch (state) {
  449. case ADB_STATE_NEW:
  450. s->adb_data_out_index = 0;
  451. break;
  452. case ADB_STATE_EVEN:
  453. if ((s->adb_data_out_index & 1) == 0) {
  454. return 0;
  455. }
  456. break;
  457. case ADB_STATE_ODD:
  458. if (s->adb_data_out_index & 1) {
  459. return 0;
  460. }
  461. break;
  462. case ADB_STATE_IDLE:
  463. return 0;
  464. }
  465. assert(s->adb_data_out_index < sizeof(s->adb_data_out) - 1);
  466. s->adb_data_out[s->adb_data_out_index++] = data;
  467. qemu_irq_raise(s->adb_data_ready);
  468. return 1;
  469. }
  470. static int adb_via_receive(MacVIAState *s, int state, uint8_t *data)
  471. {
  472. switch (state) {
  473. case ADB_STATE_NEW:
  474. return 0;
  475. case ADB_STATE_EVEN:
  476. if (s->adb_data_in_size <= 0) {
  477. qemu_irq_raise(s->adb_data_ready);
  478. return 0;
  479. }
  480. if (s->adb_data_in_index >= s->adb_data_in_size) {
  481. *data = 0;
  482. qemu_irq_raise(s->adb_data_ready);
  483. return 1;
  484. }
  485. if ((s->adb_data_in_index & 1) == 0) {
  486. return 0;
  487. }
  488. break;
  489. case ADB_STATE_ODD:
  490. if (s->adb_data_in_size <= 0) {
  491. qemu_irq_raise(s->adb_data_ready);
  492. return 0;
  493. }
  494. if (s->adb_data_in_index >= s->adb_data_in_size) {
  495. *data = 0;
  496. qemu_irq_raise(s->adb_data_ready);
  497. return 1;
  498. }
  499. if (s->adb_data_in_index & 1) {
  500. return 0;
  501. }
  502. break;
  503. case ADB_STATE_IDLE:
  504. if (s->adb_data_out_index == 0) {
  505. return 0;
  506. }
  507. s->adb_data_in_size = adb_request(&s->adb_bus, s->adb_data_in,
  508. s->adb_data_out,
  509. s->adb_data_out_index);
  510. s->adb_data_out_index = 0;
  511. s->adb_data_in_index = 0;
  512. if (s->adb_data_in_size < 0) {
  513. *data = 0xff;
  514. qemu_irq_raise(s->adb_data_ready);
  515. return -1;
  516. }
  517. if (s->adb_data_in_size == 0) {
  518. return 0;
  519. }
  520. break;
  521. }
  522. assert(s->adb_data_in_index < sizeof(s->adb_data_in) - 1);
  523. *data = s->adb_data_in[s->adb_data_in_index++];
  524. qemu_irq_raise(s->adb_data_ready);
  525. if (*data == 0xff || *data == 0) {
  526. return 0;
  527. }
  528. return 1;
  529. }
  530. static void via1_adb_update(MacVIAState *m)
  531. {
  532. MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
  533. MOS6522State *s = MOS6522(v1s);
  534. int state;
  535. int ret;
  536. state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
  537. if (s->acr & VIA1ACR_vShiftOut) {
  538. /* output mode */
  539. ret = adb_via_send(m, state, s->sr);
  540. if (ret > 0) {
  541. s->b &= ~VIA1B_vADBInt;
  542. } else {
  543. s->b |= VIA1B_vADBInt;
  544. }
  545. } else {
  546. /* input mode */
  547. ret = adb_via_receive(m, state, &s->sr);
  548. if (ret > 0 && s->sr != 0xff) {
  549. s->b &= ~VIA1B_vADBInt;
  550. } else {
  551. s->b |= VIA1B_vADBInt;
  552. }
  553. }
  554. }
  555. static void via_adb_poll(void *opaque)
  556. {
  557. MacVIAState *m = opaque;
  558. MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
  559. MOS6522State *s = MOS6522(v1s);
  560. int state;
  561. if (s->b & VIA1B_vADBInt) {
  562. state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
  563. if (adb_via_poll(m, state, &s->sr)) {
  564. s->b &= ~VIA1B_vADBInt;
  565. }
  566. }
  567. timer_mod(m->adb_poll_timer,
  568. qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
  569. (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
  570. }
  571. static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size)
  572. {
  573. MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
  574. MOS6522State *ms = MOS6522(s);
  575. int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
  576. /*
  577. * If IRQs are disabled, timers are disabled, but we need to update
  578. * VIA1_IRQ_VBLANK and VIA1_IRQ_ONE_SECOND bits in the IFR
  579. */
  580. if (now >= s->next_VBL) {
  581. ms->ifr |= VIA1_IRQ_VBLANK;
  582. via1_VBL_update(s);
  583. }
  584. if (now >= s->next_second) {
  585. ms->ifr |= VIA1_IRQ_ONE_SECOND;
  586. via1_one_second_update(s);
  587. }
  588. addr = (addr >> 9) & 0xf;
  589. return mos6522_read(ms, addr, size);
  590. }
  591. static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val,
  592. unsigned size)
  593. {
  594. MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
  595. MOS6522State *ms = MOS6522(v1s);
  596. addr = (addr >> 9) & 0xf;
  597. mos6522_write(ms, addr, val, size);
  598. via1_one_second_update(v1s);
  599. via1_VBL_update(v1s);
  600. }
  601. static const MemoryRegionOps mos6522_q800_via1_ops = {
  602. .read = mos6522_q800_via1_read,
  603. .write = mos6522_q800_via1_write,
  604. .endianness = DEVICE_BIG_ENDIAN,
  605. .valid = {
  606. .min_access_size = 1,
  607. .max_access_size = 1,
  608. },
  609. };
  610. static uint64_t mos6522_q800_via2_read(void *opaque, hwaddr addr, unsigned size)
  611. {
  612. MOS6522Q800VIA2State *s = MOS6522_Q800_VIA2(opaque);
  613. MOS6522State *ms = MOS6522(s);
  614. addr = (addr >> 9) & 0xf;
  615. return mos6522_read(ms, addr, size);
  616. }
  617. static void mos6522_q800_via2_write(void *opaque, hwaddr addr, uint64_t val,
  618. unsigned size)
  619. {
  620. MOS6522Q800VIA2State *s = MOS6522_Q800_VIA2(opaque);
  621. MOS6522State *ms = MOS6522(s);
  622. addr = (addr >> 9) & 0xf;
  623. mos6522_write(ms, addr, val, size);
  624. }
  625. static const MemoryRegionOps mos6522_q800_via2_ops = {
  626. .read = mos6522_q800_via2_read,
  627. .write = mos6522_q800_via2_write,
  628. .endianness = DEVICE_BIG_ENDIAN,
  629. .valid = {
  630. .min_access_size = 1,
  631. .max_access_size = 1,
  632. },
  633. };
  634. static void mac_via_reset(DeviceState *dev)
  635. {
  636. MacVIAState *m = MAC_VIA(dev);
  637. MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
  638. timer_mod(m->adb_poll_timer,
  639. qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
  640. (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ));
  641. timer_del(v1s->VBL_timer);
  642. v1s->next_VBL = 0;
  643. timer_del(v1s->one_second_timer);
  644. v1s->next_second = 0;
  645. }
  646. static void mac_via_realize(DeviceState *dev, Error **errp)
  647. {
  648. MacVIAState *m = MAC_VIA(dev);
  649. MOS6522State *ms;
  650. struct tm tm;
  651. /* Init VIAs 1 and 2 */
  652. sysbus_init_child_obj(OBJECT(dev), "via1", &m->mos6522_via1,
  653. sizeof(m->mos6522_via1), TYPE_MOS6522_Q800_VIA1);
  654. sysbus_init_child_obj(OBJECT(dev), "via2", &m->mos6522_via2,
  655. sizeof(m->mos6522_via2), TYPE_MOS6522_Q800_VIA2);
  656. /* Pass through mos6522 output IRQs */
  657. ms = MOS6522(&m->mos6522_via1);
  658. object_property_add_alias(OBJECT(dev), "irq[0]", OBJECT(ms),
  659. SYSBUS_DEVICE_GPIO_IRQ "[0]", &error_abort);
  660. ms = MOS6522(&m->mos6522_via2);
  661. object_property_add_alias(OBJECT(dev), "irq[1]", OBJECT(ms),
  662. SYSBUS_DEVICE_GPIO_IRQ "[0]", &error_abort);
  663. /* Pass through mos6522 input IRQs */
  664. qdev_pass_gpios(DEVICE(&m->mos6522_via1), dev, "via1-irq");
  665. qdev_pass_gpios(DEVICE(&m->mos6522_via2), dev, "via2-irq");
  666. /* VIA 1 */
  667. m->mos6522_via1.one_second_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
  668. via1_one_second,
  669. &m->mos6522_via1);
  670. m->mos6522_via1.VBL_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via1_VBL,
  671. &m->mos6522_via1);
  672. qemu_get_timedate(&tm, 0);
  673. m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
  674. m->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via_adb_poll, m);
  675. m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
  676. VIA1_IRQ_ADB_READY_BIT);
  677. }
  678. static void mac_via_init(Object *obj)
  679. {
  680. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  681. MacVIAState *m = MAC_VIA(obj);
  682. /* MMIO */
  683. memory_region_init(&m->mmio, obj, "mac-via", 2 * VIA_SIZE);
  684. sysbus_init_mmio(sbd, &m->mmio);
  685. memory_region_init_io(&m->via1mem, obj, &mos6522_q800_via1_ops,
  686. &m->mos6522_via1, "via1", VIA_SIZE);
  687. memory_region_add_subregion(&m->mmio, 0x0, &m->via1mem);
  688. memory_region_init_io(&m->via2mem, obj, &mos6522_q800_via2_ops,
  689. &m->mos6522_via2, "via2", VIA_SIZE);
  690. memory_region_add_subregion(&m->mmio, VIA_SIZE, &m->via2mem);
  691. /* ADB */
  692. qbus_create_inplace((BusState *)&m->adb_bus, sizeof(m->adb_bus),
  693. TYPE_ADB_BUS, DEVICE(obj), "adb.0");
  694. }
  695. static const VMStateDescription vmstate_mac_via = {
  696. .name = "mac-via",
  697. .version_id = 1,
  698. .minimum_version_id = 1,
  699. .fields = (VMStateField[]) {
  700. /* VIAs */
  701. VMSTATE_STRUCT(mos6522_via1.parent_obj, MacVIAState, 0, vmstate_mos6522,
  702. MOS6522State),
  703. VMSTATE_UINT8(mos6522_via1.last_b, MacVIAState),
  704. VMSTATE_BUFFER(mos6522_via1.PRAM, MacVIAState),
  705. VMSTATE_TIMER_PTR(mos6522_via1.one_second_timer, MacVIAState),
  706. VMSTATE_INT64(mos6522_via1.next_second, MacVIAState),
  707. VMSTATE_TIMER_PTR(mos6522_via1.VBL_timer, MacVIAState),
  708. VMSTATE_INT64(mos6522_via1.next_VBL, MacVIAState),
  709. VMSTATE_STRUCT(mos6522_via2.parent_obj, MacVIAState, 0, vmstate_mos6522,
  710. MOS6522State),
  711. /* RTC */
  712. VMSTATE_UINT32(tick_offset, MacVIAState),
  713. VMSTATE_UINT8(data_out, MacVIAState),
  714. VMSTATE_INT32(data_out_cnt, MacVIAState),
  715. VMSTATE_UINT8(data_in, MacVIAState),
  716. VMSTATE_UINT8(data_in_cnt, MacVIAState),
  717. VMSTATE_UINT8(cmd, MacVIAState),
  718. VMSTATE_INT32(wprotect, MacVIAState),
  719. VMSTATE_INT32(alt, MacVIAState),
  720. /* ADB */
  721. VMSTATE_TIMER_PTR(adb_poll_timer, MacVIAState),
  722. VMSTATE_INT32(adb_data_in_size, MacVIAState),
  723. VMSTATE_INT32(adb_data_in_index, MacVIAState),
  724. VMSTATE_INT32(adb_data_out_index, MacVIAState),
  725. VMSTATE_BUFFER(adb_data_in, MacVIAState),
  726. VMSTATE_BUFFER(adb_data_out, MacVIAState),
  727. VMSTATE_END_OF_LIST()
  728. }
  729. };
  730. static void mac_via_class_init(ObjectClass *oc, void *data)
  731. {
  732. DeviceClass *dc = DEVICE_CLASS(oc);
  733. dc->realize = mac_via_realize;
  734. dc->reset = mac_via_reset;
  735. dc->vmsd = &vmstate_mac_via;
  736. }
  737. static TypeInfo mac_via_info = {
  738. .name = TYPE_MAC_VIA,
  739. .parent = TYPE_SYS_BUS_DEVICE,
  740. .instance_size = sizeof(MacVIAState),
  741. .instance_init = mac_via_init,
  742. .class_init = mac_via_class_init,
  743. };
  744. /* VIA 1 */
  745. static void mos6522_q800_via1_portB_write(MOS6522State *s)
  746. {
  747. MOS6522Q800VIA1State *v1s = container_of(s, MOS6522Q800VIA1State,
  748. parent_obj);
  749. MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
  750. via1_rtc_update(m);
  751. via1_adb_update(m);
  752. v1s->last_b = s->b;
  753. }
  754. static void mos6522_q800_via1_reset(DeviceState *dev)
  755. {
  756. MOS6522State *ms = MOS6522(dev);
  757. MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);
  758. mdc->parent_reset(dev);
  759. ms->timers[0].frequency = VIA_TIMER_FREQ;
  760. ms->timers[1].frequency = VIA_TIMER_FREQ;
  761. ms->b = VIA1B_vADB_StateMask | VIA1B_vADBInt | VIA1B_vRTCEnb;
  762. }
  763. static void mos6522_q800_via1_init(Object *obj)
  764. {
  765. qdev_init_gpio_in_named(DEVICE(obj), via1_irq_request, "via1-irq",
  766. VIA1_IRQ_NB);
  767. }
  768. static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
  769. {
  770. DeviceClass *dc = DEVICE_CLASS(oc);
  771. MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);
  772. dc->reset = mos6522_q800_via1_reset;
  773. mdc->portB_write = mos6522_q800_via1_portB_write;
  774. }
  775. static const TypeInfo mos6522_q800_via1_type_info = {
  776. .name = TYPE_MOS6522_Q800_VIA1,
  777. .parent = TYPE_MOS6522,
  778. .instance_size = sizeof(MOS6522Q800VIA1State),
  779. .instance_init = mos6522_q800_via1_init,
  780. .class_init = mos6522_q800_via1_class_init,
  781. };
  782. /* VIA 2 */
  783. static void mos6522_q800_via2_portB_write(MOS6522State *s)
  784. {
  785. if (s->dirb & VIA2B_vPower && (s->b & VIA2B_vPower) == 0) {
  786. /* shutdown */
  787. qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  788. }
  789. }
  790. static void mos6522_q800_via2_reset(DeviceState *dev)
  791. {
  792. MOS6522State *ms = MOS6522(dev);
  793. MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);
  794. mdc->parent_reset(dev);
  795. ms->timers[0].frequency = VIA_TIMER_FREQ;
  796. ms->timers[1].frequency = VIA_TIMER_FREQ;
  797. ms->dirb = 0;
  798. ms->b = 0;
  799. }
  800. static void mos6522_q800_via2_init(Object *obj)
  801. {
  802. qdev_init_gpio_in_named(DEVICE(obj), via2_irq_request, "via2-irq",
  803. VIA2_IRQ_NB);
  804. }
  805. static void mos6522_q800_via2_class_init(ObjectClass *oc, void *data)
  806. {
  807. DeviceClass *dc = DEVICE_CLASS(oc);
  808. MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);
  809. dc->reset = mos6522_q800_via2_reset;
  810. mdc->portB_write = mos6522_q800_via2_portB_write;
  811. }
  812. static const TypeInfo mos6522_q800_via2_type_info = {
  813. .name = TYPE_MOS6522_Q800_VIA2,
  814. .parent = TYPE_MOS6522,
  815. .instance_size = sizeof(MOS6522Q800VIA2State),
  816. .instance_init = mos6522_q800_via2_init,
  817. .class_init = mos6522_q800_via2_class_init,
  818. };
  819. static void mac_via_register_types(void)
  820. {
  821. type_register_static(&mos6522_q800_via1_type_info);
  822. type_register_static(&mos6522_q800_via2_type_info);
  823. type_register_static(&mac_via_info);
  824. }
  825. type_init(mac_via_register_types);