flat assembler
Message board for the users of flat assembler.

Index > DOS > Multithreading in DOS : the truth is out :-(

Goto page 1, 2  Next

Is multithreading impossible in DOS ?
YES
13%
 13%  [ 2 ]
What is DOS ???
6%
 6%  [ 1 ]
No idea, do not care as long as __my__ 16 cores per 64-bit do work
13%
 13%  [ 2 ]
It is possible ... see your code, PTHREADS , HX , ... , ... , ...
66%
 66%  [ 10 ]
Total Votes : 15

Author
Thread Post new topic Reply to topic
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386
.
.
Download now : http://board.flatassembler.net/download.php?id=3666
.
.

Code:
;
; REAL MODE Multithreading (ISR) example, 8086-compatible
;
; Compile with FASM, but this should REALLY be no longer surprising Very Happy
;
; Will save file "GARBAGE" of only 40'000'000 bytes size
;
; http://board.flatassembler.net/topic.php?t=8468
;

; INT $1C - TIME - SYSTEM TIMER TICK
; Desc:   this interrupt is automatically called on each clock
;         tick by the INT 08 handler
; Notes:  this is the preferred interrupt to chain when a program needs to be
;         invoked regularly
;         not available on NEC 9800-series PCs
; SeeAlso: INT 08,INT $E2 "PC Cluster"

; --------V-M0040004A--------------------------
; MEM 0040:004A - VIDEO - COLUMNS ON SCREEN $044A
; Size:   WORD
; --------V-M00400050--------------------------
; MEM 0040:0050 - VIDEO - CURSOR POSITIONS  $0450
; Size:   8 WORDs | low XX high YY
; Desc:   contains row and column position for the cursors on each of 8 pages (?)
; --------V-M00400084--------------------------
; MEM 0040:0084 - ROWS ON SCREEN MINUS ONE  $0484
; Size:   BYTE

; --------V-P03C003C1--------------------------
; PORT $03C0,$03C1 - EGA/VGA - ATTRIBUTE CONTROLLER
; 03C0  rW  ATC index/data register
;           Every write access to this register will toggle an internal
;           index/data selection flipflop, so that consecutive writes to
;           index & data is possible through this port. To get a defined
;           start condition, each read access to the input status register
;           #1 ($03BA in mono / $03DA in color) resets to index.
;           index register (flipflop reset to 'index'): (default $20)
;                  bit5  : 0=CPU access (screen dark),
;                          1=video access to registers
;                  bit4-0: index in ATC (0..31)
; data: $11 (VGA) overscan color register (default: 0)
; 7      secondary intensity border color (SI)
; 6      secondary red (SR)
; 5      secondary green (SG)
; 4      secondary blue (SB)
; 3      intensity border color (PI)
; 2      primary red (PR)
; 1      primary green (PG)
; 0      primary blue (PB)

format binary as "COM"
use16
org $100

define pope pop

             jmp   aa0
             ;--------

tx0:         db 'GARBAGE',0    ; File to save
vvint1c:     dd 0              ; Here we store the old INT $1C target
vvscreenpos: dw 0              ; Position on screen in bytes (2 bytes/char)
vvflipper:   db 0              ; For pausing
vvcounter:   dw 0              ; For timer and fancy colouring Very Happy
vvvalue:     dw 0              ; Progess value


aa0:        cld
            call  sseol
            call  ssprint
            db "!! Hell-o world !!",$0D,$0A
            db "Greetz to multitaxing adorers among DOSsers Very Happy"
            db $0D,$0A,$0D,$0A
            db "INT $1C at $70 had: $",0
            xor   ax,ax
            mov   es,ax            ; "PUSHW 0" is not 8086 compatible
            mov   ax,[es:$72]      ; INT $1C "seg"
            mov   [vvint1c+2],ax
            mov   di,ax
            call  sshex16
            call  ssprint
            db ":$",0
            mov   ax,[es:$70]      ; INT $1C "of***"
            mov   [vvint1c],ax
            mov   si,ax
            call  sshex16
            call  sseol
            ; Now we have the old target in "vvint1c" and DI:SI , DI is "seg"

            call  ssprint
            db "And there we had: ",0
            push  di
            pope  es
            mov   cl,8
@@:         mov   al,[es:si]
            inc   si
            call  sshex8
            dec   cl
            jz    aa1
            mov   dl,44        ; ","
            call  ssonechar
            jmp   short @b
            ;-------------
aa1:        call  sseol
            call  sseol

            push  cs
            pope  di           ; "seg"
            mov   si,llisr     ; "of***"
            call  sset1c       ; !!! HOT !!!

            call  ssprint
            db "But now no longer ... Very Happy",$0D,$0A,$0D,$0A,0

            mov   cl,18        ; Unit is 55 ms Sad((
            call  sspause

            call  ssprint
            db "Saving garbage (!) now ... ??? ????? ",0

            xor   cx,cx
            mov   es,cx             ; "PUSHW 0" is not 8086 compatible

            xor   dx,dx             ; Our address | CX==0
            mov   bl,[es:$044A]     ; Width of screen
            mov   bh,0              ; We don't accept > 255
            mov   ax,[es:$0450]     ; "row and column" | al:XX | ah:YY
            cmp   ah,0
            je    @f                ; YY=0, top line
            mov   cl,ah             ; CH==0 | dealing with YY
aa3:        add   dx,bx
            loop  aa3               ; MUL'ling Very Happy
@@:         mov   cl,al             ; CH==0 | dealing with XX now
            add   dx,cx
            sub   dx,10             ; XX must be >=10 !!!
            shl   dx,1              ; 2 bytes per char !!!
            mov   [vvscreenpos],dx  ; Enable PI

            xor   cx,cx
            mov   dx,tx0
            mov   ah,$3C
            int   $21              ; Create / open for write
            mov   bx,ax            ; Handle
            mov   cx,800
aa2:        mov   [vvvalue],cx
            mov   ah,$40
            mov   cx,50000         ; Size
            xor   dx,dx            ; Addr
            int   $21              ; Save
            mov   cx,[vvvalue]
            loop  aa2              ; 800 x 50'000 bytes
            mov   ah,$3E
            int   $21              ; Close

            mov   bx,[vvscreenpos]
            mov   word [vvscreenpos],0 ; Disable PI "??? ?????" "99% 99.9s"
            mov   ax,$B800
            mov   es,ax
            mov   cx,9
@@:         mov   byte [es:bx],45  ; "-"
            inc   bx
            inc   bx
            loop  @b
            call  ssprint
            db "... Done !!!",$0D,$0A,$0D,$0A,0

            mov   cl,18            ; Unit is 55 ms Sad((
            call  sspause

            mov   di,[vvint1c+2]   ; "seg"
            mov   si,[vvint1c]     ; "of***"
            call  sset1c

            call  ssprint
            db "Removed ISR again.",$0D,$0A,$0D,$0A,0
            xor   ax,ax
            call  ssover

            jmp   lleof
            ;----------

; SUB pause

sspause:    mov   ch,0
ss3:        mov   al,[vvflipper]
@@:         cmp   al,[vvflipper]
            je    @b
            loop  ss3
            ret
            ;----

; ***************************
; *  SUB , setting INT $1C  *
; ***************************
;
; IN: (DI:SI) new target | DI is "seg" | SI is "of***"
; TR: nothing !!!

sset1c:     cli
            push  es
            push  ax

            xor   ax,ax
            mov   es,ax             ; "PUSHW 0" is not 8086 compatible
            mov   word [es:$72],di  ; "seg"
            mov   word [es:$70],si  ; "of***"

            pope  ax
            pope  es
            sti
            ret
            ;----

; *******************************
; *  Here our great ISR begins  *
; *******************************
;
; BEWARE: On entry DS = ??? !!!

llisr:      push  ds
            push  es
            push  ax
            push  bx
            push  dx
            push  di           ; We MAY NOT USE CX !!!

            push  cs
            pope  ds           ; Legal in RM

            mov   bl,[vvflipper]
            xor   bl,1
            mov   [vvflipper],bl

            mov   ax,[vvcounter]
            inc   ax
            mov   [vvcounter],ax
            and   al,3
            jnz   qq5          ; Update every 220 ms

            mov   di,[vvscreenpos]
            test  di,di
            jz    qq4          ; 0 is not valid

            mov   dx,$B800     ; Text
            mov   es,dx

            mov   dx,[vvvalue] ; 800 decimal max.
            cmp   dx,800
            jb    qq3          ; >= 800 is inacceptable
            mov   dx,799
qq3:        shr   dx,1
            shr   dx,1         ; SHR by >1 in not 8086-compatible
            shr   dx,1         ; 0...99
            mov   ax,99
            sub   ax,dx        ; AX:=AX-DX | SUB result in AX
            xor   dx,dx        ; High 16 bits for division
            mov   bx,10
            div   bx           ; Quotient in AX, remainder in DX | only AL and DL relevant
            mov   ah,dl        ; AL quot | AH remainder
            add   ax,$3030

            mov   byte [es:di  ],al    ; HI decimal = quotient
            mov   byte [es:di+2],ah    ; LO decimal = remainder
            mov   byte [es:di+4],37    ; "%"

            mov   ax,[vvcounter]
            shr   ax,1              ; 110 ms =?= 0.1s Wink
            cmp   ax,1000
            jb    @f
            mov   ax,999
@@:         xor   dx,dx             ; High 16 bits for division
            mov   bx,10
            div   bx                ; Quotient in AX (up to 99), remainder in DX (up to 9)
            mov   bl,dl             ; Remainder
            add   bl,48             ; 1/10s
            xor   dx,dx
            push  bx                ; See ^^^ 1/10s
            mov   bx,10
            div   bx                ; DIV
            pope  bx
            mov   ah,dl             ; Next remainder: "1s" in AH , "10s" in AL
            add   ax,$3030

            mov   byte [es:di+08],al    ; HI decimal = quotient
            mov   byte [es:di+10],ah    ; LO decimal = remainder
            mov   byte [es:di+12],46    ; "."
            mov   byte [es:di+14],bl    ; One more remainder
            mov   byte [es:di+16],115   ; "s"

qq4:        mov   al,[vvcounter]
            shr   al,1
            shr   al,1
            call  ssover

qq5:        pope  di
            pope  dx
            pope  bx
            pope  ax
            pope  es
            pope  ds
            jmp   far [cs:vvint1c]
            ;---------------------

; OVERSCAN stuff
;
; Input colour in AL / AX
; Trashes AX and DX !!!

ssover:     push  ax           ; No BYTE PUSH after 8080 Sad((
            mov   dx, $03DA    ; Make sure in index mode in VGA
            in    al, dx
            mov   dx, $03BA    ; Make sure in index mode in EGA Very Happy
            in    al, dx
            mov   dx, $03C0    ; "ATC" hack
            mov   al, $11      ; Set border/overscan color
            out   dx, al
            pope  ax
            and   al, $1F
            out   dx, al
            mov   al, $20      ; Finalize it
            out   dx, al
            ret
            ;----

ssprint: ; High-end style Very Happy

           pope  bx
@@:        mov   byte dl,[bx]
           inc   bx
           cmp   dl,0        ; End ?
           je    ss1         ; YES
           call  ssonechar
           jmp   short @b
           ;-------------
ss1:       push  bx
           ret
           ;----

sseol: ; Just EOL Wink

           mov   dl,$0D
           call  ssonechar
           mov   dl,$0A
           ; pass

ssonechar: ; One char | IN: DL

           mov   ah,2
           int   $21
           ret
           ;----

sshex16:
             push  ax       ; Input in AX, will get trashed, also DX
             push  cx
             mov   cl,8
             shr   ax,cl
             pope  cx
             call  sshex8
             pope  ax
             ; pass

sshex8:      push   ax
             push   cx
             mov    cl,4
             shr    al,cl
             pope   cx
             call   sshex4
             pope   ax
             ; pass

sshex4:
             and  al,$0F
             cmp  al,10       ; Decimal 10 !!!
             sbb  al,$69
             das              ; Digital Attack System
             mov  dl,al
             jmp  short ssonechar
             ;-------------------

lleof:       mov   ax,$4C00
             int   $21         ; END OF FUN, finally Very Happy
             ;--------

; END.
    


Enjoy Laughing

EDIT: Bugged php-BB decided to mess up my poll today, 10 edits needed to finally (?) fix it Sad


Last edited by DOS386 on 14 Mar 2008, 03:25; edited 10 times in total
Post 14 Mar 2008, 02:22
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
So, does it take care of multi-core/multi-cpu systems, and does it save SSE register state? Smile
Post 14 Mar 2008, 02:27
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386
> does it take care of multi-core/multi-cpu systems

NO. I prefer 2 cores/CPU's on 2 mainboards , multiple cores on one mainboard is useless, maybe except in some very very very very very very rare situations Idea

> and does it save SSE register state?

NO. It doesn't trash them. Idea

At least, if offers a reliable progress indicator running in the background, plus main code (saving), + decimal convert, + hex convert, + debugging and bugging messages and rants, + some fancy effects, all this in just 768 bytes ... standalone, and 8086 compatible.

This is the final evidence that multithreading, at least as long as used "only" for a progress indicator, and user friendliness ("seems frozen - should I push RESET now or wait even longer") is not a question of a highest-end pre-empty multi-xx kernel having many 1'000'000's lines of C++ code and requiring multiple cores to even boot up at all Laughing
Post 14 Mar 2008, 03:37
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Quote:
NO. I prefer 2 cores/CPU's on 2 mainboards , multiple cores on one mainboard is useless, maybe except in some very very very very very very rare situations
Not if you multi-task - having two cores (heck, even P4-style HyperThreading) is an immense benefit, as soon as you do any kind of data crunching on your computer.

Anyway, I wouldn't really call your example 'multi-threading'. Sure, having timer-tick controlled progress indication is fine and everything, but it's not multi-threading Smile
Post 14 Mar 2008, 07:49
View user's profile Send private message Visit poster's website Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
To me you have multi-tasking running more than one program at the same time (not really at the same time, but simulatered to seem like at the same time).

Multi-threading running more than one thread in a program at the same time (or simulatered to seem like at the same time, as above)

Now if you hook the timer int and use basic multi-tasking code in side a program, to run many threads, then you are multi-threading, and this is very simple to do code, if you put this code for example into a com file you would have multi-threading
http://www.dex4u.com/ASMcompo512b/nanoos2.zip

Also i would say it easer to implement multi-threading in a single tasking OS, than A multi-tasking OS.
Post 14 Mar 2008, 13:14
View user's profile Send private message Reply with quote
roboman



Joined: 03 Dec 2006
Posts: 122
Location: USA
roboman
Well there was concurent dos, not the same thing, a multi tasking dos. There were also a few bbs programs and games that could multi thread, but in some cases they blew off so much that you might argue they were no longer in dos and were in effect their own os...
Post 15 Mar 2008, 02:02
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4215
Location: 2018
edfed
what will set the priority for the drivers?

the application can use it's own driver, but the main can stop or switch with it's own drivers.

how to make it? is it a sort of multithread/task ISR, with a kernel level emulation of application's ISR?
Post 15 Mar 2008, 03:25
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386
Dex wrote:

Quote:
...


YES, it's only an approach to multi-threading, not -tasking Laughing

edfed wrote:

Quote:
...


Confused Question
Post 16 Mar 2008, 00:26
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
DOS386 wrote:
Dex wrote:

Quote:
...


YES, it's only an approach to multi-threading, not -tasking Laughing

Most people do not know the difference Rolling Eyes .

For those who do not know the difference: http://zone.ni.com/devzone/cda/tut/p/id/6424
Post 16 Mar 2008, 17:08
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo
Dex, I'm surprised you didn't mention explicitly the XBox, which is one task with something like three? threads.

And BTW, yes DOS can multitask (DesqView, DR-DOS, Win 3.x). You can use certain software to write such (e.g. XS compiler or DX-Forth).

EDIT: BTW, nice job, but why is the example so, er, useless? Creating a 40 MB file?? I mean, I assume you have a reason, but still .... Shocked
Post 17 Mar 2008, 17:56
View user's profile Send private message Visit poster's website Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
rugxulo wrote:

And BTW, yes DOS can multitask (DesqView, DR-DOS, Win 3.x). You can use certain software to write such (e.g. XS compiler or DX-Forth).

Also Dos's TSR, is a basic forum of multi-tasking.
Post 17 Mar 2008, 20:18
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386
rugxulo wrote:
yes DOS can multitask (DesqView, DR-DOS, Win 3.x)


Not DOS Wink

Quote:
nice job, but why is the example so, er, useless? Creating a 40 MB file?? I mean, I assume you have a reason, but still


1. Examples are usually "useless"
2. Creating a huge file ... to get time for showing the progress indicator Wink
3. Should I create an example of progress indicator applied to a sophisticated compiler, compressor, brutal-forcer instead ? An "example" with several 10'000's lines ? Shocked

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 19 Mar 2008, 12:37
View user's profile Send private message Reply with quote
System86



Joined: 15 Aug 2007
Posts: 77
System86
Also, why do you put "define pope pop"? Why not just use "pop reg" and replace "pope" with "pop" in your code?
Post 22 Mar 2008, 23:31
View user's profile Send private message Reply with quote
System86



Joined: 15 Aug 2007
Posts: 77
System86
Any system that supports interrupts can theoretically do multitasking, just save state and jump to another thread or task when a certain interrupt occurs.
Post 22 Mar 2008, 23:37
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4215
Location: 2018
edfed
yes, for example, window$, it creates a V86 module in pm linear address space, but when i set the new ISR for keyboard, there are two drivers for the keyboard:
mine, that is intended to be alone,
and m$ that can still read keyboard with it's own interface, and switch task (ctrl+tab) even if the keyboard isr is not dos compatible.
then how does it works????
if i set a timer interupt, it don't act really as real timer, because the main os will continue to work over this...
Post 22 Mar 2008, 23:40
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16842
Location: In your JS exploiting you and your system
revolution
edfed wrote:
yes, for example, window$, it creates a V86 module in pm linear address space, but when i set the new ISR for keyboard, there are two drivers for the keyboard:
mine, that is intended to be alone,
and m$ that can still read keyboard with it's own interface, and switch task (ctrl+tab) even if the keyboard isr is not dos compatible.
then how does it works????
if i set a timer interupt, it don't act really as real timer, because the main os will continue to work over this...
If you don't use the DOS emulator in Windows then you won't see this problem. DOS is not compatible with the underlying multitasking OSes so it has to be emulated or else the whole thing will crash.
Post 22 Mar 2008, 23:47
View user's profile Send private message Visit poster's website Reply with quote
System86



Joined: 15 Aug 2007
Posts: 77
System86
When the CPU is in vm86 mode and an interrupt occurs, the system switches into protected mode to handle the interrupt. The pmode int handler may or may not call the vm86 handler, it's up to the pmode handler to decide if to reflect the interrupt back into virtual 8086 mode. In the case of windows, it handles some keystrokes on its own and others it sends to the vm86 task. So its true, interrupts (and hardware in general) is emulated in a vm86 task under Windows.
Post 23 Mar 2008, 00:54
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16842
Location: In your JS exploiting you and your system
revolution
System86 wrote:
Any system that supports interrupts can theoretically do multitasking, just save state and jump to another thread or task when a certain interrupt occurs.
A system also needs to support arbitrary state saving and restoration. Some MPU's can't do it, notably most (maybe all?) of the PIC range.
Post 23 Mar 2008, 01:57
View user's profile Send private message Visit poster's website Reply with quote
sakeniwefu



Joined: 23 Mar 2008
Posts: 29
sakeniwefu
Multithreading is possible in any CPU. What's limited is the kind of multithreading/multitasking that is possible. It also may depend on the machine.

MMU - Protected Mode Preemptive Multitasking(Windows NT, Linux)
Timer Interrupts - Preemptive Multitasking(Some hobby OS?)
no Interrupts, or too slow context switch - Cooperative Multitasking(MacOS Classic, Win 3.1 and below)

I wrote a preemptive multitasking task switcher for the ZX Spectrum PC(3KHz Z80 48k RAM) using timer interrupts that saved the 8080 compatibility registers and ran at decent speed, so MS-DOS is obviously able to do it, but probably cooperative multitasking will be faster.
Post 23 Mar 2008, 10:22
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16842
Location: In your JS exploiting you and your system
revolution
sakeniwefu wrote:
Multithreading is possible in any CPU.
I am keen to learn how to do this on the PIC 16Fxx range MCUs. I have been struggling to implement it for nearly 8 years now without success. I always end up with direct conditional jumps based upon global states. The consequence of having no control over the return stack makes subroutine based task switching impossible to implement and finding a way around it is a real headache. Every time I look at the code I wonder how it can be made more general.

I know the new PIC 18xx series has two stacks and can thus implement dual threading, clearly the designers got too many complaints and made a few small changes to help the programmers out.
Post 23 Mar 2008, 11:02
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.