1 //
2 // Copyright (c) 2004 K. Wilkins
3 //
4 // This software is provided 'as-is', without any express or implied warranty.
5 // In no event will the authors be held liable for any damages arising from
6 // the use of this software.
7 //
8 // Permission is granted to anyone to use this software for any purpose,
9 // including commercial applications, and to alter it and redistribute it
10 // freely, subject to the following restrictions:
11 //
12 // 1. The origin of this software must not be misrepresented; you must not
13 //    claim that you wrote the original software. If you use this software
14 //    in a product, an acknowledgment in the product documentation would be
15 //    appreciated but is not required.
16 //
17 // 2. Altered source versions must be plainly marked as such, and must not
18 //    be misrepresented as being the original software.
19 //
20 // 3. This notice may not be removed or altered from any source distribution.
21 //
22 
23 //////////////////////////////////////////////////////////////////////////////
24 //                       Handy - An Atari Lynx Emulator                     //
25 //                          Copyright (c) 1996,1997                         //
26 //                                 K. Wilkins                               //
27 //////////////////////////////////////////////////////////////////////////////
28 // Mikey class header file                                                  //
29 //////////////////////////////////////////////////////////////////////////////
30 //                                                                          //
31 // This header file provides the interface definition and some of the code  //
32 // for the Mikey chip within the Lynx. The most crucial code is the         //
33 // Update() function which as you can probably guess updates all of the     //
34 // Mikey hardware counters and screen DMA from the prevous time it was      //
35 // called. Yes I know how to spell Mikey but I cant be bothered to change   //
36 // it everywhere.                                                           //
37 //                                                                          //
38 //    K. Wilkins                                                            //
39 // August 1997                                                              //
40 //                                                                          //
41 //////////////////////////////////////////////////////////////////////////////
42 // Revision History:                                                        //
43 // -----------------                                                        //
44 //                                                                          //
45 // 01Aug1997 KW Document header added & class documented.                   //
46 //                                                                          //
47 //////////////////////////////////////////////////////////////////////////////
48 
49 #ifndef MIKIE_H
50 #define MIKIE_H
51 
52 //#include <crtdbg.h>
53 //#define	TRACE_MIKIE
54 
55 #ifdef TRACE_MIKIE
56 
57 #define TRACE_MIKIE0(msg)					_RPT1(_CRT_WARN,"CMikie::"msg" (Time=%012d)\n",gSystemCycleCount)
58 #define TRACE_MIKIE1(msg,arg1)				_RPT2(_CRT_WARN,"CMikie::"msg" (Time=%012d)\n",arg1,gSystemCycleCount)
59 #define TRACE_MIKIE2(msg,arg1,arg2)			_RPT3(_CRT_WARN,"CMikie::"msg" (Time=%012d)\n",arg1,arg2,gSystemCycleCount)
60 #define TRACE_MIKIE3(msg,arg1,arg2,arg3)	_RPT4(_CRT_WARN,"CMikie::"msg" (Time=%012d)\n",arg1,arg2,arg3,gSystemCycleCount)
61 
62 #else
63 
64 #define TRACE_MIKIE0(msg)
65 #define TRACE_MIKIE1(msg,arg1)
66 #define TRACE_MIKIE2(msg,arg1,arg2)
67 #define TRACE_MIKIE3(msg,arg1,arg2,arg3)
68 
69 #endif
70 
71 class CSystem;
72 
73 #define MIKIE_START	0xfd00
74 #define MIKIE_SIZE	0x100
75 
76 //
77 // Define counter types and defines
78 //
79 
80 #define CTRL_A_IRQEN	0x80
81 #define CTRL_A_RTD		0x40
82 #define CTRL_A_RELOAD	0x10
83 #define CTRL_A_COUNT	0x08
84 #define CTRL_A_DIVIDE	0x07
85 
86 #define CTRL_B_TDONE	0x08
87 #define CTRL_B_LASTCK	0x04
88 #define CTRL_B_CIN		0x02
89 #define CTRL_B_COUT		0x01
90 
91 #define LINE_TIMER		0x00
92 #define SCREEN_TIMER	0x02
93 
94 #define LINE_WIDTH		160
95 #define	LINE_SIZE		80
96 
97 #define UART_TX_INACTIVE	0x80000000
98 #define UART_RX_INACTIVE	0x80000000
99 #define UART_BREAK_CODE		0x00008000
100 #define	UART_MAX_RX_QUEUE	32
101 #define UART_TX_TIME_PERIOD	(11)
102 #define UART_RX_TIME_PERIOD	(11)
103 #define UART_RX_NEXT_DELAY	(44)
104 
105 typedef struct
106 {
107    UBYTE	backup;
108    UBYTE	count;
109    UBYTE	controlA;
110    UBYTE	controlB;
111    bool	linkedlastcarry;
112 }MTIMER;
113 
114 typedef struct
115 {
116    union
117    {
118       struct
119       {
120 #ifdef MSB_FIRST
121          UBYTE unused:4;
122          UBYTE Colour:1;
123          UBYTE FourColour:1;
124          UBYTE Flip:1;
125          UBYTE DMAEnable:1;
126 #else
127 
128          UBYTE DMAEnable:1;
129          UBYTE Flip:1;
130          UBYTE FourColour:1;
131          UBYTE Colour:1;
132          UBYTE unused:4;
133 #endif
134       }Bits;
135       UBYTE Byte;
136    };
137 }TDISPCTL;
138 
139 typedef struct
140 {
141    union
142    {
143       struct
144       {
145 #ifdef MSB_FIRST
146          UBYTE unused:8;
147          UBYTE unused2:8;
148          UBYTE unused3:4;
149          UBYTE Blue:4;
150          UBYTE Red:4;
151          UBYTE Green:4;
152 #else
153          UBYTE Green:4;
154          UBYTE Red:4;
155          UBYTE Blue:4;
156 #endif
157       }Colours;
158       ULONG     Index;
159    };
160 }TPALETTE;
161 
162 
163 //
164 // Emumerated types for possible mikie windows independant modes
165 //
166 enum
167 {
168    MIKIE_BAD_MODE=0,
169    MIKIE_NO_ROTATE,
170    MIKIE_ROTATE_L,
171    MIKIE_ROTATE_R
172 };
173 
174 enum
175 {
176    MIKIE_PIXEL_FORMAT_8BPP=0,
177    MIKIE_PIXEL_FORMAT_16BPP_BGR555,
178    MIKIE_PIXEL_FORMAT_16BPP_555,
179    MIKIE_PIXEL_FORMAT_16BPP_565,
180    MIKIE_PIXEL_FORMAT_24BPP,
181    MIKIE_PIXEL_FORMAT_32BPP,
182 };
183 
184 #include <blip/Stereo_Buffer.h>
185 
186 typedef Blip_Synth<blip_good_quality, 256 * 4> Synth;
187 
188 class CMikie : public CLynxBase
189 {
190    public:
191       CMikie(CSystem& parent);
192       ~CMikie();
193 
194       Synth miksynth;
195       Stereo_Buffer mikbuf;
196 
197       bool	ContextSave(LSS_FILE *fp);
198       bool	ContextLoad(LSS_FILE *fp);
199       void	Reset(void);
200 
201       UBYTE	Peek(ULONG addr);
202       void	Poke(ULONG addr,UBYTE data);
ReadCycle(void)203       ULONG	ReadCycle(void) {return 5;};
WriteCycle(void)204       ULONG	WriteCycle(void) {return 5;};
ObjectSize(void)205       ULONG	ObjectSize(void) {return MIKIE_SIZE;};
206       void	PresetForHomebrew(void);
207       ULONG	GetLfsrNext(ULONG current);
208 
209       void	ComLynxCable(int status);
210       void	ComLynxRxData(int data);
211       void	ComLynxTxLoopback(int data);
212       void	ComLynxTxCallback(void (*function)(int data,ULONG objref),ULONG objref);
213 
214       void	DisplaySetAttributes(ULONG Rotate, ULONG Format, ULONG Pitch, UBYTE* (*DisplayCallback)(ULONG objref),ULONG objref);
215 
216       void	BlowOut(void);
217 
218       ULONG	DisplayRenderLine(void);
219       ULONG	DisplayEndOfFrame(void);
220 
SetCPUSleep(void)221       inline void SetCPUSleep(void) {gSystemCPUSleep=TRUE;};
ClearCPUSleep(void)222       inline void ClearCPUSleep(void) {gSystemCPUSleep=FALSE;gSystemCPUSleep_Saved=FALSE;};
223 
224 
225       void Update(void);
226       inline void UpdateSound(void);
SwitchAudInDir(void)227       inline bool SwitchAudInDir(void){ return(mIODIR&0x10);};
SwitchAudInValue(void)228       inline bool SwitchAudInValue(void){ return (mIODAT&0x10);};
229 
230    private:
231       CSystem		&mSystem;
232 
233       // Hardware storage
234 
235       ULONG		mDisplayAddress;
236       ULONG		mAudioInputComparator;
237       ULONG		mTimerStatusFlags;
238       ULONG		mTimerInterruptMask;
239 
240       TPALETTE	mPalette[16];
241       ULONG		mColourMap[4096];
242 
243       ULONG		mIODAT;
244       ULONG		mIODIR;
245       ULONG		mIODAT_REST_SIGNAL;
246 
247       ULONG		mDISPCTL_DMAEnable;
248       ULONG		mDISPCTL_Flip;
249       ULONG		mDISPCTL_FourColour;
250       ULONG		mDISPCTL_Colour;
251 
252       ULONG		mTIM_0_BKUP;
253       ULONG		mTIM_0_ENABLE_RELOAD;
254       ULONG		mTIM_0_ENABLE_COUNT;
255       ULONG		mTIM_0_LINKING;
256       ULONG		mTIM_0_CURRENT;
257       ULONG		mTIM_0_TIMER_DONE;
258       ULONG		mTIM_0_LAST_CLOCK;
259       ULONG		mTIM_0_BORROW_IN;
260       ULONG		mTIM_0_BORROW_OUT;
261       ULONG		mTIM_0_LAST_LINK_CARRY;
262       ULONG		mTIM_0_LAST_COUNT;
263 
264       ULONG		mTIM_1_BKUP;
265       ULONG		mTIM_1_ENABLE_RELOAD;
266       ULONG		mTIM_1_ENABLE_COUNT;
267       ULONG		mTIM_1_LINKING;
268       ULONG		mTIM_1_CURRENT;
269       ULONG		mTIM_1_TIMER_DONE;
270       ULONG		mTIM_1_LAST_CLOCK;
271       ULONG		mTIM_1_BORROW_IN;
272       ULONG		mTIM_1_BORROW_OUT;
273       ULONG		mTIM_1_LAST_LINK_CARRY;
274       ULONG		mTIM_1_LAST_COUNT;
275 
276       ULONG		mTIM_2_BKUP;
277       ULONG		mTIM_2_ENABLE_RELOAD;
278       ULONG		mTIM_2_ENABLE_COUNT;
279       ULONG		mTIM_2_LINKING;
280       ULONG		mTIM_2_CURRENT;
281       ULONG		mTIM_2_TIMER_DONE;
282       ULONG		mTIM_2_LAST_CLOCK;
283       ULONG		mTIM_2_BORROW_IN;
284       ULONG		mTIM_2_BORROW_OUT;
285       ULONG		mTIM_2_LAST_LINK_CARRY;
286       ULONG		mTIM_2_LAST_COUNT;
287 
288       ULONG		mTIM_3_BKUP;
289       ULONG		mTIM_3_ENABLE_RELOAD;
290       ULONG		mTIM_3_ENABLE_COUNT;
291       ULONG		mTIM_3_LINKING;
292       ULONG		mTIM_3_CURRENT;
293       ULONG		mTIM_3_TIMER_DONE;
294       ULONG		mTIM_3_LAST_CLOCK;
295       ULONG		mTIM_3_BORROW_IN;
296       ULONG		mTIM_3_BORROW_OUT;
297       ULONG		mTIM_3_LAST_LINK_CARRY;
298       ULONG		mTIM_3_LAST_COUNT;
299 
300       ULONG		mTIM_4_BKUP;
301       ULONG		mTIM_4_ENABLE_RELOAD;
302       ULONG		mTIM_4_ENABLE_COUNT;
303       ULONG		mTIM_4_LINKING;
304       ULONG		mTIM_4_CURRENT;
305       ULONG		mTIM_4_TIMER_DONE;
306       ULONG		mTIM_4_LAST_CLOCK;
307       ULONG		mTIM_4_BORROW_IN;
308       ULONG		mTIM_4_BORROW_OUT;
309       ULONG		mTIM_4_LAST_LINK_CARRY;
310       ULONG		mTIM_4_LAST_COUNT;
311 
312       ULONG		mTIM_5_BKUP;
313       ULONG		mTIM_5_ENABLE_RELOAD;
314       ULONG		mTIM_5_ENABLE_COUNT;
315       ULONG		mTIM_5_LINKING;
316       ULONG		mTIM_5_CURRENT;
317       ULONG		mTIM_5_TIMER_DONE;
318       ULONG		mTIM_5_LAST_CLOCK;
319       ULONG		mTIM_5_BORROW_IN;
320       ULONG		mTIM_5_BORROW_OUT;
321       ULONG		mTIM_5_LAST_LINK_CARRY;
322       ULONG		mTIM_5_LAST_COUNT;
323 
324       ULONG		mTIM_6_BKUP;
325       ULONG		mTIM_6_ENABLE_RELOAD;
326       ULONG		mTIM_6_ENABLE_COUNT;
327       ULONG		mTIM_6_LINKING;
328       ULONG		mTIM_6_CURRENT;
329       ULONG		mTIM_6_TIMER_DONE;
330       ULONG		mTIM_6_LAST_CLOCK;
331       ULONG		mTIM_6_BORROW_IN;
332       ULONG		mTIM_6_BORROW_OUT;
333       ULONG		mTIM_6_LAST_LINK_CARRY;
334       ULONG		mTIM_6_LAST_COUNT;
335 
336       ULONG		mTIM_7_BKUP;
337       ULONG		mTIM_7_ENABLE_RELOAD;
338       ULONG		mTIM_7_ENABLE_COUNT;
339       ULONG		mTIM_7_LINKING;
340       ULONG		mTIM_7_CURRENT;
341       ULONG		mTIM_7_TIMER_DONE;
342       ULONG		mTIM_7_LAST_CLOCK;
343       ULONG		mTIM_7_BORROW_IN;
344       ULONG		mTIM_7_BORROW_OUT;
345       ULONG		mTIM_7_LAST_LINK_CARRY;
346       ULONG		mTIM_7_LAST_COUNT;
347 
348       ULONG		mAUDIO_0_BKUP;
349       ULONG		mAUDIO_0_ENABLE_RELOAD;
350       ULONG		mAUDIO_0_ENABLE_COUNT;
351       ULONG		mAUDIO_0_LINKING;
352       ULONG		mAUDIO_0_CURRENT;
353       ULONG		mAUDIO_0_TIMER_DONE;
354       ULONG		mAUDIO_0_LAST_CLOCK;
355       ULONG		mAUDIO_0_BORROW_IN;
356       ULONG		mAUDIO_0_BORROW_OUT;
357       ULONG		mAUDIO_0_LAST_LINK_CARRY;
358       ULONG		mAUDIO_0_LAST_COUNT;
359       SBYTE		mAUDIO_0_VOLUME;
360       ULONG		mAUDIO_0_INTEGRATE_ENABLE;
361       ULONG		mAUDIO_0_WAVESHAPER;
362 
363       ULONG		mAUDIO_1_BKUP;
364       ULONG		mAUDIO_1_ENABLE_RELOAD;
365       ULONG		mAUDIO_1_ENABLE_COUNT;
366       ULONG		mAUDIO_1_LINKING;
367       ULONG		mAUDIO_1_CURRENT;
368       ULONG		mAUDIO_1_TIMER_DONE;
369       ULONG		mAUDIO_1_LAST_CLOCK;
370       ULONG		mAUDIO_1_BORROW_IN;
371       ULONG		mAUDIO_1_BORROW_OUT;
372       ULONG		mAUDIO_1_LAST_LINK_CARRY;
373       ULONG		mAUDIO_1_LAST_COUNT;
374       SBYTE		mAUDIO_1_VOLUME;
375       ULONG		mAUDIO_1_INTEGRATE_ENABLE;
376       ULONG		mAUDIO_1_WAVESHAPER;
377 
378       ULONG		mAUDIO_2_BKUP;
379       ULONG		mAUDIO_2_ENABLE_RELOAD;
380       ULONG		mAUDIO_2_ENABLE_COUNT;
381       ULONG		mAUDIO_2_LINKING;
382       ULONG		mAUDIO_2_CURRENT;
383       ULONG		mAUDIO_2_TIMER_DONE;
384       ULONG		mAUDIO_2_LAST_CLOCK;
385       ULONG		mAUDIO_2_BORROW_IN;
386       ULONG		mAUDIO_2_BORROW_OUT;
387       ULONG		mAUDIO_2_LAST_LINK_CARRY;
388       ULONG		mAUDIO_2_LAST_COUNT;
389       SBYTE		mAUDIO_2_VOLUME;
390       ULONG		mAUDIO_2_INTEGRATE_ENABLE;
391       ULONG		mAUDIO_2_WAVESHAPER;
392 
393       ULONG		mAUDIO_3_BKUP;
394       ULONG		mAUDIO_3_ENABLE_RELOAD;
395       ULONG		mAUDIO_3_ENABLE_COUNT;
396       ULONG		mAUDIO_3_LINKING;
397       ULONG		mAUDIO_3_CURRENT;
398       ULONG		mAUDIO_3_TIMER_DONE;
399       ULONG		mAUDIO_3_LAST_CLOCK;
400       ULONG		mAUDIO_3_BORROW_IN;
401       ULONG		mAUDIO_3_BORROW_OUT;
402       ULONG		mAUDIO_3_LAST_LINK_CARRY;
403       ULONG		mAUDIO_3_LAST_COUNT;
404       SBYTE		mAUDIO_3_VOLUME;
405       ULONG		mAUDIO_3_INTEGRATE_ENABLE;
406       ULONG		mAUDIO_3_WAVESHAPER;
407 
408       SBYTE		mAUDIO_OUTPUT[4];
409       UBYTE           mAUDIO_ATTEN[4];
410       ULONG		mSTEREO;
411       ULONG		mPAN;
412 
413       //
414       // Serial related variables
415       //
416       ULONG		mUART_RX_IRQ_ENABLE;
417       ULONG		mUART_TX_IRQ_ENABLE;
418 
419       ULONG		mUART_RX_COUNTDOWN;
420       ULONG		mUART_TX_COUNTDOWN;
421 
422       ULONG		mUART_SENDBREAK;
423       ULONG		mUART_TX_DATA;
424       ULONG		mUART_RX_DATA;
425       ULONG		mUART_RX_READY;
426 
427       ULONG		mUART_PARITY_ENABLE;
428       ULONG		mUART_PARITY_EVEN;
429 
430       int			mUART_CABLE_PRESENT;
431       void		(*mpUART_TX_CALLBACK)(int data,ULONG objref);
432       ULONG		mUART_TX_CALLBACK_OBJECT;
433 
434       int			mUART_Rx_input_queue[UART_MAX_RX_QUEUE];
435       unsigned int mUART_Rx_input_ptr;
436       unsigned int mUART_Rx_output_ptr;
437       int			mUART_Rx_waiting;
438       int			mUART_Rx_framing_error;
439       int			mUART_Rx_overun_error;
440 
441       //
442       // Screen related
443       //
444 
445       UBYTE		*mpDisplayBits;
446       UBYTE		*mpDisplayCurrent;
447       UBYTE		*mpRamPointer;
448       ULONG		mLynxLine;
449       ULONG		mLynxLineDMACounter;
450       ULONG		mLynxAddr;
451 
452       ULONG		mDisplayRotate;
453       ULONG		mDisplayFormat;
454       ULONG		mDisplayPitch;
455       UBYTE*		(*mpDisplayCallback)(ULONG objref);
456       ULONG		mDisplayCallbackObject;
457 };
458 
459 
460 #endif
461