Groups | Search | Server Info | Login | Register


Groups > comp.lang.asm.x86 > #8802

Re: Help with COM1 serial port interrupt in x86 assembly

From Borax Man <rotflol2@nospicedham.hotmail.com>
Newsgroups comp.lang.asm.x86
Subject Re: Help with COM1 serial port interrupt in x86 assembly
Date 2023-11-12 12:14 +1100
Organization A noiseless patient Spider
Message-ID <20231112121458.5fb376bb@hotmail.com> (permalink)
References <0d2adfce-74d3-4aae-a0ec-786270c2deean@googlegroups.com> <Q0V3N.10$%aH4.0@fx01.iad>

Show all headers | View raw


On Sun, 12 Nov 2023 00:30:40 GMT
Branimir Maksimovic <branimir.maksimovic@icloud.com> wrote:

> You have to tell PIC and UART to trigger interrupt. Just out instructions, I guess that now since there
> is internet, you can find info easilly. Last time I programmed that was 1994...

Yes, you will need to write an interrupt handler which gets called
when the interrupt is triggered.  I haven't done this for a serial
port, but an example of an interrupt handler I wrote using the PC
timer is below.  Its a bit more complex than it needs to be, because
it also makes sound through the PC speaker.

OurInt08 is the interrupt handler.

This section saves the old interrupts then sets the interrupt vector to point to our handler.  This is just for demonstration purposes.

	cli ;Turn off interrupts!
	mov word ax, [es:08h*4]
	mov word [cs:OldInt8], ax
	mov word ax, [es:08h*4 + 2]
	mov word [cs:OldInt8+2], ax

	mov ax, OurInt08
	mov word [es:08h*4], ax
	mov ax,cs
	mov word [es:(08h*4)+2], ax

Then don't forget to restore the old hander...


	mov ax, word [cs:OldInt8]
	mov word [es:08h*4], ax
	mov word ax, word [cs:OldInt8+2]
	mov word [es:08h*4 + 2], ax


The full program is below and it will compile with FASM.


	; A working example of how to use an interrupt handler
	; in DOS.  This source file is for FASM.
	;

	FORMAT MZ
	; DOS 16-bit EXE format
	STACK 400h
	HEAP 0	; No extra heap required.
	ENTRY CODE:Init

	; Quick example of using interrupts and chaning the PIT
	; tick rate
	use16

	freq = 42940
	inputlen = 160

SEGMENT CODE USE16

Init:
	mov ax,DATA2
	mov ds,ax
	mov fs,ax	     ; Set FS to point to data segment.
			     ; DS will change during the program
			     ; but FS won't as DOS doesn't touch this.
	mov ax, oldscreen    ; Create far pointer.
	mov word [dptr],ax
	mov word [dptr+2],ds

	mov ah,09h
	mov dx,intro
	int 21h  ; Print introduction message.

	mov cx,inputlen ; Input length
	xor ax,ax
	mov ah,3fh
	mov bx,0
	mov dx,input  ; Where to store
	int 21h
	jc endp
	cmp ax,8
	jg inputerror  ; Anything more than 6 characters we reject

	mov bx, ax ; BX will store the offset as we go through the input data.
	cmp [bx+input-1],0ah ; If this is not the last character
			     ; It means we didn't fill all the input
			     ; and some may be lost.  Best to end with
			     ; an error.  Besides, if it was a valid
			     ; number, it would have been well over the
			     ; maximum number of stars we could handle.
	jne inputerror

	xor bx, bx  ; Start index at 0.
	sub ax, 2 ; We don't want the CR/LF duo at the end.
	mov cx, ax   ; CX will be used to compare the index
	; to determine whether we have reached the end of the user data
	; we want to convert.
	xor ax, ax ; Start tally at 0.
	mov si, 10   ; Multiply each number we get by 10, as we push it up
		    ; as a significant digit.
	mov di, input
.getnum:
	cmp byte [di+bx], '0'  ; If less than '0', its not a numeral.
	jl inputerror
	cmp byte [di+bx], '9'  ; If more than '9', its not a numeral.'
	jg inputerror
	sub byte [di+bx], 30h  ; Sub 30h to convert the ascii numeral
			       ; to the number
	mul si		       ; Multiply what we have added so far by 10
	push dx
	mov dl, byte [di+bx]
	add ax,dx	       ; And add the next digit
	pop dx
	inc bx
	cmp bx, cx	     
	jl .getnum	      ; If more digits, go again.
	mov cx, ax
begindemo:	  	
	mov al, 0x36
	out 0x43, al	;tell the PIT which channel we're setting
	mov ax, cx
	out 0x40, al	;send low byte
	mov al, ah
	out 0x40, al	;send high byte
	xor dx,dx
	mov es,dx

	cli ;Turn off interrupts!
	mov word ax, [es:08h*4]
	mov word [cs:OldInt8], ax
	mov word ax, [es:08h*4 + 2]
	mov word [cs:OldInt8+2], ax

	mov ax, OurInt08
	mov word [es:08h*4], ax
	mov ax,cs
	mov word [es:(08h*4)+2], ax
	mov ax, 0B800h
	mov es,ax
	call savescreen
	; The interrupt may update the screen prior to us saving it.
	call soundon
	sti

inputloop:

	mov cx,inputlen ; Input name
	mov ax,3f00h	; Input call
	xor bx,bx	; From keyboard (stdin)
	mov dx,keybuff	; Save at keybuff
	int 21h
	cmp [fs:keybuff],'q'
	jne inputloop
	xor dx,dx
	mov es,dx
	call soundonoff

	mov es,dx
	cli
	mov ax, word [cs:OldInt8]
	mov word [es:08h*4], ax
	mov word ax, word [cs:OldInt8+2]
	mov word [es:08h*4 + 2], ax

	xor ax,ax
	out 0x43, al	;tell the PIT which channel we're setting
	out 0x40, al	;send low byte
	out 0x40, al	;send high byte

	call restorescreen

	mov ax,DATA3
	mov ds,ax
	mov ax,0b800h
	mov es,ax

	mov ah,09h
	mov dx,data3msg
	int 21h  ; Print introduction 


	mov cx,800
	mov bx,1
loop55:
	mov byte [es:bx],2
	add bx,2
	dec cx
	jnz loop55
endp:
	mov ax,4c00h	 ; Send exit code to dos
	int 21h 	; Send command to DOS
	
soundon:
	push ax 
	in al,61h	       ;-Bits D1-D0 of "port 61h" are unmasked 
	or al,03h	      ; or masked !
	out 61h,al 
	pop ax 
	ret	      
soundonoff:
	push ax 
	in al,61h	       ;-Bits D1-D0 of "port 61h" are unmasked 
	xor al,03h	       ; or masked !
	out 61h,al 
	pop ax 
	ret	      

	
OurInt08:
	; This interrupt handler could be called in any context
	; so we cannot assume anything about the state of the registers
	; including the segment registers.  As we are calling for user input
	; this is likely to be called during DOS function 3F, and DOS
	; may very well have set DS and ES to different values.
	pusha
	pushf
	add word [fs:elapsed], tickrate
	jnc skipint

	cli
	mov al,0b6h
	mov dx, 043h
	out dx,al

	mov ax,[fs:elapsed]
	mov dx, 042h
	out dx,al
	mov al, ah
	out dx,al
	sti
	popf
	popa
	jmp far [cs:OldInt8]	       ; using INT 08H emulation
skipint:
	push 0b800h
	pop gs
	mov bx,(160*20)-2
loop1:
	inc word [gs:bx]
	sub bx,2
	jnc loop1
ll2:
	mov al,20h		; EOI code for PIC
	out 20h,al		; Send
	popf
	popa
	iret

savescreen:
	push ax
	mov cx,2000-2
	xor si,si
	les di, [dptr]
	cld
	push 0b800h
	pop ds

	rep movsw
	push ds
	pop es
	mov ax,DATA2
	mov ds,ax

	pop ax
	ret

restorescreen:
	cld
	push ds
	mov ax,DATA2
	mov ds,ax
	push 0b800h
	pop es
	push ax
	mov cx,2000-2
	lds si, [dptr]		; This is unnecessary, we don't need to store the pointer
	; But I wanted to use the lds and les commands as an example
	xor di,di
	rep movsw
	pop ax
	pop ds
	ret
inputerror:
	mov dx,invalid ;Tell user about invalid input
	mov ah,09h
	int 21h
	mov ah,10h
	int 16h   ; Wait for keypress
	jmp begindemo


	OldInt8 dd 0


SEGMENT DATA3 USE16
	data3msg db "Now we are at the next part of the demonstration."
	db 13,10,"I will change some text colours.",13,10,24h


SEGMENT DATA2 USE16
	invalid   db "Invalid input or number too high.  ",\
	"Using default number of stars.",0ah,0dh,\
	"Press any key.",0ah,0dh,24h

	numstars  dw	10000
	elapsed dw 0
	intro	db  "Interrupt handler demo, by Borax Man",13,10
	db "September, 2020",13,10
	db 13,10,"Type 'q' and hit enter to exit while demo is running.",13,10,10
	db "Enter a ticrate between 0 - 65536",13,10
	db "Numbers lower than 3000 may cause problems on older machines",13,10,24h
	input	  rb	10

      	keybuff rb inputlen  ; This must be immediately after message
	dptr: rb 4
	oldscreen: rb 4000


SEGMENT ENDSEG


-- 

Back to comp.lang.asm.x86 | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Help with COM1 serial port interrupt in x86 assembly Robert Pengelly <robertapengelly@gmail.com> - 2023-11-10 22:22 -0800
  Re: Help with COM1 serial port interrupt in x86 assembly Branimir Maksimovic <branimir.maksimovic@icloud.com> - 2023-11-12 00:30 +0000
    Re: Help with COM1 serial port interrupt in x86 assembly Borax Man <rotflol2@nospicedham.hotmail.com> - 2023-11-12 12:14 +1100
      Re: Help with COM1 serial port interrupt in x86 assembly Branimir Maksimovic <branimir.maksimovic@nospicedham.icloud.com> - 2023-11-13 03:11 +0000
        Re: Help with COM1 serial port interrupt in x86 assembly Terje Mathisen <terje.mathisen@nospicedham.tmsw.no> - 2023-11-13 16:30 +0100
          Re: Help with COM1 serial port interrupt in x86 assembly Borax Man <bob@nospicedham.zerosignal.strangled.net> - 2023-11-14 10:11 +0000

csiph-web