Annotation of previous_trunk/src/kms.c, revision 1.1

1.1     ! root        1: /*  Previous - kms.c
        !             2:  
        !             3:  This file is distributed under the GNU Public License, version 2 or at
        !             4:  your option any later version. Read the file gpl.txt for details.
        !             5:  
        !             6:  Keyboard, Mouse and Sound logic Emulation.
        !             7:  
        !             8:  In real hardware this logic is located in the NeXT Megapixel Display 
        !             9:  or Soundbox
        !            10:  
        !            11:  */
        !            12: 
        !            13: #include "ioMem.h"
        !            14: #include "ioMemTables.h"
        !            15: #include "m68000.h"
        !            16: #include "kms.h"
        !            17: #include "sysReg.h"
        !            18: #include "dma.h"
        !            19: #include "rtcnvram.h"
        !            20: #include "snd.h"
        !            21: #include "video.h"
        !            22: #include "host.h"
        !            23: 
        !            24: #define LOG_KMS_LEVEL LOG_DEBUG
        !            25: #define IO_SEG_MASK    0x1FFFF
        !            26: 
        !            27: 
        !            28: struct {
        !            29:     struct {
        !            30:         Uint8 snd_dma;
        !            31:         Uint8 km;
        !            32:         Uint8 transmit;
        !            33:         Uint8 cmd;
        !            34:     } status;
        !            35:     
        !            36:     Uint32 data;
        !            37:     Uint32 km_data;
        !            38: } kms;
        !            39: 
        !            40: void KMS_Reset() {
        !            41:     kms.status.snd_dma  = 0;
        !            42:     kms.status.km       = 0;
        !            43:     kms.status.transmit = 0;
        !            44:     kms.status.cmd      = 0;
        !            45:     kms.data            = 0;
        !            46:     kms.km_data         = 0;
        !            47: }
        !            48: 
        !            49: /* KMS control and status register (0x0200E000) 
        !            50:  *
        !            51:  * x--- ---- ---- ---- ---- ---- ---- ----  sound out enable (r/w)
        !            52:  * -x-- ---- ---- ---- ---- ---- ---- ----  sound output request (r)
        !            53:  * --x- ---- ---- ---- ---- ---- ---- ----  sound output underrun detected (r/w)
        !            54:  * ---- x--- ---- ---- ---- ---- ---- ----  sound in enable (r/w)
        !            55:  * ---- -x-- ---- ---- ---- ---- ---- ----  sound input request (r)
        !            56:  * ---- --x- ---- ---- ---- ---- ---- ----  sound input overrun detected (r/w)
        !            57:  *
        !            58:  * ---- ---- x--- ---- ---- ---- ---- ----  keyboard interrupt (r)
        !            59:  * ---- ---- -x-- ---- ---- ---- ---- ----  keyboard data received (r)
        !            60:  * ---- ---- --x- ---- ---- ---- ---- ----  keyboard data overrun detected (r/w)
        !            61:  * ---- ---- ---x ---- ---- ---- ---- ----  non-maskable interrupt received (tilde and left or right cmd key) (r/w)
        !            62:  * ---- ---- ---- x--- ---- ---- ---- ----  kms interrupt (r)
        !            63:  * ---- ---- ---- -x-- ---- ---- ---- ----  kms data received (r)
        !            64:  * ---- ---- ---- --x- ---- ---- ---- ----  kms data overrun detected (r/w)
        !            65:  *
        !            66:  * ---- ---- ---- ---- x--- ---- ---- ----  dma sound out transmit pending (r)
        !            67:  * ---- ---- ---- ---- -x-- ---- ---- ----  dma sound out transmit in progress (r)
        !            68:  * ---- ---- ---- ---- --x- ---- ---- ----  cpu data transmit pending (r)
        !            69:  * ---- ---- ---- ---- ---x ---- ---- ----  cpu data transmit in progress (r)
        !            70:  * ---- ---- ---- ---- ---- x--- ---- ----  rtx_pend ???
        !            71:  * ---- ---- ---- ---- ---- -x-- ---- ----  rtx ???
        !            72:  * ---- ---- ---- ---- ---- --x- ---- ----  kms enable (return from reset state) (r/w)
        !            73:  * ---- ---- ---- ---- ---- ---x ---- ----  loop back transmitter data (r/w)
        !            74:  *
        !            75:  * ---- ---- ---- ---- ---- ---- xxxx xxxx  command to append on kms data (r/w)
        !            76:  *
        !            77:  * ---x ---x ---- ---x ---- ---- ---- ----  zero bits
        !            78:  */
        !            79: 
        !            80: 
        !            81: #define SNDOUT_DMA_ENABLE   0x80
        !            82: #define SNDOUT_DMA_REQUEST  0x40
        !            83: #define SNDOUT_DMA_UNDERRUN 0x20
        !            84: #define SNDIN_DMA_ENABLE    0x08
        !            85: #define SNDIN_DMA_REQUEST   0x04
        !            86: #define SNDIN_DMA_OVERRUN   0x02
        !            87: 
        !            88: #define KBD_INT             0x80
        !            89: #define KBD_RECEIVED        0x40
        !            90: #define KBD_OVERRUN         0x20
        !            91: #define NMI_RECEIVED        0x10
        !            92: #define KMS_INT             0x08
        !            93: #define KMS_RECEIVED        0x04
        !            94: #define KMS_OVERRUN         0x02
        !            95: 
        !            96: #define TX_DMA_PENDING      0x80
        !            97: #define TX_DMA              0x40
        !            98: #define TX_CPU_PENDING      0x20
        !            99: #define TX_CPU              0x10
        !           100: #define RTX_PEND            0x08
        !           101: #define RTX                 0x04
        !           102: #define KMS_ENABLE          0x02
        !           103: #define TX_LOOP             0x01
        !           104: 
        !           105: 
        !           106: /* KMS commands */
        !           107: 
        !           108: /* Host commands */
        !           109: #define KMSCMD_RESET    0xFF
        !           110: #define KMSCMD_ASNDOUT  0xC7    /* analog sound out */
        !           111: #define KMSCMD_KMREG    0xC5    /* access keyboard or mouse register */
        !           112: #define KMSCMD_CTRLOUT  0xC4    /* access volume control logic */
        !           113: #define KMSCMD_VOLCTRL  0xC2    /* simplified access to volume control */
        !           114: 
        !           115: #define KMSCMD_SND_IN   0x03    /* sound in */
        !           116: #define KMSCMD_SND_OUT  0x07    /* sound out */
        !           117: #define KMSCMD_SIO_MASK 0xC7    /* mask for sound in/out */
        !           118: 
        !           119: #define SIO_ENABLE      0x08    /* 1=enable, 0=disable sound */
        !           120: #define SIO_DBL_SMPL    0x10    /* 1=double sample, 0=normal */
        !           121: #define SIO_ZERO        0x20    /* double sample by 1=zero filling, 0=repetition */
        !           122: 
        !           123: /* Commands from KMS board */
        !           124: #define KMSCMD_CODEC_IN 0xC7    /* CODEC sound in */
        !           125: #define KMSCMD_KBD_RECV 0xC6    /* receive data from keyboard/mouse */
        !           126: #define KMSCMD_SO_REQ   0x07    /* sound out request */
        !           127: #define KMSCMD_SO_UNDR  0x0F    /* sound out underrun */
        !           128: 
        !           129: void KMS_command(Uint8 command, Uint32 data);
        !           130: 
        !           131: 
        !           132: /* Keyboard Registers */
        !           133: #define KM_REG_MASK     0xE0
        !           134: #define KM_READ         0x10
        !           135: #define KM_RESET        0x0F
        !           136: #define KM_SET_ADDR     0xEF
        !           137: #define KM_ADDR_MASK    0x0E
        !           138: #define KM_ADDR_MOUSE   0x01
        !           139: 
        !           140: 
        !           141: /* Device mask
        !           142:  *
        !           143:  * xxxx xxxx xxxx xxxx xxxx xxxx xxxx ----  polled devices (7 device addresses, 4 bit each)
        !           144:  * ---- ---- ---- ---- ---- ---- ---- xxxx  poll speed
        !           145:  */
        !           146: 
        !           147: Uint32 km_address = 0;
        !           148: Uint32 km_dev_msk = 0;
        !           149: 
        !           150: static void access_km_reg(Uint32 data) {
        !           151:     Uint8 reg_addr = (data>>24)&0xFF;
        !           152:     Uint8 reg_data = (data>>16)&0xFF;
        !           153:     
        !           154:     if (reg_addr==KM_RESET) {
        !           155:         Log_Printf(LOG_KMS_LEVEL, "Keyboard/Mouse: Reset");
        !           156:         kms_response();
        !           157:         return;
        !           158:     }
        !           159:     if (reg_addr==KM_SET_ADDR) {
        !           160:         Log_Printf(LOG_KMS_LEVEL, "Keyboard/Mouse: Set address to %i",(reg_data&KM_ADDR_MASK)>>1);
        !           161:         km_address = reg_data&KM_ADDR_MASK;
        !           162:         kms_response();
        !           163:         return;
        !           164:     }
        !           165:     
        !           166:     bool device_kbd = (reg_addr&KM_ADDR_MOUSE) ? false : true;
        !           167:     int device_addr = (reg_addr&KM_ADDR_MASK)>>1;
        !           168:     int device_reg = (reg_addr&KM_REG_MASK)>>5;
        !           169:     bool read_reg = (reg_addr&KM_READ) ? true : false;
        !           170:     
        !           171:     Log_Printf(LOG_KMS_LEVEL, "%s %s %i, register %i",read_reg?"Reading":"Writing",
        !           172:                device_kbd?"keyboard":"mouse",device_addr,device_reg);
        !           173:     
        !           174:     if (reg_addr&KM_READ) {
        !           175:         switch (device_reg) {
        !           176:             case 0:
        !           177:                 Log_Printf(LOG_KMS_LEVEL, "Poll device");
        !           178:                 break;
        !           179:             case 7:
        !           180:                 Log_Printf(LOG_KMS_LEVEL, "Request device revision");
        !           181:                 break;
        !           182:             default:
        !           183:                 Log_Printf(LOG_WARN, "Unknown device register");
        !           184:                 break;
        !           185:         }
        !           186:     } else { // device write
        !           187:         switch (device_reg) {
        !           188:             case 0:
        !           189:                 if (device_kbd) {
        !           190:                     Log_Printf(LOG_KMS_LEVEL, "Turn %s keyboard LED1",(reg_data&1)?"on":"off");
        !           191:                     Log_Printf(LOG_KMS_LEVEL, "Turn %s keyboard LED2",(reg_data&2)?"on":"off");
        !           192:                     break;
        !           193:                 }                
        !           194:             default:
        !           195:                 Log_Printf(LOG_WARN, "Unknown device register");
        !           196:                 break;
        !           197:         }
        !           198:     }
        !           199:     kms_response();
        !           200: }
        !           201: 
        !           202: void KMS_command(Uint8 command, Uint32 data) {
        !           203:     switch (command) {
        !           204:         case KMSCMD_KBD_RECV: // keyboard poll
        !           205:             km_dev_msk=data;
        !           206:             return;
        !           207: 
        !           208:         case KMSCMD_RESET:
        !           209:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Reset");
        !           210:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data);
        !           211:             break;
        !           212:         case KMSCMD_ASNDOUT:
        !           213:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Analog sound out");
        !           214:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data);
        !           215:             break;
        !           216:         case KMSCMD_KMREG:
        !           217:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Access keyboard/mouse register");
        !           218:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data);
        !           219:             access_km_reg(data);
        !           220:             break;
        !           221:         case KMSCMD_CTRLOUT:
        !           222:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Access volume control logic");
        !           223:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data);
        !           224:             snd_gpo_access(data>>24);
        !           225:             break;
        !           226:         case KMSCMD_VOLCTRL:
        !           227:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Access volume control (simple)");
        !           228:             Log_Printf(LOG_KMS_LEVEL, "[KMS] Data = %08X",data);
        !           229:             break;
        !           230:             
        !           231:         default: // commands without data
        !           232:             if ((command&KMSCMD_SIO_MASK)==KMSCMD_SND_OUT) {
        !           233:                 Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out command:");
        !           234: 
        !           235:                 if (command&SIO_ENABLE) {
        !           236:                     Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out enable.");
        !           237:                     if (command&SIO_DBL_SMPL) {
        !           238:                         Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out double sample.");
        !           239:                         if (command&SIO_ZERO) {
        !           240:                             Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out double sample by zero filling.");
        !           241:                         } else {
        !           242:                             Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out double sample by repetition.");
        !           243:                         }
        !           244:                     } else {
        !           245:                         Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out normal sample.");
        !           246:                     }
        !           247:                     snd_start_output(command&(SIO_DBL_SMPL|SIO_ZERO));
        !           248:                 } else {
        !           249:                     Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound out disable.");
        !           250:                     kms.status.snd_dma &= ~(SNDOUT_DMA_UNDERRUN|SNDOUT_DMA_REQUEST);
        !           251:                     snd_stop_output();
        !           252:                 }
        !           253:             } else if ((command&KMSCMD_SIO_MASK)==KMSCMD_SND_IN) {
        !           254:                 Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound in command");
        !           255:                 
        !           256:                 if (command&SIO_ENABLE) {
        !           257:                     Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound in enable.");
        !           258:                     snd_start_input(command);
        !           259:                 } else {
        !           260:                     Log_Printf(LOG_KMS_LEVEL, "[KMS] Sound in disable.");
        !           261:                     kms.status.snd_dma &= ~(SNDIN_DMA_OVERRUN|SNDIN_DMA_REQUEST);
        !           262:                     snd_stop_input();
        !           263:                 }
        !           264:             } else {
        !           265:                 Log_Printf(LOG_WARN, "[KMS] Unknown command!");
        !           266:             }
        !           267:             return;
        !           268:     }
        !           269: }
        !           270: 
        !           271: 
        !           272: void KMS_Ctrl_Snd_Write(void) {
        !           273:     Uint8 val = IoMem[IoAccessCurrentAddress&IO_SEG_MASK];
        !           274:     
        !           275:     kms.status.snd_dma &= ~(SNDOUT_DMA_ENABLE|SNDIN_DMA_ENABLE);
        !           276:     kms.status.snd_dma |= (val&(SNDOUT_DMA_ENABLE|SNDIN_DMA_ENABLE));
        !           277:     
        !           278:     if (val&SNDOUT_DMA_UNDERRUN && (!snd_output_active())) {
        !           279:         kms.status.snd_dma &= ~(SNDOUT_DMA_UNDERRUN|SNDOUT_DMA_REQUEST);
        !           280:         set_interrupt(INT_SOUND_OVRUN, RELEASE_INT);
        !           281:     }
        !           282:     if (val&SNDIN_DMA_OVERRUN && (!snd_input_active())) {
        !           283:         kms.status.snd_dma &= ~(SNDIN_DMA_OVERRUN|SNDIN_DMA_REQUEST);
        !           284:         set_interrupt(INT_SOUND_OVRUN, RELEASE_INT);
        !           285:     }
        !           286: }
        !           287: 
        !           288: void KMS_Stat_Snd_Read(void) {
        !           289:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.snd_dma;
        !           290: }
        !           291: 
        !           292: void kms_sndout_underrun() {
        !           293:     kms.status.snd_dma |=  SNDOUT_DMA_UNDERRUN|SNDOUT_DMA_REQUEST;
        !           294:     set_interrupt(INT_SOUND_OVRUN, SET_INT);
        !           295: }
        !           296: 
        !           297: void kms_sndin_overrun() {
        !           298:     kms.status.snd_dma |=  SNDIN_DMA_OVERRUN|SNDIN_DMA_REQUEST;
        !           299:     set_interrupt(INT_SOUND_OVRUN, SET_INT);
        !           300: }
        !           301: 
        !           302: void KMS_Ctrl_KM_Write(void) {
        !           303:     Uint8 val = IoMem[IoAccessCurrentAddress&IO_SEG_MASK];
        !           304:     
        !           305:     if (val&KBD_OVERRUN) {
        !           306:         kms.status.km &= ~(KBD_RECEIVED|KBD_OVERRUN|KBD_INT);
        !           307:         set_interrupt(INT_KEYMOUSE, RELEASE_INT);
        !           308:     }
        !           309:     if (val&NMI_RECEIVED) {
        !           310:         kms.status.km &= ~NMI_RECEIVED;
        !           311:         set_interrupt(INT_NMI, RELEASE_INT);
        !           312:     }
        !           313:     if (val&KMS_OVERRUN) {
        !           314:         kms.status.km &= ~(KMS_RECEIVED|KMS_OVERRUN|KMS_INT);
        !           315:         set_interrupt(INT_MONITOR, RELEASE_INT);
        !           316:     }
        !           317: }
        !           318: 
        !           319: void KMS_Stat_KM_Read(void) {
        !           320:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.km;
        !           321: }
        !           322: 
        !           323: void KMS_Ctrl_TX_Write(void) {
        !           324:     Uint8 val = IoMem[IoAccessCurrentAddress&IO_SEG_MASK];
        !           325:     
        !           326:     kms.status.transmit &= ~(KMS_ENABLE|TX_LOOP);
        !           327:     kms.status.transmit |= (val&(KMS_ENABLE|TX_LOOP));
        !           328: }
        !           329: 
        !           330: void KMS_Stat_TX_Read(void) {
        !           331:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.transmit;
        !           332: }
        !           333: 
        !           334: void KMS_Ctrl_Cmd_Write(void) {
        !           335:     kms.status.cmd = IoMem[IoAccessCurrentAddress&IO_SEG_MASK];
        !           336: }
        !           337: 
        !           338: void KMS_Stat_Cmd_Read(void) {
        !           339:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = kms.status.cmd;
        !           340: }
        !           341: 
        !           342: 
        !           343: /* KMS data register (0x0200E004) */
        !           344: 
        !           345: void KMS_Data_Write(void) {
        !           346:     kms.data = IoMem_ReadLong(IoAccessCurrentAddress&IO_SEG_MASK);
        !           347:     KMS_command(kms.status.cmd, kms.data);
        !           348: }
        !           349: 
        !           350: void KMS_Data_Read(void) {
        !           351:     IoMem_WriteLong(IoAccessCurrentAddress&IO_SEG_MASK, kms.data);
        !           352: }
        !           353: 
        !           354: 
        !           355: /* KMS keyboard and mouse data register (0x0200E008) *
        !           356:  *
        !           357:  * x--- ---- ---- ---- ---- ---- ---- ----  always 0
        !           358:  * -x-- ---- ---- ---- ---- ---- ---- ----  1 = no response error, 0 = normal event
        !           359:  * --x- ---- ---- ---- ---- ---- ---- ----  1 = user poll, 0 = internal poll
        !           360:  * ---x ---- ---- ---- ---- ---- ---- ----  1 = invalid/master, 0 = valid/slave (user/internal)
        !           361:  * ---- xxxx ---- ---- ---- ---- ---- ----  device address (lowest bit 1 = mouse, 0 = keyboard)
        !           362:  * ---- ---- xxxx xxxx ---- ---- ---- ----  chip revision: 0 = old, 1 = new, 2 = digital
        !           363:  *
        !           364:  * Mouse data:
        !           365:  * ---- ---- ---- ---- xxxx xxx- ---- ----  mouse y
        !           366:  * ---- ---- ---- ---- ---- ---x ---- ----  right button up (1) or down (0)
        !           367:  * ---- ---- ---- ---- ---- ---- xxxx xxx-  mouse x
        !           368:  * ---- ---- ---- ---- ---- ---- ---- ---x  left button up (1) or down (0)
        !           369:  *
        !           370:  * Keyboard data:
        !           371:  * ---- ---- ---- ---- x--- ---- ---- ----  valid (1) or invalid (0)
        !           372:  * ---- ---- ---- ---- -x-- ---- ---- ----  right alt
        !           373:  * ---- ---- ---- ---- --x- ---- ---- ----  left alt
        !           374:  * ---- ---- ---- ---- ---x ---- ---- ----  right command
        !           375:  * ---- ---- ---- ---- ---- x--- ---- ----  left command
        !           376:  * ---- ---- ---- ---- ---- -x-- ---- ----  right shift
        !           377:  * ---- ---- ---- ---- ---- --x- ---- ----  left shift
        !           378:  * ---- ---- ---- ---- ---- ---x ---- ----  control
        !           379:  * ---- ---- ---- ---- ---- ---- x--- ----  key up (1) or down (0)
        !           380:  * ---- ---- ---- ---- ---- ---- -xxx xxxx  keycode 
        !           381:  */
        !           382: 
        !           383: #define NO_RESPONSE_ERR 0x40000000
        !           384: #define USER_POLL       0x20000000
        !           385: #define DEVICE_INVALID  0x10000000
        !           386: #define DEVICE_MASTER   0x10000000
        !           387: 
        !           388: #define DEVICE_ADDR_MSK 0x0E000000
        !           389: #define DEVICE_MOUSE    0x01000000
        !           390: 
        !           391: #define MOUSE_Y         0x0000FE00
        !           392: #define MOUSE_RIGHT_UP  0x00000100
        !           393: #define MOUSE_X         0x000000FE
        !           394: #define MOUSE_LEFT_UP   0x00000001
        !           395: 
        !           396: #define KBD_KEY_VALID   0x00008000
        !           397: #define KBD_MOD_MASK    0x00007F00
        !           398: #define KBD_KEY_UP      0x00000080
        !           399: #define KBD_KEY_MASK    0x0000007F
        !           400: 
        !           401: 
        !           402: bool m_button_right = false;
        !           403: bool m_button_left  = false;
        !           404: bool m_move_left    = false;
        !           405: bool m_move_up      = false;
        !           406: int  m_move_x       = 0;
        !           407: int  m_move_y       = 0;
        !           408: int  m_move_dx      = 0;
        !           409: int  m_move_dy      = 0;
        !           410: void kms_mouse_move_step(void);
        !           411: 
        !           412: 
        !           413: void KMS_KM_Data_Read(void) {
        !           414:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, kms.km_data);
        !           415:     
        !           416:     kms.status.km &= ~(KBD_RECEIVED|KBD_INT);
        !           417:     set_interrupt(INT_KEYMOUSE, RELEASE_INT);
        !           418: }
        !           419: 
        !           420: static void kms_interrupt(void) {
        !           421:     kms.status.cmd = KMSCMD_KBD_RECV;
        !           422:     
        !           423:     if (kms.status.km&KBD_RECEIVED) {
        !           424:         kms.status.km |= KBD_OVERRUN;
        !           425:     }
        !           426:     kms.status.km |= (KBD_RECEIVED|KBD_INT);
        !           427:     set_interrupt(INT_KEYMOUSE, SET_INT);
        !           428: }
        !           429: 
        !           430: static bool kms_device_enabled(int dev_addr) {
        !           431:     int i,mask;
        !           432: 
        !           433:     for (i=28; i>4; i-=4) {
        !           434:         mask=(km_dev_msk>>i)&0xF;
        !           435:         if(mask==dev_addr && mask!=0xF)
        !           436:             return true;
        !           437:     }
        !           438:     Log_Printf(LOG_KMS_LEVEL, "[KMS] Device %i disabled (mask: %08X)",dev_addr,km_dev_msk);
        !           439:     return false;
        !           440: }
        !           441: 
        !           442: void kms_keydown(Uint8 modkeys, Uint8 keycode) {
        !           443:     if ((keycode==0x26)&&(modkeys&0x18)) { /* backquote and one or both command keys */
        !           444:         Log_Printf(LOG_WARN, "Keyboard initiated NMI!");
        !           445:         set_interrupt(INT_NMI, SET_INT);
        !           446:         return;
        !           447:     }
        !           448:     
        !           449:     if ((keycode==0x25)&&((modkeys&0x28)==0x28)) { /* asterisk and left alt and left command key */
        !           450:         Log_Printf(LOG_WARN, "Keyboard initiated CPU reset!");
        !           451:         host_darkmatter(false);
        !           452:         M68000_Reset(false);
        !           453:         return;
        !           454:     }
        !           455:     
        !           456:     if (keycode==0x58) { /* Power key */
        !           457:         rtc_request_power_down();
        !           458:         return;
        !           459:     }
        !           460:     
        !           461:     if (kms_device_enabled(km_address)) {
        !           462:         kms.km_data = (km_address<<24)|DEVICE_MASTER; /* keyboard */
        !           463: 
        !           464:         kms.km_data |= (modkeys<<8)|keycode|KBD_KEY_VALID;
        !           465:         
        !           466:         kms_interrupt();
        !           467:     }
        !           468: }
        !           469: 
        !           470: void kms_keyup(Uint8 modkeys, Uint8 keycode) {
        !           471:     if (keycode==0x58) {
        !           472:         rtc_stop_pdown_request();
        !           473:         return;
        !           474:     }
        !           475:     
        !           476:     if (kms_device_enabled(km_address)) {
        !           477:         kms.km_data = (km_address<<24)|DEVICE_MASTER; /* keyboard */
        !           478: 
        !           479:         kms.km_data |= (modkeys<<8)|keycode|KBD_KEY_VALID|KBD_KEY_UP;
        !           480:         
        !           481:         kms_interrupt();
        !           482:     }
        !           483: }
        !           484: 
        !           485: void kms_mouse_button(bool left, bool down) {
        !           486:     if (left) {
        !           487:         m_button_left = down;
        !           488:     } else {
        !           489:         m_button_right = down;
        !           490:     }
        !           491:     
        !           492:     if (kms_device_enabled(km_address|KM_ADDR_MOUSE)) {
        !           493:         kms.km_data = (km_address|KM_ADDR_MOUSE)<<24; /* mouse */
        !           494:         
        !           495:         kms.km_data |= m_button_left?0:MOUSE_LEFT_UP;
        !           496:         kms.km_data |= m_button_right?0:MOUSE_RIGHT_UP;
        !           497:         
        !           498:         kms_interrupt();
        !           499:     }
        !           500: }
        !           501: 
        !           502: #define MOUSE_STEP_FREQ 1000
        !           503: 
        !           504: void kms_mouse_move(int x, bool left, int y, bool up) {
        !           505:     if (x<0 || y<0) abort();
        !           506:     
        !           507:     m_move_left = left;
        !           508:     m_move_up   = up;
        !           509: 
        !           510:     int xsteps = x / 8; if(xsteps == 0) xsteps = 1;
        !           511:     int ysteps = y / 8; if(ysteps == 0) ysteps = 1;
        !           512:     
        !           513:     m_move_x  = x;
        !           514:     m_move_dx = x / xsteps;
        !           515:     
        !           516:     m_move_y  = y;
        !           517:     m_move_dy = y / ysteps;
        !           518:     
        !           519:     CycInt_AddRelativeInterruptCycles(10, INTERRUPT_MOUSE);
        !           520: }
        !           521: 
        !           522: void kms_mouse_move_step(void) {
        !           523:     
        !           524:     int x = m_move_x > m_move_dx ? m_move_dx : m_move_x;
        !           525:     int y = m_move_y > m_move_dy ? m_move_dy : m_move_y;
        !           526: 
        !           527:     m_move_x -= x;
        !           528:     m_move_y -= y;
        !           529:     
        !           530:     if (!m_move_left && x>0)  /* right */
        !           531:         x=(0x40-x)|0x40;
        !           532:     if (!m_move_up && y>0)    /* down */
        !           533:         y=(0x40-y)|0x40;
        !           534:     
        !           535:     if (kms_device_enabled(km_address|KM_ADDR_MOUSE)) {
        !           536:         kms.km_data = (km_address|KM_ADDR_MOUSE)<<24; /* mouse */
        !           537:         
        !           538:         kms.km_data |= (x<<1)&MOUSE_X;
        !           539:         kms.km_data |= (y<<9)&MOUSE_Y;
        !           540:         
        !           541:         kms.km_data |= m_button_left?0:MOUSE_LEFT_UP;
        !           542:         kms.km_data |= m_button_right?0:MOUSE_RIGHT_UP;
        !           543:         
        !           544:         kms_interrupt();
        !           545:     }
        !           546: }
        !           547: 
        !           548: void kms_response(void) {
        !           549:     kms.km_data = km_address<<24; /* keyboard */
        !           550:     kms.km_data |= USER_POLL;
        !           551:     kms.km_data |= (NO_RESPONSE_ERR|DEVICE_INVALID); /* checked on real hardware */
        !           552:     
        !           553:     kms_interrupt();
        !           554: }
        !           555: 
        !           556: void Mouse_Handler(void) {
        !           557:     CycInt_AcknowledgeInterrupt();
        !           558:     
        !           559:     if (m_move_x > 0 || m_move_y > 0) {
        !           560:         kms_mouse_move_step();
        !           561:         CycInt_AddRelativeInterruptUs((1000*1000)/MOUSE_STEP_FREQ, 0, INTERRUPT_MOUSE);
        !           562:     }
        !           563: }

unix.superglobalmegacorp.com

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