home *** CD-ROM | disk | FTP | other *** search
- {
- Kai Rohrbacher
-
- >> Basically, Mode Y works like this: use the BIOS to switch
- >> into normal 320x200x256 mode, then reprogram the sequencer to
- >> unchain the 4 bitplanes. This results in a bitplaned VRAM layout
- >> very similiar to the EGA/VGA's 16 color modes:
- >
- > By saying 4 bitplanes, are you referering to the pages? I know that
- > you can specify 4 pages in mode X/Y.
-
- No, it just means that with each VRAM address, 4 physically different RAM cells
- can be addressed: you may think of a "3-dimensional" architecture of your VGA's
- VRAM (ASCII sucks, I know...)
- ____________
- |* plane3 |
- ___|_________ |
- |* plane2 |__|
- ___|__________ |
- |* plane1 |__|
- ___|___________ |
- |* plane0 |__|
- | |
- |_______________|
-
- The upper left corner of each bitplane (marked by a "*") is referenced with the
- address $A000:0, but refers to 4 pixels! It is quite simple: instead of
- counting "$A000:0 is the first pixel, $A000:1 is the 2nd, $A000:2 is the 3rd,
- $A000:3 is the 4th, $A000:4 is the 5th" (as you would do in the normal BIOS
- mode 320x200x256), the pixels now are distributed this way: "$A000:0/plane 0 is
- the 1st, $A000:0/plane 1 is the 2nd, $A000:0/plane 2 is the 3rd, $A000:0/plane
- 3 is the 4th, $A000:1/plane 0 is the 5th" and so on.
- So obviously, w/o doing some "bitplane switching", you are always restricted to
- work on one bitplane at a time --the one actually being activated. If this is
- plane0, you may only change pixels which (x mod 4) remainder is 0, the other
- ones with (x mod 4)=1|2|3 aren't accessible, you have to "switch to the plane"
- first. Thus the name "bitplane"!
-
- DT> And what exactly does "unchain" mean, as opposed to "chained". I have the
- DT> feeling that they refer to each page(bitplane) being on its own.
- Huhh, that would go pretty much into details; a bit simplified, "chained" means
- that the bitplanes mentioned above are "glued" together for the simple BIOS
- mode, so that bitplane switching isn't necessary anymore (that is equivalent in
- saying that one VRAM address refers to one RAM cell). As there are only 65536
- addresses in the $A000 segment and we need 320x200=64000 for a full page, you
- only have 65536/64000=1.024 pages therefore. "Unchaining" means to make each
- bitplane accessible explicitely.
-
- > Now here is another problem I don't understand. I am familiar with VGA's
- > mode 13h which has one byte specifying each pixel on the screen,
- > therefore 1 byte = 1 pixel. But this takes up 64k.
-
- Small note on this: not 64K, but only 64000 bytes!
-
- > But how do you have one address represent 4 pixels, which only occupies
- > 16000 address bytes, and still be able to specify 256 colours. Won't 4
- > bitplanes at 320x200 each take up 64000x4 bytes of space?
-
- We have 320x200=64000 pixels=64000 bytes. As each 4 pixels share one address,
- 16000 address bytes per page suffice. The $A000 segment has 64K address bytes,
- thus 4*64K=256K VRAM can be addressed. 64K address bytes = 65536 address bytes;
- 65536/16000 = 4.096 pages.
-
- > How would you go about adjusting the vertical retraces, and memory
- > location you mentioned.
-
- Assuming that the DX-register has been set to 3DAh or 3BAh for color/monochrome
- display, respectively, you can trace the status of the electronic beam like
- this:
-
- @WaitNotVSyncLoop:
- in al, dx
- and al, 8
- jnz @WaitNotVSyncLoop
- @WaitVSyncLoop:
- in al, dx
- and al, 8
- jz @WaitVSyncLoop
- {now change the starting address}
- {
- (If you use "1" instead of "8" and exchange "jz" <-> "jnz" and vice vs., then
- you sync on the shorter horizontal retrace (better: horizontal _enable_)
- signal).
- The alteration of the starting address is done by the code I already posted in
- my first mail! (Its done by addressing the registers $C and $D of the
- CRT-controller).
- Note that reprogramming the starting address isn't restricted to mode X/Y, you
- can have it in normal mode 13h, too: there are 65536 addresses available, but
- only 64000 needed, thus giving a scroll range of 4.8 lines! And to complicate
- things even further, for start addressing purposes, even the BIOS mode is
- planed (that is, a row consists of 320/4 bytes only). Just for the case you
- don't believe...
- }
- PROGRAM Scroll;
- VAR
- CRTAddress,
- StatusReg : WORD;
- a : ARRAY[0..199, 0..319] OF BYTE ABSOLUTE $A000 : 0000;
- i, j : WORD;
-
- PROCEDURE SetAddress(ad : WORD); ASSEMBLER;
- ASM
- MOV BX, ad
-
- MOV DX, StatusReg
- @WaitNotVSyncLoop:
- in al, dx
- and al, 8
- jnz @WaitNotVSyncLoop
- @WaitVSyncLoop:
- in al, dx
- and al, 8
- jz @WaitVSyncLoop
-
- MOV DX, CRTAddress
- MOV AL, $0D
- CLI
- OUT DX, AL
- INC DX
- MOV AL, BL
- OUT DX, AL
- DEC DX
- MOV AL, $0C
- OUT DX, AL
- INC DX
- MOV AL, BH
- OUT DX, AL
- STI
- END;
-
- BEGIN
- IF ODD(port[$3CC]) THEN
- CRTAddress := $3D4
- ELSE
- CRTAddress := $3B4;
-
- StatusReg := CRTAddress + 6;
- ASM
- MOV AX,13h
- INT 10h
- END;
-
- FOR i := 1 TO 1000 DO
- a[Random(200), Random(320)] := Random(256);
-
- {scroll horizontally by 4 pixels}
- FOR i := 1 TO 383 DO
- SetAddress(i);
- FOR i := 382 DOWNTO 0 DO
- SetAddress(i);
-
- {scroll vertically by 1 row}
- FOR j := 1 TO 20 DO
- BEGIN
- FOR i := 1 TO 4 DO
- SetAddress(i * 80);
- FOR i := 3 DOWNTO 0 DO
- SetAddress(i * 80)
- END;
-
- ASM {back to 80x25}
- MOV AX,3
- INT 10h
- END;
-
- END.
- {
- > Your said you could specify how the memory can be layed out by the user,
- > but I am in need of what each PORT does. I know you have to send
- > different values to the port to program it, but I have no idea what each
- > port reads.
-
- There are incredibly much registers to program! For a good overview of most of
- them, try to get your hands on a copy of VGADOC*.* by Finn Thoegersen
- (jesperf@daimi.aau.dk) which covers programming a lot of SVGA's chipsets, too.
-