Image Map Image Map
Results 1 to 7 of 7

Thread: VGA timing for NTSC output with Mode X?

  1. #1

    Default VGA timing for NTSC output with Mode X?

    Hey all,

    I've been experimenting with getting a VGA card to produce an NTSC compatible signal, right now I'm using a box called TelevEyes. The box came with a little program to reprogram the VGA registers to output a 15khz signal, I have also tried using a utility called VGATV. The only problem is when a program (such as the game I'm working on), tries to mess with the vertical timing to change the resolution, strange things start happening. This then raises the question, is it possible to output a 320x240 mode-X signal to an NTSC television?

    Since mode-X is at 60hz, the same as NTSC, I didn't think that this would be a problem. Unfortunately when I run the TV display program then try to set Mode X, I get a rapidly rolling image, so something is up with the vertical timing.

    Here is my code for setting 320x240@60Hz mode X:

    Code:
    		out16(SC_INDEX, 0x0600 | MEMORY_MODE); // set mode to unchained
    
    		out16(SC_INDEX, 0x100); //synchronous reset for safety
    		out16(SC_INDEX, 0x300); //undo reset
    		
    		out16(CRTC_INDEX, 0x2c00 | V_RETRACE_END); // turn off write protect
    		out16(CRTC_INDEX, 0x0000 | UNDERLINE_LOCATION); // turn off dword mode
    		out16(CRTC_INDEX, 0xe300 | MODE_CONTROL);		// turn on byte mode
    
    		//Set the vertical resolution to 240
    		out16(CRTC_INDEX, 0x0d00 | V_TOTAL);
    		out16(CRTC_INDEX, 0x3e00 | OVERFLOW_VGA);
    		out16(CRTC_INDEX, 0xea00 | V_RETRACE_START);
    		out16(CRTC_INDEX, 0xac00 | V_RETRACE_END);
    		out16(CRTC_INDEX, 0xdf00 | V_DISPLAY_END);
    		out16(CRTC_INDEX, 0xe700 | V_BLANK_START);
    		out16(CRTC_INDEX, 0x0600 | V_BLANK_END);
    Does anyone know how I might be able to either make my code play nice with the TV utility or set my own mode for 320x240@60Hz on a TV? The issue is clearly when I mess with the vertical timing, if I keep the resolution at 320x200 it works fine.
    Currently working on new DOS game, Chuck Jones: Space Cop of the Future, Check out my Dev Blog. WARNING: contains rocket powered El Caminos

    Vintage Computers:
    Unitron Apple II clone, 2x Commodore Vic-20, Commodore 64, Commodore 128, Amiga 500, Macintosh Plus, Macintosh SE, AST Premium 286, 3 386sx PCs, Atari TT030

  2. #2
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    5,550
    Blog Entries
    1

    Default

    The "televeyes" and other cheap vga-to-TV boxes were very dumb (no framebuffer) so they relied on the host computer to set the correct card values to produce 15.7 KHz/60Hz output. The TSRs you mentioned (VGATV, etc.) work by hooking INT 10h calls and, rather than let the BIOS set up the mode, the TSR does it instead. That said, I have one of these and I remember running Doom (unchained 320x200) on a TV, which might have worked if Doom set 320x200 by first doing an int 10h and then reprogramming some registers. Memory is hazy on this specific point.

    For 320x240, your challenge is to figure out how to get as close to 15.7 KHz / 60 Hz as possible manually. "Proper" 320x240 unchained was most commonly done as follows:

    Code:
    ; This file was taken from Michael Abrash' XSHARP package, a library
    ; for programming mode X (320x240x256).
    
    ; Mode X (320x240, 256 colors) mode set routine. Works on all VGAs.
    ; C near-callable as:
    ;       void Set320x240Mode(void);
    ; Tested with TASM 2.0.
    ; Modified from public-domain mode set code by John Bridges.
    
    SC_INDEX equ    03c4h   ;Sequence Controller Index
    CRTC_INDEX equ  03d4h   ;CRT Controller Index
    MISC_OUTPUT equ 03c2h   ;Miscellaneous Output register
    SCREEN_SEG equ  0a000h  ;segment of display memory in mode X
    
            .model  small
            .data
    ; Index/data pairs for CRT Controller registers that differ between
    ; mode 13h and mode X.
    CRTParms label  word
            dw      00d06h  ;vertical total
            dw      03e07h  ;overflow (bit 8 of vertical counts)
            dw      04109h  ;cell height (2 to double-scan)
            dw      0ea10h  ;v sync start
            dw      0ac11h  ;v sync end and protect cr0-cr7
            dw      0df12h  ;vertical displayed
            dw      00014h  ;turn off dword mode
            dw      0e715h  ;v blank start
            dw      00616h  ;v blank end
            dw      0e317h  ;turn on byte mode
    CRT_PARM_LENGTH equ     (($-CRTParms)/2)
    
            .code
            public  _Set320x240Mode
    _Set320x240Mode proc    near
            push    bp      ;preserve caller's stack frame
            push    si      ;preserve C register vars
            push    di      ; (don't count on BIOS preserving anything)
    
            mov     ax,13h  ;let the BIOS set standard 256-color
            int     10h     ; mode (320x200 linear)
    
            mov     dx,SC_INDEX
            mov     ax,0604h
            out     dx,ax   ;disable chain4 mode
            mov     ax,0100h
            out     dx,ax   ;synchronous reset while switching clocks
    
            mov     dx,MISC_OUTPUT
            mov     al,0e7h
            out     dx,al   ;select 28 MHz dot clock & 60 Hz scanning rate
    
            mov     dx,SC_INDEX
            mov     ax,0300h
            out     dx,ax   ;undo reset (restart sequencer)
    
            mov     dx,CRTC_INDEX ;reprogram the CRT Controller
            mov     al,11h  ;VSync End reg contains register write
            out     dx,al   ; protect bit
            inc     dx      ;CRT Controller Data register
            in      al,dx   ;get current VSync End register setting
            and     al,7fh  ;remove write protect on various
            out     dx,al   ; CRTC registers
            dec     dx      ;CRT Controller Index
            cld
            mov     si,offset CRTParms ;point to CRT parameter table
            mov     cx,CRT_PARM_LENGTH ;# of table entries
    SetCRTParmsLoop:
            lodsw           ;get the next CRT Index/Data pair
            out     dx,ax   ;set the next CRT Index/Data pair
            loop    SetCRTParmsLoop
    
            mov     dx,SC_INDEX
            mov     ax,0f02h
            out     dx,ax   ;enable writes to all four planes
            mov     ax,SCREEN_SEG ;now clear all display memory, 8 pixels
            mov     es,ax         ; at a time
            sub     di,di   ;point ES:DI to display memory
            sub     ax,ax   ;clear to zero-value pixels
            mov     cx,8000h ;# of words in display memory
            rep     stosw   ;clear all of display memory
    
            pop     di      ;restore C register vars
            pop     si
            pop     bp      ;restore caller's stack frame
            ret
    _Set320x240Mode endp
            end
    Try these register values vs. the truncated ones you listed. No guarantees.

    All this being said, I seem to recall we covered this in DemoNews at some point (not in my VGA tweaks articles, but a guest writer). You may want to grab all 150 issues and check the "programming" sections out. I'll also see if I have a register dump in my archives that solves this problem.
    Offering a bounty for:
    - The software "Overhead Express" (doesn't have to be original, can be a copy)
    - A working Sanyo MBC-775, Olivetti M24, or Logabax 1600
    - Documentation and original disks for: Panasonic Sr. Partner, Zenith Z-160 series
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)

  3. #3

    Default

    Thanks Trixter,

    I've been looking at some of the issues of DemoNews there's quite a few of them so this may take some time. Found plenty of cool stuff already in those issues so it definitely hasn't been a waste of time! The values in my code look truncated because I used some macros for clarity, perhaps I should have defined them in my snippet, but I actually derived the values from the Michael Abrash code that you posted.
    Currently working on new DOS game, Chuck Jones: Space Cop of the Future, Check out my Dev Blog. WARNING: contains rocket powered El Caminos

    Vintage Computers:
    Unitron Apple II clone, 2x Commodore Vic-20, Commodore 64, Commodore 128, Amiga 500, Macintosh Plus, Macintosh SE, AST Premium 286, 3 386sx PCs, Atari TT030

  4. #4

    Default

    Basically got it working, the line counts just need to be about half of what they would be with regular Mode-X.
    P1030764.jpg

    There is some over scan but I think that's just the TV, I'm gonna try on my other Sony monitor which has adjustable height and see if everything is being displayed.

    I'm gonna do some more work to see if I can automatically detect if the registers have been messed with by a TSR and adjust to my special mode.
    Currently working on new DOS game, Chuck Jones: Space Cop of the Future, Check out my Dev Blog. WARNING: contains rocket powered El Caminos

    Vintage Computers:
    Unitron Apple II clone, 2x Commodore Vic-20, Commodore 64, Commodore 128, Amiga 500, Macintosh Plus, Macintosh SE, AST Premium 286, 3 386sx PCs, Atari TT030

  5. #5

    Default

    Hmm detection seems not to be as simple as I thought, I figured I could just check after setting mode 13 to see if the scan double bit was set (bit 7 of the max scan line register), however this bit never seems to be set, tested on real hardware and in dosbox. I would have expected it to be set whenever the registers havent been messed with by a special program.

    Code:
    out8(0x3D4, 0x09); //CRTC index for MAXIMUM_SCAN_LINE
    if(!(in8(0x3D5) & 0x80)) //if bit 7 is not set, then scan double is off, we must be displaying on a 15khz display
    {
    //set special TV mode
    }
    else
    {
    //set "normal" mode X
    }
    Currently working on new DOS game, Chuck Jones: Space Cop of the Future, Check out my Dev Blog. WARNING: contains rocket powered El Caminos

    Vintage Computers:
    Unitron Apple II clone, 2x Commodore Vic-20, Commodore 64, Commodore 128, Amiga 500, Macintosh Plus, Macintosh SE, AST Premium 286, 3 386sx PCs, Atari TT030

  6. #6
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    5,550
    Blog Entries
    1

    Default

    IIRC that bit was only used in compatibility modes (meaning, you'll see it set if you initialize a CGA mode, but not regular VGA).

    Sorry I can't be of more help, I'm spinning 50 plates at the moment...
    Offering a bounty for:
    - The software "Overhead Express" (doesn't have to be original, can be a copy)
    - A working Sanyo MBC-775, Olivetti M24, or Logabax 1600
    - Documentation and original disks for: Panasonic Sr. Partner, Zenith Z-160 series
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)

  7. #7

    Default

    No worries I found a register to check that works.

    Checking if the horizontal total register is 0x6B will tell you if an NTSC conversion TSR is installed, works with VGATV and TE.COM
    Currently working on new DOS game, Chuck Jones: Space Cop of the Future, Check out my Dev Blog. WARNING: contains rocket powered El Caminos

    Vintage Computers:
    Unitron Apple II clone, 2x Commodore Vic-20, Commodore 64, Commodore 128, Amiga 500, Macintosh Plus, Macintosh SE, AST Premium 286, 3 386sx PCs, Atari TT030

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •