First release of ZSNES sources

This commit is contained in:
teuf
2001-04-02 22:30:58 +00:00
commit 1fe183be02
138 changed files with 186213 additions and 0 deletions

3849
zsnes/src/dos/debug.asm Normal file

File diff suppressed because it is too large Load Diff

1821
zsnes/src/dos/dosintrf.asm Normal file

File diff suppressed because it is too large Load Diff

156
zsnes/src/dos/gppro.asm Normal file
View File

@@ -0,0 +1,156 @@
;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"
section .data
sample times 60 db 0
clock_mask db 0
data_mask db 0
section .text
NEWSYM read_gpp
push ebx
push ecx
push edx
push edi
push esi
cmp al,0
jne GPP_L14
mov byte [clock_mask],0x10
mov byte [data_mask],0x20
jmp GPP_L15
GPP_L14:
mov byte [clock_mask],0x40
mov byte [data_mask],0x80
GPP_L15:
xor ebx,ebx
xor edi,edi
cli
in al,dx
mov ah,al
GPP_L4:
xor ecx,ecx
GPP_L0:
nop
nop
nop
nop
nop
nop
in al,dx
cmp al,ah
jne GPP_L1
inc ecx
cmp ecx,255
jl GPP_L0
GPP_L1:
cmp ecx,255
je near GPP_ERR
test [clock_mask],ah
jz GPP_L2
test [clock_mask],al
jnz GPP_L2
test [data_mask],al
jz GPP_L3
mov byte [sample+edi],1
jmp GPP_L12
GPP_L3:
mov byte [sample+edi],0
GPP_L12:
inc edi
GPP_L2:
mov ah,al
cmp ebx,200
je GPP_L13
inc ebx
cmp edi,50
jl GPP_L4
GPP_L13:
sti
xor ecx,ecx
mov esi,1
GPP_L7:
cmp byte [sample+esi],1
jg GPP_ERR
jne GPP_L6
inc ecx
jmp GPP_L5
GPP_L6:
xor ecx,ecx
GPP_L5:
cmp ecx,5
je GPP_L8
cmp esi,edi
je GPP_L8
inc esi
jmp GPP_L7
GPP_L8:
cmp ecx,5
jne GPP_ERR
add esi,2
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
GPP_L10:
inc ecx
cmp ecx,5
jne GPP_L11
mov ecx,1
inc esi
GPP_L11:
mov dl,[sample+esi]
or eax,edx
shl eax,1
cmp ebx,13
je GPP_L9
inc ebx
inc esi
jmp GPP_L10
GPP_L9:
pop esi
pop edi
pop edx
pop ecx
pop ebx
ret
GPP_ERR:
sti
pop esi
pop edi
pop edx
pop ecx
pop ebx
mov eax,1
ret


621
zsnes/src/dos/initvid.asm Normal file
View File

@@ -0,0 +1,621 @@
;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 AddSub256,InitVesa2,cbitmode,cvidmode,makepal
EXTSYM scanlines,selcA000,vesa2_bits,vesa2_bpos,vesa2_clbit
EXTSYM vesa2_gpos,vesa2_rpos,vesa2_usbit,vesa2_x,vesa2_y
EXTSYM vesa2selec,InitVesa12,videotroub
NEWSYM clearfilter, dw 0
NEWSYM res640, db 0
NEWSYM res480, db 0
NEWSYM dosinitvideo2
jmp dosinitvideo.noaddsub
;*******************************************************
; InitVideo
;*******************************************************
NEWSYM dosinitvideo
mov byte[cbitmode],0
mov byte[res640],0
mov byte[res480],0
cmp byte[cvidmode],0
je near .initmodex
cmp byte[cvidmode],1
je near .initmodeq
cmp byte[cvidmode],2
je near .initvesa2320x240x8
cmp byte[cvidmode],3
je near .initvesa2320x240x16
cmp byte[cvidmode],4
je near .initvesa2640x480x8
cmp byte[cvidmode],5
je near .initvesa2640x480x16
cmp byte[cvidmode],6
je near .initvesa2512x384x8
cmp byte[cvidmode],7
je near .initvesa2512x384x16
cmp byte[cvidmode],8
je near .initvesa12640x480x16
cmp byte[cvidmode],9
je near .initvesa2320x480x8
cmp byte[cvidmode],10
je near .initvesa2320x480x16
ret
;*******************************************************
; InitModeX Sets up 320x240 unchained mode
;*******************************************************
.initmodex
mov byte[cbitmode],0
mov ax,0013h
int 10h
mov dx,03C4h
mov ax,0604h
out dx,ax
mov dx,03D4h
mov ax,0E317h
out dx,ax
mov ax,0014h
out dx,ax
mov dx,03C4h
mov ax,0F02h
out dx,ax
mov dx,03C2h
mov al,0E3h
out dx,al
mov dx,03D4h
mov ax,2C11h
out dx,ax
mov ax,0D06h
out dx,ax
mov ax,3E07h
out dx,ax
mov ax,0EA10h
out dx,ax
mov ax,0AC11h
out dx,ax
mov ax,0DF12h
out dx,ax
mov ax,0E715h
out dx,ax
mov ax,0616h
out dx,ax
mov dx,03C6h
mov al,0FFh
out dx,al
mov dx,03C4h
; select all 4 planes and clear
mov ax,0F02h
out dx,ax
push es
mov ax,[selcA000]
mov es,ax
xor edi,edi
mov ecx,65536/4
xor eax,eax
rep stosd
pop es
call makepal
ret
;*******************************************************
; InitModeQ Sets up 256x256 chained mode
;*******************************************************
.initmodeq
mov byte[cbitmode],0
cmp byte[AddSub256],1
jne .noaddsub
mov byte[cbitmode],1
.noaddsub
mov byte[vesa2_rpos],11 ; Red bit position 128,256,512,1024,2048
mov byte[vesa2_gpos],6 ; Green bit position 2^6 = 64
mov byte[vesa2_bpos],0 ; Blue bit position
mov word[vesa2_usbit],0020h ; Unused bit in proper bit location
mov word[vesa2_clbit],0F7DFh ; clear all bit 0's if AND is used
mov word[clearfilter],0F7DFh ; Filter out unnecessary bits
cmp byte[scanlines],1
je near .scanlines
mov ax,0013h
int 10h
mov dx,03D4h
mov al,11h
out dx,al
inc dx
in al,dx
and al,7Fh
mov ah,al
dec dx
mov al,11h
out dx,al
inc dx
mov al,ah
out dx,al
mov dx,03C2h
mov al,0E3h
out dx,al
mov dx,03D4h
mov ax,5F00h
out dx,ax
mov ax,3F01h
out dx,ax
mov ax,4002h
out dx,ax
mov ax,8203h
out dx,ax
mov ax,4A04h
out dx,ax
mov ax,9A05h
out dx,ax
mov ax,2306h
out dx,ax
mov ax,0B207h
out dx,ax
mov ax,0008h
out dx,ax
mov ax,6109h
out dx,ax
mov ax,0A10h
out dx,ax
mov ax,0AC11h
out dx,ax
mov ax,0FF12h
out dx,ax
mov ax,2013h
out dx,ax
mov ax,4014h
out dx,ax
mov ax,0715h
out dx,ax
mov ax,1A16h
out dx,ax
mov ax,0A317h
out dx,ax
mov dx,03C4h
mov ax,0101h
out dx,ax
mov ax,0E04h
out dx,ax
mov dx,03CEh
mov ax,4005h
out dx,ax
mov ax,0506h
out dx,ax
mov dx,03DAh
in al,dx
mov dx,03C0h
mov al,30h
out dx,al
mov al,41h
out dx,al
mov dx,03DAh
in al,dx
mov dx,03C0h
mov al,33h
out dx,al
mov al,0h
out dx,al
mov dx,03C6h
mov al,0FFh
out dx,al
cmp byte[cbitmode],1
je .nopal
call makepal
.nopal
; clear screen
push es
mov ax,[selcA000]
mov es,ax
xor edi,edi
mov ecx,256*64
xor eax,eax
rep stosd
pop es
ret
.scanlines
mov ax,0013h
int 10h
mov dx,03D4h
mov al,11h
out dx,al
inc dx
in al,dx
and al,7Fh
mov ah,al
dec dx
mov al,11h
out dx,al
inc dx
mov al,ah
out dx,al
mov dx,03C2h
mov al,0E3h
out dx,al
mov dx,03D4h
mov ax,5F00h
out dx,ax
mov ax,3F01h
out dx,ax
mov ax,4002h
out dx,ax
mov ax,8203h
out dx,ax
mov ax,4A04h
out dx,ax
mov ax,9A05h
out dx,ax
mov ax,2306h
out dx,ax
mov ax,01D07h
out dx,ax
mov ax,0008h
out dx,ax
mov ax,6009h
out dx,ax
mov ax,0A10h
out dx,ax
mov ax,0AC11h
out dx,ax
mov ax,0FF12h
out dx,ax
mov ax,2013h
out dx,ax
mov ax,4014h
out dx,ax
mov ax,0715h
out dx,ax
mov ax,1A16h
out dx,ax
mov ax,0A317h
out dx,ax
mov dx,03C4h
mov ax,0101h
out dx,ax
mov ax,0E04h
out dx,ax
mov dx,03CEh
mov ax,4005h
out dx,ax
mov ax,0506h
out dx,ax
mov dx,03DAh
in al,dx
mov dx,03C0h
mov al,30h
out dx,al
mov al,41h
out dx,al
mov dx,03DAh
in al,dx
mov dx,03C0h
mov al,33h
out dx,al
mov al,0h
out dx,al
mov dx,03C6h
mov al,0FFh
out dx,al
cmp byte[cbitmode],1
je .nopalb
call makepal
.nopalb
; clear screen
push es
mov ax,[selcA000]
mov es,ax
xor edi,edi
mov ecx,256*64
xor eax,eax
rep stosd
pop es
ret
;*******************************************************
; InitVESA2 320x240x8 Set up Linear 320x240x8b
;*******************************************************
.initvesa2320x240x8
mov byte[cbitmode],0
mov word[vesa2_x],320
mov word[vesa2_y],240
mov byte[vesa2_bits],8
call InitVesa2
cmp byte[videotroub],1
jne .notrouble
ret
.notrouble
call makepal
; clear screen (320*240 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,320*240
.loop
mov byte[es:edi],0
inc edi
dec ecx
jnz .loop
pop es
ret
;*******************************************************
; InitVESA2 320x240x16 Set up Linear 320x240x16b
;*******************************************************
.initvesa2320x240x16
mov byte[cbitmode],1
mov word[vesa2_x],320
mov word[vesa2_y],240
mov byte[vesa2_bits],16
call InitVesa2
cmp byte[videotroub],1
jne .notrouble2
ret
.notrouble2
; clear screen (320*240*2 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,320*240*2
.loopb
mov byte[es:edi],0
inc edi
dec ecx
jnz .loopb
pop es
ret
;*******************************************************
; InitVESA2 640x480x8 Set up Linear 640x480x8b
;*******************************************************
.initvesa2640x480x8
mov byte[res640],1
mov byte[res480],1
mov word[vesa2_x],640
mov word[vesa2_y],480
mov byte[vesa2_bits],8
call InitVesa2
cmp byte[videotroub],1
jne .notrouble3
ret
.notrouble3
call makepal
; clear screen (640*480 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,640*480
.loopc3
mov byte[es:edi],0
inc edi
dec ecx
jnz .loopc3
pop es
ret
;*******************************************************
; InitVESA2 640x480x16 Set up Linear 640x480x16b
;*******************************************************
.initvesa2640x480x16
mov byte[res640],1
mov byte[res480],1
mov byte[cbitmode],1
mov word[vesa2_x],640
mov word[vesa2_y],480
mov byte[vesa2_bits],16
call InitVesa2
cmp byte[videotroub],1
jne .notrouble4
ret
.notrouble4
; clear screen (640*480*2 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,640*480*2
.loopd3
mov byte[es:edi],0
inc edi
dec ecx
jnz .loopd3
pop es
ret
;*******************************************************
; InitVESA2 320x480x8 Set up Linear 320x480x8b
;*******************************************************
.initvesa2320x480x8
mov byte[res480],1
mov word[vesa2_x],320
mov word[vesa2_y],480
mov byte[vesa2_bits],8
call InitVesa2
cmp byte[videotroub],1
jne .notrouble5
ret
.notrouble5
call makepal
; clear screen (320*480 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,320*480
.loopc
mov byte[es:edi],0
inc edi
dec ecx
jnz .loopc
pop es
ret
;*******************************************************
; InitVESA2 320x480x16 Set up Linear 320x480x16b
;*******************************************************
.initvesa2320x480x16
mov byte[res480],1
mov byte[cbitmode],1
mov word[vesa2_x],320
mov word[vesa2_y],480
mov byte[vesa2_bits],16
call InitVesa2
cmp byte[videotroub],1
jne .notrouble6
ret
.notrouble6
; clear screen (320*480*2 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,320*480*2
.loopd
mov byte[es:edi],0
inc edi
dec ecx
jnz .loopd
pop es
ret
;*******************************************************
; InitVESA2 512x384x8 Set up Linear 512x384x8b
;*******************************************************
.initvesa2512x384x8
mov byte[res640],2
mov word[vesa2_x],512
mov word[vesa2_y],384
mov byte[vesa2_bits],8
call InitVesa2
cmp byte[videotroub],1
jne .notrouble7
ret
.notrouble7
call makepal
; clear screen (512*384 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,512*384
.loope
mov byte[es:edi],0
inc edi
dec ecx
jnz .loope
pop es
ret
;*******************************************************
; InitVESA2 512x384x16 Set up Linear 512x384x16b
;*******************************************************
.initvesa2512x384x16
mov byte[res640],2
mov byte[cbitmode],1
mov word[vesa2_x],512
mov word[vesa2_y],384
mov byte[vesa2_bits],16
call InitVesa2
cmp byte[videotroub],1
jne .notrouble8
ret
.notrouble8
; clear screen (512*384*2 bytes)
push es
mov ax,[vesa2selec]
mov es,ax
mov edi,0
mov ecx,512*384*2
.loopf
mov byte[es:edi],0
inc edi
dec ecx
jnz .loopf
pop es
ret
;*******************************************************
; InitVESA1.2 640x480x16 Set up 640x480x16b
;*******************************************************
.initvesa12640x480x16
mov byte[res640],1
mov byte[cbitmode],1
mov word[vesa2_x],640
mov word[vesa2_y],480
mov byte[vesa2_bits],16
call InitVesa12
ret
; clear screen (640*480*2 bytes)
push es
mov ax,[selcA000]
mov es,ax
mov ebx,9
xor edx,edx
.loopbanks
xor edi,edi
mov ecx,16384
.loopg
mov byte[es:edi],0
inc edi
dec ecx
jnz .loopg
dec ebx
jnz .loopbanks
mov ecx,6144
pop es
ret


1617
zsnes/src/dos/joy.asm Normal file

File diff suppressed because it is too large Load Diff

437
zsnes/src/dos/modemrtn.asm Normal file
View File

@@ -0,0 +1,437 @@
;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


226
zsnes/src/dos/sw.asm Normal file
View File

@@ -0,0 +1,226 @@
;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 SidewinderFix
%macro ParityCheckSW 1
mov ecx,ebx
xor cl,ch
jpe %%ParChkSW
mov [%1],ebx
%%ParChkSW:
%endmacro
section .data
gDump times 256 db 0
bDump times 128 db 0
NEWSYM _SW1, dd 0
NEWSYM _SW2, dd 0
NEWSYM _SW3, dd 0
NEWSYM _SW4, dd 0
NEWSYM _SWCount, dd 0
section .text
NEWSYM _readSideWinder
pushad
mov ecx,200
mov ebx,gDump
cli
cmp byte[SidewinderFix],0
je .write
out dx,al
.write
GetSWDataLoop:
cmp byte[SidewinderFix],0
jne .nowrite
out dx,al
.nowrite
nop
nop
nop
nop
nop
nop
in al,dx
mov [ebx],al
inc ebx
dec ecx
jnz GetSWDataLoop
sti
xor ebx,ebx
xor ecx,ecx
xor edi,edi
mov esi,1
FindCycle:
mov al,[gDump+edi]
inc edi
cmp edi,200
je SMWError
test al,00010000b
jnz WMFCS1
xor ecx,ecx
jmp FindCycle
WMFCS1:
inc ecx
cmp ecx,15
jne FindCycle
xor ebp,ebp
FindStrobeLow:
mov al,[gDump+edi]
inc edi
cmp edi,200
je SMWError
test al,00010000b
jnz FindStrobeLow
xor ecx,ecx
FindStrobeHigh:
inc ecx
cmp ecx,15
je SWModeCheck
mov al,[gDump+edi]
inc edi
cmp edi,200
je SMWError
test al,00010000b
jz FindStrobeHigh
mov [bDump+ebp],al
inc ebp
jmp FindStrobeLow
SMWDone:
popad
mov eax,0
ret
SMWError:
popad
mov eax,1
ret
SWModeCheck:
cmp ebp,5
je near ModeB1
cmp ebp,15
je near ModeA1
cmp ebp,10
je near ModeB2
cmp ebp,30
je near ModeA2
cmp ebp,45
je near ModeA3
cmp ebp,20
je near ModeB4
cmp ebp,60
je near ModeA4
jmp short SMWError
ModeA1:
cmp dword [_SWCount],3
je near ModeB3
xor ebp,ebp
call DoModeA
ParityCheckSW _SW1
jmp SMWDone
ModeA4:
mov ebp,45
call DoModeA
ParityCheckSW _SW4
ModeA3:
mov ebp,30
call DoModeA
ParityCheckSW _SW3
ModeA2:
mov ebp,15
call DoModeA
ParityCheckSW _SW2
xor ebp,ebp
call DoModeA
ParityCheckSW _SW1
jmp SMWDone
ModeB4:
mov ebp,15
call DoModeB
ParityCheckSW _SW4
ModeB3:
mov ebp,10
call DoModeB
ParityCheckSW _SW3
ModeB2:
mov ebp,5
call DoModeB
ParityCheckSW _SW2
ModeB1:
xor ebp,ebp
call DoModeB
ParityCheckSW _SW1
jmp SMWDone
DoModeB:
xor ebx,ebx
mov eax,2
mov ecx,5
add ebp,bDump
ModeBLoop:
test byte [ebp],00100000b
jnz $+4
or ebx,eax
shl eax,1
test byte [ebp],01000000b
jnz $+4
or ebx,eax
shl eax,1
test byte [ebp],10000000b
jnz $+4
or ebx,eax
shl eax,1
inc ebp
dec ecx
jnz ModeBLoop
ret
DoModeA:
xor ebx,ebx
mov eax,2
mov ecx,15
add ebp,bDump
ModeALoop:
test byte [ebp],00100000b
jnz $+4
or ebx,eax
shl eax,1
inc ebp
dec ecx
jnz ModeALoop
ret


330
zsnes/src/dos/sw32.asm Normal file
View File

@@ -0,0 +1,330 @@
;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.
;32-bit DOS-Mode driver for the Microsoft Sidewinder Gamepad
;Multi-SW Version 1.5
;(C) 1997, 1998 Robert William Grubbs, All Rights Reserved
;Latest revision 1/20/98
; Driver Source code Include file
;C-linkable, rewrote decoder -sardu
;Flat memory mode (Protected mode extender required! Tested with DOS32)
;Tested with TASM 4.0+
SW1 dd 0 ;SW #1's button status
SW2 dd 0 ;SW #2's button status
SW3 dd 0 ;SW #3's button status
SW4 dd 0 ;SW #4's button status
SWCount dd 1 ;Tell the driver how many sidewinders are present
SWSetup dd 0 ;Tell the driver what polling mode to use
; 0=Interrupts disabled, Multiple OUT statements
; 1=Interrupts disabled, Single OUT statement
; 2=Interrupts enabled, Multiple OUT statements
; 3=Interrupts enabled, Single OUT statement
gDump times 100h db 0 ;SW Status dump buffer (space for 256 bytes, uses 200)
bDump times 80h db 0 ;buffer to hold button data (Modes A and B, all SW)
;This macro calculates parity for the buttons and compares it to the SW's
; parity bit. If they don't match, the button data is discarded.
%macro ParityCheckSW 1
mov ecx,ebx ;duplicate button status
xor cl,ch ;
jpe %%ParChkSW
mov [%1],ebx ;update button status for SW #n
%%ParChkSW ;done
%endmacro
;The main subroutine; this is the important one; bow down before it
;IN: None
;Out: SWx=buttons (bit 0=null 1=up 2=dn 3=rt 4=lt 5=A 6=B 7=C 8=X)
; (9=Y 10=Z 11=L 12=R 13=St 14=M 15=Parity)
;No registers destroyed
readSideWinder:
pushad
mov ecx,200 ;dump buffer fill size
mov ebx,gDump ;initial dump pointer
mov edx,0201h ;joystick port
cmp dword[SWSetup],0
jne NotSW0
cli ;Disable interrupts (required to avoid jitter)
GetSWDataLoop: ;
out dx,al ;trigger joystick port
in al,dx ;read SW status byte
mov [ebx],al ;dump status byte
inc ebx ;increment dump pointer
dec ecx
jnz GetSWDataLoop
sti ;Re-enable interrupts
jmp SWPollDone
NotSW0:
cmp dword[SWSetup],1
jne NotSW1
cli ;Disable interrupts (required to avoid jitter)
out dx,al ;trigger joystick port
GetSWDataLoop1: ;
in al,dx ;read SW status byte
mov [ebx],al ;dump status byte
inc ebx ;increment dump pointer
dec ecx
jnz GetSWDataLoop1
sti ;Re-enable interrupts
jmp SWPollDone
NotSW1:
cmp dword[SWSetup],2
jne NotSW2
GetSWDataLoop2: ;
out dx,al ;trigger joystick port
in al,dx ;read SW status byte
mov [ebx],al ;dump status byte
inc ebx ;increment dump pointer
dec ecx
jnz GetSWDataLoop2
jmp SWPollDone
NotSW2:
;default all others to SWStatus=3
out dx,al ;trigger joystick port
GetSWDataLoop3: ;
in al,dx ;read SW status byte
mov [ebx],al ;dump status byte
inc ebx ;increment dump pointer
dec ecx
jnz GetSWDataLoop3
SWPollDone:
mov ecx,0 ;tick count
mov esi,1 ;initialize output mask
mov ebx,0 ;initialize output
mov edi,0 ;initialize input pointer
;My current method of cycle detection is to look for 15 highs in a row on
; the strobe line. Cycle ends is detected by 15 lows in a row.
;Mode A has 15 strobes in a cycle, Mode B has 5.
; Note that the 15 highs/lows for cycle detection may be too high for slow
; machines. I havn't seen a problem yet, but it may exist...
;Multiple Sidewinder data complicates things. Each additional SW tags
; another set of strobes to the cycle, 5 more in mode B, 15 more in mode A.
; Detecting extra SW gamepad data is fairly simple: count the number of
; strobes. If it is a multiple of 5, you're in mode B and can divide by 5
; to get the total number of gamepads. If it's divisible by 15, use mode A.
; However, this method cannot distinguish between mode A for one SW and mode
; B for three SW. In that case, the SWCount variable must be set correctly.
FindCycle:
mov al,[gDump+edi] ;get next status byte
inc edi ;increment input pointer
cmp edi,200 ;test for end of status block
je SWNoFind ;if it's the end, quit sub with error
test al,00010000b ;Check for nonzero bits
jnz WMFCS1 ;
xor ecx,ecx ;if zero, reset tick count
jmp FindCycle ;can't be pre-cycle
WMFCS1: ;Possibly pre-cycle
inc ecx ;increment tick count
cmp ecx,15 ;test for sufficient ticks for cycle start
jne FindCycle ;if insufficient, get next status byte
;Yippie! it found a (probable) cycle!
mov ebp,0 ;initialize bDump index (strobe count)
FindStrobeLow: ;Search for leading edge of data strobe
mov al,[gDump+edi] ;get next status byte
inc edi ;increment input pointer
cmp edi,200 ;test for end of status block
je SWNoFind ;if it's the end, quit sub with error
test al,00010000b ;get "strobe" bit
jnz SHORT FindStrobeLow ;if it isn't zero, we're not there yet
xor ecx,ecx ;initialize cycle end test count
FindStrobeHigh:
inc ecx ;increment zero count
cmp ecx,0fh ;is it 15?
je SWModeCheck ;if so, goto mode check
mov al,[gDump+edi] ;get next status byte
inc edi ;increment input pointer
cmp edi,200 ;test for end of status block
je SWNoFind ;if it's the end, quit sub with error
test al,00010000b ;get "strobe" bit
jz FindStrobeHigh ;if it is zero, we're not there yet
;if not, we're there! data bit is valid (probably)
mov [bDump+ebp],al ;preserve data for button decoding
inc ebp ;increment strobe count/bDump index
jmp FindStrobeLow ;wait for the next button
SMWDone:
SWNoFind:
popad
ret ;return to calling procedure
SWModeCheck: ;Check strobe count to identify mode and # of SW
cmp ebp,15 ;Is it Mode A with 1 Sidewinder or B with 3?
je ModeA1
cmp ebp,5 ;Is it Mode B with 1 Sidewinders?
je ModeB1
cmp ebp,30 ;Is it Mode A with 2 Sidewinders?
je ModeA2
cmp ebp,10 ;Is it Mode B with 2 Sidewinders?
je near ModeB2
cmp ebp,45 ;Is it Mode A with 3 Sidewinders?
je near ModeA3
cmp ebp,60 ;Is it Mode A with 4 Sidewinders?
je near ModeA4
cmp ebp,20 ;Is it Mode B with 4 Sidewinders?
je near ModeB4
jmp SHORT SWNoFind ;Any other # of strobes is invalid data
ModeB1:
xor ebp,ebp
call DoModeB
ParityCheckSW SW1
jmp SMWDone
ModeA1:
cmp dword [SWCount],3
je near ModeB3
xor ebp,ebp
call DoModeA
ParityCheckSW SW1
jmp SMWDone
ModeA2:
xor ebp,ebp
call DoModeA
ParityCheckSW SW1
mov ebp,15
call DoModeA
ParityCheckSW SW2
jmp SMWDone
ModeA3:
xor ebp,ebp
call DoModeA
ParityCheckSW SW1
mov ebp,15
call DoModeA
ParityCheckSW SW2
mov ebp,30
call DoModeA
ParityCheckSW SW3
jmp SMWDone
ModeA4:
xor ebp,ebp
call DoModeA
ParityCheckSW SW1
mov ebp,15
call DoModeA
ParityCheckSW SW2
mov ebp,30
call DoModeA
ParityCheckSW SW3
mov ebp,45
call DoModeA
ParityCheckSW SW4
jmp SMWDone
ModeB2:
xor ebp,ebp
call DoModeB
ParityCheckSW SW1
mov ebp,5
call DoModeB
ParityCheckSW SW2
jmp SMWDone
ModeB3:
xor ebp,ebp
call DoModeB
ParityCheckSW SW1
mov ebp,5
call DoModeB
ParityCheckSW SW2
mov ebp,10
call DoModeB
ParityCheckSW SW3
jmp SMWDone
ModeB4:
xor ebp,ebp
call DoModeB
ParityCheckSW SW1
mov ebp,5
call DoModeB
ParityCheckSW SW2
mov ebp,10
call DoModeB
ParityCheckSW SW3
mov ebp,15
call DoModeB
ParityCheckSW SW4
jmp SMWDone
ENDP
%macro SWRepeat 1
mov al,[bDump+ebp+%1]
shr al,5 ;get upper 3 bits
shl eax,1+3*%1 ;shift into place
or ebx,eax ;or into output
%endmacro
DoModeB:
xor ebx,ebx ;Initialize output
xor eax,eax
SWRepeat 0
SWRepeat 1
SWRepeat 2
SWRepeat 3
SWRepeat 4
xor ebx,0FFFEh
ret
DoModeA:
xor ebx,ebx ;Clear output
mov ecx,15 ;bit count
ALP:
mov al,[bDump+ebp]
inc ebp
shl al,3
rcr ebx,1
dec ecx
jg ALP
shr ebx,16
xor ebx,0FFFEh
ret


555
zsnes/src/dos/vesa12.asm Normal file
View File

@@ -0,0 +1,555 @@
;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 vesa2_usbit,vesa2_clbit,vesa2_clbitng,vesa2_clbitng2,vesa2_clbitng3
EXTSYM vesa2_x,vesa2_y,vesa2selec,vesa2_bits,vesa2_rpos,vesa2_gpos,vesa2_bpos
EXTSYM vesa2_rposng,vesa2_gposng,vesa2_bposng,vesa2_rtrcl,vesa2_rtrcla,vesa2_rfull
EXTSYM vesa2_gtrcl,vesa2_gtrcla,vesa2_gfull,vesa2_btrcl,vesa2_btrcla,vesa2_bfull
EXTSYM vesa2red10,dcolortab,videotroub,Change_Dir
EXTSYM genfulladdtab,genfulladdtabng,DosExit
EXTSYM InitDrive,gotoroot,InitDir,fulladdtab
; EXTSYM printnum,DosExit
EXTSYM LFBpointer,noblocks,bytesperscanline,vesamode,VESAmodelist
; add 0214h video mode
NEWSYM granularity, dw 0
NEWSYM granadd, dd 0
NEWSYM VESA12EXITTODOS
mov ax,0003h
int 10h
push edx
mov edx,.exitfromvesa12
mov ah,9
int 21h
pop edx
mov ah,9
int 21h
mov edx,.return
mov ah,9
int 21h
mov dl,[InitDrive]
mov ebx,InitDir
call Change_Dir
mov byte[videotroub],1
jmp DosExit
.exitfromvesa12 db 'Unable to Initialize VESA1.2 $'
.return db 10,13,'$'
;*******************************************************
; Set up Vesa 2
;*******************************************************
NEWSYM InitVesa12
;-------------------------------------------------;
; First - allocate some bytes in DOS memory for ;
; communication with VBE ;
;-------------------------------------------------;
mov eax,0100h
mov ebx,512/16 ; 512 bytes
int 31h ; Function 31h,100h - Allocate
; DOS memory (512 bytes)
jnc .gotmem
mov edx,.nomemmessage
jmp VESA12EXITTODOS
.nomemmessage
db ': Unable to locate DOS memory.$'
.gotmem
mov fs,dx ; FS now points to the DOS
; buffer
;--------------------------------------------------;
; Now, get information about the video card into ;
; a data structure ;
;--------------------------------------------------;
mov edi,RMREGS
mov dword[fs:0],'VBE1' ; Request VBE 2.0 info
mov dword[RMREGS.eax],4f00h
mov word[RMREGS.es],ax ; Real mode segment of DOS
; buffer
mov dword[RMREGS.edi],0
push es
push ds
pop es
mov eax,300h
mov ebx,10h
xor ecx,ecx
int 31h ; Simulate real mode interrupt
pop es
jnc .int1ok
mov edx,.noint1message
jmp VESA12EXITTODOS
.noint1message
db ': Simulated real mode interrupt failed.$'
.int1ok ; Real mode int successful!!!
mov eax,[RMREGS.eax]
cmp al,4fh ; Check vbe interrupt went OK
jz .vbedetected
mov edx,.novbemessage
jmp VESA12EXITTODOS
.novbemessage
db ': VBE not detected!!$'
.vbedetected
cmp dword[fs:0000],'VESA'
jz .vesadetected ; Check for presence of vesa
mov edx,.novesamessage
jmp VESA12EXITTODOS
.novesamessage
db ': VESA not detected!$'
.vesadetected
cmp word[fs:0004],102h
jae .vesa12detected ; Check we've got VESA 1.2 or greater
mov edx,.novesa2message
jmp VESA12EXITTODOS
.novesa2message
db ': VESA 1.2 or greater required!$'
;-----------------------------------------------------;
; OK - vesa 2.0 or greater has been detected. Copy ;
; mode information into VESAmodelist ;
;-----------------------------------------------------;
.vesa12detected
mov ax,[fs:12h] ; Get no. of 64k blocks
mov [noblocks],ax
mov ax, 2
mov bx,[fs:10h]
int 31h
jnc .wegottheselector
mov edx, .oopsnoselector
jmp VESA12EXITTODOS
.oopsnoselector
db ': Failed to allocate vesa display selector!$'
.wegottheselector
mov gs,ax
xor eax,eax
mov ebp,VESAmodelist
mov ecx,512
mov ax,[fs:0eh]
.loopcopymodes
mov bx,[gs:eax]
mov [ebp],bx
cmp bx,0ffffh
jz .copiedmodes
add ebp,2
add eax,2
dec ecx
jz .outofmodelistspace
jmp .loopcopymodes
.outofmodelistspace
mov edx,.outofmodelistspacemessage
jmp VESA12EXITTODOS
.outofmodelistspacemessage
db ': Out of VESA mode list space!$'
;----------------------------------------------;
; OK - Scan the mode list to find a matching ;
; mode for vesa2_x, vesa2_y and vesa2_depth ;
;----------------------------------------------;
.copiedmodes
mov ebp,VESAmodelist
xor ecx,ecx
.loopcheckmodes
mov cx, [ebp]
cmp cx, 0ffffh
jnz .notendoflist
mov edx,.endoflist
jmp VESA12EXITTODOS
.endoflist db ': VESA 1.2 mode does not work on your video card/driver.$'
.whichwin db 0
.notendoflist
mov edi, RMREGS
mov dword[RMREGS.eax],4f01h
mov dword[RMREGS.ebx],0
mov dword[RMREGS.ecx],ecx
mov dword[RMREGS.edi],0
push es
push ds
pop es
mov eax,300h
mov ebx,10h
xor ecx,ecx
int 31h ; Simulate real mode interrupt
pop es
jnc .modecheckok
mov edx,.modecheckfail
jmp VESA12EXITTODOS
.modecheckfail
db ': Real mode interrupt failure while checking vesa mode$'
.modecheckok
add ebp,2
test word[fs:0000h],1b
jz near .loopcheckmodes ; If mode is not available
;
; xor eax,eax
; mov ax,[fs:12h]
; call printnum
; mov ah,02h
; mov dl,'x'
; int 21h
; mov ax,[fs:14h]
; call printnum
; mov ah,02h
; mov dl,'x'
; int 21h
; xor ah,ah
; mov al,[fs:19h]
; call printnum
; mov ah,02h
; mov dl,13
; int 21h
; mov dl,10
; int 21h
mov eax,[vesa2_x]
cmp [fs:12h],ax ; Check that the height matches
jnz near .loopcheckmodes
mov eax,[vesa2_y]
cmp [fs:14h],ax ; Check that the width matches
jnz near .loopcheckmodes
mov al,[vesa2_bits]
cmp [fs:19h],al ; Check bits/pixel for match
jnz near .loopcheckmodes
; mov ah,07h
; int 21h
; D0 = Window supported
; 0 = Window is not supported
; 1 = Window is supported
; D1 = Window readable
; 0 = Window is not readable
; 1 = Window is readable
; D2 = Window writeable
; 0 = Window is not writeable
; 1 = Window is writeable
; D3-D7 = Reserved
mov byte[.whichwin],0
mov al,[fs:2] ; Get window A attributes
and al,0100b
cmp al,0100b
je .foundwin ; Mode supported
mov al,[fs:3] ; Get window B attributes
and al,0100b
cmp al,0100b
jne .foundwin ; Mode not supported
mov byte[.whichwin],1
.foundwin
; Success - a match has been found!!
sub ebp,2
mov ax,[ebp]
mov [vesamode],ax ; Store vesa 1.2 mode number
; and eax,0FFFFh
; push eax
; mov ax,0003h
; int 10h
; pop eax
; call printnum
; jmp DosExit
mov ax,[fs:10h]
mov byte[vesa2red10],0
mov byte[vesa2_rposng],11
mov byte[vesa2_gposng],6
mov byte[vesa2_bposng],0
mov dword[vesa2_clbitng],1111011111011110b
mov dword[vesa2_clbitng2],11110111110111101111011111011110b
mov dword[vesa2_clbitng2+4],11110111110111101111011111011110b
mov dword[vesa2_clbitng3],0111101111101111b
mov [bytesperscanline],ax ; Store bytes per scan line
cmp byte[fs:20h],10
jne .nored10
mov byte[fs:20h],11
mov byte[vesa2red10],1
mov byte[vesa2_rposng],10
mov byte[vesa2_gposng],5
mov dword[vesa2_clbitng],0111101111011110b
mov dword[vesa2_clbitng2],01111011110111100111101111011110b
mov dword[vesa2_clbitng2+4],01111011110111100111101111011110b
mov dword[vesa2_clbitng3],0011110111101111b
.nored10
; fix up bit lengths
mov al,16
sub al,[fs:20h]
mov ah,[fs:22h]
sub ah,[fs:20h]
mov bl,[fs:24h]
sub bl,[fs:20h]
mov bh,al
cmp bh,ah
jb .scheck1
mov bh,ah
.scheck1
cmp bh,bl
jb .scheck2
mov bh,bl
.scheck2
mov byte[fs:19h],5
mov al,16
sub al,[fs:22h]
mov ah,[fs:20h]
sub ah,[fs:22h]
mov bl,[fs:24h]
sub bl,[fs:22h]
mov bh,al
cmp bh,ah
jb .scheck1b
mov bh,ah
.scheck1b
cmp bh,bl
jb .scheck2b
mov bh,bl
.scheck2b
mov [fs:21h],bh
mov al,16
sub al,[fs:24h]
mov ah,[fs:20h]
sub ah,[fs:24h]
mov bl,[fs:22h]
sub bl,[fs:24h]
mov bh,al
cmp bh,ah
jb .scheck1c
mov bh,ah
.scheck1c
cmp bh,bl
jb .scheck2c
mov bh,bl
.scheck2c
mov [fs:23h],bh
mov word[vesa2_clbit],0
cmp byte[fs:20h],10
jne .nottopbit
mov word[vesa2_usbit],8000h
.nottopbit
; Process Red Stuff
mov al,[fs:20h] ; bit sizes = [fs:19h,21h,23h]
mov cl,al
mov bx,1
shl bx,cl
cmp byte[fs:19h],6
jne .no6bit
mov [vesa2_usbit],bx
inc al
.no6bit
or [vesa2_clbit],bx
mov [vesa2_rpos],al
dec al
mov cl,al
mov bx,001Fh
cmp cl,0FFh
je .shrr
shl bx,cl
jmp .shlr
.shrr
shr bx,1
.shlr
mov word[vesa2_rfull],bx
add al,5
mov bx,1
mov cl,al
shl bx,cl
mov word[vesa2_rtrcl],bx
xor bx,0FFFFh
mov word[vesa2_rtrcla],bx
; Process Green Stuff
mov al,[fs:22h]
mov cl,al
mov bx,1
shl bx,cl
cmp byte[fs:21h],6
jne .no6bitb
mov [vesa2_usbit],bx
inc al
.no6bitb
or [vesa2_clbit],bx
mov [vesa2_gpos],al
dec al
mov cl,al
mov bx,001Fh
cmp cl,0FFh
je .shrg
shl bx,cl
jmp .shlg
.shrg
shr bx,1
.shlg
mov word[vesa2_gfull],bx
add al,5
mov bx,1
mov cl,al
shl bx,cl
mov word[vesa2_gtrcl],bx
xor bx,0FFFFh
mov word[vesa2_gtrcla],bx
; Process Blue Stuff
mov al,[fs:24h]
mov cl,al
mov bx,1
shl bx,cl
cmp byte[fs:23h],6
jne .no6bitc
mov [vesa2_usbit],bx
inc al
.no6bitc
or [vesa2_clbit],bx
mov [vesa2_bpos],al
dec al
mov cl,al
mov bx,001Fh
cmp cl,0FFh
je .shrb
shl bx,cl
jmp .shlb
.shrb
shr bx,1
.shlb
mov word[vesa2_bfull],bx
add al,5
mov bx,1
mov cl,al
shl bx,cl
mov word[vesa2_btrcl],bx
xor bx,0FFFFh
mov word[vesa2_btrcla],bx
xor word[vesa2_clbit],0FFFFh
mov ax,[fs:4]
mov [granularity],ax
xor edx,edx
mov ax,64
mov bx,[granularity]
div bx
mov [granadd],ax
;vesa2_rtrcl dw 0 ; red transparency clear (bit+4)
;vesa2_rtrcla dw 0 ; red transparency (AND) clear (not(bit+4))
;vesa2_rfull dw 0 ; red max (or (bit-1)*1Fh)
call genfulladdtab
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov ax,4f02h
mov bx,[vesamode]
int 10h ; Set the vesa mode
cmp ax,004fh
jz .modesetok
mov edx,.unableset
jmp VESA12EXITTODOS ; Failure!!!
.unableset db 'Unable to initialize video mode.$'
.modesetok
;******************************* EXTRA BIT ****************************
ret
; Check logical scanline length
mov eax,4f06h
mov ebx,1
int 10h
cmp cx,[vesa2_x]
je .correctwidth
mov eax,4f06h ; VBE Set/Get logical scan line
; length
mov ebx,0 ; Set scan line length in
; pixels
mov ecx, [vesa2_x] ; Desired screen width
int 10h
cmp ax,04fh
jz .correctwidth
mov edx, .unablescan
jmp VESA12EXITTODOS ; Failure!!!
.unablescan db 'Unable to set scan line length.$'
.correctwidth
ret
RMREGS
.edi dd 0
.esi dd 0
.ebp dd 0
.esp dd 0
.ebx dd 0
.edx dd 0
.ecx dd 0
.eax dd 0
.flags dw 0
.es dw 0
.ds dw 0
.fs dw 0
.gs dw 0
.ip dw 0
.cs dw 0
.sp dw 0
.ss dw 0
.spare times 20 dd 0


802
zsnes/src/dos/vesa2.asm Normal file
View File

@@ -0,0 +1,802 @@
;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 printnum
EXTSYM DosExit,ZSNESBase,Change_Dir,PrintStr,newengen
EXTSYM HalfTransB,HalfTransC
EXTSYM InitDrive,gotoroot,InitDir,fulladdtab
; EXTSYM printhex
; EXTSYM printhex
EXTSYM UnusedBit,HalfTrans,UnusedBitXor,ngrposng,nggposng,ngbposng
; EXTSYM printhex
EXTSYM Init_2xSaIMMX,Init_2xSaI
; add 0214h video mode
anticrash times 10 db 0
ALIGN32
NEWSYM vesa2_usbit, dd 0 ; Unused bit in proper bit location
NEWSYM vesa2_clbit, dd 0 ; clear all bit 0's if AND is used
NEWSYM vesa2_clbitng, dd 0 ; clear all bit 0's if AND is used
NEWSYM vesa2_clbitng2, dd 0,0 ; clear all bit 0's if AND is used
NEWSYM vesa2_clbitng3, dd 0 ; clear all bit 0's if AND is used
NEWSYM vesa2_x, dd 320 ; Desired screen width
NEWSYM vesa2_y, dd 240 ; Height
NEWSYM vesa2selec, dd 0 ; VESA2 Selector Location
NEWSYM vesa2_bits, dd 8 ; Bits per pixel
NEWSYM vesa2_rpos, dd 0 ; Red bit position
NEWSYM vesa2_gpos, dd 0 ; Green bit position
NEWSYM vesa2_bpos, dd 0 ; Blue bit position
NEWSYM vesa2_rposng, dd 0 ; Red bit position
NEWSYM vesa2_gposng, dd 0 ; Green bit position
NEWSYM vesa2_bposng, dd 0 ; Blue bit position
NEWSYM vesa2_rtrcl, dd 0 ; red transparency clear (bit+4)
NEWSYM vesa2_rtrcla, dd 0 ; red transparency (AND) clear (not(bit+4))
NEWSYM vesa2_rfull, dd 0 ; red max (or bit*1Fh)
NEWSYM vesa2_gtrcl, dd 0 ; red transparency clear (bit+4)
NEWSYM vesa2_gtrcla, dd 0 ; red transparency (AND) clear (not(bit+4))
NEWSYM vesa2_gfull, dd 0 ; red max (or bit*1Fh)
NEWSYM vesa2_btrcl, dd 0 ; red transparency clear (bit+4)
NEWSYM vesa2_btrcla, dd 0 ; red transparency (AND) clear (not(bit+4))
NEWSYM vesa2_bfull, dd 0 ; red max (or bit*1Fh)
NEWSYM vesa2red10, dd 0 ; red position at bit 10
NEWSYM videotroub, dd 0 ; red position at bit 10
NEWSYM vesa3en, dd 0
NEWSYM VESAAddr, dd 0
NEWSYM ExitFromGUI, db 0
NEWSYM ErrorPointer, dd 0
NEWSYM TripBufAvail, db 0
NEWSYM dcolortab, times 256 dd 0
NEWSYM genfulladdtab
; Write to buffer
cmp byte[newengen],1
jne .notneweng
cmp byte[vesa2red10],0
jne near genfulladdtabred
.notneweng
xor ecx,ecx
.loopers
mov ax,cx
test [vesa2_rtrcl],cx
jz .nor
and ax,[vesa2_rtrcla]
or ax,[vesa2_rfull]
.nor
test [vesa2_gtrcl],cx
jz .nog
and ax,[vesa2_gtrcla]
or ax,[vesa2_gfull]
.nog
test [vesa2_btrcl],cx
jz .nob
and ax,[vesa2_btrcla]
or ax,[vesa2_bfull]
.nob
shl ax,1
mov [fulladdtab+ecx*2],ax
dec cx
jnz .loopers
ret
NEWSYM genfulladdtabred
NEWSYM genfulladdtabng
; Write to buffer
xor ecx,ecx
.loopers
mov ax,cx
test cx,0100000000000000b
jz .nor
and ax,1011111111111111b
or ax, 0011110000000000b
.nor
test cx,0000001000000000b
jz .nog
and ax,1111110111111111b
or ax, 0000000111100000b
.nog
test cx,0000000000010000b
jz .nob
and ax,1111111111101111b
or ax, 0000000000001111b
.nob
shl ax,1
mov [fulladdtab+ecx*2],ax
dec cx
jnz .loopers
ret
NEWSYM VESA2EXITTODOS
mov byte[videotroub],1
cmp byte[ExitFromGUI],0
je .nogui
mov [ErrorPointer],edx
ret
.nogui
mov ax,0003h
int 10h
push edx
mov edx,.exitfromvesa2
call PrintStr
pop edx
call PrintStr
mov edx,.return
call PrintStr
mov dl,[InitDrive]
mov ebx,InitDir
call Change_Dir
jmp DosExit
.exitfromvesa2 db 'Unable to Initialize VESA2 : ',0
.return db 10,13,0
;*******************************************************
; Set up Vesa 2
;*******************************************************
NEWSYM InitVesa2
;-------------------------------------------------;
; First - allocate some bytes in DOS memory for ;
; communication with VBE ;
;-------------------------------------------------;
mov eax,0100h
mov ebx,512/16 ; 512 bytes
int 31h ; Function 31h,100h - Allocate
; DOS memory (512 bytes)
jnc .gotmem
mov edx,.nomemmessage
jmp VESA2EXITTODOS
.nomemmessage
db 'Unable to locate DOS memory.',0
.gotmem
mov fs,dx ; FS now points to the DOS
; buffer
;--------------------------------------------------;
; Now, get information about the video card into ;
; a data structure ;
;--------------------------------------------------;
mov edi,RMREGS
mov dword[fs:0],'VBE2' ; Request VBE 2.0 info
mov dword[RMREGS.eax],4f00h
mov word[RMREGS.es],ax ; Real mode segment of DOS
; buffer
mov dword[RMREGS.edi],0
push es
push ds
pop es
mov eax,300h
mov ebx,10h
xor ecx,ecx
int 31h ; Simulate real mode interrupt
pop es
jnc .int1ok
mov edx,.noint1message
jmp VESA2EXITTODOS
.noint1message
db 'Simulated real mode interrupt failed.',0
.int1ok ; Real mode int successful!!!
mov eax,[RMREGS.eax]
cmp al,4fh ; Check vbe interrupt went OK
jz .vbedetected
mov edx,.novbemessage
jmp VESA2EXITTODOS
.novbemessage
db 'VBE not detected!!',0
.vbedetected
cmp dword[fs:0000],'VESA'
jz .vesadetected ; Check for presence of vesa
mov edx,.novesamessage
jmp VESA2EXITTODOS
.novesamessage
db 'VESA not detected!',0
.vesadetected
cmp word[fs:0004],200h
jae .vesa2detected ; Check we've got VESA 2.0 or greater
mov edx,.novesa2message
jmp VESA2EXITTODOS
.novesa2message
db 'VESA 2.0 or greater required!',0
;-----------------------------------------------------;
; OK - vesa 2.0 or greater has been detected. Copy ;
; mode information into VESAmodelist ;
;-----------------------------------------------------;
.vesa2detected
mov dword[vesa3en],0
cmp word[fs:004],300h
jb .notvbe3
mov dword[vesa3en],1
.notvbe3
mov ax,[fs:12h] ; Get no. of 64k blocks
mov [noblocks],ax
mov ax, 2
mov bx,[fs:10h]
int 31h
jnc .wegottheselector
mov edx, .oopsnoselector
jmp VESA2EXITTODOS
.oopsnoselector
db 'Failed to allocate vesa display selector!',0
.wegottheselector
mov gs,ax
xor eax,eax
mov ebp,VESAmodelist
mov ecx,512
mov ax,[fs:0eh]
.loopcopymodes
mov bx,[gs:eax]
mov [ebp],bx
cmp bx,0ffffh
jz .copiedmodes
add ebp,2
add eax,2
dec ecx
jz .outofmodelistspace
jmp .loopcopymodes
.outofmodelistspace
mov edx,.outofmodelistspacemessage
jmp VESA2EXITTODOS
.outofmodelistspacemessage
db 'Out of VESA2 mode list space!',0
;----------------------------------------------;
; OK - Scan the mode list to find a matching ;
; mode for vesa2_x, vesa2_y and vesa2_depth ;
;----------------------------------------------;
.copiedmodes
mov ebp,VESAmodelist
xor ecx,ecx
.loopcheckmodes
mov cx, [ebp]
cmp cx, 0ffffh
jnz .notendoflist
mov edx,.endoflist
jmp VESA2EXITTODOS
.endoflist db 'This VESA2 mode does not work on your video card / driver.',0
.whichwin db 0
.notendoflist
mov edi, RMREGS
mov dword[RMREGS.eax],4f01h
mov dword[RMREGS.ebx],0
mov dword[RMREGS.ecx],ecx
mov dword[RMREGS.edi],0
push es
push ds
pop es
mov eax,300h
mov ebx,10h
xor ecx,ecx
int 31h ; Simulate real mode interrupt
pop es
jnc .modecheckok
mov edx,.modecheckfail
jmp VESA2EXITTODOS
.modecheckfail
db 'Real mode interrupt failure while checking vesa mode',0
.modecheckok
add ebp,2
test word[fs:0000h],1b
jz near .loopcheckmodes ; If mode is not available
;
; xor eax,eax
; mov ax,[fs:12h]
; call printnum
; mov ah,02h
; mov dl,'x'
; int 21h
; mov ax,[fs:14h]
; call printnum
; mov ah,02h
; mov dl,'x'
; int 21h
; xor ah,ah
; mov al,[fs:19h]
; call printnum
; mov ah,02h
; mov dl,13
; int 21h
; mov dl,10
; int 21h
mov eax,[vesa2_x]
cmp [fs:12h],ax ; Check that the height matches
jnz near .loopcheckmodes
mov eax,[vesa2_y]
cmp [fs:14h],ax ; Check that the width matches
jnz near .loopcheckmodes
mov al,[vesa2_bits]
cmp [fs:19h],al ; Check bits/pixel for match
jnz near .loopcheckmodes
; mov ax,3
; int 10h
; xor eax,eax
; mov ax,[fs:0h]
; call printnum
; jmp DosExit
mov byte[TripBufAvail],1
test word[fs:0000h],400h
jz .notbuf
mov byte[TripBufAvail],1
.notbuf
; jz .notvesa3
; xor eax,eax
; mov ax,[fs:0000h]
; call printhex
; jmp DosExit
.notvesa3
; mov ah,07h
; int 21h
; D0 = Window supported
; 0 = Window is not supported
; 1 = Window is supported
; D1 = Window readable
; 0 = Window is not readable
; 1 = Window is readable
; D2 = Window writeable
; 0 = Window is not writeable
; 1 = Window is writeable
; D3-D7 = Reserved
mov byte[.whichwin],0
mov al,[fs:2] ; Get window A attributes
and al,0100b
cmp al,0100b
je .foundwin ; Mode supported
mov al,[fs:3] ; Get window B attributes
and al,0100b
cmp al,0100b
jne .foundwin ; Mode not supported
mov byte[.whichwin],1
.foundwin
; Success - a match has been found!!
sub ebp,2
mov ax,[ebp]
mov [vesamode],ax ; Store vesa 2 mode number
; call printhex
; jmp DosExit
mov ax,[fs:10h]
mov byte[vesa2red10],0
mov byte[vesa2_rposng],11
mov byte[vesa2_gposng],6
mov byte[vesa2_bposng],0
mov dword[vesa2_clbitng],1111011111011110b
mov dword[vesa2_clbitng2],11110111110111101111011111011110b
mov dword[vesa2_clbitng2+4],11110111110111101111011111011110b
mov dword[vesa2_clbitng3],0111101111101111b
mov [bytesperscanline],ax ; Store bytes per scan line
cmp byte[fs:20h],10
jne near .nored10
mov byte[fs:20h],11
mov byte[vesa2red10],1
mov byte[vesa2_rposng],10
mov byte[vesa2_gposng],5
mov dword[vesa2_clbitng],0111101111011110b
mov dword[vesa2_clbitng2],01111011110111100111101111011110b
mov dword[vesa2_clbitng2+4],01111011110111100111101111011110b
mov dword[vesa2_clbitng3],0011110111101111b
mov dword[UnusedBit], 10000000000000001000000000000000b
mov dword[HalfTrans], 01111011110111100111101111011110b
mov dword[UnusedBitXor], 01111111111111110111111111111111b
mov dword[UnusedBit+4], 10000000000000001000000000000000b
mov dword[HalfTrans+4], 01111011110111100111101111011110b
mov dword[UnusedBitXor+4],01111111111111110111111111111111b
mov dword[HalfTransB], 00000100001000010000010000100001b
mov dword[HalfTransB+4], 00000100001000010000010000100001b
mov dword[HalfTransC], 01111011110111100111101111011110b
mov dword[HalfTransC+4], 01111011110111100111101111011110b
mov dword[ngrposng],10
mov dword[nggposng],5
mov dword[ngbposng],0
.nored10
; fix up bit lengths
mov al,16
sub al,[fs:20h]
mov ah,[fs:22h]
sub ah,[fs:20h]
mov bl,[fs:24h]
sub bl,[fs:20h]
mov bh,al
cmp bh,ah
jb .scheck1
mov bh,ah
.scheck1
cmp bh,bl
jb .scheck2
mov bh,bl
.scheck2
mov byte[fs:19h],5
mov al,16
sub al,[fs:22h]
mov ah,[fs:20h]
sub ah,[fs:22h]
mov bl,[fs:24h]
sub bl,[fs:22h]
mov bh,al
cmp bh,ah
jb .scheck1b
mov bh,ah
.scheck1b
cmp bh,bl
jb .scheck2b
mov bh,bl
.scheck2b
mov [fs:21h],bh
mov al,16
sub al,[fs:24h]
mov ah,[fs:20h]
sub ah,[fs:24h]
mov bl,[fs:22h]
sub bl,[fs:24h]
mov bh,al
cmp bh,ah
jb .scheck1c
mov bh,ah
.scheck1c
cmp bh,bl
jb .scheck2c
mov bh,bl
.scheck2c
mov [fs:23h],bh
mov word[vesa2_clbit],0
cmp byte[fs:20h],10
jne .nottopbit
mov word[vesa2_usbit],8000h
.nottopbit
; Process Red Stuff
mov al,[fs:20h] ; bit sizes = [fs:19h,21h,23h]
mov cl,al
mov bx,1
shl bx,cl
cmp byte[fs:19h],6
jne .no6bit
mov [vesa2_usbit],bx
inc al
.no6bit
or [vesa2_clbit],bx
mov [vesa2_rpos],al
dec al
mov cl,al
mov bx,001Fh
cmp cl,0FFh
je .shrr
shl bx,cl
jmp .shlr
.shrr
shr bx,1
.shlr
mov word[vesa2_rfull],bx
add al,5
mov bx,1
mov cl,al
shl bx,cl
mov word[vesa2_rtrcl],bx
xor bx,0FFFFh
mov word[vesa2_rtrcla],bx
; mov ax,03h
; int 10h
; mov ax,[vesa2_rfull]
; call printhex
; jmp DosExit
; Process Green Stuff
mov al,[fs:22h]
mov cl,al
mov bx,1
shl bx,cl
cmp byte[fs:21h],6
jne .no6bitb
mov [vesa2_usbit],bx
inc al
.no6bitb
or [vesa2_clbit],bx
mov [vesa2_gpos],al
dec al
mov cl,al
mov bx,001Fh
cmp cl,0FFh
je .shrg
shl bx,cl
jmp .shlg
.shrg
shr bx,1
.shlg
mov word[vesa2_gfull],bx
add al,5
mov bx,1
mov cl,al
shl bx,cl
mov word[vesa2_gtrcl],bx
xor bx,0FFFFh
mov word[vesa2_gtrcla],bx
; Process Blue Stuff
mov al,[fs:24h]
mov cl,al
mov bx,1
shl bx,cl
cmp byte[fs:23h],6
jne .no6bitc
mov [vesa2_usbit],bx
inc al
.no6bitc
or [vesa2_clbit],bx
mov [vesa2_bpos],al
dec al
mov cl,al
mov bx,001Fh
cmp cl,0FFh
je .shrb
shl bx,cl
jmp .shlb
.shrb
shr bx,1
.shlb
mov word[vesa2_bfull],bx
add al,5
mov bx,1
mov cl,al
shl bx,cl
mov word[vesa2_btrcl],bx
xor bx,0FFFFh
mov word[vesa2_btrcla],bx
xor word[vesa2_clbit],0FFFFh
;vesa2_rtrcl dw 0 ; red transparency clear (bit+4)
;vesa2_rtrcla dw 0 ; red transparency (AND) clear (not(bit+4))
;vesa2_rfull dw 0 ; red max (or (bit-1)*1Fh)
call genfulladdtab
test word[fs:0h],10000000b ; Check if linear available
jnz .linearavailable
mov edx,.nolframebuffer
jmp VESA2EXITTODOS ; None available
.nolframebuffer db 'Linear Frame Buffer not Detected.',0
;---------------------------------------------;
; OK - now set the vesa 2 mode based on the ;
; information gleaned... ;
;---------------------------------------------;
.linearavailable
or word[vesamode],4000h ; Convert mode to its LFB
; equivalent
mov ebx,[fs:28h] ; Read in physical base ptr
mov cx,bx
shr ebx,16
mov si,[noblocks]
xor edi,edi ; Since noblocks = number of
; 64k blocks, these lines leave
; si:di holding byte size
mov eax,800h
int 31h
jnc .mappedphysicalarea
mov edx,.unablemap
jmp VESA2EXITTODOS ; Failure!!!
.unablemap db 'Unable to map physical area.',0
.mappedphysicalarea
shl ebx,16
mov bx,cx
mov [LFBpointer],ebx
mov eax,ebx
sub eax,[ZSNESBase]
mov [VESAAddr],eax
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov ax,4f02h
mov bx,[vesamode]
int 10h ; Set the vesa mode
cmp ax,004fh
jz .modesetok
mov edx,.unableset
jmp VESA2EXITTODOS ; Failure!!!
.unableset db 'Unable to initialize video mode.',0
.modesetok
;******************************* EXTRA BIT ****************************
; cmp byte[.whichwin],1 ; Check if Write is at Window B
; jne .nowinB
;
; mov ax,4F05h
; mov bx,1
; mov dx,0
; int 10h
;
;.nowinB
; Check logical scanline length
mov eax,4f06h
mov ebx,1
int 10h
cmp cx,[vesa2_x]
je .correctwidth
mov eax,4f06h ; VBE Set/Get logical scan line
; length
mov ebx,0 ; Set scan line length in
; pixels
mov ecx, [vesa2_x] ; Desired screen width
int 10h
cmp ax,04fh
jz .correctwidth
mov edx, .unablescan
jmp VESA2EXITTODOS ; Failure!!!
.unablescan db 'Unable to set scan line length.',0
.correctwidth
;*************************** END OF EXTRA BIT *************************
xor eax,eax
mov ecx,1
int 31h ; Allocate a descriptor
mov bx,ax ; Move our selector into bx
mov ecx,[LFBpointer]
mov dx,cx
shr ecx,16
mov eax,7
int 31h ; Set our selector to LFB
jnc .selectornowset
mov edx,.unablelfb
jmp VESA2EXITTODOS ; Failure!!!
.unablelfb db 'Unable to set selector to LFB.',0
.selectornowset
xor ecx,ecx
mov cx,[noblocks]
shl ecx,6 ; Multiply by 64
shl ecx,10 ; And again by 1024
sub ecx,1 ; Necessary!!!
mov dx,cx
shr ecx,16 ; CX:DX size of screen
mov eax,8
int 31h ; Set size of selector
jnc .ok
mov edx,.unablesets
jmp VESA2EXITTODOS ; Failure!!!
.unablesets db 'Unable to set size of selector.',0
.ok
lar ecx,ebx
shr ecx,8
and cl,60h
or cl,93h
and ch,0c0h ; Keep granularity bit
mov ax,9
int 31h ; Set selector access rights
jnc .accessrightsset
mov edx,.unablesetar
jmp VESA2EXITTODOS
.unablesetar db 'Unable to set selector access rights.',0
.accessrightsset
mov [vesa2selec],bx
cmp byte[vesa2red10],1
je .red10
mov eax,565
jmp .red11
.red10
mov eax,555
.red11
push eax
call Init_2xSaIMMX
call Init_2xSaI
pop eax
ret
NEWSYM LFBpointer
dd 0
NEWSYM noblocks
dw 0
NEWSYM bytesperscanline
dw 0
NEWSYM vesamode
dw 0
;----------------------------------------------------------------------
NEWSYM VESAmodelist
times 512 dw 0
;----------------------------------------------------------------------
NEWSYM RMREGS
.edi dd 0
.esi dd 0
.ebp dd 0
.esp dd 0
.ebx dd 0
.edx dd 0
.ecx dd 0
.eax dd 0
.flags dw 0
.es dw 0
.ds dw 0
.fs dw 0
.gs dw 0
.ip dw 0
.cs dw 0
.sp dw 0
.ss dw 0
.spare times 20 dd 0
;----------------------------------------------------------------------


267
zsnes/src/dos/zfile.c Normal file
View File

@@ -0,0 +1,267 @@
//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 <stdio.h>
#include <time.h>
#ifdef ZDOS
#include <dos.h>
#endif
#define DWORD unsigned int
#define BYTE unsigned char
FILE *FILEHANDLE[16];
DWORD CurrentHandle=0;
// ZFileSystemInit
// return 0
// ZOpenFile info :
BYTE * ZOpenFileName;
DWORD ZOpenMode;
// Open modes : 0 read/write in
// 1 write (create file, overwrite)
// return file handle if success, 0xFFFFFFFF if error
// ZCloseFile info :
DWORD ZCloseFileHandle;
// return 0
// ZFileSeek info :
DWORD ZFileSeekHandle;
DWORD ZFileSeekPos;
DWORD ZFileSeekMode; // 0 start, 1 end
// return 0
// ZFileReadBlock info :
BYTE * ZFileReadBlock;
DWORD ZFileReadSize;
DWORD ZFileReadHandle;
// return 0
// ZFileWriteBlock info :
BYTE * ZFileWriteBlock;
DWORD ZFileWriteSize;
DWORD ZFileWriteHandle;
// return 0
// ZFileTell
DWORD ZFileTellHandle;
// ZFileGetftime
BYTE * ZFFTimeFName;
DWORD ZFTimeHandle;
DWORD ZFDate;
DWORD ZFTime;
// MKDir/CHDir
BYTE * MKPath;
BYTE * CHPath;
BYTE * RMPath;
// GetDir
BYTE * DirName;
DWORD DriveNumber;
// ZFileDelete
BYTE * ZFileDelFName;
// return current position
DWORD ZFileSystemInit()
{
CurrentHandle=0;
return(0);
}
DWORD ZOpenFile()
{
if(ZOpenMode==0)
{
if((FILEHANDLE[CurrentHandle]=fopen(ZOpenFileName,"rb"))!=NULL)
{
CurrentHandle+=1;
return(CurrentHandle-1);
}
return(0xFFFFFFFF);
}
if(ZOpenMode==1)
{
if((FILEHANDLE[CurrentHandle]=fopen(ZOpenFileName,"wb"))!=NULL)
{
CurrentHandle+=1;
return(CurrentHandle-1);
}
return(0xFFFFFFFF);
}
if(ZOpenMode==2)
{
if((FILEHANDLE[CurrentHandle]=fopen(ZOpenFileName,"r+b"))!=NULL)
{
CurrentHandle+=1;
return(CurrentHandle-1);
}
return(0xFFFFFFFF);
}
return(0xFFFFFFFF);
}
DWORD ZCloseFile()
{
fclose(FILEHANDLE[ZCloseFileHandle]);
CurrentHandle-=1;
return(0);
}
DWORD ZFileSeek()
{
if(ZFileSeekMode==0)
{
fseek(FILEHANDLE[ZFileSeekHandle],ZFileSeekPos,SEEK_SET);
return(0);
}
if(ZFileSeekMode==1)
{
fseek(FILEHANDLE[ZFileSeekHandle],ZFileSeekPos,SEEK_END);
return(0);
}
return(0xFFFFFFFF);
}
DWORD ZFileRead()
{
return(fread(ZFileReadBlock,1,ZFileReadSize,FILEHANDLE[ZFileReadHandle]));
}
DWORD ZFileWrite()
{
if((fwrite(ZFileWriteBlock,1,ZFileWriteSize,FILEHANDLE[ZFileWriteHandle]))!=ZFileWriteSize) return(0xFFFFFFFF);
return(0);
}
DWORD ZFileTell()
{
return(ftell(FILEHANDLE[ZFileTellHandle]));
}
DWORD ZFileDelete()
{
return(remove(ZFileDelFName));
}
DWORD ZFileGetFTime()
{
_dos_open(ZFFTimeFName, 0,&ZFTimeHandle);
_dos_getftime(ZFTimeHandle,&ZFDate,&ZFTime);
_dos_close(ZFTimeHandle);
return(0);
}
DWORD ZFileMKDir()
{
return(mkdir(MKPath));
}
DWORD ZFileCHDir()
{
return(chdir(CHPath));
}
DWORD ZFileRMDir()
{
return(rmdir(RMPath));
}
DWORD ZFileGetDir()
{
return(getcwd(DirName,128));
}
BYTE * ZFileFindPATH;
DWORD ZFileFindATTRIB;
DWORD DTALocPos;
//struct _find_t {
// char reserved[21] __attribute__((packed));
// unsigned char attrib __attribute__((packed));
// unsigned short wr_time __attribute__((packed));
// unsigned short wr_date __attribute__((packed));
// unsigned long size __attribute__((packed));
// char name[256] __attribute__((packed));
//};
DWORD ZFileFindFirst()
{
return(_dos_findfirst(ZFileFindPATH,ZFileFindATTRIB,DTALocPos));
}
DWORD ZFileFindNext()
{
return(_dos_findnext(DTALocPos));
}
DWORD ZFileFindEnd() // for compatibility with windows later
{
return(0);
}
//BYTE * DirName;
//DWORD DriveNumber;
//unsigned int _dos_findfirst(char *_name, unsigned int _attr, struct _find_t *_result);
//unsigned int _dos_findnext(struct _find_t *_result);
DWORD GetTime()
{
DWORD value;
struct tm *newtime;
time_t long_time;
time( &long_time );
newtime = localtime( &long_time );
value = ((newtime->tm_sec) % 10)+((newtime->tm_sec)/10)*16
+((((newtime->tm_min) % 10)+((newtime->tm_min)/10)*16) << 8)
+((((newtime->tm_hour) % 10)+((newtime->tm_hour)/10)*16) << 16);
return(value);
}
DWORD GetDate()
{
DWORD value;
struct tm *newtime;
time_t long_time;
time( &long_time );
newtime = localtime( &long_time );
value = ((newtime->tm_mday) % 10)+((newtime->tm_mday)/10)*16
+(((newtime->tm_mon)+1) << 8)
+((((newtime->tm_year) % 10)+((newtime->tm_year)/10)*16) << 16);
+((newtime->tm_wday) << 28);
return(value);
}

396
zsnes/src/dos/zloader.c Normal file
View File

@@ -0,0 +1,396 @@
//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 <stdio.h>
#include <ctype.h>
extern void zstart(void);
extern void DosExit(void);
extern void ConvertJoyMap1(void);
extern void ConvertJoyMap2(void);
extern void displayparams(void);
extern void makeextension(void);
extern unsigned char Palette0, SPC700sh, OffBy1Line, DSPDisable,
FPUCopy, Force8b, ForcePal, GUIClick, MouseDis,
MusicRelVol, ScreenScale, SoundCompD, SoundQuality,
StereoSound, V8Mode, antienab, cvidmode, debugdisble,
debugger, enterpress, finterleave, frameskip,
gammalevel, guioff, per2exec, pl1contrl, pl2contrl,
romtype, scanlines, showallext, smallscreenon, soundon,
spcon, vsyncon, DisplayS, fname, filefound, SnowOn;
void ccmdline(void);
char *ers[] =
{
"Frame Skip must be a value of 0 to 9!\n",
"Gamma Correction Level must be a value of 0 to 5!\n",
"Sound Sampling Rate must be a value of 0 to 6!\n",
"Invalid Video Mode!\n",
"Percentage of instructions to execute must be a number from 50 to 150!\n",
"Player Input must be a value from 0 to 6!\n",
"Volume must be a number from 0 to 100!\n"
};
int argc;
char **argv;
int main(int margc, char **margv)
{
argc=margc;
argv=margv;
zstart();
}
int my_atoi(char *nptr)
{
int p,c;
c=0;
for(p=0;nptr[p];p++)
{
if( !isdigit(nptr[p]) ) c+=1;
}
if(c) return -1;
else return atoi(nptr);
}
void ccmdline(void)
{
int p=0;
p=pccmdline();
if(p == 0) return;
if(p == 9)
{
displayparams();
}
if(p == 4)
{
// printf("Mangled command line, did you forget a parm?\n");
printf("Invalid Commandline!\n");
DosExit();
}
if((p > 9) && (p < 17))
{
printf(ers[p-10]);
DosExit();
}
if(p == 2)
{
DosExit();
}
printf("cmdline returned %i\n",p);
DosExit();
}
int pccmdline(void)
{
int p;
int gfnm=0;
for(p=1;p<argc;p++)
{
/*
printf("(%i/%i): %s\n",p,argc,argv[p]);
*/
if(argv[p][0] == '-')
{
int hasroom=0;
int pp=1;
int cp=p;
int nn='_';
for(pp=1;argv[cp][pp];pp++)
{
if( (p+1) < argc) hasroom=1;
nn=tolower(argv[cp][pp+1]);
switch(tolower(argv[cp][pp]))
{
case '1': /* Player 1 Input */
{
if(!hasroom) return 4;
pl1contrl=my_atoi(argv[p+1]);
if(pl1contrl > 6) return 15;
p++;
ConvertJoyMap1();
break;
}
case '2': /* Player 2 Input */
{
if(!hasroom) return 4;
pl2contrl=my_atoi(argv[p+1]);
if(pl2contrl > 6) return 15;
p++;
ConvertJoyMap2();
break;
}
case 'f':
{
if(!hasroom) return 4;
frameskip=my_atoi(argv[p+1]);
if(frameskip > 9) return 10;
p++;
break;
}
case 'g':
{
if(!hasroom) return 4;
gammalevel=my_atoi(argv[p+1]);
if(gammalevel > 5) return 11;
p++;
break;
}
case 'p':
{
if(!hasroom) return 4;
per2exec=my_atoi(argv[p+1]);
if(per2exec > 150) return 14;
if(per2exec < 50) return 14;
p++;
break;
}
case 'r':
{
if(!hasroom) return 4;
SoundQuality=my_atoi(argv[p+1]);
if(SoundQuality > 6) return 12;
p++;
break;
}
case 'v':
{
if(nn == '8')
{
V8Mode=1;
pp++;
}
else
{
if(!hasroom) return 4;
cvidmode=my_atoi(argv[p+1]);
if(cvidmode > 10) return 13;
p++;
}
break;
}
case 'k':
{
if(!hasroom) return 4;
MusicRelVol=my_atoi(argv[p+1]);
if(MusicRelVol > 100) return 16;
p++;
break;
}
case '8':
{
Force8b=1;
break;
}
case '0': /* Palette 0 disable */
{
Palette0=1;
break;
}
case '7': /* SPC700 speed hack disable */
{
SPC700sh=1;
break;
}
case '9': /* Off by 1 line */
{
OffBy1Line=1;
break;
}
case 'e':
{
enterpress=1;
break;
}
case 'h':
{
romtype=2;
break;
}
case 'l':
{
romtype=1;
break;
}
case 'm':
{
guioff=1; /* disables GUI */
break;
}
case 'n':
{
scanlines=1;
break;
}
case 's':
{
if(nn == 'p')
{
DisplayS=1;
pp++;
}
else
if(nn == 'a')
{
showallext=1;
pp++;
}
else
if(nn == 'n')
{
SnowOn=1;
pp++;
}
else
{
spcon=1;
soundon=1;
}
break;
}
case 't':
{
ForcePal=1;
break;
}
case 'u':
{
ForcePal=2;
break;
}
case 'w':
{
vsyncon=1;
break;
}
case 'z':
{
StereoSound=1;
break;
}
case 'd':
{
if(nn == 'd')
{
DSPDisable=1;
pp++;
}
else
{
debugger=1;
debugdisble=0;
}
break;
}
case 'b':
{
SoundCompD=1;
break;
}
case 'c':
{
if(nn == 'c')
{
smallscreenon=1;
pp++;
}
else
{
ScreenScale=1;
}
break;
}
case 'y':
{
antienab=1;
break;
}
case 'o':
{
if(nn == 'm')
{
FPUCopy=2;
pp++;
}
else
{
FPUCopy=0;
}
break;
}
case 'i':
{
finterleave=1;
break;
}
case 'j':
{
GUIClick=0;
MouseDis=1;
break;
}
case '?':
{
return 9;
}
}
}
}
else
{
if(gfnm > 0)
{
printf("Limit yourself to one filename\n");
return 2;
}
else
{
char *fvar;
fvar=&fname;
fvar[0] = strlen(argv[p]);
strncpy(&fvar[1],argv[p],127);
gfnm++;
}
}
}
if(gfnm == 1)
{
filefound=0;
makeextension();
}
return 0;
}


212
zsnes/src/dos/zsipx.asm Normal file
View File

@@ -0,0 +1,212 @@
;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 ipx_init ; To init ipx
EXTSYM ipx_initcode ; return 0 if everything is ok (int)
EXTSYM ipx_packet ; 80 bytes buffer to send
EXTSYM ipx_packet_size ; size to send (max 80 bytes) (dword)
EXTSYM sendpacket ; to send a packet
EXTSYM checkpacket ; check if a packet is ready to receive
EXTSYM ipx_packet_ready ; return 1 if there is a packet ready (byte)
EXTSYM read_packet ; to read an incoming packet
EXTSYM ipx_read_packet ; 80 bytes buffer of received packet
EXTSYM ipx_deinit ; to deinit the ipx
EXTSYM IPXInfoStr,IPXInfoStrR
EXTSYM modembuffer, modemhead, modemtail
NEWSYM ipxinited, db 0
NEWSYM initipx
mov dword[modemhead],0
mov dword[modemtail],0
xor ax,ax
cmp byte[ipxinited],1
je .notokay
call ipx_init
mov ax,[ipx_initcode]
cmp ax,0
jne .notokay
mov byte[ipxinited],1
.notokay
ret
NEWSYM deinitipx
cmp byte[ipxinited],0
je .notinitialized
mov byte[ipxinited],0
call ipx_deinit
.notinitialized
ret
NEWSYM PacketPointer, dd 0
NEWSYM PreparePacketIPX
cmp byte[ipxinited],1
jne .noipx
call ipxpp
.noipx
ret
NEWSYM SendPacketIPX
cmp byte[ipxinited],1
jne .noipx
call ipxsp
.noipx
ret
NEWSYM ipxsendchar ; prepare packet
push esi
mov esi,[PacketPointer]
mov [esi],al
inc dword[PacketPointer]
pop esi
ret
NEWSYM IPXSearchval, db 0
NEWSYM ipxlookforconnect
cmp byte[ipxinited],0
je .initialized
ret
.initialized
pushad
call checkpacket
cmp byte[ipx_packet_ready],1
jne near .nopacket
call read_packet
cmp dword[ipx_read_packet],'ZZ|Z'
jne .nopacketf
cmp byte[ipx_read_packet+6],'L'
jne .nopacketf
mov ax,[ipx_read_packet+4]
cmp ax,[IPXInfoStr]
je .nopacketf
mov [IPXInfoStrR],ax
mov eax,ipx_packet
mov dword[eax],'ZY|Z'
mov bx,[IPXInfoStr]
mov [eax+4],bx
mov bx,[IPXInfoStrR]
mov [eax+6],bx
mov dword[ipx_packet_size],8
call sendpacket
mov byte[IPXSearchval],1
jmp .skipall
.nopacketf
cmp dword[ipx_read_packet],'ZY|Z'
jne .nopacket
mov bx,[IPXInfoStr]
cmp [eax+6],bx
jne .nopacket
mov bx,[eax+4]
cmp bx,[IPXInfoStr]
je .nopacket
mov [IPXInfoStrR],bx
mov byte[IPXSearchval],1
jmp .skipall
.nopacket
mov eax,ipx_packet
mov dword[eax],'ZZ|Z'
mov bx,[IPXInfoStr]
mov [eax+4],bx
mov byte[eax+6],'L'
mov dword[ipx_packet_size],7
call sendpacket
.skipall
popad
ret
NEWSYM ipxpp ; prepare packet
pushad
mov eax,ipx_packet
mov byte[eax],'Z'
mov byte[eax+1],'|'
mov byte[eax+2],'S'
mov bx,[IPXInfoStr]
mov [eax+3],bx
add eax,6
mov [PacketPointer],eax
popad
ret
NEWSYM ipxsp ; send packet
pushad
mov eax,[PacketPointer]
sub eax,ipx_packet
mov [ipx_packet+5],al
mov [ipx_packet_size],eax
call sendpacket
popad
ret
NEWSYM ipxgetchar
pushad
call checkpacket
cmp byte[ipx_packet_ready],1
jne .nopacket
call read_packet
cmp byte[ipx_read_packet],'Z'
jne .nopacket
cmp byte[ipx_read_packet+1],'|'
jne .nopacket
cmp byte[ipx_read_packet+2],'S'
jne .nopacket
mov bx,[IPXInfoStrR]
cmp [ipx_read_packet+3],bx
jne .nopacket
mov cl,[ipx_read_packet+5]
sub cl,6
mov esi,ipx_read_packet+6
cmp cl,0
je .nopacket
.loop
mov edi,[modemtail]
mov al,[esi]
mov [modembuffer+edi],al
inc dword[modemtail]
inc esi
and dword[modemtail],2047
dec cl
jnz .loop
.nopacket
popad
push eax
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
pop eax
ret