Open main menu

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

Added disassembly of AGIGRAF.OVL.
(Added AGIGRAF.OVL section's header.)
(Added disassembly of AGIGRAF.OVL.)
Line 26: Line 26:


===Disassembly of AGIGRAF.OVL===
===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===
417

edits