Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

uart interrupt tx rx in Dos32 bit open watcom (Developers)

posted by maui, 15.11.2013, 19:43

> Look at
> mc323exa.zip
> from David Dunfield to see how this was done with 16-bit code.
> Specifically, 16550A - 16550A uart FIFO control.
> DLM (data line
> monitor),
> SERMON
> (multi-serial monitor), and
> SDT (serial
> debug terminal) might also be helpful as well. If you're trying to
> implement a data transfer app, Dunfield has many in mc323exa (see
> SAMPLE.TXT)
> and others available at his
> DOS Utils
> page. They all depend on his 16-bit
> Micro C
> Compiler if you decide to rebuild them from source which is very
> easy to do and he provides links to everything you need for that on his DOS
> Utils page.

Thank for the link, I will get a look on that in these next days.

Here my code, it is a version from bimodal from open watcom goodies example:


.286

_TEXT16 SEGMENT BYTE PUBLIC 'CODE'
                                ASSUME  cs:_TEXT16

                                ;**
                                ;** The real-mode interrupt handler is in a 16-bit code segment
                                ;** so that the assembler will generate the right code.
                                ;**
                                ;** We will copy this code to a 16-bit segment in low memory
                                ;** and install it as a real mode interrupt handler before it
                                ;** gets executed.  (There's no distinction between code and
                                ;** data in real mode.)
                                ;**
                                ;** Since the handler doesn't get executed before it gets copied,
                                ;** putting it in this segment makes the C code simpler.
                                ;**
                                ;** The buffer into which we will store the data being sent
                                ;** to us is also in this segment, for simplicity.  (It's
                                ;** possible to read and write code segments in real mode.)
                                ;** We will lay out this segment using fixed offsets, so that
                                ;** we can omit the data in the executable file.  The symbolic
                                ;** offsets are only used to reference the segment BEFORE
                                ;** it has been copied low.
                                ;**
                                ;** Both the real mode and protected mode handlers will store
                                ;** their data in this same buffer (that is, in the copy in
                                ;** low memory).
                                ;**
                                ;** OFFSET    LENGTH     CONTENTS
                                ;**
                                ;** 0         <128       Real mode interrupt handler
                                ;** 128       4          Next available slot in buffer
                                ;** 132       1024       Data receive buffer
                                ;** 132+1024  1          Overflow indicator
                                ;**

maxbuf  EQU     1024

                                PUBLIC  rmhandler_, _com_port_low
rmhandler_:
                                push    ds
                                push    bx
                                mov     bx, 0B800h
                                mov     ds, bx                          ; DS = 0xB800
                                sub     bx, bx                          ; BX = 0
                                mov     WORD PTR [bx], 0720h            ; Clear 2 character cells
                                mov     WORD PTR [bx+2], 0720h

                                push    cx
                                push    ax
                                mov     cx, 10h
rmdelay:
                                mov     ax, 1
                                mul     cl
                                loop    rmdelay                         ; RM delay loop (flicker makes
                                pop     ax                              ;   screen effects understandable)
                                pop     cx

                                mov     BYTE PTR [bx],'R'               ; Write 'R' to memory map

                                db      0BBh                            ; mov bx,...
_com_port_low   DW      ?                       ;   com port base address
                                push    ax
                                push    dx
retry_int:
                                mov     bx,03E8h     ;base address of com 3
                                lea     dx, [bx+2]   ;pointing to interrupt identification
                                in      al, dx       ;getting the interrupt
                                and                     al, 02h      ;enabling only the tx bit
                                cmp     al, 02h      ;is it on?
                                je                      int_tx_rm    ;yes, go to the tx routine
                                jne             clear_int_rm ;else clear the interrupt
int_tx_rm:
                                ;my total char to send, and the index, are mapped in cs
                                mov     bl,cs:[2048+5];total of the char to send
                                mov     al,cs:[2048+6];index of char sent
                                cmp     al,bl        ;are there any char left?
                                jge                     clear_int_rm ;no, clear the interrupt
                                ;yes send the new char
                                inc             al           ;in the index
                                mov     cs:[2048+6],al;save in memory

                                mov     bx,03E8h                 ;base address of com 3
                                lea     dx,[bx]      ;pointing to the com
                                mov                     al,cs:[2048+6];sending the index +0x40(A)
                                add                     al,40h
                                out     dx,al        ;sending out

                                ;max 16 byte
                                mov                     al,cs:[2048+6];getting the index
                                and                     al,0fh        ;only the 4 lower bit
                                cmp                     al,0fh        ;equal to 15?
                                je      clear_int_rm  ;yes, exit the int
                                jmp     int_tx_rm

;                               lea     dx,[bx+2]     ;pointing to interrupt identification
;                               mov     ax,0          ;clearing ax
;                               in                      al,dx         ;getting the flags
;                               test            al,1
;                               jz      retry_int

clear_int_rm:
                                ;clearing slave
                                mov     dx,0a0h
                                mov     al,020h
                                out     dx,al                           ; Send EOI

                                ;clearing master
                                mov     dx,020h
                                mov     al,dl
                                out     dx,al                           ; Send EOI
;;;;;;;;;;;;;

                                pop     dx
                                pop     ax
                                pop     bx
                                pop     ds
                                iret
                                ASSUME  cs:NOTHING

; These variables only exist in the real mode copy of this segment
; (the one which actually gets executed)
;
;               ORG     128
;next           DD      0
;databuf        DB      maxbuf dup(0)
;overflow       DB      0

_TEXT16 ENDS



I know that it is not the best clearing code, with this the sending of all buffer it is not always processed, becouse sometime, I don't receive back the interrput of the 16th byte sent.
In the init com, i enable the fifo with outp(0x3E8+2,1), and only the interrupt tx in the outp(0x3E8+1,2)

Thanks for your time on this topic.

maui.

 

Complete thread:

Back to the forum
Board view  Mix view
22762 Postings in 2122 Threads, 402 registered users (2 online)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum