Assembly2010. 1. 5. 02:02

벌써 세월이 이렇게나 지나서 이렇게 다시 보니 감회가 새롭네요. 우연히 찾은거라 백업용으로 남겨둡니다.
Posted by houdinist
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
Assembly2010. 1. 5. 01:46




.286
.model huge, stdcall  ; meomory and calling convation
option casemap :none  ; case sensitive


include MyMacro.inc


QUEUE_MAX_BUFFER    EQU    4    ; 최대 큐 버퍼 사이즈

init_serial proto near
EnQueue proto :byte
DeQueue proto


;-----------------------------------------------------------
SgIntVact   segment at 0
    org   30h
    V_Com1VactOfs   dw  ?
    V_Com1VactSeg   dw  ?
SgIntVact   ends

;-----------------------------------------------------------
SgBiosData  segment at 40h
    org   0

    V_Com1Port  dw  ?
    V_Com2Port  dw  ?

SgBiosData  ends
;-----------------------------------------------------------
data    segment
    V_OldComVactOfs dw  ?
    V_OldComVactSeg dw  ?

    V_ComDataPort       dw  ?
    V_ComIntEnablePort  dw  ?
    V_ComIntStatPort    dw  ?
    V_ComLineCtrlPort   dw  ?
    V_ComModemCtrlPort  dw  ?
    V_ComLineStatPort   dw  ?
    V_ComModemStatPort  dw  ?

    V_InputChar db  ?
   
    Queue    db  4 dup(0)    ; 실제 큐
    QueueSize    db  0        ; 큐 사용량
    TempPos    db  0        ; 가상 인덱스
    Position    db  0        ; 실제 인덱스

data    ends

stackseg segment stack
        db      100h    dup('stack')
stackseg ends

;-----------------------------------------------------------
code    segment
  ;-----------------------------------------------------------
  main  proc  far
        invoke init_serial  ;serial port initialize

        ;set segment
        assume  cs:code,ds:data
        mov   ax , data
        mov   ds , ax

        ;input loop
        mov   V_InputChar , 0
        .while  V_InputChar != '@'
          mov   ah , 06h
          mov   dl , 0FFh
          int   21h
          .if !zero?
            mov   V_InputChar , al
            ;send to serial
            mov   dx , V_ComDataPort
            out   dx , al
          .endif
     
      ;큐에서 꺼내 출력하기
      .if QueueSize == 4
        mov cx, 4
          CharLoop:
        invoke DeQueue
        mov ah, 2
        int 21h
        loop CharLoop
      .endif
        .endw

        ;serial off
        cli
        in    al , 21h    ;interupt off
        or    al , 10h
        out   21h , al
        ;restore interupt vactor
        assume  es:SgIntVact
        mov   ax , SgIntVact
        mov   es , ax

        mov   ax , V_OldComVactOfs
        mov   cx , V_OldComVactSeg
        mov   V_Com1VactOfs , ax
        mov   V_Com1VactSeg , cx
        sti

        ;serial reset
        mov   dx , V_ComIntEnablePort
        xor   ax , ax
        out   dx , al
        mov   dx , V_ComModemCtrlPort
        out   dx , al

        ;exist
        mov   ah , 4Ch
        int   21h

  main  endp
  ;-----------------------------------------------------------
  init_serial proc near
        ;com 1 initialize
        ;set interupt handler

        ;set segment
        assume  cs:code,ds:data,es:SgIntVact
        mov   ax , data
        mov   cx , SgIntVact
        mov   ds , ax
        mov   es , cx

        ;backup old interupt vactor
        mov   ax , V_Com1VactOfs
        mov   cx , V_Com1VactSeg
        mov   V_OldComVactOfs , ax
        mov   V_OldComVactOfs , cx
        ;set interupt vactor
        cli
        mov   ax , offset Irq_Serial
        mov   cx , cs
        mov   V_Com1VactOfs , ax
        mov   V_Com1VactSeg , cx
        ;set interupt mask
        in    al , 21h
        and   al , 0EFh
        out   21h , al
        sti
        ;serial prot initialize
        assume  es:SgBiosData   ;segment set
        mov   ax , SgBiosData
        mov   es , ax

        ;set com port set
        mov   ax , V_Com1Port
        mov   bx , offset V_ComDataPort
        mov   cx , 7
        .repeat
          mov   word ptr ds:[bx] , ax
          add   bx , 2    ;next register pointer
          inc   ax        ;next port address
        .untilcxz

        ;set boud rate , parrity , data length , stop bit
        mov   dx , V_ComLineCtrlPort
        mov   al , 83h    ;boud rate setting and none parrity ,
        out   dx , al     ;1 stop bit , 8bit data
        mov   dx , V_ComDataPort
        mov   al , 0Ch    ;9600 bps
        out   dx , al
        mov   dx , V_ComIntEnablePort
        xor   ax , ax
        out   dx , al

        ;set interupt
        mov   dx , V_ComLineCtrlPort
        mov   al , 3
        out   dx , al   ;data io mode
        mov   dx , V_ComIntEnablePort
        mov   al , 1    ; data receved only
        out   dx , al

        ;set  modem controler
        mov   dx , V_ComModemCtrlPort
        mov   al , 1011b    ;enable interupt and RTS,DTR
        out   dx , al

        ret

  init_serial endp
  ;-----------------------------------------------------------
  Irq_Serial  proc far
        ;protect register
        push  ax
        push  dx
        push  ds
        ;set segment
        assume  ds:data
        mov   ax , data
        mov   ds , ax
        ;when recive do set input charactor
        mov   dx , V_ComIntStatPort
        in    al , dx
        .if al & 100b    ;interupt generate and recive data?
          ;set data
          mov   dx , V_ComDataPort
          in    al , dx
          invoke EnQueue, al
        .endif
        ;set EOI
        mov   al , 20h
        out   20h , al
        ;restore register
        pop   ds
        pop   dx
        pop   ax

        iret

  Irq_Serial  endp

  EnQueue PROC MyValue:BYTE
    pusha
   
    assume ds:data       
    mov ax, data        ;
    mov ds, ax            ; 데이터 세그먼트 설정


    cmp QueueSize, QUEUE_MAX_BUFFER    ; 현재버퍼크기 >= 최대버퍼크기
    jge LABEL_BufferFull        ; 버퍼가 꽉 찻으므로 종료

    cmp Position, QUEUE_MAX_BUFFER    ;
    jl  LABEL_PositionNext        ; 데이터인덱스 < 최대버퍼크기
    mov Position, 0            ; Postion = 0

    LABEL_PositionNext:
    mov ah, Position        ;----------------------------------
    mov al, QueueSize        ; TempPos = Position + QueueSize
    add ah, al            ;
    mov TempPos, ah            ;----------------------------------

    cmp TempPos, QUEUE_MAX_BUFFER    ;
    jl  LABEL_TempPosChange        ; TempPos < 최대버퍼크기
    sub TempPos, QUEUE_MAX_BUFFER    ; TempPos = TempPos - 최대버퍼크기

    LABEL_TempPosChange:
    mov ah, MyValue            ;----------------------------------        
    xor bx, bx            ; 지정된 위치에 데이터 넣기
    mov bl, byte ptr TempPos    ;
    mov Queue[bx], ah        ;----------------------------------
       
    inc QueueSize            ; 현재버퍼크기 1 증가
    LABEL_Exit:
   

    popa
    ret

    LABEL_BufferFull:
       
    ;버퍼가 가득 차면 현재큐내용을 보여주고 초기화
    ShowAllQueueDebugString

    mov QueueSize, 0
    mov TempPos, 0
    mov Position, 0

    NextLine
            ;
       
    popa
    ret
    EnQueue ENDP


    ;-------------------------------------------------------------------
    ;
    ;    큐에서 값 하나를 꺼낸다.
    ;   
    ;    인자 :
    ;    리턴 : DL -> 큐에서 꺼낸 값
    ;
    ;-------------------------------------------------------------------
    DeQueue PROC
    push ax                ;-----------------------------
    push ds                ; 레지스터 보호
    push bx                ; ax, ds, bx, si, cx
    push si                ;
    push cx                ;-----------------------------
       
    assume ds:data           
    mov ax, data        ;
    mov ds, ax            ; 데이터 세그먼트 초기화
       
    cmp QueueSize, 0        ;
    jz  LABEL_BufferEmpty        ; 큐에 내용이 없으면 Buffer UnderFlow

    xor bx, bx            ;
    mov bl, byte ptr Position    ; 가져 올 값의 인덱스 구하기 -> BL
               

   
       
    mov dl, Queue[bx]        ; 구한 인덱스릐 큐 값을 DL에 넣는다. -> DL
    mov Queue[bx], 0        ; 값을 빼고 빈자리에 'x'를 넣는다.

    inc Position            ; 인덱스를 다음 값의 위치로 셋팅
    dec QueueSize            ; 큐 사이즈를 하나 줄인다.


   

    pop cx                ;---------------------------------
    pop si                ; 레지스터 복원
    pop bx                ; cx, si, bx, ds, ax
    pop ds                ;
    pop ax                ;---------------------------------
               
    ret

    LABEL_BufferEmpty:
   
       
    ShowAllQueueDebugString

    mov QueueSize, 0
    mov TempPos, 0
    mov Position, 0

    NextLine



    pop cx                ;---------------------------------
    pop si                ; 레지스터 복원
    pop bx                ; cx, si, bx, ds, ax
    pop ds                ;
    pop ax                ;---------------------------------
               

    ret
    DeQueue ENDP   

;-----------------------------------------------------------
code    ends
;-----------------------------------------------------------

        end   main

Posted by houdinist