Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mode 12h (640x480x4) code for DJGPP?

126 views
Skip to first unread message

Doug Eleveld

unread,
Oct 31, 2003, 8:18:35 AM10/31/03
to
Does anyone have (or know where to get some) DJGPP source code for
VGA mode 12h that they can share?

Pixel plotting and blitting code specifically. I'm pulling all my hair out
trying to figure out how to do it as fast and efficient as possible with
such a strange mode.

Thanks in advance,

Doug Eleveld

alex

unread,
Oct 31, 2003, 8:05:34 PM10/31/03
to
I think the memory arrangement of that mode is rather odd (if i recall
correctly,
cos it has been a long time for me)

Seeing you are using a 32 bit protected mode capable compiler, did you
realise you have access to graphic framebuffers?

You can use Hi Res modes, 24 Bit colour in 1024x768 if u wish.
have a look at the VESA 2.0 specification. Its quite easy to set up.

If u absolutely must use this dinosaur 12h video mode. I dont think
I can help you.

framebuffer access is certainly faster

Alex.


"Doug Eleveld" <dele...@dds.nl> wrote in message
news:ebb50998.03103...@posting.google.com...

Doug Eleveld

unread,
Nov 2, 2003, 1:46:44 PM11/2/03
to
"alex" <n...@spam.pls.kthx.com> wrote in message news:<bnv0ln$545$1...@lust.ihug.co.nz>...

> I think the memory arrangement of that mode is rather odd (if i recall
> correctly,
> cos it has been a long time for me)
>
> Seeing you are using a 32 bit protected mode capable compiler, did you
> realise you have access to graphic framebuffers?
>
> You can use Hi Res modes, 24 Bit colour in 1024x768 if u wish.
> have a look at the VESA 2.0 specification. Its quite easy to set up.
>
> If u absolutely must use this dinosaur 12h video mode. I dont think
> I can help you.
>
> framebuffer access is certainly faster

Yes, I already have a good vesa code but I wanted to have maximum
portability.
I'm improving my gui (DEPUI) and I want to run even on *really* old
computers. Not that it's absolutely necessary, it's more of a good
feeling for me that my
code will run on just about any computer hardware. So thats why I'd
like Mode 12h stuff.

Doug

Alex Russell

unread,
Nov 2, 2003, 9:48:21 PM11/2/03
to
"Doug Eleveld" <dele...@dds.nl> wrote in message
news:ebb50998.03103...@posting.google.com...

Any good ega planed mode code should work.

The BEST book for old video hardware is:

Programmers Guide to
PC & PS/2 video Systems
by
Richard Wilton

ISBN 1-55615-103-9

My copy (no you can't have it) was published by Microsoft press back in
1987.


Here is some ega code:

;
; Copyright 1991, Alec Russell, All rights reserved
; from "programmer's guide to PC &PS/2 video systems"
; by Richard Wilton
;
; created April 10, 1991
; last update ;
;
; determine buffer address of a pixel in EGA VGA native graphics
; modes.
;
; caller AX = y coord
; BX = x coord
;
; returns AH = bitmask
; BX = byte offset in buffer
; CL = number of bits to shift left
; ES = video buffer segment
;
; see page 96 for details and comments
;

BytesPerLine EQU 80 ;bytes in one horizontal
line
OriginOffset EQU 0
VideoBufferseg EQU 0A000h

_TEXT SEGMENT byte public 'CODE'
ASSUME cs:_TEXT

PUBLIC PixelAddr10
PixelAddr10 PROC near

mov cl,bl
push dx

mov dx, BytesPerLine
mul dx

pop dx
shr bx, 1
shr bx, 1
shr bx, 1
add bx, ax
add bx, OriginOffset

mov ax, VideoBufferSeg
mov es, ax

and cl, 7
xor cl, 7
mov ah, 1
ret

PixelAddr10 ENDP

_TEXT ENDS
END


;
; Copyright 1991, Alec Russell, All rights reserved
; from "programmer's guide to PC &PS/2 video systems"
; by Richard Wilton
;
; created April 10, 1991
; last update :
; functions to copy bit-blocks to/from system ram/video ram
;
; see page 352 for details and comments
;
; function : copy bit block from video buffer to system ram
; in native EGA and VGA graphics modes.
;
; caller: Microsoft C, large and compact memory models
;
;
; int get_ega_bit_block(int x0, int y0, int x1, int y1, char far *buffer);
;
;
; returns size of block in system ram.
;
;

ARGx0 EQU word ptr [bp+4]
ARGy0 EQU word ptr [bp+6]
ARGx1 EQU word ptr [bp+8]
ARGy1 EQU word ptr [bp+10]
ADDRbuf EQU [bp+12]

VARPixelRows EQU word ptr [bp-2]
VARPixelRowlen EQU word ptr [bp-4]

BytesPerRow EQU 80
ByteOffSetshift EQU 3 ; reflects number of pixels
per byte

_TEXT SEGMENT byte public 'CODE'
ASSUME cs:_TEXT

EXTRN PixelAddr10:near

PUBLIC _get_ega_bit_block
_get_ega_bit_block PROC near

push bp
mov bp, sp
sub sp, 4
push ds
push si
push di

; compute dimension of block

mov ax, ARGx1
sub ax, ARGx0
mov cx, 0FF07h
and cl, al
xor cl, 7
shl ch, cl
mov cl, ch
push cx

mov cl, ByteOffsetshift
shr ax, cl
inc ax
push ax

mov ax, ARGy1
sub ax, ARGy0
inc ax
push ax

; establish addressing

mov ax, ARGy0
mov bx, ARGx0
call PixelAddr10
xor cl, 7
push es
pop ds
mov si, bx

les di, ADDRbuf

; build 5 byte bit-block header

pop ax
mov VARPixelRows, ax
stosw
pop ax
mov VARPixelRowLen, ax
stosw
pop ax
mov ch, al
stosb

; set up graphics controler

mov dx, 3CEh
mov ax, 0005
out dx, ax
mov ax, 0304h

; copy from video buffer to system RAM

L01: out dx, ax
push ax
push VARPixelRows
push si

L02: mov bx, VARPixelRowLen
push si

L03: lodsw
dec si
rol ax, cl
stosb
dec bx
jnz L03

and es:[di-1], ch
pop si
add si, BytesPerRow

dec VARPixelRows
jnz L02

pop si
pop VARPixelRows
pop ax

dec ah
jns L01

mov ax, di
sub ax, ADDRbuf

pop di
pop si
pop ds
mov sp, bp
pop bp
ret

_get_ega_bit_block ENDP
_TEXT ENDS

END

;
; Copyright 1991, Alec Russell, All rights reserved
; from "programmer's guide to PC &PS/2 video systems"
; by Richard Wilton
;
; added "mode" parameter
;
; created April 10, 1991
; last update ; April 11, 1991
;
; functions to copy bit-blocks to/from system ram/video ram
;
; see page 352 for details and comments
;
; function : copy bit block to video buffer from system ram
; in native EGA and VGA graphics modes.
;
; caller: Microsoft C, large and compact memory models
;
;
; void put_ega_bit_block(char far *buff, int x, int y, char mode);
;
;

ADDRbuf EQU dword ptr [bp+4] ; far pointer
ARGx EQU word ptr [bp+8]
ARGy EQU word ptr [bp+10]
ARGmode EQU byte ptr [bp+12]

VARPixelRows EQU word ptr [bp-2]
VARPixelRowLen EQU word ptr [bp-4]
VARRowCounter EQU word ptr [bp-6]
VARStartMask EQU word ptr [bp-8]
VAREndMaskL EQU word ptr [bp-10]
VAREndMaskR EQU word ptr [bp-12]

BytesPerRow EQU 80
ByteOffSetshift EQU 3 ; reflects number of pixels
per byte
; RMWbits EQU 18h ;selects replace Xor AND
or OR

_TEXT SEGMENT byte public 'CODE'
ASSUME cs:_TEXT

EXTRN PixelAddr10:near

PUBLIC _put_ega_bit_block
_put_ega_bit_block PROC near

push bp
mov bp, sp
sub sp, 12
push ds
push si
push di

; establish addressing

mov ax, ARGy
mov bx, ARGx
call PixelAddr10
inc cl
and cl, 7
mov di, bx

lds si, ADDRbuf

; obtain dimesions of block from header

lodsw
mov VARPixelRows, ax
lodsw
mov VARPixelRowLen, ax
lodsb
mov ch, al

; setup graphics controler

mov dx, 3CEh

mov ah, ARGmode
mov al, 3
out dx, ax

mov ax, 0805h
out dx, ax

mov ax, 0007
out dx, ax

mov ax, 0FF08h
out dx, ax

mov dl, 0C4h
mov ax, 0802h
cmp cx, 0FF00h
jne L15 ; jump if not byte aligned

; byte aligned routine

mov cx, VARPixelRowLen

L10: out dx, ax
push ax
push di
mov bx, VARPixelRows

L11: push di
push cx

L12: lodsb
and es:[di], al
inc di
loop L12

pop cx
pop di
add di, BytesPerRow
dec bx
jnz L11

pop di
pop ax
shr ah, 1
jnz L10

jmp Lexit

; non-aligned bytes routine

L15: push ax

mov bx, 0FFh
mov al, ch
cbw
cmp VARPixelRowLen, 1
jne L16

mov bl, ch
mov ah, ch
xor al, al

L16: shl ax, cl
shl bx, cl

mov bl, al
mov al, 8
mov VAREndMaskL, ax
mov ah, bl
mov VAREndMaskR, ax
mov ah, bh
mov VARStartMask, ax

mov bx, VARPixelRowLen
pop ax

; set pixels row by row in the bit planes

L17: out dx, ax
push ax
push di
mov dl, 0CEh

mov ax, VARPixelRows
mov VARRowCounter, ax

; set pixels at start of row for current bit plane

L18: push di
push si
push bx

mov ax, VARStartMask
out dx, ax

lodsw

dec si
test cl, cl
jnz L19

dec bx
jnz L20

jmp short L22

L19: rol ax, cl
and es:[di], ah
inc di
dec bx

L20: push ax
mov ax, 0FF08h
out dx, ax
pop ax

dec bx
jng L22

; set pixels in middle of row

L21: and es:[di], al
inc di

lodsw
dec si
rol ax, cl
dec bx
jnz L21

; set pixels at end of row

L22: mov bx, ax
mov ax, VAREndMaskL
out dx, ax
and es:[di], bl

mov ax, VAREndMaskR
out dx, ax
and es:[di+1], bh

pop bx
pop si
add si, bx
pop di
add di, BytesPerRow
dec VARRowCounter
jnz L18

pop di
pop ax
mov dl, 0C4h
shr ah, 1
jnz L17

; restore graphics controler to default mode

Lexit: mov ax, 0F02h
out dx, ax

mov dl, 0CEh
mov ax, 0003
out dx, ax

mov ax, 0005
out dx, ax

mov ax, 0F07h
out dx, ax

mov ax, 0FF08h
out dx, ax

pop di
pop si
pop ds
mov sp, bp
pop bp
ret

_put_ega_bit_block ENDP

_TEXT ENDS

END

--
Alex Russell
alexande...@telus.net


mcheu

unread,
Nov 3, 2003, 12:33:40 AM11/3/03
to

Try hunting here:

http://sunsite.lanet.lv/ftp/mirror/x2ftp/msdos/programming/djgpp2/00index.html

It's a mirror to the old MSDOS game programming archive: x2ftp.oulu.fi

While not all the code is meant for DJGPP, you'll probably find
something that will help you.
----------------------------------------
Thanks,
MCheu

0 new messages