x86 machine code for PC (e.g. MS-DOS COM file), 27 bytes
This machine code (displayed here with a Unicode rendering of the usual CP437 of PC BIOS) will blink the CAPS LOCK indicator forever on a PC:
The code has been made so it contains no NULL bytes, and can thus be typed with the keyboard (using the Alt+XXX trick for extended characters) to create a COM file (e.g., using the
COPY CON blink.com command under MS-DOS, in which case the output file will have to contain a spurious 28th byte, the
^Z (EOF) character required to stop the copy operation).
The effect is achieved by directly sending commands to the keyboard controller of the PC (port 60h) to set the LED state (as a side-effect, it might set Num Lock and Scroll Lock LEDs to a random non-blinking state). The timing, to minimize the number of instructions, is achieved by using the countdown timer maintained by the BIOS at address
0040:0040 (it decrements every 54.925 ms, with 9 cycles the blinking cycle is 494.3 ms, which is within the allowed margin) — this counter is normally used by the BIOS to stop the floppy disk motor; as the floppy drive is not used by the program and the code is assumed to run in a single-task environment (e.g. DOS), playing with the floppy motor timer is not an issue.
The code runs fine under MS-DOS (tried with VirtualBox, it should also run fine on real hardware, although I didn't have the time yet to make a bootable MS-DOS USB stick to test). As it doesn't rely on any OS functions, it can even run without the operating system (e.g., by placing it in the boot sector of a disk). It requires at least a 80186 processor to run, because of the "immediate push" instructions used to shorten the code of some bytes.
Assembly source code:
PUSH 0x40 ; pushes 0x0040 (BIOS data segment) on the stack POP DS ; pops it into DS segment selector MOV SI, DS ; copies DS to SI (timer counter is nicely placed at 40:40) PUSH 0x60 ; pushes 0x0060 (kbd controller port) on the stack POP DX ; pops it to DX loop: MOV AL, 0xED ; 8042 keyboard controller 'set mode indicators' command OUT DX, AL ; outputs the command to the keyboard contr oller MOV AL, BL ; copy BL register to AL OUT DX, AL ; outputs LED state to keyboard controller XOR BL, 4 ; toggles bit 2 (CAPS LOCK) for next iteration MOV BYTE PTR[SI], 0x0A ; sets floppy motor countdown timer to 10 wait: CMP BYTE PTR[SI], 0x01 ; checks if timer reached 1 JE loop ; if yes, time for next iteration JMP wait ; if not, checks again
Hexadecimal dump of the assembled code:
6A 40 1F 8C DE 6A 60 5A B0 ED EE 88 D8 EE 80 F3 04 C6 04 0A 80 3C 01 74 EF EB F9
Footage of blinking LED will be posted later.