Difference between revisions of "AGI/Specifications/Other/AGI256/Implementation Details"

Jump to navigation Jump to search
Fixed a typo. Hadn't put & in front of some code where it should have been.
(Completed disassembly of AGIOBJS.OVL)
(Fixed a typo. Hadn't put & in front of some code where it should have been.)
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
In the original PC AGI interpreter v2.936 the engine holds the color and priority/control
In the original PC AGI interpreter v2.936 the engine holds the color and priority/control
line information for each pixel in a 160x200 byte buffer. The color data for each pixel
line information for each pixel in a 160x168 byte buffer. The color data for each pixel
is held in the byte's lower 4 bits and the priority/control line data is held in the upper
is held in the byte's lower 4 bits and the priority/control line data is held in the upper
4 bits.
4 bits.


AGI256 extends this 160x200 byte buffer to a 320x200 byte buffer so that the 256-color
AGI256 extends this 160x168 byte buffer to a 320x168 byte buffer so that the 256-color
data is held in the right 160x200 half of the buffer and the original style 16-color and
data is held in the right 160x168 half of the buffer and the original style 16-color and
priority/control line information is held in the left 160x200 half of the buffer.
priority/control line information is held in the left 160x168 half of the buffer.
 
When loading 256-color picture resource with the unknown170 command
the picture is loaded straight into the right 160x168 half of the 320x168 memory buffer.
 
Cel blitting routine is modified so that when sprite data would normally be written
to a position (x, y) in the 16-color buffer (i.e. the left 160x168 half) it's actually
written to the same position (x, y) but in the 256-color buffer (i.e. the right 160x168 half).


==Used external info==
==Used external info==
Line 24: Line 31:
* AGI.EXE
* AGI.EXE
* AGIDATA.OVL
* AGIDATA.OVL
===Reverse engineered C version of AGI256's AGIOBJS.OVL===
Things may be wrong, misleading etc. Caveat emptor.
This is the cel blitting routine from AGIOBJS.OVL.
<pre>
struct blitStruct {
uint8 b0;
uint8 b1;
uint8 notEgo; // Sort of a guess based on variable's usage, may also be dontUpdateEgoVisibility or something like that
uint16 xPos;
uint16 yPos; // Is this named correctly?
uint8 b7;
uint8 b8;
uint8 b9;
uint8 b10;
uint8 b11;
uint8 b12;
uint8 b13;
uint8 b14;
uint8 b15;
struct celStruct *celPtr; // Offset into segment DS really, 16 bits
uint8 b18;
uint8 b19;
uint8 b20;
uint8 b21;
uint8 b22;
uint8 b23;
uint8 b24;
uint8 b25;
uint8 b26;
uint8 b27;
uint8 b28;
uint8 b29;
uint8 b30;
uint8 b31;
uint8 b32;
uint8 b33;
uint8 b34;
uint8 b35;
uint8 celPriority;
};
struct celStruct {
uint8 width; // This is a guess
uint8 height;
union {
uint8 flags; // Uses values from enum flagsEnum
uint8 transparentColor; // Only lower 4 bits
};
uint8 rleData[?];
};
enum flagsEnum {
F_MIRROR = 1 << 7;
};
#define _WIDTH 160
#define _HEIGHT 168
uint16 screenOffset(uint8 x, uint8 y) {
return y * (_WIDTH * 2) + x;
}
void agi256BlitCel(struct blitStruct *s) {
uint8 *pic = &agi256PicSeg[0];
const uint16 endPos = (_WIDTH * 2) * (_HEIGHT - 1); // I would have put (((_WIDTH * 2) * (_HEIGHT - 1)) - _WIDTH) here
bool celInvisible = true;
uint8 height = s->celPtr->height;
uint8 celPriority = s->celPriority;
if (s->celPtr->flags & F_MIRROR) // Test for mirroring
blitMirrorCell();
uint8 *rleData = s->celPtr->rleData;
uint16 pos = screenOffset(s->xPos, s->yPos - height + 1);
uint8 transparentColor = s->celPtr->transparentColor;
do {
uint16 oldPos = pos;
while (uint8 rleByte = *(rleData++)) { // rleByte != 0
uint8 runColor = rleByte >> 4;
uint8 runLength = rleByte & 0x0f;
if (runColor == transparentColor) { // Check for transparency
pos += runLength;
} else do {
uint8 pixelPriority = pic[pos] >> 4; // Read pixel's priority/control line info
if (pixelPriority < 3) {
pixelPriority = 0;
for (uint16 ySearchPos = pos + _WIDTH * 2;
ySearchPos < endPos && (pixelPriority = pic[ySearchPos] >> 4) < 3;
ySearchPos += _WIDTH * 2);
}
if (celPriority >= pixelPriority) {
pic[pos + _WIDTH] = runColor;
celInvisible = false;
}
pos++;
} while (--runLength > 0);
}
pos = oldPos + _WIDTH * 2;
} while (--height > 0);
if (!s->notEgo)
setFlag(f1, celInvisible);
}
</pre>
===Differences between AGI v2.936's AGIDATA.OVL and AGI256's AGIDATA.OVL===
<pre>
dseg:0x08C5: dw offset CmdUnknown170
</pre>
Unknown170 command's subroutine's location has been
changed from the original 0x2726 to hacked 0x9975.
0x9975 goes beyond what is in AGI.EXE so
it goes to point to the AGIGRAF.OVL's functions.
AGIGRAF.OVL is loaded into cseg:0x9800 so taking
away the displacement we get 0x9975-0x9800 = 0x175.
See the AGIGRAF.OVL disassembly for more details
about the function that this points to.
===Disassembly of AGIGRAF.OVL===
<pre>
codeseg:9800 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9800
codeseg:9800 ; AGIGRAF.OVL starts here at 0x9800
codeseg:9800 ; Attributes: thunk
codeseg:9800
codeseg:9800 j_AG_setGrafMode proc near              ; CODE XREF: sub_5528+14�p
codeseg:9800                jmp    AG_setGrafMode  ; In Sonneveld's Agi2917.idb there was j_EGAGrafMode here.
codeseg:9800 j_AG_setGrafMode endp                  ;
codeseg:9800                                        ; Sets 320x200 256 color video mode (Mode 13h),
codeseg:9800                                        ; sets ds:[videoOfs] to 0xA000 and
codeseg:9800                                        ; clears first 64 KiB of video memory with zeroes.
codeseg:9803
codeseg:9803 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9803
codeseg:9803 ; Attributes: thunk
codeseg:9803
codeseg:9803 j_AG_setTextMode proc near              ; CODE XREF: cmd_text_screen_106+1E�p
codeseg:9803                jmp    AG_setTextMode  ; In Sonneveld's Agi2917.idb there was j_EGATextMode here.
codeseg:9803 j_AG_setTextMode endp                  ;
codeseg:9803                                        ; Sets 40x25 16 color text mode,
codeseg:9803                                        ; enables background intensity (Colors 8-15),
codeseg:9803                                        ; sets some cursor stuff and
codeseg:9803                                        ; clears the text screen using ds:[textClrAttr] attribute.
codeseg:9806
codeseg:9806 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9806
codeseg:9806 ; Attributes: thunk
codeseg:9806
codeseg:9806 j_AG_agi256ShowPic proc near            ; CODE XREF: sub_78CB+18�p
codeseg:9806                jmp    AG_agi256ShowPic ; In Sonneveld's Agi2917.idb there was j_EGAShowPic here.
codeseg:9806 j_AG_agi256ShowPic endp                ;
codeseg:9806                                        ; Sets the 320x200 256 color video mode,
codeseg:9806                                        ; clears screen etc (Look at setVideoMode)
codeseg:9806                                        ; and calls an unknown function.
codeseg:9809
codeseg:9809 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9809
codeseg:9809 ; Attributes: thunk
codeseg:9809
codeseg:9809 j_AG_emptyFunc4 proc near
codeseg:9809                jmp    AG_emptyFunc4  ; In Sonneveld's Agi2917.idb there was an empty function here too.
codeseg:9809 j_AG_emptyFunc4 endp                    ;
codeseg:9809                                        ; Does nothing. Don't know what functionality
codeseg:9809                                        ; would have been here in the original AGI interpreter.
codeseg:9809                                        ; Maybe something to do with other than EGA graphics adapters?
codeseg:980C
codeseg:980C ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:980C
codeseg:980C ; Attributes: thunk
codeseg:980C
codeseg:980C j_AG_agi256PutBlock proc near          ; CODE XREF: _Pic_Show+40�p
codeseg:980C                                        ; sub_560C+E�p ...
codeseg:980C                jmp    AG_agi256PutBlock ; In Sonneveld's Agi2917.idb there was j_EGAPutBlock here.
codeseg:980C j_AG_agi256PutBlock endp                ;
codeseg:980C                                        ; Shows an AGI 256 picture (Puts it into video memory).
codeseg:980C                                        ; Uses x2 horizontal stretching.
codeseg:980F
codeseg:980F ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:980F
codeseg:980F ; Attributes: thunk
codeseg:980F
codeseg:980F j_AG_calcHeightLUT proc near            ; CODE XREF: sub_5528+E�p
codeseg:980F                jmp    AG_calcHeightLUT ; In Sonneveld's Agi2917.idb there was j_EGAInit here.
codeseg:980F j_AG_calcHeightLUT endp                ;
codeseg:980F                                        ; Precalculates table for Y*320 values (0 <= y < 200)
codeseg:9812
codeseg:9812 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9812
codeseg:9812 ; Attributes: thunk
codeseg:9812
codeseg:9812 j_AG_agi256FilledRect proc near        ; CODE XREF: _BoxNBorder+11�p
codeseg:9812                                        ; _BoxNBorder+28�p ...
codeseg:9812                jmp    AG_agi256FilledRect ; In Sonneveld's Agi2917.idb there was j_EGAFilledRect here.
codeseg:9812 j_AG_agi256FilledRect endp              ;
codeseg:9812                                        ; Fills a solid rectangle in video memory with a given fill color.
codeseg:9812                                        ; Inputs:
codeseg:9812                                        ; DL = fill color
codeseg:9812                                        ; AL = yPos ?? (More like last row)
codeseg:9812                                        ; AH = xPos
codeseg:9812                                        ; BH = yLen
codeseg:9812                                        ; BL = xLen
codeseg:9815
codeseg:9815 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9815
codeseg:9815 ; In Sonneveld's Agi2917.idb there was j_EGAGrafMode here.
codeseg:9815 ;
codeseg:9815 ; Sets 320x200 256 color video mode (Mode 13h),
codeseg:9815 ; sets ds:[videoOfs] to 0xA000 and
codeseg:9815 ; clears first 64 KiB of video memory with zeroes.
codeseg:9815
codeseg:9815 AG_setGrafMode  proc near              ; CODE XREF: j_AG_setGrafMode�j
codeseg:9815                                        ; AG_agi256ShowPic+8�p
codeseg:9815                mov    ax, 13h
codeseg:9818                int    10h            ; - VIDEO - SET VIDEO MODE
codeseg:9818                                        ; AL = mode
codeseg:981A                mov    bx, 0A000h
codeseg:981D                mov    videoSeg, bx
codeseg:9821                nop
codeseg:9822                nop
codeseg:9823                nop
codeseg:9824                nop
codeseg:9825                nop
codeseg:9826                nop
codeseg:9827                push    es
codeseg:9828                mov    es, videoSeg
codeseg:982C                xor    ax, ax
codeseg:982E                mov    di, ax
codeseg:9830                mov    cx, 8000h
codeseg:9833                repe stosw
codeseg:9835                pop    es
codeseg:9836                retn
codeseg:9836 AG_setGrafMode  endp
codeseg:9836
codeseg:9837
codeseg:9837 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9837
codeseg:9837 ; In Sonneveld's Agi2917.idb there was j_EGATextMode here.
codeseg:9837 ;
codeseg:9837 ; Sets 40x25 16 color text mode,
codeseg:9837 ; enables background intensity (Colors 8-15),
codeseg:9837 ; sets some cursor stuff and
codeseg:9837 ; clears the text screen using ds:[textClrAttr] attribute.
codeseg:9837 ; Attributes: bp-based frame
codeseg:9837
codeseg:9837 AG_setTextMode  proc near              ; CODE XREF: j_AG_setTextMode�j
codeseg:9837                push    si
codeseg:9838                push    di
codeseg:9839                push    bp
codeseg:983A                mov    bp, sp
codeseg:983C                sub    sp, 2
codeseg:983F                mov    ax, 1          ; Set 40x25 16 color text (AH = 0, AL = 1)
codeseg:9842                int    10h            ; - VIDEO - SET VIDEO MODE
codeseg:9842                                        ; AL = mode
codeseg:9844                mov    ax, 1003h
codeseg:9847                xor    bx, bx          ; Disable blinking i.e. enable background intensity (Colors 8-15).
codeseg:9849                int    10h            ; - VIDEO - TOGGLE INTENSITY/BLINKING BIT (Jr, PS, TANDY 1000, EGA, VGA)
codeseg:9849                                        ; BL = 00h enable background intensity
codeseg:9849                                        ; = 01h enable blink
codeseg:984B                mov    cx, 3000h
codeseg:984E                mov    ah, 1
codeseg:9850                int    10h            ; - VIDEO - SET CURSOR CHARACTERISTICS
codeseg:9850                                        ; CH bits 0-4 = start line for cursor in character cell
codeseg:9850                                        ; bits 5-6 = blink attribute
codeseg:9850                                        ; CL bits 0-4 = end line for cursor in character cell
codeseg:9852                xor    bh, bh
codeseg:9854                xor    dx, dx
codeseg:9856                mov    ah, 2
codeseg:9858                int    10h            ; - VIDEO - SET CURSOR POSITION
codeseg:9858                                        ; DH,DL = row, column (0,0 = upper left)
codeseg:9858                                        ; BH = page number
codeseg:985A                mov    bh, byte ptr textClrAttr
codeseg:985E                xor    al, al          ; AL = 0 = blank whole window
codeseg:9860                xor    cx, cx          ; CH = row 0
codeseg:9860                                        ; CL = column 0
codeseg:9862                mov    dx, 1827h      ; DH = row 24
codeseg:9862                                        ; DL = column 39
codeseg:9865                mov    ah, 6
codeseg:9867                int    10h            ; - VIDEO - SCROLL PAGE UP
codeseg:9867                                        ; AL = number of lines to scroll window (0 = blank whole window)
codeseg:9867                                        ; BH = attributes to be used on blanked lines
codeseg:9867                                        ; CH,CL = row,column of upper left corner of window to scroll
codeseg:9867                                        ; DH,DL = row,column of lower right corner of window
codeseg:9869                add    sp, 2
codeseg:986C                pop    bp
codeseg:986D                pop    di
codeseg:986E                pop    si
codeseg:986F                retn
codeseg:986F AG_setTextMode  endp
codeseg:986F
codeseg:9870
codeseg:9870 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9870
codeseg:9870 ; In Sonneveld's Agi2917.idb there was j_EGAShowPic here.
codeseg:9870 ;
codeseg:9870 ; Sets the 320x200 256 color video mode,
codeseg:9870 ; clears screen etc (Look at setVideoMode)
codeseg:9870 ; and calls an unknown function.
codeseg:9870 ; Attributes: bp-based frame
codeseg:9870
codeseg:9870 AG_agi256ShowPic proc near              ; CODE XREF: j_AG_agi256ShowPic�j
codeseg:9870                push    si
codeseg:9871                push    di
codeseg:9872                push    bp
codeseg:9873                mov    bp, sp
codeseg:9875                sub    sp, 2
codeseg:9878                call    AG_setGrafMode  ; In Sonneveld's Agi2917.idb there was j_EGAGrafMode here.
codeseg:9878                                        ;
codeseg:9878                                        ; Sets 320x200 256 color video mode (Mode 13h),
codeseg:9878                                        ; sets ds:[videoOfs] to 0xA000 and
codeseg:9878                                        ; clears first 64 KiB of video memory with zeroes.
codeseg:987B                call    _Pic_Show      ; Was _Pic_Show in Agi2917.idb
codeseg:987E                add    sp, 2
codeseg:9881                pop    bp
codeseg:9882                pop    di
codeseg:9883                pop    si
codeseg:9884                retn
codeseg:9884 AG_agi256ShowPic endp
codeseg:9884
codeseg:9885
codeseg:9885 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9885
codeseg:9885 ; In Sonneveld's Agi2917.idb there was an empty function here too.
codeseg:9885 ;
codeseg:9885 ; Does nothing. Don't know what functionality
codeseg:9885 ; would have been here in the original AGI interpreter.
codeseg:9885 ; Maybe something to do with other than EGA graphics adapters?
codeseg:9885
codeseg:9885 AG_emptyFunc4  proc near              ; CODE XREF: j_AG_emptyFunc4�j
codeseg:9885                retn
codeseg:9885 AG_emptyFunc4  endp
codeseg:9885
codeseg:9886
codeseg:9886 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9886
codeseg:9886 ; In Sonneveld's Agi2917.idb there was j_EGAPutBlock here.
codeseg:9886 ;
codeseg:9886 ; Shows an AGI 256 picture (Puts it into video memory).
codeseg:9886 ; Uses x2 horizontal stretching.
codeseg:9886
codeseg:9886 AG_agi256PutBlock proc near            ; CODE XREF: j_AG_agi256PutBlock�j
codeseg:9886
codeseg:9886 xPos            = ah                    ; Use case: 0
codeseg:9886 yPos            = al                    ; Use case: 167 (Is this register named correctly??)
codeseg:9886 xLen            = bl                    ; Use case: 160
codeseg:9886 yLen            = bh                    ; Use case: 168
codeseg:9886
codeseg:9886                test    xPos, 1
codeseg:9889                jz      xPosEven
codeseg:988B                dec    xPos            ; xPos wasn't even, so make it even by decreasing it by one
codeseg:988D                inc    xLen
codeseg:988F
codeseg:988F xPosEven:                              ; CODE XREF: AG_agi256PutBlock+3�j
codeseg:988F                inc    xLen
codeseg:9891                and    xLen, 11111110b ; Make xLen even
codeseg:9894                mov    cx, bx
codeseg:9896                sub    yPos, yLen
codeseg:9898
codeseg:9898 loc_9898:                              ; CODE XREF: sub_5257+14�p
codeseg:9898                                        ; _Pic_Show+35�p ...
codeseg:9898                inc    yPos            ; Some Hercules code used to be at codeseg:0x9899
codeseg:9898                                        ; but isn't anymore. It's shouldn't be called in AGI256 at all.
codeseg:989A
codeseg:989A loc_989A:                              ; Calculates the screen offset for given coordinate? Video or AGI screen offset?
codeseg:989A                call    screenOffset    ; DI = AL * 320 + AH
codeseg:989A                                        ; (Destroys BX contents (Returns with BH = 0, BL = AH))
codeseg:989A                                        ;
codeseg:989A                                        ; Maybe not named quite correctly?
codeseg:989D                mov    si, di
codeseg:989F                call    agiToScreenCoords ; Calculates (baseY+Y)*320 + X*2
codeseg:989F                                        ;
codeseg:989F                                        ; Inputs: AL = Y, AH = X
codeseg:989F                                        ; Reads from DS:[byte_B389] = baseY
codeseg:989F                                        ; (Actually reads baseY as a word, but uses it like
codeseg:989F                                        ; it can't overflow to over 8 bits when adding Y to it)
codeseg:989F                                        ; Returns: DI = heightLUT[baseY+Y] + X*2 = (baseY+Y)*320 + X*2
codeseg:989F                                        ; (Side-effects: BH = 0, BL = AH = X)
codeseg:98A2                jmp    AG_convCoord    ; Input: CX
codeseg:98A2 AG_agi256PutBlock endp                  ; BH = CH = Y
codeseg:98A2                                        ; BL = CL/2 = X / 2
codeseg:98A2                                        ; SI += 160 (Go to right half of the 320x168 area)
codeseg:98A2                                        ; goto AG_stretchToScreen
codeseg:98A5 ; ---------------------------------------------------------------------------
codeseg:98A5                nop
codeseg:98A6
codeseg:98A6 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:98A6
codeseg:98A6 ; Copies data from agi256 picture segment to video memory with x2 horizontal stretching.
codeseg:98A6 ; Both source and destination buffers use a stride/pitch of 320 bytes.
codeseg:98A6 ; Inputs:
codeseg:98A6 ; BL = xLen
codeseg:98A6 ; BH = yLen
codeseg:98A6 ; SI = srcOffset
codeseg:98A6 ; DI = destOffset
codeseg:98A6
codeseg:98A6 AG_stretchToScreen proc near            ; CODE XREF: AG_convCoord+8�j
codeseg:98A6
codeseg:98A6 xLen            = bl
codeseg:98A6 yLen            = bh
codeseg:98A6 xCounterHi      = ch
codeseg:98A6 xCounterLo      = cl
codeseg:98A6
codeseg:98A6                push    ds
codeseg:98A7                push    es
codeseg:98A8                mov    es, videoSeg
codeseg:98AC                mov    ds, agi256PicSeg
codeseg:98B0
codeseg:98B0 yLoop:                                  ; CODE XREF: AG_stretchToScreen+2E�j
codeseg:98B0                xor    xCounterHi, xCounterHi ; Stretches source AGI 256 picture into video memory
codeseg:98B0                                        ; (Doubles the width of the picture, so 160 becomes 320 etc).
codeseg:98B0                                        ; BL = source width (Probably 160)?
codeseg:98B0                                        ; BH = source height (Probably 168)?
codeseg:98B2                mov    xCounterLo, xLen
codeseg:98B4                push    di
codeseg:98B5                push    si
codeseg:98B6
codeseg:98B6 xLoop:                                  ; CODE XREF: AG_stretchToScreen+1E�j
codeseg:98B6                lodsw                  ; Read word from AGI 256 picture buffer
codeseg:98B7                nop
codeseg:98B8                nop
codeseg:98B9                nop
codeseg:98BA                mov    dl, ah
codeseg:98BC                mov    ah, al
codeseg:98BE                stosw                  ; Put first read byte twice into video memory
codeseg:98BF                mov    al, dl
codeseg:98C1                mov    ah, al
codeseg:98C3                stosw                  ; Put second read byte twice into video memory
codeseg:98C4                loop    xLoop          ; Loop xCounterLo times (xCounterHi is zero)
codeseg:98C6                pop    si
codeseg:98C7                pop    di
codeseg:98C8                dec    yLen
codeseg:98CA                jz      end
codeseg:98CC                add    si, 320        ; Figuring that source image width is 160 and still its pointer
codeseg:98CC                                        ; is added by 320 rather than 160 when going to the next line...
codeseg:98CC                                        ; it might make sense if the priorities are 160 wide per row as well
codeseg:98CC                                        ; and a row of picture data is always followed by a row of priority data.
codeseg:98D0                add    di, 320
codeseg:98D4                jmp    short yLoop    ; Stretches source AGI 256 picture into video memory
codeseg:98D4                                        ; (Doubles the width of the picture, so 160 becomes 320 etc).
codeseg:98D4                                        ; BL = source width (Probably 160)?
codeseg:98D4                                        ; BH = source height (Probably 168)?
codeseg:98D6 ; ---------------------------------------------------------------------------
codeseg:98D6
codeseg:98D6 end:                                    ; CODE XREF: AG_stretchToScreen+24�j
codeseg:98D6                pop    es
codeseg:98D7                pop    ds
codeseg:98D8                retn
codeseg:98D8 AG_stretchToScreen endp
codeseg:98D8
codeseg:98D9
codeseg:98D9 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:98D9
codeseg:98D9 ; In Sonneveld's Agi2917.idb there was j_EGAFilledRect here.
codeseg:98D9 ;
codeseg:98D9 ; Fills a solid rectangle in video memory with a given fill color.
codeseg:98D9 ; Inputs:
codeseg:98D9 ; DL = fill color
codeseg:98D9 ; AL = yPos ?? (More like last row)
codeseg:98D9 ; AH = xPos
codeseg:98D9 ; BH = yLen
codeseg:98D9 ; BL = xLen
codeseg:98D9
codeseg:98D9 AG_agi256FilledRect proc near          ; CODE XREF: j_AG_agi256FilledRect�j
codeseg:98D9
codeseg:98D9 yLen            = bh
codeseg:98D9 xLen            = bl
codeseg:98D9
codeseg:98D9                push    es
codeseg:98DA                mov    es, videoSeg
codeseg:98DE                mov    dh, dl
codeseg:98E0                sub    al, yLen
codeseg:98E2                inc    al
codeseg:98E4                mov    cx, bx
codeseg:98E6                call    agiToScreenCoords ; Calculates (baseY+Y)*320 + X*2
codeseg:98E6                                        ;
codeseg:98E6                                        ; Inputs: AL = Y, AH = X
codeseg:98E6                                        ; Reads from DS:[byte_B389] = baseY
codeseg:98E6                                        ; (Actually reads baseY as a word, but uses it like
codeseg:98E6                                        ; it can't overflow to over 8 bits when adding Y to it)
codeseg:98E6                                        ; Returns: DI = heightLUT[baseY+Y] + X*2 = (baseY+Y)*320 + X*2
codeseg:98E6                                        ; (Side-effects: BH = 0, BL = AH = X)
codeseg:98E9                mov    bx, cx
codeseg:98EB                mov    ax, dx
codeseg:98ED                mov    dx, 320
codeseg:98F0                xor    ch, ch
codeseg:98F2                sub    dx, cx
codeseg:98F4                sub    dx, cx
codeseg:98F6
codeseg:98F6 xLoop:                                  ; CODE XREF: AG_agi256FilledRect+27�j
codeseg:98F6                mov    cl, xLen
codeseg:98F8                repe stosw
codeseg:98FA                dec    yLen
codeseg:98FC                jz      end
codeseg:98FE                add    di, dx
codeseg:9900                jmp    short xLoop
codeseg:9902 ; ---------------------------------------------------------------------------
codeseg:9902
codeseg:9902 end:                                    ; CODE XREF: AG_agi256FilledRect+23�j
codeseg:9902                pop    es
codeseg:9903                retn
codeseg:9903 AG_agi256FilledRect endp
codeseg:9903
codeseg:9904
codeseg:9904 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9904
codeseg:9904 ; In Sonneveld's Agi2917.idb there was j_EGAInit here.
codeseg:9904 ;
codeseg:9904 ; Precalculates table for Y*320 values (0 <= y < 200)
codeseg:9904
codeseg:9904 AG_calcHeightLUT proc near              ; CODE XREF: j_AG_calcHeightLUT�j
codeseg:9904                lea    di, ds:heightLUT
codeseg:9908                mov    ax, 0
codeseg:990B                mov    dx, 200
codeseg:990E
codeseg:990E mulWidthLoop:                          ; CODE XREF: AG_calcHeightLUT+F�j
codeseg:990E                stosw
codeseg:990F                add    ax, 320
codeseg:9912                dec    dx
codeseg:9913                jnz    mulWidthLoop
codeseg:9915                retn
codeseg:9915 AG_calcHeightLUT endp
codeseg:9915
codeseg:9916
codeseg:9916 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9916
codeseg:9916 ; To me this seems to blink the colors on the screen
codeseg:9916 ; syncronized to some event.
codeseg:9916 ;
codeseg:9916 ; setPalette(uint16 cx) {
codeseg:9916 ;  read 16 colors from video card to ds:[palette]
codeseg:9916 ;
codeseg:9916 ;  for (int z = 0; z < cx; z++) {
codeseg:9916 ;    for (int y = 0; y < 20; y++) {
codeseg:9916 ;      for (int i=0; i < 16*3; i++) {
codeseg:9916 ;        ds:palette[i] ^= 0xff; // Inverts palette
codeseg:9916 ;      }
codeseg:9916 ;      write 16 colors to video card from ds:[palette]
codeseg:9916 ;      wait for word_A139 to change (Loop until it does)
codeseg:9916 ;    }
codeseg:9916 ;  }
codeseg:9916 ; }
codeseg:9916
codeseg:9916 AG_blinkScreen  proc near              ; CODE XREF: cmd_shake_screen_110+2F�p
codeseg:9916                push    bx
codeseg:9917                push    si
codeseg:9918                push    di
codeseg:9919                push    es
codeseg:991A                push    dx
codeseg:991B                mov    ax, ds
codeseg:991D                mov    es, ax
codeseg:991F                push    cx
codeseg:9920                mov    dx, offset palette
codeseg:9923                xor    bx, bx
codeseg:9925                mov    cx, 16          ; Read first 16 colors from video card
codeseg:9928                mov    al, 17h
codeseg:992A                mov    ah, 10h
codeseg:992C                int    10h            ; - VIDEO - READ BLOCK OF DAC REGISTERS (EGA, VGA/MCGA)
codeseg:992C                                        ; BX = starting palette register, CX = number of palette registers to read
codeseg:992C                                        ; ES:DX -> buffer (3 * CX bytes in size)
codeseg:992C                                        ; Return: CX number of red, green and blue triples in buffer
codeseg:992E                pop    cx
codeseg:992F
codeseg:992F outerLoop:                              ; CODE XREF: AG_blinkScreen+4C�j
codeseg:992F                push    cx              ; At first run, CX's value at function start is pushed
codeseg:9930                mov    cx, 20
codeseg:9933
codeseg:9933 loop20Times:                            ; CODE XREF: AG_blinkScreen+49�j
codeseg:9933                push    cx              ; At first run, 20 is pushed
codeseg:9934                mov    bx, 47          ; 48/3 = 16 (Dealing with triples here)
codeseg:9937                mov    al, 0FFh
codeseg:9939
codeseg:9939 invertPalette:                          ; CODE XREF: AG_blinkScreen+28�j
codeseg:9939                xor    palette[bx], al ; Inverts 16 colors in palette and writes them to video card DAC
codeseg:993D                dec    bx
codeseg:993E                jns    invertPalette  ; Inverts 16 colors in palette and writes them to video card DAC
codeseg:9940                mov    dx, offset palette
codeseg:9943                xor    bx, bx
codeseg:9945                mov    cx, 16
codeseg:9948                mov    al, 12h
codeseg:994A                mov    ah, 10h
codeseg:994C                int    10h            ; - VIDEO - SET BLOCK OF DAC REGISTERS (EGA, VGA/MCGA)
codeseg:994C                                        ; BX = starting color register, CX = number of registers to set
codeseg:994C                                        ; ES:DX -> table of 3*CX bytes where each 3 byte group represents one
codeseg:994C                                        ; byte each of red, green and blue (0-63)
codeseg:994E                mov    cx, 1
codeseg:9951
codeseg:9951 neverLoopsHere:                        ; CODE XREF: AG_blinkScreen+46�j
codeseg:9951                mov    bx, word_A139
codeseg:9955
codeseg:9955 waitForChange:                          ; CODE XREF: AG_blinkScreen+43�j
codeseg:9955                cmp    bx, word_A139
codeseg:9959                jz      waitForChange
codeseg:995B                dec    cx
codeseg:995C                jnz    neverLoopsHere  ; This seems to never loop, so why is it here at all?
codeseg:995E                pop    cx
codeseg:995F                loop    loop20Times    ; At first run, 20 is pushed
codeseg:9961                pop    cx
codeseg:9962                loop    outerLoop      ; At first run, CX's value at function start is pushed
codeseg:9964                pop    dx
codeseg:9965                pop    es
codeseg:9966                pop    di
codeseg:9967                pop    si
codeseg:9968                pop    bx
codeseg:9969                retn
codeseg:9969 AG_blinkScreen  endp
codeseg:9969
codeseg:996A
codeseg:996A ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:996A
codeseg:996A ; Input: CX
codeseg:996A ; BH = CH = Y
codeseg:996A ; BL = CL/2 = X / 2
codeseg:996A ; SI += 160 (Go to right half of the 320x168 area)
codeseg:996A ; goto AG_stretchToScreen
codeseg:996A
codeseg:996A AG_convCoord    proc near              ; CODE XREF: AG_agi256PutBlock+1C�j
codeseg:996A                mov    bx, cx
codeseg:996C                shr    bl, 1
codeseg:996E                add    si, 160
codeseg:9972                jmp    AG_stretchToScreen ; Copies data from agi256 picture segment to video memory with x2 horizontal stretching.
codeseg:9972 AG_convCoord    endp                    ; Both source and destination buffers use a stride/pitch of 320 bytes.
codeseg:9972                                        ; Inputs:
codeseg:9972                                        ; BL = xLen
codeseg:9972                                        ; BH = yLen
codeseg:9972                                        ; SI = srcOffset
codeseg:9972                                        ; DI = destOffset
codeseg:9975
codeseg:9975 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9975
codeseg:9975 ; Command unknown 170
codeseg:9975 ;
codeseg:9975 ; In AGIDATA.OVL at offset 0x08C5 there's
codeseg:9975 ; dw offset CmdUnknown170 and now
codeseg:9975 ; it's 0x9975 which points to 0x9800 + 0x175,
codeseg:9975 ; so it's 0x175 in this file. So it points to this function.
codeseg:9975 ;
codeseg:9975 ; uint16 *cmdUnknown170(uint16 *varNum) { 
codeseg:9975 ;  uint8 var = agiVar[*varNum];
codeseg:9975 ;  AG_readAgi256Pic(var);
codeseg:9975 ;  return ++varNum;
codeseg:9975 ; }
codeseg:9975 ; Attributes: bp-based frame
codeseg:9975
codeseg:9975 AG_cmd_set_simple_170 proc near        ; DATA XREF: dataseg:08C5�o
codeseg:9975
codeseg:9975 varNum          = word ptr  8
codeseg:9975
codeseg:9975                push    si
codeseg:9976                push    di
codeseg:9977                push    bp
codeseg:9978                mov    bp, sp
codeseg:997A                mov    di, [bp+varNum] ; DI = varNum
codeseg:997D                inc    [bp+varNum]    ; varNum++
codeseg:9980                mov    al, [di]        ; AL = [DS:DI] = [old varNum]
codeseg:9982                sub    ah, ah          ; AX = zero_extend(AL)
codeseg:9984                mov    di, ax          ; DI = [old varNum]
codeseg:9986                mov    al, agiVar[di]  ; AL = agiVar[[old varNum]]
codeseg:998A                sub    ah, ah
codeseg:998C                push    ax
codeseg:998D                call    AG_readAgi256Pic ; Reads an AGI 256 picture with the given number to
codeseg:998D                                        ; agi256PicSeg so that the picture is a 160x168 picture in
codeseg:998D                                        ; a 320x168 area, but in the right half of it
codeseg:998D                                        ; (i.e. 168 <= x < 320 and 0 <= y < 168)
codeseg:9990                add    sp, 2
codeseg:9993                mov    ax, [bp+varNum]
codeseg:9996                pop    bp
codeseg:9997                pop    di
codeseg:9998                pop    si
codeseg:9999                retn
codeseg:9999 AG_cmd_set_simple_170 endp
codeseg:9999
codeseg:999A
codeseg:999A ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:999A
codeseg:999A ; Reads an AGI 256 picture with the given number to
codeseg:999A ; agi256PicSeg so that the picture is a 160x168 picture in
codeseg:999A ; a 320x168 area, but in the right half of it
codeseg:999A ; (i.e. 168 <= x < 320 and 0 <= y < 168)
codeseg:999A ; Attributes: bp-based frame
codeseg:999A
codeseg:999A AG_readAgi256Pic proc near              ; CODE XREF: AG_cmd_set_simple_170+18�p
codeseg:999A
codeseg:999A picNum          = word ptr  4
codeseg:999A
codeseg:999A                push    bp
codeseg:999B                mov    bp, sp
codeseg:999D                jmp    jumpOverData
codeseg:999D ; ---------------------------------------------------------------------------
codeseg:99A0 aPicdir        db 'PICDIR',0
codeseg:99A7 aVol_0          db 'VOL.0',0
codeseg:99AD tempBuf        db 3 dup(0F0h)
codeseg:99B0 ; ---------------------------------------------------------------------------
codeseg:99B0
codeseg:99B0 jumpOverData:                          ; CODE XREF: AG_readAgi256Pic+3�j
codeseg:99B0                push    ds
codeseg:99B1                mov    cx, cs
codeseg:99B3                mov    ds, cx
codeseg:99B5                assume ds:codeseg
codeseg:99B5                call    $+3
codeseg:99B8
codeseg:99B8 loc_99B8:                              ; CODE XREF: cmd_shake_screen_110+17�p
codeseg:99B8                pop    dx              ; At first run, if called from 0x99B5
codeseg:99B8                                        ; DX = IP from the stack, which in turn is 0x99B8
codeseg:99B8                                        ; as it was the IP for the next instruction as call $+3 at 0x99B5 was made.
codeseg:99B9                sub    dx, 18h        ; Subtract 0x18 from given value.
codeseg:99B9                                        ; On first run it's 0x99B8 - 0x18 = 0x99A0 = offset "PICDIR"
codeseg:99BC                mov    ax, 3D00h
codeseg:99BF                int    21h            ; DOS - 2+ - OPEN DISK FILE WITH HANDLE
codeseg:99BF                                        ; DS:DX -> ASCIZ filename
codeseg:99BF                                        ; AL = access mode
codeseg:99BF                                        ; 0 - read
codeseg:99C1                jnb    fileOpenSuccess ; JNB = JNC
codeseg:99C1                                        ; AX = file handle if CF not set,
codeseg:99C1                                        ; AX = error code if CF is set
codeseg:99C3
codeseg:99C3 error:                                  ; CODE XREF: AG_readAgi256Pic+3D�j
codeseg:99C3                                        ; AG_readAgi256Pic+4D�j ...
codeseg:99C3                pop    ds
codeseg:99C4                assume ds:dataseg
codeseg:99C4                retn
codeseg:99C5 ; ---------------------------------------------------------------------------
codeseg:99C5
codeseg:99C5 fileOpenSuccess:                        ; CODE XREF: AG_readAgi256Pic+27�j
codeseg:99C5                mov    bx, ax          ; BX = AX = file handle of the picture directory file
codeseg:99C7                mov    dx, [bp+picNum]
codeseg:99CA                mov    al, 3
codeseg:99CC                mul    dl              ; AX = AL*DL = DL*3 = picNum*3
codeseg:99CE                mov    dx, ax          ; DX = AX = picNum*3
codeseg:99D0                xor    cx, cx          ; Seek to position picNum*3 from beginning of file
codeseg:99D2                mov    ax, 4200h      ; Inputs: BX = file handle,
codeseg:99D2                                        ; CX = 16-bit MSB of bytes to move,
codeseg:99D2                                        ; DX = 16-bit LSB of bytes to move
codeseg:99D2                                        ; Returns:
codeseg:99D2                                        ; DX:AX = new pointer location if CF not set
codeseg:99D5                int    21h            ; DOS - 2+ - MOVE FILE READ/WRITE POINTER (LSEEK)
codeseg:99D5                                        ; AL = method: offset from beginning of file
codeseg:99D7                jb      error          ; JC error
codeseg:99D9                call    $+3
codeseg:99DC                pop    dx
codeseg:99DD                sub    dx, 2Fh ; '/'  ; If called from 0x99D9 then after this subtraction
codeseg:99DD                                        ; DX will be 0x99DC - 0x2F = 0x99AD = offset tempBuf
codeseg:99E0                mov    cx, 3          ; Read three bytes from position picNum*3
codeseg:99E3                mov    ah, 3Fh
codeseg:99E5                int    21h            ; DOS - 2+ - READ FROM FILE WITH HANDLE
codeseg:99E5                                        ; BX = file handle, CX = number of bytes to read
codeseg:99E5                                        ; DS:DX -> buffer
codeseg:99E7                jb      error
codeseg:99E9                mov    ah, 3Eh
codeseg:99EB                int    21h            ; DOS - 2+ - CLOSE A FILE WITH HANDLE
codeseg:99EB                                        ; BX = file handle
codeseg:99ED                mov    di, dx
codeseg:99EF                mov    al, [di]
codeseg:99F1                shr    al, 4          ; AL = tempBuf[0]/16
codeseg:99F4                sub    di, 2
codeseg:99F7                add    [di], al        ; Add tempBuf[0]/16 to "VOL.0" string's suffix (i.e. '0')
codeseg:99F7                                        ; so that it may become "VOL.0" - "VOL.9".
codeseg:99F9                sub    dx, 6          ; DX = offset aVol_0
codeseg:99FC                mov    ax, 3D00h      ; Open correct volume file (Some of "VOL.0" to "VOL.9")
codeseg:99FF                int    21h            ; DOS - 2+ - OPEN DISK FILE WITH HANDLE
codeseg:99FF                                        ; DS:DX -> ASCIZ filename
codeseg:99FF                                        ; AL = access mode
codeseg:99FF                                        ; 0 - read
codeseg:9A01                jb      error
codeseg:9A03                mov    bx, ax          ; BX = AX = file handle of the volume file
codeseg:9A05                mov    di, dx
codeseg:9A07                add    di, 6          ; DI = offset tempBuf
codeseg:9A0A                xor    ch, ch
codeseg:9A0C                mov    cl, [di]
codeseg:9A0E                and    cl, 0Fh        ; CL = tempBuf[0] % 16
codeseg:9A11                inc    di
codeseg:9A12                mov    dh, [di]        ; DH = tempBuf[1]
codeseg:9A14                inc    di
codeseg:9A15                mov    dl, [di]        ; DL = tempBuf[2]
codeseg:9A17                mov    ax, 4200h      ; Inputs: BX = file handle,
codeseg:9A17                                        ; CX = 16-bit MSB of bytes to move,
codeseg:9A17                                        ; DX = 16-bit LSB of bytes to move
codeseg:9A17                                        ; Returns:
codeseg:9A17                                        ; DX:AX = new pointer location if CF not set
codeseg:9A1A                int    21h            ; DOS - 2+ - MOVE FILE READ/WRITE POINTER (LSEEK)
codeseg:9A1A                                        ; AL = method: offset from beginning of file
codeseg:9A1C                jb      error
codeseg:9A1E                mov    ax, 4201h
codeseg:9A21                xor    cx, cx
codeseg:9A23                mov    dx, 5          ; Move 5 bytes onwards from current seeking location
codeseg:9A26                int    21h            ; DOS - 2+ - MOVE FILE READ/WRITE POINTER (LSEEK)
codeseg:9A26                                        ; AL = method: offset from present location
codeseg:9A28                jb      error
codeseg:9A2A                pop    ds
codeseg:9A2B                push    ds
codeseg:9A2C                mov    dx, agi256PicSeg
codeseg:9A30                mov    ds, dx
codeseg:9A32                mov    dx, 160        ; Start reading to agi256PicSeg:[160]
codeseg:9A35                mov    cx, 168
codeseg:9A38
codeseg:9A38 readRow:                                ; CODE XREF: AG_readAgi256Pic+AB�j
codeseg:9A38                push    cx              ; Read 168 rows of 160 bytes each.
codeseg:9A39                mov    cx, 160
codeseg:9A3C                mov    ah, 3Fh
codeseg:9A3E                int    21h            ; DOS - 2+ - READ FROM FILE WITH HANDLE
codeseg:9A3E                                        ; BX = file handle, CX = number of bytes to read
codeseg:9A3E                                        ; DS:DX -> buffer
codeseg:9A40                add    dx, 320        ; Go to next row by adding 320 to destination pointer
codeseg:9A44                pop    cx
codeseg:9A45                loop    readRow        ; Read 168 rows of 160 bytes each.
codeseg:9A47                mov    ah, 3Eh
codeseg:9A49                int    21h            ; DOS - 2+ - CLOSE A FILE WITH HANDLE
codeseg:9A49                                        ; BX = file handle
codeseg:9A4B                pop    ds
codeseg:9A4C                pop    bp
codeseg:9A4D                retn
codeseg:9A4D AG_readAgi256Pic endp
codeseg:9A4D
codeseg:9A4E ; ---------------------------------------------------------------------------
codeseg:9A4E
codeseg:9A4E loc_9A4E:
codeseg:9A4E                nop
codeseg:9A4F
codeseg:9A4F ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9A4F
codeseg:9A4F ; Sets and/or clears current pixel bits
codeseg:9A4F ; AL = ES:[DI] = PIXEL
codeseg:9A4F ; (PIXEL |= BH) &= BL
codeseg:9A4F
codeseg:9A4F AG_setClrCurrPixel proc near            ; CODE XREF: _SBuffXLine+2A�p
codeseg:9A4F                                        ; _SBuffYLine+3C�p ...
codeseg:9A4F                mov    al, es:[di]
codeseg:9A52                or      al, bh
codeseg:9A54                and    al, bl
codeseg:9A56                mov    es:[di], al
codeseg:9A59                retn
codeseg:9A59 AG_setClrCurrPixel endp
codeseg:9A59
codeseg:9A5A
codeseg:9A5A ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9A5A
codeseg:9A5A ; Was _WindowLineClr in Sonneveld's Agi2917.idb
codeseg:9A5A ;
codeseg:9A5A ; Clears first 8 rows (320*8 bytes) of video memory
codeseg:9A5A ; with white pixels (Color 15).
codeseg:9A5A
codeseg:9A5A AG_setWhiteMenuBar proc near            ; CODE XREF: _StatLineWrite+1A�p
codeseg:9A5A                                        ; sub_93D1+1C�p
codeseg:9A5A                push    cx
codeseg:9A5B                push    es
codeseg:9A5C                push    di
codeseg:9A5D                push    ax
codeseg:9A5E                mov    ax, 0A000h
codeseg:9A61                mov    es, ax
codeseg:9A63                assume es:nothing
codeseg:9A63                xor    di, di
codeseg:9A65                mov    ax, 0F0Fh
codeseg:9A68                mov    cx, (320*8)/2
codeseg:9A6B                repe stosw
codeseg:9A6D                pop    ax
codeseg:9A6E                pop    di
codeseg:9A6F                pop    es
codeseg:9A70                assume es:dataseg
codeseg:9A70                pop    cx
codeseg:9A71                retn
codeseg:9A71 AG_setWhiteMenuBar endp
codeseg:9A71
codeseg:9A71 ; ---------------------------------------------------------------------------
codeseg:9A72 byte_9A72      db 33Eh dup(0)
</pre>


===Disassembly of AGIOBJS.OVL===
===Disassembly of AGIOBJS.OVL===
Line 37: Line 920:
codeseg:9DB0                jmp    AO_agi256_saveArea ; savearea(struct Sprite *s) {
codeseg:9DB0                jmp    AO_agi256_saveArea ; savearea(struct Sprite *s) {
codeseg:9DB0 j_AO_agi256_saveArea endp              ;  int srcOffset = screenOffset(s->xPos, s->yPos);
codeseg:9DB0 j_AO_agi256_saveArea endp              ;  int srcOffset = screenOffset(s->xPos, s->yPos);
codeseg:9DB0                                        ;  uint8 *src = agi256PicSeg[srcOffset + 160];
codeseg:9DB0                                        ;  uint8 *src = &agi256PicSeg[srcOffset + 160];
codeseg:9DB0                                        ;  for (int y = 0; y < s->ySize; y++)
codeseg:9DB0                                        ;  for (int y = 0; y < s->ySize; y++)
codeseg:9DB0                                        ;    memcpy(s->buffer + s->xSize * y, src + 320 * y, s->xSize);
codeseg:9DB0                                        ;    memcpy(s->buffer + s->xSize * y, src + 320 * y, s->xSize);
Line 69: Line 952:
codeseg:9DB9 ; savearea(struct Sprite *s) {
codeseg:9DB9 ; savearea(struct Sprite *s) {
codeseg:9DB9 ;  int srcOffset = screenOffset(s->xPos, s->yPos);
codeseg:9DB9 ;  int srcOffset = screenOffset(s->xPos, s->yPos);
codeseg:9DB9 ;  uint8 *src = agi256PicSeg[srcOffset + 160];
codeseg:9DB9 ;  uint8 *src = &agi256PicSeg[srcOffset + 160];
codeseg:9DB9 ;  for (int y = 0; y < s->ySize; y++)
codeseg:9DB9 ;  for (int y = 0; y < s->ySize; y++)
codeseg:9DB9 ;    memcpy(s->buffer + s->xSize * y, src + 320 * y, s->xSize);
codeseg:9DB9 ;    memcpy(s->buffer + s->xSize * y, src + 320 * y, s->xSize);
417

edits

Navigation menu