Annotation of hatari/src/psg.c, revision 1.1.1.6

1.1       root        1: /*
1.1.1.4   root        2:   Hatari - psg.c
1.1       root        3: 
1.1.1.4   root        4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
1.1.1.3   root        6: 
1.1.1.4   root        7:   Programmable Sound Generator (YM-2149) - PSG
1.1.1.3   root        8: 
1.1.1.4   root        9:   Also used for the printer (centronics) port emulation (PSG Port B, Register 15)
1.1       root       10: */
1.1.1.6 ! root       11: const char PSG_rcsid[] = "Hatari $Id: psg.c,v 1.10 2006/02/08 22:49:27 eerot Exp $";
1.1       root       12: 
                     13: #include "main.h"
1.1.1.3   root       14: #include "configuration.h"
1.1.1.4   root       15: #include "ioMem.h"
1.1.1.5   root       16: #include "joy.h"
1.1.1.4   root       17: #include "m68000.h"
1.1       root       18: #include "memorySnapShot.h"
                     19: #include "sound.h"
1.1.1.4   root       20: #include "printer.h"            /* because Printer I/O goes through PSG Register 15 */
1.1.1.3   root       21: #include "psg.h"
                     22: 
1.1       root       23: 
1.1.1.4   root       24: Uint8 PSGRegisterSelect;        /* 0xff8800 (read/write) */
                     25: Uint8 PSGRegisters[16];         /* Register in PSG, see PSG_REG_xxxx */
                     26: 
                     27: static BOOL bLastWriteToIOB;    /* boolean flag: did the last write to the PSG go to IOB? */
1.1       root       28: 
                     29: 
                     30: /*-----------------------------------------------------------------------*/
                     31: /*
                     32:   Reset variables used in PSG
                     33: */
                     34: void PSG_Reset(void)
                     35: {
1.1.1.4   root       36:        PSGRegisterSelect = 0;
                     37:        memset(PSGRegisters, 0, sizeof(PSGRegisters));
                     38:        bLastWriteToIOB = FALSE;
1.1       root       39: }
                     40: 
1.1.1.2   root       41: 
                     42: /*-----------------------------------------------------------------------*/
1.1       root       43: /*
1.1.1.4   root       44:   Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
1.1       root       45: */
                     46: void PSG_MemorySnapShot_Capture(BOOL bSave)
                     47: {
1.1.1.4   root       48:        /* Save/Restore details */
                     49:        MemorySnapShot_Store(&PSGRegisterSelect, sizeof(PSGRegisterSelect));
                     50:        MemorySnapShot_Store(PSGRegisters, sizeof(PSGRegisters));
                     51:        MemorySnapShot_Store(&bLastWriteToIOB, sizeof(bLastWriteToIOB));
1.1       root       52: }
                     53: 
1.1.1.2   root       54: 
                     55: /*-----------------------------------------------------------------------*/
1.1       root       56: /*
1.1.1.4   root       57:   Write byte to 0xff88000, this is used as a selector for when we read/write
                     58:   to address 0xff8802
1.1       root       59: */
1.1.1.4   root       60: void PSG_SelectRegister_WriteByte(void)
1.1       root       61: {
1.1.1.6 ! root       62:        M68000_WaitState(4);
1.1.1.4   root       63: 
1.1.1.6 ! root       64:        PSGRegisterSelect = IoMem[0xff8800] & 0x0f;     /* Store register to select (value in bits 0-3) */
1.1       root       65: }
                     66: 
1.1.1.2   root       67: 
                     68: /*-----------------------------------------------------------------------*/
1.1       root       69: /*
1.1.1.5   root       70:   Read byte from 0xff8800, returns PSG data
1.1       root       71: */
1.1.1.4   root       72: void PSG_SelectRegister_ReadByte(void)
1.1       root       73: {
1.1.1.6 ! root       74:        M68000_WaitState(4);
        !            75: 
1.1.1.5   root       76:        if (PSGRegisterSelect == 14)
                     77:        {
                     78:                /* Second parallel port joystick uses centronics strobe bit as fire button: */
                     79:                if (ConfigureParams.Joysticks.Joy[JOYID_PARPORT2].nJoystickMode != JOYSTICK_DISABLED)
                     80:                {
                     81:                        if (Joy_GetStickData(JOYID_PARPORT2) & 0x80)
                     82:                                PSGRegisters[14] &= ~32;
                     83:                        else
                     84:                                PSGRegisters[14] |= 32;
                     85:                }
                     86:        }
                     87:        else if (PSGRegisterSelect == 15)
                     88:        {
                     89:                /* PSG register 15 is parallel port data register - used by parallel port joysticks: */
                     90:                if (ConfigureParams.Joysticks.Joy[JOYID_PARPORT1].nJoystickMode != JOYSTICK_DISABLED)
                     91:                {
                     92:                        PSGRegisters[15] &= 0x0f;
                     93:                        PSGRegisters[15] |= ~Joy_GetStickData(JOYID_PARPORT1) << 4;
                     94:                }
                     95:                if (ConfigureParams.Joysticks.Joy[JOYID_PARPORT2].nJoystickMode != JOYSTICK_DISABLED)
                     96:                {
                     97:                        PSGRegisters[15] &= 0xf0;
                     98:                        PSGRegisters[15] |= ~Joy_GetStickData(JOYID_PARPORT2) & 0x0f;
                     99:                }
                    100:        }
                    101: 
1.1.1.4   root      102:        /* Read data last selected by register */
                    103:        IoMem[0xff8800] = PSGRegisters[PSGRegisterSelect];
1.1       root      104: }
                    105: 
1.1.1.2   root      106: 
                    107: /*-----------------------------------------------------------------------*/
1.1       root      108: /*
1.1.1.4   root      109:   Write byte to 0xff8802, stores according to PSG select register (write 0xff8800)
                    110: */
                    111: void PSG_DataRegister_WriteByte(void)
                    112: {
1.1.1.6 ! root      113:        M68000_WaitState(4);
        !           114: 
1.1.1.4   root      115:        Sound_Update();                            /* Create samples up until this point with current values */
                    116:        PSGRegisters[PSGRegisterSelect] = IoMem[0xff8802];        /* Write value to PSGRegisters[] */
                    117: 
                    118:        switch (PSGRegisterSelect)
                    119:        {
                    120: 
                    121:         /* Check registers 8,9 and 10 which are 'amplitude' for each channel and
                    122:          * store if wrote to (to check for sample playback) */
                    123:         case PSG_REG_CHANNEL_A_AMP:
                    124:                bWriteChannelAAmp = TRUE;
                    125:                break;
                    126:         case PSG_REG_CHANNEL_B_AMP:
                    127:                bWriteChannelBAmp = TRUE;
                    128:                break;
                    129:         case PSG_REG_CHANNEL_C_AMP:
                    130:                bWriteChannelCAmp = TRUE;
                    131:                break;
                    132: 
                    133:         case PSG_REG_ENV_SHAPE:            /* Whenever 'write' to register 13, cause envelope to reset */
                    134:                bEnvelopeFreqFlag = TRUE;
                    135:                bWriteEnvelopeFreq = TRUE;
                    136:                break;
                    137: 
                    138:         /*
                    139:          * FIXME: This is only a prelimary dirty hack!
                    140:          * Port B (Printer port) - writing here needs to be dispatched to the printer
                    141:          * STROBE (Port A bit5) does a short LOW and back to HIGH when the char is valid
                    142:          * To print you need to write the character byte to IOB and you need to toggle STROBE
                    143:          * (like EmuTOS does)....therefor we print when STROBE gets low and last write access to
                    144:          * the PSG was to IOB
                    145:          */
                    146:         case PSG_REG_IO_PORTA:
                    147:                /* Printer dispatching only when printing is activated */
                    148:                if (ConfigureParams.Printer.bEnablePrinting)
                    149:                {
                    150:                        /* Is STROBE low and did the last write go to IOB? */
                    151:                        if ((PSGRegisters[PSG_REG_IO_PORTA]&32)==0 && bLastWriteToIOB)
                    152:                        {
                    153:                                /* Seems like we want to print something... */
                    154:                                Printer_TransferByteTo((unsigned char) PSGRegisters[PSG_REG_IO_PORTB]);
                    155:                        }
                    156:                }
                    157:                break;
                    158:        }
                    159: 
                    160:        /* Remember if we wrote to IO Port B */
                    161:        bLastWriteToIOB = (PSGRegisterSelect == PSG_REG_IO_PORTB);
1.1       root      162: }
                    163: 
1.1.1.2   root      164: 
                    165: /*-----------------------------------------------------------------------*/
1.1       root      166: /*
                    167:   Read byte from 0xff8802, returns 0xff
                    168: */
1.1.1.4   root      169: void PSG_DataRegister_ReadByte(void)
1.1       root      170: {
1.1.1.6 ! root      171:        M68000_WaitState(4);
1.1.1.4   root      172: 
1.1.1.6 ! root      173:        IoMem[0xff8802] = 0xff;
1.1       root      174: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.