Skip to content

Commit

Permalink
Merge pull request #51 from 640-KB/master
Browse files Browse the repository at this point in the history
delay_15us implementation using PIT polling
  • Loading branch information
skiselev committed Sep 28, 2023
2 parents 371e63c + 385881b commit b2a691d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/config.inc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
%define MIN_RAM_SIZE 32 ; At least 32 KiB to boot the system
%define MAX_RAM_SIZE 640 ; Scan this much memory during POST
%define RAM_TEST_BLOCK 16384 ; block size for RAM test
%define PIT_DELAY ; Use PIT polling for delays
%endif ; MACHINE_BOOK8088

; Settings for IBM PC/XT
Expand All @@ -80,6 +81,7 @@
%define MIN_RAM_SIZE 32 ; At least 32 KiB to boot the system
%define MAX_RAM_SIZE 640 ; Scan this much memory during POST
%define RAM_TEST_BLOCK 16384 ; block size for RAM test
%define PIT_DELAY ; Use PIT polling for delays
%endif ; MACHINE_XT

; Automatic settings based on the machine settings above
Expand Down
62 changes: 61 additions & 1 deletion src/delay.inc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,66 @@ delay_15us:
ret

%else ; AT_DELAY
%ifdef PIT_DELAY

;=========================================================================
; delay_15us - delay for multiplies of 15 microseconds using PIT
; Input:
; CX = time to delay (in 15 microsecond units)
;
; - Calculate the total number of PIT ticks necessary
; 1,193,182 / 1000 ms / 1000 us / * 15 us * 2 = ~ 36 ticks/us
; - Latch the PIT and draw down the countdown total on each read.
; - Exit when countdown underflows.
;
; Note: Mode 3 (Square Wave) decements the readable counter by 2, so the
; effective frequency of the counter is actually 2,386,360 Hz.
;
; Contributed by @640-KB (under GPL-3.0 license)
; Based on contribution by @Raffzahn (under CC BY-SA 4.0):
; https://retrocomputing.stackexchange.com/a/24874/21323
;-------------------------------------------------------------------------
delay_15us:
push ax
push bx
push cx
push dx
mov ax,2*15*pic_freq/1000/1000+1 ; ~ 36 ticks/us
mul cx ; dx:ax = countdown of pit ticks to wait
xchg ax,bx ; dx:bx = countdown ticks
call io_wait_latch ; ax = start read
mov cx,ax ; cx = last read
.tick_loop:
call io_wait_latch ; ax = current counter reading
sub cx,ax ; cx = # of ticks elapsed since last reading
sub bx,cx ; subtract change in ticks from countdown
mov cx,ax ; cx = save the last read
sbb dx,0 ; borrow out of high word (if necessary)
jae .tick_loop ; loop while countdown >= 0
pop dx
pop cx
pop bx
pop ax
ret

;=========================================================================
; Latch PIT 0 and read counter
; Output:
; AX = current counter
;-------------------------------------------------------------------------
io_wait_latch:
mov al,0 ; counter 0, latch (00b)
pushf ; save current IF
cli ; disable interrupts
out pit_ctl_reg,al ; write command to ctc
in al,pit_ch0_reg ; read low byte of counter 0 latch
mov ah,al ; save it
in al,pit_ch0_reg ; read high byte of counter 0 latch
popf ; restore IF state
xchg al,ah ; convert endian
ret

%else ; LOOP_DELAY

;=========================================================================
; delay_15us - delay for multiplies of approximately 15 microseconds
Expand All @@ -77,9 +137,9 @@ delay_15us:
pop ax
ret

%endif ; PIT_DELAY
%endif ; AT_DELAY


%if 0
;=========================================================================
; divide_32 - divide 64-bit argument by 32-bit, return 64-bit result
Expand Down

0 comments on commit b2a691d

Please sign in to comment.