;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;   procedury ComIntr_1,2,3,4   jednotky  ChnCom
;
;   (C)1998 SofCon, Stresovick  49, 160 00 Praha 6
;           Ing. Vladim¡r Kastner, Na Vlcovce 6, Praha 6
;           Adam Wild, Dejvicka 42, Praha 6
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.list
ComRBR          equ     0      ; Receive Buffer Register
ComTHR          equ     0      ; Transmitter Holding Register
ComIER          equ     1      ; Interrupt Enable Register
ComIIR          equ     2      ; Interrupt Identification Register
ComLCR          equ     3      ; Line Control Register
ComMCR          equ     4      ; Modem Control Register
ComLSR          equ     5      ; Line Status Register
ComMSR          equ     6      ; Modem Status Register

ifdef Kit188
AICU188         equ   0FF22h   ; Port for End of Interrupt
else
EOI             equ     020h   ; End of Interrupt Value
AICUM           equ     020h   ; Master port for End of Interrupt
AICUS           equ     0a0h   ; Slave port for End of Interrupt
endif

MIP             equ 00000001b  ; Mask for Interrupt Pending
MErrRec         equ 00011110b  ; UnMask redundant bits from Status
MErrSTS         equ 00000110b  ; Mask for Interrupt from Status
MRecReady       equ 00000100b  ; Mask for Interrupt from Receiver
MTransReady     equ 00000010b  ; Mask for Interrupt from Transmitter
ErrOvf          equ 10000000b  ; Overflow receiving buffer
TransOff        equ 11111101b  ; Disable interrupt from Transmitter
TransOn         equ 00000010b  ; Enable interrupt from Transmitter
RecOn           equ 00000101b  ; Enable interrupt from Receiver and Status
NoInterrupt     equ 00000000b  ; Disable All interrupts

tRecCom struc
        ComAdrIIR   DW  ?      ; Address of Interrupt Identification Register
        IRQ         DW  ?      ; IRQ Number
        BufRec      DD  ?      ; Pointer to Receive buffer
        URec        DW  ?      ; Index to first free space in Receive buffer
        VRec        DW  ?      ; Index to first not get up char in Receive buffer
        MaxURec     DW  ?      ; Maximum size of Receive buffer
        BufTrans    DD  ?      ; Pointer to Send buffer
        UTrans      DW  ?      ; Index to first not sent char in Send buffer
        MaxUTrans   DW  ?      ; Size of send message
        FlRecOn     DW  ?      ; Flag for enable Receive Interrupt after message was sent
        FlRecDel    DW  ?      ; Flag for delete first received char after message was sent
        CntIrq      DW  ?      ; IRQ counter
        CntRecB     DW  ?      ; Receive or status counter
        CntSendB    DW  ?      ; Send counter
ends

save    macro   r0,r1,r2,r3,r4,r5,r6,r7,r8,r9
        ifnb    <r0>
        push    r0
        save    r1,r2,r3,r4,r5,r6,r7,r8,r9
        endif
        endm

unsave  macro   r0,r1,r2,r3,r4,r5,r6,r7,r8,r9
        ifnb    <r0>
        unsave  r1,r2,r3,r4,r5,r6,r7,r8,r9
        pop     r0
        endif
        endm

Data    segment
          irp _x,<_1,_2,_3,_4>
            extrn   aRecCom&_x   : tRecCom
          endm
Data    ends

mirq    macro   _x,_y
        local   na0,na1,na2,na3,na4
        local   nb1,nb2,nb3
        local   ne0,ne1,ne2
        local   nm0

        public  ComIntr&_x

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;procedura ComIntr&_x; interrupt;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;.xlist
code    segment
        assume  cs:code,ds:nothing,es:nothing
.list
ComIntr&_x proc far
;.xlist
        save    ds,ax,dx,di,es,bp
        mov     ds,cs:VData                  ;ds:=DATA segment
        assume  ds:Data

        cli
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; zjisteni, cim bylo preruseni zpusobeno
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
na0:
        mov     dx,ARecCom&_y.ComAdrIIR      ;dx:=address of IIR register i8250
        in      al,dx                        ;al:=pricina preruseni
        test    al,MIP                       ;Interrupt Pending ?
;        sti                                 ;nelze pri ReTOS
        jz      short na1
        jmp     ne0                          ;jmp neni-li zadost
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; zjisteni, zda bylo preruseni zpusobeno prijmem znaku nebo statusem
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
na1:    inc     ARecCom&_y.CntIrq            ;inkrementace citace poctu preruseni

        test    al,MRecReady
        jz      nb1                          ;jmp if not Receive Buffer Ready
                                             ;dx=IIR
        inc     ARecCom&_y.CntRecB           ;inkrementace citace poctu prijatych znaku
        add     dx,ComLSR-ComIIR             ;dx:=LSR
        in      al,dx
        and     al,MErrRec
        les     bp,[ARecCom&_y.BufRec]       ;es:=seg(BufRec) bp:=ofs(BufRec)
        mov     di,ARecCom&_y.URec           ;di:=index to BufRec
        shl     di,1
        mov     es:[bp][di]+1,al             ;BufRec^[URec].sts:=port[ComAdrLSR] and MErrRec
        add     dx,ComRBR-ComLSR             ;dx:=RBR
        in      al,dx
        mov     es:[bp][di],al               ;BufRec^[URec].hod:=port[ComAdrRBR]
        shr     di,1
        cmp     byte ptr [ARecCom&_y.FlRecDel],0
        jne     short na3                    ;ma-li se prijaty znak vypustit

;        cli
        inc     di
        cmp     di,ARecCom&_y.MaxURec
        ja      short na2                    ;je-li vetsi nez MaxURec

        mov     ARecCom&_y.URec,di
        cmp     di,ARecCom&_y.VRec
        jne     short na0                    ;neni preteceni bufferu

        inc     di
        cmp     di,ARecCom&_y.MaxURec
        jb      short na4
        mov     di,0
na4:
        mov     ARecCom&_y.URec,di
        mov     di,ARecCom&_y.VRec
        shl     di,1
        or      byte ptr es:[bp][di]+1,ErrOvf
        jmp     short na0

na2:    mov     ARecCom&_y.URec,0            ;nastaveni na zacatek bufferu
        cmp     ARecCom&_y.VRec,0
        jne     short na0                    ;neni preteceni bufferu

        mov     ARecCom&_y.URec,1
        mov     di,2
        or      byte ptr es:[bp][di]-1,ErrOvf
        jmp     na0

na3:    mov     ARecCom&_y.FlRecDel,0
        jmp     na0
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; zjisteni, zda bylo preruseni zpusobeno odvysilanim znaku
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
nb1:    test    al,MTransReady
        jz      nm0                          ;jmp neni-li pricinou Transmitter
                                             ;dx=IIR
        mov     di,ARecCom&_y.UTrans         ;di:=index do BufTrans
        cmp     di,ARecCom&_y.MaxUtrans
        jae     short nb2                    ;je-li konec vysilani

        inc     ARecCom&_y.CntSendB          ;inkrementace citace poctu odeslanych znaku
        les     bp,[ARecCom&_y.BufTrans]     ;es:=seg(BufTrans) bp:=ofs(BufTrans)
        add     dx,ComTHR-ComIIR             ;dx:=THR
        mov     al,es:[bp][di]
        out     dx,al                        ;port[ComAdrTHR]:=BufTrans^[UTrans]
        inc     [ARecCom&_y.UTrans]
        jmp     na0

nb2:    inc     [ARecCom&_y.UTrans]
        add     dx,ComIER-ComIIR             ;dx:=IER
        in      al,dx
        and     al,TRansOff                  ;zakazani vysilace
        cmp     byte ptr [ARecCom&_y.FlRecOn],0 ;ma-li se povolit prijem po jeho zakazani
        jne     short nb3

        or      al,RecOn
        out     dx,al
        add     dx,ComLSR-ComIER             ;dx:=LSR
        in      al,dx
        add     dx,ComRBR-ComLSR             ;dx:=RBR
        in      al,dx
        jmp     na0

nb3:    out     dx,al
        jmp     na0
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; zjisteni, zda bylo preruseni zpusobeno statusem od modemu
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
nm0:                                         ; pricinnou je modem status
        add     dx,ComMSR-ComIIR             ;dx:=MSR
        in      al,dx
        jmp     na0
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; vytvoreni nabezne hrany pro 8250
; End Of Interrupt pro radic preruseni
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ne0:
;        add     dx,ComIER-ComIIR             ;dx:=IER
;        cli                                  ;disable interrupts
;        in      al,dx
;        mov     ah,al
;        mov     al,NoInterrupt
;        out     dx,al
;        mov     al,ah
;        out     dx,al

ifdef Kit188
        mov     dx,AICU188
        mov     ax,[ARecCom&_y.IRQ]
        out     dx,ax                        ;end of specific IRQ
else
        mov     al,EOI
        out     AICUM,al                     ;8259a master := NEOI
        cmp     [ARecCom&_y.IRQ],2           ;if (IRQ = 2) then jmp ne2
        je      ne2
ifNdef MCP                                   ;if (IRQ > 7) then jmp ne2
        cmp     [ARecCom&_y.IRQ],7
        jna     ne1
endif
ne2:    out     AICUS,al                     ;8259a slave  := NEOI
ne1:
endif

        unsave  ds,ax,dx,di,es,bp
        iret
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;end; { ComIntr&_x }
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
.list
ComIntr&_x endp
;.xlist
code    ends
.list
        endm

mmirq   macro
        irp     a,<<_1,_1>,<_2,_2>,<_3,_3>,<_4,_4>>
        mirq    a
        endm
        endm

code    segment
VData   dw      Data
code    ends

        mmirq

        end
