Open main menu

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

Completed disassembly of AGIOBJS.OVL
(Added first part of AGIOBJS.OVL's disassembly.)
(Completed disassembly of AGIOBJS.OVL)
Line 184: Line 184:
codeseg:9E22                nop
codeseg:9E22                nop
codeseg:9E23
codeseg:9E23
codeseg:9E23 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9E23
codeseg:9E23 ; Loop in pseudo C:
codeseg:9E23 ; for (int y = 0; y < Sprite.ySize; y++) {
codeseg:9E23 ;  memcpy(ES:DI, DS:SI, Sprite.xSize);
codeseg:9E23 ;  DI += 320;
codeseg:9E23 ;  SI += Sprite.xSize; 
codeseg:9E23 ; }
codeseg:9E23
codeseg:9E23 AO_agi256_restoreArea_loop proc near    ; CODE XREF: AO_agi256_restoreArea_loop+8�j
codeseg:9E23                                        ; AO_agi256_restoreArea_loop_init+D�j
codeseg:9E23                mov    cl, al          ; Move Sprite.xSize bytes per row
codeseg:9E25                repe movsb              ; Move the bytes from DS:SI to ES:DI
codeseg:9E27                add    di, dx          ; Move to the next row
codeseg:9E27                                        ; repe movsb added Sprite.xSize to DI
codeseg:9E27                                        ; add di,dx adds (320 - Sprite.xSize) to DI
codeseg:9E27                                        ; so the addition is Sprite.xSize + (320 - Sprite.xSize) = 320
codeseg:9E29                dec    ah
codeseg:9E2B                jnz    AO_agi256_restoreArea_loop ; Loop in pseudo C:
codeseg:9E2B                                        ; for (int y = 0; y < Sprite.ySize; y++) {
codeseg:9E2B                                        ;  memcpy(ES:DI, DS:SI, Sprite.xSize);
codeseg:9E2B                                        ;  DI += 320;
codeseg:9E2B                                        ;  SI += Sprite.xSize; 
codeseg:9E2B                                        ; }
codeseg:9E2D                pop    es
codeseg:9E2E                add    sp, 2
codeseg:9E31                pop    bp
codeseg:9E32                pop    di
codeseg:9E33                pop    si
codeseg:9E34                retn
codeseg:9E34 AO_agi256_restoreArea_loop endp ; sp =  0Ah
codeseg:9E34
codeseg:9E35
codeseg:9E35 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9E35
codeseg:9E35 ; Attributes: bp-based frame
codeseg:9E35
codeseg:9E35 AO_agi256_blit  proc near              ; CODE XREF: j_AO_agi256_blit�j
codeseg:9E35
codeseg:9E35 structPtr      = word ptr  8
codeseg:9E35 arg_1C          = byte ptr  24h
codeseg:9E35
codeseg:9E35                push    si
codeseg:9E36                push    di
codeseg:9E37                push    bp
codeseg:9E38                mov    bp, sp
codeseg:9E3A                sub    sp, 2
codeseg:9E3D                mov    bp, [bp+structPtr]
codeseg:9E40                mov    al, [bp+2]
codeseg:9E43                push    ax
codeseg:9E44                mov    si, [bp+10h]
codeseg:9E47                test    byte ptr [si+2], 80h
codeseg:9E4B                jz      dontMirror
codeseg:9E4D                push    bp
codeseg:9E4E                call    _BlitMirrorCell
codeseg:9E51                pop    bp
codeseg:9E52                mov    si, [bp+10h]
codeseg:9E55
codeseg:9E55 dontMirror:                            ; CODE XREF: AO_agi256_blit+16�j
codeseg:9E55                inc    si
codeseg:9E56                lodsw
codeseg:9E57                mov    dx, ax
codeseg:9E59                mov    ah, byte ptr [bp+blitStruc.xPos]
codeseg:9E5C                mov    al, byte ptr [bp+blitStruc.yPos]
codeseg:9E5F                sub    al, dl
codeseg:9E61                inc    al
codeseg:9E63                call    screenOffset    ; Calculates the screen offset for given coordinate? Video or AGI screen offset?
codeseg:9E63                                        ; DI = AL * 320 + AH
codeseg:9E63                                        ; (Destroys BX contents (Returns with BH = 0, BL = AH))
codeseg:9E63                                        ;
codeseg:9E63                                        ; Maybe not named quite correctly?
codeseg:9E66                shl    dh, 1
codeseg:9E68                shl    dh, 1
codeseg:9E6A                shl    dh, 1
codeseg:9E6C                shl    dh, 1          ; DH *= 16
codeseg:9E6E                push    es
codeseg:9E6F                mov    es, agi256PicSeg
codeseg:9E73                mov    bl, 1
codeseg:9E75                mov    bh, [bp+arg_1C]
codeseg:9E78                shl    bh, 1
codeseg:9E7A                shl    bh, 1
codeseg:9E7C                shl    bh, 1
codeseg:9E7E                shl    bh, 1          ; BH *= 16
codeseg:9E80                mov    bp, di
codeseg:9E82                xor    cx, cx
codeseg:9E84                jmp    short startBlit ; Read byte from DS:[SI++]
codeseg:9E86 ; ---------------------------------------------------------------------------
codeseg:9E86                nop
codeseg:9E87
codeseg:9E87 ah_eq_dh:                              ; CODE XREF: AO_agi256_blit+61�j
codeseg:9E87                cbw                    ; Sign extend AL to AX (0 <= AL <= 0x0F, so AH = 0)
codeseg:9E88                add    di, ax          ; DI += AX
codeseg:9E8A
codeseg:9E8A startBlit:                              ; CODE XREF: AO_agi256_blit+4F�j
codeseg:9E8A                                        ; AO_agi256_blit+83�j ...
codeseg:9E8A                lodsb                  ; Read byte from DS:[SI++]
codeseg:9E8B                or      al, al
codeseg:9E8D                jz      zeroByte        ; Jump if it's zero
codeseg:9E8F                mov    ah, al          ; Double the pixel
codeseg:9E91                and    ax, 0F00Fh      ; Make lower nibble of AL contain pixel's color info and
codeseg:9E91                                        ; upper nibble of AH contain pixel's priority/control info
codeseg:9E94                cmp    ah, dh
codeseg:9E96                jz      ah_eq_dh        ; Sign extend AL to AX (0 <= AL <= 0x0F, so AH = 0)
codeseg:9E98                mov    cl, al
codeseg:9E9A                shr    ah, 1
codeseg:9E9C                shr    ah, 1
codeseg:9E9E                shr    ah, 1
codeseg:9EA0                shr    ah, 1          ; Bring priority/control info to lower nibble of AH
codeseg:9EA2
codeseg:9EA2 xLoop:                                  ; CODE XREF: AO_agi256_blit+81�j
codeseg:9EA2                                        ; AO_agi256_blit+B1�j
codeseg:9EA2                mov    al, es:[di]    ; Read pixel
codeseg:9EA5                and    al, 0F0h        ; Leave only the priority/control info
codeseg:9EA7                cmp    al, 2 shl 4
codeseg:9EA9                jbe    controlByte012  ; Jump if pixel's control info is 0, 1 or 2
codeseg:9EAB                cmp    al, bh
codeseg:9EAD                ja      priGreaterThanBH
codeseg:9EAF                mov    al, bh          ; AL <= BH so
codeseg:9EAF                                        ; AL = BH <=> AL = MAX(AL, BH)
codeseg:9EB1
codeseg:9EB1 loc_9EB1:                              ; CODE XREF: AO_agi256_blit+AE�j
codeseg:9EB1                or      al, ah          ; AL |= AH
codeseg:9EB3                jmp    AO_agi256_blit_sub ; ES:[160 + DI++] = AL & 0x0F;
codeseg:9EB3                                        ; BL = 0;
codeseg:9EB6 ; ---------------------------------------------------------------------------
codeseg:9EB6
codeseg:9EB6 afterBlitSubCall:                      ; CODE XREF: AO_agi256_blit_sub+D�j
codeseg:9EB6                loop    xLoop          ; Read pixel
codeseg:9EB8                jmp    short startBlit ; Read byte from DS:[SI++]
codeseg:9EBA ; ---------------------------------------------------------------------------
codeseg:9EBA
codeseg:9EBA zeroByte:                              ; CODE XREF: AO_agi256_blit+58�j
codeseg:9EBA                dec    dl              ; DL--
codeseg:9EBC                jz      zeroDL
codeseg:9EBE                add    bp, 320
codeseg:9EC2                mov    di, bp
codeseg:9EC4                jmp    short startBlit ; Read byte from DS:[SI++]
codeseg:9EC6 ; ---------------------------------------------------------------------------
codeseg:9EC6
codeseg:9EC6 controlByte012:                        ; CODE XREF: AO_agi256_blit+74�j
codeseg:9EC6                push    di
codeseg:9EC7                xor    ch, ch
codeseg:9EC9
codeseg:9EC9 loc_9EC9:                              ; CODE XREF: AO_agi256_blit+A7�j
codeseg:9EC9                cmp    di, 0D0C0h
codeseg:9ECD                jnb    loc_9EDE
codeseg:9ECF                add    di, 320
codeseg:9ED3                mov    ch, es:[di]
codeseg:9ED6                and    ch, 0F0h
codeseg:9ED9                cmp    ch, 20h ; ' '
codeseg:9EDC                jbe    loc_9EC9
codeseg:9EDE
codeseg:9EDE loc_9EDE:                              ; CODE XREF: AO_agi256_blit+98�j
codeseg:9EDE                pop    di
codeseg:9EDF                cmp    ch, bh
codeseg:9EE1                mov    ch, 0
codeseg:9EE3                jbe    loc_9EB1        ; AL |= AH
codeseg:9EE5
codeseg:9EE5 priGreaterThanBH:                      ; CODE XREF: AO_agi256_blit+78�j
codeseg:9EE5                inc    di
codeseg:9EE6                loop    xLoop          ; Read pixel
codeseg:9EE8                jmp    short startBlit ; Read byte from DS:[SI++]
codeseg:9EEA ; ---------------------------------------------------------------------------
codeseg:9EEA
codeseg:9EEA zeroDL:                                ; CODE XREF: AO_agi256_blit+87�j
codeseg:9EEA                pop    es
codeseg:9EEB                pop    ax
codeseg:9EEC                or      al, al
codeseg:9EEE                jnz    zeroDL_notZeroAL
codeseg:9EF0                mov    al, 1          ; f1 = Ego is invisible on the screen (Completely obscured by another object)
codeseg:9EF2                test    bl, bl
codeseg:9EF4                jnz    notZeroBL      ; Hide ego (Set ego as invisible)
codeseg:9EF6                call    _ResetFlagAL    ; Show ego (Set ego as visible i.e. not invisible)
codeseg:9EF9                jmp    short zeroDL_notZeroAL
codeseg:9EFB ; ---------------------------------------------------------------------------
codeseg:9EFB
codeseg:9EFB notZeroBL:                              ; CODE XREF: AO_agi256_blit+BF�j
codeseg:9EFB                call    _SetFlagAL      ; Hide ego (Set ego as invisible)
codeseg:9EFE
codeseg:9EFE zeroDL_notZeroAL:                      ; CODE XREF: AO_agi256_blit+B9�j
codeseg:9EFE                                        ; AO_agi256_blit+C4�j
codeseg:9EFE                add    sp, 2
codeseg:9F01                pop    bp
codeseg:9F02                pop    di
codeseg:9F03                pop    si
codeseg:9F04                retn
codeseg:9F04 AO_agi256_blit  endp
codeseg:9F04
codeseg:9F05
codeseg:9F05 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9F05
codeseg:9F05 ; DX = 320 - Sprite.xSize (AL)
codeseg:9F05 ; SI += 160 (This is done in part 2 of the loop init, actually)
codeseg:9F05 ; This is elsewhere than directly inside AO_agi256_saveArea
codeseg:9F05 ; probably because it didn't fit otherwise. Returns to AO_agi256_saveArea_loop
codeseg:9F05 ; (Although calls AO_agi256_saveArea_loop_init_part2 first)
codeseg:9F05
codeseg:9F05 AO_agi256_saveArea_loop_init proc near  ; CODE XREF: AO_agi256_saveArea+28�j
codeseg:9F05                mov    dx, 320
codeseg:9F08                push    ax
codeseg:9F09                xor    ah, ah
codeseg:9F0B                sub    dx, ax          ; DX = 320 - Sprite.xSize
codeseg:9F0D                pop    ax
codeseg:9F0E                jmp    AO_agi256_saveArea_loop_init_part2 ; This is elsewhere than directly inside AO_agi256_saveArea_loop_init
codeseg:9F0E AO_agi256_saveArea_loop_init endp      ; probably because it didn't fit otherwise. Returns to AO_agi256_saveArea_loop
codeseg:9F0E
codeseg:9F11
codeseg:9F11 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9F11
codeseg:9F11 ; DX = 320 - Sprite.xSize (AL)
codeseg:9F11 ; DI += 160
codeseg:9F11 ; This is elsewhere than directly inside AO_agi256_restoreArea
codeseg:9F11 ; probably because it didn't fit otherwise. Returns to AO_agi256_restoreArea_loop
codeseg:9F11
codeseg:9F11 AO_agi256_restoreArea_loop_init proc near
codeseg:9F11                                        ; CODE XREF: AO_agi256_restoreArea+26�j
codeseg:9F11                mov    dx, 320
codeseg:9F14                push    ax
codeseg:9F15                xor    ah, ah
codeseg:9F17                sub    dx, ax
codeseg:9F19                pop    ax
codeseg:9F1A                add    di, 160
codeseg:9F1E                jmp    AO_agi256_restoreArea_loop ; Loop in pseudo C:
codeseg:9F1E AO_agi256_restoreArea_loop_init endp    ; for (int y = 0; y < Sprite.ySize; y++) {
codeseg:9F1E                                        ;  memcpy(ES:DI, DS:SI, Sprite.xSize);
codeseg:9F1E                                        ;  DI += 320;
codeseg:9F1E                                        ;  SI += Sprite.xSize; 
codeseg:9F1E                                        ; }
codeseg:9F21
codeseg:9F21 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9F21
codeseg:9F21 ; This is elsewhere than directly inside AO_agi256_saveArea_loop_init
codeseg:9F21 ; probably because it didn't fit otherwise. Returns to AO_agi256_saveArea_loop
codeseg:9F21
codeseg:9F21 AO_agi256_saveArea_loop_init_part2 proc near
codeseg:9F21                                        ; CODE XREF: AO_agi256_saveArea_loop_init+9�j
codeseg:9F21                add    si, 160
codeseg:9F25                jmp    AO_agi256_saveArea_loop ; Loop in pseudo C:
codeseg:9F25 AO_agi256_saveArea_loop_init_part2 endp ; for (int y = 0; y < Sprite.ySize; y++) {
codeseg:9F25                                        ;  memcpy(ES:DI, DS:SI, Sprite.xSize);
codeseg:9F25                                        ;  SI += 320;
codeseg:9F25                                        ;  DI += Sprite.xSize; 
codeseg:9F25                                        ; }
codeseg:9F28
codeseg:9F28 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
codeseg:9F28
codeseg:9F28 ; ES:[160 + DI++] = AL & 0x0F;
codeseg:9F28 ; BL = 0;
codeseg:9F28
codeseg:9F28 AO_agi256_blit_sub proc near            ; CODE XREF: AO_agi256_blit+7E�j
codeseg:9F28                add    di, 160
codeseg:9F2C                and    al, 0Fh
codeseg:9F2E                stosb
codeseg:9F2F                sub    di, 160
codeseg:9F33                xor    bl, bl
codeseg:9F35                jmp    afterBlitSubCall
codeseg:9F35 AO_agi256_blit_sub endp
codeseg:9F35
codeseg:9F35 ; ---------------------------------------------------------------------------
codeseg:9F38                db 0D8h dup(0)
codeseg:9F38 codeseg        ends
codeseg:9F38
</pre>
</pre>


417

edits