www.pudn.com > sn068s.zip > SCRMODE.ASM


; 
; 
; Screen mode setup/blitting code 
; -Handlers to set up special display modes; 
; -Virtual SNES screen -> PC screen copiers. 
; 
; 
 
%include "misc.ni" 
%include "screen.ni" 
 
section .text 
EXPORT_C scrmode_start 
 
extern _SNES_Screen 
extern _ScreenX,_ScreenY 
extern _SCREEN_MODE 
extern _SNES_Screen8 
extern _Copy_Screen 
extern _HICOLOUR_Palette 
 
section .data 
ALIGND 
Copy_Screen_Table: 
dd VGA_COPY,SQUASH,MODEX_COPY,VGA_COPY 
dd HICOLOUR0_COPY,HICOLOUR1_COPY,HICOLOUR2_COPY,STRETCH_COPY 
 
section .text 
ALIGNC 
EXPORT Clear_Screen 
    push eax 
    push ecx 
    push edi 
 
    mov edi,[_SNES_Screen] 
    xor eax,eax 
 
    mov ecx,[_ScreenX] 
    shr ecx,2 
    imul ecx,[_ScreenY] 
ALIGNC 
.clear_loop: 
    sub ecx,byte 4 
    mov [edi+ecx],eax 
    jz  short .exit_loop 
    sub ecx,byte 4 
    mov [edi+ecx],eax 
    jz  short .exit_loop 
    sub ecx,byte 4 
    mov [edi+ecx],eax 
    jz  short .exit_loop 
    sub ecx,byte 4 
    mov [edi+ecx],eax 
    jnz short .clear_loop 
.exit_loop: 
 
    pop edi 
    pop ecx 
    pop eax 
	ret 
 
ALIGNC 
;EXPORT_C Copy_Screen 
EXPORT Copy_Screen 
    pusha 
 
    mov al,[_SCREEN_MODE] 
    and eax,byte 7 
    jmp [Copy_Screen_Table+eax*4] 
 
ALIGNC 
VGA_COPY:   ; Directly blit to VGA memory 
SQUASH:     ; This routine is specialized! 320x200 squash copy 
MODEX_COPY: 
    popa 
    jmp _Copy_Screen ; Have Allegro blit the screen and ret for us 
 
ALIGNC 
HICOLOUR0_COPY:     ; Temp hack, converts 256 cols to 65536 col screen 
 
; 320x200 screen... 
 
    mov edi,[_SNES_Screen] 
    mov esi,[_SNES_Screen8] 
    add edi,byte (320-256)  ; Offset to center of actual screen 
    xor eax,eax 
 
    mov dl,200 
.line_loop: 
    mov dh,0                ; do 256 times 
.pixel_loop: 
    mov al,[esi] 
    inc esi 
    mov bx,[_HICOLOUR_Palette+eax*4] 
    mov [edi],bx 
    add edi,byte 2 
    dec dh 
    jnz short .pixel_loop 
 
    add edi,(320-256)*2     ; Adjust to next line 
    add esi,byte GfxBufferLineSlack 
    dec dl 
    jnz short .line_loop  
 
	popa 
    jmp _Copy_Screen    ; Have Allegro blit the screen and ret for us 
 
ALIGNC 
HICOLOUR1_COPY:         ; Temp hack, converts 256 cols to 65536 col screen 
 
; 320x240 screen... 
 
    mov edi,[_SNES_Screen] 
    mov esi,[_SNES_Screen8] 
    add edi,byte (320-256)  ; Offset to center of actual screen 
    xor eax,eax 
 
    mov dl,240 
.line_loop: 
    mov dh,0                ; do 256 times 
.pixel_loop: 
    mov al,[esi] 
    inc esi 
    mov bx,[_HICOLOUR_Palette+eax*4] 
    mov [edi],bx 
    add edi,byte 2 
    dec dh 
    jnz short .pixel_loop 
 
    add edi,(320-256)*2 ; Adjust to next line 
    add esi,byte GfxBufferLineSlack 
    dec dl 
    jnz short .line_loop 
 
	popa 
    jmp _Copy_Screen    ; Have Allegro blit the screen and ret for us 
 
ALIGNC 
HICOLOUR2_COPY:     ; Temp hack, converts 256 cols to 65536 col screen 
 
; 640x480 screen... 256 used 384 remains 
 
    mov edi,[_SNES_Screen] 
    mov esi,[_SNES_Screen8] 
    add edi,(640-256)+(640*240) ; Offset to center of actual screen 
    xor eax,eax 
 
    mov dl,240 
.line_loop: 
    mov dh,0                    ; do 256 times 
.pixel_loop: 
    mov al,[esi] 
    inc esi 
    mov bx,[_HICOLOUR_Palette+eax*4] 
    mov [edi],bx 
    add edi,byte 2 
    dec dh 
    jnz short .pixel_loop 
 
    add edi,(640-256)*2     ; Adjust to next line 
    add esi,byte GfxBufferLineSlack 
    dec dl 
    jnz short .line_loop 
 
	popa 
    jmp _Copy_Screen    ; Have Allegro blit the screen and ret for us 
 
ALIGNC 
STRETCH_COPY:       ; Temp hack, converts 256 cols to 65536 col screen 
 
; 640x480 screen... 256*2 used 128 remains 
 
    mov edi,[_SNES_Screen] 
    mov esi,[_SNES_Screen8] 
    add edi,(640-512)       ; Offset to center of actual screen 
    xor eax,eax 
 
    mov dl,240 
.line_loop: 
    mov dh,0                ; do 256 times 
.pixel_loop: 
    mov al,[esi] 
    inc esi 
    mov ebx,[_HICOLOUR_Palette+eax*4] 
    mov [edi],ebx 
    mov [640*2+edi],ebx 
    add edi,byte 4 
    dec dh 
    jnz short .pixel_loop 
 
    add edi,128*2+(640*2)   ; Adjust to next line 
    add esi,byte GfxBufferLineSlack 
    dec dl 
    jnz short .line_loop 
 
	popa 
    jmp _Copy_Screen    ; Have Allegro blit the screen and ret for us 
 
ALIGNC 
EXPORT_C Set256x239     ; This sets up a 256x239 linear VGA mode 
 pusha 
 
 ; 0 -> Display -> Overscan -> Blank -> Retrace -> End Blank -> Overscan 
 
 ; Disable CRTC write protect 
 mov edx,0x3D4 
 mov al,0x11 
 out dx,al 
 inc edx 
 in  al,dx 
 and al,0x7F 
 out dx,al 
 
 ; Start dumping regs to VGA 
 ; Horizontal Total: 95 (+5) clocks 
 ;  Display Enable: 63 (+1) clocks 
 ;  Start Blanking: Clock 64   End Blanking: 34 
 ;  Start Retrace:  Clock 78   End Retrace:  22 
 ;  Display Enable Skew: 0     Retrace Skew: 0 
 ; Vertical Total: 525 (+2) clocks 
 ;  Display Enable: 477 (+1) rows 
 ;  Start Blanking: Row 478    End Blanking: x0D 
 ;  Start Retrace:  Row 478    End Retrace:  0010b 
 
 mov edx,0x3C2 
 ; - V sync, - H sync, 25.175MHz clock, enable memory, CGA CRTC addressing 
 ; 0: CRTC addressing mode (0:MDA 3B4/1:CGA 3D4): CGA 3D4 
 ; 1: Display memory access enable: enabled 
 ; 2-3: Dot clock frequency select: 
 ;  00: 25.175MHz (640 pixel wide modes) 
 ;  01: 28.322MHz (720 pixel wide modes) 
 ;  10, 11: External clock selects (max 65MHz) 
 ; 4: Reserved = 0 
 ; 5: Address extension bit: 0 
 ; 6,7: Horizontal, Vertical sync polarity selects 
 ;  0 = +, 1 = - 
 ;  00 = ???   01 = 400   10 = 350    11 = 480 
 mov al,0xE3        ; Misc. Output 
 out dx,al 
 mov edx,0x3D4      ; CRTC 
 mov al,0           ; Horizontal Total 
 mov ah,0x5F        ; 95 (+5) clocks 
 out dx,ax 
 mov al,1           ; Horizontal Display Enable 
 mov ah,0x3F        ; 63 (+1) clocks 
 out dx,ax 
 mov al,2           ; Start Horizontal Blanking 
 ; Primary centering control - increase number to move left 
 mov ah,0x40        ; Clock 64 
 out dx,ax 
 mov al,3           ; End Horizontal Blanking 
 ; 0-4: End Horizontal Blanking = 34 (bits 0-4 of 6) 
 ; 5-6: Display Enable Skew = 0 clocks 
 ; 7: Reserved/Lightpen (must be set for normal operation) 
 mov ah,0x82 
 out dx,ax 
 mov al,4           ; Start Horizonal Retrace Pulse 
 mov ah,0x4E        ; Clock 78 
 out dx,ax 
 mov al,5           ; End Horizontal Retrace 
 ; 0-4: End Horizontal Retrace = 22 (clocks?) 
 ; 5-6: Horizontal Retrace Skew = 0 clocks 
 ; 7: End Horizontal Blanking = 34 (bit 5 of 6) 
 mov ah,0x96 
 out dx,ax 
 mov al,6           ; Vertical Total (bits 0-7 of 10) 
 mov ah,0x0D        ; 525 (+2) 
 out dx,ax 
 mov al,7           ; Overflow 
 ; 0,5: Vertical Total = 525 rows (+2) (bits 8-9 of 10) 
 ; 1,6: Vertical Display Enable End = Row 479 (bits 8-9 of 10) 
 ; 2,7: Vertical Retrace Start = Row 480 (bits 8-9 of 10) 
 ; 3: Start Vertical Blanking = Row 480 (bit 8 of 10) 
 ; 4: Line Compare = (bit 8 of 10) 
 mov ah,0x3E 
 out dx,ax 
 mov al,8           ; Preset Row Scan 
 ; 0-4: Preset Row Scan = 0 
 ; 5-6: Byte Panning Control = 0 
 ; 7: Reserved = 0 
 mov ah,0 
 out dx,ax 
 mov al,9           ; Maximum Scan Line 
 ; 0-4: Maximum Scan Lines = 1 (+1) 
 ; 5: Start Vertical Blanking = Row 480 (bit 9 of 10) 
 ; 6: Line Compare = () (bit 9 of 10) 
 ; 7: Double Scan Line Display = 0 
 mov ah,0x41 
 out dx,ax 
 mov al,0x10        ; Vertical Retrace Start (bits 0-7 of 10) 
 ; Primary centering control - increase number to move up 
 mov ah,0xEA        ; Row 490 
 out dx,ax 
 mov al,0x11        ; Vertical Retrace End 
 ; 0-3: Vertical Retrace End = 0010 
 ; 4: Clear Vertical Interrupt: state cleared 
 ; 5: Vertical Interrupt: disabled 
 ; 6: Refresh Bandwidth Select: 3 memory refresh cycles/scan line 
 ; 7: CRTC Register Protect: enabled 
 mov ah,0xA2 
 out dx,ax 
 mov al,0x12        ; Vertical Display Enable End (bits 0-7 of 10) 
 mov ah,0xDD        ; Row 477 
 out dx,ax 
 mov al,0x13        ; Offset 
 mov ah,0x20        ; 32 * 8 = 256 
 out dx,ax 
 mov al,0x14        ; Underline Location 
 ; 0-4: Underline Location = 0 
 ; 5: Display Address Dwell 4 (clocks per address inc): 0 (1) 
 ; 6: Display Address Unit 4 (unit size of address inc): 1 (4) 
 ; 7: Reserved = 0 
 mov ah,0x40 
 out dx,ax 
 mov al,0x15        ; Start Vertical Blanking (bits 0-7 of 10) 
 mov ah,0xDD        ; Row 477 
 out dx,ax 
 mov al,0x16        ; End Vertical Blanking 
 mov ah,0x0D        ; Row x0D 
 out dx,ax 
 mov al,0x17        ; CRTC Mode Control 
 ; 0: Display address bit 13 = Row bit 0: disabled 
 ; 1: Display address bit 14 = Row bit 1: disabled 
 ; 2: Row counter increment frequency (by line or by 2): by line 
 ; 3: Display Address Dwell 2 (clocks per address inc): 0 (1) 
 ; 4: Reserved = 0 
 ; 5: Display Address Unit Bank Selection (8k/32k): 32k 
 ; 6: Display Address Unit 2 (unit size of address inc): 0 (4) 
 ; 7: Reset/generate retrace signals: Generate 
 mov ah,0xA3 
 out dx,ax 
 mov edx,0x3C4      ; Sequencer 
 mov al,1 
 mov ah,1 
 out dx,ax 
 mov al,4 
 mov ah,0x0E 
 out dx,ax 
 mov edx,0x3CE      ; Graphics controller 
 mov al,5 
 mov ah,0x40 
 out dx,ax 
 mov al,6 
 mov ah,5 
 out dx,ax 
 mov edx,0x3DA 
 in al,dx 
 mov edx,0x3C0 
 mov al,0x30 
 out dx,al 
 mov al,0x41 
 out dx,al 
 mov edx,0x3DA 
 in al,dx 
 mov edx,0x3C0 
 mov al,0x33 
 out dx,al 
 mov al,0 
 out dx,al 
 popa 
 ret 
 
ALIGNC 
EXPORT_C Set256x224     ; This sets up a 256x224 linear VGA mode 
 pusha 
 
 ; 0 -> Display -> Overscan -> Blank -> Retrace -> End Blank -> Overscan 
 
 ; Disable CRTC write protect 
 mov edx,0x3D4 
 mov al,0x11 
 out dx,al 
 inc edx 
 in  al,dx 
 and al,0x7F 
 out dx,al 
 
 ; Start dumping regs to VGA 
 mov edx,0x3C2 
 ; - V sync, - H sync, 25.175MHz clock, enable memory, CGA CRTC addressing 
 mov al,0xE3        ; Misc. Output 
 out dx,al 
 mov edx,0x3D4      ; CRTC 
 mov al,0           ; Horizontal Total 
 mov ah,0x5F        ; 95 (+5) clocks 
 out dx,ax 
 mov al,1           ; Horizontal Display Enable 
 mov ah,0x3F        ; 63 (+1) clocks 
 out dx,ax 
 mov al,2           ; Start Horizontal Blanking 
 ; Primary centering control - increase number to move left 
 mov ah,0x40        ; Clock 64 
 out dx,ax 
 mov al,3           ; End Horizontal Blanking 
 ; 0-4: End Horizontal Blanking = 34 (bits 0-4 of 6) 
 ; 5-6: Display Enable Skew = 0 clocks 
 ; 7: Reserved/Lightpen (must be set for normal operation) 
 mov ah,0x82 
 out dx,ax 
 mov al,4           ; Start Horizonal Retrace Pulse 
 mov ah,0x4E        ; Clock 78 
 out dx,ax 
 mov al,5           ; End Horizontal Retrace 
 ; 0-4: End Horizontal Retrace = 22 (clocks?) 
 ; 5-6: Horizontal Retrace Skew = 0 clocks 
 ; 7: End Horizontal Blanking = 34 (bit 5 of 6) 
 mov ah,0x96 
 out dx,ax 
 mov al,6           ; Vertical Total (bits 0-7 of 10) 
 mov ah,0x0D        ; 525 (+2) 
 out dx,ax 
 mov al,7           ; Overflow 
 ; 0,5: Vertical Total = 525 rows (+2) (bits 8-9 of 10) 
 ; 1,6: Vertical Display Enable End = Row 479 (bits 8-9 of 10) 
 ; 2,7: Vertical Retrace Start = Row 480 (bits 8-9 of 10) 
 ; 3: Start Vertical Blanking = Row 480 (bit 8 of 10) 
 ; 4: Line Compare = (bit 8 of 10) 
 mov ah,0x3E 
 out dx,ax 
 mov al,8           ; Preset Row Scan 
 ; 0-4: Preset Row Scan = 0 
 ; 5-6: Byte Panning Control = 0 
 ; 7: Reserved = 0 
 mov ah,0 
 out dx,ax 
 mov al,9           ; Maximum Scan Line 
 ; 0-4: Maximum Scan Lines = 1 (+1) 
 ; 5: Start Vertical Blanking = Row 480 (bit 9 of 10) 
 ; 6: Line Compare = () (bit 9 of 10) 
 ; 7: Double Scan Line Display = 0 
 mov ah,0x41 
 out dx,ax 
 mov al,0x10        ; Vertical Retrace Start (bits 0-7 of 10) 
 ; Primary centering control - increase number to move up 
 mov ah,0xE0        ; Row 480 
 out dx,ax 
 mov al,0x11        ; Vertical Retrace End 
 ; 0-3: Vertical Retrace End = 0010 
 ; 4: Clear Vertical Interrupt: state cleared 
 ; 5: Vertical Interrupt: disabled 
 ; 6: Refresh Bandwidth Select: 3 memory refresh cycles/scan line 
 ; 7: CRTC Register Protect: enabled 
 mov ah,0xA2 
 out dx,ax 
 mov al,0x12        ; Vertical Display Enable End (bits 0-7 of 10) 
 mov ah,0xBF        ; Row 447 
 out dx,ax 
 mov al,0x13        ; Offset 
 mov ah,0x20        ; 32 * 8 = 256 
 out dx,ax 
 mov al,0x14        ; Underline Location 
 ; 0-4: Underline Location = 0 
 ; 5: Display Address Dwell 4 (clocks per address inc): 0 (1) 
 ; 6: Display Address Unit 4 (unit size of address inc): 1 (4) 
 ; 7: Reserved = 0 
 mov ah,0x40 
 out dx,ax 
 mov al,0x15        ; Start Vertical Blanking (bits 0-7 of 10) 
 mov ah,0xBD        ; Row 445 
 out dx,ax 
 mov al,0x16        ; End Vertical Blanking 
 mov ah,0x0D        ; Row x0D 
 out dx,ax 
 mov al,0x17        ; CRTC Mode Control 
 ; 0: Display address bit 13 = Row bit 0: disabled 
 ; 1: Display address bit 14 = Row bit 1: disabled 
 ; 2: Row counter increment frequency (by line or by 2): by line 
 ; 3: Display Address Dwell 2 (clocks per address inc): 0 (1) 
 ; 4: Reserved = 0 
 ; 5: Display Address Unit Bank Selection (8k/32k): 32k 
 ; 6: Display Address Unit 2 (unit size of address inc): 0 (4) 
 ; 7: Reset/generate retrace signals: Generate 
 mov ah,0xA3 
 out dx,ax 
 mov edx,0x3C4      ; Sequencer 
 mov al,1 
 mov ah,1 
 out dx,ax 
 mov al,4 
 mov ah,0x0E 
 out dx,ax 
 mov edx,0x3CE      ; Graphics controller 
 mov al,5 
 mov ah,0x40 
 out dx,ax 
 mov al,6 
 mov ah,5 
 out dx,ax 
 mov edx,0x3DA 
 in  al,dx 
 mov edx,0x3C0 
 mov al,0x30 
 out dx,al 
 mov al,0x41 
 out dx,al 
 mov edx,0x3DA 
 in  al,dx 
 mov edx,0x3C0 
 mov al,0x33 
 out dx,al 
 mov al,0 
 out dx,al 
 popa 
 ret 
 
section .text 
ALIGNC 
section .data 
ALIGND 
section .bss 
ALIGNB