Annotation of previous/src/kms.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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