; ; FLASH.A86 - Version 0.0 ; Flashes The LEDs On An AT Keyboard Until A Key Is Pressed ; Freeware from Kirk Lawrence ; (Disassembled from the DOS program LEDS.COM; author unknown) ; ; Improvements over original DOS version: ; Routine added to check for AT-class machine. ; Timing routine changed to make the flash rate independent of CPU speed. ; cseg org 100h jmp okay ; num dw 0 error db 13,10,' This program requires an AT-class computer.' db 13,10,07,'$' ; start: ;------------------------------------------------------------------- ; This routine checks the processor type to insure that we've got an ; AT-class machine. ; pushf ;push flags pop ax ;get flags mov cx,ax ;save flags and ax,0FFFh ;clear flag bits 12-15 push ax ;save flag value on stack popf ;replace current flags value pushf ;get new flags pop ax ;store new flags in AX and ax,0F000h ;if bits 12-15 are set, then CPU cmp ax,0F000h ; is an 8086/8088 jne okay ;we've got an AT, so go do the deed mov cl,9 ;function 9 - print string mov dx,offset error ;point to error message int 224 ;call BDOS xor cx,cx ;function 0 - reset system int 224 ;exit to CP/M-86 ;--------------------------------- ; This is the start of the program. ; okay: mov ax,0040h mov es,ax mov bx,0017h mov es: al,[bx] and al,70h mov bx,01A4h mov [bx],al sub3: mov al,01 call sub1 call sub2 mov al,02 call sub1 call sub2 mov al,04 call sub1 call sub2 mov ah,01 int 16h jz sub3 mov ah,00 int 16h mov bx,0017h and es: byte ptr [bx],08Fh mov bx,01A4h mov al,[bx] mov bx,0017h or es: [bx],al mov cl,04 shr al,cl call sub1 xor cx,cx xor ax,ax xor dx,dx int 224 sub1: mov ah,al sub4: in al,064h test al,02 jnz sub4 mov bx,0097h and es: byte ptr [bx],0EFh mov al,0EDh out 60h,al sub5: mov bx,0097h test es: byte ptr [bx],010h jz sub5 mov al,ah out 60h,al ret ;------------------------------------------------------------------------- ; Here's the improved timing routine. It uses the BIOS timer interrupt, ; thereby making the LED flash rate independent of the processor's speed, ; and allowing the program to perform consistently on all computers. ; Originally, a LOOP was used -- with the number of loops set to an ; arbitrary value. ; sub2: push ax ;preserve register AX mov ah,00 ;function 0 - read system timer int 1Ah ;call BIOS timer services add dx,1 ;add our delay factor mov num,dx ;move total into variable count: mov ah,00h ;function 0 - read system timer int 1Ah ;call BIOS timer services cmp dx,num ;has time period elapsed? je thatsall ;yes, go return jmp count ;no, go count some more thatsall: pop ax ;restore register AX ret ;return end