Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

delay_15us implementation using PIT polling #51

Merged
merged 2 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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