home *** CD-ROM | disk | FTP | other *** search
/ Emulator Universe CD / emulatoruniversecd1998.iso / Speccy / Emulators / winemu / SOURCES / Z80 / PORTS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-21  |  5.0 KB  |  194 lines

  1. /* Ports.c: Z80 I/O - low level routines.
  2.  *
  3.  * Copyright 1996 Rui Fernando Ferreira Ribeiro.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include "env.h"
  21. #include <dos.h>
  22.  
  23.  
  24. /* keeps last out to ula --- handy to know the border colour */
  25. static UCHAR out_ula = 0;
  26.  
  27. /* count transition in beeper */
  28. static USHORT freq = 0;
  29.  
  30. /* constants to count time to calculate freq */
  31. long TimeBeep = 0;
  32. long Tinterval = 0;
  33.  
  34. /* returns colour of border */
  35. UCHAR get_sbrdr(void)
  36. {
  37.    return out_ula & 7;
  38. }
  39.  
  40. /* try to calculate frequency used */
  41. do_int_tasks()
  42. {
  43.    if(Tinterval)
  44.    {
  45.       freq = ((USHORT)(70938L/Tinterval))*50;
  46.       if((freq > 15000) || (freq < 200) )
  47.          freq = 0;
  48.    }
  49.    else
  50.       freq = 0;
  51.    TimeBeep = Tinterval = 0;
  52.    return freq;
  53. }
  54.  
  55. /*=========================================================================*
  56.  *                            writeport                                    *
  57.  *=========================================================================*/
  58. void writeport(port, value)
  59. USHORT port;
  60. UCHAR value;
  61. {
  62.    /* ULA -- b4 - ALTF  b3 - MIC b2b1b0 - BORDER
  63.     */
  64.  
  65.    /* Even port - ULA */
  66.    if(!(port & 1))
  67.    {
  68.       {
  69.          /* delay of 1T when dealing with ULA */
  70.          T(1);
  71.  
  72.      /***** Activate beeper *******/
  73.          if(bSoundOn)
  74.         outportb(0x61, (inportb(0x61) & 0xfc) | ((value & 0x10)?0:2) );
  75.      /* Again sound for windows
  76.       */
  77. #if defined(WINDOWS_SOUND)
  78.      if(value & 0x10)
  79.      {
  80.         Tinterval = clock_ticks - TimeBeep;
  81.             TimeBeep = clock_ticks;
  82.      }
  83. #else
  84. /***** Activate beeper *******/
  85.          if(bSoundOn)
  86.         outportb(0x61, (inportb(0x61) & 0xfc) | ((value & 0x10)?0:2) );
  87. #endif
  88.      out_ula = value;
  89.        }
  90.    }
  91. }
  92.  
  93. /* buffer teclado -- se uma tecla for premida ficara 1 no respectivo bit */
  94. /* keyboard buffer -- if key pressed corresponding bit = 1 */
  95. UCHAR keybd_buff[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  96.  
  97. /* Spectrum keyboard :
  98.      port high byte (low level active)
  99.      multiples rows can be active at the same time
  100.  
  101.           Scan disposition:
  102.  
  103.              b3   b4
  104.              b2   b5
  105.              b1   b6
  106.              b0   b7
  107.  
  108. each scan line has 5 bits (5 keys, low level active):
  109.  
  110.      Left side: b0b1b2b3b4       Right side: b4b3b2b1b0
  111.  
  112.  When multiple scan lines are active, it will be made a 'and' operation between
  113. their values to get the final value ; ghost keys are generated with that
  114. operation
  115.  
  116.  
  117. KEYS:
  118.  
  119. */
  120.  
  121. UCHAR joystick = 0x00;      /*     FIRE  UP  DOWN  RIGHT LEFT */
  122.                 /* 000  b4   b3   b2    b1    b0  */
  123.  
  124.  
  125. /*=========================================================================*
  126.  *                            readport                                     *
  127.  *=========================================================================*/
  128. UCHAR readport(port)
  129. USHORT port;
  130. {
  131.    UCHAR value = 0xff;
  132.    static UCHAR lport;
  133.  
  134.    /* ULA --  b7  b6    b5 b4b3b2b1b0 */
  135.    /*         1   1    EAR  KEY_CODE  */
  136.  
  137.                
  138.  
  139.    lport = ~(UCHAR)port;  
  140.    /* Joystick has precedence over keyboard -- Street Hawk, Command4
  141.       Every major emulator got this wrong except Specem (aka Irish emulator)
  142.     */
  143.    if(lport & 0x20) /* joystick */
  144.       value = joystick;
  145.    else
  146.       /* Port par - ULA */
  147.       if(lport & 1)
  148.       {
  149.      UCHAR  i = 0, tmp_value, t_val = 1;
  150.      UCHAR  scan_stat = ~(port >> 8);
  151.  
  152.      /* delay of 1T when dealing with ULA */
  153.          T(1);
  154.      value = 0;
  155.      /* scan keyboard -- multiple rows can be active
  156.       */
  157.      for(i = 0 ; i < 8 ; i++)
  158.      {
  159.         if(t_val & scan_stat)
  160.         {
  161.            value |= keybd_buff[i];
  162.         }
  163.         t_val <<= 1;
  164.      }
  165.  
  166.      /* Now it's time to test for ghost keys.
  167.       */
  168.      tmp_value = value;
  169.      for(i = 0 ; i < 8 ; i++)
  170.      {
  171.         if(tmp_value & *(keybd_buff+i))
  172.            value |= *(keybd_buff+i);
  173.       }
  174.       /* And finally we have the Spectrum value of port
  175.          0x40 is the difference between model 3 and model 2
  176.        */                                           
  177.       value = (~value)  & (bModel3?((UCHAR)0xBF):(UCHAR)0xFF);
  178.       return value;                                       
  179.        }
  180.        else
  181.        /* Any other port --- this is not well implemented
  182.     */
  183.        if(clock_ticks < (USHORT)57121u)
  184.       value = clock_ticks/224;
  185.     else
  186.        value = 0xFF;
  187.     /*  if(clock_ticks > (USHORT)14368u)
  188.       {
  189.       }*/
  190.    return(value);
  191. }                                                           
  192.  
  193. /* EOF: Ports.c */
  194.