; pit.asm: A simple bootable PIT tester. ; Copyright (c) 2006 Stanislav Maslovski ; ; Compile with nasm, and then put the binary into the boot sector of a diskette: ; # nasm pit.asm ; # cat pit >/dev/fd0 ; # reboot ; When booted use PF keys F1-F3 for tests. ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; cpu 8086 %define delay jmp short $+2 ; ***************************** section .text org 7C00h v_off equ 4*08h v_seg equ v_off+2 TRIES equ 16 LATCH equ 1000h tbl equ 8000h ; here CS:IP = 0000:7C00; 64K of low memory is more than enough for us start: ; set segregs and stack mov ax, cs mov ds, ax mov es, ax cli mov ss, ax mov sp, 7C00h; expands below the code sti ; print init message call dnl mov si, init_msg call puts ; reprogram irq 0 vector cli mov ax, [v_off] mov [old_vec+0], ax mov ax, [v_seg] mov [old_vec+2], ax mov word [v_off], irq_h mov [v_seg], cs ; set channel 0 mode 2 r/w 2 bytes, LATCH mov al, 34h mov dx, LATCH call pit_reset sti ; catch several interrupts mov cx, 5 mov [cnt1], cx .l1: cmp [cnt1], cx jae .l1 loop .l1 jmp short main ; main loop main_dnl: call dnl main: ; print banner mov si, banner_msg call puts ; wait for a function key pressed .l2: xor ah, ah int 16h or al, al jnz .l2 mov cx, TRIES mov di, tbl ; select the test sub ah, 3Bh jz range dec ah jz latency dec ah jz sequence jmp short .l2 dump: ; dumps the table of values mov cx, TRIES mov si, tbl .l3: lodsw mov dx, ax call printw loop .l3 %if (TRIES % 16) jmp short main_dnl %else jmp short main %endif ; ***************************** ; latency test ; ***************************** latency: mov [cnt1], cx .l1: cmp [cnt1], cx jae .l1 mov ax, [ch0] stosw loop .l1 jmp short dump ; ***************************** ; sequence test ; ***************************** sequence: cli ; catch this value or less mov dx, [seq_st] .l2 call pit_latch cmp ax, dx ja .l2 ; read sequence into the table .l4: stosw .l3: call pit_latch cmp ax, dx je .l3 mov dx, ax loop .l4 ; correct the start value (useful at the next test) mov ax, [tbl] sub ax, dx add ax, LATCH shr ax, 1 mov [seq_st], ax sti jmp short dump ; ***************************** ; range test ; ***************************** range: cli xor cx, cx mov bx, cx mov dx, cx dec dx .l3: call pit_latch cmp ax, dx jae .l1 mov dx, ax .l1: cmp ax, bx jbe .l2 mov bx, ax .l2: loop .l3 sti call printw mov dx, bx call printw jmp main_dnl ; ***************************** irq_h: push ax ; read the PIT count call pit_latch mov [cs:ch0], ax ; update counters dec word [cs:cnt1] dec word [cs:cnt2] jnz .l1 mov word [cs:cnt2], 10000h/LATCH ; jump to bios isr pop ax jmp far [cs:old_vec] .l1: ; ack the interrupt and leave mov al, 20h out 20h, al pop ax iret ; ***************************** putch: push cx mov cx, 1 mov ah, 0Eh int 10h pop cx ret ; ***************************** dnl: mov al, 0Dh call putch mov al, 0Ah call putch ret ; ***************************** puts: lodsb or al, al jz .l1 call putch jmp short puts .l1: call dnl ret ; ***************************** printw: push cx mov cx, 4 call print_hex mov al, ' ' call putch pop cx ret ; ***************************** print_hex: .l1: rol dx, 1 rol dx, 1 rol dx, 1 rol dx, 1 mov al, dl and al, 0Fh add al, '0' cmp al, '9' jbe .l2 add al, 'A'-'9'-1 .l2: call putch loop .l1 ret ; ***************************** pit_latch: xor al, al out 43h, al delay pit_inw: in al, 40h delay xchg al, ah in al, 40h delay xchg al, ah ret ; ***************************** pit_reset: out 43h, al delay pit_outw: mov al, dl out 40h, al delay mov al, dh out 40h, al delay ret ; ***************************** cnt1: dw 0 cnt2: dw 10000h/LATCH ch0: dw 0 ; ***************************** init_msg: db 'PIT init: Ch 0 Mod 2 rw 2b LATCH=1000h', 0 banner_msg: db 'Test: F1=Range F2=Latency F3=Sequence', 0 old_vec: dw 0, 0 seq_st: dw TRIES ; ***************************** ; signature times 510-($-$$) db 0FFh db 55h, 0AAh ; *****************************