Assembly2010. 1. 5. 01:53

.286
.model large, stdcall
option casemap:none


;------------------------------------------------------------------------------------
; procedure declare
;------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------
; DrawBitmap
;
; wBitmapSegment:word   =>  Bitmap Data segment
; wBitmapOffset:word    =>  Bitmap Data offset
; wX:word               =>  x coordination
; wY:word               =>  y coordination
; wWidth:word           =>  width
; wHeight:word          =>  height
; wColorKey             =>  Color Key
;
; 반환값                =>  cx : x 좌표
;                           dx : y 좌표
DrawBitmap proto far :word, :word, :word, :word, :word, :word, :word

;------------------------------------------------------------------------------------
; ClearBitmap
;
; wBitmapSegment:word   =>  Bitmap Data segment
; wBitmapOffset:word    =>  Bitmap Data offset
; wX:word               =>  x coordination
; wY:word               =>  y coordination
; wWidth:word           =>  width
; wHeight:word          =>  height
ClearBitmap proto far :word, :word, :word, :word, :word, :word

;------------------------------------------------------------------------------------
; data segment
;------------------------------------------------------------------------------------
seg_data segment
        v_image byte    054h,054h,054h,023h,023h,023h,023h,054h,054h,054h,
                        054h,054h,023h,023h,023h,023h,023h,023h,054h,054h,
                        054h,023h,023h,023h,023h,023h,023h,023h,023h,054h,
                        023h,023h,023h,023h,023h,023h,023h,023h,023h,023h
        v_backupimage   byte    100     dup     (18h)
        v_x             word    0
        v_y             word    0
seg_data ends

;------------------------------------------------------------------------------------
; stack segment
;------------------------------------------------------------------------------------
seg_stack segment stack
                        byte    100h    dup     ('stack')
seg_stack ends

;------------------------------------------------------------------------------------
; code segment
;------------------------------------------------------------------------------------
seg_code segment
main proc far
        xor     ax, ax
        push    ds
        push    ax

        assume  cs:seg_code, ds:seg_data, ss:seg_stack
        mov     ax, seg_data
        mov     ds, ax

        ; 13h graphic mode
        mov     ah, 0
        mov     al, 13h
        int     10h

        mov     ax, 0A000h
        mov     es, ax

        ; Clear Screen
        mov     cx, 320*200
        mov     di, 0
        mov     al, 018h
        cld
        rep     stosb

L_TEXTLOOP:
        mov     ax, 3
        int     33h
        or      bx, bx
        jnz     L_EXIT

        shr   cx , 1

        .if (v_x != cx)||(v_y != dx)
                push    cx
                push    dx
                invoke  ClearBitmap, seg v_backupimage, offset v_backupimage, v_x, v_y, 10, 4
                pop     dx
                pop     cx

                mov     v_x, cx
                mov     v_y, dx
                invoke  DrawBitmap,  seg v_image,  offset v_image,  cx,  dx,  10,  4, 54h
        .endif

        jmp     L_TEXTLOOP
L_EXIT:
        ; 3 text mode
        mov     ah, 0
        mov     al, 3
        int     10h

        ret
main endp

;------------------------------------------------------------------------------------
; Bitmap Draw
DrawBitmap proc far wBitmapSegment:word, wBitmapOffset:word, wX:word, wY:word, wWidth:word, wHeight:word, wColorKey:word
        ; 지역변수 선언
        local   wXCount:word
        local   wYCount:word

        mov     wXCount, 0
        mov     wYCount, 0

        ; 레지스터 보호
        push    ds
        push    es

        ; 클리핑 처리
        .if     wX >= 309
                mov     wX, 309
        .elseif wY >= 195
                mov     wY, 195
        .elseif wX <= 0
                mov     wX, 0
        .elseif wY <= 0
                mov     wY, 0
        .endif

        ; 비트맵 세그먼트 설정
        mov     ax, wBitmapSegment
        mov     ds, ax

        ; 비트맵 옵셋 설정
        mov     si, wBitmapOffset

        ; 비디오 세그먼트 설정
        mov     ax, 0A000h
        mov     es, ax

        ; 시작 주소 계산
        mov     ax, wY
        mov     cx, 320
        mul     cx
        add     ax, wX
        mov     di, ax  ; di => 최종 비디오 메모리 주소

        push    di
        ; 배경 저장
        mov     ax, wHeight
        lea     bx, ds:v_backupimage
        .while wYCount < ax
                mov     ax, wWidth
                .while  wXCount < ax
                        mov     al, es:[di]
                        mov     ds:[bx], al
                        inc     di
                        inc     bx
                        inc     wXCount
                        mov     ax, wWidth
                .endw

                mov     ax, 320
                sub     ax, wWidth
                add     di, ax

                mov     wXCount, 0
                inc     wYCount
                mov     ax, wHeight
        .endw
        pop     di

        mov     wXCount, 0
        mov     wYCount, 0
        ; 실제 그리기
        mov     ax, wHeight
        .while wYCount < ax
                mov     ax, wWidth
                .while wXCount < ax
                        mov     al, byte ptr ds:[si]
                        .if     al != byte ptr wColorKey
                                mov     es:[di], al
                                inc     di
                                inc     si
                                inc     wXCount
                                mov     ax, wWidth
                        .else
                                inc     di
                                inc     si
                                inc     wXCount
                                mov     ax, wWidth
                        .endif
                .endw

                mov     ax, 320
                sub     ax, wWidth
                add     di, ax

                mov     wXCount, 0
                inc     wYCount
                mov     ax, wHeight
        .endw

L_EXIT:
        ; 위치 저장
        mov     cx, wX
        mov     dx, wY

        pop     es
        pop     ds
        ret
DrawBitmap      endp

;------------------------------------------------------------------------------------
; Bitmap Clear
ClearBitmap proc far wBitmapSegment:word, wBitmapOffset:word, wX:word, wY:word, wWidth:word, wHeight:word
        ; 지역변수 선언
        local   wXCount:word
        local   wYCount:word
        mov     wXCount, 0
        mov     wYCount, 0

        ; 레지스터 보호
        push    es

        .if     wX >= 309
                mov     wX, 309
        .elseif wY >= 195
                mov     wY, 195
        .elseif wX <= 0
                mov     wX, 0
        .elseif wY <= 0
                mov     wY, 0
        .endif

        ; 비트맵 세그먼트 설정
        mov     ax, wBitmapSegment
        mov     ds, ax

        ; 비트맵 옵셋 설정
        mov     si, wBitmapOffset

        ; 비디오 세그먼트 설정
        mov     ax, 0A000h
        mov     es, ax

        ; 시작 주소 계산
        mov     ax, wY
        mov     cx, 320
        mul     cx
        add     ax, wX
        mov     di, ax          ; di => 최종 비디오 메모리 주소

        ; 배경 이미지 복원
        mov     ax, wHeight
        .while wYCount < ax
                mov     ax, wWidth
                .while  wXCount < ax
                        mov     al, byte ptr ds:[si]
                        mov     es:[di], al
                        inc     di
                        inc     si
                        inc     wXCount
                        mov     ax, wWidth
                .endw

                mov     ax, 320
                sub     ax, wWidth
                add     di, ax

                mov     wXCount, 0
                inc     wYCount
                mov     ax, wHeight
        .endw

L_EXIT:
        pop     es
        ret
ClearBitmap     endp
seg_code ends

        end     main




Posted by houdinist