Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 13:44 24 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMB for DOS pause problem

Author Message
DaveJacko
Regular Member

Joined: 25/07/2019
Location: United Kingdom
Posts: 76
Posted: 09:09pm 22 Sep 2024
Copy link to clipboard 
Print this post

If anyone has nothing important to do,
can they confirm that.. in MMBasic for DOS

pauseplus 1000
end

sub pauseplus(ptim)
for i=1 to ptim
pause 1
'do some code
next i
end sub

seems to delay for > 10 seconds. Pause 1000 is 1 second
I hope It's me doing something stupid, workarounds welcome!
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1240
Posted: 09:27pm 22 Sep 2024
Copy link to clipboard 
Print this post

  DaveJacko said  If anyone has nothing important to do,
can they confirm that.. in MMBasic for DOS

pauseplus 1000
end

sub pauseplus(ptim)
for i=1 to ptim
pause 1
'do some code
next i
end sub

seems to delay for > 10 seconds. Pause 1000 is 1 second
I hope It's me doing something stupid, workarounds welcome!


AFAIK your observation is correct. I got 15600ms!
This is really unexpected and weird.

Regards
Michael
causality ≠ correlation ≠ coincidence
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6097
Posted: 09:29pm 22 Sep 2024
Copy link to clipboard 
Print this post

MMBasic for DOS uses the DOS timer which goes in ~16mS steps so pause delays will be 16,32 etc mS

Try this with different PAUSE times

'
startedx = TIMER
pauseplus 100
PRINT TIMER - startedx
END

SUB pauseplus(ptim)
FOR i=1 TO ptim
started = TIMER
PAUSE 20
PRINT TIMER - started
'do some code
NEXT i
END SUB



MMB4W uses a high definition timer so doesn't have the same problem.

The strange 16mS came about because the default screen refresh in Microsoft land is 60Hz

Jim
Edited 2024-09-23 07:32 by TassyJim
VK7JH
MMedit   MMBasic Help
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1240
Posted: 09:51pm 22 Sep 2024
Copy link to clipboard 
Print this post

  DaveJacko said  ... workarounds welcome!

Instead of "PAUSE", use an empty loop with a duration of 1 ms.

sub pauseplus(ptim)
for i=1 to ptim
 for j=1 to 3050
 next j
 'do some code
next
end sub


Works for me.
Edited 2024-09-23 08:17 by twofingers
causality ≠ correlation ≠ coincidence
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2135
Posted: 10:07pm 22 Sep 2024
Copy link to clipboard 
Print this post

Perhaps:-
Pause 1000 / 16
'or
T = Timer + 1000 : Do While Timer < T : Loop

Not tested but I expect the resolution will still only be 16mS.
Edited 2024-09-23 08:09 by phil99
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1240
Posted: 10:05am 23 Sep 2024
Copy link to clipboard 
Print this post

How about this:
timer=0
pauseplus 1000
? timer
end

sub pauseplus(ptim)
for i=1 to ptim
do while timer<ptim:loop
'do some code
next
end sub

Michael
causality ≠ correlation ≠ coincidence
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2350
Posted: 12:31pm 23 Sep 2024
Copy link to clipboard 
Print this post

you may get better mileage out of this:
n=timer+1000
do while timer<n
  print "doing stuff... ";
loop


the above will fall through after spinning in a loop for 1000mS 'doing stuff'. place the loop inside another loop, and then you can also do the things you only want done once a second:
n=timer+1000
do
  print "doing things at the start of the interval"

  do while timer<n
    print "doing stuff... ";
  loop

  print timer
  n=n+1000
loop


depending upon how timer is implemented on the win32 console port of mmbasic, it may only be incremented (approximately) 18.2 times per second. this was (way back when) derived from a crystal oscillator running at 4x the NTSC colorburst frequency of 3.579545MHz:

3.579545MHz * 4 = 14.31818MHz
14.31818MHz / 3 / (2^18) = 18.2065074Hz (tick rate)

with the processor clock for the original 8088 based IBM PC and IBM XT being:

14.31818MHz / 3 = 4.772727MHz

since then various other periodic counters have been added to the PC's hardware, and to varying degrees used by windows, but as to which one is actually used in a specific case is not always certain!


cheers,
rob   :-)
Edited 2024-09-23 23:15 by robert.rozee
 
DaveJacko
Regular Member

Joined: 25/07/2019
Location: United Kingdom
Posts: 76
Posted: 08:27pm 24 Sep 2024
Copy link to clipboard 
Print this post

Thanks all !

especially Rob for the background info and work-around.

This will help me develop my RS232 graphics terminal for the LCD Backpack,
featuring swipe left, right and tap.

Dave  
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 857
Posted: 05:55am 25 Sep 2024
Copy link to clipboard 
Print this post

Bit of a long-shot but who knows.

My DOS programs reprogram the clock interrupt (and compensate to preserve time-keeping).

This example is 8 X normal speed but I've had it interrupting @ (not sure) 5 or 8KHz.

This was created for QuickBasic/MS PDS 7.1


Title INT.ASM Interrupt Control Programs

;Revision History
;Rev 001
;Rev 002
; Call to PDPress added 1/11/94
;Rev 003
; Call to PumpTimer added 6/15/94
;Rev 004
; Call to DeadMan added 4/5/95
;Rev 005
; Call to IntTimer added 1/6/95



  option segment:use16

.386
.dosseg
.model medium,basic

public  flgoff  
public  flgseg  

public  inpoff  
public  inpseg        

public optoff
public optseg
public  outoff  
public  outseg  


.data

inpseg  dw      0       ;inputs array
inpoff  dw      0
outseg  dw      0       ;outputs array
outoff  dw      0
flgseg  dw      0       ;flags array
flgoff  dw      0
optoff dw 0 ;options array
optseg dw 0

.code  

extrn ButtonHandler:proc

extrn DMCInt:proc
extrn DeadMan:proc

extrn   inhand:proc
extrn IntTimer:proc

extrn MandStop:proc

extrn PDPress:proc

extrn   ophand:proc

extrn PumpTimer:proc

extrn ScreenTimer:proc


getw    MACRO   to,from ;get a parameter and save it
mov     bx,from
mov     ax,[bx]
mov     word ptr to,ax
ENDM


install proc    inps:ptr word, ino:ptr word, \
ops:ptr word, opo:ptr word, \
fls:ptr word, flo:ptr word, \
opts:ptr word, opto:ptr word


pusha                   ;save registers
push    ds
push    es
mov     ax,@data        ;set data seg
mov     ds,ax

;save passed parameters for interrupt handler use

getw    inpseg,inps     ;get inputs segment    
getw    inpoff,ino      ;get inputs offset
getw    outseg,ops      ;get outputs segment    
getw    outoff,opo      ;get outputs offset
getw    flgseg,fls      ;get flags segment    
getw    flgoff,flo      ;get flags offset
getw optseg,opts ;get options segment
getw optoff,opto ;get options segment

mov     ax,3508h        ;get current interrupt vector
int     21h
mov     word ptr cs:oldvec,bx   ;save segment
mov     word ptr cs:oldvec+2,es ;save segment

cli                     ;stop interrupt

mov     al,36h          ;reprogram timer to 8 times
out     43h,al          ;normal speed
mov     al,0
jmp @F
@@:
jmp @F
@@:
out     40h,al
; mov     al,20h
MOV al,4
jmp @F
@@:
jmp @F
@@:
out     40h,al

push    cs              ;change interrupt vector
pop     ds
lea     dx, newint
mov     ax,2508h
int     21h

sti                     ;restart interrupt


pop     es              ;restore
pop     ds
popa

ret
install endp


uninst  proc

pusha
push ds
push     es
push     si
push     di

cli                             ;stop interrupts

mov     al,36h                  ;timer back to normal
out     43h,al                  ;alert for coming values
jmp @F
@@:
jmp @F
@@:
mov     al,00h    
out     40h,al                  ;lsb
jmp @F
@@:
jmp @F
@@:
out     40h,al                  ;msb


lds     dx,cs:oldvec            ;restore old interrupt
mov     ax,2508h                
int     21h                    

sti                             ;enable interrupts

pop      di
pop      si
pop      es                      ;restore registers
pop      ds
popa

ret
uninst  endp

newint  proc    near
pusha                           ;save registers
push     ds
push     es
push     si
push     di

call IntTimer ;cpu independant interrupt timer
call DeadMan ;deadman relay driver
call    inhand          ;update inputs
call ButtonHandler ;Pb interlock handler
call MandStop ;stop mandrel on switch
call PDPress ;Pressure die pressure handler
call    DMCInt          ;DMC comms
call   ophand          ;update outputs

; allow for speeded up clock

dec     cs:counter              ;count down
jns     exit                    ;not time yet

; this section runs every eigth interrupt

mov     cs:counter,63            ;restart timer

dec cs:SecTimer ;update seconds counter
jns @F

mov cs:sectimer,18 ;restart seconds timer
call ScreenTimer ;do this once per second
call PumpTimer
@@:
pop      di
pop      si
pop      es                      ;restore registers
pop      ds
popa
jmp      cs:oldvec               ;to normal clock interrupt
 
exit:  
mov      al,20h                  ;issue an EOI
out      20h,al

pop      di
pop      si
pop      es                      ;restore registers
pop      ds
popa
iret                            ;return from interrupt

oldvec  dd      0
counter dw      0
SecTimer dw 18 ;one second(approx) timer

newint  endp
end



Lots of surplus stuff there, obviously.
Edited 2024-09-25 15:59 by PhenixRising
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024