fixing ps2 mouse inhibit bug
@@ -118,6 +118,7 @@ void mouse_buf_init(mouse_buf *lb, uint8_t size);
|
||||
uint8_t mouse_buf_add(mouse_buf *lb, mouse_event* event);
|
||||
mouse_event* mouse_buf_peek(mouse_buf *lb);
|
||||
void mouse_buf_pop(mouse_buf *lb);
|
||||
void mouse_buf_reset(mouse_buf *lb);
|
||||
|
||||
void gamepad_buf_init(gamepad_buf *lb, uint8_t size);
|
||||
uint8_t gamepad_buf_add(gamepad_buf *lb, gamepad_event* event);
|
||||
|
||||
@@ -22,6 +22,15 @@ uint8_t ps2mouse_get_outgoing_data(mouse_event* this_event, ps2_outgoing_buf* pb
|
||||
uint8_t ps2mouse_send_update(ps2_outgoing_buf* pbuf);
|
||||
uint8_t ps2mouse_write_nowait(uint8_t data);
|
||||
void ps2mouse_reset(void);
|
||||
|
||||
#define PS2_OK 0
|
||||
#define PS2_ERROR_SCAN_DISABLED 1
|
||||
#define PS2_ERROR_UNKNOWN_CODE_SET 9
|
||||
#define PS2_ERROR_HOST_INHIBIT 69
|
||||
#define PS2_ERROR_UNUSED_CODE 2
|
||||
#define PS2_ERROR_UNKNOWN 3
|
||||
#define PS2_ERROR_TIMEOUT 4
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -93,8 +93,8 @@
|
||||
<flags>2</flags>
|
||||
<showCmd>3</showCmd>
|
||||
<MinPosition>
|
||||
<xPos>-1</xPos>
|
||||
<yPos>-1</yPos>
|
||||
<xPos>-32000</xPos>
|
||||
<yPos>-32000</yPos>
|
||||
</MinPosition>
|
||||
<MaxPosition>
|
||||
<xPos>-1</xPos>
|
||||
@@ -3606,9 +3606,9 @@
|
||||
<ActiveTab>0</ActiveTab>
|
||||
<Doc>
|
||||
<Name>../Src/main.c</Name>
|
||||
<ColumnNumber>18</ColumnNumber>
|
||||
<TopLine>396</TopLine>
|
||||
<CurrentLine>411</CurrentLine>
|
||||
<ColumnNumber>17</ColumnNumber>
|
||||
<TopLine>317</TopLine>
|
||||
<CurrentLine>349</CurrentLine>
|
||||
<Folding>1</Folding>
|
||||
<ContractedFolders></ContractedFolders>
|
||||
<PaneID>0</PaneID>
|
||||
|
||||
@@ -27,22 +27,22 @@ Project File Date: 03/28/2022
|
||||
<h2>Output:</h2>
|
||||
*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
|
||||
Build target 'ibmpc'
|
||||
compiling xt_kb.c...
|
||||
compiling ps2kb.c...
|
||||
compiling main.c...
|
||||
../Src/main.c(467): warning: #188-D: enumerated type mixed with another type
|
||||
../Src/main.c(474): warning: #188-D: enumerated type mixed with another type
|
||||
HAL_GPIO_WritePin(GAMEPAD_B1_GPIO_Port, GAMEPAD_B1_Pin, !(this_gamepad_event->button_1));
|
||||
../Src/main.c(468): warning: #188-D: enumerated type mixed with another type
|
||||
../Src/main.c(475): warning: #188-D: enumerated type mixed with another type
|
||||
HAL_GPIO_WritePin(GAMEPAD_B2_GPIO_Port, GAMEPAD_B2_Pin, !(this_gamepad_event->button_2));
|
||||
../Src/main.c(469): warning: #188-D: enumerated type mixed with another type
|
||||
../Src/main.c(476): warning: #188-D: enumerated type mixed with another type
|
||||
HAL_GPIO_WritePin(GAMEPAD_B3_GPIO_Port, GAMEPAD_B3_Pin, !(this_gamepad_event->button_3));
|
||||
../Src/main.c(470): warning: #188-D: enumerated type mixed with another type
|
||||
../Src/main.c(477): warning: #188-D: enumerated type mixed with another type
|
||||
HAL_GPIO_WritePin(GAMEPAD_B4_GPIO_Port, GAMEPAD_B4_Pin, !(this_gamepad_event->button_4));
|
||||
../Src/main.c: 4 warnings, 0 errors
|
||||
../Src/main.c(707): warning: #177-D: function "MX_IWDG_Init" was declared but never referenced
|
||||
static void MX_IWDG_Init(void)
|
||||
../Src/main.c: 5 warnings, 0 errors
|
||||
linking...
|
||||
Program Size: Code=16500 RO-data=428 RW-data=132 ZI-data=2180
|
||||
Program Size: Code=16332 RO-data=428 RW-data=132 ZI-data=2164
|
||||
FromELF: creating hex file...
|
||||
"ibmpc\ibmpc.axf" - 0 Error(s), 4 Warning(s).
|
||||
"ibmpc\ibmpc.axf" - 0 Error(s), 5 Warning(s).
|
||||
|
||||
<h2>Software Packages used:</h2>
|
||||
|
||||
@@ -65,7 +65,7 @@ Package Vendor: Keil
|
||||
<h2>Collection of Component Files used:</h2>
|
||||
|
||||
* Component: ARM::CMSIS:CORE:5.3.0
|
||||
Build Time Elapsed: 00:00:02
|
||||
Build Time Elapsed: 00:00:01
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -40,7 +40,7 @@ F (..\Src\helpers.c)(0x61BCF9FD)(--c99 -c --cpu Cortex-M0 -D__MICROLIB -g -O3 --
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h)(0x5DFA0893)
|
||||
@@ -78,7 +78,7 @@ F (..\Src\ps2kb.c)(0x626EFE47)(--c99 -c --cpu Cortex-M0 -D__MICROLIB -g -O3 --ap
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h)(0x5DFA0893)
|
||||
I (../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h)(0x5DFA0880)
|
||||
I (../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h)(0x5DFA0880)
|
||||
I (../Drivers/CMSIS/Include/core_cm0.h)(0x5DFA0892)
|
||||
I (../Drivers/CMSIS/Include/core_cm0.h)(0x5DFA0892)
|
||||
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5D9B4298)
|
||||
I (../Drivers/CMSIS/Include/core_cmInstr.h)(0x5DFA0892)
|
||||
I (../Drivers/CMSIS/Include/cmsis_armcc.h)(0x5DFA0892)
|
||||
@@ -114,11 +114,11 @@ I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart_ex.h)(0x5DFA0893)
|
||||
|
||||
-D__UVISION_VERSION="529" -D_RTE_ -DSTM32F072xB -DUSE_HAL_DRIVER -DSTM32F072xB
|
||||
|
||||
-o ibmpc\ps2kb.o --omf_browse ibmpc\ps2kb.crf --depend ibmpc\ps2kb.d)
|
||||
-o ibmpc\ps2kb.o --omf_browse ibmpc\ps2kb.crf --depend ibmpc\ps2kb.d)
|
||||
I (C:\Keil_v5\ARM\ARMCC\include\stdio.h)(0x5D9B429A)
|
||||
I (C:\Keil_v5\ARM\ARMCC\include\string.h)(0x5D9B4298)
|
||||
I (C:\Keil_v5\ARM\ARMCC\include\stdlib.h)(0x5D9B429A)
|
||||
I (../Inc/helpers.h)(0x61FBBDBE)
|
||||
I (../Inc/helpers.h)(0x626F16F7)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h)(0x5DFA0893)
|
||||
I (../Inc/stm32f0xx_hal_conf.h)(0x62423606)
|
||||
I (../Inc/main.h)(0x62423606)
|
||||
@@ -152,12 +152,12 @@ I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart_ex.h)(0x5DFA0893)
|
||||
I (../Inc/shared.h)(0x61B61A00)
|
||||
I (../Inc/ps2kb.h)(0x626EE78C)
|
||||
I (../Inc/ps2kb.h)(0x626EE78C)
|
||||
I (../Inc/delay_us.h)(0x617487C7)
|
||||
F (..\Src\ps2mouse.c)(0x626F229D)(--c99 -c --cpu Cortex-M0 -D__MICROLIB -g -O3 --apcs=interwork --split_sections -I ../Inc -I ../Drivers/STM32F0xx_HAL_Driver/Inc -I ../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I ../Drivers/CMSIS/Include
|
||||
|
||||
|
||||
-I.\RTE\_ibmpc
|
||||
|
||||
|
||||
-IC:\Users\allen\AppData\Local\Arm\Packs\ARM\CMSIS\5.6.0\CMSIS\Core\Include
|
||||
|
||||
-IC:\Users\allen\AppData\Local\Arm\Packs\Keil\STM32F0xx_DFP\2.0.0\Drivers\CMSIS\Device\ST\STM32F0xx\Include
|
||||
@@ -202,7 +202,7 @@ F (..\Src\xt_kb.c)(0x626F0101)(--c99 -c --cpu Cortex-M0 -D__MICROLIB -g -O3 --ap
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart_ex.h)(0x5DFA0893)
|
||||
I (../Inc/shared.h)(0x61B61A00)
|
||||
I (../Inc/ps2mouse.h)(0x61BC59D5)
|
||||
I (../Inc/ps2mouse.h)(0x626F088E)
|
||||
I (../Inc/delay_us.h)(0x617487C7)
|
||||
F (..\Inc\delay_us.h)(0x617487C7)()
|
||||
F (..\Inc\helpers.h)(0x626F16F7)()
|
||||
@@ -239,7 +239,7 @@ I (../Inc/shared.h)(0x61B61A00)
|
||||
I (../Drivers/CMSIS/Include/core_cmFunc.h)(0x5DFA0892)
|
||||
I (../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h)(0x5DFA0880)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h)(0x5DFA0893)
|
||||
@@ -275,10 +275,10 @@ I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart.h)(0x5DFA0893)
|
||||
I (../Inc/helpers.h)(0x626F16F7)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h)(0x5DFA0893)
|
||||
I (../Inc/stm32f0xx_hal_conf.h)(0x62423606)
|
||||
I (../Inc/main.h)(0x62423606)
|
||||
I (../Inc/main.h)(0x62423606)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h)(0x5DFA0893)
|
||||
I (../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h)(0x5DFA0893)
|
||||
I (../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h)(0x5DFA0880)
|
||||
I (../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h)(0x5DFA0880)
|
||||
I (../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h)(0x5DFA0880)
|
||||
I (../Drivers/CMSIS/Include/core_cm0.h)(0x5DFA0892)
|
||||
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5D9B4298)
|
||||
|
||||
@@ -324,9 +324,16 @@ void ps2mouse_update(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// only pop the item if sending is complete
|
||||
if(ps2mouse_send_update(&my_ps2_outbuf) == 0)
|
||||
mouse_buf_pop(&my_mouse_buf);
|
||||
if(ps2mouse_send_update(&my_ps2_outbuf) == PS2_ERROR_HOST_INHIBIT)
|
||||
{
|
||||
HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_SET);
|
||||
while(ps2mouse_get_bus_status() != PS2_BUS_IDLE)
|
||||
;
|
||||
HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_RESET);
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
mouse_buf_pop(&my_mouse_buf);
|
||||
}
|
||||
|
||||
void ps2kb_update(void)
|
||||
@@ -541,9 +548,9 @@ int main(void)
|
||||
MX_TIM2_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART3_UART_Init();
|
||||
MX_IWDG_Init();
|
||||
// MX_IWDG_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
// HAL_IWDG_Refresh(&hiwdg);
|
||||
printf("%s\nrev%d v%d.%d.%d\n", boot_message, hw_revision, version_major, version_minor, version_patch);
|
||||
delay_us_init(&htim2);
|
||||
protocol_status_lookup_init();
|
||||
@@ -582,7 +589,7 @@ int main(void)
|
||||
|
||||
while (1)
|
||||
{
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
// HAL_IWDG_Refresh(&hiwdg);
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
|
||||
@@ -69,7 +69,7 @@ void ps2mouse_restore_defaults(void)
|
||||
ps2mouse_sampling_rate = 100;
|
||||
ps2mouse_resolution = 2;
|
||||
ps2mouse_scale = 1;
|
||||
ps2mouse_data_reporting_enabled = 0;
|
||||
ps2mouse_data_reporting_enabled = 1;
|
||||
ps2mouse_current_mode = PS2MOUSE_MODE_STREAM;
|
||||
ps2mouse_prev_mode = PS2MOUSE_MODE_STREAM;
|
||||
reset_accumulators();
|
||||
@@ -113,7 +113,7 @@ uint8_t ps2mouse_read(uint8_t* result, uint8_t timeout_ms)
|
||||
while(ps2mouse_get_bus_status() != PS2_BUS_REQ_TO_SEND)
|
||||
{
|
||||
if(HAL_GetTick() - ps2mouse_wait_start >= timeout_ms)
|
||||
return 1;
|
||||
return PS2_ERROR_TIMEOUT;
|
||||
}
|
||||
|
||||
delay_us(CLKHALF);
|
||||
@@ -150,7 +150,7 @@ uint8_t ps2mouse_read(uint8_t* result, uint8_t timeout_ms)
|
||||
PS2MOUSE_DATA_HI();
|
||||
|
||||
*result = data & 0xFF;
|
||||
return 0;
|
||||
return PS2_OK;
|
||||
}
|
||||
|
||||
uint8_t ps2mouse_wait_for_idle(uint8_t timeout_ms)
|
||||
@@ -159,15 +159,15 @@ uint8_t ps2mouse_wait_for_idle(uint8_t timeout_ms)
|
||||
while(ps2mouse_get_bus_status() != PS2_BUS_IDLE)
|
||||
{
|
||||
if(HAL_GetTick() - ps2mouse_wait_start >= timeout_ms)
|
||||
return 1;
|
||||
return PS2_ERROR_TIMEOUT;
|
||||
}
|
||||
return 0;
|
||||
return PS2_OK;
|
||||
}
|
||||
|
||||
uint8_t ps2mouse_write_delay_start(uint8_t data, uint8_t timeout_ms)
|
||||
{
|
||||
if(ps2mouse_wait_for_idle(timeout_ms) != 0)
|
||||
return 1;
|
||||
return PS2_ERROR_TIMEOUT;
|
||||
delay_us(BYTEWAIT);
|
||||
return ps2mouse_write_nowait(data);
|
||||
}
|
||||
@@ -175,7 +175,7 @@ uint8_t ps2mouse_write_delay_start(uint8_t data, uint8_t timeout_ms)
|
||||
uint8_t ps2mouse_write(uint8_t data, uint8_t timeout_ms)
|
||||
{
|
||||
if(ps2mouse_wait_for_idle(timeout_ms) != 0)
|
||||
return 1;
|
||||
return PS2_ERROR_TIMEOUT;
|
||||
return ps2mouse_write_nowait(data);
|
||||
}
|
||||
|
||||
@@ -237,8 +237,8 @@ void ps2mouse_host_req_reply(uint8_t cmd, mouse_event* mevent)
|
||||
reset_accumulators();
|
||||
PS2MOUSE_SENDACK();
|
||||
mouse_device_id = 0; // standard ps/2 mouse
|
||||
if (sample_rate_history_index > 2 && sample_rate_history[sample_rate_history_index-1] == 80 && sample_rate_history[sample_rate_history_index-2] == 100 && sample_rate_history[sample_rate_history_index-3] == 200)
|
||||
mouse_device_id = 3; // intellimouse with scroll wheel
|
||||
// if (sample_rate_history_index > 2 && sample_rate_history[sample_rate_history_index-1] == 80 && sample_rate_history[sample_rate_history_index-2] == 100 && sample_rate_history[sample_rate_history_index-3] == 200)
|
||||
// mouse_device_id = 3; // intellimouse with scroll wheel
|
||||
ps2mouse_write(mouse_device_id, PS2MOUSE_WRITE_DEFAULT_TIMEOUT_MS);
|
||||
break;
|
||||
case 0xF0: // set remote mode
|
||||
@@ -336,7 +336,7 @@ uint8_t ps2mouse_get_outgoing_data(mouse_event* this_event, ps2_outgoing_buf* pb
|
||||
pbuf->data[3] = (uint8_t)(this_event->scroll_vertical);
|
||||
if(mouse_device_id != 0)
|
||||
pbuf->size = PS2MOUSE_PACKET_SIZE_INTELLIMOUSE;
|
||||
return 0;
|
||||
return PS2_OK;
|
||||
}
|
||||
|
||||
uint8_t ps2mouse_write_nowait(uint8_t data)
|
||||
@@ -351,7 +351,10 @@ uint8_t ps2mouse_write_nowait(uint8_t data)
|
||||
PS2MOUSE_CLK_HI();
|
||||
delay_us(CLKHALF);
|
||||
if(PS2MOUSE_READ_CLK_PIN() == GPIO_PIN_RESET)
|
||||
return 1;
|
||||
{
|
||||
ps2mouse_release_lines();
|
||||
return PS2_ERROR_HOST_INHIBIT;
|
||||
}
|
||||
|
||||
for (int i=0; i < 8; i++)
|
||||
{
|
||||
@@ -366,7 +369,10 @@ uint8_t ps2mouse_write_nowait(uint8_t data)
|
||||
PS2MOUSE_CLK_HI();
|
||||
delay_us(CLKHALF);
|
||||
if(PS2MOUSE_READ_CLK_PIN() == GPIO_PIN_RESET)
|
||||
return 1;
|
||||
{
|
||||
ps2mouse_release_lines();
|
||||
return PS2_ERROR_HOST_INHIBIT;
|
||||
}
|
||||
|
||||
parity = parity ^ (data & 0x01);
|
||||
data = data >> 1;
|
||||
@@ -384,7 +390,10 @@ uint8_t ps2mouse_write_nowait(uint8_t data)
|
||||
PS2MOUSE_CLK_HI();
|
||||
delay_us(CLKHALF);
|
||||
if(PS2MOUSE_READ_CLK_PIN() == GPIO_PIN_RESET)
|
||||
return 1;
|
||||
{
|
||||
ps2mouse_release_lines();
|
||||
return PS2_ERROR_HOST_INHIBIT;
|
||||
}
|
||||
|
||||
// stop bit
|
||||
PS2MOUSE_DATA_HI();
|
||||
@@ -396,16 +405,18 @@ uint8_t ps2mouse_write_nowait(uint8_t data)
|
||||
|
||||
delay_us(BYTEWAIT_END);
|
||||
|
||||
return 0;
|
||||
return PS2_OK;
|
||||
}
|
||||
|
||||
uint8_t ps2mouse_send_update(ps2_outgoing_buf* pbuf)
|
||||
{
|
||||
uint8_t write_result;
|
||||
for (int i = 0; i < pbuf->size; ++i)
|
||||
{
|
||||
// return error if inhibited or interrupted while transmitting
|
||||
if(ps2mouse_write(pbuf->data[i], 255) != 0)
|
||||
return 1;
|
||||
write_result = ps2mouse_write(pbuf->data[i], 255);
|
||||
if(write_result)
|
||||
return write_result;
|
||||
}
|
||||
return 0;
|
||||
return PS2_OK;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,60 @@
|
||||
if(ps2mouse_send_update(&my_ps2_outbuf) == PS2_ERROR_HOST_INHIBIT)
|
||||
{
|
||||
HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_SET);
|
||||
while(ps2mouse_get_bus_status() != PS2_BUS_IDLE)
|
||||
;
|
||||
// HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_RESET);
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
uint8_t send_result = ps2mouse_send_update(&my_ps2_outbuf);
|
||||
if(send_result == PS2_ERROR_HOST_INHIBIT)
|
||||
{
|
||||
HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_SET);
|
||||
while(ps2mouse_get_bus_status() != PS2_BUS_IDLE)
|
||||
;
|
||||
HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_RESET);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_buf_pop(&my_mouse_buf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// uint8_t send_result = ps2mouse_send_update(&my_ps2_outbuf);
|
||||
// while(send_result == PS2_ERROR_HOST_INHIBIT)
|
||||
// {
|
||||
// HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_SET);
|
||||
// HAL_Delay(10);
|
||||
// }
|
||||
// mouse_buf_pop(&my_mouse_buf);
|
||||
|
||||
while(1)
|
||||
{
|
||||
uint8_t send_result = ps2mouse_send_update(&my_ps2_outbuf);
|
||||
if(send_result == PS2_ERROR_HOST_INHIBIT)
|
||||
{
|
||||
HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(1);
|
||||
HAL_GPIO_WritePin(ERR_LED_GPIO_Port, ERR_LED_Pin, GPIO_PIN_RESET);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_buf_pop(&my_mouse_buf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// only pop the item if sending is complete
|
||||
if(ps2mouse_send_update(&my_ps2_outbuf))
|
||||
HAL_Delay(1);
|
||||
else
|
||||
mouse_buf_pop(&my_mouse_buf);
|
||||
|
||||
void xtkb_update(void)
|
||||
{
|
||||
xtkb_check_for_softreset();
|
||||
|
||||
1202
photos/'8042' PS_2 Controller - OSDev Wiki.htm
Normal file
BIN
photos/'8042' PS_2 Controller - OSDev Wiki_files/At-kbc.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
photos/'8042' PS_2 Controller - OSDev Wiki_files/Ps2-kbc.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,3 @@
|
||||
div.mw-geshi div,div.mw-geshi div pre,span.mw-geshi,pre.source-css,pre.source-javascript{font-family:monospace,Courier !important} @media print{ }
|
||||
|
||||
/* cache key: wikidb:resourceloader:filter:minify-css:4:990d0644862009377a1a48a78b53b366 */
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
1732
resources/Linux_m68k for Macintosh - Mac Plus hardware.htm
Normal file
|
After Width: | Height: | Size: 444 B |
|
After Width: | Height: | Size: 444 B |
|
After Width: | Height: | Size: 444 B |
|
After Width: | Height: | Size: 444 B |
@@ -0,0 +1,71 @@
|
||||
/* $Id$ */
|
||||
|
||||
body {
|
||||
font-family: sans-serif, verdana, arial, helvetica;
|
||||
padding: 0em;
|
||||
border-width: 0em;
|
||||
}
|
||||
|
||||
table.fullheight {
|
||||
background-color: #c4c4c4;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gray {
|
||||
background-color: #c4c4c4;
|
||||
}
|
||||
|
||||
.white {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.nomargin {
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
.bordertop {
|
||||
background-color: #ffffff;
|
||||
background-image: url("/gfx/border_top.gif");
|
||||
background-repeat: repeat;
|
||||
}
|
||||
.borderbottom {
|
||||
background-color: #ffffff;
|
||||
background-image: url("/gfx/border_bottom.gif");
|
||||
background-repeat: repeat;
|
||||
}
|
||||
.borderleft {
|
||||
background-color: #ffffff;
|
||||
background-image: url("/gfx/border_left.gif");
|
||||
background-repeat: repeat;
|
||||
}
|
||||
.borderright {
|
||||
background-color: #ffffff;
|
||||
background-image: url("/gfx/border_right.gif");
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
td.submenu {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a:link { text-decoration: none; font-weight: bold; color: #5555aa; }
|
||||
a:visited { text-decoration: none; font-weight: bold; color: #222266; }
|
||||
a:active { text-decoration: none; font-weight: bold; color: #7777ff; }
|
||||
a:hover { text-decoration: none; font-weight: bold; color: #7777ff; }
|
||||
a.active { text-decoration: none; font-weight: bold; color: #555555; }
|
||||
|
||||
h1 {
|
||||
font-size: xx-large;
|
||||
font-weight: bold;
|
||||
}
|
||||
h2 {
|
||||
font-size: x-large;
|
||||
font-weight: bold;
|
||||
}
|
||||
h3 {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
}
|
||||
h4 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 948 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
4458
resources/PS_2 Keyboard - OSDev Wiki.htm
Normal file
3
resources/PS_2 Keyboard - OSDev Wiki_files/load.css
Normal file
3
resources/PS_2 Keyboard - OSDev Wiki_files/load_002.css
Normal file
@@ -0,0 +1,3 @@
|
||||
div.mw-geshi div,div.mw-geshi div pre,span.mw-geshi,pre.source-css,pre.source-javascript{font-family:monospace,Courier !important} @media print{ }
|
||||
|
||||
/* cache key: wikidb:resourceloader:filter:minify-css:4:990d0644862009377a1a48a78b53b366 */
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
1694
resources/PS_2 PC Keyboard Scan Sets Translation Table.html
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
2380
resources/The PS_2 Keyboard Interface.htm
Normal file
517
resources/The PS_2 Mouse_Keyboard Protocol.htm
Normal file
@@ -0,0 +1,517 @@
|
||||
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html><head>
|
||||
|
||||
<meta content="text/html; charset=windows-1252" http-equiv="Content-Type">
|
||||
|
||||
<meta content="Mozilla/4.76 [en] (Win98; U) [Netscape]" name="GENERATOR">
|
||||
|
||||
<meta content="Adam C" name="Author">
|
||||
|
||||
<meta content="This site contains info on the PS/2 protocol and interfacing keyboards and the PS/2 mouse." name="Description">
|
||||
|
||||
<meta content="PS/2, PS/2, PS/2, PS/2, PS/2, PS/2, PS/2, PS/2, PS/2, PS/2, PIC, microcontroller, interfacing, keyboard, mouse, mice, AT keyboard, PS/2 mouse, PC keyboard, interfacing, mouse, PS/2" name="KeyWords">
|
||||
<title>The PS/2 Mouse/Keyboard Protocol</title><!--This file created 3:58 PM 2/5/2000 by Claris Home Page version 3.0-->
|
||||
</head>
|
||||
|
||||
<body vlink="#3333ff" link="#0000ee" bgcolor="#ffffff" alink="#3333ff">
|
||||
<a href="http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/PS2/ps2.htm">http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/PS2/ps2.htm</a><br>
|
||||
<x-claris-window right="1012" left="0" bottom="607" top="0"> <x-claris-tagview mode="minimal"> </x-claris-tagview></x-claris-window>
|
||||
<table cols="1" width="100%" cellspacing="0" cellpadding="4" border="0" bgcolor="#faf0e6">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<center><font size="+2"><br>
|
||||
PS/2 Mouse/Keyboard Protocol</font><br>
|
||||
This article is Copyright 1999, Adam Chapweske </center>
|
||||
<br>
|
||||
|
||||
<p><b>Introduction:</b> </p>
|
||||
|
||||
<p>The PS/2 device interface, used by many modern mice and keyboards,
|
||||
was developed by IBM and originally appeared in the IBM Technical Reference
|
||||
Manual. However, this document has not been printed for many years
|
||||
and as far as I know, there is currently no official publication of this
|
||||
information. I have not had access to the IBM Technical Reference
|
||||
Manual, so all information on this page comes from my own experiences as
|
||||
well as help from the references listed at the bottom of this page. </p>
|
||||
|
||||
<p>This document descibes the interface used by the PS/2 mouse, PS/2
|
||||
keyboard, and AT keyboard. I'll cover the physical and electrical
|
||||
interface, as well as the protocol. If you need higher-level information,
|
||||
such as commands, data packet formats, or other information specific to the
|
||||
keyboard or mouse, I have written separate documents for the two devices:
|
||||
</p>
|
||||
|
||||
<blockquote><a href="http://panda.cs.ndsu.nodak.edu/%7Eachapwes/PICmicro/keyboard/atkeyboard.html">The
|
||||
PS/2 (AT) Keyboard Interface</a> <br>
|
||||
<a href="http://panda.cs.ndsu.nodak.edu/%7Eachapwes/PICmicro/mouse/mouse.html">The
|
||||
PS/2 Mouse Interface</a></blockquote>
|
||||
I also encourage you to check this site's <a href="http://panda.cs.ndsu.nodak.edu/%7Eachapwes/PICmicro">main page</a>
|
||||
for more information related to this topic, including projects, code,
|
||||
and links related to the mouse and keyboard. Please send an <a href="mailto:achapwes@panda.cs.ndsu.nodak.edu">email </a>if you find any
|
||||
mistakes or bad advice on this site.<br>
|
||||
<br>
|
||||
<b>The Physical Interface:</b><br>
|
||||
|
||||
<p>The physical PS/2 port is one of two styles of connectors:
|
||||
The 5-pin DIN or the 6-pin mini-DIN. Both connectors are completely
|
||||
(electrically) similar; the only practical difference between the two is
|
||||
the arrangement of pins. This means the two types of connectors can
|
||||
easily be changed with simple hard-wired adaptors. These cost about
|
||||
$6 each or you can make your own by matching the pins on any two connectors.
|
||||
The DIN standard was created by the German Standardization Organization
|
||||
(Deutsches Institut fuer Norm) . Their website is at <a target="_top" href="http://www.din.de/">http://www.din.de</a> (this site is
|
||||
in German, but most of their pages are also available in English.) </p>
|
||||
|
||||
<p>PC keyboards use either a 6-pin mini-DIN or a 5-pin DIN connector.
|
||||
If your keyboard has a 6-pin mini-DIN and your computer has a 5-pin DIN
|
||||
(or visa versa), the two can be made compatible with the adaptors described
|
||||
above. Keyboards with the 6-pin mini-DIN are often referred to as
|
||||
"PS/2" keyboards, while those with the 5-pin DIN are called "AT" devices
|
||||
("XT" keyboards also used the 5-pin DIN, but they are quite old and haven't
|
||||
been made for many years.) All modern keyboards built for the PC are
|
||||
either PS/2, AT, or USB. This document <i>does not</i> apply to USB
|
||||
devices, which use a completely different interface. </p>
|
||||
|
||||
<p>Mice come in a number of shapes and sizes (and interfaces.)
|
||||
The most popular type is probably the PS/2 mouse, with USB mice gaining
|
||||
popularity. Just a few years ago, serial mice were also quite popular,
|
||||
but the computer industry is abandoning them in support of USB and PS/2 devices.
|
||||
This document applies only to PS/2 mice. If you want to interface
|
||||
a serial or USB mouse, there's plenty of information available elsewhere
|
||||
on the web.<br>
|
||||
<br>
|
||||
The cable connecting the keyboard/mouse to the computer is usually about
|
||||
six feet long and consists of four to six 26 AWG wires surrounded by a thin
|
||||
layer of mylar foil sheilding. If you need a longer cable, you can
|
||||
buy PS/2 extenstion cables from most consumer electronics stores. You
|
||||
should not connect multiple extension cables together. If you need a
|
||||
30-foot keyboard cable, buy a 30-foot keyboard cable. Do not simply
|
||||
connect five 6-foot cables together. Doing so could result in poor communication
|
||||
between the keyboard/mouse and the host.<br>
|
||||
</p>
|
||||
|
||||
<p>As a side note, there is one other type of connector you may run
|
||||
into on keyboards. While most keyboard cables are hard-wired to the keyboard,
|
||||
there are some whose cable is not permanently attached and come as a separate
|
||||
component. These cables have a DIN connector on one end (the end
|
||||
that connects to the computer) and a SDL (Sheilded Data Link) connector
|
||||
on the keyboard end. SDL was created by a company called "AMP."
|
||||
This connector is somewhat similar to a telephone connector in that it has
|
||||
wires and springs rather than pins, and a clip holds it in place.
|
||||
If you need more information on this connector, you might be able to find
|
||||
it on AMP's website at <a target="_top" href="http://www.connect.amp.com/">http://www.connect.amp.com</a>. I have only seen this
|
||||
type of connector on (old) XT keyboards, although there may be AT keyboards
|
||||
that also use the SDL. Don't confuse the SDL connector with the USB
|
||||
connector--they probably both look similar in my diagram below, but they
|
||||
are actually very different. Keep in mind that the SDL connector has
|
||||
springs and moving parts, while the USB connector does not. </p>
|
||||
|
||||
<p>The pinouts for each connector are shown below: <br>
|
||||
|
||||
<table width="468">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
<center>Male <br>
|
||||
<img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/fpindin.JPG" width="80" height="68" align="bottom">
|
||||
<br>
|
||||
(Plug)</center>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<center>Female <br>
|
||||
<img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/fpdin1.JPG" width="80" height="68">
|
||||
<br>
|
||||
(Socket)</center>
|
||||
</td>
|
||||
<td><b>5-pin DIN (AT/XT): </b> <br>
|
||||
1 - Clock <br>
|
||||
2 - Data <br>
|
||||
3 - Not Implemented <br>
|
||||
4 - Ground <br>
|
||||
5 - Vcc (+5V)</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<table width="469">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
<center>Male <br>
|
||||
<img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/spindin.JPG" width="80" height="68" align="bottom">
|
||||
<br>
|
||||
(Plug)</center>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<center>Female <br>
|
||||
<img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/spindin1.JPG" width="80" height="68" align="bottom">
|
||||
<br>
|
||||
(Socket)</center>
|
||||
</td>
|
||||
<td><b>6-pin Mini-DIN (PS/2):</b> <br>
|
||||
1 - Data <br>
|
||||
2 - Not Implemented <br>
|
||||
3 - Ground <br>
|
||||
4 - Vcc (+5V) <br>
|
||||
5 - Clock <br>
|
||||
6 - Not Implemented</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<table width="469">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
<center><img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/sdl.jpg" width="114" height="49" align="bottom">
|
||||
</center>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<center><img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/sdl1.jpg" width="114" height="49" align="bottom">
|
||||
</center>
|
||||
</td>
|
||||
<td><b>6-pin SDL:</b> <br>
|
||||
A - Not Implemented <br>
|
||||
B - Data <br>
|
||||
C - Ground <br>
|
||||
D - Clock <br>
|
||||
E - Vcc (+5V) <br>
|
||||
F - Not Implemented</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<p><br>
|
||||
<b>The Electrical Interface:</b><br>
|
||||
</p>
|
||||
|
||||
<p>Note: Throughout this document, I will use the more general
|
||||
term "host" to refer to the computer--or whatever the keyboard/mouse is
|
||||
connected to-- and the term "device" will refer to the keyboard/mouse. </p>
|
||||
|
||||
<p>Vcc/Ground provide power to the keyboard/mouse. The keyboard
|
||||
or mouse should not draw more than 100 mA from the host and care must be
|
||||
taken to avoid transient surges. Such surges can be caused by "hot-plugging"
|
||||
a keyboard/mouse (ie, connect/disconnect the device while the computer's
|
||||
power is on.) Older motherboards had a surface-mounted fuse protecting
|
||||
the keyboard and mouse ports. When this fuse blew, the motherboard was
|
||||
useless to the consumer, and non-fixable to the average technician. Most
|
||||
newer motherboards use auto-reset "Poly" fuses that go a long way to remedy
|
||||
this problem. However, this is not a standard and there's still plenty
|
||||
of older motherboards in use. Therefore, I recommend against hot-plugging
|
||||
a PS/2 mouse or keyboard.<br>
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<p><u>Summary: Power Specifications</u><br>
|
||||
Vcc = +5V. <br>
|
||||
Max Current = 100 mA.<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<p>The Data and Clock lines are both open-collector with pullup resistors
|
||||
to +5V. An "open-collector" interface has two possible state: low,
|
||||
or high impedance. In the "low" state, a transistor pulls the line to
|
||||
ground level. In the "high impedance" state, the interface acts as
|
||||
an open circuit and doesn't drive the line low or high. Furthermore, a "pullup"
|
||||
resistor is connected between the bus and Vcc so the bus is pulled high if
|
||||
none of the devices on the bus are actively pulling it low. The exact
|
||||
value of this resistor isn't too important (1~10 kOhms); larger resistances
|
||||
result in less power consumption and smaller resistances result in a faster
|
||||
rise time. A general open-collector interface is shown below:<br>
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<p><font color="#ff0000">Figure 1: General open-collector interface.
|
||||
Data and Clock are read on the microcontroller's pins A and B, respectively.
|
||||
Both lines are normally held at +5V, but can be pulled to ground by
|
||||
asserting logic "1" on C and D. As a result, Data equals D, inverted,
|
||||
and Clock equals C, inverted.</font><br>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<blockquote>
|
||||
<p><img alt="" src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/ps2.JPG" width="352" height="330">
|
||||
<br>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<p><br>
|
||||
Note: When looking through examples on this website, you'll notice I use
|
||||
a few tricks when implementing an open-collector interface with PIC microcontrollers.
|
||||
I use the same pin for both input and output, and I enable the PIC's
|
||||
internal pullup resistors rather than using external resistors. A line
|
||||
is pulled to ground by setting the corresponding pin to output, and writing
|
||||
a "zero" to that port. The line is set to the "high impedance" state
|
||||
by setting the pin to input. Taking into account the PIC's built-in
|
||||
protection diodes and sufficient current sinking, I think this is a valid
|
||||
configuration. Let me know if your experiences have proved otherwise.<br>
|
||||
<br>
|
||||
<b>Communication: General Description</b><br>
|
||||
</p>
|
||||
|
||||
<p>The PS/2 mouse and keyboard implement a bidirectional synchronous
|
||||
serial protocol. The bus is "idle" when both lines are high (open-collector).
|
||||
This is the only state where the keyboard/mouse is allowed begin transmitting
|
||||
data. The host has ultimate control over the bus and may inhibit
|
||||
communication at any time by pulling the Clock line low. <br>
|
||||
</p>
|
||||
|
||||
<p>The device always generates the clock signal. If the host
|
||||
wants to send data, it must first inhibit communication from the device by
|
||||
pulling Clock low. The host then pulls Data low and releases Clock.
|
||||
This is the "Request-to-Send" state and signals the device to start
|
||||
generating clock pulses.<br>
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<p><u>Summary: Bus States</u><br>
|
||||
Data = high, Clock = high: <i>Idle state.</i><br>
|
||||
Data = high, Clock = low: <i>Communication Inhibited.</i><br>
|
||||
Data = low, Clock = high: <i>Host Request-to-Send</i></p>
|
||||
</blockquote>
|
||||
All data is transmitted one byte at a time and each byte is sent
|
||||
in a frame consisting of 11-12 bits. These bits are:
|
||||
|
||||
<ul>
|
||||
<li> 1 start bit. This is always 0.</li>
|
||||
<li> 8 data bits, least significant bit first.</li>
|
||||
<li> 1 parity bit (odd parity).</li>
|
||||
<li> 1 stop bit. This is always 1.</li>
|
||||
<li> 1 acknowledge bit (host-to-device communication only)</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p> The parity bit is set if there is an even number of 1's in the data
|
||||
bits and reset (0) if there is an odd number of 1's in the data bits.
|
||||
The number of 1's in the data bits plus the parity bit always add up to
|
||||
an odd number (odd parity.) This is used for error detection. The
|
||||
keyboard/mouse must check this bit and if incorrect it should respond as
|
||||
if it had received an invalid command.<br>
|
||||
</p>
|
||||
|
||||
<p>Data sent from the device to the host is read on the <i>falling
|
||||
</i>edge of the clock signal; data sent from the host to the device
|
||||
is read on the <i>rising </i>edge<i>.</i> The clock frequency
|
||||
must be in the range 10 - 16.7 kHz. This means clock must be high for
|
||||
30 - 50 microseconds and low for 30 - 50 microseconds.. If you're designing
|
||||
a keyboard, mouse, or host emulator, you should modify/sample the Data line
|
||||
in the middle of each cell. I.e. 15 - 25 microseconds after
|
||||
the appropriate clock transition. Again, the keyboard/mouse always
|
||||
generates the clock signal, but the host always has ultimate control over
|
||||
communication. </p>
|
||||
|
||||
<p> </p>
|
||||
Timing is absolutely crucial. Every time quantity I give in this
|
||||
article must be followed exactly.<br>
|
||||
<br>
|
||||
<b>Communication: Device-to-Host</b><br>
|
||||
|
||||
<p>The Data and Clock lines are both open collector. A resistor
|
||||
is connected between each line and +5V, so the idle state of the bus is
|
||||
high. When the keyboard or mouse wants to send information, it first checks
|
||||
the Clock line to make sure it's at a high logic level. If it's not,
|
||||
the host is inhibiting communication and the device must buffer any to-be-sent
|
||||
data until the host releases Clock. The Clock line must be continuously
|
||||
high for at least 50 microseconds before the device can begin to transmit
|
||||
its data. </p>
|
||||
|
||||
<p>As I mentioned in the previous section, the keyboard and mouse use
|
||||
a serial protocol with 11-bit frames. These bits are: </p>
|
||||
|
||||
<ul>
|
||||
<li> 1 start bit. This is always 0.</li>
|
||||
<li> 8 data bits, least significant bit first.</li>
|
||||
<li> 1 parity bit (odd parity).</li>
|
||||
<li> 1 stop bit. This is always 1.</li>
|
||||
|
||||
</ul>
|
||||
The keyboard/mouse writes a bit on the Data line when Clock is
|
||||
high, and it is read by the host when Clock is low. Figures 2 and 3
|
||||
illustrate this.<br>
|
||||
|
||||
<p><font color="#ff0000">Figure 2: Device-to-host communication.
|
||||
The Data line changes state when Clock is high and that data is valid
|
||||
when Clock is low.</font> <br>
|
||||
</p>
|
||||
|
||||
<blockquote><img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/waveform1.jpg" width="432" height="139">
|
||||
</blockquote>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<p><font color="#ff0000">Figure 3: Scan code for the "Q" key (15h)
|
||||
being sent from a keyboard to the computer. Channel A is the Clock
|
||||
signal; channel B is the Data signal.</font> </p>
|
||||
|
||||
<blockquote><font color="#ffffff">---</font><img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/qscope.JPG" width="386" height="255">
|
||||
<br>
|
||||
</blockquote>
|
||||
|
||||
<p> The clock frequency is 10-16.7 kHz. The time from the rising
|
||||
edge of a clock pulse to a Data transition must be at least 5 microseconds.
|
||||
The time from a data transition to the falling edge of a clock pulse must
|
||||
be at least 5 microseconds and no greater than 25 microseconds. <br>
|
||||
</p>
|
||||
|
||||
<p>The host may inhibit communication at any time by pulling the Clock
|
||||
line low for at least 100 microseconds. If a transmission is inhibited
|
||||
before the 11th clock pulse, the device must abort the current transmission
|
||||
and prepare to retransmit the current "chunk" of data when host releases
|
||||
Clock. A "chunk" of data could be a make code, break code, device ID,
|
||||
mouse movement packet, etc. For example, if a keyboard is interrupted
|
||||
while sending the second byte of a two-byte break code, it will need to retransmit
|
||||
both bytes of that break code, not just the one that was interrupted.<br>
|
||||
</p>
|
||||
|
||||
<p>If the host pulls clock low before the first high-to-low clock transition,
|
||||
or after the falling edge of the last clock pulse, the keyboard/mouse does
|
||||
not need to retransmit any data. However, if new data is created that
|
||||
needs to be transmitted, it will have to be buffered until the host releases
|
||||
Clock. Keyboards have a 16-byte buffer for this purpose. If more
|
||||
than 16 bytes worth of keystrokes occur, further keystrokes will be ignored
|
||||
until there's room in the buffer. Mice only store the most current movement
|
||||
packet for transmission. </p>
|
||||
|
||||
<p></p>
|
||||
|
||||
<p><b>Host-to-Device Communication:</b><br>
|
||||
</p>
|
||||
|
||||
<p>The packet is sent a little differently in host-to-device communication...
|
||||
</p>
|
||||
|
||||
<p>First of all, the PS/2 device always generates the clock signal.
|
||||
If the host wants to send data, it must first put the Clock and Data lines
|
||||
in a "Request-to-send" state as follows: </p>
|
||||
|
||||
<ul>
|
||||
<li> Inhibit communication by pulling Clock low for at least
|
||||
100 microseconds.</li>
|
||||
<li> Apply "Request-to-send" by pulling Data low, then release
|
||||
Clock.</li>
|
||||
|
||||
</ul>
|
||||
The device should check for this state at intervals not to exceed 10
|
||||
milliseconds. When the device detects this state, it will begin
|
||||
generating Clock signals and clock in eight data bits and one stop bit.
|
||||
The host changes the Data line only when the Clock line is low, and
|
||||
data is read by the device when Clock is high. This is opposite of
|
||||
what occours in device-to-host communication.
|
||||
|
||||
<p>After the stop bit is received, the device will acknowledge the received
|
||||
byte by bringing the Data line low and generating one last clock pulse.
|
||||
If the host does not release the Data line after the 11th clock pulse, the
|
||||
device will continue to generate clock pulses until the the Data line is
|
||||
released (the device will then generate an error.) </p>
|
||||
|
||||
<p>The host may abort transmission at time before the 11th clock pulse
|
||||
(acknowledge bit) by holding Clock low for at least 100 microseconds.
|
||||
</p>
|
||||
|
||||
<p>To make this process a little easier to understand, here's the steps
|
||||
the host must follow to send data to a PS/2 device: </p>
|
||||
|
||||
<blockquote>1) Bring the Clock line low for at least 100
|
||||
microseconds. <br>
|
||||
2) Bring the Data line low. <br>
|
||||
3) Release the Clock line. <br>
|
||||
4) Wait for the device to bring the Clock line low.
|
||||
<br>
|
||||
5) Set/reset the Data line to send the first data bit
|
||||
<br>
|
||||
6) Wait for the device to bring Clock high. <br>
|
||||
7) Wait for the device to bring Clock low. <br>
|
||||
8) Repeat steps 5-7 for the other seven data bits and the
|
||||
parity bit <br>
|
||||
9) Release the Data line. <br>
|
||||
10) Wait for the device to bring Data low. <br>
|
||||
11) Wait for the device to bring Clock low. <br>
|
||||
12) Wait for the device to release Data and Clock</blockquote>
|
||||
|
||||
<p><br>
|
||||
<font color="#000000">Figure 3 shows this graphically and Figure
|
||||
4 separates the timing to show which signals are generated by the host,
|
||||
and which are generated by the PS/2 device. Notice the change in timing
|
||||
for the "ack" bit--the data transition occours when the Clock line is
|
||||
high (rather than when it is low as is the case for the other 11 bits.)</font>
|
||||
</p>
|
||||
|
||||
<p><font color="#ff0000">Figure 3: Host-to-Device Communication.</font>
|
||||
<br>
|
||||
<img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/waveform2.jpg" width="504" height="131">
|
||||
</p>
|
||||
|
||||
<p><font color="#ff0000">Figure 4: Detailed host-to-device communication.</font>
|
||||
<br>
|
||||
<img src="The%20PS_2%20Mouse_Keyboard%20Protocol_files/waveform3.jpg" width="552" height="247">
|
||||
<br>
|
||||
</p>
|
||||
|
||||
<p>Referring to Figure 4, there's two time quantities the host looks
|
||||
for. (a) is the time it takes the device to begin generating clock pulses
|
||||
after the host initially takes the Clock line low, which must be no greater
|
||||
than 15 ms. (b) is the time it takes for the packet to be sent, which
|
||||
must be no greater than 2ms. If either of these time limits is not
|
||||
met, the host should generate an error. Immediately after the "ack"
|
||||
is received, the host may bring the Clock line low to inhibit communication
|
||||
while it processes data. If the command sent by the host requires a
|
||||
response, that response must be received no later than 20 ms after the host
|
||||
releases the Clock line. If this does not happen, the host generates
|
||||
an error. </p>
|
||||
|
||||
<p></p>
|
||||
|
||||
<ul>
|
||||
|
||||
<ul>
|
||||
|
||||
</ul>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<p> </p>
|
||||
|
||||
|
||||
<blockquote> </blockquote>
|
||||
<b>Other Sources / References:</b>
|
||||
|
||||
<ul>
|
||||
<li> <a href="http://govschl.ndsu.nodak.edu/%7Eachapwes/PICmicro/index.html">Adam's
|
||||
micro-Resources Home</a></li>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<center> </center>
|
||||
|
||||
<center></center>
|
||||
|
||||
<p><br>
|
||||
</p>
|
||||
|
||||
<p><b></b></p>
|
||||
<br>
|
||||
|
||||
</body></html>
|
||||
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/fpdin1.JPG
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/fpindin.JPG
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/ps2.JPG
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/qscope.JPG
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/sdl.jpg
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/sdl1.jpg
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/spindin.JPG
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/spindin1.JPG
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/waveform1.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/waveform2.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
resources/The PS_2 Mouse_Keyboard Protocol_files/waveform3.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
33
resources/Wayback Machine.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Wayback Machine</title>
|
||||
<script src="Wayback%20Machine_files/analytics.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">window.addEventListener('DOMContentLoaded',function(){var v=archive_analytics.values;v.service='wb';v.server_name='wwwb-app227.us.archive.org';v.server_ms=1120;archive_analytics.send_pageview({});});</script>
|
||||
<script type="text/javascript" src="Wayback%20Machine_files/bundle-playback.js" charset="utf-8"></script>
|
||||
<link rel="stylesheet" type="text/css" href="Wayback%20Machine_files/banner-styles.css">
|
||||
<link rel="stylesheet" type="text/css" href="Wayback%20Machine_files/iconochive.css">
|
||||
<script src="Wayback%20Machine_files/jquery-1.js"></script>
|
||||
</head>
|
||||
<body style="height:100vh;overflow:hidden;margin:0;display:flex;flex-flow:column nowrap;align-items:stretch;">
|
||||
<div style="flex:0 0;">
|
||||
<!-- BEGIN WAYBACK TOOLBAR INSERT -->
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin-top:0 !important;
|
||||
padding-top:0 !important;
|
||||
/*min-width:800px !important;*/
|
||||
}
|
||||
</style>
|
||||
<script>__wm.rw(0);</script>
|
||||
<div id="wm-ipp-base" style="display: block; direction: ltr;" lang="en">
|
||||
</div><div id="wm-ipp-print">The Wayback Machine - https://web.archive.org/web/20170108131104/http://www.computer-engineering.org/ps2keyboard/scancodes3.html</div>
|
||||
<script type="text/javascript">
|
||||
__wm.bt(675,27,25,2,"web","http://www.computer-engineering.org/ps2keyboard/scancodes3.html","20170108131104",1996,"/_static/",["/_static/css/banner-styles.css?v=fantwOh2","/_static/css/iconochive.css?v=qtvMKcIJ"], false);
|
||||
__wm.rw(1);
|
||||
</script>
|
||||
<!-- END WAYBACK TOOLBAR INSERT --></div>
|
||||
<iframe id="playback" src="Wayback%20Machine_files/scancodes3.htm" style="flex:1 0" frameborder="0">
|
||||
</iframe>
|
||||
|
||||
</body></html>
|
||||
474
resources/Wayback Machine_files/analytics.js
Normal file
@@ -0,0 +1,474 @@
|
||||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0
|
||||
/* eslint-disable no-var, semi, prefer-arrow-callback, prefer-template */
|
||||
|
||||
/**
|
||||
* Collection of methods for sending analytics events to Archive.org's analytics server.
|
||||
*
|
||||
* These events are used for internal stats and sent (in anonymized form) to Google Analytics.
|
||||
*
|
||||
* @see analytics.md
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
window.archive_analytics = (function defineArchiveAnalytics() {
|
||||
// keep orignal Date object so as not to be affected by wayback's
|
||||
// hijacking global Date object
|
||||
var Date = window.Date;
|
||||
var ARCHIVE_ANALYTICS_VERSION = 2;
|
||||
var DEFAULT_SERVICE = 'ao_2';
|
||||
var NO_SAMPLING_SERVICE = 'ao_no_sampling'; // sends every event instead of a percentage
|
||||
|
||||
var startTime = new Date();
|
||||
|
||||
/**
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function isPerformanceTimingApiSupported() {
|
||||
return 'performance' in window && 'timing' in window.performance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines how many milliseconds elapsed between the browser starting to parse the DOM and
|
||||
* the current time.
|
||||
*
|
||||
* Uses the Performance API or a fallback value if it's not available.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API
|
||||
*
|
||||
* @return {Number}
|
||||
*/
|
||||
function getLoadTime() {
|
||||
var start;
|
||||
|
||||
if (isPerformanceTimingApiSupported())
|
||||
start = window.performance.timing.domLoading;
|
||||
else
|
||||
start = startTime.getTime();
|
||||
|
||||
return new Date().getTime() - start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines how many milliseconds elapsed between the user navigating to the page and
|
||||
* the current time.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API
|
||||
*
|
||||
* @return {Number|null} null if the browser doesn't support the Performance API
|
||||
*/
|
||||
function getNavToDoneTime() {
|
||||
if (!isPerformanceTimingApiSupported())
|
||||
return null;
|
||||
|
||||
return new Date().getTime() - window.performance.timing.navigationStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an arithmetic calculation on a string with a number and unit, while maintaining
|
||||
* the unit.
|
||||
*
|
||||
* @param {String} original value to modify, with a unit
|
||||
* @param {Function} doOperation accepts one Number parameter, returns a Number
|
||||
* @returns {String}
|
||||
*/
|
||||
function computeWithUnit(original, doOperation) {
|
||||
var number = parseFloat(original, 10);
|
||||
var unit = original.replace(/(\d*\.\d+)|\d+/, '');
|
||||
|
||||
return doOperation(number) + unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the default font size of the browser.
|
||||
*
|
||||
* @returns {String|null} computed font-size with units (typically pixels), null if it cannot be computed
|
||||
*/
|
||||
function getDefaultFontSize() {
|
||||
var fontSizeStr;
|
||||
|
||||
if (!('getComputedStyle' in window))
|
||||
return null;
|
||||
|
||||
var style = window.getComputedStyle(document.documentElement);
|
||||
if (!style)
|
||||
return null;
|
||||
|
||||
fontSizeStr = style.fontSize;
|
||||
|
||||
// Don't modify the value if tracking book reader.
|
||||
if (document.querySelector('#BookReader'))
|
||||
return fontSizeStr;
|
||||
|
||||
return computeWithUnit(fontSizeStr, function reverseBootstrapFontSize(number) {
|
||||
// Undo the 62.5% size applied in the Bootstrap CSS.
|
||||
return number * 1.6;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL parameters for a given Location
|
||||
* @param {Location}
|
||||
* @return {Object} The URL parameters
|
||||
*/
|
||||
function getParams(location) {
|
||||
if (!location) location = window.location;
|
||||
var vars;
|
||||
var i;
|
||||
var pair;
|
||||
var params = {};
|
||||
var query = location.search;
|
||||
if (!query) return params;
|
||||
vars = query.substring(1).split('&');
|
||||
for (i = 0; i < vars.length; i++) {
|
||||
pair = vars[i].split('=');
|
||||
params[pair[0]] = decodeURIComponent(pair[1]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function getMetaProp(name) {
|
||||
var metaTag = document.querySelector('meta[property=' + name + ']');
|
||||
return metaTag ? metaTag.getAttribute('content') || null : null;
|
||||
}
|
||||
|
||||
var ArchiveAnalytics = {
|
||||
/**
|
||||
* @type {String|null}
|
||||
*/
|
||||
service: getMetaProp('service'),
|
||||
mediaType: getMetaProp('mediatype'),
|
||||
primaryCollection: getMetaProp('primary_collection'),
|
||||
|
||||
/**
|
||||
* Key-value pairs to send in pageviews (you can read this after a pageview to see what was
|
||||
* sent).
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
values: {},
|
||||
|
||||
/**
|
||||
* Sends an analytics ping, preferably using navigator.sendBeacon()
|
||||
* @param {Object} values
|
||||
* @param {Function} [onload_callback] (deprecated) callback to invoke once ping to analytics server is done
|
||||
* @param {Boolean} [augment_for_ao_site] (deprecated) if true, add some archive.org site-specific values
|
||||
*/
|
||||
send_ping: function send_ping(values, onload_callback, augment_for_ao_site) {
|
||||
if (typeof window.navigator !== 'undefined' && typeof window.navigator.sendBeacon !== 'undefined')
|
||||
this.send_ping_via_beacon(values);
|
||||
else
|
||||
this.send_ping_via_image(values);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a ping via Beacon API
|
||||
* NOTE: Assumes window.navigator.sendBeacon exists
|
||||
* @param {Object} values Tracking parameters to pass
|
||||
*/
|
||||
send_ping_via_beacon: function send_ping_via_beacon(values) {
|
||||
var url = this.generate_tracking_url(values || {});
|
||||
window.navigator.sendBeacon(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a ping via Image object
|
||||
* @param {Object} values Tracking parameters to pass
|
||||
*/
|
||||
send_ping_via_image: function send_ping_via_image(values) {
|
||||
var url = this.generate_tracking_url(values || {});
|
||||
var loadtime_img = new Image(1, 1);
|
||||
loadtime_img.src = url;
|
||||
loadtime_img.alt = '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Construct complete tracking URL containing payload
|
||||
* @param {Object} params Tracking parameters to pass
|
||||
* @return {String} URL to use for tracking call
|
||||
*/
|
||||
generate_tracking_url: function generate_tracking_url(params) {
|
||||
var baseUrl = '//analytics.archive.org/0.gif';
|
||||
var keys;
|
||||
var outputParams = params;
|
||||
var outputParamsArray = [];
|
||||
|
||||
outputParams.service = outputParams.service || this.service || DEFAULT_SERVICE;
|
||||
|
||||
// Build array of querystring parameters
|
||||
keys = Object.keys(outputParams);
|
||||
keys.forEach(function keyIteration(key) {
|
||||
outputParamsArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(outputParams[key]));
|
||||
});
|
||||
outputParamsArray.push('version=' + ARCHIVE_ANALYTICS_VERSION);
|
||||
outputParamsArray.push('count=' + (keys.length + 2)); // Include `version` and `count` in count
|
||||
|
||||
return baseUrl + '?' + outputParamsArray.join('&');
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {int} page Page number
|
||||
*/
|
||||
send_scroll_fetch_event: function send_scroll_fetch_event(page) {
|
||||
var additionalValues = { ev: page };
|
||||
var loadTime = getLoadTime();
|
||||
var navToDoneTime = getNavToDoneTime();
|
||||
if (loadTime) additionalValues.loadtime = loadTime;
|
||||
if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime;
|
||||
this.send_event('page_action', 'scroll_fetch', location.pathname, additionalValues);
|
||||
},
|
||||
|
||||
send_scroll_fetch_base_event: function send_scroll_fetch_base_event() {
|
||||
var additionalValues = {};
|
||||
var loadTime = getLoadTime();
|
||||
var navToDoneTime = getNavToDoneTime();
|
||||
if (loadTime) additionalValues.loadtime = loadTime;
|
||||
if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime;
|
||||
this.send_event('page_action', 'scroll_fetch_base', location.pathname, additionalValues);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} [options]
|
||||
* @param {String} [options.mediaType]
|
||||
* @param {String} [options.mediaLanguage]
|
||||
* @param {String} [options.page] The path portion of the page URL
|
||||
*/
|
||||
send_pageview: function send_pageview(options) {
|
||||
var settings = options || {};
|
||||
|
||||
var defaultFontSize;
|
||||
var loadTime = getLoadTime();
|
||||
var mediaType = settings.mediaType;
|
||||
var primaryCollection = settings.primaryCollection;
|
||||
var page = settings.page;
|
||||
var navToDoneTime = getNavToDoneTime();
|
||||
|
||||
/**
|
||||
* @return {String}
|
||||
*/
|
||||
function get_locale() {
|
||||
if (navigator) {
|
||||
if (navigator.language)
|
||||
return navigator.language;
|
||||
|
||||
else if (navigator.browserLanguage)
|
||||
return navigator.browserLanguage;
|
||||
|
||||
else if (navigator.systemLanguage)
|
||||
return navigator.systemLanguage;
|
||||
|
||||
else if (navigator.userLanguage)
|
||||
return navigator.userLanguage;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
defaultFontSize = getDefaultFontSize();
|
||||
|
||||
// Set field values
|
||||
this.values.kind = 'pageview';
|
||||
this.values.timediff = (new Date().getTimezoneOffset()/60)*(-1); // *timezone* diff from UTC
|
||||
this.values.locale = get_locale();
|
||||
this.values.referrer = (document.referrer == '' ? '-' : document.referrer);
|
||||
|
||||
if (loadTime)
|
||||
this.values.loadtime = loadTime;
|
||||
|
||||
if (navToDoneTime)
|
||||
this.values.nav_to_done_ms = navToDoneTime;
|
||||
|
||||
if (settings.trackingId) {
|
||||
this.values.ga_tid = settings.trackingId;
|
||||
}
|
||||
|
||||
/* START CUSTOM DIMENSIONS */
|
||||
if (defaultFontSize)
|
||||
this.values.ga_cd1 = defaultFontSize;
|
||||
|
||||
if ('devicePixelRatio' in window)
|
||||
this.values.ga_cd2 = window.devicePixelRatio;
|
||||
|
||||
if (mediaType)
|
||||
this.values.ga_cd3 = mediaType;
|
||||
|
||||
if (settings.mediaLanguage) {
|
||||
this.values.ga_cd4 = settings.mediaLanguage;
|
||||
}
|
||||
|
||||
if (primaryCollection) {
|
||||
this.values.ga_cd5 = primaryCollection;
|
||||
}
|
||||
/* END CUSTOM DIMENSIONS */
|
||||
|
||||
if (page)
|
||||
this.values.page = page;
|
||||
|
||||
this.send_ping(this.values);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a tracking "Event".
|
||||
* @param {string} category
|
||||
* @param {string} action
|
||||
* @param {string} label
|
||||
* @param {Object} additionalEventParams
|
||||
*/
|
||||
send_event: function send_event(
|
||||
category,
|
||||
action,
|
||||
label,
|
||||
additionalEventParams
|
||||
) {
|
||||
if (!label) label = window.location.pathname;
|
||||
if (!additionalEventParams) additionalEventParams = {};
|
||||
if (additionalEventParams.mediaLanguage) {
|
||||
additionalEventParams.ga_cd4 = additionalEventParams.mediaLanguage;
|
||||
delete additionalEventParams.mediaLanguage;
|
||||
}
|
||||
var eventParams = Object.assign(
|
||||
{
|
||||
kind: 'event',
|
||||
ec: category,
|
||||
ea: action,
|
||||
el: label,
|
||||
cache_bust: Math.random(),
|
||||
},
|
||||
additionalEventParams
|
||||
);
|
||||
this.send_ping(eventParams);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends every event instead of a small percentage.
|
||||
*
|
||||
* Use this sparingly as it can generate a lot of events.
|
||||
*
|
||||
* @param {string} category
|
||||
* @param {string} action
|
||||
* @param {string} label
|
||||
* @param {Object} additionalEventParams
|
||||
*/
|
||||
send_event_no_sampling: function send_event_no_sampling(
|
||||
category,
|
||||
action,
|
||||
label,
|
||||
additionalEventParams
|
||||
) {
|
||||
var extraParams = additionalEventParams || {};
|
||||
extraParams.service = NO_SAMPLING_SERVICE;
|
||||
this.send_event(category, action, label, extraParams);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} options see this.send_pageview options
|
||||
*/
|
||||
send_pageview_on_load: function send_pageview_on_load(options) {
|
||||
var self = this;
|
||||
window.addEventListener('load', function send_pageview_with_options() {
|
||||
self.send_pageview(options);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles tracking events passed in URL.
|
||||
* Assumes category and action values are separated by a "|" character.
|
||||
* NOTE: Uses the unsampled analytics property. Watch out for future high click links!
|
||||
* @param {Location}
|
||||
*/
|
||||
process_url_events: function process_url_events(location) {
|
||||
var eventValues;
|
||||
var actionValue;
|
||||
var eventValue = getParams(location).iax;
|
||||
if (!eventValue) return;
|
||||
eventValues = eventValue.split('|');
|
||||
actionValue = eventValues.length >= 1 ? eventValues[1] : '';
|
||||
this.send_event_no_sampling(
|
||||
eventValues[0],
|
||||
actionValue,
|
||||
window.location.pathname
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Attaches handlers for event tracking.
|
||||
*
|
||||
* To enable click tracking for a link, add a `data-event-click-tracking`
|
||||
* attribute containing the Google Analytics Event Category and Action, separated
|
||||
* by a vertical pipe (|).
|
||||
* e.g. `<a href="foobar" data-event-click-tracking="TopNav|FooBar">`
|
||||
*
|
||||
* To enable form submit tracking, add a `data-event-form-tracking` attribute
|
||||
* to the `form` tag.
|
||||
* e.g. `<form data-event-form-tracking="TopNav|SearchForm" method="GET">`
|
||||
*
|
||||
* Additional tracking options can be added via a `data-event-tracking-options`
|
||||
* parameter. This parameter, if included, should be a JSON string of the parameters.
|
||||
* Valid parameters are:
|
||||
* - service {string}: Corresponds to the Google Analytics property data values flow into
|
||||
*/
|
||||
set_up_event_tracking: function set_up_event_tracking() {
|
||||
var self = this;
|
||||
var clickTrackingAttributeName = 'event-click-tracking';
|
||||
var formTrackingAttributeName = 'event-form-tracking';
|
||||
var trackingOptionsAttributeName = 'event-tracking-options';
|
||||
|
||||
function handleAction(event, attributeName) {
|
||||
var selector = '[data-' + attributeName + ']';
|
||||
var eventTarget = event.target;
|
||||
if (!eventTarget) return;
|
||||
var target = eventTarget.closest(selector);
|
||||
if (!target) return;
|
||||
var categoryAction;
|
||||
var categoryActionParts;
|
||||
var options;
|
||||
categoryAction = target.dataset[toCamelCase(attributeName)];
|
||||
if (!categoryAction) return;
|
||||
categoryActionParts = categoryAction.split('|');
|
||||
options = target.dataset[toCamelCase(trackingOptionsAttributeName)];
|
||||
options = options ? JSON.parse(options) : {};
|
||||
self.send_event(
|
||||
categoryActionParts[0],
|
||||
categoryActionParts[1],
|
||||
categoryActionParts[2] || window.location.pathname,
|
||||
options.service ? { service: options.service } : {}
|
||||
);
|
||||
}
|
||||
|
||||
function toCamelCase(str) {
|
||||
return str.replace(/\W+(.)/g, function (match, chr) {
|
||||
return chr.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
handleAction(e, clickTrackingAttributeName);
|
||||
});
|
||||
|
||||
document.addEventListener('submit', function(e) {
|
||||
handleAction(e, formTrackingAttributeName);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
get_data_packets: function get_data_packets() {
|
||||
return [this.values];
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a tracking image for tracking JS compatibility.
|
||||
*
|
||||
* @param {string} type The type value for track_js_case in query params for 0.gif
|
||||
*/
|
||||
create_tracking_image: function create_tracking_image(type) {
|
||||
this.send_ping_via_image({
|
||||
cache_bust: Math.random(),
|
||||
kind: 'track_js',
|
||||
track_js_case: type,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return ArchiveAnalytics;
|
||||
}());
|
||||
// @license-end
|
||||
500
resources/Wayback Machine_files/banner-styles.css
Normal file
@@ -0,0 +1,500 @@
|
||||
@import 'record.css'; /* for SPN1 */
|
||||
|
||||
#wm-ipp-base {
|
||||
height:65px;/* initial height just in case js code fails */
|
||||
padding:0;
|
||||
margin:0;
|
||||
border:none;
|
||||
background:none transparent;
|
||||
}
|
||||
#wm-ipp {
|
||||
z-index: 2147483647;
|
||||
}
|
||||
#wm-ipp, #wm-ipp * {
|
||||
font-family:Lucida Grande, Helvetica, Arial, sans-serif;
|
||||
font-size:12px;
|
||||
line-height:1.2;
|
||||
letter-spacing:0;
|
||||
width:auto;
|
||||
height:auto;
|
||||
max-width:none;
|
||||
max-height:none;
|
||||
min-width:0 !important;
|
||||
min-height:0;
|
||||
outline:none;
|
||||
float:none;
|
||||
text-align:left;
|
||||
border:none;
|
||||
color: #000;
|
||||
text-indent: 0;
|
||||
position: initial;
|
||||
background: none;
|
||||
}
|
||||
#wm-ipp div, #wm-ipp canvas {
|
||||
display: block;
|
||||
}
|
||||
#wm-ipp div, #wm-ipp tr, #wm-ipp td, #wm-ipp a, #wm-ipp form {
|
||||
padding:0;
|
||||
margin:0;
|
||||
border:none;
|
||||
border-radius:0;
|
||||
background-color:transparent;
|
||||
background-image:none;
|
||||
/*z-index:2147483640;*/
|
||||
height:auto;
|
||||
}
|
||||
#wm-ipp table {
|
||||
border:none;
|
||||
border-collapse:collapse;
|
||||
margin:0;
|
||||
padding:0;
|
||||
width:auto;
|
||||
font-size:inherit;
|
||||
}
|
||||
#wm-ipp form input {
|
||||
padding:1px !important;
|
||||
height:auto;
|
||||
display:inline;
|
||||
margin:0;
|
||||
color: #000;
|
||||
background: none #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
#wm-ipp form input[type=submit] {
|
||||
padding:0 8px !important;
|
||||
margin:1px 0 1px 5px !important;
|
||||
width:auto !important;
|
||||
border: 1px solid #000 !important;
|
||||
background: #fff !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
#wm-ipp a {
|
||||
display: inline;
|
||||
}
|
||||
#wm-ipp a:hover{
|
||||
text-decoration:underline;
|
||||
}
|
||||
#wm-ipp a.wm-btn:hover {
|
||||
text-decoration:none;
|
||||
color:#ff0 !important;
|
||||
}
|
||||
#wm-ipp a.wm-btn:hover span {
|
||||
color:#ff0 !important;
|
||||
}
|
||||
#wm-ipp #wm-ipp-inside {
|
||||
margin: 0 6px;
|
||||
border:5px solid #000;
|
||||
border-top:none;
|
||||
background-color:rgba(255,255,255,0.9);
|
||||
-moz-box-shadow:1px 1px 4px #333;
|
||||
-webkit-box-shadow:1px 1px 4px #333;
|
||||
box-shadow:1px 1px 4px #333;
|
||||
border-radius:0 0 8px 8px;
|
||||
}
|
||||
/* selectors are intentionally verbose to ensure priority */
|
||||
#wm-ipp #wm-logo {
|
||||
padding:0 10px;
|
||||
vertical-align:middle;
|
||||
min-width:100px;
|
||||
flex: 0 0 100px;
|
||||
}
|
||||
#wm-ipp .c {
|
||||
padding-left: 4px;
|
||||
}
|
||||
#wm-ipp .c .u {
|
||||
margin-top: 4px !important;
|
||||
}
|
||||
#wm-ipp .n {
|
||||
padding:0 0 0 5px !important;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
#wm-ipp .n a {
|
||||
text-decoration:none;
|
||||
color:#33f;
|
||||
font-weight:bold;
|
||||
}
|
||||
#wm-ipp .n .b {
|
||||
padding:0 6px 0 0 !important;
|
||||
text-align:right !important;
|
||||
overflow:visible;
|
||||
white-space:nowrap;
|
||||
color:#99a;
|
||||
vertical-align:middle;
|
||||
}
|
||||
#wm-ipp .n .y .b {
|
||||
padding:0 6px 2px 0 !important;
|
||||
}
|
||||
#wm-ipp .n .c {
|
||||
background:#000;
|
||||
color:#ff0;
|
||||
font-weight:bold;
|
||||
padding:0 !important;
|
||||
text-align:center;
|
||||
}
|
||||
#wm-ipp.hi .n td.c {
|
||||
color:#ec008c;
|
||||
}
|
||||
#wm-ipp .n td.f {
|
||||
padding:0 0 0 6px !important;
|
||||
text-align:left !important;
|
||||
overflow:visible;
|
||||
white-space:nowrap;
|
||||
color:#99a;
|
||||
vertical-align:middle;
|
||||
}
|
||||
#wm-ipp .n tr.m td {
|
||||
text-transform:uppercase;
|
||||
white-space:nowrap;
|
||||
padding:2px 0;
|
||||
}
|
||||
#wm-ipp .c .s {
|
||||
padding:0 5px 0 0 !important;
|
||||
vertical-align:bottom;
|
||||
}
|
||||
#wm-ipp #wm-nav-captures {
|
||||
white-space: nowrap;
|
||||
}
|
||||
#wm-ipp .c .s a.t {
|
||||
color:#33f;
|
||||
font-weight:bold;
|
||||
line-height: 1.8;
|
||||
}
|
||||
#wm-ipp .c .s div.r {
|
||||
color: #666;
|
||||
font-size:9px;
|
||||
white-space:nowrap;
|
||||
}
|
||||
#wm-ipp .c .k {
|
||||
padding-bottom:1px;
|
||||
}
|
||||
#wm-ipp .c .s {
|
||||
padding:0 5px 2px 0 !important;
|
||||
}
|
||||
#wm-ipp td#displayMonthEl {
|
||||
padding: 2px 0 !important;
|
||||
}
|
||||
#wm-ipp td#displayYearEl {
|
||||
padding: 0 0 2px 0 !important;
|
||||
}
|
||||
|
||||
div#wm-ipp-sparkline {
|
||||
position:relative;/* for positioning markers */
|
||||
white-space:nowrap;
|
||||
background-color:#fff;
|
||||
cursor:pointer;
|
||||
line-height:0.9;
|
||||
}
|
||||
#sparklineImgId, #wm-sparkline-canvas {
|
||||
position:relative;
|
||||
z-index:9012;
|
||||
max-width:none;
|
||||
}
|
||||
#wm-ipp-sparkline div.yt {
|
||||
position:absolute;
|
||||
z-index:9010 !important;
|
||||
background-color:#ff0 !important;
|
||||
top: 0;
|
||||
}
|
||||
#wm-ipp-sparkline div.mt {
|
||||
position:absolute;
|
||||
z-index:9013 !important;
|
||||
background-color:#ec008c !important;
|
||||
top: 0;
|
||||
}
|
||||
#wm-ipp .r {
|
||||
margin-left: 4px;
|
||||
}
|
||||
#wm-ipp .r a {
|
||||
color:#33f;
|
||||
border:none;
|
||||
position:relative;
|
||||
background-color:transparent;
|
||||
background-repeat:no-repeat !important;
|
||||
background-position:100% 100% !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
#wm-ipp #wm-capinfo {
|
||||
/* prevents notice div background from sticking into round corners of
|
||||
#wm-ipp-inside */
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
#wm-ipp #wm-capinfo .c-logo {
|
||||
display:block;
|
||||
float:left;
|
||||
margin-right:3px;
|
||||
width:90px;
|
||||
min-height:90px;
|
||||
max-height: 290px;
|
||||
border-radius:45px;
|
||||
overflow:hidden;
|
||||
background-position:50%;
|
||||
background-size:auto 90px;
|
||||
box-shadow: 0 0 2px 2px rgba(208,208,208,128) inset;
|
||||
}
|
||||
#wm-ipp #wm-capinfo .c-logo span {
|
||||
display:inline-block;
|
||||
}
|
||||
#wm-ipp #wm-capinfo .c-logo img {
|
||||
height:90px;
|
||||
position:relative;
|
||||
left:-50%;
|
||||
}
|
||||
#wm-ipp #wm-capinfo .wm-title {
|
||||
font-size:130%;
|
||||
}
|
||||
#wm-ipp #wm-capinfo a.wm-selector {
|
||||
display:inline-block;
|
||||
color: #aaa;
|
||||
text-decoration:none !important;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
#wm-ipp #wm-capinfo a.wm-selector.selected {
|
||||
background-color:#666;
|
||||
}
|
||||
#wm-ipp #wm-capinfo a.wm-selector:hover {
|
||||
color: #fff;
|
||||
}
|
||||
#wm-ipp #wm-capinfo.notice-only #wm-capinfo-collected-by,
|
||||
#wm-ipp #wm-capinfo.notice-only #wm-capinfo-timestamps {
|
||||
display: none;
|
||||
}
|
||||
#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content {
|
||||
background-color:#ff0;
|
||||
padding:5px;
|
||||
font-size:14px;
|
||||
text-align:center;
|
||||
}
|
||||
#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content * {
|
||||
font-size:14px;
|
||||
text-align:center;
|
||||
}
|
||||
#wm-ipp #wm-expand {
|
||||
right: 1px;
|
||||
bottom: -1px;
|
||||
color: #ffffff;
|
||||
background-color: #666 !important;
|
||||
padding:0 5px 0 3px !important;
|
||||
border-radius: 3px 3px 0 0 !important;
|
||||
}
|
||||
#wm-ipp #wm-expand span {
|
||||
color: #ffffff;
|
||||
}
|
||||
#wm-ipp #wm-expand #wm-expand-icon {
|
||||
display: inline-block;
|
||||
transition: transform 0.5s;
|
||||
transform-origin: 50% 45%;
|
||||
}
|
||||
#wm-ipp #wm-expand.wm-open #wm-expand-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
#wm-ipp #wmtb {
|
||||
text-align:right;
|
||||
}
|
||||
#wm-ipp #wmtb #wmtbURL {
|
||||
width: calc(100% - 45px);
|
||||
}
|
||||
#wm-ipp #wm-graph-anchor {
|
||||
border-right:1px solid #ccc;
|
||||
}
|
||||
/* time coherence */
|
||||
html.wb-highlight {
|
||||
box-shadow: inset 0 0 0 3px #a50e3a !important;
|
||||
}
|
||||
.wb-highlight {
|
||||
outline: 3px solid #a50e3a !important;
|
||||
}
|
||||
#wm-ipp-print {
|
||||
display:none !important;
|
||||
}
|
||||
@media print {
|
||||
#wm-ipp-base {
|
||||
display:none !important;
|
||||
}
|
||||
#wm-ipp-print {
|
||||
display:block !important;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
@media (max-width:414px) {
|
||||
#wm-ipp .xxs {
|
||||
display:none !important;
|
||||
}
|
||||
}
|
||||
@media (min-width:1055px) {
|
||||
#wm-ipp #wm-graph-anchor {
|
||||
display:block !important;
|
||||
}
|
||||
}
|
||||
@media (max-width:1054px) {
|
||||
#wm-ipp #wm-graph-anchor {
|
||||
display:none !important;
|
||||
}
|
||||
}
|
||||
@media (max-width:1163px) {
|
||||
#wm-logo {
|
||||
display:none !important;
|
||||
}
|
||||
}
|
||||
|
||||
#wm-btns {
|
||||
white-space: nowrap;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
#wm-btns #wm-save-snapshot-open {
|
||||
margin-right: 7px;
|
||||
top: -6px;
|
||||
}
|
||||
|
||||
#wm-btns #wm-sign-in {
|
||||
box-sizing: content-box;
|
||||
display: none;
|
||||
margin-right: 7px;
|
||||
top: -8px;
|
||||
|
||||
/*
|
||||
round border around sign in button
|
||||
*/
|
||||
border: 2px #000 solid;
|
||||
border-radius: 14px;
|
||||
padding-right: 2px;
|
||||
padding-bottom: 2px;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
}
|
||||
|
||||
#wm-btns #wm-sign-in>.iconochive-person {
|
||||
font-size: 12.5px;
|
||||
}
|
||||
|
||||
#wm-save-snapshot-open > .iconochive-web {
|
||||
color:#000;
|
||||
font-size:160%;
|
||||
}
|
||||
|
||||
#wm-ipp #wm-share {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#wm-share > #wm-screenshot {
|
||||
display: inline-block;
|
||||
margin-right: 3px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#wm-screenshot > .iconochive-image {
|
||||
color:#000;
|
||||
font-size:160%;
|
||||
}
|
||||
|
||||
#wm-share > #wm-video {
|
||||
display: inline-block;
|
||||
margin-right: 3px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#wm-video > .iconochive-movies {
|
||||
color: #000;
|
||||
display: inline-block;
|
||||
font-size: 150%;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
#wm-btns #wm-save-snapshot-in-progress {
|
||||
display: none;
|
||||
font-size:160%;
|
||||
opacity: 0.5;
|
||||
position: relative;
|
||||
margin-right: 7px;
|
||||
top: -5px;
|
||||
}
|
||||
|
||||
#wm-btns #wm-save-snapshot-success {
|
||||
display: none;
|
||||
color: green;
|
||||
position: relative;
|
||||
top: -7px;
|
||||
}
|
||||
|
||||
#wm-btns #wm-save-snapshot-fail {
|
||||
display: none;
|
||||
color: red;
|
||||
position: relative;
|
||||
top: -7px;
|
||||
}
|
||||
|
||||
.wm-icon-screen-shot {
|
||||
background: url("../images/web-screenshot.svg") no-repeat !important;
|
||||
background-size: contain !important;
|
||||
width: 22px !important;
|
||||
height: 19px !important;
|
||||
|
||||
display: inline-block;
|
||||
}
|
||||
#donato {
|
||||
/* transition effect is disable so as to simplify height adjustment */
|
||||
/*transition: height 0.5s;*/
|
||||
height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid #999 !important;
|
||||
}
|
||||
body.wm-modal {
|
||||
height: auto !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
#donato #donato-base {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/*bottom: 0;*/
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 2147483639;
|
||||
}
|
||||
body.wm-modal #donato #donato-base {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 2147483640;
|
||||
}
|
||||
|
||||
.wb-autocomplete-suggestions {
|
||||
font-family: Lucida Grande, Helvetica, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
cursor: default;
|
||||
border: 1px solid #ccc;
|
||||
border-top: 0;
|
||||
background: #fff;
|
||||
box-shadow: -1px 1px 3px rgba(0,0,0,.1);
|
||||
position: absolute;
|
||||
display: none;
|
||||
z-index: 2147483647;
|
||||
max-height: 254px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.wb-autocomplete-suggestion {
|
||||
position: relative;
|
||||
padding: 0 .6em;
|
||||
line-height: 23px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.02em;
|
||||
color: #333;
|
||||
}
|
||||
.wb-autocomplete-suggestion b {
|
||||
font-weight: bold;
|
||||
}
|
||||
.wb-autocomplete-suggestion.selected {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
3
resources/Wayback Machine_files/bundle-playback.js
Normal file
116
resources/Wayback Machine_files/iconochive.css
Normal file
@@ -0,0 +1,116 @@
|
||||
@font-face{font-family:'Iconochive-Regular';src:url('https://archive.org/includes/fonts/Iconochive-Regular.eot?-ccsheb');src:url('https://archive.org/includes/fonts/Iconochive-Regular.eot?#iefix-ccsheb') format('embedded-opentype'),url('https://archive.org/includes/fonts/Iconochive-Regular.woff?-ccsheb') format('woff'),url('https://archive.org/includes/fonts/Iconochive-Regular.ttf?-ccsheb') format('truetype'),url('https://archive.org/includes/fonts/Iconochive-Regular.svg?-ccsheb#Iconochive-Regular') format('svg');font-weight:normal;font-style:normal}
|
||||
[class^="iconochive-"],[class*=" iconochive-"]{font-family:'Iconochive-Regular'!important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
|
||||
.iconochive-Uplevel:before{content:"\21b5"}
|
||||
.iconochive-exit:before{content:"\1f6a3"}
|
||||
.iconochive-beta:before{content:"\3b2"}
|
||||
.iconochive-logo:before{content:"\1f3db"}
|
||||
.iconochive-audio:before{content:"\1f568"}
|
||||
.iconochive-movies:before{content:"\1f39e"}
|
||||
.iconochive-software:before{content:"\1f4be"}
|
||||
.iconochive-texts:before{content:"\1f56e"}
|
||||
.iconochive-etree:before{content:"\1f3a4"}
|
||||
.iconochive-image:before{content:"\1f5bc"}
|
||||
.iconochive-web:before{content:"\1f5d4"}
|
||||
.iconochive-collection:before{content:"\2211"}
|
||||
.iconochive-folder:before{content:"\1f4c2"}
|
||||
.iconochive-data:before{content:"\1f5c3"}
|
||||
.iconochive-tv:before{content:"\1f4fa"}
|
||||
.iconochive-article:before{content:"\1f5cf"}
|
||||
.iconochive-question:before{content:"\2370"}
|
||||
.iconochive-question-dark:before{content:"\3f"}
|
||||
.iconochive-info:before{content:"\69"}
|
||||
.iconochive-info-small:before{content:"\24d8"}
|
||||
.iconochive-comment:before{content:"\1f5e9"}
|
||||
.iconochive-comments:before{content:"\1f5ea"}
|
||||
.iconochive-person:before{content:"\1f464"}
|
||||
.iconochive-people:before{content:"\1f465"}
|
||||
.iconochive-eye:before{content:"\1f441"}
|
||||
.iconochive-rss:before{content:"\221e"}
|
||||
.iconochive-time:before{content:"\1f551"}
|
||||
.iconochive-quote:before{content:"\275d"}
|
||||
.iconochive-disc:before{content:"\1f4bf"}
|
||||
.iconochive-tv-commercial:before{content:"\1f4b0"}
|
||||
.iconochive-search:before{content:"\1f50d"}
|
||||
.iconochive-search-star:before{content:"\273d"}
|
||||
.iconochive-tiles:before{content:"\229e"}
|
||||
.iconochive-list:before{content:"\21f6"}
|
||||
.iconochive-list-bulleted:before{content:"\2317"}
|
||||
.iconochive-latest:before{content:"\2208"}
|
||||
.iconochive-left:before{content:"\2c2"}
|
||||
.iconochive-right:before{content:"\2c3"}
|
||||
.iconochive-left-solid:before{content:"\25c2"}
|
||||
.iconochive-right-solid:before{content:"\25b8"}
|
||||
.iconochive-up-solid:before{content:"\25b4"}
|
||||
.iconochive-down-solid:before{content:"\25be"}
|
||||
.iconochive-dot:before{content:"\23e4"}
|
||||
.iconochive-dots:before{content:"\25a6"}
|
||||
.iconochive-columns:before{content:"\25af"}
|
||||
.iconochive-sort:before{content:"\21d5"}
|
||||
.iconochive-atoz:before{content:"\1f524"}
|
||||
.iconochive-ztoa:before{content:"\1f525"}
|
||||
.iconochive-upload:before{content:"\1f4e4"}
|
||||
.iconochive-download:before{content:"\1f4e5"}
|
||||
.iconochive-favorite:before{content:"\2605"}
|
||||
.iconochive-heart:before{content:"\2665"}
|
||||
.iconochive-play:before{content:"\25b6"}
|
||||
.iconochive-play-framed:before{content:"\1f3ac"}
|
||||
.iconochive-fullscreen:before{content:"\26f6"}
|
||||
.iconochive-mute:before{content:"\1f507"}
|
||||
.iconochive-unmute:before{content:"\1f50a"}
|
||||
.iconochive-share:before{content:"\1f381"}
|
||||
.iconochive-edit:before{content:"\270e"}
|
||||
.iconochive-reedit:before{content:"\2710"}
|
||||
.iconochive-gear:before{content:"\2699"}
|
||||
.iconochive-remove-circle:before{content:"\274e"}
|
||||
.iconochive-plus-circle:before{content:"\1f5d6"}
|
||||
.iconochive-minus-circle:before{content:"\1f5d5"}
|
||||
.iconochive-x:before{content:"\1f5d9"}
|
||||
.iconochive-fork:before{content:"\22d4"}
|
||||
.iconochive-trash:before{content:"\1f5d1"}
|
||||
.iconochive-warning:before{content:"\26a0"}
|
||||
.iconochive-flash:before{content:"\1f5f2"}
|
||||
.iconochive-world:before{content:"\1f5fa"}
|
||||
.iconochive-lock:before{content:"\1f512"}
|
||||
.iconochive-unlock:before{content:"\1f513"}
|
||||
.iconochive-twitter:before{content:"\1f426"}
|
||||
.iconochive-facebook:before{content:"\66"}
|
||||
.iconochive-googleplus:before{content:"\67"}
|
||||
.iconochive-reddit:before{content:"\1f47d"}
|
||||
.iconochive-tumblr:before{content:"\54"}
|
||||
.iconochive-pinterest:before{content:"\1d4df"}
|
||||
.iconochive-popcorn:before{content:"\1f4a5"}
|
||||
.iconochive-email:before{content:"\1f4e7"}
|
||||
.iconochive-embed:before{content:"\1f517"}
|
||||
.iconochive-gamepad:before{content:"\1f579"}
|
||||
.iconochive-Zoom_In:before{content:"\2b"}
|
||||
.iconochive-Zoom_Out:before{content:"\2d"}
|
||||
.iconochive-RSS:before{content:"\1f4e8"}
|
||||
.iconochive-Light_Bulb:before{content:"\1f4a1"}
|
||||
.iconochive-Add:before{content:"\2295"}
|
||||
.iconochive-Tab_Activity:before{content:"\2318"}
|
||||
.iconochive-Forward:before{content:"\23e9"}
|
||||
.iconochive-Backward:before{content:"\23ea"}
|
||||
.iconochive-No_Audio:before{content:"\1f508"}
|
||||
.iconochive-Pause:before{content:"\23f8"}
|
||||
.iconochive-No_Favorite:before{content:"\2606"}
|
||||
.iconochive-Unike:before{content:"\2661"}
|
||||
.iconochive-Song:before{content:"\266b"}
|
||||
.iconochive-No_Flag:before{content:"\2690"}
|
||||
.iconochive-Flag:before{content:"\2691"}
|
||||
.iconochive-Done:before{content:"\2713"}
|
||||
.iconochive-Check:before{content:"\2714"}
|
||||
.iconochive-Refresh:before{content:"\27f3"}
|
||||
.iconochive-Headphones:before{content:"\1f3a7"}
|
||||
.iconochive-Chart:before{content:"\1f4c8"}
|
||||
.iconochive-Bookmark:before{content:"\1f4d1"}
|
||||
.iconochive-Documents:before{content:"\1f4da"}
|
||||
.iconochive-Newspaper:before{content:"\1f4f0"}
|
||||
.iconochive-Podcast:before{content:"\1f4f6"}
|
||||
.iconochive-Radio:before{content:"\1f4fb"}
|
||||
.iconochive-Cassette:before{content:"\1f4fc"}
|
||||
.iconochive-Shuffle:before{content:"\1f500"}
|
||||
.iconochive-Loop:before{content:"\1f501"}
|
||||
.iconochive-Low_Audio:before{content:"\1f509"}
|
||||
.iconochive-First:before{content:"\1f396"}
|
||||
.iconochive-Invisible:before{content:"\1f576"}
|
||||
.iconochive-Computer:before{content:"\1f5b3"}
|
||||