//----------------------------------------------------------------- // wait10ms.s // // This program shows how to program a ten-millisecond delay // using Channel #2 of our PC's Programmable Interval Timer. // // 10 milliseconds = 1/100 seconds // // To test we execute this delay a thousand times (10 secs). // // to assemble: $ as wait10ms.s -o wait10ms.o // and to link: $ ld wait10ms.o -T ldscript -o wait10ms.b // and install: $ dd if=wait10ms.b of=/dev/sda4 seek=1 // // NOTE: This code begins executing with CS:IP = 1000:0002. // // programmer: ALLAN CRUSE // written on: 20 OCT 2008 //----------------------------------------------------------------- # manifest constants .equ CLOCK_PULSES_PER_SECOND, 1193182 .equ MILLISECONDS_PER_SECOND, 1000 .equ DELAY_IN_MILLISECONDS, 10 .section .text #------------------------------------------------------------------ .word 0xABCD # loader expects signature #------------------------------------------------------------------ main: .code16 mov %sp, %cs:ipltos+0 mov %ss, %cs:ipltos+2 mov %cs, %ax mov %ax, %ss lea tos, %sp call compute_channel2_latch call turn_on_channel2_input mov $1000, %cx tenms: call program_channel2_latch call await_count_completion loop tenms call disable_channel2_input lss %cs:ipltos, %sp lret #------------------------------------------------------------------ ipltos: .word 0, 0 # holds loader's SS and SP #------------------------------------------------------------------ #------------------------------------------------------------------ latch: .word 0 # latch for a ten ms delay #------------------------------------------------------------------ compute_channel2_latch: mov $CLOCK_PULSES_PER_SECOND, %eax mov $DELAY_IN_MILLISECONDS, %ecx mul %ecx mov $MILLISECONDS_PER_SECOND, %ecx div %ecx mov %ax, %ss:latch ret #------------------------------------------------------------------ turn_on_channel2_input: in $0x61, %al and $0x0C, %al or $0x01, %al out %al, $0x61 ret #------------------------------------------------------------------ program_channel2_latch: mov $0xB0, %al out %al, $0x43 mov %ss:latch+0, %al out %al, $0x42 mov %ss:latch+1, %al out %al, $0x42 ret #------------------------------------------------------------------ await_count_completion: delay: in $0x61, %al test $0x20, %al jz delay ret #------------------------------------------------------------------ disable_channel2_input: in $0x61, %al and $0x0C, %al out %al, $0x61 ret #------------------------------------------------------------------ .align 16 .space 256 tos: #------------------------------------------------------------------ .end