ORG 0x100 hSync equ 0x220 vSync equ 0x224 backPorch equ 0x208 videoDimensions equ 0x20C fbiInit0 equ 0x210 fbiInit1 equ 0x214 fbiInit2 equ 0x218 fbiInit3 equ 0x21C fbiInit4 equ 0x200 fbiInit5 equ 0x244 fbiInit7 equ 0x24C trexInit0 equ 0x31C trexInit1 equ 0x320 clutData equ 0x228 dacData equ 0x22C bltSrcBaseAddr equ 0x2C0 bltDstBaseAddr equ 0x2C4 bltClipX equ 0x2D4 bltClipY equ 0x2D8 bltSrcXY equ 0x2E0 bltDstXY equ 0x2E4 bltSize equ 0x2E8 bltXYStrides equ 0x2C8 bltROP equ 0x2EC bltCommand equ 0x2F8 lfbMode equ 0x114 clipLeftRight equ 0x118 clipLowYHighY equ 0x11C fbzColorPath equ 0x104 fbzMode equ 0x110 sSetupMode equ 0x260 color1 equ 0x148 zaColor equ 0x130 textureMode equ 0x300 texBaseAddr equ 0x30C tLOD equ 0x304 sVx equ 0x264 sVy equ 0x268 sWtmu0 equ 0x288 sS_W0 equ 0x28C sT_W0 equ 0x290 fastfillCMD equ 0x124 sBeginTriCMD equ 0x2A4 sDrawTriCMD equ 0x2A0 P1 equ 16 P2 equ 32 macro InMMR Register { push WORD 0 pop es mov edi,[MMR] add edi,Register mov eax,[es:edi] } macro OutMMR Register,Data { push WORD 0 pop es mov edi,[MMR] add edi,Register mov eax,Data mov [es:edi],eax } macro DrawTunnel { mov [j],0 @j: mov [i],0 @i: fld DWORD [Pi2] ;X fimul DWORD [i] fmul DWORD [_P1] fstp DWORD [Pi2iP1] fild DWORD [j] fmul DWORD [_2] fadd DWORD [Angle] fstp DWORD [Angle2j] fld DWORD [Pi2iP1] fsin fstp DWORD [SinPi2iP1] fld DWORD [Angle2j] fmul DWORD [_29] fsin fmul DWORD [_2] fstp DWORD [_2SinAngle2j29] fld DWORD [Angle2j] fmul [_13] fcos fstp DWORD [CosAngle2j13] fld DWORD [Angle] fmul DWORD [_29] fsin fmul DWORD [_2] fstp DWORD [_2SinAngle29] fld DWORD [Angle] fmul DWORD [_13] fcos fstp DWORD [CosAngle13] fld DWORD [SinPi2iP1] fadd DWORD [_2SinAngle2j29] fadd DWORD [CosAngle2j13] fsub DWORD [_2SinAngle29] fsub DWORD [CosAngle13] fmul DWORD [_416] mov edi,[i] shl edi,5 add edi,[j] shl edi,2 add edi,X fstp DWORD [edi] fld DWORD [Pi2iP1] ;Y fcos fstp DWORD [CosPi2iP1] fld DWORD [Angle2j] fmul DWORD [_33] fcos fmul DWORD [_2] fstp DWORD [_2CosAngle2j33] fld DWORD [Angle2j] fmul [_17] fsin fstp DWORD [SinAngle2j17] fld DWORD [Angle] fmul DWORD [_33] fcos fmul DWORD [_2] fstp DWORD [_2CosAngle33] fld DWORD [Angle] fmul DWORD [_17] fsin fstp DWORD [SinAngle17] fld DWORD [CosPi2iP1] fadd DWORD [_2CosAngle2j33] fadd DWORD [SinAngle2j17] fsub DWORD [_2CosAngle33] fsub DWORD [SinAngle17] fmul DWORD [_390] mov edi,[i] shl edi,5 add edi,[j] shl edi,2 add edi,Y fstp DWORD [edi] inc [i] cmp [i],P1 jbe @i inc [j] cmp [j],P2-1 jbe @j mov [j],0 @@j: mov [i],0 @@i: mov edi,[i] ;i j shl edi,5 add edi,[j] shl edi,2 mov ebx,X add ebx,edi push DWORD [ebx] mov ebx,Y add ebx,edi push DWORD [ebx] mov ebx,Z add ebx,edi push DWORD [ebx] fild DWORD [i] fmul DWORD [_256P1] fstp DWORD [_] push DWORD [_] fild DWORD [j] fmul DWORD [_256P2] fstp DWORD [j256P2] fld DWORD [Angle] fmul DWORD [_2_03] fadd DWORD [j256P2] fstp DWORD [_] push DWORD [_] mov edi,[i] ;i+1 j inc edi shl edi,5 add edi,[j] shl edi,2 mov ebx,X add ebx,edi push DWORD [ebx] mov ebx,Y add ebx,edi push DWORD [ebx] mov ebx,Z add ebx,edi push DWORD [ebx] fld1 fiadd DWORD [i] fmul DWORD [_256P1] fstp DWORD [_] push DWORD [_] fild DWORD [j] fmul DWORD [_256P2] fstp DWORD [j256P2] fld DWORD [Angle] fmul DWORD [_2_03] fadd DWORD [j256P2] fstp DWORD [_] push DWORD [_] mov edi,[i] ;i j+1 shl edi,5 add edi,[j] inc edi shl edi,2 mov ebx,X add ebx,edi push DWORD [ebx] mov ebx,Y add ebx,edi push DWORD [ebx] mov ebx,Z add ebx,edi push DWORD [ebx] fild DWORD [i] fmul DWORD [_256P1] fstp DWORD [_] push DWORD [_] fld1 fiadd DWORD [j] fmul DWORD [_256P2] fstp DWORD [j256P2] fld DWORD [Angle] fmul DWORD [_2_03] fadd DWORD [j256P2] fstp DWORD [_] push DWORD [_] mov edi,[i] ;i+1 j+1 inc edi shl edi,5 add edi,[j] inc edi shl edi,2 mov ebx,X add ebx,edi push DWORD [ebx] mov ebx,Y add ebx,edi push DWORD [ebx] mov ebx,Z add ebx,edi push DWORD [ebx] fld1 fiadd DWORD [i] fmul DWORD [_256P1] fstp DWORD [_] push DWORD [_] fld1 fiadd DWORD [j] fmul DWORD [_256P2] fstp DWORD [j256P2] fld DWORD [Angle] fmul DWORD [_2_03] fadd DWORD [j256P2] fstp DWORD [_] push DWORD [_] call QUAD inc [i] cmp [i],P1-1 jbe @@i inc [j] cmp [j],P2-2 jbe @@j } call TestVirtual cmp al,0 jz @Real retn @Real: call TestPCI cmp al,0 jz @PCI retn @PCI: call TestMonster cmp al,0 jz @Monster retn @Monster: call CalculateAddress call FLAT call Voodoo2_INIT OutMMR bltSrcBaseAddr,0x00000000 OutMMR bltDstBaseAddr,0x00000000 OutMMR bltXYStrides,0x00140014 OutMMR bltSrcXY,0x01E00000 OutMMR bltDstXY,0x00000000 OutMMR bltSize,0x01DF027F OutMMR bltClipX,0x00000280 OutMMR bltClipY,0x000003C0 OutMMR clipLeftRight,0x00000280 OutMMR clipLowYHighY,0x01E003C0 OutMMR bltROP,0x0000000C OutMMR lfbMode,0x00000000 OutMMR color1,0x00000000 OutMMR zaColor,0.0 OutMMR fbzMode,0x00010F99 OutMMR fbzColorPath,0x2C000001 OutMMR sSetupMode,0x00060030 OutMMR textureMode,0x00040A17 OutMMR texBaseAddr,0x00000000 OutMMR tLOD,0x00000104 call TunnelToTMU finit call InitZ push WORD 0 pop es mov di,0x0024 push DWORD [es:di] pop [OldKey] push cs push NewKey cli pop DWORD [es:di] sti call Voodoo2_ON @REPEAT: mov al,[K] cmp al,01 je @EXIT cmp al,02 je @NotInvertOutput cmp al,03 je @InvertOutput cmp al,04 je @EnableBilinear cmp al,05 je @DisableBilinear cmp al,06 je @EnableSubpixel cmp al,07 je @DisableSubpixel cmp al,08 je @EnableDepth cmp al,09 je @DisableDepth cmp al,10 je @NegativeCulling cmp al,11 je @PositiveCulling cmp al,19 je @Reset cmp al,72 je @UP cmp al,80 je @DOWN jmp @DRAW @EXIT: call Voodoo2_OFF push WORD 0 pop es mov di,0x0024 push [OldKey] cli pop DWORD [es:di] sti retn @NotInvertOutput: InMMR fbzColorPath and eax,0xFFFEFFFF OutMMR fbzColorPath,eax jmp @DRAW @InvertOutput: InMMR fbzColorPath or eax,0x00010000 OutMMR fbzColorPath,eax jmp @DRAW @EnableBilinear: OutMMR textureMode,0x00040A17 jmp @DRAW @DisableBilinear: OutMMR textureMode,0x00040A11 jmp @DRAW @EnableSubpixel: InMMR fbzColorPath or eax,0x04000000 OutMMR fbzColorPath,eax jmp @DRAW @DisableSubpixel: InMMR fbzColorPath and eax,0xFBFFFFFF OutMMR fbzColorPath,eax jmp @DRAW @EnableDepth: InMMR fbzMode or eax,0x00000010 OutMMR fbzMode,eax jmp @DRAW @DisableDepth: InMMR fbzMode and eax,0xFFFFFFEF OutMMR fbzMode,eax jmp @DRAW @NegativeCulling: OutMMR sSetupMode,0x00060030 jmp @DRAW @PositiveCulling: OutMMR sSetupMode,0x00020030 jmp @DRAW @Reset: OutMMR fbzMode,0x00010F99 OutMMR fbzColorPath,0x2C000001 OutMMR sSetupMode,0x00060030 OutMMR textureMode,0x00040A17 jmp @DRAW @UP: fld DWORD [Speed] fadd DWORD [V] fstp DWORD [Speed] jmp @DRAW @DOWN: fld DWORD [Speed] fsub DWORD [V] fstp DWORD [Speed] @DRAW: OutMMR fastfillCMD,0 DrawTunnel OutMMR bltCommand,0x8001C010 fld DWORD [Angle] fadd DWORD [Speed] fstp DWORD [Angle] jmp @REPEAT ;PROCEDURE TestVirtual: ;al=0 - Real Mode al=1 - Virtual Mode smsw ax and al,1 retn TestPCI: ;al=0 - YES PCI BIOS al=1 - NOT PCI BIOS mov ax,0xB101 int 1Ah cmp ah,0 jz @3 mov al,1 retn @3: cmp edx,'PCI ' je @4 mov al,1 retn @4: xor al,al retn TestMonster: ;al=0 - YES Monster al=1 - NOT Monster mov ax,0xB102 mov cx,0x0002 ;Device ID mov dx,0x121A ;Vendor ID xor si,si int 1Ah cmp ah,0 jz @5 mov al,1 retn @5: mov [BusDeviceFunction],bx xor al,al retn InPCID: push bp mov bp,sp mov ax,0xB10A mov bx,[BusDeviceFunction] mov di,[bp+4] int 0x1A mov eax,ecx pop bp retn 2 OutPCID: push bp mov bp,sp mov ax,0xB10D mov bx,[BusDeviceFunction] mov di,[bp+8] mov ecx,[bp+4] int 0x1A pop bp retn 6 CalculateAddress: push WORD 0x0010 call InPCID and eax,0xFFFFFFF0 mov [MMR],eax add eax,0x00800000 mov [TMU],eax retn FLAT: xor eax,eax mov ax,cs shl eax,4 xor ebx,ebx mov bx,GDT add eax,ebx mov DWORD [GDTP+2],eax lgdt FWORD [GDTP] in al,92h or al,2 out 92h,al cli in al,70h or al,80h out 70h,al mov eax,cr0 or al,1 mov cr0,eax jmp $+2 mov bx,8 mov es,bx and al,0xFE mov cr0,eax jmp $+2 in al,70h and al,0x7F out 70h,al sti retn InDAC: push bp mov bp,sp xor eax,eax or ah,[bp+4] or ah,0x08 OutMMR dacData,eax InMMR fbiInit2 and eax,0x000000FF pop bp retn 2 OutDAC: push bp mov bp,sp xor eax,eax or ah,[bp+6] or al,[bp+4] OutMMR dacData,eax pop bp retn 4 PLL: push WORD 0x07 ;Video Clock push WORD 0x0E call OutDAC push WORD 0x05 call InDAC push ax push WORD 0x04 push WORD 0x00 call OutDAC push WORD 0x05 push [M] call OutDAC push WORD 0x05 mov ax,[P] shl al,5 or ax,[N] push ax call OutDAC push WORD 0x04 push WORD 0x0E call OutDAC pop ax and al,0xF8 or al,0x20 push WORD 0x05 push ax call OutDAC push WORD 0x07 ;Graphic Clock push WORD 0x0E call OutDAC push 0x05 call InDAC push ax push WORD 0x04 push WORD 0x0A call OutDAC push WORD 0x05 push [M] call OutDAC mov ax,[P] shl al,5 or ax,[N] push WORD 0x05 push ax call OutDAC push WORD 0x04 push WORD 0x0E call OutDAC pop ax and al,0xEF push WORD 0x05 push ax call OutDAC retn VideoTiming: mov ax,[hSyncOff] shl eax,16 or ax,[hSyncOn] OutMMR hSync,eax mov ax,[vSyncOff] shl eax,16 or ax,[vSyncOn] OutMMR vSync,eax mov ax,[vBackPorch] shl eax,16 or ax,[hBackPorch] OutMMR backPorch,eax mov ax,[yDimension] shl eax,16 or ax,[xDimension] dec ax OutMMR videoDimensions,eax retn Gamma: xor bl,bl @Fill: mov ah,bl mov al,bl shl al,3 shl eax,16 or ah,bl shl ah,3 or al,ah OutMMR clutData,eax inc bl cmp bl,31 jbe @Fill OutMMR clutData,0x20000000 retn Voodoo2_INIT: push WORD 0x0040 call InPCID or eax,0x00000003 push WORD 0x0040 push eax call OutPCID InMMR fbiInit0 or eax,0x00000006 OutMMR fbiInit0,eax InMMR fbiInit1 or eax,0x00000100 OutMMR fbiInit1,eax InMMR fbiInit2 and eax,0xFFBFFFFF OutMMR fbiInit2,eax push WORD 0x0040 call InPCID or eax,0x00000004 push WORD 0x0040 push eax call OutPCID call PLL push WORD 0x06 ;16BPP push WORD 0x50 call OutDAC push WORD 0x0040 call InPCID and eax,0xFFFFFFFB push WORD 0x0040 push eax call OutPCID call VideoTiming OutMMR fbiInit0,0x6C400350 OutMMR fbiInit1,0x2201E0A8 OutMMR fbiInit2,0x1874B0C2 OutMMR fbiInit3,0x77D08232 OutMMR fbiInit4,0x0FFDC25F OutMMR fbiInit5,0x0840B920 OutMMR fbiInit7,0x0FFB82AA InMMR fbiInit2 or eax,0x00400000 OutMMR fbiInit2,eax InMMR fbiInit1 and eax,0xFFFFFEFF OutMMR fbiInit1,eax InMMR fbiInit0 and eax,0xFFFFFFF9 OutMMR fbiInit0,eax call Gamma OutMMR trexInit0,0x00000BFF OutMMR trexInit1,0x300347FC retn Voodoo2_ON: InMMR fbiInit0 or eax,0x00000001 OutMMR fbiInit0,eax retn Voodoo2_OFF: InMMR fbiInit0 and eax,0xFFFFFFFE OutMMR fbiInit0,eax retn TunnelToTMU: push WORD 0 pop es xor esi,esi mov si,cs shl esi,4 add esi,Tunnel mov edi,[TMU] add edi,0x00020000 xor ecx,ecx @t: xor edx,edx @s: mov eax,[es:esi] mov ebx,ecx shl ebx,7 add ebx,edx shl ebx,2 mov [es:edi+ebx],eax add esi,4 inc edx cmp edx,64 jne @s inc ecx cmp ecx,128 jne @t retn NewKey: push ax in al,0x60 mov [K],al mov al,0x20 out 0x20,al pop ax iret QUAD: push bp mov bp,sp fld1 ;Vertex0 fdiv DWORD [bp+72] fst DWORD [w] fmul DWORD [bp+80] fadd DWORD [_320] fstp DWORD [_] OutMMR sVx,[_] fld DWORD [w] fmul DWORD [bp+76] fsubr DWORD [_720] fstp DWORD [_] OutMMR sVy,[_] OutMMR sWtmu0,[w] fld DWORD [w] fmul DWORD [bp+68] fstp DWORD [_] OutMMR sS_W0,[_] fld DWORD [w] fmul DWORD [bp+64] fstp DWORD [_] OutMMR sT_W0,[_] OutMMR sBeginTriCMD,0 fld1 ;Vertex1 fdiv DWORD [bp+52] fst DWORD [w] fmul DWORD [bp+60] fadd DWORD [_320] fstp DWORD [_] OutMMR sVx,[_] fld DWORD [w] fmul DWORD [bp+56] fsubr DWORD [_720] fstp DWORD [_] OutMMR sVy,[_] OutMMR sWtmu0,[w] fld DWORD [w] fmul DWORD [bp+48] fstp DWORD [_] OutMMR sS_W0,[_] fld DWORD [w] fmul DWORD [bp+44] fstp DWORD [_] OutMMR sT_W0,[_] OutMMR sDrawTriCMD,0 fld1 ;Vertex2 fdiv DWORD [bp+32] fst DWORD [w] fmul DWORD [bp+40] fadd DWORD [_320] fstp DWORD [_] OutMMR sVx,[_] fld DWORD [w] fmul DWORD [bp+36] fsubr DWORD [_720] fstp DWORD [_] OutMMR sVy,[_] OutMMR sWtmu0,[w] fld DWORD [w] fmul DWORD [bp+28] fstp DWORD [_] OutMMR sS_W0,[_] fld DWORD [w] fmul DWORD [bp+24] fstp DWORD [_] OutMMR sT_W0,[_] OutMMR sDrawTriCMD,0 fld1 ;Vertex3 fdiv DWORD [bp+12] fst DWORD [w] fmul DWORD [bp+20] fadd DWORD [_320] fstp DWORD [_] OutMMR sVx,[_] fld DWORD [w] fmul DWORD [bp+16] fsubr DWORD [_720] fstp DWORD [_] OutMMR sVy,[_] OutMMR sWtmu0,[w] fld DWORD [w] fmul DWORD [bp+8] fstp DWORD [_] OutMMR sS_W0,[_] fld DWORD [w] fmul DWORD [bp+4] fstp DWORD [_] OutMMR sT_W0,[_] OutMMR sDrawTriCMD,0 pop bp retn 80 InitZ: mov [j],0 @Ij: mov [i],0 @Ii: fld1 fiadd DWORD [j] mov edi,[i] shl edi,5 add edi,[j] shl edi,2 add edi,Z fstp DWORD [edi] inc [i] cmp [i],P1 jbe @Ii inc [j] cmp [j],P2-1 jbe @Ij retn Tunnel file 'TUNNEL' K db 0 GDT dq ?,0x8F92000000FFFF GDTP dw 15,?,? M dw 88 N dw 6 P dw 1 hSyncOn dw 45 hSyncOff dw 785 vSyncOn dw 3 vSyncOff dw 506 hBackPorch dw 64 vBackPorch dw 18 xDimension dw 640 yDimension dw 480 Pi2 dd 6.28318531 _P1 dd 0.0625 _2 dd 2.0 _29 dd 0.03448276 _13 dd 0.07692308 _416 dd 416.0 _33 dd 0.03030303 _17 dd 0.05882353 _390 dd 390.0 _256P1 dd 16.0 _256P2 dd 8.0 _2_03 dd 6.66666667 _320 dd 320.0 _720 dd 720.0 Angle dd 0.0 Speed dd 0.3 V dd 0.004 BusDeviceFunction dw ? OldKey dd ? MMR dd ? TMU dd ? w dd ? i dd ? j dd ? Pi2iP1 dd ? Angle2j dd ? SinPi2iP1 dd ? _2SinAngle2j29 dd ? CosAngle2j13 dd ? _2SinAngle29 dd ? CosAngle13 dd ? CosPi2iP1 dd ? _2CosAngle2j33 dd ? SinAngle2j17 dd ? _2CosAngle33 dd ? SinAngle17 dd ? j256P2 dd ? _ dd ? X rd (P1+1)*P2 Y rd (P1+1)*P2 Z rd (P1+1)*P2