www.pudn.com > zsnes117b-src.zip > modemrtn.asm


;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) 
; 
;This program is free software; you can redistribute it and/or 
;modify it under the terms of the GNU General Public License 
;as published by the Free Software Foundation; either 
;version 2 of the License, or (at your option) any later 
;version. 
; 
;This program is distributed in the hope that it will be useful, 
;but WITHOUT ANY WARRANTY; without even the implied warranty of 
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
;GNU General Public License for more details. 
; 
;You should have received a copy of the GNU General Public License 
;along with this program; if not, write to the Free Software 
;Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 
%include "macros.mac" 
 
EXTSYM ComNum, ComIRQ, BaudRate 
EXTSYM dssel,FossilUse 
EXTSYM GUIinit18_2hz,GUIinit36_4hz 
EXTSYM GUIMenuItem 
   EXTSYM delay 
 
 
 
 
 
 
 
 
 
NEWSYM UartType, db 0 
NEWSYM cantinitmodem, db 1 
NEWSYM ModemInited, db 0 
 
ComPort dw 2E8h  ; 1=3F8,2=2F8,3=3E8,4=2E8 
PortData dw 0,3F8h,2F8h,3E8h,2E8h 
ComInt  db 0 
BRateSel dw 000Ch,0008h,0006h,0004h,0003h,0002h,0001h 
oldhandmodems dw 0 
oldhandmodemo dd 0 
PICMaskPm   db 21h 
PortNum       dw 0 
CharStore     db 0 
 
NEWSYM ModemGetChar 
   cmp byte[UartType],2 
   je near FossilGetChar 
   xor dh,dh 
   mov eax,[modemhead] 
   cmp eax,[modemtail] 
   je .nonewchar 
   mov dh,1 
   mov dl,[modembuffer+eax] 
   inc dword[modemhead] 
   and dword[modemhead],2047 
.nonewchar 
   ret 
 
FossilGetChar: 
   pushad 
   mov ah,0Ch 
   mov dx,[PortNum] 
   int 14h 
   cmp ax,0FFFFh 
   je .nochar 
   mov ah,02h 
   mov dx,[PortNum] 
   int 14h 
   mov [CharStore],al 
   popad 
   mov dh,1 
   mov dl,[CharStore] 
   ret 
.nochar 
   popad 
   xor dh,dh 
   ret 
 
NEWSYM ModemCheckRing 
   cmp byte[UartType],2 
   je near .fossil 
   mov dx,[ComPort] 
   add dx,6 
   in al,dx 
   shr al,6 
   and al,01h 
   ret 
.fossil 
   pushad 
   mov ah,03h 
   mov dx,[PortNum] 
   int 14h 
   test al,40h 
   jnz .ring 
   popad 
   xor al,al 
   ret 
.ring 
   popad 
   mov al,1 
   ret 
 
NEWSYM ModemCheckDCD 
   cmp byte[UartType],2 
   je near .fossil 
   mov dx,[ComPort] 
   add dx,6 
   in al,dx 
   shr al,7 
   and al,01h 
   ret 
.fossil 
   pushad 
   mov ah,03h 
   mov dx,[PortNum] 
   int 14h 
   test al,80h 
   jnz .dcd 
   popad 
   xor al,al 
   ret 
.dcd 
   popad 
   mov al,1 
   ret 
 
NEWSYM ModemSendChar 
   cmp byte[UartType],2 
   je near FossilSendChar 
   push ecx 
   push edx 
   push ebx 
   mov ecx,1000000 
   mov bl,al 
.loop 
   mov dx,[ComPort] 
   add dx,5 
   in al,dx 
   test al,00100000b 
   jnz .transokay 
   loop .loop 
   xor al,al 
   pop ebx 
   pop edx 
   pop ecx 
   ret 
.transokay 
   mov al,bl 
   mov dx,[ComPort]             ; Send the char through the modem 
   out dx,al 
   pop ebx 
   pop edx 
   pop ecx 
   ret 
 
FossilSendChar: 
   pushad 
   mov ah,01h 
   mov dx,[PortNum] 
   int 14h 
   popad 
   ret 
 
 
NEWSYM InitModem 
   mov byte[ModemInited],1 
   cmp byte[FossilUse],0 
   jne near InitFossil 
   mov byte[cantinitmodem],0 
   cli 
   ; Get Port value 
   xor eax,eax 
   mov al,[ComNum] 
   mov ax,[PortData+eax*2] 
   mov [ComPort],ax 
 
   mov dx,[ComPort] 
   add dx,2 
   xor al,al 
   out dx,al 
 
   ; Set IRQ PIC Mask Port 
   mov byte[PICMaskPm],21h 
   mov bl,[ComIRQ] 
   cmp bl,7 
   jbe .noupper 
   add bl,60h 
   add byte[PICMaskPm],80h 
.noupper 
   add bl,8 
   mov [ComInt],bl 
 
   ; Get IRQ handler 
   mov ax,204h 
   mov bl,[ComInt] 
   int 31h 
   mov [oldhandmodems],cx 
   mov [oldhandmodemo],edx 
   ; Set IRQ handler 
   mov ax,205h 
   mov bl,[ComInt] 
   mov cx,cs 
   mov edx,modemhandler 
   int 31h 
 
   mov dx,[ComPort] 
   add dx,3 
   mov al,00000011b 
   out dx,al 
 
   ; Set Normal Modem functioning, User2 bit, and DTR 
   mov dx,[ComPort] 
   add dx,4 
   mov al,00001011b 
   out dx,al 
 
   ; Enable IRQ 
   xor dh,dh 
   mov dl,[PICMaskPm]           ; Output to IRQ PIC Mask Port 
   mov cl,[ComIRQ]              ; Get proper bit 
   and cl,07h 
   mov al,01h 
   shl al,cl 
   not al                       ; Complement since clear bit = enable 
   mov bl,al 
   in al,dx                     ; input to preserve other bits 
   and al,bl 
   xor al,al 
   out dx,al 
 
   ; Enable interrupt to execute only on data available 
   mov dx,[ComPort] 
   inc dx 
   mov al,00000001b 
   out dx,al 
   sti 
 
   ; Write baudrate 
   mov dx,[ComPort] 
   add dx,3 
   in al,dx 
   or al,10000000b 
   out dx,al 
   mov eax,[BaudRate] 
   mov ax,[BRateSel+eax*2] 
   mov dx,[ComPort] 
   inc dx 
   push eax 
   mov al,ah 
   out dx,al 
   pop eax 
   dec dx 
   out dx,al 
   mov dx,[ComPort] 
   add dx,3 
   in al,dx 
   and al,01111111b 
   out dx,al 
 
   ; Initialize 16550A UART chip 
   mov dx,[ComPort] 
   add dx,2 
   mov al,0C7h 
   out dx,al 
   nop 
   nop 
   in al,dx 
   mov byte[UartType],1 
   test al,40h 
   jnz .passed16550a 
   xor al,al 
   out dx,al 
   mov byte[UartType],0 
.passed16550a 
   ret 
 
InitFossil: 
   xor edx,edx 
   mov dl,[ComNum] 
   dec dl 
   mov [PortNum],dx 
   mov byte[cantinitmodem],0 
   mov byte[UartType],2 
   mov ah,04h 
   mov dx,[PortNum] 
   int 14h 
   cmp ax,1954h 
   jne .notsuccess 
   xor ah,ah 
   mov al,00000011b     ; 19200 baud, 81N 
   mov dx,[PortNum] 
   int 14h 
   ret 
.notsuccess 
   mov byte[cantinitmodem],1 
   ret 
 
modemhandler: 
   push ds 
   push eax 
   mov ax,[cs:dssel] 
   mov ds,ax 
   push edx 
   mov dx,[ComPort] 
   add dx,4 
   in al,dx 
   and al,11111101b 
   out dx,al 
 
.next 
   mov dx,[ComPort] 
   in al,dx 
   mov edx,[modemtail] 
   mov [modembuffer+edx],al 
   inc dword[modemtail] 
   and dword[modemtail],2047 
   mov dx,[ComPort] 
   add dx,2 
   in al,dx 
   test al,1 
   jz .next 
 
   mov al,20h 
   out 20h,al 
 
   cmp byte[ComIRQ],7 
   jbe .nohighirq 
   mov al,20h 
   out 0A0h,al 
.nohighirq 
 
   mov dx,[ComPort] 
   add dx,4 
   in al,dx 
   or al,00000010b 
   out dx,al 
 
   pop edx 
   pop eax 
   pop ds 
   iretd 
 
NEWSYM ModemClearBuffer 
    mov dword[modemhead],0 
    mov dword[modemtail],0 
    ret 
 
NEWSYM modembuffer, times 2048 db 0 
NEWSYM modemhead, dd 0 
NEWSYM modemtail, dd 0 
 
NEWSYM DeInitModem 
   cmp byte[ModemInited],1 
   je .okaydeinit 
   ret 
.okaydeinit 
   mov byte[ModemInited],0 
   cmp byte[UartType],2 
   je near DeInitFossil 
   cli 
   mov dx,[ComPort] 
   add dx,2 
   xor al,al 
   out dx,al 
 
   xor dh,dh 
   mov dl,[PICMaskPm] 
   mov cl,[ComIRQ] 
   and cl,07h 
   mov al,01h 
   shl al,cl 
   mov bl,al 
   in al,dx 
   or al,bl 
   xor al,al 
   out dx,al 
   mov dx,[ComPort] 
   inc dx 
   mov al,00h 
   out dx,al 
   mov dx,[ComPort] 
   add dx,4 
   out dx,al 
 
   mov cx,[oldhandmodems] 
   mov edx,[oldhandmodemo] 
   mov ax,205h 
   mov bl,[ComInt] 
   int 31h 
   sti 
   ret 
 
DeInitFossil: 
   mov byte[cantinitmodem],0 
   jne .nodeinit 
   mov ax,0600h 
   mov dx,[PortNum] 
   int 14h              ; Lower DTR 
   mov ah,05h 
   mov dx,[PortNum] 
   int 14h 
.nodeinit 
   ret 
 
NEWSYM DeInitModemC 
   cmp byte[ModemInited],1 
   je .okaydeinit 
   ret 
.okaydeinit 
   cmp byte[UartType],2 
   je near DeInitFossil 
   cli 
   mov al,00h 
   mov dx,[ComPort] 
   add dx,4 
   out dx,al 
 
   mov al,13 
   mov dx,[ComPort] 
   out dx,al 
 
   mov ecx,16384 
   call delay 
 
   out dx,al 
 
   mov al,00001001b 
   mov dx,[ComPort] 
   add dx,4 
   out dx,al 
   sti 
   ret