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

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.5 ! root       11: char PSG_rcsid[] = "Hatari $Id: psg.c,v 1.8 2005/09/25 21:32:25 thothy 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.4   root       62:        PSGRegisterSelect = IoMem[0xff8800] & 0x0f;     /* Store register to select (value in bits 0-3) */
                     63: 
                     64:        M68000_WaitState();
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.5 ! root       74:        if (PSGRegisterSelect == 14)
        !            75:        {
        !            76:                /* Second parallel port joystick uses centronics strobe bit as fire button: */
        !            77:                if (ConfigureParams.Joysticks.Joy[JOYID_PARPORT2].nJoystickMode != JOYSTICK_DISABLED)
        !            78:                {
        !            79:                        if (Joy_GetStickData(JOYID_PARPORT2) & 0x80)
        !            80:                                PSGRegisters[14] &= ~32;
        !            81:                        else
        !            82:                                PSGRegisters[14] |= 32;
        !            83:                }
        !            84:        }
        !            85:        else if (PSGRegisterSelect == 15)
        !            86:        {
        !            87:                /* PSG register 15 is parallel port data register - used by parallel port joysticks: */
        !            88:                if (ConfigureParams.Joysticks.Joy[JOYID_PARPORT1].nJoystickMode != JOYSTICK_DISABLED)
        !            89:                {
        !            90:                        PSGRegisters[15] &= 0x0f;
        !            91:                        PSGRegisters[15] |= ~Joy_GetStickData(JOYID_PARPORT1) << 4;
        !            92:                }
        !            93:                if (ConfigureParams.Joysticks.Joy[JOYID_PARPORT2].nJoystickMode != JOYSTICK_DISABLED)
        !            94:                {
        !            95:                        PSGRegisters[15] &= 0xf0;
        !            96:                        PSGRegisters[15] |= ~Joy_GetStickData(JOYID_PARPORT2) & 0x0f;
        !            97:                }
        !            98:        }
        !            99: 
1.1.1.4   root      100:        /* Read data last selected by register */
                    101:        IoMem[0xff8800] = PSGRegisters[PSGRegisterSelect];
                    102: 
                    103:        M68000_WaitState();
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: {
                    113:        Sound_Update();                            /* Create samples up until this point with current values */
                    114:        PSGRegisters[PSGRegisterSelect] = IoMem[0xff8802];        /* Write value to PSGRegisters[] */
                    115: 
                    116:        switch (PSGRegisterSelect)
                    117:        {
                    118: 
                    119:         /* Check registers 8,9 and 10 which are 'amplitude' for each channel and
                    120:          * store if wrote to (to check for sample playback) */
                    121:         case PSG_REG_CHANNEL_A_AMP:
                    122:                bWriteChannelAAmp = TRUE;
                    123:                break;
                    124:         case PSG_REG_CHANNEL_B_AMP:
                    125:                bWriteChannelBAmp = TRUE;
                    126:                break;
                    127:         case PSG_REG_CHANNEL_C_AMP:
                    128:                bWriteChannelCAmp = TRUE;
                    129:                break;
                    130: 
                    131:         case PSG_REG_ENV_SHAPE:            /* Whenever 'write' to register 13, cause envelope to reset */
                    132:                bEnvelopeFreqFlag = TRUE;
                    133:                bWriteEnvelopeFreq = TRUE;
                    134:                break;
                    135: 
                    136:         /*
                    137:          * FIXME: This is only a prelimary dirty hack!
                    138:          * Port B (Printer port) - writing here needs to be dispatched to the printer
                    139:          * STROBE (Port A bit5) does a short LOW and back to HIGH when the char is valid
                    140:          * To print you need to write the character byte to IOB and you need to toggle STROBE
                    141:          * (like EmuTOS does)....therefor we print when STROBE gets low and last write access to
                    142:          * the PSG was to IOB
                    143:          */
                    144:         case PSG_REG_IO_PORTA:
                    145:                /* Printer dispatching only when printing is activated */
                    146:                if (ConfigureParams.Printer.bEnablePrinting)
                    147:                {
                    148:                        /* Is STROBE low and did the last write go to IOB? */
                    149:                        if ((PSGRegisters[PSG_REG_IO_PORTA]&32)==0 && bLastWriteToIOB)
                    150:                        {
                    151:                                /* Seems like we want to print something... */
                    152:                                Printer_TransferByteTo((unsigned char) PSGRegisters[PSG_REG_IO_PORTB]);
                    153:                        }
                    154:                }
                    155:                break;
                    156:        }
                    157: 
                    158:        /* Remember if we wrote to IO Port B */
                    159:        bLastWriteToIOB = (PSGRegisterSelect == PSG_REG_IO_PORTB);
                    160: 
                    161:        M68000_WaitState();
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.4   root      171:        IoMem[0xff8802] = 0xff;
                    172: 
                    173:        M68000_WaitState();
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.