home *** CD-ROM | disk | FTP | other *** search
- ; Generic assembler routines having to do with video adapter
- ;
- ; ---- Video Routines
- ;
- ; setvideomode()
- ; setvideotext()
- ; getcolor()
- ; putcolor()
- ; out_line()
- ; drawbox()
- ; home()
- ; movecursor()
- ; keycursor()
- ; putstring()
- ; setattr()
- ; scrollup()
- ; scrolldown()
- ; putstr()
- ; loaddac()
- ; spindac()
- ; adapter_init
- ; adapter_detect
- ; setnullvideo
- ;
- ; ---- Help (Video) Support
- ;
- ; setfortext()
- ; setforgraphics()
- ; setclear()
- ; findfont()
- ;
-
- ; required for compatibility if Turbo ASM
- IFDEF ??version
- MASM51
- QUIRKS
- ENDIF
-
- .MODEL medium,c
-
- .8086
-
- ; these must NOT be in any segment!!
- ; this get's rid of TURBO-C fixup errors
-
- extrn startvideo:far ; start your-own-video routine
- extrn readvideo:far ; read your-own-video routine
- extrn writevideo:far ; write your-own-video routine
- extrn endvideo:far ; end your-own-video routine
- extrn readvideopalette:far ; read-your-own-palette routine
- extrn writevideopalette:far ; write-your-own-palette routine
-
- extrn startdisk:far ; start disk-video routine
- extrn readdisk:far ; read disk-video routine
- extrn writedisk:far ; write disk-video routine
- extrn enddisk:far ; end disk-video routine
-
- extrn buzzer:far ; nyaah, nyaah message
-
- extrn getakey:far ; for keycursor routine
- extrn keypressed:far ; ...
-
- ; TARGA 28 May 80 - j mclain
- extrn StartTGA :far ; start TARGA
- extrn ReadTGA :far ; read TARGA
- extrn WriteTGA :far ; write TARGA
- extrn EndTGA :far ; end TARGA
- extrn ReopenTGA :far ; restart TARGA
-
- ; TARGA+ Mark Peterson 2-12-91
- extrn MatchTPlusMode:far
- extrn CheckForTPlus:far
- extrn WriteTPlusBankedPixel:far
- extrn ReadTPlusBankedPixel:far
- extrn TPlusLUT:far
-
- ; 8514/A routines ; changed 8514/A routines to near JCO 4/11/92
- extrn open8514 :near ; start 8514a
- extrn reopen8514:near ; restart 8514a
- extrn close8514 :near ; stop 8514a
- extrn fr85wdot :near ; 8514a write dot
- extrn fr85wbox :near ; 8514a write box
- extrn fr85rdot :near ; 8514a read dot
- extrn fr85rbox :near ; 8514a read box
- extrn w8514pal :near ; 8514a pallete update
-
- ; HW Compatible 8514/A routines ; AW, made near JCO 4/11/92
- extrn open8514hw :near ; start 8514a
- extrn reopen8514hw:near ; restart 8514a
- extrn close8514hw :near ; stop 8514a
- extrn fr85hwwdot :near ; 8514a write dot
- extrn fr85hwwbox :near ; 8514a write box
- extrn fr85hwrdot :near ; 8514a read dot
- extrn fr85hwrbox :near ; 8514a read box
- extrn w8514hwpal :near ; 8514a pallete update
-
- ; Hercules Routines
- extrn inithgc :far ; Initialize Hercules card graphics mode
- extrn termhgc :far ; Terminate Hercules card graphics mode
- extrn writehgc :far ; Hercules write dot
- extrn readhgc :far ; Hercules read dot
-
- ; setforgraphics/setfortext textsafe=save
- extrn savegraphics :far
- extrn restoregraphics :far
-
- .DATA
-
- ; ************************ External variables *****************************
-
- extrn oktoprint: word ; flag: == 1 if printf() will work
- extrn videoentry:byte ; video table entry flag
- extrn dotmode: word ; video mode (see the comments
- ; in front of the internal video
- ; table for legal dot modes)
- extrn textsafe2: word ; textsafe over-ride from videotable
-
- extrn sxdots:word,sydots:word ; physical screen number of dots
- extrn sxoffs:word,syoffs:word ; logical screen top left
- extrn colors:word ; colors
- extrn cyclelimit:word ; limiting factor for DAC-cycler
- extrn debugflag:word ; for debugging purposes only
-
- extrn boxcount:word ; (previous) box pt counter: 0 if none.
- extrn boxx:word, boxy:word ; zoom-box save-value locations
- extrn boxvalues:byte ; zoom-box save-pixel locations
-
- extrn xorTARGA:word ; TARGA 3 June 89 j mclain
- ; flag says xor pixels for box
-
- extrn cpu:word ; CPU type (86, 186, 286, or 386)
- extrn extraseg:word ; location of the EXTRA segment
-
- extrn suffix:word ; (safe place during video-mode switches)
-
- extrn swaplength:word ; savegraphics/restoregraphics stuff
- extrn swapoffset:dword ; ...
- extrn swapvidbuf:dword ; ...
- extrn swaptotlen:dword ; ...
-
- extrn rotate_lo:word, rotate_hi:word
-
- extrn bios_palette:word
- extrn paldata:byte
-
- extrn xdots:word
- extrn ydots:word
- extrn colors:word
- extrn NonInterlaced:word
- extrn PixelZoom:word
- extrn MaxColorRes:word
- extrn TPlusFlag:WORD ; TARGA+ Mark Peterson 2-12-91
- extrn ai_8514:byte ;flag for 8514a afi JCO 4/11/92
-
- ; ************************ Public variables *****************************
-
- public andcolor ; used by 'calcmand'
- public videotable
- public loadPalette ; flag for loading VGA/TARGA palette from disk
- public dacbox ; GIF saves use this
- public daclearn, daccount ; Rotate may want to use this
- public rowcount ; row-counter for decoder and out_line
- public gotrealdac ; loaddac worked, really got a dac
- public reallyega ; "really an EGA" (faking a VGA) flag
- public diskflag ; disk video active flag
- public video_type ; video adapter type
- public svga_type ; SuperVGA video adapter type
- public mode7text ; for egamono and hgc
- public textaddr ; text segment
- public textsafe ; setfortext/setforgraphics logic
- public boxcolor ; zoom box color
- public goodmode ; video mode ok?
- public text_type ; current mode's type of text
- public textrow ; current row in text mode
- public textcol ; current column in text mode
- public textrbase ; textrow is relative to this
- public textcbase ; textcol is relative to this
-
- public color_dark ; darkest color in palette
- public color_bright ; brightest color in palette
- public color_medium ; nearest to medbright grey in palette
-
- public swapsetup ; for savegraphics/restoregraphics
-
- public TPlusInstalled
-
- public vesa_detect ; set to 0 to disable VESA-detection
-
- public vxdots ; virtual scan line length
- ; arrays declared here, used elsewhere
- ; arrays not used simultaneously are deliberately overlapped
-
- ; ************************ Internal variables *****************************
-
- vxdots dw 0 ; virtual scan line length (bytes)
-
- goodmode dw 0 ; if non-zero, OK to read/write pixels
- dotwrite dw 0 ; write-a-dot routine: mode-specific
- dotread dw 0 ; read-a-dot routine: mode-specific
- linewrite dw 0 ; write-a-line routine: mode-specific
- lineread dw 0 ; read-a-line routine: mode-specific
- swapsetup dd 0 ; setfortext/graphics setup routine
- andcolor dw 0 ; "and" value used for color selection
- color db 0 ; the color to set a pixel
- videoflag db 0 ; special "your-own-video" flag
- tgaflag db 0 ; TARGA 28 May 89 - j mclain
- loadPalette db 0 ; TARGA/VGA load palette from disk
-
- f85flag db 0 ;flag for 8514a
-
- HGCflag db 0 ;flag for Hercules Graphics Adapter
-
- TPlusInstalled dw 0
-
- xga_pos_base dw 0 ; MCA Pos Base value
- xga_cardid dw 0 ; MCA Card ID value
- xga_reg_base dw -1 ; XGA IO Reg Base (-1 means dunno yet)
- xga_1mb dd 0 ; XGA 1MB aperture address
- xga_4mb dd 0 ; XGA 4MB aperture address
- xga_result dw 0 ; XGA_detect result code
- xga_isinmode dw 0 ; XGA is in this mode right now
- xga_iscolors dw 0 ; XGA using this many colors (0=64K)
- xga_clearvideo db 0 ; set to 80h to prevent video-clearing
- xga_loaddac db 0 ; set to 1 to load 'dacbox' on modesw
- xga_xdots dw 0 ; pixels per scan line
-
- align 2
- tmpbufptr dd 0
- color_dark dw 0 ; darkest color in palette
- color_bright dw 0 ; brightest color in palette
- color_medium dw 0 ; nearest to medbright grey in palette
- ; ; Zoom-Box values (2K x 2K screens max)
- boxcolor dw 0 ; Zoom-Box color
- reallyega dw 0 ; 1 if its an EGA posing as a VGA
- gotrealdac dw 0 ; 1 if loaddac has a dacbox
- diskflag dw 0 ; special "disk-video" flag
- palettega db 17 dup(0) ; EGA palette registers go here
- daclearn db 0 ; 0 if "learning" DAC speed
- dacnorm db 0 ; 0 if "normal" DAC update
- daccount dw 0 ; DAC registers to update in 1 pass
- dacbox db 773 dup(0) ; DAC goes here
- ;;saved_dacreg dw 0ffffh,0,0,0 ; saved DAC register goes here
-
- orvideo db 0 ; "or" value for setvideo
- align 2
- rowcount dw 0 ; row-counter for decoder and out_line
-
- videomem dw 0a000h ; VGA videomemory
- videoax dw 0 ; graphics mode values: ax
- videobx dw 0 ; graphics mode values: bx
- videocx dw 0 ; graphics mode values: cx
- videodx dw 0 ; graphics mode values: dx
-
- video_type dw 0 ; actual video adapter type:
- ; 0 = type not yet determined
- ; 1 = Hercules
- ; 2 = CGA (assumed if nothing else)
- ; 3 = EGA
- ; 4 = MCGA
- ; 5 = VGA
- ; 6 = VESA (not yet checked)
- ; 11 = 8514/A (not yet checked)
- ; 12 = TIGA (not yet checked)
- ; 13 = TARGA (not yet checked)
- svga_type dw 0 ; (forced) SVGA type
- ; 1 = ahead "A" type
- ; 2 = ATI
- ; 3 = C&T
- ; 4 = Everex
- ; 5 = Genoa
- ; 6 = Ncr
- ; 7 = Oak-Tech
- ; 8 = Paradise
- ; 9 = Trident
- ; 10 = Tseng 3000
- ; 11 = Tseng 4000
- ; 12 = Video-7
- ; 13 = ahead "B" type
- ; 14 = "null" type (for testing only)
- mode7text dw 0 ; nonzero for egamono and hgc
- textaddr dw 0b800h ; b800 for mode 3, b000 for mode 7
- textsafe dw 0 ; 0 = default, runup chgs to 1
- ; 1 = yes
- ; 2 = no, use 640x200
- ; 3 = bios, yes plus use int 10h-1Ch
- ; 4 = save, save entire image
- text_type dw 0 ; current mode's type of text:
- ; 0 = real text, mode 3 (or 7)
- ; 1 = 640x200x2, mode 6
- ; 2 = some other mode, graphics
- video_entries dw 0 ; offset into video_entries table
- video_bankadr dw 0 ; offset of video_banking routine
- video_bankseg dw 0 ; segment of video_banking routine
-
- textrow dw 0 ; for putstring(-1,...)
- textcol dw 0 ; for putstring(..,-1,...)
- textrbase dw 0 ; textrow is relative to this
- textcbase dw 0 ; textcol is relative to this
- cursortyp dw 0
-
- tandyseg dw ? ;Tandy 1000 video segment address
- tandyofs dw ? ;Tandy 1000 Offset into video buffer
- tandyscan dw ? ;Tandy 1000 scan line address pointer
-
-
- ; ******************* "Tweaked" VGA mode variables ************************
-
- ; 704 x 528 mode
- x704y528 db 704/8 ; number of screen columns
- db 528/16 ; number of screen rows
- db 68h, 57h, 58h, 8Bh ; CRTC Registers
- db 59h, 86h, 3EH,0F0h
- db 0h, 60h, 0h, 0h
- db 0h, 0h, 2h, 3Dh
- db 19h, 8Bh, 0Fh, 2Ch
- db 0h, 18h, 38h,0E3h
- db 0FFh
- ; 720 x 540 mode
- x720y540 db 720/8 ; number of screen columns
- db 540/16 ; number of screen rows
- db 6Ah, 59h, 5Ah, 8Dh ; CRTC Registers
- db 5Eh, 8Bh, 4AH,0F0h
- db 0h, 60h, 0h, 0h
- db 0h, 0h, 2h, 49h
- db 24h, 86h, 1Bh, 2Dh
- db 0h, 24h, 44h,0E3h
- db 0FFh
- ; 736 x 552 mode
- x736y552 db 736/8 ; number of screen columns
- db 552/16 ; number of screen rows
- db 6Ch, 5Bh, 5Ch, 8Fh ; CRTC Registers
- db 5Fh, 8Ch, 56H,0F0h
- db 0h, 60h, 0h, 0h
- db 0h, 0h, 2h, 55h
- db 2Bh, 8Dh, 27h, 2Eh
- db 0h, 30h, 50h,0E3h
- db 0FFh
- ; 752 x 564 mode
- x752y564 db 752/8 ; number of screen columns
- db 564/16 ; number of screen rows
- db 6Eh, 5Dh, 5Eh, 91h ; CRTC Registers
- db 62h, 8Fh, 62H,0F0h
- db 0h, 60h, 0h, 0h
- db 0h, 0h, 2h, 61h
- db 37h, 89h, 33h, 2Fh
- db 0h, 3Ch, 5Ch,0E3h
- db 0FFh
- ; 768 x 576 mode
- x768y576 db 768/8 ; number of screen columns
- db 576/16 ; number of screen rows
- db 70h, 5Fh, 60h, 93h ; CRTC Registers
- db 66h, 93h, 6EH,0F0h
- db 0h, 60h, 0h, 0h
- db 0h, 0h, 2h, 6Dh
- db 43h, 85h, 3Fh, 30h
- db 0h, 48h, 68h,0E3h
- db 0FFh
- ; 784 x 588 mode
- x784y588 db 784/8 ; number of screen columns
- db 588/16 ; number of screen rows
- db 72h, 61h, 62h, 95h ; CRTC Registers
- db 69h, 96h, 7AH,0F0h
- db 0h, 60h, 0h, 0h
- db 0h, 0h, 2h, 79h
- db 4Fh, 81h, 4Bh, 31h
- db 0h, 54h, 74h,0E3h
- db 0FFh
- ; 800 x 600 mode
- x800y600 db 800/8 ; number of screen columns
- db 600/16 ; number of screen rows
- db 74h, 63h, 64h, 97h ; CRTC Registers
- db 68h, 95h, 86H,0F0h
- db 0h, 60h, 0h, 0h
- db 0h, 0h, 2h, 85h
- db 5Bh, 8Dh, 57h, 32h
- db 0h, 60h, 80h,0E3h
- db 0FFh
-
- x360y480 db 360/8 ; number of screen columns
- db 480/16 ; number of screen rows
- db 6bh, 59h, 5ah, 8eh ; CRTC Registers
- db 5eh, 8ah, 0DH,03Eh
- db 0h, 40h, 00h, 0h
- db 0h, 0h, 0h, 31h
- db 0EAh, 0ACh, 0DFh, 2Dh
- db 0h,0E7h, 06h,0E3h
- db 0FFh
-
- x320y480 db 320/8 ; number of screen columns
- db 480/16 ; number of screen rows
- db 5fh, 4fh, 50h, 82h ; CRTC Registers
- db 54h, 80h, 0DH,03Eh
- db 0h, 40h, 00h, 0h
- db 0h, 0h, 0h, 0h
- db 0EAh, 0AEh, 0DFh, 28h
- db 0h,0E7h, 006h,0E3h
- db 0FFh
-
- ; mode x from Michael Abrash
- x320y240 db 320/8 ; number of screen columns
- db 240/16 ; number of screen rows
- db 05fh, 04fh, 050h, 082h
- db 054h, 080h, 0dh, 03eh
- db 00h, 041h, 00h, 00h
- db 00h, 00h, 00h, 00h
- db 0eah, 0ach, 0dfh, 028h
- db 00h, 0e7h, 06h, 0e3h
- db 0ffh
-
- x320y400 db 320/8 ; number of screen columns
- db 400/16 ; number of screen rows
- db 5fh, 4fh, 50h, 82h ; CRTC Registers
- db 54h, 80h,0bfh, 1fh
- db 00h, 40h, 00h, 00h
- db 00h, 00h, 00h, 00h
- db 9ch, 8eh, 8fh, 28h
- db 00h, 96h,0b9h,0E3h
- db 0FFh
-
- x640y400 db 640/8 ; number of screen columns
- db 400/16 ; number of screen rows
- db 5eh, 4fh, 50h, 01h ; CRTC Registers
- db 54h, 9fh,0c0h, 1fh
- db 00h, 40h, 00h, 00h
- db 00h, 00h, 00h, 00h
- db 9ch,08eh, 8fh, 28h
- db 00h, 95h,0bch,0c3h
- db 0ffh
- ;for VGA
- x400y600 db 400/8
- db 600/16
- db 74h,63h,64h,97h
- db 68h,95h,86h,0F0h
- db 00h,60h,00h,00h
- db 00h,00h,00h,31h
- db 5Bh,8Dh,57h,32h
- db 0h,60h,80h,0E3h
- db 0FFh
- ;for VGA
- x376y564 db 376/8
- db 564/16
- db 6eh,5dh,5eh,91h
- db 62h,8fh,62h,0F0h
- db 00h,60h,00h,00h
- db 00h,00h,00h,31h
- db 37h,89h,33h,2fh
- db 0h,3ch,5ch,0E3h
- db 0FFh
- ;for VGA
- x400y564 db 400/8
- db 564/16
- db 74h,63h,64h,97h
- db 68h,95h,62h,0F0h
- db 00h,60h,00h,00h
- db 00h,00h,00h,31h
- db 37h,89h,33h,32h
- db 0h,3ch,5ch,0E3h
- db 0FFh
-
- testati db 832/8
- db 612/16
- db 7dh,65h,68h,9fh
- db 69h,92h,44h,1Fh
- db 00h,00h,00h,00h
- db 00h,00h,00h,00h
- db 34h,86h,37h,34h
- db 0fh,34h,40h,0E7h
- db 0FFh
-
- align 2
-
- tweaks dw offset x704y528 ; tweak table
- dw offset x704y528
- dw offset x720y540
- dw offset x736y552
- dw offset x752y564
- dw offset x768y576
- dw offset x784y588
- dw offset x800y600
- dw offset x360y480
- dw offset x320y400
- dw offset x640y400 ; Tseng Super VGA
- dw offset x400y600 ; new tweak (VGA)
- dw offset x376y564 ; new tweak (VGA)
- dw offset x400y564 ; new tweak (VGA)
- dw offset x720y540 ; ATI Tweak
- dw offset x736y552 ; ATI Tweak
- dw offset x752y564 ; ATI Tweak
- dw offset testati ; ATI 832x816 (works!)
- dw offset x320y480
- dw offset x320y240
-
- tweakflag dw 0 ; tweak mode active flag
- tweaktype dw 0 ; 8 or 9 (320x400 or 360x480)
-
- bios_vidsave dw 0 ; for setfortext/graphics
-
- .CODE
-
- FRAME MACRO regs
- push bp
- mov bp, sp
- IRP reg, <regs>
- push reg
- ENDM
- ENDM
-
- UNFRAME MACRO regs
- IRP reg, <regs>
- pop reg
- ENDM
- pop bp
- ENDM
-
-
- ; Video Table Entries
- ;
- ; The Video Table has been moved to a FARDATA segment to relieve
- ; some of the pressure on the poor little overloaded 64K DATA segment.
-
- .code
-
- video_requirements dw 0 ; minimal video_type req'd
- dw 1, 3, 4, 5, 5, 5, 5, 5, 1, 1 ; dotmodes 1 - 10
- dw 1, 5, 2, 1, 5, 5, 5, 5, 1, 5 ; dotmodes 11 - 20
- dw 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 ; dotmodes 21 - 30
-
- videotable label byte ; video table actually starts on the NEXT byte
-
- ; Feel free to add your favorite video adapter to FRACTINT.CFG.
- ; The entries hard coded here are repeated from fractint.cfg in case
- ; it gets lost/destroyed, so a user can still have some modes.
-
- ; Currently available Video Modes are (use the BIOS as a last resort)
- ; 1) use the BIOS (INT 10H, AH=12/13, AL=color) ((SLOW))
- ; 2) pretend it's a (perhaps super-res) EGA/VGA
- ; 3) pretend it's an MCGA
- ; 4) SuperVGA 256-Color mode using the Tseng Labs Chipset
- ; 5) SuperVGA 256-Color mode using the Paradise Chipset
- ; 6) SuperVGA 256-Color mode using the Video-7 Chipset
- ; 7) Non-Standard IBM VGA 360 x 480 x 256-Color mode
- ; 8) SuperVGA 1024x768x16 mode for the Everex Chipset
- ; 9) TARGA video modes
- ; 10) HERCULES video mode
- ; 11) Non-Video [disk or RAM] "video"
- ; 12) 8514/A video modes
- ; 13) CGA 320x200x4-color and 640x200x2-color modes
- ; 14) Tandy 1000 video modes
- ; 15) SuperVGA 256-Color mode using the Trident Chipset
- ; 16) SuperVGA 256-Color mode using the Chips & Tech Chipset
- ; 17) SuperVGA 256-Color mode using the ATI VGA Wonder Chipset
- ; 18) SuperVGA 256-Color mode using the Everex Chipset
- ; 19) Roll-Your-Own video, as defined in YOURVID.C
- ; 20) SuperVGA 1024x768x16 mode for the ATI VGA Wonder Chipset
- ; 21) SuperVGA 1024x768x16 mode for the Tseng Labs Chipset
- ; 22) SuperVGA 1024x768x16 mode for the Trident Chipset
- ; 23) SuperVGA 1024x768x16 mode for the Video 7 Chipset
- ; 24) SuperVGA 1024x768x16 mode for the Paradise Chipset
- ; 25) SuperVGA 1024x768x16 mode for the Chips & Tech Chipset
- ; 26) SuperVGA 1024x768x16 mode for the Everex Chipset
- ; 27) SuperVGA Auto-Detect mode
- ; 28) VESA modes
- ; 29) True Color Auto-Detect
-
- ; (Several entries have been commented out - they should/did work,
- ; but are handled by alternative entries. Where multiple SuperVGA
- ; entries are covered by a single SuperVGA Autodetect mode, the
- ; individual modes have been commented out. Where a SuperVGA
- ; Autodetect mode covers only one brand of adapter, the Autodetect
- ; mode has been commented out to avoid confusion.)
-
- ; |--Adapter/Mode-Name------|-------Comments-----------|
-
- ; |------INT 10H------|Dot-|--Resolution---|
- ; |key|--AX---BX---CX---DX|Mode|--X-|--Y-|Color|
-
- db "IBM 16-Color EGA ",0,"Standard EGA hi-res mode ",0
- dw 1060, 10h, 0, 0, 0, 2, 640, 350, 16
- db "IBM 256-Color VGA/MCGA ",0,"Quick and LOTS of colors ",0
- dw 1061, 13h, 0, 0, 0, 3, 320, 200, 256
- db "IBM 16-Color VGA ",0,"Nice high resolution ",0
- dw 1062, 12h, 0, 0, 0, 2, 640, 480, 16
- db "IBM 4-Color CGA ",0,"(Ugh - Yuck - Bleah) ",0
- dw 1063, 4h, 0, 0, 0, 13, 320, 200, 4
- db "IBM Hi-Rez B&W CGA ",0,"('Hi-Rez' Ugh - Yuck) ",0
- dw 1064, 6h, 0, 0, 0, 13, 640, 200, 2
- db "IBM B&W EGA ",0,"(Monochrome EGA) ",0
- dw 1065, 0fh, 0, 0, 0, 2, 640, 350, 2
- db "IBM B&W VGA ",0,"(Monochrome VGA) ",0
- dw 1066, 11h, 0, 0, 0, 2, 640, 480, 2
- db "IBM Low-Rez EGA ",0,"Quick but chunky ",0
- dw 1067, 0dh, 0, 0, 0, 2, 320, 200, 16
- db "IBM VGA (non-std) ",0,"Register Compatibles ONLY",0
- dw 1068, 0h, 0, 0, 9, 7, 320, 400, 256
- db "IBM VGA (non-std) ",0,"Register Compatibles ONLY",0
- dw 1084, 0h, 0, 0, 8, 7, 360, 480, 256
- db "SuperVGA/VESA Autodetect ",0,"Works with most SuperVGA ",0
- dw 1085, 0, 0, 0, 0, 27, 800, 600, 16
- db "SuperVGA/VESA Autodetect ",0,"Works with most SuperVGA ",0
- dw 1086, 0, 0, 0, 0, 27,1024, 768, 16
- db "SuperVGA/VESA Autodetect ",0,"Works with most SuperVGA ",0
- dw 1087, 0, 0, 0, 0, 27, 640, 400, 256
- db "SuperVGA/VESA Autodetect ",0,"Works with most SuperVGA ",0
- dw 1088, 0, 0, 0, 0, 27, 640, 480, 256
- db "SuperVGA/VESA Autodetect ",0,"Works with most SuperVGA ",0
- dw 1089, 0, 0, 0, 0, 27, 800, 600, 256
- db "SuperVGA/VESA Autodetect ",0,"Works with most SuperVGA ",0
- dw 1090, 0, 0, 0, 0, 27,1024, 768, 256
- db "VESA Standard interface ",0,"OK: Andy Fu - Chips&Tech ",0
- dw 1091,4f02h,106h, 0, 0, 28,1280,1024, 16
- db "VESA Standard interface ",0,"OK: Andy Fu - Chips&Tech ",0
- dw 1092,4f02h,107h, 0, 0, 28,1280,1024, 256
- db "8514/A Low Res ",0,"HW/AI (AI Reqs HDILOAD) ",0
- dw 1093, 3h, 0, 0, 1, 12, 640, 480, 256
- db "8514/A High Res ",0,"HW/AI (AI Reqs HDILOAD) ",0
- dw 1094, 3h, 0, 0, 1, 12,1024, 768, 256
- db "8514/A Low W/Border ",0,"HW/AI (AI Reqs HDILOAD) ",0
- dw 1095, 3h, 0, 0, 1, 12, 632, 474, 256
- db "8514/A High W/Border ",0,"HW/AI (AI Reqs HDILOAD) ",0
- dw 1096, 3h, 0, 0, 1, 12,1016, 762, 256
- db "IBM Med-Rez EGA ",0,"(Silly but it's there!) ",0
- dw 1097, 0eh, 0, 0, 0, 2, 640, 200, 16
- db "IBM VGA (non-std) ",0,"Register Compatibles ONLY",0
- dw 1098, 0h, 0, 0, 18, 7, 320, 480, 256
- db "Hercules Graphics ",0,"OK: Timothy Wegner ",0
- dw 1099, 8h, 0, 0, 0, 10, 720, 348, 2
- db "Tandy 1000 ",0,"OK: Joseph Albrecht ",0
- dw 1100, 9h, 0, 0, 0, 14, 320, 200, 16
- db "Pdise/AST/COMPAQ VGA ",0,"OK: Phil Wilson ",0
- dw 1101, 59h, 0, 0, 0, 1, 800, 600, 2
- db 140 dup(0) ; 2 unused slots here default table
- db "Disk/RAM 'Video' ",0,"Full-Page L-Jet @ 75DPI ",0
- dw 1104, 3h, 0, 0, 0, 11, 800, 600, 2
- db "Disk/RAM 'Video' ",0,"Full-Page L-Jet @ 150DPI ",0
- dw 1105, 3h, 0, 0, 0, 11,1600,1200, 2
- db "Disk/RAM 'Video' ",0,"Full-Page Epson @ 120DPI ",0
- dw 1106, 3h, 0, 0, 0, 11, 768, 960, 2
- db "Disk/RAM 'Video' ",0,"Full-Page Paintjet 90DPI ",0
- dw 1107, 3h, 0, 0, 0, 11, 960, 720, 256
- db "Disk/RAM 'Video' ",0,"For Background Fractals ",0
- dw 1108, 3h, 0, 0, 0, 11, 800, 600, 256
- db "Disk/RAM 'Video' ",0,"For Background Fractals ",0
- dw 1109, 3h, 0, 0, 0, 11,2048,2048, 256
- db 280 dup(0) ; 4 unused slots here default table
- db 70 dup(0) ; 1 slot reserved for unassigned current mode
-
-
- bios_savebuf db 256 dup(0) ; enough for 4 blocks (64 bytes/block)
-
- .code
-
- ; XGA Graphics mode setup values
- ; (the first two entries in each line
- ; indicate where the table values are to be stored)
- ;
- ; 1024x768x256 vvv
- ; 1024x768x16 -----vvvv
- ; 640x480x256 -----------vvvv
- ; 640x480x65536 ----------------vvvv
- ; 800x600x16 -----------------------vvvv
- ; 800x600x256 -----------------------------vvvv
- ; 800x600x65536 ----------------------------------vvvv
-
- xga_twidth dw 9 ; width of these tables
-
- xga_requir dw 0, 0, 0dh, 05h, 01h, 09h, 01h, 01h, 09h ; adapter requirements
- xga_colors dw 0, 0, 256, 16, 256, 0, 16, 256, 0 ; 0 means 64K colors
- xga_swidth dw 0, 0, 1024, 512, 640, 1280, 400, 800, 1600 ; bytes / scan line
-
- xga_val db 004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; interrupt enable
- db 005h, 000h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh ; interrupt status
- db 000h, 000h, 004h, 004h, 004h, 004h, 004h, 004h, 004h ; operating mode
- db 00ah, 064h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; palette mask
- db 001h, 000h, 001h, 001h, 001h, 001h, 001h, 001h, 001h ; vid mem aper cntl
- db 008h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; vid mem aper indx
- db 006h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; virt mem ctl
- db 009h, 000h, 003h, 002h, 003h, 004h, 002h, 003h, 004h ; mem access mode
- db 00ah, 050h, 001h, 001h, 001h, 001h, 001h, 001h, 001h ; disp mode 1
- db 00ah, 050h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; disp mode 1
- db 00ah, 010h, 09dh, 09dh, 063h, 063h, 088h, 088h, 088h ; horiz tot lo.
- db 00ah, 011h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; horiz tot hi.
- db 00ah, 012h, 07fh, 07fh, 04fh, 04fh, 063h, 063h, 063h ; hor disp end lo
- db 00ah, 013h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; hor disp end hi
- db 00ah, 014h, 080h, 080h, 050h, 050h, 064h, 064h, 064h ; hor blank start lo
- db 00ah, 015h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; hor blank start hi
- db 00ah, 016h, 09ch, 09ch, 062h, 062h, 087h, 087h, 087h ; hor blank end lo
- db 00ah, 017h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; hor blank end hi
- db 00ah, 018h, 087h, 087h, 055h, 055h, 06ah, 06ah, 06ah ; hor sync start lo
- db 00ah, 019h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; hor sync start hi
- db 00ah, 01ah, 09ch, 09ch, 061h, 061h, 084h, 084h, 084h ; hor sync end lo
- db 00ah, 01bh, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; hor sync end hi
- db 00ah, 01ch, 040h, 040h, 000h, 000h, 000h, 000h, 000h ; hor sync pos
- db 00ah, 01eh, 004h, 004h, 000h, 000h, 000h, 000h, 000h ; hor sync pos
- db 00ah, 020h, 030h, 030h, 00ch, 00ch, 086h, 086h, 086h ; vert tot lo
- db 00ah, 021h, 003h, 003h, 002h, 002h, 002h, 002h, 002h ; vert tot hi
- db 00ah, 022h, 0ffh, 0ffh, 0dfh, 0dfh, 057h, 057h, 057h ; vert disp end lo
- db 00ah, 023h, 002h, 002h, 001h, 001h, 002h, 002h, 002h ; vert disp end hi
- db 00ah, 024h, 000h, 000h, 0e0h, 0e0h, 058h, 058h, 058h ; vert blank start lo
- db 00ah, 025h, 003h, 003h, 001h, 001h, 002h, 002h, 002h ; vert blank start hi
- db 00ah, 026h, 02fh, 02fh, 00bh, 00bh, 085h, 085h, 085h ; vert blank end lo
- db 00ah, 027h, 003h, 003h, 002h, 002h, 002h, 002h, 002h ; vert blank end hi
- db 00ah, 028h, 000h, 000h, 0eah, 0eah, 058h, 058h, 058h ; vert sync start lo
- db 00ah, 029h, 003h, 003h, 001h, 001h, 002h, 002h, 002h ; vert sync start hi
- db 00ah, 02ah, 008h, 008h, 0ech, 0ech, 06eh, 06eh, 06eh ; vert sync end
- db 00ah, 02ch, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh ; vert line comp lo
- db 00ah, 02dh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh ; vert line comp hi
- db 00ah, 036h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; sprite cntl
- db 00ah, 040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; start addr lo
- db 00ah, 041h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; start addr me
- db 00ah, 042h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; start addr hi
- db 00ah, 043h, 080h, 040h, 050h, 0a0h, 032h, 064h, 0c8h ; pixel map width lo
- db 00ah, 044h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; pixel map width hi
- db 00ah, 054h, 00dh, 00dh, 000h, 000h, 001h, 001h, 001h ; clock sel
- db 00ah, 051h, 003h, 002h, 003h, 004h, 002h, 003h, 004h ; display mode 2
- db 00ah, 070h, 000h, 000h, 000h, 000h, 080h, 080h, 080h ; ext clock sel
- db 00ah, 050h, 00fh, 00fh, 0c7h, 0c7h, 007h, 007h, 007h ; display mode 1
- db 00ah, 055h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; Border Color
- db 00ah, 060h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; Sprite Pal Lo
- db 00ah, 061h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; Sprite Pal hi
- db 00ah, 062h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; Sprite Pre Lo
- db 00ah, 063h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ; Sprite Pre hi
- db 00ah, 064h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh ; Palette Mask
- db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh ; end of the list
-
-
- xga_newbank proc ; XGA-specific bank-switching routine
- cmp xga_isinmode,2 ; are we in an XGA-specific mode?
- jl return ; nope. bail out.
- mov curbk,ax ; save the new current bank value
- mov dx,xga_reg_base ; Select Page
- add dx,08h
- out dx,al ; assumes bank number is in al
- return: ret
- xga_newbank endp
-
- xga_16linewrite proc near ; 16-color Line Write
- mov bx,ax ; calculate the # of columns
- sub bx,cx
- mov ax,xga_xdots ; this many dots / line
- mul dx ; times this many lines - ans in dx:ax
- push cx ; save the X-value for a tad
- shr cx,1 ; and adjust for two bits per pixel
- add ax,cx ; plus this many x-dots
- adc dx,0 ; answer in dx:ax - dl=bank, ax=offset
- mov di,ax ; save offset in DI
- pop cx ; restore the X-value
- mov ax,dx ; xga_newbank expects bank in al
- new_bank:
- call far ptr xga_newbank
- same_bank:
- mov ah,es:[di] ; grab the old byte value
- mov al,[si] ; and the new color value
- and al,0fh ; isolate the bits we want
- test cx,1 ; odd pixel address?
- jnz xga_sk1 ; yup
- and ah,0f0h ; isolate the low-order
- jmp short xga_sk2
- xga_sk1:and ah,0fh ; isolate the high-order
- shl al,1
- shl al,1
- shl al,1
- shl al,1
- xga_sk2:or al,ah ; combine the two nibbles
- mov es:[di],al ; write the dot
- inc si ; increment the source addr
- dec bx ; more to go?
- jz done ; nope
- inc cx ; next pixel
- test cx,1 ; odd pixel?
- jnz same_bank ; yup
- inc di ; increment the destination
- cmp di,0 ; segment wrap?
- jnz same_bank ; nope
- mov ax,curbk ; update the bank cvalue
- inc ax
- jmp new_bank
- done: ret
- xga_16linewrite endp
-
- xga_super16addr proc near ; can be put in-line but shared by
- ; read and write routines
- clc ; clear carry flag
- push ax ; save this for a tad
- mov ax,xga_xdots ; this many dots / line
- mul dx ; times this many lines - ans in dx:ax
- push cx ; save the X-value for a tad
- shr cx,1 ; and adjust for two bits per pixel
- add ax,cx ; plus this many x-dots
- adc dx,0 ; answer in dx:ax - dl=bank, ax=offset
- pop cx ; restore the X-value
- mov bx,ax ; save this in BX
- cmp dx,curbk ; see if bank changed
- je same_bank ; jump if old bank ok
- mov ax,dx ; xga_newbank expects bank in al
- call far ptr xga_newbank
- same_bank:
- pop ax ; restore AX
- ret
- xga_super16addr endp
-
- xga_16write proc near ; XGA 256 colors write-a-dot
- call xga_super16addr ; calculate address and switch banks
- mov ah,es:[bx] ; grab the old byte value
- and al,0fh ; isolate the bits we want
- test cx,1 ; odd pixel address?
- jnz xga_sk1 ; yup
- and ah,0f0h ; isolate the low-order
- jmp short xga_sk2
- xga_sk1:and ah,0fh ; isolate the high-order
- shl al,1
- shl al,1
- shl al,1
- shl al,1
- xga_sk2:or al,ah ; combine the two nibbles
- mov es:[bx],al ; write the dot
- ret ; we done.
- xga_16write endp
-
- xga_16read proc near ; XGA 256 colors read-a-dot
- call xga_super16addr ; calculate address and switch banks
- mov al,es:[bx] ; read the dot
- test cx,1 ; odd number of pixels?
- jz xga_sk1 ; nope
- shr ax,1 ; adjust for odd pixel count
- shr ax,1
- shr ax,1
- shr ax,1
- xga_sk1:and ax,0fh ; isolate the byte value
- ret ; we done.
- xga_16read endp
-
- xga_clear proc uses es si di ; clear the XGA memory
- cmp xga_clearvideo,0 ; should we really do this?
- jne return ; nope. skip it.
- mov bx,xga_result ; find out how much memory we have
- and bx,08h ; in 64K pages
- add bx,08h
- mov ax,0a000h ; set up to clear 0a0000-0affff
- push ax
- pop es
- xloop: mov ax,bx ; initialize the bank addr
- call xga_newbank
- mov ax,0
- mov cx,16384 ; clear out 32K
- mov di,0
- rep stosw
- mov cx,16384 ; clear out 32K
- rep stosw
- dec bx ; another page?
- cmp bx,0
- jge xloop
- return: ret
- xga_clear endp
-
- xga_setpalette proc uses es si di, palette:word ; set the XGA palette
- cmp xga_isinmode,2 ; are we in an XGA graphics mode?
- jl return ; nope
-
- mov dx,xga_reg_base ; wait for a retrace
- add dx,5
- mov al,1 ; clear the start-of-blanking
- out dx,al
- bloop: in al,dx
- test al,01h ; blanking started?
- jz bloop ; nope - try again
-
- mov dx,xga_reg_base ; set up for a palette load
- add dx,0ah
- mov ax,0064h ; make invisible
- out dx,ax
- mov ax,0055h ; border color
- out dx,ax
- mov ax,0066h ; palette mode
- out dx,ax
- mov ax,0060h ; start at palette 0
- out dx,ax
- mov ax,0061h
- out dx,ax
-
- mov si,palette
- mov cx,768
- mov ax,065h ; palette update
- out dx,al
- inc dx ; palette data
- .186
- rep outsb
- .8086
- dec dx
-
- mov ax,0ff64h ; make visible
- out dx,ax
-
- return: ret
- xga_setpalette endp
-
- xga_detect proc uses es di si
-
- cmp xga_reg_base,-2 ; has the XGA detector already failed?
- jne xga_sk1 ; ne = not yet
- jmp xga_notfound ; e = yes, fail again
- xga_sk1:cmp xga_reg_base,-1 ; have we already found the XGA?
- je xga_loc ; e = no
- jmp xga_found ; yes, process it
-
- xga_loc:push bp ; save around int 10H calls
- mov ax,1f00h ; XGA-2 detect:
- int 10h ; get DMQS length
- pop bp ; restore BP
- cmp al,1fh ; did this work?
- jne xga_man ; nope - try the older, manual approach
- cmp bx,768 ; room for the results?
- ja xga_man ; no?!? try the older approach
- mov ax,1f01h ; get DMQS info
- push ds ; into here
- pop es ; ...
- mov di, offset dacbox ; ...
- int 10h ; ...
- cmp al,1fh ; safety first
- jne xga_man ; ?? try the older approach
- mov bx, word ptr dacbox+09h ; get the register base
- mov xga_reg_base,bx ; save the results
- mov xga_result,1 ; say we found an adapter
- cmp byte ptr dacbox+15h,4 ; do we have 1MB of adapter RAM?
- jb @F ; nope
- or xga_result,8h ; yup - say so.
- @@: mov bx, word ptr dacbox+13h ; get the composite monitor ID
- and bx,0f00h ; high-rez-monitor?
- cmp bx,0f00h ; ..
- je @F ; nope
- or xga_result,4 ; yup
- @@: jmp xga_found ; say we found the adapter
-
- xga_man:mov ah,35h ; DOS get interrupt vector
- mov al,15h ; Int 15h
- int 21h ; returns vector in es:bx
- mov ax,es ; segment part
- or ax,ax ; undefined vector?
- jnz xga_sk2 ; nz = no, OK so far
- jmp xga_notfound ; z = yes - not an MCA machine
- xga_sk2:mov dx,-1 ; start with an invalid POS address
- mov ax,0c400h ; look for POS base address
- int 15h ; (Microchannel machines only)
- jnc xga_sk3 ; nc = success
- jmp xga_notfound ; error - not an MC machine
- xga_sk3:mov xga_pos_base,dx ; save pos_base_address
- xor cx,cx ; check all MCA slots & motherboard
- cmp dx,-1 ; do we have a good POS?
- jne xga_lp1 ; ne = yes, proceed with MCA checks
- jmp xga_notfound ; no, fail
- xga_lp1:cli ; no interrupts, please
- cmp cx,0 ; treat the motherboard differently?
- jne xga_sk4 ; ne = yes
- mov al,0dfh ; enable the motherboard for setup
- mov dx,94h
- out dx,al
- jmp short xga_sk5
- xga_sk4:mov ax,0c401h ; enable an MCA slot for setup
- mov bx,cx ; this slot
- int 15h
- xga_sk5:mov dx,xga_pos_base ; get pos record for the slot ID
- in ax,dx
- mov xga_cardid,ax
- add dx,2 ; compute IO Res Base
- in al,dx ; get POS data byte1
- mov byte ptr xga_1mb,al ; save it temporarily
- inc dx ; switch to byte 2
- in al,dx ; get POS data
- mov byte ptr xga_1mb+1,al ; save it temporarily
- inc dx ; switch to byte 3
- in al,dx ; get POS data
- mov byte ptr xga_1mb+2,al ; save it temporarily
- inc dx ; switch to byte 4
- in al,dx ; get POS data
- mov byte ptr xga_1mb+3,al ; save it temporarily
- cmp cx,0 ; treat the motherboard differently
- jne xga_sk6 ; ne = yes
- mov al,0ffh ; enable the motherboard for normal
- out 094h,al
- jmp short xga_sk7
- xga_sk6:mov ax,0c402h ; enable the MCA slot for normal
- mov bx,cx ; this slot
- int 15h
- xga_sk7:sti ; interrupts on again
-
- mov ax,xga_cardid ; is an XGA adapter on this slot?
- cmp ax,08fd8h
- jae xga_sk8 ; ae = yes
- jmp xga_lp2 ; try another slot
- xga_sk8:cmp ax,08fdbh ; still within range?
- jbe xga_sk9 ; be = yes
- jmp xga_lp2 ; no, try another slot
-
- xga_sk9:mov al,byte ptr xga_1mb ; restore POS data byte 1
- and ax,0eh ; muck about with it to get reg base
- shl ax,1
- shl ax,1
- shl ax,1
- add ax,2100h
- mov xga_reg_base,ax
- mov dx,xga_reg_base ; is there a monitor on this slot?
- add dx,0ah
- mov al,052h
- out dx,al
- mov dx,xga_reg_base
- add dx,0bh
- in al,dx
- and al,0fh
- cmp al,00h ; illegal value, returned under Win 3.0
- je xga_lp2
- cmp al,0fh
- jne xga_isthere ; ne = yes
-
- xga_lp2:inc cx ; try another adapter?
- cmp cx,9 ; done all slots?
- ja xga_ska ; a = yes
- jmp xga_lp1 ; no, try another slot
-
- xga_ska:jmp xga_notfound ; forget it - no XGA here
-
- xga_isthere:
- and ax,06h ; strip off the low & high bit
- xor ax,05h ; reverse the 3rd & low bits
- mov xga_result,ax ; save the result flag
-
- mov dx,xga_reg_base ; is this XGA in VGA mode?
- in al,dx
- test al,1
- jnz xga_skb ; nz = yes - single-monitor setup
- or xga_result,10h ; dual-monitor setup
- xga_skb:
-
- mov ah,byte ptr xga_1mb+2 ; retrieve POS data byte 3
- and ax,0fe00h ; eliminate the low-order bits
- mov bl,byte ptr xga_1mb ; retrieve POS data byte 1
- and bx,0eh ; strip it down to the IODA
- mov cx,5 ; shift it up 5 bits
- shl bx,cl
- or ax,bx ; compute the 4MB aperture value
- mov word ptr xga_4mb+2,ax ; save the result
-
- mov al, byte ptr xga_1mb+3 ; retrieve POS data byte 4
- and ax,0fh ; select the 1MB aperture bits
- mov cx,4 ; shift it up 4 bits
- shl ax,cl
- mov word ptr xga_1mb+2,ax ; save the result
- mov ax,0
- mov word ptr xga_1mb,ax
-
- mov dx,xga_reg_base ; Interrupt Disable
- add dx,4
- xor al,al
- out dx,al
-
- mov dx,xga_reg_base ; Switch to Extended Mode
- ;; add dx,00h
- mov al,4
- out dx,al
-
- mov dx,xga_reg_base ; Aperture Control
- add dx,01h
- mov al,1
- out dx,al
-
- mov dx,xga_reg_base ; disable Palette Mask
- add dx,0ah
- mov ax,0064h
- out dx,ax
-
- mov xga_isinmode,2 ; pretend we're already in graphics
- mov al,12 ; select page 12
- call xga_newbank
-
- push es ; see if this page has any memory
- mov ax,0a000h
- push ax
- pop es
- mov ah,000a5h
- mov es:0,al
- mov es:1,ah
- cmp es:0,al
- jne xga_512
- add xga_result,8 ; 1MB RAM found
- xga_512:pop es
-
- mov al,0 ; select page 0
- call xga_newbank
- mov xga_isinmode,0 ; replace the "in-graphics" flag
-
- mov dx,xga_reg_base ; Palette Mask
- add dx,0ah
- mov ax,0ff64h
- out dx,ax
-
- test xga_result,10h ; dual monitor setup?
- jnz xga_found ; yup - don't restore as a VGA
-
- mov dx,xga_reg_base ; Switch to VGA Mode
- ;; add dx,00h
- mov al,1
- out dx,al
-
- mov dx,03c3h ; Enable VGA Address Code
- mov al,1
- out dx,al
-
- jmp short xga_found
-
- xga_notfound:
- mov xga_reg_base,-2 ; set failure flag
- xga_found:
- mov ax,xga_result ; return the result
- ret
-
- xga_detect endp
-
- xga_mode proc uses es di si, mode:word
-
- mov curbk,-1 ; preload impossible bank number
-
- call xga_detect ; is an XGA adapter present?
- cmp ax,0
- jne whichmode
- jmp nope ; nope
- whichmode:
- mov bx,mode
- cmp bx,xga_twidth ; mode number out of range?
- jb whichmode0
- jmp nope ; yup - fail right now.
- whichmode0:
- cmp mode,0 ; 80-col VGA text mode?
- jne whichmode1
- jmp mode_0 ; yup
- whichmode1:
- cmp mode,1 ; 132-col VGA text mode?
- jne whichmode2
- jmp nope ; Fractint doesn't use this routine
- whichmode2:
- mov bx,mode ; locate the table entries
- add bx,mode
- mov dx,xga_requir[bx] ; does our setup support this mode?
- and al,dl
- cmp al,dl
- je whichmode3
- jmp nope ; nope
- whichmode3:
-
- mov ax,13h ; switch to 320x200x256 mode
- call maybeor ; maybe or AL or (for Video-7s) BL
- int 10h
- push ds ; reset ES==DS
- pop es
- mov ax,1017h ; get the DAC values
- mov bx,0
- mov cx,256
- mov dx,offset paldata ; a safe place when switching XGA modes
- int 10h
- cmp xga_loaddac,0 ; save the palette?
- je paskip ; (yes, if we want to fake 'loaddac')
- mov si, offset paldata
- mov di, offset dacbox
- mov cx,768/2
- rep movsw
- mov xga_loaddac,0 ; reset the toggle for next time
- paskip:
- mov bx,769 ; adjust the palette
- paloop: dec bx
- mov ah,paldata[bx]
-
- shl ah,1
- shl ah,1
- mov paldata[bx],ah
- cmp bx,0
- jne paloop
-
- mov dx,xga_reg_base ; Palette Mask
- add dx,0ah
- mov ax,00064h ; (Disable the XGA palette)
- out dx,ax
-
- mov dx,xga_swidth[bx] ; collect and save the scan-line length
- mov xga_xdots,dx
- mov dx,xga_colors[bx] ; how many colors do we have?
- mov xga_iscolors,dx ; save this
-
- mode_3: mov dx,03c3h ; Enable VGA Address Code
- mov al,1
- out dx,al
-
- mov si,offset xga_val ; point to start of values table
- mov bx,mode ; use mode as an offset
- model1: mov dx,xga_reg_base ; get the base pointer
- mov ah,0 ; get the increment
- mov al,cs:0[si]
- cmp al,0ffh ; end of the table?
- je model2 ; yup
- add dx,ax
- cmp al,0ah ; check for access type
- je modsk2
- mov al,cs:0[si+bx] ; get the value and OUT it
- out dx,al
- jmp short modsk3
- modsk2: mov al,cs:1[si] ; get the value and OUT it
- mov ah,cs:0[si+bx]
- out dx,ax
- modsk3: add si,xga_twidth ; try another table entry
- jmp short model1
- model2:
-
- mov xga_isinmode,2 ; pretend we're already in graphics
- call xga_clear ; clear out the memory
- mov curbk,-1 ; reset the bank counter
-
- mov dx,xga_reg_base ; set up for final loads
- add dx,0ah
- mov bx,mode ; how many colors do we have?
- add bx,mode
- cmp xga_colors[bx],0 ; "true color" mode?
- jne modsk4 ; nope - skip the funny palette load
-
- mov ax,0064h ; make invisible
- out dx,ax
- mov ax,8055h ; border color
- out dx,ax
- mov ax,0066h ; palette mode
- out dx,ax
- mov ax,0060h ; start at palette 0
- out dx,ax
- mov ax,0061h ; ""
- out dx,ax
-
- mov cx,0 ; ready to update the palette
- mov al,065h ; palette update
- out dx,al
- inc dx ; palette data
- model3: mov al,0 ; zero out the...
- out dx,al ; red value
- out dx,al ; and the green value
- mov al,cl ; klooge up the blue value
- and al,1fh ; convert to 1,2,...1f
- shl al,1 ; convert to 2,4,...3e
- shl al,1 ; convert to 4,8,...7c
- shl al,1 ; convert to 8,16,..fd
- out dx,al ; blue value
- inc cx ; another palette value to go?
- cmp cx,128
- jb model3
- dec dx ; back to normal
-
- mov ax,0ff64h ; make the palette visible
- out dx,ax
- jmp ok
-
- modsk4: mov bx, offset paldata ; reset the palette
- push bx
- mov xga_isinmode,2
- call xga_setpalette
- pop bx
- jmp ok
-
- mode_0: ; Set 80 column mode
- mov dx,xga_reg_base ; Aperture Control
- add dx,01h
- xor al,al ; (disable the XGA 64K aperture)
- out dx,al
-
- mov dx,xga_reg_base ; Interrupt Disable
- add dx,4
- xor al,al
- out dx,al
-
- mov dx,xga_reg_base ; Clear Interrupts
- add dx,5
- mov al,0ffh
- out dx,al
-
- test xga_result,10h ; dual monitor setup?
- jz mode_0a
- jmp nope ; yup - don't restore as a VGA
- mode_0a:
-
- mov dx,xga_reg_base ; Palette Mask
- add dx,0ah
- mov ax,0ff64h ; (Enable the XGA palette)
- out dx,ax
-
- mov dx,xga_reg_base ; Enable VFB, Prepare for Reset
- add dx,0ah
- mov ax,1550h
- out dx,ax
-
- mov dx,xga_reg_base ; Enable VFB, reset CRTC
- add dx,0ah
- mov ax,1450h
- out dx,ax
-
- mov dx,xga_reg_base ; Normal Scale Factors
- add dx,0ah
- mov ax,0051h
- out dx,ax
-
- mov dx,xga_reg_base ; Select VGA Oscillator
- add dx,0ah
- mov ax,0454h
- out dx,ax
-
- mov dx,xga_reg_base ; Ext Oscillator (VGA)
- add dx,0ah
- mov ax,7f70h
- out dx,ax
-
- mov dx,xga_reg_base ; Ensure no Vsynch Interrupts
- add dx,0ah
- mov ax,202ah
- out dx,ax
-
- mov dx,xga_reg_base ; Switch to VGA Mode
- ;; add dx,00h
- mov al,1
- out dx,al
-
- mov dx,03c3h ; Enable VGA Address Code
- mov al,1
- out dx,al
-
- mov ax,1202h ; select 400 scan lines
- mov bl,30h
- int 10h
-
- mov ax,0+3 ; set video mode 3
- or al,xga_clearvideo ; (might supress video-clearing)
- cmp xga_clearvideo,0 ; clear the video option set?
- je mode_0b
- mov ax,08eh ; ugly klooge: VGA graphics, no clear
- mode_0b:
- int 10h
-
- jmp ok ; we're done
-
- nope:
- mov xga_isinmode,0
- mov ax,0 ; return failure
- ret
- ok:
- mov ax,mode ; remember the mode we're in
- mov xga_isinmode,ax
- mov ax,1 ; return OK
- ret
- xga_mode endp
-
-
- ; **************** internal Read/Write-a-dot routines ***********************
- ;
- ; These Routines all assume the following register values:
- ;
- ; AL = The Color (returned on reads, sent on writes)
- ; CX = The X-Location of the Pixel
- ; DX = The Y-Location of the Pixel
-
- nullwrite proc near ; "do-nothing" write
- ret
- nullwrite endp
-
- nullread proc near ; "do-nothing" read
- mov ax,0 ; "return" black pixels
- ret
- nullread endp
-
- normalwrite proc near ; generic write-a-dot routine
- mov ah,12 ; write the dot (al == color)
- mov bx,0 ; this page
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret ; we done.
- normalwrite endp
-
- normalread proc near ; generic read-a-dot routine
- mov ah,13 ; read the dot (al == color)
- mov bx,0 ; this page
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret ; we done.
- normalread endp
-
- mcgawrite proc near ; MCGA 320*200, 246 colors
- xchg dh,dl ; bx := 256*y
- mov bx,cx ; bx := x
- add bx,dx ; bx := 256*y + x
- shr dx,1
- shr dx,1 ; dx := 64*y
- add bx,dx ; bx := 320*y + x
- mov es:[bx],al ; write the dot
- ret ; we done.
- mcgawrite endp
-
- mcgaread proc near ; MCGA 320*200, 246 colors
- xchg dh,dl ; dx := 256*y
- mov bx,cx ; bx := x
- add bx,dx ; bx := 256*y + x
- shr dx,1
- shr dx,1 ; dx := 64*y
- add bx,dx ; bx := 320*y + x
- mov al,es:[bx] ; retrieve the previous value
- ret ; we done.
- mcgaread endp
-
- ; These routines are for bit-plane 16 color modes, including bank
- ; switched superVGA varieties such as the Tseng 1024x768x16 mode.
- ; Tim Wegner
- ;
- vgawrite proc near ; bank-switched EGA/VGA write mode 0
- mov bh,al ; save the color value for a bit
- mov ax,vxdots ; this many dots / line
- mul dx ; times this many lines
- add ax,cx ; plus this many x-dots
- adc dx,0 ; DX:AX now holds the pixel count
- mov cx,ax ; save this for the bit mask
- and cx,7 ; bit-mask shift calculation
- xor cl,7 ; ...
- mov si,ax ; set up for the address shift
- shr dx,1 ; (ugly) 32-bit shift-by-3 logic
- rcr si,1 ; ((works on ANY 80x6 processor))
- shr dx,1 ; ...
- rcr si,1 ; ...
- shr dx,1 ; ...
- rcr si,1 ; ...
-
- cmp dx,curbk ; see if bank changed
- je vgasame_bank ; jump if old bank ok
- mov ax,dx ; newbank expects bank in al
- call far ptr newbank ; switch banks
- vgasame_bank:
-
- mov dx,03ceh ; graphics controller address
- mov ax,0108h ; set up controller bit mask register
- shl ah,cl ; ...
- out dx,ax ; ...
- mov ah,bh ; set set/reset registers
- mov al,0 ; ...
- out dx,ax ; ...
- mov ax,0f01h ; enable set/reset registers
- out dx,ax ; ...
- or es:[si],al ; update all bit planes
- ret ; we done.
- vgawrite endp
-
- vgaread proc near ; bank-switched EGA/VGA read mode 0
- mov ax,vxdots ; this many dots / line
- mul dx ; times this many lines
- add ax,cx ; plus this many x-dots
- adc dx,0 ; DX:AX now holds the pixel count
- mov cx,ax ; save this for the bit mask
- and cx,7 ; bit-mask shift calculation
- xor cl,7 ; ...
- mov si,ax ; set up for the address shift
- shr dx,1 ; (ugly) 32-bit shift-by-3 logic
- rcr si,1 ; ((works on ANY 80x6 processor))
- shr dx,1 ; ...
- rcr si,1 ; ...
- shr dx,1 ; ...
- rcr si,1 ; ...
-
- cmp dx,curbk ; see if bank changed
- je vgasame_bank ; jump if old bank ok
- mov ax,dx ; newbank expects bank in al
- call far ptr newbank ; switch banks
- vgasame_bank:
-
- mov ch,01h ; bit mask to shift
- shl ch,cl ; ...
- mov bx,0 ; initialize bits-read value (none)
- mov dx,03ceh ; graphics controller address
- mov ax,0304h ; set up controller address register
- vgareadloop:
- out dx,ax ; do it
- mov bh,es:[si] ; retrieve the old value
- and bh,ch ; mask one bit
- neg bh ; set bit 7 correctly
- rol bx,1 ; rotate the bit into bl
- dec ah ; go for another bit?
- jge vgareadloop ; sure, why not.
- mov al,bl ; returned pixel value
- ret ; we done.
- vgaread endp
-
- outax8bit proc near ; convert OUT DX,AX to
- push ax ; several OUT DX,ALs
- out dx,al ; (leaving registers intact)
- inc dx
- mov al,ah
- out dx,al
- dec dx
- pop ax
- ret
- outax8bit endp
-
-
- ; --------------------------------------------------------------------------
-
- ; new Tandy and CGA code from Joseph Albrecht
-
- align 2
- ;Scan line address table for 16K video memory
- scan16k dw 0000h,2000h,0050h,2050h,00A0h,20A0h,00F0h,20F0h
- dw 0140h,2140h,0190h,2190h,01E0h,21E0h,0230h,2230h
- dw 0280h,2280h,02D0h,22D0h,0320h,2320h,0370h,2370h
- dw 03C0h,23C0h,0410h,2410h,0460h,2460h,04B0h,24B0h
- dw 0500h,2500h,0550h,2550h,05A0h,25A0h,05F0h,25F0h
- dw 0640h,2640h,0690h,2690h,06E0h,26E0h,0730h,2730h
- dw 0780h,2780h,07D0h,27D0h,0820h,2820h,0870h,2870h
- dw 08C0h,28C0h,0910h,2910h,0960h,2960h,09B0h,29B0h
- dw 0A00h,2A00h,0A50h,2A50h,0AA0h,2AA0h,0AF0h,2AF0h
- dw 0B40h,2B40h,0B90h,2B90h,0BE0h,2BE0h,0C30h,2C30h
- dw 0C80h,2C80h,0CD0h,2CD0h,0D20h,2D20h,0D70h,2D70h
- dw 0DC0h,2DC0h,0E10h,2E10h,0E60h,2E60h,0EB0h,2EB0h
- dw 0F00h,2F00h,0F50h,2F50h,0FA0h,2FA0h,0FF0h,2FF0h
- dw 1040h,3040h,1090h,3090h,10E0h,30E0h,1130h,3130h
- dw 1180h,3180h,11D0h,31D0h,1220h,3220h,1270h,3270h
- dw 12C0h,32C0h,1310h,3310h,1360h,3360h,13B0h,33B0h
- dw 1400h,3400h,1450h,3450h,14A0h,34A0h,14F0h,34F0h
- dw 1540h,3540h,1590h,3590h,15E0h,35E0h,1630h,3630h
- dw 1680h,3680h,16D0h,36D0h,1720h,3720h,1770h,3770h
- dw 17C0h,37C0h,1810h,3810h,1860h,3860h,18B0h,38B0h
- dw 1900h,3900h,1950h,3950h,19A0h,39A0h,19F0h,39F0h
- dw 1A40h,3A40h,1A90h,3A90h,1AE0h,3AE0h,1B30h,3B30h
- dw 1B80h,3B80h,1BD0h,3BD0h,1C20h,3C20h,1C70h,3C70h
- dw 1CC0h,3CC0h,1D10h,3D10h,1D60h,3D60h,1DB0h,3DB0h
- dw 1E00h,3E00h,1E50h,3E50h,1EA0h,3EA0h,1EF0h,3EF0h
-
- ;Scan line address table for 32K video memory
- scan32k dw 0000h,2000h,4000h,6000h,00a0h,20a0h,40a0h,60a0h
- dw 0140h,2140h,4140h,6140h,01e0h,21e0h,41e0h,61e0h
- dw 0280h,2280h,4280h,6280h,0320h,2320h,4320h,6320h
- dw 03c0h,23c0h,43c0h,63c0h,0460h,2460h,4460h,6460h
- dw 0500h,2500h,4500h,6500h,05a0h,25a0h,45a0h,65a0h
- dw 0640h,2640h,4640h,6640h,06e0h,26e0h,46e0h,66e0h
- dw 0780h,2780h,4780h,6780h,0820h,2820h,4820h,6820h
- dw 08c0h,28c0h,48c0h,68c0h,0960h,2960h,4960h,6960h
- dw 0a00h,2a00h,4a00h,6a00h,0aa0h,2aa0h,4aa0h,6aa0h
- dw 0b40h,2b40h,4b40h,6b40h,0be0h,2be0h,4be0h,6be0h
- dw 0c80h,2c80h,4c80h,6c80h,0d20h,2d20h,4d20h,6d20h
- dw 0dc0h,2dc0h,4dc0h,6dc0h,0e60h,2e60h,4e60h,6e60h
- dw 0f00h,2f00h,4f00h,6f00h,0fa0h,2fa0h,4fa0h,6fa0h
- dw 1040h,3040h,5040h,7040h,10e0h,30e0h,50e0h,70e0h
- dw 1180h,3180h,5180h,7180h,1220h,3220h,5220h,7220h
- dw 12c0h,32c0h,52c0h,72c0h,1360h,3360h,5360h,7360h
- dw 1400h,3400h,5400h,7400h,14a0h,34a0h,54a0h,74a0h
- dw 1540h,3540h,5540h,7540h,15e0h,35e0h,55e0h,75e0h
- dw 1680h,3680h,5680h,7680h,1720h,3720h,5720h,7720h
- dw 17c0h,37c0h,57c0h,77c0h,1860h,3860h,5860h,7860h
- dw 1900h,3900h,5900h,7900h,19a0h,39a0h,59a0h,79a0h
- dw 1a40h,3a40h,5a40h,7a40h,1ae0h,3ae0h,5ae0h,7ae0h
- dw 1b80h,3b80h,5b80h,7b80h,1c20h,3c20h,5c20h,7c20h
- dw 1cc0h,3cc0h,5cc0h,7cc0h,1d60h,3d60h,5d60h,7d60h
- dw 1e00h,3e00h,5e00h,7e00h,1ea0h,3ea0h,5ea0h,7ea0h
-
- ;Scan line address table for 64K video memory
- scan64k dw 00000h,00140h,00280h,003c0h,00500h,00640h,00780h,008c0h
- dw 00a00h,00b40h,00c80h,00dc0h,00f00h,01040h,01180h,012c0h
- dw 01400h,01540h,01680h,017c0h,01900h,01a40h,01b80h,01cc0h
- dw 01e00h,01f40h,02080h,021c0h,02300h,02440h,02580h,026c0h
- dw 02800h,02940h,02a80h,02bc0h,02d00h,02e40h,02f80h,030c0h
- dw 03200h,03340h,03480h,035c0h,03700h,03840h,03980h,03ac0h
- dw 03c00h,03d40h,03e80h,03fc0h,04100h,04240h,04380h,044c0h
- dw 04600h,04740h,04880h,049c0h,04b00h,04c40h,04d80h,04ec0h
- dw 05000h,05140h,05280h,053c0h,05500h,05640h,05780h,058c0h
- dw 05a00h,05b40h,05c80h,05dc0h,05f00h,06040h,06180h,062c0h
- dw 06400h,06540h,06680h,067c0h,06900h,06a40h,06b80h,06cc0h
- dw 06e00h,06f40h,07080h,071c0h,07300h,07440h,07580h,076c0h
- dw 07800h,07940h,07a80h,07bc0h,07d00h,07e40h,07f80h,080c0h
- dw 08200h,08340h,08480h,085c0h,08700h,08840h,08980h,08ac0h
- dw 08c00h,08d40h,08e80h,08fc0h,09100h,09240h,09380h,094c0h
- dw 09600h,09740h,09880h,099c0h,09b00h,09c40h,09d80h,09ec0h
- dw 0a000h,0a140h,0a280h,0a3c0h,0a500h,0a640h,0a780h,0a8c0h
- dw 0aa00h,0ab40h,0ac80h,0adc0h,0af00h,0b040h,0b180h,0b2c0h
- dw 0b400h,0b540h,0b680h,0b7c0h,0b900h,0ba40h,0bb80h,0bcc0h
- dw 0be00h,0bf40h,0c080h,0c1c0h,0c300h,0c440h,0c580h,0c6c0h
- dw 0c800h,0c940h,0ca80h,0cbc0h,0cd00h,0ce40h,0cf80h,0d0c0h
- dw 0d200h,0d340h,0d480h,0d5c0h,0d700h,0d840h,0d980h,0dac0h
- dw 0dc00h,0dd40h,0de80h,0dfc0h,0e100h,0e240h,0e380h,0e4c0h
- dw 0e600h,0e740h,0e880h,0e9c0h,0eb00h,0ec40h,0ed80h,0eec0h
- dw 0f000h,0f140h,0f280h,0f3c0h,0f500h,0f640h,0f780h,0f8c0h
-
- ;
- ; ***** CGA Video Routines *****
- ;
-
- ;plot a point on 320x200x4 color graphics screen
- plotcga4 proc near
-
- mov bx,0b800h ;point es at video buffer
- mov es,bx ; ..
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- mov bx,cs:scan16k[bx] ; ..
- mov ah,cl ;save low byte of column
- shr cx,1 ;get column offset
- shr cx,1 ; ..
- add bx,cx ;add column offset to address
- not ah ;get shift count
- and ah,3 ; ..
- shl ah,1 ; ..
- mov cl,ah ; ..
- and al,3 ;mask off unwanted bits
- rol al,cl ;get or mask
- mov ah,0fch ;get and mask
- rol ah,cl ; ..
- mov cl,es:[bx] ;plot the point
- and cl,ah ; ..
- or cl,al ; ..
- mov es:[bx],cl ; ..
- ret
-
- plotcga4 endp
-
- ;return a point from 320x200x4 color graphics screen
- getcga4 proc near
-
- mov bx,0b800h ;point es at video buffer
- mov es,bx ; ..
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- mov bx,cs:scan16k[bx] ; ..
- mov ax,cx ;save column
- shr ax,1 ;get column offset
- shr ax,1 ; ..
- add bx,ax ;add column offset to address
- not cl ;get shift count
- and cl,3 ; ..
- shl cl,1 ; ..
- mov al,es:[bx] ;return the point
- ror al,cl ; ..
- and ax,3 ; ..
- ret
-
- getcga4 endp
-
- ;plot a point on 640x200x2 color graphics screen
- plotcga2 proc near
-
- mov bx,0b800h ;point es at video buffer
- mov es,bx ; ..
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- mov bx,cs:scan16k[bx] ; ..
- mov ah,cl ;save low order byte of column
- shr cx,1 ;get column offset
- shr cx,1 ; ..
- shr cx,1 ; ..
- add bx,cx ;add column offset to address
- not ah ;get shift count
- and ah,7 ; ..
- mov cl,ah ; ..
- and al,1 ;mask off unwanted bits
- rol al,cl ;get or mask
- mov ah,0feh ;get and mask
- rol ah,cl ; ..
- mov cl,es:[bx] ;plot the point
- and cl,ah ; ..
- or cl,al ; ..
- mov es:[bx],cl ; ..
- ret
-
- plotcga2 endp
-
- ;return a point from 640x200x2 color graphics screen
- getcga2 proc near
-
- mov bx,0b800h ;point es at video buffer
- mov es,bx ; ..
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- mov bx,cs:scan16k[bx] ; ..
- mov ax,cx ;save column
- shr ax,1 ;get column offset
- shr ax,1 ; ..
- shr ax,1 ; ..
- add bx,ax ;add column offset to address
- not cl ;get shift count
- and cl,7 ; ..
- mov al,es:[bx] ;return the point
- ror al,cl ; ..
- and ax,1 ; ..
- ret
-
- getcga2 endp
-
- ;
- ; ***** Tandy 1000 Video Routines *****
- ;
-
- ;plot a point on tandy 1000 640x200x4 color graphics screen
- plottandy4 proc near
-
- mov bx,0b800h ;point es at video segment
- mov es,bx ; ..
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- mov bx,cs:scan32k[bx] ; ..
- mov dx,cx ;save column
- shr dx,1 ;get column offset
- shr dx,1 ; ..
- and dl,0feh ; ..
- add bx,dx ;add column offset to address
- not cl ;get shift count
- and cl,7 ; ..
- mov ah,al ;get or mask
- shr ah,1 ; ..
- and ax,101h ; ..
- rol ax,cl ; ..
- mov dx,0fefeh ;get and mask
- rol dx,cl ; ..
- mov cx,es:[bx] ;plot the point
- and cx,dx ; ..
- or cx,ax ; ..
- mov es:[bx],cx ; ..
- ret
-
- plottandy4 endp
-
- ;return a point from tandy 1000 640x200x4 color graphics screen
- gettandy4 proc near
-
- mov bx,0b800h ;point es at video segment
- mov es,bx ; ..
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- mov bx,cs:scan32k[bx] ; ..
- mov ax,cx ;save column
- shr ax,1 ;get column offset
- shr ax,1 ; ..
- and al,0feh ; ..
- add bx,ax ;add column offset to address
- not cl ;get shift count
- and cl,7 ; ..
- mov ax,es:[bx] ;return the point
- ror ax,cl ; ..
- and ax,101h ; ..
- rol ah,1 ; ..
- or al,ah ; ..
- and ax,3 ; ..
- ret
-
- gettandy4 endp
-
- ;plot a point on tandy 1000 16 color graphics screen
- plottandy16 proc near
-
- mov es,tandyseg ;point es at video buffer
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- add bx,tandyscan ; ..
- mov bx,cs:[bx] ; ..
- mov ah,0f0h ;set mask for odd pixel
- mov dx,cx ;save x
- shr dx,1 ;get column offset
- jc plottandy16a ;check for odd/even pixel
- not ah ;set mask for even pixel
- mov cl,4 ;move color to proper pobxtion
- shl al,cl ; ..
- plottandy16a:
- add bx,dx ;add column offset to address
- mov dl,es:[bx] ;plot the point
- and dl,ah ; ..
- or dl,al ; ..
- mov es:[bx],dl ; ..
- ret
-
- plottandy16 endp
-
- ;return a point from tandy 1000 16 color graphics mode
- gettandy16 proc near
-
- mov es,tandyseg ;point es at video buffer
- mov bx,dx ;get scan line address
- shl bx,1 ; ..
- add bx,tandyscan ; ..
- mov bx,cs:[bx] ; ..
- mov dx,cx ;save x
- shr cx,1 ;add column offset to address
- add bx,cx ; ..
- mov al,es:[bx] ;get pixel
- test dl,1 ;check for odd/even pixel
- jnz gettandy16a ; ..
- mov cl,4 ;move color to proper position
- shr al,cl ; ..
- gettandy16a:
- and ax,0fh ;mask off unwanted bits
- ret
-
- gettandy16 endp
-
- ;setup tandy 1000 640x200x16 color mode
- tandysetup proc near
- mov dx,03d4h ; write to this address
- mov ax,07100h ; write to this register and value
- call tandyport ; do it.
- mov ax,05001h ; write to this register and value
- call tandyport ; do it.
- mov ax,05a02h ; write to this register and value
- call tandyport ; do it.
- mov ax,00e03h ; write to this register and value
- call tandyport ; do it.
- mov ax,0ff04h ; write to this register and value
- call tandyport ; do it.
- mov ax,00605h ; write to this register and value
- call tandyport ; do it.
- mov ax,0c806h ; write to this register and value
- call tandyport ; do it.
- mov ax,0e207h ; write to this register and value
- call tandyport ; do it.
- mov ax,00009h ; write to this register and value
- call tandyport ; do it.
- mov ax,0000ch ; write to this register and value
- call tandyport ; do it.
- mov ax,01810h ; write to this register and value
- call tandyport ; do it.
- mov ax,04612h ; write to this register and value
- call tandyport ; do it.
- mov dx,03d8h ; new port
- mov al,01bh ; and value
- out dx,al ; do it.
- mov dx,03d9h ; new port
- mov al,000h ; and value
- out dx,al ; do it.
- mov dx,03ddh ; new port
- mov al,000h ; and value
- out dx,al ; do it.
- mov dx,03dfh ; new port
- mov al,024h ; and value
- out dx,al ; do it.
- mov dx,03dah ; new port
- mov al,001h ; and value
- out dx,al ; do it.
- mov dx,03deh ; new port
- mov al,00fh ; and value
- out dx,al ; do it.
- mov dx,03dah ; new port
- mov al,002h ; and value
- out dx,al ; do it.
- mov dx,03deh ; new port
- mov al,000h ; and value
- out dx,al ; do it.
- mov dx,03dah ; new port
- mov al,003h ; and value
- out dx,al ; do it.
- mov dx,03deh ; new port
- mov al,010h ; and value
- out dx,al ; do it.
- mov dx,03dah ; new port
- mov al,005h ; and value
- out dx,al ; do it.
- mov dx,03deh ; new port
- mov al,001h ; and value
- out dx,al ; do it.
- mov dx,03dah ; new port
- mov al,008h ; and value
- out dx,al ; do it.
- mov dx,03deh ; new port
- mov al,002h ; and value
- out dx,al ; do it.
-
- ;set color palette registers to default state
- mov cx,16 ;reset colors 0-15 to default state
- xor bh,bh ;set initial color
- xor bl,bl ;set initial paletter register
- mov di,2 ;reset border color
- call settandypal ; ..
- tandysetup1:
- mov di,16 ;port offset for palette registers
- call settandypal ;set palette register
- inc bl ;bump up to next palette register
- inc bh ;bump up to next color
- loop tandysetup1 ;do remaining palette registers
-
- cmp orvideo,0 ; are we supposed to clear RAM?
- jne tandysetup2 ; (nope)
- push es ; save ES for a tad
- mov ax,0a000h ; clear the memory
- mov es,ax ; ...
- cld ; string ops forward
- mov cx,07d00h ; this many words
- mov di,0 ; starting here
- mov ax,0 ; clear out to zero
- rep stosw ; do it.
- pop es ; restore ES
- tandysetup2:
- mov oktoprint,0 ; no printing in this mode
- ret
-
- tandysetup endp
-
- ;write data to 6845 registers
- tandyport proc near
-
- out dx,al ;write 6845 reg number to port 3d4
- mov al,ah ;write 6845 reg data to port 3d5
- inc dx ; ..
- out dx,al ; ..
- dec dx ;point back to port 3d4
- ret
-
- tandyport endp
-
- ;subroutine to set a Tandy 1000 palette register
- settandypal proc near
- mov dx,3dah ;address & status register
- cli ;disable interrupts
- settandypal2:
- in al,dx ;get status register
- and al,8 ;look for bit 3
- jz settandypal2 ;wait for vertical retrace
- mov al,bl ;get palette number
- cbw ; ..
- add ax,di ;add offset for palette register
- out dx,al ;set palette
- mov al,bh ;get color to store
- mov dx,3deh ;palette data register
- out dx,al ;set palette color
- mov dx,3dah ;address & status register
- xor ax,ax ;al = 0 to reset address register
- out dx,al ;reset it
- sti ;re-enable interrupts
- ret
-
- settandypal endp
-
- ; -----------------------------------------------------------------------------
-
-
- ; The 360x480 mode draws heavily on Michael Abrash's article in
- ; the January/February 1989 "Programmer's Journal" and files uploaded
- ; to Compuserv's PICS forum by Dr. Lawrence Gozum - integrated here
- ; by Timothy Wegner
-
- ; Michael Abrash equates. Not all used, but I'll leave for reference.
-
- VGA_SEGMENT EQU 0A000h
- SC_INDEX EQU 3C4h ;Sequence Controller Index register
- GC_INDEX EQU 3CEh ;Graphics Controller Index register
- CRTC_INDEX EQU 3D4h ;CRT Controller Index register
- MAP_MASK EQU 2 ;Map Mask register index in SC
- MEMORY_MODE EQU 4 ;Memory Mode register in SC
- MAX_SCAN_LINE EQU 9 ;Maximum Scan Line reg index in CRTC
- ;Use 9 for 2 pages of 320x400
- ;MAX_SCAN_LINE EQU 1 ;Use 1 for 4 pages of 320x200
- START_ADD_HIGH EQU 0Ch ;Start Address High reg index in CRTC
- UNDERLINE EQU 14h ;Underline Location reg index in CRTC
- MODE_CONTROL EQU 17h ;Mode Control reg index in CRTC
- READ_MAP EQU 4 ;Read Mask register index in SC
- GRAPHICS_MODE EQU 5 ;Graphics Mode register index in SC
- MISC EQU 6 ;Miscellaneous register index in SC
- WORD_OUTS_OK EQU 1 ;set to 0 to assemble for computers
- ;that can't handle word outs to indexed
- ;VGA registers
- ;
- ;Macro to output a word value to a port
- ;
- OUT_WORD MACRO
- IF WORD_OUTS_OK
- OUT DX,AX
- ELSE
- OUT DX,AL
- INC DX
- XCHG AH,AL
- OUT DX,AL
- DEC DX
- XCHG AH,AL
- ENDIF
- ENDM
-
- ;Macro to ouput a constant value to an indexed VGA register
- CONSTANT_TO_INDEXED_REGISTER MACRO ADDRESS,INDEX,VALUE
- MOV DX,ADDRESS
- MOV AX,(VALUE SHL 8)+INDEX
- OUT_WORD
- ENDM
-
- tweak256read proc near uses si ; Tweaked-VGA ...x256 color mode
-
- mov ax,vxdots
- ;; shr ax,1
- ;; shr ax,1 ; now ax = vxdots/4
- mul dx ;Point to start of desired row
- push cx ;Save X coordinate for later
- shr cx,1 ;There are 4 pixels at each address
- shr cx,1 ;so divide X by 4
- add ax,cx ;Point to pixels address
- mov si,ax
- pop ax ;Retrieve X coordinate
- and al,3 ;Get the plane number of the pixel
- mov ah,al
- mov al,READ_MAP
- mov dx,GC_INDEX
- OUT_WORD ;Set to write to the proper plane for the
- ;pixel
- xor ax,ax
- lods byte ptr es:[si] ;Read the pixel
- ret
-
- tweak256read endp
-
- tweak256write proc near uses di ; Tweaked-VGA ...x256 color mode
- mov bl,al ; color
- mov ax,vxdots
- ;; shr ax, 1
- ;; shr ax, 1 ; now ax = vxdots/4
- mul dx ;Point to start of desired row
- push cx ;Save X coordinate for later
- shr cx,1 ;There are 4 pixels at each address
- shr cx,1 ;so divide X by 4
- add ax,cx ;Point to pixels address
- mov di,ax
- pop cx ;Retrieve X coordinate
- and cl,3 ;Get the plane number of the pixel
- mov ah,1
- shl ah,cl ;Set the bit corresponding to the plane
- ;the pixel is in
- mov al,MAP_MASK
- mov dx,SC_INDEX
- OUT_WORD ;Set to write to the proper plane for the
- ;pixel
- mov es:[di],bl ;Draw the pixel
-
- ret
- tweak256write endp
-
- ; The following ATI 1024x768x16 mode is courtesy of Mark Peterson
-
- ati1024read proc near ; ATI 1024x768x16 read
- call ati1024addr ; calculate the address
- mov al,es:[bx] ; get the byte the pixel is in
-
- cmp xga_isinmode,0 ; say, is this really XGA-style I/O?
- je notxga ; nope
- test cl,1 ; is X odd?
- jnz atireadhigh ; Yup. Use the high bits
- jmp short atireadlow ; else use the low bits
- notxga:
-
- test cl,1 ; is X odd?
- jz atireadhigh ; Nope. Use the high bits
- atireadlow:
- and ax,0fh ; zero out the high-order bits
- ret
- atireadhigh:
- and ax,0f0h ; zero out the low-order bits
- mov cl,4 ; shift the results
- shr al,cl ; ...
- ret
- ati1024read endp
-
- ati1024write proc near ; ATI 1024x768x16 write
- call ati1024addr ; calculate the address
- mov dl,es:[bx] ; get the byte the pixel is in
- and al,00fh ; zero out the high-order color bits
-
- cmp xga_isinmode,0 ; say, is this really XGA-style I/O?
- je notxga ; nope
- test cl,1 ; is X odd?
- jnz atiwritehigh ; Yup. Use the high bits
- jmp short atiwritelow ; else use the low bits
- notxga:
-
- test cl,1 ; is X odd?
- jz atiwritehigh ; Nope. Use the high bits
- atiwritelow:
- and dl,0f0h ; zero out the low-order video bits
- or dl,al ; add the two together
- mov es:[bx],dl ; and write the results
- ret
- atiwritehigh:
- mov cl,4 ; shift the color bits
- shl al,cl ; ...
- and dl,0fh ; zero out the high-order video bits
- or dl,al ; add the two together
- mov es:[bx],dl ; and write the results
- ret
- ati1024write endp
-
- ati1024addr proc near ; modification of TIW's Super256addr
- clc ; clear carry flag
- push ax ; save this for a tad
- mov ax,vxdots ; this many dots / line
- mul dx ; times this many lines - ans in dx:ax
- add ax,cx ; plus this many x-dots
- adc dx,0 ; answer in dx:ax
- shr dx,1 ; shift the answer right one bit
- rcr ax,1 ; .. in the 32-bit DX:AX combo
- mov bx,ax ; save this in BX
- cmp dx,curbk ; see if bank changed
- je atisame_bank ; jump if old bank ok
- mov ax,dx ; newbank expects bank in al
- call far ptr newbank
- atisame_bank:
- pop ax ; restore AX
- ret
- ati1024addr endp
-
- ;
- ; The following 'Super256' code is courtesy of Timothy Wegner.
- ;
-
- super256write proc near ; super-VGA ...x256 colors write-a-dot
- call super256addr ; calculate address and switch banks
- mov es:[bx],al ; write the dot
- ret ; we done.
- super256write endp
-
- super256read proc near ; super-VGA ...x256 colors read-a-dot
- call super256addr ; calculate address and switch banks
- mov al,es:[bx] ; read the dot
- ret ; we done.
- super256read endp
-
- super256addr proc near ; can be put in-line but shared by
- ; read and write routines
- clc ; clear carry flag
- push ax ; save this for a tad
- mov ax,vxdots ; this many dots / line
- mul dx ; times this many lines - ans in dx:ax
- add ax,cx ; plus this many x-dots
- adc dx,0 ; answer in dx:ax - dl=bank, ax=offset
- mov bx,ax ; save this in BX
- cmp dx,curbk ; see if bank changed
- je same_bank ; jump if old bank ok
- mov ax,dx ; newbank expects bank in al
- call far ptr newbank
- same_bank:
- pop ax ; restore AX
- ret
- super256addr endp
-
- ;
- ; BANKS.ASM was used verbatim except:
- ; 1) removed ".model small"
- ; 2) deleted "end"
- ; Integrated by Tim Wegner 8/15/89
- ; (switched to John's 9/7/89 version on 9/10/89 - Bert)
- ; (switched to John's 1/5/90 version on 1/9/90 - Bert)
- ; (switched to John's version 3 on 4/27/90 - Bert)
- ; (added logic for various resolution on 9/10/90 - Bert)
- ; (upgraded to John's version 3.5 on 5/14/91 - Bert)
- ;
-
- ; .MODEL medium,c
-
- ;
- ; Copyright 1988,89,90,91 John Bridges
- ; Free for use in commercial, shareware or freeware applications
- ;
- ; SVGAMODE.ASM
- ;
- .data
-
- OSEG equ SS: ;segment override for variable access
-
- bankadr dw offset $nobank
- if @CodeSize
- bankseg dw seg $nobank
- endif
-
- vesa_bankswitch dd $vesa_nullbank ; initially, do-nothing
- vesa_mapper dd $nobank
- vesa_detect dw 1 ; set to 0 to disable VESA-detection
- vesa_gran_offset dw 0
- vesa_low_window dw 0
- vesa_high_window dw 1
- vesa_granularity db 0 ; BDT VESA Granularity value
-
- public curbk
-
- align 2
- curbk dw 0
-
- vga512 dw 0
- vga1024 dw 0
-
-
- public supervga_list ; pointer to head of the SuperVGA list
-
- supervga_list db "aheada"
- aheada dw 0
- db "ati "
- ativga dw 0
- db "chi "
- chipstech dw 0
- db "eve "
- everex dw 0
- db "gen "
- genoa dw 0
- db "ncr "
- ncr dw 0
- db "oak "
- oaktech dw 0
- db "par "
- paradise dw 0
- db "tri "
- trident dw 0
- db "tseng3"
- tseng dw 0
- db "tseng4"
- tseng4 dw 0
- db "vid "
- video7 dw 0
- db "aheadb"
- aheadb dw 0
- db "vesa "
- vesa dw 0
- db "cirrus"
- cirrus dw 0
- db "t8900 "
- t8900 dw 0
- db "compaq"
- compaq dw 0
- db "xga "
- xga dw 0
- db " " ; end-of-the-list
- dw 0
-
- done_detect dw 0 ;flag to call adapter_detect & whichvga once
-
- ; this part is new - Bert
- .code
-
- vesa_entries dw 0
- dw 640, 400,256, 4f02h,100h
- dw 640, 480,256, 4f02h,101h
- dw 800, 600, 16, 4f02h,102h
- dw 800, 600,256, 4f02h,103h
- dw 1024, 768, 16, 4f02h,104h
- dw 1024, 768,256, 4f02h,105h
- dw 1280,1024, 16, 4f02h,106h
- dw 1280,1024,256, 4f02h,107h
- ahead_entries dw 0
- dw 800, 600, 16, 06ah,0
- dw 800, 600, 16, 071h,0
- dw 1024, 768, 16, 074h,0
- dw 640, 400,256, 060h,0
- dw 640, 480,256, 061h,0
- dw 800, 600,256, 062h,0
- dw 1024, 768,256, 063h,0
- ati_entries dw 0
- dw 800, 600, 16, 054h,0
- dw 1024, 768, 16, 065h,0ffh ; (non-standard mode flag)
- ; dw 1024, 768, 16, 055h,0
- dw 640, 400,256, 061h,0
- dw 640, 480,256, 062h,0
- dw 800, 600,256, 063h,0
- dw 1024, 768,256, 064h,0
- chips_entries dw 0
- dw 800, 600, 16, 070h,0
- dw 1024, 768, 16, 072h,0
- dw 640, 400,256, 078h,0
- dw 640, 480,256, 079h,0
- dw 800, 600,256, 07bh,0
- compaq_entries dw 0
- dw 640, 480,256, 02eh,0fdh ; (non-standard mode flag)
- everex_entries dw 0
- dw 752, 410, 16, 070h,01h
- dw 800, 600, 16, 070h,02h
- dw 1280, 350, 4, 070h,11h
- dw 1280, 600, 4, 070h,12h
- dw 640, 350,256, 070h,13h
- dw 640, 400,256, 070h,14h
- dw 512, 480,256, 070h,15h
- dw 1024, 768, 16, 070h,20h
- dw 640, 480,256, 070h,30h
- dw 800, 600,256, 070h,31h
- dw 1024, 768,256, 070h,32h
- genoa_entries dw 0
- dw 1024, 768, 4, 07fh,0
- dw 720, 512, 16, 059h,0
- dw 800, 600, 16, 079h,0
- dw 1024, 768, 16, 05fh,0
- dw 640, 350,256, 05bh,0
- dw 640, 400,256, 07eh,0
- dw 640, 480,256, 05ch,0
- dw 720, 512,256, 05dh,0
- dw 800, 600,256, 05eh,0
- ncr_entries dw 0
- dw 1024, 768, 2, 5ah,0
- dw 800, 600, 16, 58h,0
- dw 1024, 768, 16, 5dh,0
- dw 640, 400,256, 5eh,0
- dw 640, 480,256, 5fh,0
- dw 800, 600,256, 5ch,0
- ; dw 0 ; this appears to be extra! JCO
- oaktech_entries dw 0
- dw 800, 600, 16, 52h,0
- dw 640, 480,256, 53h,0
- dw 800, 600,256, 54h,0
- dw 1024, 768, 16, 56h,0
- dw 1024, 768,256, 59h,0
- dw 1280,1024, 16, 58h,0
- ; dw 0
- paradise_entries dw 0
- dw 800, 600, 2, 059h,0
- dw 800, 600, 16, 058h,0
- dw 640, 400,256, 05eh,0
- dw 640, 480,256, 05fh,0
- dw 1024, 768, 16, 05dh,0
- dw 800, 600,256, 05ch,0 ; Chuck Ebbert, 910524
- trident_entries dw 0
- dw 1024, 768, 4, 060h,0
- dw 800, 600, 16, 05bh,0
- dw 1024, 768, 16, 05fh,0
- dw 640, 400,256, 05ch,0
- dw 640, 480,256, 05dh,0
- dw 800, 600,256, 05eh,0
- dw 1024, 768,256, 062h,0
- tseng_entries dw 0
- dw 800, 600, 16, 029h,0
- dw 1024, 768, 16, 037h,0
- dw 640, 350,256, 02dh,0
- dw 640, 400,256, 0,0feh ; (non-standard mode flag)
- dw 640, 480,256, 02eh,0
- dw 720, 512,256, 02fh,0
- dw 800, 600,256, 030h,0
- dw 1024, 768,256, 038h,0
- tseng4_entries dw 0
- dw 800, 600, 16, 29h,0
- dw 1024, 768, 16, 37h,0
- dw 640, 350,256, 2dh,0
- dw 640, 400,256, 2fh,0
- dw 640, 480,256, 2eh,0
- dw 800, 600,256, 30h,0
- dw 1024, 768,256, 38h,0
- video7_entries dw 0
- dw 752, 410, 16, 6f05h,60h
- dw 720, 540, 16, 6f05h,61h
- dw 800, 600, 16, 6f05h,62h
- dw 1024, 768, 2, 6f05h,63h
- dw 1024, 768, 4, 6f05h,64h
- dw 1024, 768, 16, 6f05h,65h
- dw 640, 400,256, 6f05h,66h
- dw 640, 480,256, 6f05h,67h
- dw 720, 540,256, 6f05h,68h
- dw 800, 600,256, 6f05h,69h
- dw 1024, 768,256, 6f05h,6ah
- xga_entries dw 0
- dw 1024, 768,256,0ffffh,02h
- dw 1024, 768, 16,0ffffh,03h
- dw 640, 400,256,0ffffh,04h
- dw 640, 480,256,0ffffh,04h
- dw 800, 600, 16,0ffffh,06h
- dw 800, 600,256,0ffffh,07h
- no_entries dw 0
- dw 320, 200,256, 13h,0
- dw 640, 480, 16, 12h,0
- dw 0
-
- .code
-
- newbank proc ;bank number is in AX
- cli
- mov OSEG[curbk],ax
- if @CodeSize
- call dword ptr OSEG[bankadr]
- else
- call word ptr OSEG[bankadr]
- endif
- ret
- newbank endp
-
- $tseng proc ;Tseng
- push ax
- push dx
- and al,7
- mov ah,al
- shl al,1
- shl al,1
- shl al,1
- or al,ah
- or al,01000000b
- mov dx,3cdh
- out dx,al
- sti
- pop dx
- pop ax
- ret
- $tseng endp
-
- $tseng4 proc ;Tseng 4000 series
- push ax
- push dx
- mov ah,al
- mov dx,3bfh ;Enable access to extended registers
- mov al,3
- out dx,al
- mov dl,0d8h
- mov al,0a0h
- out dx,al
- and ah,15
- mov al,ah
- shl al,1
- shl al,1
- shl al,1
- shl al,1
- or al,ah
- mov dl,0cdh
- out dx,al
- sti
- pop dx
- pop ax
- ret
- $tseng4 endp
-
- $trident proc ;Trident
- push ax
- push dx
- mov dx,3ceh ;set page size to 64k
- mov al,6
- out dx,al
- inc dl
- in al,dx
- dec dl
- or al,4
- mov ah,al
- mov al,6
- out dx,ax
-
- mov dl,0c4h ;switch to BPS mode
- mov al,0bh
- out dx,al
- inc dl
- in al,dx
- dec dl
-
- mov ah,byte ptr OSEG[curbk]
- xor ah,2
- mov dx,3c4h
- mov al,0eh
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $trident endp
-
- $video7 proc ;Video 7
- push ax
- push dx
- push cx
- ; Video-7 1024x768x16 mode patch (thanks to Frank Lozier 11/8/89).
- cmp colors,16
- jne video7xx
- shl ax,1
- shl ax,1
- video7xx:
- and ax,15
- mov ch,al
- mov dx,3c4h
- mov ax,0ea06h
- out dx,ax
- mov ah,ch
- and ah,1
- mov al,0f9h
- out dx,ax
- mov al,ch
- and al,1100b
- mov ah,al
- shr ah,1
- shr ah,1
- or ah,al
- mov al,0f6h
- out dx,al
- inc dx
- in al,dx
- dec dx
- and al,not 1111b
- or ah,al
- mov al,0f6h
- out dx,ax
- mov ah,ch
- mov cl,4
- shl ah,cl
- and ah,100000b
- mov dl,0cch
- in al,dx
- mov dl,0c2h
- and al,not 100000b
- or al,ah
- out dx,al
- sti
- pop cx
- pop dx
- pop ax
- ret
- $video7 endp
-
- $paradise proc ;Paradise
- push ax
- push dx
- mov dx,3ceh
- mov ax,50fh ;turn off write protect on VGA registers
- out dx,ax
- mov ah,byte ptr OSEG[curbk]
- shl ah,1
- shl ah,1
- shl ah,1
- shl ah,1
- mov al,9
- out dx,ax
- mov ax,000Fh ;reprotect registers, 910512
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $paradise endp
-
- $chipstech proc ;Chips & Tech
- push ax
- push dx
- mov dx,46e8h ;place chip in setup mode
- mov ax,1eh
- out dx,ax
- mov dx,103h ;enable extended registers
- mov ax,0080h ; (patched per JB's msg - Bert)
- out dx,ax
- mov dx,46e8h ;bring chip out of setup mode
- mov ax,0eh
- out dx,ax
- mov ah,byte ptr OSEG[curbk]
- shl ah,1 ;change 64k bank number into 16k bank number
- shl ah,1
- mov al,10h
- mov dx,3d6h
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $chipstech endp
-
- $ativga proc ;ATI VGA Wonder
- push ax
- push dx
- mov ah,al
- mov dx,1ceh
- mov al,0b2h
- out dx,al
- inc dl
- in al,dx
- shl ah,1
- and al,0e1h
- or ah,al
- mov al,0b2h
- dec dl
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $ativga endp
-
- $everex proc ;Everex
- push ax
- push dx
- push cx
- mov cl,al
- mov dx,3c4h
- mov al,8
- out dx,al
- inc dl
- in al,dx
- dec dl
- shl al,1
- shr cl,1
- rcr al,1
- mov ah,al
- mov al,8
- out dx,ax
- mov dl,0cch
- in al,dx
- mov dl,0c2h
- and al,0dfh
- shr cl,1
- jc nob2
- or al,20h
- nob2: out dx,al
- sti
- pop cx
- pop dx
- pop ax
- ret
- $everex endp
-
- $aheada proc
- push ax
- push dx
- push cx
- mov ch,al
- mov dx,3ceh ;Enable extended registers
- mov ax,200fh
- out dx,ax
- mov dl,0cch ;bit 0
- in al,dx
- mov dl,0c2h
- and al,11011111b
- shr ch,1
- jnc temp_1
- or al,00100000b
- temp_1: out dx,al
- mov dl,0cfh ;bits 1,2,3
- mov al,0
- out dx,al
- inc dx
- in al,dx
- dec dx
- and al,11111000b
- or al,ch
- mov ah,al
- mov al,0
- out dx,ax
- sti
- pop cx
- pop dx
- pop ax
- ret
- $aheada endp
-
- $aheadb proc
- push ax
- push dx
- push cx
- mov ch,al
- mov dx,3ceh ;Enable extended registers
- mov ax,200fh
- out dx,ax
- mov ah,ch
- mov cl,4
- shl ah,cl
- or ah,ch
- mov al,0dh
- out dx,ax
- sti
- pop cx
- pop dx
- pop ax
- ret
- $aheadb endp
-
- $oaktech proc ;Oak Technology Inc OTI-067
- push ax
- push dx
- and al,15
- mov ah,al
- shl al,1
- shl al,1
- shl al,1
- shl al,1
- or ah,al
- mov al,11h
- mov dx,3deh
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $oaktech endp
-
- $genoa proc ;GENOA GVGA
- push ax
- push dx
- mov ah,al
- shl al,1
- shl al,1
- shl al,1
- or ah,al
- mov al,6
- or ah,40h
- mov dx,3c4h
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $genoa endp
-
- $ncr proc ;NCR 77C22E
- push ax
- push dx
- shl al,1 ;change 64k bank number into 16k bank number
- shl al,1
- mov ah,al
- mov al,18h
- mov dx,3c4h
- out dx,ax
- mov ax,19h
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $ncr endp
-
- $compaq proc ;Compaq
- push ax
- push dx
- mov dx,3ceh
- mov ax,50fh ;unlock extended registers
- out dx,ax
- mov ah,byte ptr OSEG[curbk]
- shl ah,1 ;change 64k bank number into 4k bank number
- shl ah,1
- shl ah,1
- shl ah,1
- mov al,45h
- out dx,ax
- sti
- pop dx
- pop ax
- ret
- $compaq endp
-
- ;
- ; Read/Write 64K pages
- ;
- $vesa1 proc ; VESA bank switching
- push ax
- push bx
- push dx
- mul vesa_granularity ; Adjust for the granularity factor
- mov dx,ax ; Select window position
- mov bx,0 ; select window (bank) sub-command
- call dword ptr vesa_bankswitch ; do it!
- pop dx
- pop bx
- pop ax
- sti
- ret
- $vesa1 endp
- ;
- ; Read-only/Write-only 64K pages
- ;
- $vesa2 proc ; VESA bank switching
- push ax
- push bx
- push dx
- mul vesa_granularity ; Adjust for the granularity factor
- mov dx,ax ; Select window position
- push dx
- mov bx,0 ; select window (bank) sub-command
- call dword ptr vesa_bankswitch ; do it!
- pop dx
- inc bx
- call dword ptr vesa_bankswitch
- pop dx
- pop bx
- pop ax
- sti
- ret
- $vesa2 endp
- ;
- ; Read/Write 32K pages
- ;
- $vesa3 proc ; VESA bank switching
- push ax
- push bx
- push dx
- mul vesa_granularity ; Adjust for the granularity factor
- mov dx,ax ; Select window position
- push dx
- mov bx,vesa_low_window ; select window (bank) sub-command
- call dword ptr vesa_bankswitch ; do it!
- pop dx
- add dx,vesa_gran_offset ; 2nd window is at 32K offset from 1st
- mov bx,vesa_high_window
- call dword ptr vesa_bankswitch
- pop dx
- pop bx
- pop ax
- sti
- ret
- $vesa3 endp
-
- $vesa_nullbank proc ; null routine for vesa_bankswitch when unknown
- ret
- $vesa_nullbank endp
-
- $nobank proc
- sti
- ret
- $nobank endp
-
- bkadr macro flag,func,entries ; Bert
- mov video_entries, offset entries ; Bert
- mov [flag],1
- mov [bankadr],offset func
- if @CodeSize
- mov [bankseg],seg func
- endif
- endm
-
- nojmp macro
- local lbl
- jmp lbl
- lbl:
- endm
-
- whichvga proc near
- push bp ; save it around all the int 10s
-
- cmp svga_type,0 ; was a SuperVGA adapter forced?
- jne type1_forced ; yup - wade through the options
- jmp not_forced ; nope - skip this section
- type1_forced:
- cmp svga_type,1
- jne type2_forced
- bkadr aheada,$aheada,ahead_entries
- type2_forced:
- cmp svga_type,2
- jne type3_forced
- bkadr ativga,$ativga,ati_entries
- type3_forced:
- cmp svga_type,3
- jne type4_forced
- bkadr chipstech,$chipstech,chips_entries
- type4_forced:
- cmp svga_type,4
- jne type5_forced
- bkadr everex,$everex,everex_entries
- type5_forced:
- cmp svga_type,5
- jne type6_forced
- bkadr genoa,$genoa,genoa_entries
- type6_forced:
- cmp svga_type,6
- jne type7_forced
- bkadr ncr,$ncr,ncr_entries
- type7_forced:
- cmp svga_type,7
- jne type8_forced
- bkadr oaktech,$oaktech,oaktech_entries
- type8_forced:
- cmp svga_type,8
- jne type9_forced
- bkadr paradise,$paradise,paradise_entries
- type9_forced:
- cmp svga_type,9
- jne type10_forced
- bkadr trident,$trident,trident_entries
- type10_forced:
- cmp svga_type,10
- jne type11_forced
- bkadr tseng,$tseng,tseng_entries
- type11_forced:
- cmp svga_type,11
- jne type12_forced
- bkadr tseng4,$tseng4,tseng4_entries
- type12_forced:
- cmp svga_type,12
- jne type13_forced
- bkadr video7,$video7,video7_entries
- type13_forced:
- cmp svga_type,13
- jne type14_forced
- bkadr aheadb,$aheadb,ahead_entries
- type14_forced:
- jmp fini
- not_forced:
-
- cmp vesa_detect,0 ; is VESA-detection disabled?
- je notvesa ; yup - skip this
- mov ax,4f00h ; check for VESA adapter
- push ds ; set ES == DS
- pop es ; ...
- mov di, offset dacbox ; answer goes here (a safe place)
- int 10h ; do it.
- cmp ax,004fh ; successful response?
- jne notvesa ; nope. Not a VESA adapter
-
- cmp byte ptr 0[di],'V' ; string == 'VESA'?
- jne notvesa ; nope. Not a VESA adapter
- cmp byte ptr 1[di],'E' ; string == 'VESA'?
- jne notvesa ; nope. Not a VESA adapter
- cmp byte ptr 2[di],'S' ; string == 'VESA'?
- jne notvesa ; nope. Not a VESA adapter
- cmp byte ptr 3[di],'A' ; string == 'VESA'?
- jne notvesa ; nope. Not a VESA adapter
- bkadr vesa,$vesa_nullbank, vesa_entries
- jmp fini
- notvesa:
-
- call xga_detect ; XGA Adapter?
- cmp ax,0
- je notxga ; nope
- bkadr xga,xga_newbank, xga_entries
- jmp fini
- notxga:
-
- mov si,1
- mov ax,0c000h
- mov es,ax
- cmp word ptr es:[40h],'13'
- jnz noati
- bkadr ativga,$ativga,ati_entries ; Bert
- mov dx,es:[10h] ; Get value of ATI extended register
- mov bl,es:[43h] ; Get value of ATI chip version
- cmp bl,'3'
- jae v6up ; Use different method to determine
- mov al,0bbh ; memory size of chip version is 3 or higher
- cli
- out dx,al
- inc dx
- in al,dx ; Get ramsize byte for chip versions 1 & 2
- sti
- test al,20h
- jz no512
- mov [vga512],1
- jmp short no512
-
- v6up: mov al,0b0h ; Method used for newer ATI chip versions
- cli
- out dx,al
- inc dx
- in al,dx ; Get ramsize byte for versions 3-5
- sti
- test al,10h ; Check if ramsize byte indicates 256K or 512K bytes
- jz v7up
- mov [vga512],1
- v7up: cmp bl,'4' ; Check for ramsize for ATI chip versions 4 & 5
- jb no512
- test al,8 ; Check if version 5 ATI chip has 1024K
- jz no512
- mov [vga1024],1
- no512: jmp fini
-
- noati: mov ax,7000h ;Test for Everex
- xor bx,bx
- cld
- int 10h
- cmp al,70h
- jnz noev
- bkadr everex,$everex, everex_entries ; Bert
- and ch,11000000b
- jz temp_2
- mov [vga512],1
- temp_2: and dx,0fff0h
- cmp dx,6780h
- jz yeste
- cmp dx,2360h
- jnz note
- yeste: bkadr trident,$trident, everex_entries ; Bert
- mov everex,0
- note: jmp fini
-
- noev:
- mov ax,0bf03h ;Test for Compaq
- xor bx,bx
- mov cx,bx
- int 10h
- cmp ax,0bf03h
- jnz nocp
- test cl,40h ;is 640x480x256 available? ;(??)
- jz nocp
- bkadr compaq,$compaq,compaq_entries ; Bert
- mov [vga512],1
- jmp fini
-
- nocp: mov dx,3c4h ;Test for NCR 77C22E
- mov ax,0ff05h
- call $isport2
- jnz noncr
- mov ax,5 ;Disable extended registers
- out dx,ax
- mov ax,0ff10h ;Try to write to extended register 10
- call $isport2 ;If it writes then not NCR
- jz noncr
- mov ax,105h ;Enable extended registers
- out dx,ax
- mov ax,0ff10h
- call $isport2
- jnz noncr ;If it does NOT write then not NCR
- bkadr ncr,$ncr,ncr_entries ; Bert
- mov [vga512],1
- jmp fini
-
- noncr: mov dx,3c4h ;Test for Trident
- mov al,0bh
- out dx,al
- inc dl
- in al,dx
- and al,0fh
- cmp al,06h
- ja notri
- cmp al,2
- jb notri
- bkadr trident,$trident, trident_entries ; Bert
- cmp al,3
- jb no89
- mov [t8900],1
- mov dx,3d4h ; (was 3d5h in version 17.2)
- mov al,1fh
- out dx,al
- inc dx
- in al,dx
- and al,3
- cmp al,1
- jb notmem
- mov [vga512],1
- je notmem
- mov [vga1024],1
- notmem: jmp fini
-
- no89: mov [vga512],1
- jmp fini
-
- notri: mov ax,6f00h ;Test for Video 7
- xor bx,bx
- cld
- int 10h
- cmp bx,'V7'
- jnz nov7
- bkadr video7,$video7, video7_entries ; Bert
- mov ax,6f07h
- cld
- int 10h
- and ah,7fh
- cmp ah,1
- jbe temp_3
- mov [vga512],1
- temp_3: cmp ah,3
- jbe temp_4
- mov [vga1024],1
- temp_4: jmp fini
-
- nov7: mov dx,3d4h ;Test for GENOA GVGA
- mov al,2eh ;check for Herchi Register top 6 bits
- out dx,al
- inc dx
- in al,dx
- dec dx
- test al,11111100b ;top 6 bits should be zero
- jnz nogn
- mov ax,032eh ;check for Herchi Register
- call $isport2
- jnz nogn
- mov dx,3c4h
- mov al,7
- out dx,al
- inc dx
- in al,dx
- dec dx
- test al,10001000b
- jnz nogn
- mov al,10h
- out dx,al
- inc dx
- in al,dx
- dec dx
- and al,00110000b
- cmp al,00100000b
- jnz nogn
- mov dx,3ceh
- mov ax,0ff0bh
- call $isport2
- jnz nogn
- mov dx,3c4h ;check for memory segment register
- mov ax,3f06h
- call $isport2
- jnz nogn
- mov dx,3ceh
- mov ax,0ff0ah
- call $isport2
- jnz nogn
- bkadr genoa,$genoa, genoa_entries ; Bert
- mov [vga512],1
- jmp fini
-
- nogn: call $cirrus ;Test for Cirrus
- cmp [cirrus],0
- je noci
- jmp fini
-
- noci: mov dx,3ceh ;Test for Paradise
- mov al,9 ;check Bank switch register
- out dx,al
- inc dx
- in al,dx
- dec dx
- or al,al
- jnz nopd
-
- mov ax,50fh ;turn off write protect on VGA registers
- out dx,ax
- mov dx,offset $pdrsub
- mov cx,1
- call $chkbk
- jc nopd ;if bank 0 and 1 same not paradise
- bkadr paradise,$paradise, paradise_entries ; Bert
- mov dx,3ceh
- mov al,0bh ;512k detect from Bob Berry
- out dx,al
- inc dx
- in al,dx
- test al,80h ;if top bit set then 512k
- jz nop512
- test al,40h
- jz nop1024
- mov [vga1024],1
- jmp fini
- nop1024:
- mov [vga512],1
- nop512: jmp fini
-
- nopd: mov ax,5f00h ;Test for Chips & Tech
- xor bx,bx
- cld
- int 10h
- cmp al,5fh
- jnz noct
- bkadr chipstech,$chipstech, chips_entries ; Bert
- cmp bh,1
- jb temp_5
- mov [vga512],1
- temp_5:
- jmp fini
-
- noct: mov ch,0
- mov dx,3dah ;Test for Tseng 4000 & 3000
- in al,dx ;bit 8 is opposite of bit 4
- mov ah,al ;(vertical retrace bit)
- shr ah,1
- shr ah,1
- shr ah,1
- shr ah,1
- xor al,ah
- test al,00001000b
- ; jz nots
- jnz @F
- jmp nots
- @@:
- mov dx,3d4h ;check for Tseng 4000 series
- mov ax,0f33h
- call $isport2
- jnz not4
- mov ax,0ff33h ;top 4 bits should not be there
- call $isport2
- ; jz nots
- jnz @F
- jmp nots
- @@:
- mov ch,1
-
- not4: mov dx,3bfh ;Enable access to extended registers
- mov al,3
- out dx,al
- mov dx,3d8h
- mov al,0a0h
- out dx,al
- cmp ch,0
- jnz yes4
-
- mov dx,3d4h ;Test for Tseng 3000 or 4000
- mov ax,1f25h ;is the Overflow High register there?
- call $isport2
- jnz nots
- mov al,03fh ;bottom six bits only
- jmp short yes3
- yes4: mov al,0ffh
- yes3: mov dx,3cdh ;test bank switch register
- call $isport1
- jnz nots
- bkadr tseng,$tseng, tseng_entries ; Bert
- cmp ch,0
- jnz t4mem
- ; mov [vga512],1
- call $t3memchk
- jmp fini
-
- t4mem: mov dx,3d4h ;Tseng 4000 memory detect 1meg
- mov al,37h
- out dx,al
- inc dx
- in al,dx
- test al,1000b ;if using 64kx4 RAMs then no more than 256k
- jz nomem
- and al,3
- cmp al,1 ;if 8 bit wide bus then only two 256kx4 RAMs
- jbe nomem
- mov [vga512],1
- cmp al,2 ;if 16 bit wide bus then four 256kx4 RAMs
- je nomem
- mov [vga1024],1 ;full meg with eight 256kx4 RAMs
- nomem: bkadr tseng4,$tseng4, tseng4_entries ; Bert
- jmp fini
-
- nots:
- mov dx,3ceh ;Test for Above A or B chipsets
- mov ax,0ff0fh ;register should not be fully available
- call $isport2
- jz noab
- mov ax,200fh
- out dx,ax
- inc dx
- nojmp
- in al,dx
- cmp al,21h
- jz verb
- cmp al,20h
- jnz noab
- bkadr aheada,$aheada, ahead_entries ; Bert
- mov [vga512],1
- jmp short fini
-
- verb: bkadr aheadb,$aheadb, ahead_entries ; Bert
- mov [vga512],1
- jmp short fini
-
- noab: mov dx,3deh ;Test for Oak Technology
- mov ax,0ff11h ;look for bank switch register
- call $isport2
- jnz nooak
- bkadr oaktech,$oaktech, oaktech_entries ; Bert
- mov al,0dh
- out dx,al
- inc dx
- nojmp
- in al,dx
- test al,11000000b
- jz no4ram
- mov [vga512],1
- test al,01000000b
- jz no4ram
- mov [vga1024],1
- no4ram: jmp short fini
-
- nooak: mov si,0
-
- fini: mov ax,si
- pop bp
- ret
- whichvga endp
-
-
- ;Segment to access video buffer (based on GR[6])
- buftbl dw 0A000h,0A000h,0B000h,0B800h
-
- $t3memchk proc near ;[Charles Marslett -- ET3000 memory ck]
- mov dx,3dah
- in al,dx ;Reset the attribute flop (read 0x3DA)
- mov dx,03c0h
- mov al,36h
- out dx,al
- inc dx
- in al,dx ;Save contents of ATTR[0x16]
- push ax
- or al,10h
- dec dx
- out dx,al
- mov dx,3ceh ;Find the RAM buffer...
- mov al,6
- out dx,al
- inc dx
- in al,dx
- and ax,000Ch
- shr ax,1
-
- mov bx,ax
- push es
- mov es,cs:buftbl[bx]
- mov ax,09C65h
- mov bx,1
- mov es:[bx],ax
- mov es:[bx+2],ax
- inc bx
- mov ax,es:[bx]
- pop es
- cmp ax,0659Ch
- jne et3k_256
- mov [vga512],1
- et3k_256:
- mov dx,3c0h
- mov al,36h
- out dx,al
- pop ax
- out dx,al ;Restore ATTR[16h]
- ret
- $t3memchk endp
-
-
- $cirrus proc near
- mov dx,3d4h ; assume 3dx addressing
- mov al,0ch ; screen a start address hi
- out dx,al ; select index
- inc dx ; point to data
- mov ah,al ; save index in ah
- in al,dx ; get screen a start address hi
- xchg ah,al ; swap index and data
- push ax ; save old value
- push dx ; save crtc address
- xor al,al ; clear crc
- out dx,al ; and out to the crtc
-
- mov al,1fh ; Eagle ID register
- dec dx ; back to index
- out dx,al ; select index
- inc dx ; point to data
- in al,dx ; read the id register
- mov bh,al ; and save it in bh
-
- mov cl,4 ; nibble swap rotate count
- mov dx,3c4h ; sequencer/extensions
- mov bl,6 ; extensions enable register
-
- ror bh,cl ; compute extensions disable value
- mov ax,bx ; extensions disable
- out dx,ax ; disable extensions
- inc dx ; point to data
- in al,dx ; read enable flag
- or al,al ; disabled ?
- jnz exit ; nope, not an cirrus
-
- ror bh,cl ; compute extensions enable value
- dec dx ; point to index
- mov ax,bx ; extensions enable
- out dx,ax ; enable extensions
- inc dx ; point to data
- in al,dx ; read enable flag
- cmp al,1 ; enabled ?
- jne exit ; nope, not an cirrus
- mov [cirrus],1
- mov video_entries, offset no_entries ; Bert
- mov [bankadr],offset $nobank
- if @CodeSize
- mov [bankseg],seg $nobank
- endif
- exit: pop dx ; restore crtc address
- dec dx ; point to index
- pop ax ; recover crc index and data
- out dx,ax ; restore crc value
- ret
- $cirrus endp
-
- $chkbk proc near ;paradise bank switch check
- mov di,0b800h
- mov es,di
- xor di,di
- mov bx,1234h
- call $gochk
- jnz nopd
- mov bx,4321h
- call $gochk
- jnz nopd
- clc
- ret
- nopd: stc
- ret
- $chkbk endp
-
- $gochk proc near
- push si
- mov si,bx
-
- mov al,cl
- call dx
- xchg bl,es:[di]
- mov al,ch
- call dx
- xchg bh,es:[di]
-
- xchg si,bx
-
- mov al,cl
- call dx
- xor bl,es:[di]
- mov al,ch
- call dx
- xor bh,es:[di]
-
- xchg si,bx
-
- mov al,ch
- call dx
- mov es:[di],bh
- mov al,cl
- call dx
- mov es:[di],bl
-
- mov al,0
- call dx
- or si,si
- pop si
- ret
- $gochk endp
-
-
- $pdrsub proc near ;Paradise
- push dx
- mov ah,al
- mov dx,3ceh
- mov al,9
- out dx,ax
- pop dx
- ret
- $pdrsub endp
-
- $isport2 proc near
- push bx
- mov bx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- xchg al,ah
- push ax
- mov ax,bx
- out dx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- and al,bh
- cmp al,bh
- jnz noport
- mov al,ah
- mov ah,0
- out dx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- and al,bh
- cmp al,0
- noport: pop ax
- out dx,ax
- pop bx
- ret
- $isport2 endp
-
- $isport1 proc near
- mov ah,al
- in al,dx
- push ax
- mov al,ah
- out dx,al
- in al,dx
- and al,ah
- cmp al,ah
- jnz noport
- mov al,0
- out dx,al
- in al,dx
- and al,ah
- cmp al,0
- noport: pop ax
- out dx,al
- ret
- $isport1 endp
-
- videowrite proc near ; your-own-video write routine
- mov ah,0 ; clear the high-order color byte
- push ax ; colors parameter
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr writevideo ; let the external routine do it
- add sp,6 ; pop the parameters
- ret ; we done.
- videowrite endp
-
- videoread proc near ; your-own-video read routine
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr readvideo ; let the external routine do it
- add sp,4 ; pop the parameters
- ret ; we done.
- videoread endp
-
- diskwrite proc near ; disk-video write routine
- push ax ; colors parameter
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr writedisk ; let the external routine do it
- add sp,6 ; pop the parameters
- ret ; we done.
- diskwrite endp
-
- diskread proc near ; disk-video read routine
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr readdisk ; let the external routine do it
- add sp,4 ; pop the parameters
- ret ; we done.
- diskread endp
-
-
- ; ***********************************************************************
- ;
- ; TARGA MODIFIED 1 JUNE 89 - j mclain
- ;
- tgawrite proc near
- push ax ; colors parameter
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr WriteTGA ; writeTGA( x, y, color )
- add sp,6 ; pop the parameters
- ret
- tgawrite endp
-
- tgaread proc near
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr ReadTGA ; readTGA( x, y )
- add sp,4 ; pop the parameters
- ret
- tgaread endp
-
-
- ; TARGA+ Code 2-11-91, Mark Peterson
-
- TPlusWrite PROC NEAR
- push ax
- push dx
- push cx
- call FAR PTR WriteTPlusBankedPixel
- add sp, 6
- ret
- TPlusWrite ENDP
-
- TPlusRead PROC NEAR
- push dx
- push cx
- call FAR PTR ReadTPlusBankedPixel
- add sp, 4
- ret
- TPlusRead ENDP
-
- ; 8514/a afi routines JCO, not needed, 4/11/92
- ;f85start proc near
- ; call far ptr open8514
- ; ret
- ;f85start endp
-
- ;f85end proc near
- ; call far ptr close8514
- ; ret
- ;f85end endp
-
- ;f85write proc near
- ; call far ptr fr85wdot
- ; ret
- ;f85write endp
-
- ;f85read proc near
- ; call far ptr fr85rdot
- ; ret
- ;f85read endp
-
- hgcwrite proc near
- mov ah,0 ; clear the high-order color byte
- push ax ; colors parameter
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr writehgc ; let the Herc. Write dot routine do it
- add sp,6 ; pop the parameters
- ret
- hgcwrite endp
-
- hgcread proc near
- push dx ; 'y' parameter
- push cx ; 'x' parameter
- call far ptr readhgc ; call the Hercules Read dot routine
- add sp,4 ; pop the parameters
- ret
- hgcread endp
-
- hgcstart proc near ; hercules start routine
- call far ptr inithgc ; let the external routine do it
- ret ; we done.
- hgcstart endp
-
- hgcend proc near ; hercules end routine
- call far ptr termhgc ; let the external routine do it
- ret ; we done.
- hgcend endp
-
- ; **************** video adapter initialization *******************
- ;
- ; adapter_init:
- ; called from general.asm once per run
-
- adapter_init proc far ; initialize the video adapter (to VGA)
- mov ax,[bankadr] ; Initialize the bank-switching
- mov video_bankadr,ax ; logic to the do-nothing routine
- mov ax,[bankseg] ; ...
- mov video_bankseg,ax ; ...
- mov bx,0 ; clear out all of the 256-mode flags
- mov tseng,bx ; ...
- mov trident,bx ; ...
- mov video7,bx ; ...
- mov paradise,bx ; ...
- mov chipstech,bx ; ...
- mov ativga,bx ; ...
- mov everex,bx ; ...
- mov cirrus,bx ; ...
- mov aheada,bx ; ...
- mov aheadb,bx ; ...
- mov tseng4,bx ; ...
- mov oaktech,bx ; ...
- mov [bankadr],offset $nobank
- mov [bankseg],seg $nobank
- mov video_entries, offset no_entries ; ...
- ret
- adapter_init endp
-
- ; adapter_detect:
- ; This routine performs a few quick checks on the type of
- ; video adapter installed.
- ; It sets variables video_type and textsafe,
- ; and fills in a few bank-switching routines.
-
- adapter_detect proc uses di si es
- push bp ; some bios's don't save during int 10h
- cmp done_detect,0 ; been called already?
- je adapter_detect2 ; nope
- jmp adapter_ret ; yup, do nothing
- adapter_detect2:
- inc done_detect ; don't get called again
-
- cmp video_type,0 ; video_type preset by command line arg?
- jne go_adapter_set ; yup, use what we're told
-
- cmp TPlusFlag, 0
- je NotTPlus
- call far ptr CheckForTPlus
- or ax, ax
- jz NotTPlus
- mov TPlusInstalled, 1 ; flag it and check for primary adapter
-
- NotTPlus:
- mov ax,1a00h ; start by trying int 10 func 1A
- int 10h ; ...
- cmp al,1ah ; was AL modified?
- je adapter_detect_4 ; yup. go decode what we got
- mov ax,1200h ; try this vga-only function
- mov bl,34h ; enable cursor emulation
- int 10h ; ...
- cmp al,12h ; did it work?
- je adapter_detect_vga ; yup, vga
- mov ah,12h ; look for an EGA
- mov bl,10h ; by using an EGA-specific call
- int 10h ; ...
- cmp bl,10h ; was BL modified?
- je adapter_detect_notega ; nope, < EGA
- mov video_type,3 ; set the video type: EGA
- cmp bh,1 ; monochrome monitor?
- jne go_adapter_set ; nope
- mov mode7text,1 ; yup, use mode 7 for text
- jmp short go_adapter_set ; We done.
- adapter_detect_4:
- cmp bl,1 ; =1?
- jne adapter_detect_4a ; nope
- jmp adapter_detect_hgc ; MDA, assume HGC (nothing else works)
- adapter_detect_4a:
- mov video_type,2 ; set the video type: CGA
- cmp bl,3 ; <=2?
- jb go_adapter_set ; exit with type CGA
- mov video_type,3 ; set the video type: EGA
- cmp bl,5 ; =5?
- jne adapter_detect_5 ; nope
- mov mode7text,1 ; yup, monochrome monitor, mode 7 text
- go_adapter_set:
- jmp adapter_set
- adapter_detect_5:
- cmp bl,6 ; <=5?
- jb go_adapter_set ; exit with type EGA
- cmp bl,10 ; <=9?
- jb adapter_detect_vga ; vga, go check which kind
- mov video_type,4 ; set the video type: MCGA
- cmp bl,13 ; <=12?
- jb go_adapter_set ; exit with type MCGA
- adapter_detect_vga:
- mov video_type,5 ; set the video type: VGA
- call whichvga ; autodetect which VGA is there
- mov ax,[bankadr] ; save the results
- mov video_bankadr,ax ; ...
- mov ax,[bankseg] ; ...
- mov video_bankseg,ax ; ...
- jmp adapter_set
- adapter_detect_notega:
- mov video_type,2 ; set the video type: CGA
- ; HGC detect code from book by Richard Wilton follows
- mov dx,3B4h ; check for MDA, use MDA CRTC address
- mov al,0Fh ; select 6845 reg 0Fh (Cursor Low)
- out dx,al
- inc dx
- in al,dx ; AL := current Cursor Low value
- mov ah,al ; preserve in AH
- mov al,66h ; AL := arbitrary value
- out dx,al ; try to write to 6845
- mov cx,200h
- mdalp: loop mdalp ; wait for 6845 to respond
- in al,dx ; read cursor low again
- xchg ah,al
- out dx,al ; restore original value
- cmp ah,66h ; test whether 6845 responded
- jne adapter_set ; nope, exit with type CGA
- mov dl,0BAh ; DX := 3BAh (status port)
- in al,dx
- and al,80h
- mov ah,al ; AH := bit 7 (vertical sync on HGC)
- mov cx,8000h ; do this 32768 times
- mdalp2: in al,dx
- and al,80h ; isolate bit 7
- cmp ah,al
- loope mdalp2 ; wait for bit 7 to change
- je adapter_set ; didn't change, exit with type CGA
- ;; in al,dx
- ;; and al,01100000b ; mask off bits 5 and 6
- ;; Next line probably backwards but doesn't matter, the test in this area
- ;; distinguishes HGC/HGC+/InColor, which we don't care about anyway.
- ;; jnz adapter_set ; not hgc/hgc+, exit with type CGA
- adapter_detect_hgc:
- mov video_type,1 ; HGC
- mov mode7text,1 ; use mode 7 for text
-
- adapter_set:
- ; ensure a nice safe standard state
- mov ax,3 ; set 80x25x16 text mode, clear screen
- cmp mode7text,0 ; use mode 7 for text?
- je adapter_set2 ; nope
- mov ax,7 ; set mono text mode, clear screen
- adapter_set2:
- int 10h ; set text mode
- mov ax,0500h ; select display page zero
- int 10h ; ...
-
- ; now the color text stuff
- cmp textsafe,2 ; command line textsafe=no?
- je adapter_go_ret ; yup, believe the user
- cmp video_type,3 ; >= ega?
- jae adapter_setup ; yup
- mov textsafe,2 ; textsafe=no
- adapter_go_ret: ; a label for some short jumps
- jmp adapter_ret ; to the exit
-
- adapter_setup:
- ; more standard state, ega and up stuff
- mov ax,1003h ; top attribute bit means blink
- mov bl,01h ; ...
- int 10h ; ...
- mov ax,1103h ; font block 0, 256 chars (not 512)
- mov bl,00h ; ...
- int 10h ; ...
- mov ax,1202h ; 400 scan lines in text mode (vga)
- mov bl,30h ; ...
- int 10h ; ...
- mov ax,1200h ; cga cursor emulation (vga)
- mov bl,34h ; ...
- int 10h ; ...
- mov ax,1200h ; enable default palette loading
- mov bl,31h ; ...
- int 10h ; ...
- cmp textsafe,0 ; were we told textsafe=yes|bios|save?
- jne adapter_ret ; yup
- mov textsafe,1 ; set textsafe=yes
- adapter_ret:
- cld ; some MSC 6.0 libraries assume this!
- pop bp
- ret
- adapter_detect endp
-
-
- ; select_vga_plane:
- ; Call this routine with cx = plane number.
- ; It works for vga and for ega. (I hope.)
- ; It uses no local variables, caller may have ds register modified.
- ; On return from this routine, the requested vid mem plane is mapped
- ; to A0000; this means that the sequencer and graphics controller
- ; states are not very useful for further real work - before any further
- ; screen painting, better reset video mode.
-
- select_vga_plane proc near ; cl = plane number
- ; some callers may have ds modified, use no variables in here!
- mov dx,SC_INDEX ; sequencer controller
- mov ax,0102h ; select plane
- shl ah,cl ; bit for desired plane
- out dx,ax ; ...
- mov ax,0604h ; no chaining
- out dx,ax ; ...
- mov dx,GC_INDEX ; graphics controller
- mov ax,0001h ; use processor data
- out dx,ax ; ...
- mov al, 04h ; select read plane
- mov ah,cl ; desired plane
- out dx,ax ; ...
- mov ax,0005h ; no even/odd, write mode 0
- out dx,ax ; ...
- mov ax,0106h ; map to a000, no chain, graphics
- out dx,ax ; ...
- mov ax,0ff08h ; enable 8 bits per write
- out dx,ax ; ...
- ret ; all done
- select_vga_plane endp
-
-
- ; **************** internal Read/Write-a-line routines *********************
- ;
- ; These routines are called by out_line(), put_line() and get_line().
- ; They assume the following register values:
- ;
- ; si = offset of array of colors for a row (write routines)
- ; di = offset of array of colors for a row (read routines)
- ;
- ; ax = stopping column
- ; bx =
- ; cx = starting column
- ; dx = row
- ;
- ; Note: so far have converted only normaline, normalineread, mcgaline,
- ; mcgareadline, super256line, super256readline -- Tim
-
- normaline proc near ; Normal Line
- normal_line1:
- push ax ; save stop col
- mov al,[si] ; retrieve the color
- xor ah,ah ; MCP 6-7-91
- push cx ; save the counter around the call
- push dx ; save column around the call
- push si ; save the pointer around the call also
- call dotwrite ; write the dot via the approved method
- pop si ; restore the pointer
- pop dx ; restore the column
- pop cx ; restore the counter
- inc si ; bump it up
- inc cx ; bump it up
- pop ax ; retrieve number of dots
- cmp cx,ax ; more to go?
- jle normal_line1 ; yup. do it.
- ret
- normaline endp
-
- normalineread proc near ; Normal Line
- mov bx,videomem
- mov es,bx
- normal_lineread1:
- push ax ; save stop col
- push cx ; save the counter around the call
- push dx ; save column around the call
- push di ; save the pointer around the call also
- call dotread ; read the dot via the approved method
- pop di ; restore the pointer
- pop dx ; restore the column
- pop cx ; restore the counter
- mov bx,di ; locate the actual pixel color
- mov [bx],al ; retrieve the color
- inc di ; bump it up
- inc cx ; bump it up
- pop ax ; retrieve number of dots
- cmp cx,ax ; more to go?
- jle normal_lineread1 ; yup. do it.
- ret
- normalineread endp
-
- mcgaline proc near ; MCGA 320*200, 246 colors
- sub ax,cx ; last col - first col
- inc ax ; + 1
-
- xchg dh,dl ; bx := 256*y
- mov bx,cx ; bx := x
- add bx,dx ; bx := 256*y + x
- shr dx,1
- shr dx,1 ; dx := 64*y
- add bx,dx ; bx := 320*y + x
- mov di,bx ; di = offset of row in video memory
-
- mov cx,ax ; move this many bytes
- rep movsb ; zap line into memory
- ret
- mcgaline endp
-
- mcgareadline proc near ; MCGA 320*200, 246 colors
-
- sub ax,cx ; last col - first col
- inc ax ; + 1
-
- xchg dh,dl ; bx := 256*y
- mov bx,cx ; bx := x
- add bx,dx ; bx := 256*y + x
- shr dx,1
- shr dx,1 ; dx := 64*y
- add bx,dx ; bx := 320*y + x
- mov si,bx ; di = offset of row in video memory
-
- mov cx,ax ; move this many bytes
- mov ax,ds ; copy data segment to ...
- mov es,ax ; ... es
- mov ax,videomem ; copy video segment to ...
- mov ds,ax ; ... ds
- rep movsb ; zap line into memory
- mov ax,es
- mov ds,ax ; restore data segement to ds
- ret
- mcgareadline endp
-
- vgaline proc near ; Bank Switch EGA/VGA line write
- push cx ; save a few registers
- push ax ; ...
- push dx ; ...
-
- mov bx,dx ; save the rowcount
- mov ax,vxdots ; compute # of dots / pass
- shr ax,1 ; (given 8 passes)
- shr ax,1 ; ...
- shr ax,1 ; ...
- mov di,ax
- neg di ; temp: to see if line will overflow
- mul bx ; now calc first video addr
- cmp dx,curbk ; see if bank changed
- jne bank_is_changing ; if bank change call normaline
- cmp ax,di
- ja bank_is_changing ; if bank WILL change, call normaline
-
- mov di,cx ; compute the starting destination
- shr di,1 ; divide by 8
- shr di,1 ; ...
- shr di,1 ; ...
- add di,ax ; add the first pixel offset
-
- mov dx,03ceh ; set up graphics cntrlr addr
- mov ax,8008h ; set up for the bit mask
- and cx,7 ; adjust for the first pixel offset
- ror ah,cl ; ...
-
- pop bx ; flush old DX value
- pop bx ; flush old AX value
- pop cx ; flush old CX value
- sub bx,cx ; convert to a length value
- add bx,si ; locate the last source locn
-
- mov cx,ax ; save the bit mask
-
- vgaline1:
- out dx,ax ; set the graphics bit mask
- push ax ; save registers for a tad
- push si ; ...
- push di ; ...
- vgaline2:
- mov ah,ds:[si] ; get the color
- mov al,0 ; set set/reset registers
- out dx,ax ; do it.
- mov ax,0f01h ; enable set/reset registers
- out dx,ax ; do it.
- or es:[di],al ; update all bit planes
- inc di ; set up the next video addr
- add si,8 ; and the next source addr
- cmp si,bx ; are we beyond the end?
- jbe vgaline2 ; loop if more dots this pass
- pop di ; restore the saved registers
- pop si ; ...
- pop ax ; ...
- inc si ; offset the source 1 byte
- cmp si,bx ; are we beyond the end?
- ja vgaline4 ; stop if no more dots this pass
- ror ah,1 ; alter bit mask value
- cmp ah,80h ; time to update DI:
- jne vgaline3 ; nope
- inc di ; yup
- vgaline3:
- cmp ah,ch ; already done all 8 of them?
- jne vgaline1 ; nope. do another one.
- vgaline4:
- ;;; call videocleanup ; else cleanup time.
- ret ; and we done.
-
- bank_is_changing:
- pop dx ; restore the registers
- pop ax ; ...
- pop cx ; ...
- call normaline ; just calling newbank didn't quite
- ret ; work. This depends on no bank
- vgaline endp ; change mid line (ok for 1024 wide)
-
- vgareadline proc near ; Bank Switch EGA/VGA line read
- push cx ; save a few registers
- push ax ; ...
- push dx ; ...
-
- mov bx,dx ; save the rowcount
- mov ax,vxdots ; compute # of dots / pass
- shr ax,1 ; (given 8 passes)
- shr ax,1 ; ...
- shr ax,1 ; ...
- mul bx ; now calc first video addr
- cmp dx,curbk ; see if bank changed
- jne bank_is_changing ; if bank change call normaline
-
- mov si,cx ; compute the starting destination
- shr si,1 ; divide by 8
- shr si,1 ; ...
- shr si,1 ; ...
- add si,ax ; add the first pixel offset
-
- and cx,7 ; adjust for the first pixel offset
- mov ch,cl ; save the original offset value
-
- pop bx ; flush old DX value
- pop bx ; flush old AX value
- pop ax ; flush old CX value
- sub bx,ax ; convert to a length value
- add bx,di ; locate the last dest locn
-
- mov ax,0a000h ; EGA/VGA screen starts here
- mov es,ax ; ...
-
- mov dx,03ceh ; set up graphics cntrlr addr
-
- vgaline1:
- push bx ; save BX for a tad
- mov ch,80h ; bit mask to shift
- shr ch,cl ; ...
- mov bx,0 ; initialize bits-read value (none)
- mov ax,0304h ; set up controller address register
- vgareadloop:
- out dx,ax ; do it
- mov bh,es:[si] ; retrieve the old value
- and bh,ch ; mask one bit
- neg bh ; set bit 7 correctly
- rol bx,1 ; rotate the bit into bl
- dec ah ; go for another bit?
- jge vgareadloop ; sure, why not.
- mov ds:[di],bl ; returned pixel value
- pop bx ; restore BX
- inc di ; set up the next dest addr
- cmp di,bx ; are we beyond the end?
- ja vgaline3 ; yup. We done.
- inc cl ; alter bit mask value
- cmp cl,8 ; time to update SI:
- jne vgaline2 ; nope
- inc si ; yup
- mov cl,0 ; ...
- vgaline2:
- jmp short vgaline1 ; do another one.
-
- vgaline3:
- ;;; call videocleanup ; else cleanup time.
- ret ; and we done.
-
- bank_is_changing:
- pop dx ; restore the registers
- pop ax ; ...
- pop cx ; ...
- call normalineread ; just calling newbank didn't quite
- ret ; work. This depends on no bank
- vgareadline endp ; change mid line (ok for 1024 wide)
-
- super256lineaddr proc near ; super VGA 256 colors
- mov ax,vxdots ; this many dots / line
- mov bx,dx ; rowcount
- mul bx ; times this many lines
- push ax ; save pixel address for later
- cmp dx,curbk ; bank ok?
- push dx ; save bank
- je bank_is_ok ; jump if bank ok
- mov al,dl ; newbank needs bank in al
- call far ptr newbank
- bank_is_ok:
- inc bx ; next row
- mov ax,vxdots ; this many dots / line
- mul bx ; times this many lines
- sub ax,1 ; back up some to the last pixel of the
- sbb dx,0 ; previous line
- pop bx ; bank at start of row
- pop ax ; ax = offset of row in video memory
- ret
- super256lineaddr endp
-
- super256line proc near ; super VGA 256 colors
- push ax ; stop col
- push dx ; row
- call super256lineaddr ; ax=video,dl=newbank,bl=oldbank
- mov di,ax ; video offset
- cmp dl,bl ; did bank change?
- pop dx ; row
- pop ax ; stop col
- jne bank_did_chg
- add di,cx ; add start col to video address
- sub ax,cx ; ax = stop - start
- mov cx,ax ; + start column
- inc cx ; number of bytes to move
- rep movsb ; zap line into memory
- jmp short linedone
- bank_did_chg:
- call normaline ; normaline can handle bank change
- linedone:
- ret
- super256line endp
-
- super256readline proc near ; super VGA 256 colors
- push ax ; stop col
- push dx ; row
- call super256lineaddr ; ax=video,dl=newbank,bl=oldbank
- mov si,ax ; video offset
- cmp dl,bl ; did bank change?
- pop dx ; row
- pop ax ; stop col
- jne bank_did_chg
-
- add si,cx ; add start col to video address
- sub ax,cx ; ax = stop - start
- mov cx,ax ; + start column
- inc cx ; number of bytes to move
- mov ax,ds ; save data segment to es
- mov es,ax
- mov ax,videomem ; video segment to es
- mov ds,ax
- rep movsb ; zap line into memory
- mov ax,es ; restore data segment to ds
- mov ds,ax
- jmp short linedone
- bank_did_chg:
- call normalineread ; normaline can handle bank change
- linedone:
- ret
- super256readline endp
-
- tweak256line proc near ; Normal Line: no assumptions
- local plane:byte
- mov bx,ax ; bx = stop col
- sub bx,cx ; bx = stop-start
- inc bx ; bx = how many pixels to write
- cmp bx,3 ; less than four points?
- jg nottoosmall ; algorithm won't work as written
- call normaline ; - give up and call normaline
- ret ; we done
- nottoosmall: ; at least four points - go for it!
- push bx ; save number of pixels
- and bx,3 ; pixels modulo 4 = no of extra pts
- mov ax,vxdots ; width of video row
- ;; shr ax, 1
- ;; shr ax, 1 ; now ax = vxdots/4
- mul dx ; ax points to start of desired row
- push cx ; Save starting column for later
- shr cx,1 ; There are 4 pixels at each address
- shr cx,1 ; so divide X by 4
- add ax,cx ; Point to pixel's address
- mov di,ax ; video offset of first point
- pop cx ; Retrieve starting column
- and cl,3 ; Get the plane number of the pixel
- mov ah,1
- shl ah,cl ; Set the bit corresponding to the plane
- ; the pixel is in
- mov plane,ah ; Save starting plane for ending test
- mov al,MAP_MASK ;
- mov dx,SC_INDEX
- pop cx ; number of pixels to write
- shr cx,1
- shr cx,1 ; cx = number of pixels/4
- cmp bx,0 ; extra pixels?
- je tweak256line1 ; nope - don't add one
- inc cx ; yup - add one more pixel
- tweak256line1:
- OUT DX,AX ; set up VGA registers for plane
- push cx ; save registers changed by movsb
- push si ; ...
- push di ; ...
- tweak256line2:
- movsb ; move the next pixel
- add si,3 ; adjust the source addr (+4, not +1)
- loop tweak256line2 ; loop if more dots this pass
- pop di ; restore the saved registers
- pop si ; ...
- pop cx ; ...
- dec bx ; one less extra pixel
- cmp bx,0 ; out of extra pixels?
- jne noextra
- dec cx ; yup - next time one fewer to write
- noextra:
- inc si ; offset the source 1 byte
- shl ah,1 ; set up for the next video plane
- cmp ah,16 ; at last plane?
- jne notlastplane
- mov ah,1 ; start over with plane 0
- inc di ; bump up video memory
- notlastplane:
- cmp ah,plane ; back to first plane?
- jne tweak256line1 ; nope. perform another loop.
- ret
- tweak256line endp
-
- tweak256readline proc near ; Normal Line: no assumptions
- local plane:byte
- mov bx,ax ; bx = stop col
- sub bx,cx ; bx = stop-start
- inc bx ; bx = how many pixels to write
- cmp bx,3 ; less than four points?
- jg nottoosmall ; algorithm won't work as written
- call normalineread ; - give up and call normalineread
- ret ; we done
- nottoosmall: ; at least four points - go for it!
- push bx ; save number of pixels
- and bx,3 ; pixels modulo 4 = no of extra pts
- mov ax,vxdots ; width of video row
- ;; shr ax, 1
- ;; shr ax, 1 ; now ax = vxdots/4
- mul dx ; ax points to start of desired row
- push cx ; Save starting column for later
- shr cx,1 ; There are 4 pixels at each address
- shr cx,1 ; so divide X by 4
- add ax,cx ; Point to pixel's address
- mov si,ax
- pop cx ; Retrieve starting column
- and cl,3 ; Get the plane number of the pixel
- mov ah,cl
- mov plane,ah ; Save starting plane
- mov al,READ_MAP
- mov dx,GC_INDEX
- pop cx ; number of pixels to write
- shr cx,1
- shr cx,1 ; cx = number of pixels/4
- cmp bx,0 ; extra pixels?
- je tweak256line1 ; nope - don't add one
- inc cx ; yup - add one more pixel
- tweak256line1:
- out dx,ax
- push ax ; save registers
- push cx ; ...
- push di ; ...
- push si ; ...
- mov ax,ds ; copy data segment to es
- mov es,ax ; ...
- mov ax,videomem ; copy video segment to ds
- mov ds,ax ; ...
- tweak256line2:
- movsb ; move the next pixel
- add di,3 ; adjust the source addr (+4, not +1)
- loop tweak256line2 ; loop if more dots this pass
- mov ax,es
- mov ds,ax ; restore data segement to ds
- pop si ; restore the saved registers
- pop di ; ...
- pop cx ; ...
- pop ax ; ...
- dec bx ; one less extra pixel
- cmp bx,0 ; out of extra pixels?
- jne noextra
- dec cx ; yup - next time one fewer to write
- noextra:
- inc di ; offset the source 1 byte
- inc ah ; set up for the next video plane
- and ah,3
- cmp ah,0 ; at last plane?
- jne notlastplane
- inc si ; bump up video memory
- notlastplane:
- cmp ah,plane ; back to first plane?
- jne tweak256line1 ; nope. perform another loop.
- ret
- tweak256readline endp
-
-
- ;f85line proc near
- ; call fr85wbox ;put out the box
- ; ret
- ;f85line endp
-
- ;f85readline proc near
- ; call fr85rbox ;read the box
- ; ret
- ;f85readline endp
-
- ; ******************** Function videocleanup() **************************
-
- ; Called at the end of any assembler video read/writes to make
- ; the world safe for 'printf()'s.
- ; Currently, only ega/vga needs cleanup work, but who knows?
- ;
-
- ;;videocleanup proc near
- ;; mov ax,dotwrite ; check: were we in EGA/VGA mode?
- ;; cmp ax,offset vgawrite ; ...
- ;; jne short videocleanupdone ; nope. no adjustments
- ;; mov dx,03ceh ; graphics controller address
- ;; mov ax,0ff08h ; restore the default bit mask
- ;; out dx,ax ; ...
- ;; mov ax,0003h ; restore the function select
- ;; out dx,ax ; ...
- ;; mov ax,0001h ; restore the enable set/reset
- ;; out dx,ax ; ...
- ;;videocleanupdone:
- ;; ret
- ;;videocleanup endp
-
-
- ; ******************** Zoombox functions **************************
-
- clearbox proc uses di si es
- mov xorTARGA,1 ; faster to flag xorTARGA rather
- ; than check if TARGA is runnin
-
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
-
- mov bx,boxcount ; load up a counter: # points to clear
- dec bx ; switch to an offset value
- eraseoldbox:
- shl bx,1 ; switch to a word pointer
- mov cx,boxx[bx] ; get the (previous) point location
- mov dx,boxy[bx] ; ...
- shr bx,1 ; switch back to character pointer
- mov al,boxvalues[bx] ; get the (previous) color
- push bx ; save the counter
- call dotwrite ; adjust the dot.
- pop bx ; restore the counter
- dec bx ; are we done yet?
- jns eraseoldbox ; nope. try again.
- mov xorTARGA,0 ; in case of TARGA, no more xor
- ;;; call videocleanup ; perform any video cleanup required
- ret ; we done.
- clearbox endp
-
- dispbox proc uses di si es
- mov xorTARGA,1 ; faster to flag xorTARGA rather
- ; than check if TARGA is runnin
-
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
-
- mov bx,boxcount ; load up a counter: # points to draw
- dec bx ; switch to an offset
- readnewbox:
- shl bx,1 ; switch to word counter
- mov cx,boxx[bx] ; get the (new) point location
- mov dx,boxy[bx] ; ...
- shr bx,1 ; switch back to character counter
- push bx ; save the counter
- call dotread ; read the (previous) dot value
- pop bx ; restore the counter
- mov boxvalues[bx],al ; get the (previous) color
- dec bx ; are we done yet?
- jns readnewbox ; nope. try again.
- mov bx,boxcount ; load up a counter: # points to draw
- dec bx ; switch to an offset
- drawnewbox:
- shl bx,1 ; switch to word counter
- mov cx,boxx[bx] ; get the (new) point location
- mov dx,boxy[bx] ; ...
- shr bx,1 ; switch back to character counter
- mov ax,colors ; set the (new) box color
- dec ax
- and ax,boxcolor
- cmp colors,2 ; uhh, is this a B&W screen?
- jne drawnewnotbw ; nope. proceed
- mov al,1 ; XOR the old color
- sub al,boxvalues[bx] ; for visibility
- drawnewnotbw:
- push bx ; save the counter
- call dotwrite ; adjust the dot.
- pop bx ; restore the counter
- dec bx ; are we done yet?
- jns drawnewbox ; nope. try again.
- mov xorTARGA,0 ; in case of TARGA, no more xor
- ;;; call videocleanup ; perform any video cleanup required
- ret ; we done.
-
- dispbox endp
-
-
- ; ********************** Function setvideotext() ************************
-
- ; Sets video to text mode, using setvideomode to do the work.
-
- setvideotext proc
- sub ax,ax
- mov dotmode,ax ; make this zero to avoid trouble
- push ax
- push ax
- push ax
- mov ax,3
- push ax
- call far ptr setvideomode ; (3,0,0,0)
- add sp,8
- ret
- setvideotext endp
-
-
- ; **************** Function setvideomode(ax, bx, cx, dx) ****************
-
- ; This function sets the (alphanumeric or graphic) video mode
- ; of the monitor. Called with the proper values of AX thru DX.
- ; No returned values, as there is no particular standard to
- ; adhere to in this case.
-
- ; (SPECIAL "TWEAKED" VGA VALUES: if AX==BX==CX==0, assume we have a
- ; genuine VGA or register compatable adapter and program the registers
- ; directly using the coded value in DX)
-
- setvideomode proc uses di si es,argax:word,argbx:word,argcx:word,argdx:word
-
- mov ax,sxdots ; initially, set the virtual line
- mov vxdots,ax ; to be the scan line length
-
- cmp dotmode, 29
- jne NotTrueColorMode
- jmp TrueColorAuto
- NotTrueColorMode:
- cmp diskflag,1 ; is disk video active?
- jne nodiskvideo ; nope.
- call far ptr enddisk ; yup, external disk-video end routine
- nodiskvideo:
- cmp videoflag,1 ; say, was the last video your-own?
- jne novideovideo ; nope.
- call far ptr endvideo ; yup, external your-own end routine
- mov videoflag,0 ; set flag: no your-own-video
- jmp short notarga
- novideovideo:
- cmp tgaflag,1 ; TARGA MODIFIED 2 June 89 j mclain
- jne notarga
- call far ptr EndTGA ; endTGA( void )
- mov tgaflag,0 ; set flag: targa cleaned up
- notarga:
-
- cmp xga_isinmode,0 ; XGA in graphics mode?
- je noxga ; nope
- mov ax,0 ; pull it out of graphics mode
- push ax
- mov xga_clearvideo,al
- call far ptr xga_mode
- pop ax
- noxga:
-
- cmp f85flag, 1 ; was the last video 8514?
- jne no8514 ; nope.
- cmp ai_8514, 0 ;check afi flag, JCO 4/11/92
- jne f85endafi
- call close8514hw ;use registers, JCO 4/11/92
- jmp f85enddone
- f85endafi:
- call close8514 ;use near afi, JCO 4/11/92
- ; call f85end ;use afi
- f85enddone:
- mov f85flag, 0
- no8514:
- cmp HGCflag, 1 ; was last video Hercules
- jne noHGC ; nope
- call hgcend
- mov HGCflag, 0
- noHGC:
- mov oktoprint,1 ; say it's OK to use printf()
- mov goodmode,1 ; assume a good video mode
- mov xga_loaddac,1 ; tell the XGA to fake a 'loaddac'
- mov ax,video_bankadr ; restore the results of 'whichvga()'
- mov [bankadr],ax ; ...
- mov ax,video_bankseg ; ...
- mov [bankseg],ax ; ...
-
- mov ax,argax ; load up for the interrupt call
- mov bx,argbx ; ...
- mov cx,argcx ; ...
- mov dx,argdx ; ...
-
- mov videoax,ax ; save the values for future use
- mov videobx,bx ; ...
- mov videocx,cx ; ...
- mov videodx,dx ; ...
-
- call setvideo ; call the internal routine first
-
- cmp goodmode,0 ; is it still a good video mode?
- jne videomodeisgood ; yup.
- mov ax,offset nullwrite ; set up null write-a-dot routine
- mov bx,offset mcgaread ; set up null read-a-dot routine
- mov cx,offset normaline ; set up normal linewrite routine
- mov dx,offset mcgareadline ; set up normal linewrite routine
- mov si,offset swapnormread ; set up the normal swap routine
- jmp videomode ; return to common code
-
- videomodeisgood:
- mov bx,dotmode ; set up for a video table jump
- cmp bx,30 ; are we within the range of dotmodes?
- jbe videomodesetup ; yup. all is OK
- mov bx,0 ; nope. use dullnormalmode
- videomodesetup:
- shl bx,1 ; switch to a word offset
- mov bx,cs:videomodetable[bx] ; get the next step
- jmp bx ; and go there
- videomodetable dw offset dullnormalmode ; mode 0
- dw offset dullnormalmode ; mode 1
- dw offset vgamode ; mode 2
- dw offset mcgamode ; mode 3
- dw offset tseng256mode ; mode 4
- dw offset paradise256mode ; mode 5
- dw offset video7256mode ; mode 6
- dw offset tweak256mode ; mode 7
- dw offset everex16mode ; mode 8
- dw offset targaMode ; mode 9
- dw offset hgcmode ; mode 10
- dw offset diskmode ; mode 11
- dw offset f8514mode ; mode 12
- dw offset cgamode ; mode 13
- dw offset tandymode ; mode 14
- dw offset trident256mode ; mode 15
- dw offset chipstech256mode ; mode 16
- dw offset ati256mode ; mode 17
- dw offset everex256mode ; mode 18
- dw offset yourownmode ; mode 19
- dw offset ati1024mode ; mode 20
- dw offset tseng16mode ; mode 21
- dw offset trident16mode ; mode 22
- dw offset video716mode ; mode 23
- dw offset paradise16mode ; mode 24
- dw offset chipstech16mode ; mode 25
- dw offset everex16mode ; mode 26
- dw offset VGAautomode ; mode 27
- dw offset VESAmode ; mode 28
- dw offset TrueColorAuto ; mode 29
- dw offset dullnormalmode ; mode 30
- dw offset dullnormalmode ; mode 31
-
- tandymode: ; from Joseph Albrecht
- mov tandyseg,0b800h ; set video segment address
- mov tandyofs,0 ; set video offset address
- mov ax,offset plottandy16 ; set up write-a-dot
- mov bx,offset gettandy16 ; set up read-a-dot
- mov cx,offset normaline ; set up the normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swapnormread ; set up the normal swap routine
- cmp videoax,8 ; check for 160x200x16 color mode
- je tandy16low ; ..
- cmp videoax,9 ; check for 320x200x16 color mode
- je tandy16med ; ..
- cmp videoax,0ah ; check for 640x200x4 color mode
- je tandy4high ; ..
- cmp videoax,0bh ; check for 640x200x16 color mode
- je tandy16high ; ..
- tandy16low:
- mov tandyscan,offset scan16k; set scan line address table
- jmp videomode ; return to common code
- tandy16med:
- mov tandyscan,offset scan32k; set scan line address table
- jmp videomode ; return to common code
- tandy4high:
- mov ax,offset plottandy4 ; set up write-a-dot
- mov bx,offset gettandy4 ; set up read-a-dot
- jmp videomode ; return to common code
- tandy16high:
- mov tandyseg,0a000h ; set video segment address
- mov tandyofs,8000h ; set video offset address
- mov tandyscan,offset scan64k; set scan line address table
- jmp videomode ; return to common code
- dullnormalmode:
- mov ax,offset normalwrite ; set up the BIOS write-a-dot routine
- mov bx,offset normalread ; set up the BIOS read-a-dot routine
- mov cx,offset normaline ; set up the normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swapnormread ; set up the normal swap routine
- jmp videomode ; return to common code
- mcgamode:
- mov ax,offset mcgawrite ; set up MCGA write-a-dot routine
- mov bx,offset mcgaread ; set up MCGA read-a-dot routine
- mov cx,offset mcgaline ; set up the MCGA linewrite routine
- mov dx,offset mcgareadline ; set up the MCGA lineread routine
- mov si,offset swap256 ; set up the MCGA swap routine
- jmp videomode ; return to common code
- tseng16mode:
- mov tseng,1 ; set chipset flag
- mov [bankadr],offset $tseng
- mov [bankseg],seg $tseng
- jmp vgamode ; set ega/vga functions
- trident16mode:
- mov trident,1 ; set chipset flag
- mov [bankadr],offset $trident
- mov [bankseg],seg $trident
- jmp vgamode
- video716mode:
- mov video7,1 ; set chipset flag
- mov [bankadr],offset $video7
- mov [bankseg],seg $video7
- jmp vgamode
- paradise16mode:
- mov paradise,1 ; set chipset flag
- mov [bankadr],offset $paradise
- mov [bankseg],seg $paradise
- jmp vgamode
- chipstech16mode:
- mov chipstech,1 ; set chipset flag
- mov [bankadr],offset $chipstech
- mov [bankseg],seg $chipstech
- jmp vgamode
- everex16mode:
- mov everex,1 ; set chipset flag
- mov [bankadr],offset $everex
- mov [bankseg],seg $everex
- jmp vgamode
- VESAmode: ; set VESA 16-color mode
- mov ax,word ptr vesa_mapper
- mov [bankadr],ax
- mov ax,word ptr vesa_mapper+2
- mov [bankseg],ax
- VGAautomode: ; set VGA auto-detect mode
- cmp colors,256 ; 256 colors?
- je VGAauto256mode ; just like SuperVGA
- cmp xga_isinmode,0 ; in an XGA mode?
- jne xgamode
- cmp colors,16 ; 16 colors?
- je vgamode ; just like a VGA
- jmp dullnormalmode ; otherwise, use the BIOS
-
- xgamode:
- mov ax,offset xga_16write ; set up XGA write-a-dot routine
- mov bx,offset xga_16read ; set up XGA read-a-dot routine
- mov cx,offset xga_16linewrite ; set up the XGA linewrite routine
- mov dx,offset normalineread ; set up the XGA lineread routine
- mov si,offset swap256 ; set up the swap routine
- jmp videomode ; return to common code
-
- VGAauto256mode:
- jmp super256mode ; just like a SuperVGA
- egamode:
- vgamode:
- ;;; shr vxdots,1 ; scan line increment is in bytes...
- ;;; shr vxdots,1
- ;;; shr vxdots,1
- mov ax,offset vgawrite ; set up EGA/VGA write-a-dot routine.
- mov bx,offset vgaread ; set up EGA/VGA read-a-dot routine
- mov cx,offset vgaline ; set up the EGA/VGA linewrite routine
- mov dx,offset vgareadline ; set up the EGA/VGA lineread routine
- mov si,offset swapvga ; set up the EGA/VGA swap routine
- jmp videomode ; return to common code
- tseng256mode:
- mov tseng,1 ; set chipset flag
- mov [bankadr],offset $tseng
- mov [bankseg],seg $tseng
- jmp super256mode ; set super VGA linear memory functions
- paradise256mode:
- mov paradise,1 ; set chipset flag
- mov [bankadr],offset $paradise
- mov [bankseg],seg $paradise
- jmp super256mode ; set super VGA linear memory functions
- video7256mode:
- mov video7, 1 ; set chipset flag
- mov [bankadr],offset $video7
- mov [bankseg],seg $video7
- jmp super256mode ; set super VGA linear memory functions
- trident256mode:
- mov trident,1 ; set chipset flag
- mov [bankadr],offset $trident
- mov [bankseg],seg $trident
- jmp super256mode ; set super VGA linear memory functions
- chipstech256mode:
- mov chipstech,1 ; set chipset flag
- mov [bankadr],offset $chipstech
- mov [bankseg],seg $chipstech
- jmp super256mode ; set super VGA linear memory functions
- ati256mode:
- mov ativga,1 ; set chipset flag
- mov [bankadr],offset $ativga
- mov [bankseg],seg $ativga
- jmp super256mode ; set super VGA linear memory functions
- everex256mode:
- mov everex,1 ; set chipset flag
- mov [bankadr],offset $everex
- mov [bankseg],seg $everex
- jmp super256mode ; set super VGA linear memory functions
- VGA256automode: ; Auto-detect SuperVGA
- jmp super256mode ; set super VGA linear memory functions
- VESA256mode: ; set VESA 256-color mode
- mov ax,word ptr vesa_mapper
- mov [bankadr],ax
- mov ax,word ptr vesa_mapper+2
- mov [bankseg],ax
- jmp super256mode ; set super VGA linear memory functions
- super256mode:
- mov ax,offset super256write ; set up superVGA write-a-dot routine
- mov bx,offset super256read ; set up superVGA read-a-dot routine
- mov cx,offset super256line ; set up the linewrite routine
- mov dx,offset super256readline ; set up the normal lineread routine
- mov si,offset swap256 ; set up the swap routine
- jmp videomode ; return to common code
- tweak256mode:
- shr vxdots,1 ; scan line increment is in bytes...
- shr vxdots,1
- mov oktoprint,0 ; NOT OK to printf() in this mode
- mov ax,offset tweak256write ; set up tweaked-256 write-a-dot
- mov bx,offset tweak256read ; set up tweaked-256 read-a-dot
- mov cx,offset tweak256line ; set up tweaked-256 read-a-line
- mov dx,offset tweak256readline ; set up the normal lineread routine
- mov si,offset swapvga ; set up the swap routine
- jmp videomode ; return to common code
- cgamode:
- mov cx,offset normaline ; set up the normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swapnormread ; set up the normal swap routine
- cmp videoax,4 ; check for 320x200x4 color mode
- je cga4med ; ..
- cmp videoax,5 ; ..
- je cga4med ; ..
- cmp videoax,6 ; check for 640x200x2 color mode
- je cga2high ; ..
- cga4med:
- mov ax,offset plotcga4 ; set up CGA write-a-dot
- mov bx,offset getcga4 ; set up CGA read-a-dot
- jmp videomode ; return to common code
- cga2high:
- mov ax,offset plotcga2 ; set up CGA write-a-dot
- mov bx,offset getcga2 ; set up CGA read-a-dot
- jmp videomode ; return to common code
- ati1024mode:
- mov ativga,1 ; set ATI flag.
- mov ax,offset ati1024write ; set up ATI1024 write-a-dot
- mov bx,offset ati1024read ; set up ATI1024 read-a-dot
- mov cx,offset normaline ; set up the normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swap256 ; set up the swap routine
- jmp videomode ; return to common code
- diskmode:
- call far ptr startdisk ; external disk-video start routine
- mov ax,offset diskwrite ; set up disk-vid write-a-dot routine
- mov bx,offset diskread ; set up disk-vid read-a-dot routine
- mov cx,offset normaline ; set up the normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swapnormread ; set up the normal swap routine
- jmp videomode ; return to common code
- yourownmode:
- call far ptr startvideo ; external your-own start routine
- mov ax,offset videowrite ; set up ur-own-vid write-a-dot routine
- mov bx,offset videoread ; set up ur-own-vid read-a-dot routine
- mov cx,offset normaline ; set up the normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swapnormread ; set up the normal swap routine
- mov videoflag,1 ; flag "your-own-end" needed.
- jmp videomode ; return to common code
- targaMode: ; TARGA MODIFIED 2 June 89 - j mclain
- call far ptr StartTGA
- mov ax,offset tgawrite ;
- mov bx,offset tgaread ;
- mov cx,offset normaline ; set up the normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swapnormread ; set up the normal swap routine
- mov tgaflag,1 ;
- jmp videomode ; return to common code
- f8514mode: ; 8514 modes
- cmp ai_8514, 0 ; check if afi flag is set, JCO 4/11/92
- jne f85afi ; yes, try afi
- call open8514hw ; start the 8514a, try registers first JCO
- jnc f85ok
- mov ai_8514, 1 ; set afi flag
- f85afi:
- call open8514 ; start the 8514a, try afi
- jnc f85ok
- mov ai_8514, 0 ; clear afi flag, JCO 4/11/92
- mov goodmode,0 ; oops - problems.
- mov dotmode, 0 ; if problem starting use normal mode
- jmp dullnormalmode
- hgcmode:
- mov oktoprint,0 ; NOT OK to printf() in this mode
- call hgcstart ; Initialize the HGC card
- mov ax,offset hgcwrite ; set up HGC write-a-dot routine
- mov bx,offset hgcread ; set up HGC read-a-dot routine
- mov cx,offset normaline ; set up normal linewrite routine
- mov dx,offset normalineread ; set up the normal lineread routine
- mov si,offset swapnormread ; set up the normal swap routine
- mov HGCflag,1 ; flag "HGC-end" needed.
- jmp videomode ; return to common code
- f85ok:
- cmp ai_8514, 0
- jne f85okafi ; afi flag is set JCO 4/11/92
- mov ax,offset fr85hwwdot ;use register routines
- mov bx,offset fr85hwrdot ;changed to near calls
- mov cx,offset fr85hwwbox ;
- mov dx,offset fr85hwrbox ;
- mov si,offset swapnormread ; set up the normal swap routine
- mov f85flag,1 ;
- mov oktoprint,0 ; NOT OK to printf() in this mode
- jmp videomode ; return to common code
- f85okafi:
- mov ax,offset fr85wdot ;use afi routines, JCO 4/11/92
- mov bx,offset fr85rdot ;changed to near calls
- mov cx,offset fr85wbox ;
- mov dx,offset fr85rbox ;
- mov si,offset swapnormread ; set up the normal swap routine
- mov f85flag,1 ;
- mov oktoprint,0 ; NOT OK to printf() in this mode
- jmp videomode ; return to common code
- TrueColorAuto:
- cmp TPlusInstalled, 1
- jne NoTPlus
- push NonInterlaced
- push PixelZoom
- push MaxColorRes
- push ydots
- push xdots
- call far ptr MatchTPlusMode
- add sp, 10
- or ax, ax
- jz NoTrueColorCard
-
- cmp ax, 1 ; Are we limited to 256 colors or less?
- jne SetTPlusRoutines ; All right! True color mode!
-
- mov cx, MaxColorRes ; Aw well, give'm what they want.
- shl ax, cl
- mov colors, ax
-
- SetTPlusRoutines:
- mov goodmode, 1
- mov oktoprint, 1
- mov ax, offset TPlusWrite
- mov bx, offset TPlusRead
- mov cx, offset normaline
- mov dx, offset normalineread
- mov si, offset swapnormread
- jmp videomode
-
- NoTPlus:
- NoTrueColorCard:
- mov goodmode, 0
- jmp videomode
-
- videomode:
- mov dotwrite,ax ; save the results
- mov dotread,bx ; ...
- mov linewrite,cx ; ...
- mov lineread,dx ; ...
- mov word ptr swapsetup,si ; ...
- mov ax,cs ; ...
- mov word ptr swapsetup+2,ax ; ...
-
- mov ax,colors ; calculate the "and" value
- dec ax ; to use for eventual color
- mov andcolor,ax ; selection
-
- mov boxcount,0 ; clear the zoom-box counter
-
- mov daclearn,0 ; set the DAC rotates to learn mode
- mov daccount,6 ; initialize the DAC counter
- cmp cpu,88 ; say, are we on a 186/286/386?
- jbe setvideoslow ; boo! hiss!
- mov daclearn,1 ; yup. bypass learn mode
- mov ax,cyclelimit ; and go as fast as he wants
- mov daccount,ax ; ...
- setvideoslow:
- call far ptr loaddac ; load the video dac, if we can
- ret
- setvideomode endp
-
- set_vesa_mapping_func proc near
- mov cx, word ptr suffix+2
- and cx,0707h
- cmp cx,0305h
- je use_vesa2
- cmp cx,0503h
- je use_vesa2
- test ch,01h
- jz use_vesa1
- cmp word ptr suffix+6,32 ; None of the above -- 2 32K R/W?
- jne use_vesa1 ; if not, use original 1 64K R/W!
- mov word ptr vesa_mapper,offset $vesa3
- mov ax,32
- div byte ptr suffix+4 ; Get number of pages in 32K
- mov vesa_gran_offset,ax ; Save it for mapping function
- xor dx,dx
- mov al,1
- test word ptr suffix+8, 00800h
- jz low_high_seq
- xchg ax,dx
- low_high_seq:
- mov vesa_low_window,dx ; Window number at A000-A7FF
- mov vesa_high_window,ax ; Window number at A800-AFFF
- jmp short vesamapselected
- use_vesa2:
- mov word ptr vesa_mapper,offset $vesa2
- jmp short vesamapselected
- use_vesa1:
- mov word ptr vesa_mapper,offset $vesa1
- vesamapselected:
- mov word ptr vesa_mapper+2,seg $vesa1
- ret
- set_vesa_mapping_func endp
-
-
- setnullvideo proc
- mov ax,offset nullwrite ; set up null write-a-dot routine
- mov dotwrite,ax ; ...
- mov ax,offset nullread ; set up null read-a-dot routine
- mov dotread,ax ; ...
- ret
- setnullvideo endp
-
- setvideo proc near ; local set-video more
-
- cmp xga_isinmode,0 ; XGA in graphics mode?
- je noxga ; nope
- push ax
- push bx
- push cx
- push dx
- mov ax,0 ; pull it out of graphics mode
- push ax
- mov xga_clearvideo,al
- call far ptr xga_mode
- pop ax
- pop dx
- pop cx
- pop bx
- pop ax
- noxga:
-
- push bp ; save it around all the int 10s
- mov text_type,2 ; set to this for most exit paths
- mov si,offset $vesa_nullbank ; set to do nothing if mode not vesa
- mov word ptr vesa_bankswitch,si
- mov si,seg $vesa_nullbank
- mov word ptr vesa_bankswitch+2,si
- mov word ptr vesa_mapper,offset $nobank
- mov word ptr vesa_mapper+2,seg $nobank
- mov tweakflag,0
-
- cmp ax,0 ; TWEAK?: look for AX==BX==CX==0
- jne short setvideobios ; ...
- cmp bx,0 ; ...
- jne short setvideobios ; ...
- cmp cx,0 ; ...
- jne short setvideobios ; ...
-
- cmp dotmode, 27 ; check for auto-detect modes
- je setvideoauto1
- cmp dotmode, 20 ; check for auto-detect modes
- je setvideoauto1
- cmp dotmode, 4 ; check for auto-detect modes
- je setvideoauto1
- cmp dotmode, 28 ; check for auto-detect modes
- je setvideoauto1
-
- jmp setvideoregs ; anything else - assume register tweak
-
- setvideoauto1:
- jmp setvideoauto ; stupid short 'je' instruction!!
-
- setvideobios:
- mov text_type,0 ; if next branch taken this is true
- cmp ax,3 ; text mode?
- jne setvideobios2 ; nope
- mov textaddr,0b800h
- cmp mode7text,0 ; egamono/hgc?
- je setvideobios_doit ; nope. Just do it.
- mov textaddr,0b000h
- mov ax,7 ; use mode 7
- call maybeor ; maybe or AL or (for Video-7s) BL
- push bp ; weird but necessary, set mode twice
- int 10h ; get colors right on vga systems
- pop bp ; ..
- mov ax,7 ; for the 2nd hit
- jmp short setvideobios_doit
- setvideobios2:
- mov text_type,1 ; if next branch taken this is true
- cmp ax,6 ; 640x200x2 mode?
- je setvideobios_doit ; yup. Just do it.
- mov text_type,2 ; not mode 3 nor 6, so this is true
- mov si,dotmode ; compare the dotmode against
- mov di,video_type ; the video type
- add si,si ; (convert to a word pointer)
- cmp cs:video_requirements[si],di
- jbe setvideobios_doit ; ok
- jmp setvideoerror ; Error.
- setvideobios_doit:
- cmp dotmode,14 ; check for Tandy 1000 mode
- jne setvideobios_doit2 ; ..
- cmp ax,0ah ; check for Tandy 640x200x4 color mode
- jne setvideobios_doit1 ; ..
- push bp ; setup Tandy 640x200x4 color mode
- int 10h ; ..
- pop bp ; ..
- mov di,16 ;port offset for palette registers
- mov bx,0b01h ; remap colors for better display on
- call settandypal ; .. Tandy 640x200x4 color mode
- mov di,16 ;port offset for palette registers
- mov bx,0d02h ; ..
- call settandypal ; ..
- mov di,16 ;port offset for palette registers
- mov bx,0f03h ; ..
- call settandypal ; ..
- jmp setvideobios_worked
- setvideobios_doit1:
- cmp ax,0bh ; check for Tandy 640x200x16 color mode
- jne setvideobios_doit2 ; ..
- call tandysetup ; setup Tandy 640x200x16 color mode
- jmp setvideobios_worked
- setvideobios_doit2:
- call maybeor ; maybe or AL or (for Video-7s) BL
- push bp ; some BIOS's don't save this
- int 10h ; do it via the BIOS.
- pop bp ; restore the saved register
- cmp dotmode,28 ; VESA mode?
- jne setvideobios_worked ; Nope. Return.
- cmp ah,0 ; did it work?
- jne setvideoerror ; Nope. Failed.
- mov vesa_granularity,1 ; say use 64K granules
- push es ; set ES == DS
- mov ax,ds ; ...
- mov es,ax ; ...
- mov ax,4f01h ; ask about this video mode
- mov cx,bx ; this mode
- and cx,07fffh ; (oops - correct for the high-bit)
- mov di, offset suffix ; (a safe spot for 256 bytes)
- int 10h ; do it
- cmp ax,004fh ; did the call work?
- jne nogoodvesamode ; nope
- mov cx, word ptr suffix ; get the attributes
- test cx,1 ; available video mode?
- jz nogoodvesamode ; nope. skip some code
- call set_vesa_mapping_func
- mov cx, word ptr suffix+12 ; get the Bank-switching routine
- mov word ptr vesa_bankswitch, cx ; ...
- mov cx, word ptr suffix+14 ; ...
- mov word ptr vesa_bankswitch+2, cx ; ...
- mov cx, word ptr suffix+16 ; get the bytes / scan line
- cmp cx,0 ; is this entry filled in?
- je skipvesafix ; nope
- ;;; cmp colors,256 ; 256-color mode?
- ;;; jne skipvesafix ; nope
- cmp byte ptr suffix+24,1
- jbe store_vesa_bytes
- shl cx,1 ; if a planar mode, bits are pixels
- shl cx,1 ; so we multiply bytes by 8
- shl cx,1
- store_vesa_bytes:
- mov vxdots,cx ; adjust the screen width accordingly XXX
- ; cmp cx,sxdots ; 8/93 JRS textsafe=save fix
- ; je skipvesafix
- ; mov ax,offset swapnormread ; use the slow swap routine
- ; mov word ptr swapsetup,ax ; ...
- skipvesafix:
- mov cx, word ptr suffix+4 ; get the granularity
- cmp cl,1 ; ensure the divide won't blow out
- jb nogoodvesamode ; granularity == 0???
- mov ax,64 ; ...
- div cl ; divide 64K by granularity
- mov vesa_granularity,al ; multiply the bank number by this
- nogoodvesamode:
- pop es ; restore ES
- mov ax,4f02h ; restore the original call
- setvideobios_worked:
- jmp setvideoreturn ; Return.
-
- setvideoerror: ; oops. No match found.
- mov goodmode,0 ; note that the video mode is bad
- mov ax,3 ; switch to text mode
- jmp setvideobios_doit
-
- setvideoauto:
- mov si, video_entries ; look for the correct resolution
- sub si,8 ; get a running start
- setvideoloop:
- add si,10 ; get next entry
- mov ax,cs:0[si] ; check X-res
- cmp ax,0 ; anything there?
- je setvideoerror ; nope. No match
- cmp ax,sxdots
- jne setvideoloop
- mov ax,cs:2[si] ; check Y-res
- cmp ax,sydots
- jne setvideoloop
- mov ax,cs:4[si] ; check Colors
- cmp ax,colors
- jne setvideoloop
- mov ax,cs:6[si] ; got one! Load AX
- mov bx,cs:8[si] ; Load BX
-
- cmp ax,0ffffh ; XGA special?
- jne notxgamode
- mov al,orvideo
- mov xga_clearvideo,al
- cmp al,0 ; clearing the video?
- jne xgask1 ; yup
- mov ax,03h ; switch to text mode (briefly)
- int 10h
- xgask1:
- push bx
- call far ptr xga_mode
- pop bx
- cmp ax,0
- je setvideoloop
- jmp setvideoreturn
- notxgamode:
-
- cmp bx,0ffh ; ATI 1024x768x16 special?
- jne notatimode
- mov dotmode,20 ; Convert to ATI specs
- mov al,65h
- mov bx,0
- jmp setvideobios
- notatimode:
- cmp bx,0feh ; Tseng 640x400x256 special?
- jne nottsengmode
- mov ax,0 ; convert to Tseng specs
- mov bx,0
- mov cx,0
- mov dx,10
- mov dotmode,4
- jmp setvideoregs
- nottsengmode:
- cmp bx,0fdh ; Compaq 640x480x256 special?
- jne notcompaqmode
- mov vxdots,1024 ; (compaq uses 1024-byte scanlines)
- mov bx,offset swapnormread ; use the slow swap routine
- mov word ptr swapsetup,bx ; ...
- mov bx,0
- jmp setvideobios
- notcompaqmode:
- cmp ax,4f02h ; VESA mode?
- jne notvesamode
- mov dotmode,28 ; convert to VESA specs
- notvesamode:
- jmp setvideobios
-
- setvideoregs: ; assume genuine VGA and program regs
- mov si, dotmode ; compare the dotmode against
- mov di,video_type ; the video type
- add si,si ; (convert to a word pointer)
- cmp cs:video_requirements[si],di
- jbe setvideoregs_doit ; good value. Do it.
- jmp setvideoerror ; bad value. Error.
- setvideoregs_doit:
- mov si,dx ; get the video table offset
- shl si,1 ; ...
- mov si,word ptr tweaks[si] ; ...
-
- mov tweaktype, dx ; save tweaktype
- cmp dx,8 ; 360x480 tweak256mode?
- je isatweaktype ; yup
- cmp dx,9 ; 320x400 tweak256mode?
- je isatweaktype ; yup
- cmp dx,18 ; 320x480 tweak256mode?
- je isatweaktype ; yup
- cmp dx,19 ; 320x240 tweak256mode?
- je isatweaktype ; yup
- cmp dx,10 ; Tseng tweak?
- je tsengtweak ; yup
- ;Patch - Michael D. Burkey (5/22/90)
- cmp dx,14 ; ATI Mode Support
- je ATItweak
- cmp dx,15
- je ATItweak
- cmp dx,16
- je ATItweak
- cmp dx,17
- je ATItweak2 ; ATI 832x616 mode
- cmp dx,11 ; tweak256mode? (11 & up)
- jae isatweaktype ; yup
- ;End Patch
- jmp not256 ; nope none of the above
- tsengtweak:
- mov ax,46 ; start with S-VGA mode 2eh
- call maybeor ; maybe don't clear the video memory
- int 10h ; let the bios clear the video memory
- mov dx,3c2h ; misc output
- mov al,063h ; dot clock
- out dx,al ; select it
- mov dx,3c4h ; sequencer again
- mov ax,0300h ; restart sequencer
- out dx,ax ; running again
- jmp is256;
- ATItweak:
- mov ax,62h
- ;; pb, why no maybeor call here?
- int 10h
- mov dx,3c2h
- mov al,0e3h
- out dx,al
- mov dx,3c4h
- mov ax,0300h
- out dx,ax
- jmp is256
-
- ATItweak2:
- mov ax,63h
- ;; pb, why no maybeor call here?
- int 10h
- mov dx,3c4h
- mov ax,0300h
- out dx,ax
- jmp is256
-
- isatweaktype:
- mov tweakflag,1
- mov ax,0013h ; invoke video mode 13h
- call maybeor ; maybe or AL or (for Video-7s) BL
- int 10h ; do it
-
- mov dx,3c4h ; alter sequencer registers
- mov ax,0604h ; disable chain 4
- out dx,ax
-
- cmp orvideo,0 ; are we supposed to clear RAM?
- jne noclear256 ; (nope)
-
- mov dx,03c4h ; alter sequencer registers
- mov ax,0f02h ; enable writes to all planes
- OUT_WORD
-
- push es ; save ES for a tad
- mov ax,VGA_SEGMENT ; clear out all 256K of
- mov es,ax ; video memory
- sub di,di ; (64K at a time, but with
- mov ax,di ; all planes enabled)
- mov cx,8000h ;# of words in 64K
- cld
- rep stosw ;clear all of display memory
- pop es ; restore ES
-
- noclear256:
- mov dx,3c4h ; alter sequencer registers
- mov ax,0604h ; disable chain 4
- out dx,ax
-
- jmp short is256 ; forget the ROM characters
-
- not256:
-
- mov ax,0012h ; invoke video mode 12h
- call maybeor ; maybe or AL or (for Video-7s) BL
- int 10h ; do it.
-
- is256: push es ; save ES for a tad
- mov ax,40h ; Video BIOS DATA area
- mov es,ax ; ...
-
- mov dx,word ptr es:[63h] ; say, where's the 6845?
- add dx,6 ; locate the status register
- vrdly1: in al,dx ; loop until vertical retrace is off
- test al,8 ; ...
- jnz vrdly1 ; ...
- vrdly2: in al,dx ; now loop until it's on!
- test al,8 ; ...
- jz vrdly2 ; ...
-
- cli ; turn off all interrupts
- mov dx,tweaktype
- cmp dx,9 ; 320x400 mode?
- je not256mode ; yup - skip this stuff
- cmp dx,10 ; Tseng tweak mode?
- je not256mode ; yup - skip this stuff
- ;patch #2 (M. Burkey 5/22/90)
- cmp dx,17 ; for 832x616 ATI Mode
- je not256mode
- ;patch end
- mov cl,0E7h ; value for misc output reg
- cmp dx,18 ; 320x480 mode?
- je setmisc320 ; nope, use above value
- cmp dx,19 ; 320x240 mode?
- jne setmiscoreg ; nope, use above value
- setmisc320:
- mov cl,0E3h ; value for misc output reg
- setmiscoreg:
- mov dx,03c4h ; Sequencer Synchronous reset
- mov ax,0100h ; set sequencer reset
- out dx,ax
- mov dx,03c2h ; Update Misc Output Reg
- mov al,cl
- out dx,al
- mov dx,03c4h ; Sequencer Synchronous reset
- mov ax,0300h ; clear sequencer reset
- out dx,ax
- not256mode:
- mov dx,word ptr es:[63h] ; say, where's the 6845?
- add si,2 ; point SI to the CRTC registers table
- mov al,11h ; deprotect registers 0-7
- mov ah,byte ptr [si+11h]
- and ah,7fh
- out dx,ax
-
- mov cx,18h ; update this many registers
- mov bx,00 ; starting with this one.
- crtcloop:
- mov al,bl ; update this register
- mov ah,byte ptr [bx+si] ; to this
- out dx,ax
- inc bx ; ready for the next register
- loop crtcloop ; (if there is a next register)
- sti ; restore interrupts
-
- pop es ; restore ES
-
- setvideoreturn:
- mov curbk,0ffffh ; stuff impossible value into cur-bank
- mov orvideo,0 ; reset the video to clobber memory
- pop bp
- ret
- setvideo endp
-
- maybeor proc near ; or AL or BL for mon-destr switch
- cmp ah,4fh ; VESA special mode?
- je maybeor2 ; yup. Do this one different
- cmp ah,6fh ; video-7 special mode?
- je maybeor1 ; yup. do this one different
- or al,orvideo ; normal non-destructive switch
- jmp short maybeor99 ; we done.
- maybeor1:
- or bl,orvideo ; video-7 switch
- jmp short maybeor99
- maybeor2:
- or bh,orvideo ; VESA switch
- maybeor99:
- ret ; we done.
- maybeor endp
-
-
- ; ********* Functions setfortext() and setforgraphics() ************
-
- ; setfortext() resets the video for text mode and saves graphics data
- ; setforgraphics() restores the graphics mode and data
- ; setclear() clears the screen after setfortext()
-
- monocolors db 0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-
- setfortext proc uses es si di
- push bp ; save it around the int 10s
- cmp dotmode, 12 ;check for 8514
- jne tnot8514
- cmp f85flag, 0 ;check 8514 active flag
- je go_dosettext
- cmp ai_8514, 0 ;using registers? JCO 4/11/92
- jne not85reg
- call close8514hw ;close adapter if not, with registers
- jmp done85close
- not85reg:
- call close8514 ;close adapter if not, with afi
- done85close:
- mov f85flag, 0
- go_dosettext:
- jmp dosettext ; safe to go to mode 3
- tnot8514:
- cmp dotmode,9 ; Targa?
- je go_dosettext ; yup, leave it open & go to text
-
- cmp xga_isinmode,0 ; XGA in graphics mode?
- je noxga ; nope
- mov ax,xga_isinmode ; remember if we were in XGA mode
- mov xga_clearvideo,80h ; don't clear the video!
- mov ax,0 ; switch to VGA (graphics) mode
- push ax
- call far ptr xga_mode
- pop ax ; proceed on like nothing happened
- mov xga_clearvideo,0 ; reset the clear-video flag
- noxga:
-
- cmp dotmode,14 ; (klooge for Tandy 640x200x16)
- je setfortextcga
- cmp videoax,0 ; check for CGA modes
- je go_setfortextnocga ; not this one
- cmp dotmode,10 ; Hercules?
- je setfortextcga ; yup
- cmp videoax,7 ; <= vid mode 7?
- jbe setfortextcga ; yup
- go_setfortextnocga:
- jmp setfortextnocga ; not this one
- setfortextcga: ; from mode ensures we can go to mode 3, so do it
- mov ax,extraseg ; set ES == Extra Segment
- add ax,1000h ; (plus 64K)
- mov es,ax ; ...
- mov di,4000h ; save the video data here
- mov ax,0b800h ; video data starts here <XXX>
- mov si,0 ; ...
- cmp videoax,3 ; from mode 3?
- jne setfortextcga2 ; nope
- cmp mode7text,0 ; egamono/hgc?
- je setfortextcga2 ; nope
- mov ax,0b000h ; video data starts here
- setfortextcga2:
- mov cx,2000h ; save this many words
- cmp dotmode,10 ; Hercules?
- jne setfortextcganoherc ; nope
- mov di,0 ; (save 32K)
- mov ax,0b000h ; (from here)
- mov cx,4000h ; (save this many words)
- setfortextcganoherc:
- cmp dotmode,14 ; check for Tandy 1000 specific modes
- jne setfortextnotandy ; ..
- mov ax,tandyseg ; video data starts here
- mov si,tandyofs ; save video data here
- mov di,0 ; save the video data here
- mov cx,4000h ; save this many words
- setfortextnotandy:
- push ds ; save DS for a tad
- mov ds,ax ; reset DS
- cld ; clear the direction flag
- rep movsw ; save them.
- pop ds ; restore DS
- cmp dotmode,10 ; Hercules?
- jne dosettext ; nope
- cmp HGCflag, 0 ; check HGC active flag
- je dosettext
- call hgcend ; close adapter
- mov HGCflag, 0
- dosettext:
- mov ax,3 ; set up the text call
- mov bx,0 ; ...
- mov cx,0 ; ...
- mov dx,0 ; ...
- call setvideo ; set the video
- jmp setfortextreturn
- setfortextnocga:
- mov bios_vidsave,0 ; default, not using bios for state save
- mov ax,textsafe2 ; videotable override?
- cmp ax,0 ; ...
- jne setfortextsafe ; yup
- mov ax,textsafe ; nope, use general setting
- setfortextsafe:
- cmp ax,2 ; textsafe=no?
- jne setforcolortext ; nope
- jmp setfordummytext ; yup, use 640x200x2
- setforcolortext:
- ; must be ega, mcga, or vga, else we'd have set textsafe=no in runup
- cmp ax,4 ; textsafe=save?
- jne setforcolortext2 ; nope
- mov ax,0 ; disable the video (I think)
- call disablevideo ; ...
- call far ptr savegraphics ; C rtn which uses swapsetup
- call swapvga_reset ; some cleanup for swapvga case
- mov orvideo,80h ; preserve memory, just for speed
- cmp videoax,0fh ; ega 640x350x2?
- jne dosettext ; nope, go call bios for mode 3
- mov ax,83h ; I know this is silly! have to set
- int 10h ; mode twice when coming from mode 0fh
- jmp dosettext ; on some machines to get right colors
- setforcolortext2:
- cmp ax,3 ; textsafe=bios?
- jne setforcolortext3 ; nope
- cmp video_type,5 ; vga?
- jl setforcolortext3 ; nope
- mov ax,1c00h ; check size of reqd save area
- mov cx,3 ; for hardware + bios states
- int 10h ; ask...
- cmp al,1ch ; function recognized?
- jne setforcolortext3 ; nope
- cmp bx,4 ; buffer big enough? (3 seems usual)
- ja setforcolortext3 ; nope
- mov bios_vidsave,1 ; using bios to save vid state
- mov ax,cs ; ptr to save buffer
- mov es,ax ; ...
- mov bx,offset bios_savebuf ; ...
- mov ax,1c01h ; save state
- mov cx,3 ; hardware + bios
- int 10h ; ...
- setforcolortext3:
- push ds ; save ds
- mov ax,extraseg ; set ES == Extra Segment
- add ax,1000h ; (plus 64K)
- mov es,ax ; ...
- cld
- mov ax,0a000h ; video mem address
- cmp video_type,4 ; mcga?
- jne setfortextegavga ; nope
- mov ds,ax ; set ds to video mem
- xor di,di ; from vid offset 0
- xor si,si ; to save offset 0
- mov cx,1000h ; save 4k words
- rep movsw ; font info
- mov si,8000h ; from vid offset 8000h
- mov cx,0800h ; save 2k words
- rep movsw ; characters and attributes
- pop ds ; restore ds
- mov orvideo,80h ; set the video to preserve memory
- jmp dosettext ; (else more than we saved gets cleared)
- setfortextegavga:
- sub ax,ax ; set bank just in case
- call far ptr newbank
- mov ax,8eh ; switch to a mode with known mapping
- cmp videoax,0fh ; coming from ega 640x350x2?
- jne sftknownmode ; nope
- mov ax,8fh ; yup, stay in it but do the set mode
- sftknownmode:
- int 10h ; set the safe mode
- mov ax,0 ; disable the video (I think)
- call disablevideo ; ...
- mov ax,0a000h ; video mem address
- mov ds,ax ; set ds to video mem
- xor di,di ; to offset 0 in save area
- ;; mov cx,0 ; set to plane 0
- ;; call select_vga_plane ; ...
- ;; mov cx,0800h ; save 2k words
- ;; xor si,si ; from offset 0 in vid mem
- ;; rep movsw ; save plane 0 2k bytes (char values)
- mov cx,2 ; set to plane 2
- call select_vga_plane ; ...
- mov cx,1000h ; save 4k words
- xor si,si ; from offset 0 in vid mem
- rep movsw ; save plane 2 8k bytes (font)
- ;; mov cx,1 ; set to plane 1
- ;; call select_vga_plane ; ...
- ;; mov cx,0800h ; save 2k words
- ;; xor si,si ; from offset 0 in vid mem
- ;; rep movsw ; save plane 1 2k bytes (attributes)
- ;; push ds ; now zap attributes to zero to
- ;; pop es ; avoid flicker in the next stages
- ;; xor di,di ; ...
- ;; xor ax,ax ; ...
- ;; mov cx,0400h ; ...
- ;; rep stosw ; ...
- pop ds ; restore ds
- mov orvideo,80h ; set the video to preserve memory
- mov ax,3 ; set up the text call
- mov bx,0 ; ...
- mov cx,0 ; ...
- mov dx,0 ; ...
- call setvideo ; set the video
- push ds ; save ds
- mov ax,extraseg ; set ES == Extra Segment
- add ax,1000h ; (plus 64K)
- mov es,ax ; ...
- mov ax,textaddr
- mov ds,ax
- cld
- xor si,si
- mov di,2000h ; past the saved font info
- mov cx,0800h ; 2k words (text & attrs)
- rep movsw ; save them
- pop ds
- jmp setfortextreturn
- setfordummytext: ; use 640x200x2 simulated text mode
- mov ax,0 ; disable the video (I think)
- call disablevideo ; ...
- mov orvideo,80h ; set the video to preserve memory
- mov ax,6 ; set up the text call
- mov bx,0 ; ...
- mov cx,0 ; ...
- mov dx,0 ; ...
- call setvideo ; set the video
- mov ax,0 ; disable the video (I think)
- call disablevideo ; ...
- cld ; clear the direction flag
- mov ax,extraseg ; set ES == Extra Segment
- add ax,1000h ; (plus 64K)
- mov es,ax ; ...
- mov di,4000h ; save the video data here
- mov ax,0b800h ; video data starts here
- push ds ; save DS for a tad
- mov ds,ax ; reset DS
- mov si,0 ; ...
- mov cx,4000 ; save this many words
- rep movsw ; save them.
- mov si,2000h ; ...
- mov cx,4000 ; save this many words
- rep movsw ; save them.
- pop ds ; restore DS
- mov ax,0b800h ; clear the video buffer
- mov es,ax ; ...
- mov di,0 ; ...
- mov ax,0 ; to blanks
- mov cx,4000 ; this many blanks
- rep stosw ; do it.
- mov di,2000h ; ...
- mov cx,4000 ; this many blanks
- rep stosw ; do it.
- mov ax,20h ; enable the video (I think)
- call disablevideo ; ...
- mov bx,23 ; set mode 6 fgrd to grey
- mov cx,2a2ah ; register 23, rgb white
- mov dh,2ah ; ...
- mov ax,1010h ; int 10 10-10 affects mcga,vga
- int 10h ; ...
- mov ax,cs ; do it again, another way
- mov es,ax ; ...
- mov dx,offset monocolors ; ...
- mov ax,1002h ; int 10 10-02 handles pcjr,ega,vga
- int 10h ; ...
-
- setfortextreturn:
- call far ptr setclear ; clear and home the cursor
- pop bp
- ret
- setfortext endp
-
- setforgraphics proc uses es si di
- push bp ; save it around the int 10s
- cmp dotmode, 12 ;check for 8514
- jne gnot8514
- cmp f85flag, 0
- jne go_graphicsreturn
- cmp ai_8514, 0 ;check afi flag JCO 4/11/92
- jne reopenafi
- call reopen8514hw ;use registers
- jmp reopen85done
- reopenafi:
- call reopen8514 ;use afi
- reopen85done:
- mov f85flag, 1
- go_graphicsreturn:
- jmp setforgraphicsreturn
- gnot8514:
- cmp dotmode,9 ; Targa?
- jne gnottarga ; nope
- call far ptr ReopenTGA
- jmp short go_graphicsreturn
- gnottarga:
-
- cmp dotmode,14 ; check for Tandy 1000 specific modes
- je setforgraphicscga ; yup
- cmp videoax,0 ; check for CGA modes
- je setforgraphicsnocga_x ; not this one
- cmp dotmode,10 ; Hercules?
- je setforgraphicscga ; yup
- cmp videoax,7 ; vid mode <=7?
- jbe setforgraphicscga ; CGA mode
- setforgraphicsnocga_x:
- jmp setforgraphicsnocga
- setforgraphicscga:
- cmp dotmode,10 ; Hercules?
- jne tnotHGC2 ; (nope. dull-normal stuff)
- call hgcstart ; Initialize the HGC card
- mov HGCflag,1 ; flag "HGC-end" needed.
- jmp short twasHGC2 ; bypass the normal setvideo call
- tnotHGC2:
- cmp dotmode,14 ; Tandy?
- jne tnottandy1 ; nope
- mov orvideo,80h ; set the video to preserve memory
- tnottandy1:
- mov ax,videoax ; set up the video call
- mov bx,videobx ; ...
- mov cx,videocx ; ...
- mov dx,videodx ; ...
- call setvideo ; do it.
- twasHGC2:
- mov bx,extraseg ; restore is from Extraseg
- add bx,1000h ; (plus 64K)
- mov si,4000h ; video data is saved here
- mov ax,0b800h ; restore the video area
- mov di,0 ; ...
- cmp videoax,3 ; from mode 3?
- jne setforgraphicscga2 ; nope
- cmp mode7text,0 ; egamono/hgc?
- je setforgraphicscga2 ; nope
- mov ax,0b000h ; video data starts here
- setforgraphicscga2:
- mov cx,2000h ; restore this many words
- cmp dotmode,10 ; Hercules?
- jne setforgraphicscganoherc ; nope
- mov si,0 ; (restore 32K)
- mov ax,0b000h ; (to here)
- mov cx,4000h ; (restore this many words)
- setforgraphicscganoherc:
- cmp dotmode,14 ; check for Tandy 1000 specific modes
- jne tnottandy2 ; ..
- mov ax,tandyseg ; video data starts here
- mov di,tandyofs ; save video data here
- mov si,0 ; video data is saved here
- mov cx,4000h ; save this many words
- tnottandy2:
- push ds ; save DX for a tad
- mov es,ax ; load the dest seg into ES
- mov ds,bx ; restore it from the source seg
- cld ; clear the direction flag
- rep movsw ; restore them.
- pop ds ; restore DS
- jmp setforgraphicsreturn
- setforgraphicsnocga:
- mov ax,0 ; disable the video (I think)
- call disablevideo ; ...
- cld ; clear the direction flag
- mov ax,textsafe2 ; videotable override?
- cmp ax,0 ; ...
- jne setforgraphicssafe ; yup
- mov ax,textsafe ; nope, use general setting
- setforgraphicssafe:
- cmp ax,2 ; textsafe=no?
- jne setforgraphicsnocga2
- jmp setfordummygraphics ; yup, 640x200x2
- setforgraphicsnocga2:
- ; must be ega, mcga, or vga, else we'd have set textsafe=no in runup
- cmp ax,4 ; textsafe=save?
- jne setforgraphicsnocga3 ; nope
- ;; pb, always clear video here:
- ;; need if for ega/vga with < 16 colors to clear unused planes
- ;; and, some bios's don't implement ah or'd with 80h?!?, dodge their bugs
- ;; cmp dotmode,2 ; ega/vga, <=16 colors?
- ;; jne setfgncfast ; nope
- ;; cmp colors,16 ; < 16 colors?
- ;; jae setfgncfast ; nope
- ;; jmp short setfgncsetvid ; special, need unused planes clear
- ;;setfgncfast:
- ;; mov orvideo,80h ; preserve memory (just to be fast)
- ;;setfgncsetvid:
- mov orvideo,00h ; JRS ; preserve memory (just to be fast)
- mov ax,videoax ; set up the video call
- mov bx,videobx ; ...
- mov cx,videocx ; ...
- mov dx,videodx ; ...
- call setvideo ; do it.
- sub ax,ax ; disable the video (I think)
- call disablevideo ; ...
- call far ptr restoregraphics ; C rtn which uses swapsetup
- call swapvga_reset ; some cleanup for swapvga case
- mov ax,20h ; enable the video (I think)
- call disablevideo ; ...
- jmp setforgraphicsreturn
- setforgraphicsnocga3:
- push ds ; save ds
- mov ax,0a000h ; set es to video mem
- mov es,ax ; ...
- cmp video_type,4 ; mcga?
- jne setforgraphicsegavga ; nope
- mov ax,extraseg ; set DS == Extra Segment
- add ax,1000h ; (plus 64K)
- mov ds,ax ; ...
- xor si,si ; from save offset 0
- xor di,di ; to vid offset 0
- mov cx,1000h ; restore 4k words
- rep movsw ; font info
- mov di,8000h ; to vid offset 8000h
- mov cx,0800h ; restore 2k words
- rep movsw ; characters and attributes
- jmp short setforgraphicsdoit
- setforgraphicsegavga:
- ;; mov cx,0 ; set to plane 0
- ;; call select_vga_plane ; ...
- ;; mov ax,extraseg ; set DS == Extra Segment
- ;; add ax,1000h ; (plus 64K)
- ;; mov ds,ax ; ...
- ;; mov cx,0800h ; restore 2k words
- ;; xor si,si ; from offset 0 in save area
- ;; xor di,di ; to offset 0 in vid mem
- ;; rep movsw ; restore plane 0 2k bytes (char values)
- mov ax,textaddr
- mov es,ax
- mov ax,extraseg ; set DS == Extra Segment
- add ax,1000h ; (plus 64K)
- mov ds,ax ; ...
- cld
- xor di,di
- mov si,2000h ; past the saved font info
- mov cx,0800h ; 2k words (text & attrs)
- rep movsw ; restore them
- pop ds
- mov ax,8eh ; switch to a mode with known mapping
- cmp videoax,0fh ; returning to ega 640x350x2?
- jne sfgnotega ; nope
- mov ax,8fh ; yup, go directly to it
- sfgnotega:
- int 10h ; set the safe mode
- mov ax,0 ; disable the video (I think)
- call disablevideo ; ...
- mov cx,2 ; set to plane 2
- call select_vga_plane ; ...
- push ds
- mov ax,0a000h ; set es to video mem
- mov es,ax ; ...
- mov ax,extraseg ; set DS == Extra Segment
- add ax,1000h ; (plus 64K)
- mov ds,ax ; ...
- mov cx,1000h ; restore 4k words
- xor di,di ; to offset 0 in vid mem
- xor si,si ; from offset 0 in extraseg
- rep movsw ; restore plane 2 8k bytes (font)
- ;; mov cx,1 ; set to plane 1
- ;; call select_vga_plane ; ...
- ;; mov cx,0800h ; restore 2k words
- ;; xor di,di ; to offset 0 in vid mem
- ;; rep movsw ; restore plane 1 2k bytes (attributes)
- jmp short setforgraphicsdoit
- setfordummygraphics:
- push ds ; save ds
- mov ax,0b800h ; restore the video area
- mov es,ax ; ES == video addr
- mov di,0 ; ...
- mov ax,extraseg ; ...
- add ax,1000h ; (plus 64K)
- mov ds,ax ; ...
- mov si,4000h ; video data is saved here
- mov cx,4000 ; restore this many words
- rep movsw ; restore them.
- mov di,2000h
- mov cx,4000 ; restore this many words
- rep movsw ; restore them.
- setforgraphicsdoit:
- pop ds ; restore DS
- cmp bios_vidsave,0 ; did setfortext use bios state save?
- je setforgraphicssetvid ; nope
- mov ax,cs ; ptr to save buffer
- mov es,ax ; ...
- mov bx,offset bios_savebuf ; ...
- mov ax,1c02h ; restore state
- mov cx,3 ; hardware + bios
- int 10h ; ...
- jmp short setforgraphicsreturn
- setforgraphicssetvid:
- mov orvideo,80h ; set the video to preserve memory
- mov ax,videoax ; set up the video call
- mov bx,videobx ; ...
- mov cx,videocx ; ...
- mov dx,videodx ; ...
- call setvideo ; do it.
- mov ax,20h ; enable the video (I think)
- call disablevideo ; ...
- setforgraphicsreturn:
- mov curbk,0ffffh ; stuff impossible value into cur-bank
- mov ax,1 ; set up call to spindac(0,1)
- push ax ; ...
- mov ax,0 ; ...
- push ax ; ...
- call far ptr spindac ; do it.
- pop ax ; restore the registers
- pop ax ; ...
- pop bp
- ret
- setforgraphics endp
-
- ; swapxxx routines: indirect call via swapsetup, used by savegraphics
- ; and restoregraphics
-
- swap256 proc uses es si di ; simple linear banks version
- mov ax,word ptr swapoffset+2; high word of offset is bank
- call far ptr newbank ; map in the bank
- mov ax,0a000h ; high word of vid addr
- mov word ptr swapvidbuf+2,ax; store it
- mov ax,word ptr swapoffset ; offset in bank
- mov word ptr swapvidbuf,ax ; store as low word of vid addr
- neg ax ; 65536-offset
- jz swap256ret ; offset 0
- cmp ax,swaplength ; rest of bank smaller than req length?
- jae swap256ret ; nope
- mov swaplength,ax ; yup, reduce length to what's available
- swap256ret:
- ret
- swap256 endp
-
- swapvga proc uses es si di ; 4 (or less) planes version
- xor si,si ; this will be plane number
- mov ax,word ptr swaptotlen ; dx,ax = total length
- mov dx,word ptr swaptotlen+2
- mov cx,word ptr swapoffset ; bx,cx = offset
- mov bx,word ptr swapoffset+2
- cmp colors,4 ; 4 or 2 color mode?
- jle swapvga_2 ; yup, no plane 2/3
- shr dx,1 ; 1/2 of total
- rcr ax,1 ; ...
- cmp dx,bx ; 1/2 total <= offset?
- jb swapvga_1 ; yup
- ja swapvga_2 ; nope
- cmp ax,cx ; ...
- ja swapvga_2 ; nope
- swapvga_1:
- mov si,2 ; plane 2
- sub cx,ax ; subtract 1/2 total from offset
- sbb bx,dx ; ...
- swapvga_2:
- cmp colors,2 ; 2 color mode?
- jle swapvga_4 ; yup, just plane 0
- shr dx,1 ; 1/4 of total (or 1/2 if 4 colors)
- rcr ax,1 ; ...
- cmp dx,bx ; 1/4 total <= remaining offset?
- jb swapvga_3 ; yup
- ja swapvga_4 ; nope
- cmp ax,cx ; ...
- ja swapvga_4 ; nope
- swapvga_3:
- inc si ; plane 1 or 3
- sub cx,ax ; subtract 1/4 total from offset
- sbb bx,dx ; ...
- swapvga_4:
- mov di,0 ; bank size (65536 actually)
- cmp bx,dx ; in last bank?
- jne swapvga_5 ; nope
- mov di,ax ; yup, note its size
- swapvga_5:
- mov ax,0a000h ; high word of vid addr
- mov word ptr swapvidbuf+2,ax; store it
- mov word ptr swapvidbuf,cx ; low word of vid addr (offset in bank)
- sub di,cx ; bank size - offset
- je swapvga_6 ; 0 implies bank = 65536
- cmp di,swaplength ; rest of bank smaller than req length?
- jae swapvga_6 ; nope
- mov swaplength,di ; yup, reduce length to what's available
- swapvga_6:
- push si ; remember plane
- mov ax,bx ; top word of offset is bank
- call far ptr newbank ; map in the bank
- mov dx,03ceh ; graphics controller address
- pop cx ; plane
- mov ah,cl ; ...
- mov al,04h ; set up controller address register
- out dx,ax ; map the plane into memory for reads
- mov ax,0001h ; set/reset enable - all bits processor
- out dx,ax ; ...
- mov ax,0ff08h ; bit mask - all bits processor
- out dx,ax ; ...
- mov dx,03c4h ; sequencer address
- mov ah,1 ; 1 << plane number
- shl ah,cl ; ...
- mov al,02h ; sequencer plane write enable register
- out dx,ax ; enable just this plane for writing
- ret
- swapvga endp
-
- swapvga_reset proc near
- cmp word ptr swapsetup,offset swapvga; swapvga being used?
- jne swapvga_reset_ret
- mov ax,0f02h ; write enable register, all planes
- mov dx,03c4h ; sequencer address
- out dx,ax
- swapvga_reset_ret:
- ret
- swapvga_reset endp
-
- swapnormread proc uses es si di ; the SLOW version
- local xdot:word,ydot:word,bytesleft:word,bits:word,bitctr:word
- local savebyte:byte
- mov ax,swaplength ; bytes to save
- mov bytesleft,ax ; ...
- mov bits,8 ; bits/pixel
- mov bx,word ptr swapoffset ; pixel offset to save
- mov cx,word ptr swapoffset+2
- mov ax,colors ; colors
- swapnorm_bits:
- cmp ax,256 ; accounted for 8 bits yet?
- jae swapnorm_gotbits ; yup
- shr bits,1 ; nope, halve the bits/pixel
- shl bx,1 ; double the pixel offset
- rcl cx,1 ; ...
- mul ax ; square colors accounted for
- jmp short swapnorm_bits ; check if enough yet
- swapnorm_gotbits:
- mov ax,bx ; pixel offset now in dx:ax
- mov dx,cx ; ...
- div sxdots ; translate pixel offset to row/col
- mov ydot,ax ; ...
- mov xdot,dx ; ...
- mov ax,extraseg ; Extra Segment
- add ax,1000h ; plus 64K
- mov word ptr swapvidbuf+2,ax; temp buffer to return to caller
- mov word ptr swapvidbuf,0 ; ...
- mov word ptr tmpbufptr+2,ax ; running ptr for building buffer
- mov word ptr tmpbufptr,0 ; ...
- mov bitctr,0
- swapnorm_loop:
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; for dotread
- mov cx,xdot ; load up the registers
- mov dx,ydot ; for the video routine
- call dotread ; read the dot via the approved method
- mov cx,bits ; bits per pixel
- cmp cx,8 ; 1 byte per pixel?
- je swapnorm_store ; yup, go store a byte
- add bitctr,cx ; nope, add how many we're storing
- mov bl,savebyte ; load the byte being built
- swapnorm_shift:
- shr al,1 ; shift pixel into byte
- rcr bl,1 ; ...
- loop swapnorm_shift ; for number of bits/pixel
- mov savebyte,bl ; save byte we're building
- cmp bitctr,8 ; filled a byte yet?
- jb swapnorm_nxt ; nope
- mov al,bl ; yup, set up to store
- mov bitctr,0 ; clear counter for next time
- swapnorm_store:
- les di,tmpbufptr ; buffer pointer
- stosb ; store byte
- dec bytesleft ; finished?
- jz swapnorm_ret ; yup
- mov word ptr tmpbufptr,di ; store incremented buffer pointer
- swapnorm_nxt:
- inc xdot ; for next dotread call
- mov ax,xdot ; past row length?
- cmp ax,sxdots ; ...
- jb swapnorm_loop ; nope, go for next pixel
- inc ydot ; yup, increment row
- mov xdot,0 ; and reset column
- jmp short swapnorm_loop ; go for next pixel
- swapnorm_ret:
- ret
- swapnormread endp
-
- swapnormwrite proc uses es si di ; the SLOW way
- local xdot:word,ydot:word,bytesleft:word,bits:word,bitctr:word
- local savebyte:byte
- mov ax,swaplength ; bytes to restore
- inc ax ; +1
- mov bytesleft,ax ; save it
- mov bits,8 ; bits/pixel
- mov bx,word ptr swapoffset ; pixel offset to restore
- mov cx,word ptr swapoffset+2; ...
- mov ax,colors ; colors
- swapnormw_bits:
- cmp ax,256 ; accounted for 8 bits yet?
- jae swapnormw_gotbits ; yup
- shr bits,1 ; nope, halve the bits/pixel
- shl bx,1 ; double the pixel offset
- rcl cx,1 ; ...
- mul ax ; square colors accounted for
- jmp short swapnormw_bits ; check if enough yet
- swapnormw_gotbits:
- mov ax,bx ; pixel offset now in dx:ax
- mov dx,cx ; ...
- div sxdots ; translate pixel offset to row/col
- mov ydot,ax ; ...
- mov xdot,dx ; ...
- mov dx,word ptr swapvidbuf+2; temp buffer from caller
- mov ax,word ptr swapvidbuf ; ...
- mov word ptr tmpbufptr+2,dx ; running ptr in buffer
- mov word ptr tmpbufptr,ax ; ...
- mov bitctr,0
- swapnormw_loop:
- mov cx,bits ; bits per pixel
- sub bitctr,cx ; subtract a pixel from counter
- jg swapnormw_extract ; got some left in savebyte
- dec bytesleft ; all done?
- jz swapnormw_ret ; yup
- les si,tmpbufptr ; buffer pointer
- mov dl,es:[si] ; next byte
- inc word ptr tmpbufptr ; incr buffer pointer for next time
- mov bitctr,8 ; reset unused bit count
- cmp cx,8 ; 1 byte/pixel?
- je swapnormw_store ; yup, go the fast way
- mov bl,dl ; byte to extract from
- jmp short swapnormw_extract2
- swapnormw_extract:
- mov bl,savebyte ; byte with bits left to use
- mov dl,bl ; current pixel in bottom n bits
- swapnormw_extract2:
- shr bl,1 ; for next time
- loop swapnormw_extract2 ; for bits per pixel
- mov savebyte,bl ; save remaining bits
- swapnormw_store:
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; for dotread
- mov al,dl ; color to write
- and ax,andcolor ; ...
- mov cx,xdot ; load up the registers
- mov dx,ydot ; for the video routine
- call dotwrite ; write the dot via the approved method
- inc xdot ; for next dotread call
- mov ax,xdot ; past row length?
- cmp ax,sxdots ; ...
- jb swapnormw_loop ; nope, go for next pixel
- inc ydot ; yup, increment row
- mov xdot,0 ; and reset column
- jmp short swapnormw_loop ; go for next pixel
- swapnormw_ret:
- ret
- swapnormwrite endp
-
- ; far move routine for savegraphics/restoregraphics
-
- movewords proc uses es di si, len:word, fromptr:dword, toptr:dword
- push ds ; save DS
- mov cx,len ; words to move
- les di,toptr ; destination buffer
- lds si,fromptr ; source buffer
- cld ; direction=forward
- rep movsw ; do it.
- pop ds ; restore DS
- ret ; we done.
- movewords endp
-
- ; clear text screen
-
- setclear proc uses es si di ; clear the screen after setfortext
- call far ptr home ; home the cursor
- mov ax,textaddr
- mov es,ax
- xor di,di
- cmp text_type,0 ; real text mode?
- jne setcbw ; nope
- mov ax,0720h ; blank with white attribute
- mov cx,2000 ; 80x25
- rep stosw ; clear it
- jmp short setcdone
- setcbw: xor ax,ax ; graphics text
- mov cx,4000 ; 640x200x2 / 8
- rep stosw ; clear it
- mov di,2000h ; second part
- mov cx,4000
- rep stosw ; clear it
- setcdone:
- xor ax,ax ; zero
- mov textrbase,ax ; clear this
- mov textcbase,ax ; and this
- ret ; we done.
- setclear endp
-
-
- disablevideo proc near ; wierd video trick to disable/enable
- push dx ; save some registers
- push ax ; ...
- mov dx,03bah ; set attribute comtroller flip-flop
- in al,dx ; regardless of video mode
- mov dx,03dah ; ...
- in al,dx ; ...
- mov dx,03c0h ; attribute controller address
- pop ax ; 00h = disable, 20h = enable
- out dx,al ; trust me.
- pop dx ; restore DX and we done.
- ret
- disablevideo endp
-
- ; ************** Function findfont(n) ******************************
-
- ; findfont(0) returns far pointer to 8x8 font table if it can
- ; find it, NULL otherwise;
- ; nonzero parameter reserved for future use
-
- findfont proc uses es si di, fontparm:word
- mov ax,01130h ; func 11, subfunc 30
- mov bh,03h ; 8x8 font, bottom 128 chars
- sub cx,cx ; so we can tell if anything happens
- int 10h ; ask bios
- sub ax,ax ; default return, NULL
- sub dx,dx ; ...
- or cx,cx ; did he set cx?
- jz findfontret ; nope, return with NULL
- mov dx,es ; yup, return far pointer
- mov ax,bp ; ...
- findfontret:
- ret ; note that "uses" gets bp reset here
- findfont endp
-
- ; **************** Function home() ********************************
-
- ; Home the cursor (called before printfs)
-
- home proc
- mov ax,0200h ; force the cursor
- mov bx,0 ; in page 0
- mov dx,0 ; to the home position
- mov textrow,dx ; update our local values
- mov textcol,dx ; ...
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret
- home endp
-
- ; **************** Function movecursor(row, col) **********************
-
- ; Move the cursor (called before printfs)
-
- movecursor proc row:word, col:word
- mov ax,row ; row specified?
- cmp ax,-1 ; ...
- je mccol ; nope, inherit it
- mov textrow,ax ; yup, store it
- mccol: mov ax,col ; col specified?
- cmp ax,-1 ; ...
- je mcdoit ; nope, inherit it
- mov textcol,ax ; yup, store it
- mcdoit: mov ax,0200h ; force the cursor
- mov bx,0 ; in page 0
- mov dh,byte ptr textrow ; move to this row
- add dh,byte ptr textrbase ; ...
- mov dl,byte ptr textcol ; move to this column
- add dl,byte ptr textcbase ; ...
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret
- movecursor endp
-
- ; **************** Function keycursor(row, col) **********************
-
- ; Subroutine to wait cx ticks, or till keystroke pending
-
- tickwait proc
- FRAME <es> ; std stack frame for TC++ overlays
- tickloop1:
- push cx ; save loop ctr
- sub ax,ax ; set ES to BIOS data area
- mov es,ax ; ...
- mov bx,es:046ch ; obtain the current timer value
- push bx
- call far ptr keypressed ; check if keystroke pending
- pop bx
- pop cx ; restore loop ctr
- cmp ax,0 ; keystroke?
- jne tickret ; yup, return
- tickloop2:
- cmp bx,es:046ch ; a new clock tick started yet?
- je tickloop2 ; nope
- loop tickloop1 ; wait another tick?
- xor ax,ax ; nope, exit no key, ticks done
- tickret:
- UNFRAME <es> ; pop stack frame
- ret
- tickwait endp
-
- ; Show cursor, wait for a key, disable cursor, return key
-
- keycursor proc uses es si di, row:word, col:word
- mov cursortyp,0607h ; default cursor
- mov ax,row ; row specified?
- cmp ax,-1 ; ...
- je ckcol ; nope, inherit it
- test ax,08000h ; top bit on?
- je ckrow ; nope
- and ax,07fffh ; yup, clear it
- mov cursortyp,0507h ; and use a bigger cursor
- ckrow: mov textrow,ax ; store row
- ckcol: mov ax,col ; col specified?
- cmp ax,-1 ; ...
- je ckmode ; nope, inherit it
- mov textcol,ax ; yup, store it
- ckmode: cmp text_type,1 ; are we in 640x200x2 mode?
- jne ck_text ; nope. do it the easy way
- ck_bwloop: ; 640x200x2 cursor loop
- mov cx,3 ; wait 3 ticks for keystroke
- call far ptr tickwait ; ...
- cmp ax,0 ; got a keystroke?
- je ckwait ; nope
- jmp ck_get ; yup, fetch it and return
- ckwait: mov ax,320 ; offset in vid mem of top row 1st byte:
- mov bx,textrow ; row
- add bx,textrbase ; ...
- mul bx ; row*320 + col
- add ax,textcol ; ...
- add ax,textcbase ; ...
- mov di,ax ; ...
- mov ax,0b800h ; set es to vid memory
- mov es,ax ; ...
- mov ah,byte ptr es:00f0h[di]; row 6 of character
- mov al,byte ptr es:20f0h[di]; row 7 of character
- push ax ; save them
- mov cx,8 ; count on bits in orig value
- xor bx,bx ; ...
- ckbits: shl al,1 ; ...
- adc bx,0 ; ...
- loop ckbits ; ...
- mov al,0 ; black cursor
- cmp bx,4 ; >= 4 on bits in orig value?
- jge ckbwgo ; yup, use black cursor
- not al ; nope, use white cursor
- ckbwgo: mov byte ptr es:20f0h[di],al; turn on cursor, row 7
- cmp cursortyp,0607h ; small cursor?
- je ckbwwt ; yup
- mov byte ptr es:00f0h[di],al; nope, turn on cursor row 6
- ckbwwt: mov cx,3 ; wait 3 ticks for keystroke
- call far ptr tickwait ; ...
- pop bx ; saved orig value
- mov byte ptr es:00f0h[di],bh; turn off cursor, row 6
- mov byte ptr es:20f0h[di],bl; turn off cursor, row 7
- cmp ax,0 ; got a keystroke?
- jne ck_get ; yup, fetch it and return
- jmp short ck_bwloop ; and keep waiting
- ck_text:
- cmp text_type,0 ; real text mode?
- jne ckgetw ; nope, no cursor at all
- push bp ; some bios's don't save this
- mov ah,1 ; set cursor type
- mov cx,cursortyp ; ...
- int 10h ; ...
- mov ah,02 ; move cursor
- xor bx,bx ; page
- mov dh,byte ptr textrow ; row
- add dh,byte ptr textrbase ; ...
- mov dl,byte ptr textcol ; col
- add dh,byte ptr textcbase ; ...
- int 10h ; ...
- pop bp
- ckgetw: call far ptr keypressed ; not getakey, help/tab mey be enabled
- cmp ax,0 ; key available?
- je ckgetw ; nope, keep waiting
- ck_get: call far ptr getakey ; get the keystroke
- cmp text_type,0 ; real text mode?
- jne ck_ret ; nope, done
- push bp ; some bios's don't save this
- push ax ; save it
- mov ah,1 ; make cursor normal size
- mov cx,0607h ; ...
- int 10h ; ...
- mov ah,02 ; move cursor
- xor bx,bx ; page
- mov dx,1950h ; off the display
- int 10h ; ...
- pop ax ; keystroke value
- pop bp
- ck_ret:
- ret
- keycursor endp
-
- ; ************* Function scrollup(toprow, botrow) ******************
-
- ; Scroll the screen up (from toprow to botrow)
-
- scrollup proc uses es, toprow:word, botrow:word
-
- mov ax,0601h ; scropp up one line
- mov bx,0700h ; new line is black
- mov cx,toprow ; this row,
- mov ch,cl ; ...
- mov cl,0 ; first column
- mov dx,botrow ; to this row,
- mov dh,dl ; ...
- mov dl,79 ; last column
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret ; we done.
- scrollup endp
-
- ; ************* Function scrolldown(toprow, botrow) ******************
-
- ; Scroll the screen down (from toprow to botrow)
-
- scrolldown proc uses es, toprow:word, botrow:word
-
- mov ax,0701h ; scropp down one line
- mov bx,0700h ; new line is black
- mov cx,toprow ; this row,
- mov ch,cl ; ...
- mov cl,0 ; first column
- mov dx,botrow ; to this row,
- mov dh,dl ; ...
- mov dl,79 ; last column
- push bp ; some BIOS's don't save this
- int 10h ; do it.
- pop bp ; restore the saved register
- ret ; we done.
- scrolldown endp
-
-
- ; **************** Function getcolor(xdot, ydot) *******************
-
- ; Return the color on the screen at the (xdot,ydot) point
-
- getcolor proc uses di si es, xdot:word, ydot:word
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
- mov cx,xdot ; load up the registers
- mov dx,ydot ; for the video routine
- add cx,sxoffs ; ...
- add dx,syoffs ; ...
- call dotread ; read the dot via the approved method
- mov ah,0 ; clear the high-order bits
- ret ; we done.
- getcolor endp
-
- ; Fastcall version, called when C programs are compiled by MSC 6.00A:
-
- @getcolor proc FORTRAN ; ax=xdot, dx=ydot
- push si ; preserve these
- push di ; ...
- mov cx,ax ; load up the registers
- add cx,sxoffs ; ...
- add dx,syoffs ; ...
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; ...
- call dotread ; read the dot via the approved method
- xor ah,ah ; clear the high-order bits
- pop di ; restore
- pop si ; ...
- ret ; we done.
- @getcolor endp
-
- ; ************** Function putcolor(xdot, ydot, color) *******************
-
- ; write the color on the screen at the (xdot,ydot) point
-
- putcolor proc uses di si es, xdot:word, ydot:word, xcolor:word
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
- mov cx,xdot ; load up the registers
- mov dx,ydot ; for the video routine
- add cx,sxoffs ; ...
- add dx,syoffs ; ...
- mov ax,xcolor ; ...
- and ax,andcolor ; (ensure that 'color' is in the range)
- call dotwrite ; write the dot via the approved method
- ;;; call videocleanup ; perform any video cleanup required
- ret ; we done.
- putcolor endp
-
- ; Fastcall version, called when C programs are compiled by MSC 6.00A:
-
- @putcolor proc FORTRAN ; ax=xdot, dx=ydot, bx=color
- push si ; preserve these
- push di ; ...
- mov cx,ax ; load up the registers
- add cx,sxoffs ; ...
- add dx,syoffs ; ...
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; ...
- mov ax,bx ; color
- and ax,andcolor ; ensure that 'color' is in range
- call dotwrite ; write the dot via the approved method
- ;;; call videocleanup ; perform any video cleanup required
- pop di ; restore
- pop si ; ...
- ret ; we done.
- @putcolor endp
-
-
- ; ***************Function out_line(pixels,linelen) *********************
-
- ; This routine is a 'line' analog of 'putcolor()', and sends an
- ; entire line of pixels to the screen (0 <= xdot < xdots) at a clip
- ; Called by the GIF decoder
-
- out_line proc uses di si es, pixels:ptr byte, linelen:word
- mov cx,sxoffs ; start at left side of logical screen
- mov dx,rowcount ; sanity check: don't proceed
- add dx,syoffs ; ...
- cmp dx,sydots ; beyond the end of the screen
- ja out_lineret ; ...
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
- mov ax, linelen ; last pixel column
- add ax, sxoffs ; ...
- dec ax ; ...
- mov si,pixels ; get the color for dot 'x'
- call linewrite ; mode-specific linewrite routine
- inc rowcount ; next row
- out_lineret:
- xor ax,ax ; return 0
- ret
-
- out_line endp
-
- ; ***Function get_line(int row,int startcol,int stopcol, unsigned char *pixels) ***
-
- ; This routine is a 'line' analog of 'getcolor()', and gets a segment
- ; of a line from the screen and stores it in pixels[] at one byte per
- ; pixel
- ; Called by the GIF decoder
-
- get_line proc uses di si es, row:word, startcol:word, stopcol:word, pixels:ptr byte
- mov cx,startcol ; sanity check: don't proceed
- add cx,sxoffs ; ...
- cmp cx,sxdots ; beyond the right end of the screen
- ja get_lineret ; ...
- mov dx,row ; sanity check: don't proceed
- add dx,syoffs ; ...
- cmp dx,sydots ; beyond the bottom of the screen
- ja get_lineret ; ...
- mov ax, stopcol ; last pixel to read
- add ax, sxoffs ; ...
- mov di, pixels ; get the color for dot 'x'
- call lineread ; mode-specific lineread routine
- get_lineret:
- xor ax,ax ; return 0
- ret
- get_line endp
-
- ; ***Function put_line(int row,int startcol,int stopcol, unsigned char *pixels) ***
-
- ; This routine is a 'line' analog of 'putcolor()', and puts a segment
- ; of a line from the screen and stores it in pixels[] at one byte per
- ; pixel
- ; Called by the GIF decoder
-
- put_line proc uses di si es, row:word, startcol:word, stopcol:word, pixels:ptr byte
- mov cx,startcol ; sanity check: don't proceed
- add cx,sxoffs ; ...
- cmp cx,sxdots ; beyond the right end of the screen
- ja put_lineret ; ...
- mov dx,row ; sanity check: don't proceed
- add dx,syoffs ; ...
- cmp dx,sydots ; beyond the bottom of the screen
- ja put_lineret ; ...
- mov ax,0a000h ; EGA, VGA, MCGA starts here
- mov es,ax ; save it here during this routine
- mov ax, stopcol ; last column
- add ax, sxoffs; ; ...
- cmp ax,sxdots ; beyond the right end of the screen?
- ja put_lineret ; ...
- mov si,pixels ; put the color for dot 'x'
- call linewrite ; mode-specific linewrite routine
- put_lineret:
- xor ax,ax ; return 0
- ret
- put_line endp
-
-
- ;-----------------------------------------------------------------
-
- ; setattr(row, col, attr, count) where
- ; row, col = row and column to start printing.
- ; attr = color attribute.
- ; count = number of characters to set
- ; This routine works only in real color text mode.
-
- setattr proc uses es di, row:word, col:word, attr:word, count:word
- mov ax,row ; row specified?
- cmp ax,-1 ; ...
- je setac ; nope, inherit it
- mov textrow,ax ; yup, store it
- setac: mov ax,col ; col specified?
- cmp ax,-1 ; ...
- je setago ; nope, inherit it
- mov textcol,ax ; yup, store it
- setago: cmp text_type,0 ; real color text mode?
- jne setax ; nope, do nothing
- mov ax,textrow ; starting row
- add ax,textrbase ; ...
- mov cx,160 ; x 2 bytes/row (char & attr bytes)
- imul cx
- mov bx,textcol ; add starting column
- add bx,textcbase ; ...
- add ax,bx ; twice since 2 bytes/char
- add ax,bx ; ...
- mov di,ax ; di -> start location in Video segment
- mov cx,count ; number of bytes to set
- jcxz setax ; none?
- mov ax,attr ; get color attributes in al
- mov dx,0b800h ; set video pointer
- cmp mode7text,0 ; egamono/hgc?
- je setalstore ; nope
- mov dx,0b000h ; mode 7 address
- mov al,07h ; normal mda ttribute
- cmp ah,0 ; inverse?
- jge setalchkbright ; nope
- mov al,70h ; yup
- jmp short setalstore
- setalchkbright:
- test ah,40h ; bright?
- jz setalstore ; nope
- mov al,0Fh ; yup
- setalstore:
- mov es,dx ; ...
- setalp: mov byte ptr es:1[di],al ; set attribute
- add di,2 ; for next one
- loop setalp ; do next char
- setax: ret
- setattr endp
-
-
- ;-----------------------------------------------------------------
-
- ; PUTSTR.asm puts a string directly to video display memory. Called from C by:
- ; putstring(row, col, attr, string) where
- ; row, col = row and column to start printing.
- ; attr = color attribute.
- ; string = far pointer to the null terminated string to print.
- ; Written for the A86 assembler (which has much less 'red tape' than MASM)
- ; by Bob Montgomery, Orlando, Fla. 7-11-88
- ; Adapted for MASM 5.1 by Tim Wegner 12-11-89
- ; Furthur mucked up to handle graphics
- ; video modes by Bert Tyler 1-07-90
- ; Reworked for: row,col update/inherit;
- ; 620x200x2 inverse video; far ptr to string;
- ; fix to avoid scrolling when last posn chgd;
- ; divider removed; newline ctl chars; PB 9-25-90
-
- putstring proc uses es di si, row:word, col:word, attr:word, string:far ptr byte
- mov ax,row ; row specified?
- cmp ax,-1 ; ...
- je putscol ; nope, inherit it
- mov textrow,ax ; yup, store it
- putscol:
- mov ax,col ; col specified?
- cmp ax,-1 ; ...
- je putsmode ; nope, inherit it
- mov textcol,ax ; yup, store it
- putsmode:
- les si,string ; load buffer pointer
- cmp text_type,0 ; are we in color text mode?
- jne short put_substring ; nope
- jmp put_text ; yup
-
- put_substring: ; graphics mode substring loop
- push si ; save start pointer
- push textcol ; save start column
- put_loop:
- mov al,byte ptr es:[si] ; get next char
- cmp al,0 ; end of string?
- je puts_chk_invert ; yup
- cmp al,10 ; end of line?
- je puts_chk_invert ; yup
- push si ; save offset
- push es ; save this
- push bp ; and this
- push ax ; and this last, needed soonest
- mov ah,02h ; set up bios set cursor call
- xor bh,bh ; page 0
- mov dl,byte ptr textcol ; screen location
- add dl,byte ptr textcbase ; ...
- mov dh,byte ptr textrow ; ...
- add dh,byte ptr textrbase ; ...
- int 10h ; invoke the bios
- pop ax ; the character to write
- mov ah,09h ; set up the bios write char call
- mov bx,7 ; page zero, color
- mov cx,1 ; write 1 character
- int 10h ; invoke the bios
- pop bp ; restore
- pop es ; restore
- pop si ; restore
- inc si ; on to the next character
- inc textcol ; ...
- jmp short put_loop ; ...
- puts_chk_invert:
- pop bx ; starting column number
- pop dx ; restore start offset
- cmp attr,0 ; top bit of attribute on?
- jge short puts_endsubstr ; nope, nothing more to do
- cmp text_type,1 ; 640x200x2 mode?
- jne short puts_endsubstr ; nope, can't do anything more
- mov cx,si ; calc string length
- sub cx,dx ; ...
- jcxz short puts_endsubstr ; empty string?
- push ax ; remember terminating char
- push es ; and this
- ; make the string inverse video on display
- mov ax,320 ; offset in vid mem of 1st byte's top
- mov di,textrow ; row*320 + col
- add di,textrbase ; ...
- mul di ; ...
- add ax,bx ; ...
- add ax,textcbase ; ...
- mov di,ax ; ...
- mov ax,0b800h ; set es to vid memory
- mov es,ax ; ...
- puts_invert:
- not byte ptr es:0000h[di] ; invert the 8x8 making up a character
- not byte ptr es:2000h[di]
- not byte ptr es:0050h[di]
- not byte ptr es:2050h[di]
- not byte ptr es:00a0h[di]
- not byte ptr es:20a0h[di]
- not byte ptr es:00f0h[di]
- not byte ptr es:20f0h[di]
- inc di
- loop puts_invert ; on to the next character
- pop es ; restore
- pop ax ; ...
- puts_endsubstr:
- cmp al,0 ; the very end?
- je short putstring_ret ; we done.
- inc si ; go past the newline char
- mov textcol,0 ; do newline
- inc textrow ; ...
- jmp put_substring ; on to the next piece
-
- put_text: ; text mode substring loop
- mov ax,textrow ; starting row
- add ax,textrbase ; ...
- mov cx,160 ; x 2 bytes/row (char & attr bytes)
- imul cx
- mov bx,textcol ; add starting column
- add bx,textcbase ; ...
- add ax,bx ; twice since 2 bytes/char
- add ax,bx ; ...
- mov di,ax ; di -> start location in Video segment
- mov ax,attr ; get color attributes in ah
- cmp mode7text,0 ; egamono/hgc? (MDA)
- je B0 ; nope, use color attr
- mov al,07h ; default, white on blank
- cmp ah,0 ; top bit of attr set?
- jge mdachkbright ; nope
- mov al,70h ; inverse video
- jmp short B0
- mdachkbright:
- test ah,40h ; 2nd bit of attr set?
- jz B0 ; nope
- mov al,0Fh ; bright
- B0: mov ah,al
- B1: mov al,byte ptr es:[si] ; get a char in al
- cmp al,0 ; end of string?
- je putstring_ret ; yes, done
- inc si ; bump for next time
- cmp al,10 ; newline?
- jne B2 ; nope
- mov textcol,0 ; yup, do it
- inc textrow ; ...
- jmp short put_text ; on to the next substring
- B2: push es ; No, store char & attribute
- mov dx,textaddr ; ...
- mov es,dx ; ...
- stosw ; ...
- pop es ; ...
- inc textcol ; update local var
- jmp short B1 ; do next char
-
- putstring_ret:
- ret
- putstring endp
-
-
- ; **************** EGA Palette <==> VGA DAC Conversion Routines **********
-
- ; paltodac converts a 16-palette EGA value to a 256-color VGA
- ; value (duplicated 16 times)
- ; dactopal converts the first 16 VGA values to a 16-palette
- ; EGA value
-
- ; local routines called with register values
- ; BH = VGA Red Color xxRRRRRR
- ; BL = VGA Green Color xxGGGGGG
- ; CH = VGA Blue Color xxBBBBBB
- ; CL = EGA Palette xxrgbRGB
- ;
- ; palettetodac converts CL to BH/BL/CH
- ; dactopalette converte BH/BL/CH to CL
-
- ; *************************************************************************
-
- palettetodac proc near
- mov bx,0 ; initialize RGB values to 0
- mov ch,0 ; ...
- test cl,20h ; low-red high?
- jz palettetodac1 ; nope
- or bh,10h ; set it
- palettetodac1:
- test cl,10h ; low-green high?
- jz palettetodac2 ; nope
- or bl,10h ; set it
- palettetodac2:
- test cl,08h ; low-blue high?
- jz palettetodac3 ; nope
- or ch,10h ; set it
- palettetodac3:
- test cl,04h ; high-red high?
- jz palettetodac4 ; nope
- or bh,20h ; set it
- palettetodac4:
- test cl,02h ; high-green high?
- jz palettetodac5 ; nope
- or bl,20h ; set it
- palettetodac5:
- test cl,01h ; high-blue high?
- jz palettetodac6 ; nope
- or ch,20h ; set it
- palettetodac6:
- ret
- palettetodac endp
-
- dactopalette proc near
- mov cl,0 ; initialize RGB values to 0
- test bh,10h ; low-red high?
- jz dactopalette1 ; nope
- or cl,20h ; set it
- dactopalette1:
- test bl,10h ; low-green high?
- jz dactopalette2 ; nope
- or cl,10h ; set it
- dactopalette2:
- test ch,10h ; low-blue high?
- jz dactopalette3 ; nope
- or cl,08h ; set it
- dactopalette3:
- test bh,20h ; high-red high?
- jz dactopalette4 ; nope
- or cl,04h ; set it
- dactopalette4:
- test bl,20h ; high-green high?
- jz dactopalette5 ; nope
- or cl,02h ; set it
- dactopalette5:
- test ch,20h ; high-blue high?
- jz dactopalette6 ; nope
- or cl,01h ; set it
- dactopalette6:
- ret
- dactopalette endp
-
- paltodac proc uses es si di
- mov si,0 ; initialize the loop values
- mov di,0
- paltodacloop:
- mov cl,palettega[si] ; load up a single palette register
- call palettetodac ; convert it to VGA colors
- mov dacbox+0[di],bh ; save the red value
- mov dacbox+1[di],bl ; and the green value
- mov dacbox+2[di],ch ; and the blue value
- inc si ; bump up the registers
- add di,3 ; ...
- cmp si,16 ; more to go?
- jne paltodacloop ; yup.
- push ds ; set ES to DS temporarily
- pop es ; ...
- mov ax,15 ; do this 15 times to get to 256
- mov di,offset dacbox+48 ; set up the first destination
- paltodacloop2:
- mov cx,24 ; copy another block of 16 registers
- mov si,offset dacbox ; set up for the copy
- rep movsw ; do it
- dec ax ; need to do another block?
- jnz paltodacloop2 ; yup. do it.
- ret ; we done.
- paltodac endp
-
- dactopal proc uses es si di
- mov si,0 ; initialize the loop values
- mov di,0
- dactopalloop:
- mov bh,dacbox+0[di] ; load up the VGA red value
- mov bl,dacbox+1[di] ; and the green value
- mov ch,dacbox+2[di] ; and the blue value
- call dactopalette ; convert it to an EGA palette
- mov palettega[si],cl ; save as a single palette register
- inc si ; bump up the registers
- add di,3 ; ...
- cmp si,16 ; more to go?
- jne dactopalloop ; yup.
- mov cl,palettega ; copy palette 0
- mov palettega+16,cl ; to the overscan register
- ret ; we done.
- dactopal endp
-
-
- ; *********************** Function loaddac() ****************************
-
- ; Function to Load the dacbox[][] array, if it can
- ; (sets gotrealdac to 0 if it can't, 1 if it can)
-
- loaddac proc uses es
- cmp dotmode, 29 ; truecolor? MCP 5-29-91
- jne NotTPlusLoaddac
- mov ax,4402h
- push ax
- mov ax,256 * 3
- push ax
- xor ax,ax
- push ax
- push ds
- mov ax,OFFSET dacbox
- push ax
- call far ptr TPlusLUT
- add sp, 10
- or ax, ax
- jz NotTPlusLoaddac ; Didn't work, try a regular palette
- jmp loaddacdone
- NotTPlusLoaddac:
- cmp dotmode,19 ; roll-your-own video mode?
- jne loaddac_notyourown
- call far ptr readvideopalette
- cmp ax,-1 ; palette-write handled yet?
- jne go_loaddacdone ; yup.
- loaddac_notyourown:
- mov reallyega,0 ; set flag: not an EGA posing as a VGA
- cmp dotmode,9 ; TARGA 3 June 89 j mclain
- je go_loaddacdone
- cmp f85flag, 0
- jne go_loaddacdone
-
- cmp xga_isinmode,0 ; XGA graphics mode?
- jne go_loaddacdone
-
- mov dacbox,255 ; a flag value to detect invalid DAC
- cmp debugflag,16 ; pretend we're not a VGA?
- je loaddacdebug ; yup.
- push ds ; ...
- pop es ; ...
- mov ax,1017h ; get the old DAC values
- mov bx,0 ; (assuming, of course, they exist)
- mov cx,256 ; ...
- mov dx,offset dacbox ; ...
- push bp
- int 10h ; do it.
- pop bp
- loaddacdebug:
- cmp dacbox,255 ; did it work? do we have a VGA?
- je loaddacega ; nope, go check ega
- cmp colors,16 ; 16 color vga?
- jne go_loaddacdone ; nope, all done
- cld ; yup, must straighten out dacbox,
- push ds ; 16 color vga uses indirection thru
- pop es ; palette select
- mov si,offset dacbox+60 ; dac[20] is used for color 6 so
- mov di,offset dacbox+18 ; copy dacbox[20] to dacbox[6]
- mov cx,3 ; ...
- rep movsb ; ...
- mov si,offset dacbox+168 ; dac[56-63] are used for colors 8-15 so
- mov di,offset dacbox+24 ; copy dacbox[56-63] to dacbox[8-15]
- mov cx,24 ; ...
- rep movsb ; ...
- go_loaddacdone:
- jmp short loaddacdone
- loaddacega:
- cmp colors,16 ; are we using 16 or more colors?
- jb loaddacdone ; nope. forget it.
- ;; cmp sydots,350 ; 640x350 range?
- cmp video_type,3 ; EGA or better?
- jb loaddacdone ; nope. forget it.
- mov bx,offset palettega ; make up a dummy palette
- mov cx,3800h ; start with color 0 == black
- loaddacega1: ; and color 8 == low-white
- mov 0[bx],cl ; save one color
- mov 8[bx],ch ; and another color
- inc bx ; bump up the DAC
- add cx,0101h ; and the colors
- cmp cl,8 ; finished 8 colors?
- jne loaddacega1 ; nope. get more.
- mov reallyega,1 ; note that this is really an EGA
- call far ptr paltodac ; "convert" it to a VGA DAC
- mov daclearn,1 ; bypass learn mode
- mov ax,cyclelimit ; and spin as fast as he wants
- mov daccount,ax ; ...
- loaddacdone:
- cmp colors,16 ; 16 color mode?
- jne loaddacdone2 ; nope
- cld ; yup, clear the excess dacbox
- mov cx,360 ; entries to all zeros for editpal
- sub ax,ax
- push ds
- pop es
- mov di,offset dacbox+48
- rep stosw
- loaddacdone2:
- cmp tweakflag,0 ; tweaked mode?
- je loaddacdone3 ; nope
- mov dx,3c4h ; alter sequencer registers
- mov ax,0604h ; disable chain 4
- out dx,ax
- loaddacdone3:
- mov gotrealdac,1 ; flag for whether mode supports DAC
- cmp dacbox,255 ; did DAC get loaded or fudged?
- jne loaddacret ; yup
- mov gotrealdac,0 ; nope
- loaddacret:
- ret
- loaddac endp
-
- ; *************** Function spindac(direction, rstep) ********************
-
- ; Rotate the MCGA/VGA DAC in the (plus or minus) "direction"
- ; in "rstep" increments - or, if "direction" is 0, just replace it.
-
- spindac proc uses di si es, direction:word, rstep:word
- cmp dotmode,9 ; TARGA 3 June 89 j mclain
- je spinbailout
- cmp dotmode,11 ; disk video mode?
- je spinbailout
- cmp gotrealdac,0 ; do we have DAC registers to spin?
- je spinbailout ; nope. bail out.
- cmp colors,16 ; at least 16 colors?
- jge spindacdoit ; yup. spin away.
- spinbailout:
- jmp spindacreturn ; nope. bail out.
-
- spindacdoit:
- push ds ; need ES == DS here
- pop es ; ...
- cmp direction,0 ; just replace it?
- je newDAC ; yup.
-
- mov cx, rstep ; loop through the rotate "rstep" times
- stepDAC:
- push cx ; save the loop counter for a tad
- mov si,offset dacbox
- mov di,si
- mov ax,rotate_lo ; calc low end of rotate range
- cmp ax,colors ; safety check for 16 color mode
- jae nextDAC ; out of range, none to rotate
- add si,ax
- add si,ax
- add si,ax
- mov ax,rotate_hi ; calc high end of rotate range
- cmp ax,colors ; safety check for 16 color mode
- jb stepDAC2 ; ok, in range
- mov ax,colors ; out of range, use colors-1
- dec ax ; ...
- stepDAC2:
- add di,ax
- add di,ax
- add di,ax
- mov cx,di ; size of rotate range - 1
- sub cx,si
- jcxz nextDAC ; do nothing if range 0
- cmp direction,1 ; rotate upwards?
- jne short downDAC ; nope. downwards
- mov bx,word ptr [si] ; save the first entry
- mov dl,byte ptr [si+2] ; ...
- cld ; set the direction
- mov di,si ; set up the rotate
- add si,3 ; ...
- rep movsb ; rotate it
- mov word ptr [di],bx ; store the last entry
- mov byte ptr [di+2],dl ; ...
- jmp short nextDAC ; set the new DAC
- downDAC:
- std ; set the direction
- mov bx,word ptr [di] ; save the last entry
- mov dl,byte ptr [di+2] ; ...
- mov si,di ; set up the rotate
- dec si ; ...
- add di,2 ; ...
- rep movsb ; rotate it
- mov word ptr [si+1],bx ; store the first entry
- mov byte ptr [si+3],dl ; ...
- cld ; reset the direction
- nextDAC:
- pop cx ; restore the loop counter
- loop stepDAC ; and loop until done.
-
- newDAC:
- cmp dotmode,19 ; roll-your-own video?
- jne spin_notyourown ; nope
- call far ptr writevideopalette
- cmp ax,-1 ; negative result?
- je go_spindoit ; yup. handle it locally.
- jmp spindacreturn ; else we done.
- go_spindoit:
- jmp spindoit
-
- spin_notyourown:
- cmp dotmode, 29
- je TPlusOrXGAspindac
- cmp xga_isinmode,0 ; XGA extended graphics?
- je notxga
-
- TPlusOrXGAspindac:
- mov si,offset dacbox
- push si
- mov bx,0
- xgalp1: mov al,[si+bx] ; adjust VGA -> XGA
- shl al,1
- shl al,1
- mov [si+bx],al
- inc bx
- cmp bx,768
- jne xgalp1
-
- cmp dotmode, 29 ; Are we a TARGA+?
- jne XGAPaletteCall ; nope - XGA
- mov ax,4403h
- push ax
- mov ax,256 * 3
- push ax
- xor ax,ax
- push ax
- push ds
- mov ax,OFFSET dacbox
- push ax
- call far ptr TPlusLUT
- add sp, 10
- jmp TPlusOrXGASet
-
- XGAPaletteCall:
- call far ptr xga_setpalette
-
- TPlusOrXGASet:
- pop si
- mov bx,0
- xgalp2: mov al,[si+bx] ; adjust XGA -> VGA
- shr al,1
- shr al,1
- mov [si+bx],al
- inc bx
- cmp bx,768
- jne xgalp2
- jmp spindacreturn
- notxga:
-
- cmp bios_palette,0 ; BIOS palette updates forced?
- je not_bios_palette ; nope
- mov ax,1012h ; use a BIOS update
- mov bx,0
- mov cx,256
- push ds
- pop es
- mov dx,offset dacbox
- int 10h
- jmp spindacreturn
- not_bios_palette:
-
- cmp f85flag, 0 ; if 8514a then update pallette
- je spindoit
- jmp spin8514
-
- spindoit:
- cmp colors,16 ; 16 color vga?
- jne spindoit2 ; nope
- cmp reallyega,1 ; is this really an EGA?
- je spindoit2 ; yup
- cld ; vga 16 color, straighten out dacbox,
- push ds ; 16 color vga uses indirection thru
- pop es ; palette select
- mov si,offset dacbox+18 ; dac[20] is used for color 6 so
- mov di,offset dacbox+60 ; copy dacbox[6] to dacbox[20]
- mov cx,3 ; ...
- rep movsb ; ...
- mov si,offset dacbox+24 ; dac[56-63] are used for colors 8-15 so
- mov di,offset dacbox+168 ; copy dacbox[8-15] to dacbox[56-63]
- mov cx,24 ; ...
- rep movsb ; ...
- spindoit2:
- mov bx,0 ; set up to update the DAC
- mov dacnorm,0 ; indicate no overflow
- dacupdate:
- mov cx,daccount ; ...
- mov ax,256 ; calculate 256 - BX
- sub ax,bx ; ...
- cmp ax,cx ; is that less than the update count?
- jge retrace1 ; nope. no adjustment
- mov cx,ax ; else adjust
- mov dacnorm,1 ; and indicate overflow
- retrace1:
- mov dx,03dah ; wait for no retrace
- in al,dx ; ...
- and al,8 ; this bit is high during a retrace
- jnz retrace1 ; so loop until it goes low
- retrace2:
- in al,dx ; wait for no retrace
- and al,8 ; this bit is high during a retrace
- jz retrace2 ; so loop until it goes high
- cmp reallyega,1 ; is this really an EGA?
- je spinega ; yup. spin it that way.
- cmp cpu,88 ; are we on a (yuck, ugh) 8088/8086?
- jle spinbios ; yup. go through the BIOS
- .186
- mov dx,03c8h ; set up for a blitz-write
- mov ax,bx ; from this register
- cli ; critical section: no ints
- out dx,al ; starting register
- inc dx ; set up to update colors
- mov si, offset dacbox ; get starting addr in SI
- add si,bx ; ...
- add si,bx ; ...
- add si,bx ; ...
- mov ax,cx ; triple the value in CX
- add cx,ax ; ...
- add cx,ax ; ...
- rep outsb ; whap! Zango! They're updated!
- sti ; end of critical section
- mov cx,ax ; restore CX for code below
- jmp spindone ; skip over the BIOS version.
- .8086
- spinbios:
- mov dx,offset dacbox ; set up the DAC box offset
- add dx,bx ; ...
- add dx,bx ; ...
- add dx,bx ; ...
- push bp ; save some registers
- push cx ; (AMSTRAD might need this)
- push dx ; ...
- push bx ; ...
- mov ax,1012h ; update the DAC
- int 10h ; do it.
- pop bx ; restore the registers
- pop dx ; ...
- pop cx ; ...
- pop bp ; ...
- jmp spindone ; jump to common code
- spinega:
- cmp bx,0 ; skip this if not the first time thru
- jne spindone ; ...
- push bx ; save some registers
- push cx ; aroud the call
- call far ptr dactopal ; convert the VGA DAC to an EGA palette
- pop cx ; restore the registers
- pop bx ; from prior to the call
- mov ax,1002h ; update the EGA palette
- mov dx,offset palettega ; ...
- int 10h ; do it.
- spindone:
- cmp daclearn,0 ; are we still in learn mode?
- jne nolearn ; nope.
- mov dx,03dah ; check for the retrace
- in al,dx ; ...
- and al,1 ; this bit is high if display disabled
- jz donelearn ; oops. retrace finished first.
- cmp dacnorm,0 ; was this a "short" update?
- jne short nolearn ; then don't increment it
- inc daccount ; increment the daccount value
- inc daccount ; increment the daccount value
- inc daccount ; increment the daccount value
- mov ax,cyclelimit ; collect the cycle-limit value
- cmp daccount,ax ; sanity check: don't update too far
- jle short nolearn ; proceed if reasonable.
- donelearn:
- sub daccount,6 ; done learning: reduce the daccount
- mov daclearn,1 ; set flag: no more learning
- cmp daccount,4 ; there's a limit to how slow we go
- jge nolearn ; ...
- mov daccount,4 ; ...
- nolearn:
- add bx,cx ; set up for the next batch
- cmp bx,256 ; more to go?
- jge spindacreturn ; nope. we done.
- jmp dacupdate ; yup. do it.
-
- spin8514:
- cmp ai_8514, 0 ;check afi flag JCO 4/11/92
- jne spin85afi
- call w8514hwpal ; AW
- jmp spindacreturn
- spin85afi:
- call w8514pal ;use afi
-
- spindacreturn:
- ret
- spindac endp
-
- ; *************** Function find_special_colors ********************
-
- ; Find the darkest and brightest colors in palette, and a medium
- ; color which is reasonably bright and reasonably grey.
-
- find_special_colors proc uses si
- mov color_dark,0 ; for default cases
- mov color_medium,7 ; ...
- mov color_bright,15 ; ...
- cmp colors,2 ; 2 color mode?
- jg fscnot2
- mov color_medium,1 ; yup, set assumed values and return
- mov color_bright,1
- ret
- fscnot2:
- cmp colors,16 ; < 16 color mode? (ie probably 4)
- jge fscnot4
- mov color_medium,2 ; yup, set assumed values and return
- mov color_bright,3
- ret
- fscnot4:
- cmp gotrealdac,0 ; dac valid?
- je fscret ; nope, return with defaults set earlier
- mov bh,255 ; bh is lowest brightness found yet
- sub bl,bl ; bl is highest found yet
- sub ah,ah ; ah is best found for medium choice yet
- mov si,offset dacbox ; use si as pointer to dac
- sub cx,cx ; use cx for color number
- fscloop:
- mov al,byte ptr 0[si] ; add red,green,blue (assumed all <= 63)
- add al,byte ptr 1[si] ; ...
- add al,byte ptr 2[si] ; ...
- cmp al,bh ; less than lowest found so far?
- jae fscchkbright
- mov color_dark,cx ; yup, note new darkest
- mov bh,al ; ...
- fscchkbright:
- cmp al,bl ; > highest found so far?
- jbe fscchkmedium
- mov color_bright,cx ; yup, note new brightest
- mov bl,al ; ...
- fscchkmedium:
- cmp al,150 ; too bright?
- jae fscnextcolor ; yup, don't check for medium
- add al,80 ; so the subtract below will be safe
- cmp al,ah ; already less than best found?
- jbe fscnextcolor
- mov dh,byte ptr 0[si] ; penalize by (maxgun-mingun)/2
- mov dl,byte ptr 1[si]
- cmp dh,dl ; set dh to max gun
- jae fscmed1
- xchg dh,dl ; now dh=max(0,1), dl=min(0,1)
- fscmed1:
- cmp dh,byte ptr 2[si] ; 2 > dh?
- jae fscmed2
- mov dh,byte ptr 2[si]
- fscmed2:
- cmp dl,byte ptr 2[si] ; 2 < dl?
- jbe fscmed3
- mov dl,byte ptr 2[si]
- fscmed3:
- sub dh,dl ; now subtract the penalty
- shr dh,1
- sub al,dh
- cmp al,ah ; a new best?
- jbe fscnextcolor
- mov color_medium,cx ; yup, note new medium
- mov ah,al ; ...
- fscnextcolor:
- add si,3 ; point to next dac entry
- inc cx ; next color number
- cmp cx,colors ; scanned them all?
- jl fscloop ; nope, go around again
- cmp ah,0 ; find any medium color?
- jne fscret ; yup, all done
- mov ax,color_bright ; must be a pretty bright image,
- mov color_medium,ax ; use the brightest for medium
- fscret:
- ret
- find_special_colors endp
-
-
- ; *************** Functions get_a_char, put_a_char ********************
-
- ; Get and put character and attribute at cursor
- ; Hi nybble=character, low nybble attribute. Text mode only
-
- get_a_char proc
- mov ah,8
- xor bh,bh
- int 10h
- ret
- get_a_char endp
-
- put_a_char proc character:word
- mov ax,character
- mov bl,ah
- mov ah,9
- xor bh,bh
- mov cx,1
- int 10h
- ret
- put_a_char endp
-
- end
-