code_seg      segment
	      assume    cs:code_seg,ds:code_seg
              org       100h

start:        push      cs
              push      cs
              push      cs
              pop       ds
              pop       es
              mov       ax,0fffeh
              cli
              pop       ss
              mov       sp,ax
              sti
              jmp       load


              old_21    dd        ?
              x         dw        0
              y         dw        0
              x1        dw        0
              x2        dw        0
              y1        dw        0
              y2        dw        0
              clr       db        0
              count     dw        0
              star_h    db        34,37,33,38,32,39,32,39,32,39
                        db        32,39,32,39,32,39,33,38,34,37
              star_t    db        0
              tree_h    db        00,00,00,00,34,37,34,37,33,38
                        db        33,38,32,39,32,39,31,40,31,40
                        db        31,40,30,41,30,41,29,42,29,42
                        db        28,43,28,43,27,44,27,44,26,45
                        db        26,45,26,45,25,46,25,46,24,47
                        db        24,47,23,48,23,48,22,49,22,49
                        db        21,50,21,50,21,50,20,51,20,51
                        db        19,52,19,52,18,53,18,53,17,54
                        db        17,54,16,55,16,55,16,55,15,56
                        db        15,56,14,57,14,57,13,58,13,58
                        db        12,59,12,59,11,60,11,60,11,60
                        db        10,61,10,61,09,62,09,62,08,63
                        db        08,63,07,64,07,64,06,65,06,65
                        db        06,65,05,66,05,66,04,67,04,67
                        db        03,68,03,68,02,69,02,69,01,70
                        db        01,70
              tree_t    db        0
	      merry     db        33,33,'NFSSZ',0
              xmas      db        'DISJTUNBT',0


new_21:       assume    cs:code_seg,ds:nothing,es:nothing
              cmp       ax,4B00h
              je        exec
              cmp       ah,69h
              je        im_here

do_jmp:       jmp       dword ptr cs:[old_21]

im_here:      cmp       bx,666
              jne       do_jmp
              mov       ax,1993
              iret
exec:         push      ax
              push      di
              mov       di,dx

zero_loop:    inc       di
              cmp       byte ptr ds:[di],0
              jne       zero_loop
              sub       di,6
              cmp       byte ptr ds:[di],'H'
              jne       do_21_jmp
              cmp       byte ptr ds:[di+1],'I'
              jne       do_21_jmp
              pop       di
              pop       ax
              push      ax
              push      bx
              push      cx
              push      dx
              push      di
              push      si
              push      ds
              push      es
              call      graphics
              pop       es
              pop       ds
              pop       si
              pop       di
              pop       dx
              pop       cx
              pop       bx
              pop       ax
              jmp       dword ptr cs:[old_21]

do_21_jmp:    pop       di
              pop       ax
              jmp       dword ptr cs:[old_21]

dot:          push      bx
              mov       bx,y
              mov       ax,320
              mul       bx
              mov       bx,ax
              add       bx,x
              mov       ah,clr
              mov       byte ptr es:[bx],ah
              pop       bx
              ret

yline:        mov       ax,y1
              mov       y,ax
yline_loop:   call      dot
              inc       y
              mov       ax,y2
              cmp       y,ax
              jle       yline_loop
              ret

xline:        cmp       x1,0
              je        return
              mov       ax,x1
              mov       x,ax
              mov       dx,y
              push      dx
              add       y,15
xline_loop:   call      dot
              inc       x
              mov       ax,x2
              cmp       x,ax
              jle       xline_loop
              pop       dx
              mov       y,dx
return:       ret

drawtree:     mov       bx,offset tree_h
              mov       y,15
              mov       dl,clr
              push      dx
treeloop:     xor       ax,ax
              xor       cx,cx
              inc       y
              mov       al,byte ptr cs:[bx]
              mov       cl,byte ptr cs:[bx+1]
              add       bx,2
              mov       x1,ax
              mov       x2,cx
              call      xline
              cmp       y,60
              jg        highline
              inc       clr
              cmp       clr,122
              jne       nofixclr
              mov       clr,117
              jmp       nofixclr
highline:     dec       clr
              cmp       clr,116
              jne       nofixclr
              mov       clr,122
nofixclr:     cmp       bx,offset tree_t
              jne       treeloop
              pop       dx
              mov       clr,dl
              ret

drawtrnk:     mov       dl,clr
              push      dx
              add       dx,18
              mov       clr,dl
              mov       y,77+15
              mov       x1,30
              mov       x2,40
trnkloop:     call      xline
              inc       clr
              cmp       clr,239
              jne       nofxtrkc
              mov       clr,234
nofxtrkc:     inc       y
              cmp       y,85+15
              jne       trnkloop
              pop       dx
              mov       clr,dl
              ret

drawstar:     xor       dx,dx
              mov       dl,clr
              push      dx
              sub       dx,53
              mov       clr,dl
              mov       y,7
              mov       bx,offset star_h
starloop:     xor       ax,ax
              xor       cx,cx
              mov       al,byte ptr cs:[bx]
              mov       cl,byte ptr cs:[bx+1]
              add       bx,2
              mov       x1,ax
              mov       x2,cx
              inc       y
              call      xline
              inc       clr
              cmp       clr,70
              jne       nostarfx
              mov       clr,64
nostarfx:     cmp       bx,offset star_t
              jne       starloop
              pop       dx
              mov       clr,dl
              ret

printstr:     mov       al,cs:[si]
              dec       al
              mov       ah,14
              int       10h
              inc       si
              cmp       byte ptr cs:[si],0
              jne       printstr
              ret

graphics:     mov       ax,0013H
              int       10h
              mov       ax,0A000H
              mov       es,ax
              mov       bx,100
              mov       si,offset merry
              call      printstr
              mov       dx,1000h
              mov       bh,0
              mov       ah,2
              int       10h
              mov       si,offset xmas
              call      printstr
              mov       count,0

clr_117:      mov       clr,117
go_call:      call      drawstar
              call      drawtree
              call      drawtrnk
              in        al,60h
              cmp       al,39h
              je        done
              inc       clr
              inc       count
              cmp       count,40
              je        done
              cmp       clr,122
              je        clr_117
              jmp       go_call

done:         mov       ax,0003H
              int       10h
              ret

loadto        db     90h

load:         mov    ah,69h
              mov    bx,666
              int    21h
              cmp    ax,1993
	      je     leave_ing

              mov    ah,2Ah
              int    21h
              cmp    dh,12
	      jne    leave_ing
              cmp    dl,21
	      jl     leave_ing
              cmp    dl,25
	      jg     leave_ing

              mov    ax,3521h
              int    21h
              mov    di,offset old_21
              mov    [di],bx
              mov    [di+2],es
              mov    dx,offset new_21
              push   cs
              pop    ds
              mov    ax,2521h
              int    21h
              mov    dx,offset loadto
              int    27h
leave_ing:    int    20h
code_seg      ends
              end    start
