File:  [OS/2 SDKs] / os2sdk / demos / examples / asmexmpl / asmexmpl.asm
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:26:25 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: os2sdk-1988, HEAD
Microsoft OS/2 SDK 03-01-1988

;
; This is an example of an assembly language program using 286DOS calls.
; It creates two threads, one which writes a message to the screen every
; two seconds, the other every second. As an example of semaphore usage
; the two threads request a semaphore before writing to the screen.
;
; Created by Microsoft Corp. 1986

.286p		; Allow only protect mode instructions

STACK_SIZE	equ	400h	; Stack for each thread

STACK	segment word stack 'STACK'

	dw  2048 dup(?)

STACK	ends

DSEG	segment word public 'DATA'

Selector	dw	?		; selector returned from DOSALLOCSEG
sem		dd	0		; semaphore
thread1ID	dw	?		; thread id

; message written from thread 0
;
hello0		db	"thread zero hello", 0dh, 0ah
HELLO0_SIZE	equ	($ - hello0)

; message written from thread 1
;
hello1		db	"thread ONE hello", 0dh, 0ah
HELLO1_SIZE	equ	($ - hello1)

DSEG	ends

DGROUP	GROUP	DSEG
	assume cs:CSEG, ds:DGROUP

	extrn	DOSALLOCSEG	:FAR	    ; MS OS/2 calls used
	extrn	DOSCREATETHREAD :FAR
	extrn	DOSEXIT 	:FAR
	extrn	DOSSEMCLEAR	:FAR
	extrn	DOSSEMREQUEST	:FAR
	extrn	DOSSLEEP	:FAR
	extrn	DOSWRITE	:FAR

CSEG	segment byte public 'CODE'

	; allocate memory for the new thread's stack

START:
	push	STACK_SIZE		; size requested
	mov	bx, SEG DGROUP
	push	bx			; push far address of selector
	push	offset DGROUP:[Selector]
	push	0			; not to be shared
	call	DOSALLOCSEG		; allocate stack
	or	ax, ax			; did an error occur?
	jnz	ErrorExit

	; create the new thread

	push	SEG CSEG		; push far call address for new thread
	push	offset CSEG:thread1
	push	bx			; far address of returned thread number
	push	offset DGROUP:[thread1ID]
	push	DGROUP:[Selector]	; far address of allocated stack
	push	STACK_SIZE	
	call	DOSCREATETHREAD		; create a new thread
	or	ax, ax
	jnz	ErrorExit

	call	far ptr thread0

ErrorExit:
	push	1		; terminate all threads
	push	1		; return error code
	call	DOSEXIT		; exit program

thread0	PROC	FAR

	push	bp			; set up local stack for access
	mov	bp, sp	

startThread0:
	push	bx			; far address of ram semaphore
	push	offset DGROUP:[sem]
	mov	ax, -1			; no timeout, wait forever
	cwd				; convert to long
	push	dx	
	push	ax
	call	DOSSEMREQUEST		; request semaphore

; got semaphore, now write message to screen

	push	1			; file handle for standard out
	push	bx			; far address of write buffer
	push	offset DGROUP:[hello0]
	push	HELLO0_SIZE		; size of write buffer
	lea	ax, [bp - 2]		; bytes written
	push	ss
	push	ax
	call	DOSWRITE		; write message 

	push	bx			; far ptr to semaphore
	push	offset DGROUP:[sem]
	call	DOSSEMCLEAR		; release semaphore

	push	0			; give up processor
	push	2000
	call	DOSSLEEP
	jmp	short startThread0	; loop forever

thread0	ENDP


; This is where the new thread will execute.

thread1	PROC	FAR

	push	bp			; set up local stack access
	mov	bp, sp	

startThread1:
	push	bx
	push	offset DGROUP:[sem]	; address of semaphore
	mov	ax, -1			; wait forever
	cwd				; convert to long
	push	dx	
	push	ax
	call	DOSSEMREQUEST		; request semaphore

; got semaphore, now write message to screen

	push	1			; file handle for standard out
	push	bx			; write buffer address
	push	offset DGROUP:[hello1]

	push	HELLO1_SIZE		; write buffer size

	lea	ax, [bp - 2]		; bytes written
	push	ss
	push	ax
	call	DOSWRITE		; write message

	push	bx			; far ptr to semaphore
	push	offset DGROUP:[sem]
	call	DOSSEMCLEAR		; release semaphore

	push	0			; give up processor
	push	1000
	call	DOSSLEEP
	jmp	short startThread1	; loop forever

thread1	ENDP

CSEG	ends
	end	START

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.