wrapemu.cpp
  1  #include <string.h>
  2  
  3  #include "emuapi.h"
  4  
  5  #include "dcastaway.h"
  6  #include "st.h"
  7  #include "mem.h"
  8  #include "m68k_intrf.h"
  9  #include "xram.h"
 10  #include "iopins.h"
 11  
 12  
 13  
 14  #ifndef NO_SOUND  
 15  #include "sound.h"
 16  #endif
 17  
 18  #include "tossw14.h"
 19  
 20  static bool hires = true;
 21  
 22  int8 *membase;
 23  int8 *rombase;
 24  
 25  static int hbl = 0;
 26  static int hsync = 0;
 27  static int vsyncpend = 0, hsyncpend = 0;
 28  
 29  int exmousex=160,exmousey=100;
 30  int CompleteSndBufIdx; 
 31  int waitstate=0;
 32  int maybe_border=0;
 33  unsigned cyclenext=512;
 34  unsigned vid_adr_cycleyet=0;
 35  static unsigned char vid_cycles_pal[1024];
 36  unsigned char *vid_cycle=(unsigned char *)&vid_cycles_pal;
 37  extern unsigned char fdc_motor;
 38  
 39  #define XRES 320
 40  #define YRES 200
 41  
 42  static unsigned short line[XRES*2]; // max 640 pixels in hires
 43  
 44  
 45  #define PALMULT8(x)  ((x)<<5)
 46  #define RGBVAL16(r,g,b)  ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
 47  
 48  void Redraw16 ( int row, int vid_adr ) 
 49  {
 50    static unsigned short palmap [ 16 ];
 51    register unsigned short *line_i;
 52    line_i = (unsigned short *)(&membase[vid_adr]);
 53    register unsigned short *line_o= &line[0];
 54    if (vid_flag) {
 55      unsigned char i, r, g, b;
 56      for (i = 0; i < 16; i++) {
 57        b = PALMULT8 ( (vid_col[i] & 0x7) );
 58        g = PALMULT8 ( ((vid_col[i] >> 4) & 0x7) );
 59        r = PALMULT8 ( ((vid_col[i] >> 8) & 0x7) );
 60        palmap [ i ] = RGBVAL16(r,g,b); 
 61      }
 62      vid_flag=0;
 63    }
 64    register int col;
 65    register int bit;
 66    for (col=0; col<20; col++) {
 67      register unsigned short pl0=*line_i++,pl1=*line_i++,pl2=*line_i++,pl3=*line_i++;
 68      for (bit=15;bit>=0;bit--) {
 69        int ind = (pl0 >> bit) & 0x1;
 70        ind += ((pl1 >> bit) & 0x1)<<1;
 71        ind += ((pl2 >> bit) & 0x1)<<2;
 72        ind += ((pl3 >> bit) & 0x1)<<3;
 73        *line_o++ = palmap [ ind ]; 
 74      }
 75    }
 76    if (hires) {
 77      emu_DrawLine16(&line[0], XRES, YRES*2, row*2);  
 78      emu_DrawLine16(&line[0], XRES, YRES*2, row*2+1);  
 79    }
 80    else {
 81      emu_DrawLine16(&line[0], XRES, YRES, row);
 82    }
 83  }
 84  
 85  void Redraw16_med ( int row, int vid_adr )
 86  {
 87    static unsigned short palmap [ 4 ];
 88    register unsigned short *line_i;
 89    line_i = (unsigned short *)(&membase[vid_adr]);
 90    register unsigned short *line_o= &line[0];
 91    if (vid_flag) {
 92      unsigned char i, r, g, b;
 93      for (i = 0; i < 4; i++) {
 94        b = PALMULT8 ( (vid_col[i] & 0x7) );
 95        g = PALMULT8 ( ((vid_col[i] >> 4) & 0x7) );
 96        r = PALMULT8 ( ((vid_col[i] >> 8) & 0x7) );
 97        palmap [ i ] = RGBVAL16(r,g,b); 
 98      }
 99      vid_flag=0;
100    }
101    register int col;
102    register int bit;
103    for (col=0; col<40; col++) {
104      register unsigned short pl0=*line_i++,pl1=*line_i++;
105      for (bit=15;bit>=0;bit--) {
106        int ind = (pl0 >> bit) & 0x1;
107        ind += ((pl1 >> bit) & 0x1)<<1;
108        if (hires) {
109          *line_o++ = palmap [ ind ]; 
110        }
111        else {
112          if (bit & 0x01)
113            *line_o++ = palmap [ ind ]; 
114        }      
115      }
116    }
117    if (hires) {
118      emu_DrawLine16(&line[0], XRES*2, YRES*2, row*2);  
119      emu_DrawLine16(&line[0], XRES*2, YRES*2, row*2+1);  
120    }
121    else {
122      emu_DrawLine16(&line[0], XRES, YRES, row);
123    }
124  }
125  
126  void Redraw16_hi ( int row, int vid_adr ) 
127  {
128    if (hires) {
129    static unsigned short palmap [ 2 ];
130      register unsigned short *line_i;
131      line_i = (unsigned short *)(&membase[vid_adr]);
132      register unsigned short *line_o= &line[0];
133      if (vid_flag) {
134        palmap [ 0 ] = RGBVAL16(0xff,0xff,0xff); 
135        palmap [ 1 ] = RGBVAL16(0x00,0x00,0x00); 
136        vid_flag=0;
137      }
138      register int col;
139      register int bit;
140      for (col=0; col<40; col++) {
141        register unsigned short pl0=*line_i++;
142        for (bit=15;bit>=0;bit--) {
143          int ind = (pl0 >> bit) & 0x1;
144          *line_o++ = palmap [ ind ]; 
145        }
146      }
147      emu_DrawLine16(&line[0], XRES*2, YRES*2, row*2);  
148      line_o= &line[0];   
149      for (col=0; col<40; col++) {
150        register unsigned short pl0=*line_i++;
151        for (bit=15;bit>=0;bit--) {
152          int ind = (pl0 >> bit) & 0x1;
153          *line_o++ = palmap [ ind ]; 
154        }
155      }
156      emu_DrawLine16(&line[0], XRES*2, YRES*2, row*2+1);  
157    }
158  }
159  
160  
161  void ast_Init(void)
162  {
163    hires = emu_IsVgaHires()?true:false;  
164  
165    emu_printf("Allocating RAM");
166    membase = (int8*)xram_MemPool();
167  
168    for (int i=0; i<MEMSIZE;i++)
169      membase[i]=0; 
170          
171    rombase = (int8*)&tos[0]-ROMBASE;   
172    (void) memcpy (membase, &tos[0], 8);
173  }
174  
175  static int mouse_x = XRES/2;
176  static int mouse_y = 100;
177  static int prev_mouse_x = XRES/2;
178  static int prev_mouse_y = 100;
179  
180  static int prev_key = 0; 
181  static int prev_j = 0; 
182  static int prev_mouseb1 = 0;
183  static int prev_mouseb2 = 0;
184  static bool isMouse = true;
185  static int joynum = 1;
186  static int hk = 0;
187  static int prev_hk = 0;
188  static int k = 0;
189  static int prev_k = 0;
190  
191  
192  #define INV_KEY 0
193  
194  const int16_t keyboardAsciiConv[] = // QWERTY Keyboard
195  {
196  /* 0x00 */ INV_KEY,
197  /* 0x01 */ INV_KEY,
198  /* 0x02 */ INV_KEY,
199  /* 0x03 */ INV_KEY,
200  /* 0x04 */ INV_KEY,
201  /* 0x05 */ INV_KEY,
202  /* 0x06 */ INV_KEY,
203  /* 0x07 */ INV_KEY,
204  /* 0x08 */ INV_KEY,
205  /* 0x09 */ 0x0f,     // tab
206  /* 0x0A */ 0x1C,     // enter
207  /* 0x0B */ INV_KEY,
208  /* 0x0C */ INV_KEY,
209  /* 0x0D */ INV_KEY,
210  /* 0x0E */ INV_KEY,
211  /* 0x0F */ INV_KEY,
212  /* 0x10 */ INV_KEY,
213  /* 0x11 */ INV_KEY,
214  /* 0x12 */ INV_KEY,
215  /* 0x13 */ INV_KEY,
216  /* 0x14 */ INV_KEY,
217  /* 0x15 */ INV_KEY,
218  /* 0x16 */ INV_KEY,
219  /* 0x17 */ INV_KEY,
220  /* 0x18 */ INV_KEY,
221  /* 0x19 */ INV_KEY,
222  /* 0x1A */ INV_KEY,
223  /* 0x1B */ 0x01,     // esc
224  /* 0x1C */ INV_KEY,
225  /* 0x1D */ INV_KEY,
226  /* 0x1E */ INV_KEY,
227  /* 0x1F */ INV_KEY,
228  /* 0x20 */ 0x39,     // space
229  /* 0x21 */ INV_KEY,
230  /* 0x22 */ INV_KEY,
231  /* 0x23 */ INV_KEY,
232  /* 0x24 */ INV_KEY,
233  /* 0x25 */ INV_KEY,
234  /* 0x26 */ 43,       // ampercent (backslash)
235  /* 0x27 */ 40,       // single quote
236  /* 0x28 */ 26,       // bracket left
237  /* 0x29 */ 27,       // bracket right
238  /* 0x2A */ INV_KEY,  // mult *
239  /* 0x2B */ INV_KEY,
240  /* 0x2C */ 51,       // comma ,
241  /* 0x2D */ 12,       // minus -
242  /* 0x2E */ 52,       // period .
243  /* 0x2F */ 53,       // slash /
244  /* 0x30 */ 0x0B,     // 0
245  /* 0x31 */ 0x02,
246  /* 0x32 */ 0x03,
247  /* 0x33 */ 0x04,
248  /* 0x34 */ 0x05,
249  /* 0x35 */ 0x06,
250  /* 0x36 */ 0x07,
251  /* 0x37 */ 0x08,
252  /* 0x38 */ 0x09,
253  /* 0x39 */ 0x0A,     // 9
254  /* 0x3A */ INV_KEY,  // colon :
255  /* 0x3B */ 39,       // semi colon ;
256  /* 0x3C */ INV_KEY,
257  /* 0x3D */ 13,       // equal =
258  /* 0x3E */ INV_KEY,
259  /* 0x3F */ INV_KEY,
260  /* 0x40 */ INV_KEY,
261  /* 0x41 */ INV_KEY,
262  /* 0x42 */ INV_KEY,
263  /* 0x43 */ INV_KEY,
264  /* 0x44 */ INV_KEY,
265  /* 0x45 */ INV_KEY,
266  /* 0x46 */ INV_KEY,
267  /* 0x47 */ INV_KEY,
268  /* 0x48 */ INV_KEY,
269  /* 0x49 */ INV_KEY,
270  /* 0x4A */ INV_KEY,
271  /* 0x4B */ INV_KEY,
272  /* 0x4C */ INV_KEY,
273  /* 0x4D */ INV_KEY,
274  /* 0x4E */ INV_KEY,
275  /* 0x4F */ INV_KEY,
276  /* 0x50 */ INV_KEY,
277  /* 0x51 */ INV_KEY,
278  /* 0x52 */ INV_KEY,
279  /* 0x53 */ INV_KEY,
280  /* 0x54 */ INV_KEY,
281  /* 0x55 */ INV_KEY,
282  /* 0x56 */ INV_KEY,
283  /* 0x57 */ INV_KEY,
284  /* 0x58 */ INV_KEY,
285  /* 0x59 */ INV_KEY,
286  /* 0x5A */ INV_KEY,
287  /* 0x5B */ INV_KEY,
288  /* 0x5C */ INV_KEY,
289  /* 0x5D */ INV_KEY,
290  /* 0x5E */ INV_KEY,
291  /* 0x5F */ INV_KEY,
292  /* 0x60 */ INV_KEY,
293  /* 0x61 */ 0x1E,    // A
294  /* 0x62 */ 0x30,    // B
295  /* 0x63 */ 0x2E,    // C
296  /* 0x64 */ 0x20,    // D
297  /* 0x65 */ 0x12,    // E
298  /* 0x66 */ 0x21,    // F
299  /* 0x67 */ 0x22,    // G
300  /* 0x68 */ 0x23,    // H
301  /* 0x69 */ 0x17,    // I
302  /* 0x6A */ 0x24,    // J
303  /* 0x6B */ 0x25,    // K
304  /* 0x6C */ 0x26,    // L
305  /* 0x6D */ 0x32,    // M
306  /* 0x6E */ 0x31,    // N
307  /* 0x6F */ 0x18,    // O
308  /* 0x70 */ 0x19,    // P
309  /* 0x71 */ 0x10,    // Q
310  /* 0x72 */ 0x13,    // R
311  /* 0x73 */ 0x1F,    // S
312  /* 0x74 */ 0x14,    // T
313  /* 0x75 */ 0x16,    // U
314  /* 0x76 */ 0x2F,    // V
315  /* 0x77 */ 0x11,    // W
316  /* 0x78 */ 0x2D,    // X
317  /* 0x79 */ 0x15,    // Y
318  /* 0x7A */ 0x2C,    // Z
319  /* 0x7B */ INV_KEY,
320  /* 0x7C */ INV_KEY,
321  /* 0x7D */ INV_KEY,
322  /* 0x7E */ INV_KEY,
323  /* 0x7F */ 0x0E     // backspace
324  };
325  
326  
327  const int16_t keyboardSpecialConv[] = // Functions and other keys
328  {
329  /* 0xC0 */ INV_KEY,
330  /* 0xC1 */ INV_KEY,
331  /* 0xC2 */ 0x3b,   // F1
332  /* 0xC3 */ 0x3c,   // F2
333  /* 0xC4 */ 0x3d,   // F3
334  /* 0xC5 */ 0x3e,   // F4
335  /* 0xC6 */ 0x3f,   // F5
336  /* 0xC7 */ 0x40,   // F6
337  /* 0xC8 */ 0x41,   // F7
338  /* 0xC9 */ 0x42,   // F8
339  /* 0xCA */ 0x43,   // F9
340  /* 0xCB */ 0x44,   // F10
341  /* 0xCC */ INV_KEY,
342  /* 0xCD */ INV_KEY,
343  /* 0xCE */ INV_KEY,
344  /* 0xCF */ INV_KEY,
345  /* 0xD0 */ INV_KEY,
346  /* 0xD1 */ INV_KEY,
347  /* 0xD2 */ INV_KEY,
348  /* 0xD3 */ INV_KEY,
349  /* 0xD4 */ INV_KEY, // DEL
350  /* 0xD5 */ INV_KEY,
351  /* 0xD6 */ INV_KEY,
352  /* 0xD7 */ INV_KEY,
353  /* 0xD8 */ INV_KEY,
354  /* 0xD9 */ INV_KEY,
355  /* 0xDA */ INV_KEY,
356  /* 0xDB */ INV_KEY,
357  /* 0xDC */ INV_KEY,
358  /* 0xDD */ INV_KEY,
359  /* 0xDE */ INV_KEY,
360  /* 0xDF */ INV_KEY
361  };
362  
363  
364  
365  void emu_KeyboardOnDown(int keymodifer, int key) {
366    //emu_printi(key);
367    int keyCode = INV_KEY;
368    if ((key >=0xc0) && (key <=0xdf)) {
369      keyCode = keyboardSpecialConv[(key-0xc0) & 0x1f];    
370    }
371    else {
372      keyCode = keyboardAsciiConv[key & 0x7f];
373    }  
374    //emu_printi(keyCode);
375  
376    IkbdKeyPress ( keyCode );
377  }
378  
379  void emu_KeyboardOnUp(int keymodifer, int key) {
380    int keyCode = INV_KEY;
381    if ((key >=0xc0) && (key <=0xdf)) {
382      keyCode = keyboardSpecialConv[(key-0xc0) & 0x1f];    
383    }
384    else {
385      keyCode = keyboardAsciiConv[key & 0x7f];
386    }     
387    IkbdKeyRelease ( keyCode );
388  }
389  
390  
391  extern void ast_Input(int click) {
392    hk = emu_ReadI2CKeyboard();
393    k = emu_ReadKeys();   
394  }
395  
396  static void do_events(void) 
397  {
398    int bClick = k & ~prev_k;
399    prev_k = k;
400    int  mouseb1 = prev_mouseb1;
401    int  mouseb2 = prev_mouseb2;  
402    
403    // Toggle keymap + mouse/joystick
404    if (bClick & MASK_KEY_USER2) {
405      if (isMouse) isMouse = false;
406      else isMouse = true;
407  //#ifndef HAS_T4_VGA     
408      emu_setKeymap(0);
409  //#endif  
410    }
411    
412  
413    // force joystick mode if mouse detected
414    if (emu_MouseDetected() ) isMouse = false;
415    
416    if (hk != prev_hk) {
417      prev_hk = hk;
418      if ( (hk != 0) && (hk != prev_key) ) {     
419        prev_key = hk;
420        int keyCode = INV_KEY;
421        if ((prev_key >=0xc0) && (prev_key <=0xdf)) {
422          keyCode = keyboardSpecialConv[(prev_key-0xc0) & 0x1f];    
423        }
424        else {
425          keyCode = keyboardAsciiConv[prev_key & 0x7f];
426        }  
427        IkbdKeyPress ( keyCode );
428      }     
429    }
430    if ( (hk == 0) && (prev_key) ) {
431        int keyCode = INV_KEY;
432        if ((prev_key >=0xc0) && (prev_key <=0xdf)) {
433          keyCode = keyboardSpecialConv[(prev_key-0xc0) & 0x1f];    
434        }
435        else {
436          keyCode = keyboardAsciiConv[prev_key & 0x7f];
437        }  
438        IkbdKeyRelease ( keyCode /*| 0x80*/ );
439        prev_key = 0;
440    }
441  
442    int buts,dx,dy;
443    int mouseEvent = emu_GetMouse(&dx,&dy,&buts);
444    if (mouseEvent){
445      mouse_x += dx;
446      if ( (vid_shiftmode==COL2) && (hires) ) {
447          if ( mouse_x >= XRES*2 ) {
448            mouse_x = XRES*2-1;
449          }      
450      }
451      else {
452        if ( mouse_x >= XRES ) {
453          mouse_x = XRES-1;
454        }        
455      }
456       
457      if ( mouse_x < 0 ) {
458        mouse_x = 0;     
459      }
460      mouse_y += dy;
461      if ( mouse_y >= YRES ) {
462        mouse_y = YRES-1;
463      } 
464      else if ( mouse_y < 0 ) {
465        mouse_y = 0;      
466      }
467      
468      if (buts & 0x1) {
469        mouseb1 |=1; 
470      }
471      else {
472        mouseb1 &=~1;       
473      }
474      if (buts & 0x2) {
475        mouseb2 |=1;
476      }
477      else {
478        mouseb2 &=~1;     
479      }
480    }
481  
482    if (!isMouse)
483    {
484      int j = 0;     
485      if (( k & MASK_JOY1_LEFT) || ( k & MASK_JOY2_LEFT)) {
486        j |= 0x04;
487      }
488      if (( k & MASK_JOY1_RIGHT) || ( k & MASK_JOY2_RIGHT)) {
489        j |= 0x08;
490      }
491      if (( k & MASK_JOY1_UP) || ( k & MASK_JOY2_UP)) {
492        j |= 0x01;
493      }
494      if (( k & MASK_JOY1_DOWN) || ( k & MASK_JOY2_DOWN)) {
495        j |= 0x02;
496      }  
497      if (( k & MASK_JOY1_BTN) || ( k & MASK_JOY2_BTN)) {
498        j |= 0x80;
499      }
500      if (j != prev_j) {
501        IkbdJoystickChange(joynum,j);
502        prev_j = j;
503      }
504    }
505    else {
506      if (( k & MASK_JOY1_RIGHT) || ( k & MASK_JOY2_RIGHT)) {
507        mouse_x += 1;
508        if ( (vid_shiftmode==COL2) && (hires) ) {
509            if ( mouse_x >= XRES*2 ) {
510              mouse_x = XRES*2-1;
511            }      
512        }
513        else {
514          if ( mouse_x >= XRES ) {
515            mouse_x = XRES-1;
516          }        
517        }
518      }
519      else if (( k & MASK_JOY1_LEFT) || ( k & MASK_JOY2_LEFT)) {
520        mouse_x -= 1;       
521        if ( mouse_x < 0 ) {
522          mouse_x = 0;       
523        }
524      }
525      else if (( k & MASK_JOY1_UP) || ( k & MASK_JOY2_UP)) {
526        mouse_y -= 1;       
527        if ( mouse_y < 0 ) {
528          mouse_y = 0;
529        }
530      }
531      else if (( k & MASK_JOY1_DOWN) || ( k & MASK_JOY2_DOWN)) {
532        mouse_y += 1;       
533        if ( mouse_y >= YRES ) {
534           mouse_y = YRES-1;
535       }
536      }  
537      
538      if (( k & MASK_JOY1_BTN) || ( k & MASK_JOY2_BTN)) {
539        mouseb1 |= 1;
540      }
541      else  {
542        mouseb1 &=~1;  
543      }
544      if (( k & MASK_KEY_USER1)) {
545        mouseb2 |= 1;
546      }
547      else  {
548        mouseb2 &=~1;  
549      }    
550    }
551  
552    if ( (prev_mouse_x != mouse_x) | (prev_mouse_y != mouse_y) ) {
553        IkbdMouseMotion ( mouse_x, mouse_y );
554        IkbdLoop(); 
555        prev_mouse_x = mouse_x;
556        prev_mouse_y = mouse_y;
557    }
558  
559  
560    if ( (mouseb1 != prev_mouseb1) ){
561      if (mouseb1) {
562        IkbdMousePress(2);
563        //emu_printf("b1p");
564      }
565      else {
566        IkbdMouseRelease(2);
567        //emu_printf("b1r");
568      }
569      IkbdLoop();
570      prev_mouseb1 = mouseb1;  
571    }    
572    if ( (mouseb2 != prev_mouseb2) ){
573      if (mouseb2) {
574        IkbdMousePress(1);
575        //emu_printf("b2p");
576      }
577      else {
578        IkbdMouseRelease(1);
579        //emu_printf("b2r");
580      }
581      IkbdLoop();
582      prev_mouseb2 = mouseb2;  
583    }    
584  }     
585  
586  
587  
588  void ast_Step(void)
589  {
590    int delay_fdc_motor=0;
591    unsigned long cycleco=0;
592    unsigned long oldpend,newpend;
593    hsync=0;
594    hbl=0;
595    vsyncpend=0;
596    hsyncpend=0;
597  
598    int running = 1;
599   /* Event loop */
600    while (running) 
601    {
602        cycleco=cpu_loop(cyclenext);
603        cycleco+=waitstate;
604        waitstate=0;
605  #ifndef NO_SOUND
606        SoundCycles+=cycleco;
607  #endif            
608        //MFP timer A delay mode
609        if (mfp_ascale>1) {
610            mfp_acount-=mfp_ascale*cycleco;
611            if (mfp_acount<=0) {
612              do {mfp_acount+=mfp_tadr;} while (mfp_acount<=0);
613              oldpend=mfp_ipra; newpend=(oldpend|0x20)&mfp_iera;
614              if (newpend!=oldpend) {mfp_ipra=newpend;
615  
616              }
617            }
618    #ifdef USE_SHORT_SLICE
619            cyclenext=4+(mfp_acount/mfp_ascale);
620    #endif
621        }
622    #ifdef USE_SHORT_SLICE
623        else
624            cyclenext=512;
625    #endif
626        //MFP timer B delay mode
627        if (mfp_bscale>1) {
628            mfp_bcount-=mfp_bscale*cycleco;
629            if (mfp_bcount<=0) {
630              do {mfp_bcount+=mfp_tbdr;} while (mfp_bcount<=0);
631                oldpend=mfp_ipra; newpend=(oldpend|0x1)&mfp_iera;
632                if (newpend!=oldpend) {mfp_ipra=newpend;
633                }
634            }
635    #ifdef USE_SHORT_SLICE
636            {
637                int n=4+(mfp_bcount/mfp_bscale);
638                if (n<cyclenext)
639                    cyclenext=n;
640            }
641    #endif
642        }
643        //MFP timer C delay mode
644        if (mfp_cscale>1) {
645            mfp_ccount-=mfp_cscale*cycleco;
646            if (mfp_ccount<=0) {
647              do {mfp_ccount+=mfp_tcdr;} while (mfp_ccount<=0);
648                oldpend=mfp_iprb; newpend=(oldpend|0x20)&mfp_ierb;
649                if (newpend!=oldpend) {mfp_iprb=newpend;
650                }
651            }
652    #ifdef USE_SHORT_SLICE
653            {
654                int n=4+(mfp_ccount/mfp_cscale);
655                if (n<cyclenext)
656                    cyclenext=n;
657            }
658    #endif
659        }
660        //MFP timer D delay mode
661        if (mfp_dscale>1) {
662            mfp_dcount-=mfp_dscale*cycleco;
663            if (mfp_dcount<=0) {
664              do {mfp_dcount+=mfp_tddr;} while (mfp_dcount<=0);
665                oldpend=mfp_iprb; newpend=(oldpend|0x10)&mfp_ierb;
666                if (newpend!=oldpend) {mfp_iprb=newpend;
667                }
668            }
669    #ifdef USE_SHORT_SLICE
670            {
671                int n=4+(mfp_dcount/mfp_dscale);
672                if (n<cyclenext)
673                    cyclenext=n;
674            }
675    #endif
676        }
677      
678        
679        vid_adr+=(cycleco)&(~3);
680  
681        //Count hbls
682        hsync-=cycleco;
683  
684      if (hsync<=0) {
685        hbl++; hsync+=512;
686        //Generate hbl interrupt
687        Interrupt(AUTOINT2, 2);
688        
689  
690        //Trigger event counters for visible scan-lines
691        if (hbl<64) {
692          vid_adr=(vid_baseh<<16)+(vid_basem<<8);
693        }
694        else if (hbl<264) {
695          if ( (hbl == 132 )) {
696  //        if ( (hbl % (end_visible_screen/2) ) == 0) {
697              //CPUEvent();
698              //timer_tick = 1; 
699            }
700          //Do IO every 64 hbls
701          if (!(hbl&63)) {
702            //Generate FDC interrupt in mfp?
703            if (!(mfp_gpip & 0x20)) {
704              mfp_iprb |= 0x80;
705              mfp_iprb &= mfp_ierb;           
706            } 
707            //Generate ACIA interrupt in mfp?
708            IkbdWriteBuffer();
709            if (!(mfp_gpip & 0x10)) {
710              mfp_iprb |= 0x40;
711              mfp_iprb &= mfp_ierb;           
712            }
713          }
714  
715  
716          if (emu_FrameSkip() == 0 ) {
717            //Update video address and draw screen line
718            vid_adr=(vid_baseh<<16)+(vid_basem<<8)+(hbl-64)*160;
719            if (vid_shiftmode==MONO) {
720              Redraw16_hi( hbl - 64, vid_adr );
721            }  
722            else if (vid_shiftmode==COL2) {
723              Redraw16_med( hbl - 64, vid_adr );
724            } else {
725              Redraw16( hbl - 64, vid_adr );
726            }        
727          }
728  
729          //Timer-A event count mode
730          if (mfp_ascale==1) {
731            mfp_acount-=1048576;
732            if (mfp_acount<=0) {
733              mfp_acount=mfp_tadr;
734              oldpend=mfp_ipra; newpend=(oldpend|0x20)&mfp_iera;
735              if (newpend!=oldpend) {mfp_ipra=newpend;
736              }
737            }
738          }
739          //Timer-B event count mode
740          if (mfp_bscale==1) {
741            mfp_bcount-=1048576;
742            if (mfp_bcount<=0) {
743              mfp_bcount=mfp_tbdr;
744              oldpend=mfp_ipra; newpend=(oldpend|0x1)&mfp_iera;
745              if (newpend!=oldpend) {mfp_ipra=newpend;
746              }
747            }
748          }
749        }
750  
751  
752        //Vertical blank?
753        else if (hbl>=313)
754        {
755          emu_DrawVsync();
756          do_events();
757  #ifndef NO_SOUND  
758          Sound_Update_VBL();
759  #endif        
760          running=0;  
761  
762               
763          hbl=0;
764          //Generate vsync interrupt
765          Interrupt(AUTOINT4, 4);
766          //Do fdc spinup
767          if (fdc_motor){
768            if (delay_fdc_motor>150) {
769              fdc_status &= ~0x80;
770              delay_fdc_motor=0;
771              fdc_motor=0;
772            }
773            else delay_fdc_motor++;
774          }
775        }
776      }
777  
778  
779      //Recalculate interrupts?
780      {
781        if (6>GetI()) {
782          //Mfp interrupt
783          {
784            int number;
785            uint16 imr, ipr, isr, irr;
786            int in_request;
787            //Find in_request and in_service
788            imr = (mfp_imra<<8)+mfp_imrb;
789            ipr = (mfp_ipra<<8)+mfp_iprb;
790            irr = imr & ipr;
791            isr = (mfp_isra<<8) + mfp_isrb;
792            //in_request higher than in_service?
793            if (irr>isr) {
794              //Find highest set bit
795              for (in_request = 15; in_request > 0; in_request--) {
796                if (irr & 0x8000) break;
797                irr <<= 1;
798              }
799              isr = 1 << in_request;
800              //Set interrupt in service bits in MFP
801              if (mfp_ivr & 0x8) {
802                mfp_isra |= isr >> 8;
803                mfp_isrb |= isr;
804              }else{
805                mfp_isra &= (~isr) >> 8;
806                mfp_isrb &= ~isr;
807              }
808              //Clear interrupt pending bits in MFP
809              mfp_ipra &= ~(isr >> 8);
810              mfp_iprb &= ~isr;
811              //Pass interrupt to cpu
812              number = in_request | (mfp_ivr & 0xf0);
813              Interrupt(number, 6);
814            }
815          }
816        }     
817      }
818    }
819  }
820  
821  
822  void ast_Start(char * floppy1, char * floppy2, int mode)
823  {
824    if (mode) display_mode = MONO;
825    
826    emu_printf("init started");
827    strncpy (disk[0].name, floppy1, strlen(floppy1));
828    strncpy (disk[1].name, floppy2, strlen(floppy2));
829  
830    initialize_memmap();
831    FDCInit(0);
832    FDCInit(1);
833    //FDCeject(0);
834    //FDCeject(1);
835    IkbdReset(); 
836    IOInit();   
837  #ifdef HAS_SND
838    emu_sndInit();
839  #endif 
840  #ifndef NO_SOUND
841  #ifdef HAS_SND 
842    Sound_Init(); 
843  #endif  
844  #endif   
845  
846    HWReset(); /* CPU Reset */
847  
848    emu_printf("init done");
849  }
850  
851  void SND_Process(void *stream, int len) {
852  #ifndef NO_SOUND
853  #ifdef HAS_SND 
854    Sound_UpdateFromCallBack16((short *)stream, len);
855  #endif  
856  #endif
857  }