
; Kon-B00t VGA display code
; executed at 0000h:2C00h

; es:bx = 9XXXh:0000h, 65 KB allocated memory & 128 sectors read in there, data
;   2 sectors     from sector LBA 10
;   126 sectors   from sector LBA 12
;   128 sectors = 64 KB, most probably some picture data
; ds:0000h = picture data (like es)

; this module handles VGA display

00000000  90                nop

; display the initial picture (the picture data is passed in ds:0000h)
00000001  E8B300            call word Display_Raw_Picture
00000004  E80201            call word Clear_768_bytes_Buffer                    ; clear 768 bytes after the picture

; get the current video mode
00000007  B40F              mov ah,0Fh                                          ; Function 0Fh = Get Current Video Mode
00000009  CD10              int 0x10                                            ; Video Interrupt, al = display mode, bh = active page
0000000B  50                push ax                                             ; remember the display mode (al)
0000000C  1E                push ds

; set the video mode to 13h = T  40x25  9x16  360x400   16   8   B800 VGA
0000000D  B81300            mov ax,0013h                                        ; Function 00h = Set Video Mode
00000010  CD10              int 0x10

; reset the palette using the zeroed 768 bytes
00000012  E8DB00            call word Set_VGA_Palette

; display the picture using the new video mode
00000015  E89F00            call word Display_Raw_Picture

; set a new palette
00000018  33DB              xor bx,bx                                           ; palette multipler = 0+
Loop_Palette_1:
0000001A  E85701            call word Wait_For_Vertical_Retrace_Sync
0000001D  E82301            call word Clone_Palette
00000020  E8CD00            call word Set_VGA_Palette
00000023  B80A00            mov ax,10
00000026  E8EE00            call word Wait_Refresh_Cycle                        ; wait 10 refresh cycles
00000029  43                inc bx                                              ; next time
0000002A  83FB20            cmp bx,byte +0x20                                   ; 20 times
0000002D  75EB              jnz Loop_Palette_1

0000002F  E85001            call word Get_Font_Pointer
00000032  33DB              xor bx,bx

Show_User_Interface_Animation:
00000034  E85B01            call word Display_KryptosLogic_Message              ; display the message
00000037  B8F000            mov ax,0xf0
0000003A  E8DA00            call word Wait_Refresh_Cycle                        ; wait 240 refresh cycles
0000003D  1E                push ds
0000003E  06                push es
0000003F  1F                pop ds                                              ; set ds to es
00000040  E87400            call word Display_Raw_Picture
00000043  1F                pop ds
00000044  43                inc bx                                              ; multiplier for the displayed message position
00000045  83FB0A            cmp bx,byte +0xa                                    ; within range (10)?
00000048  7C02              jl Within_Range
0000004A  33DB              xor bx,bx                                           ; otherwise wrap around
Something_1:
0000004C  B401              mov ah,0x1                                          ; 01h Check For Keystroke
0000004E  CD16              int 0x16
00000050  74E2              jz Show_User_Interface_Animation                    ; if not, repeat
00000052  1F                pop ds

; set another palette
00000053  BB2000            mov bx,0x20                                         ; palette multiplier = 32-
Loop_Palette_2:
00000056  E81B01            call word Wait_For_Vertical_Retrace_Sync
00000059  E8E700            call word Clone_Palette
0000005C  E89100            call word Set_VGA_Palette
0000005F  B80A00            mov ax,10
00000062  E8B200            call word Wait_Refresh_Cycle                        ; wait 10 refresh cycles
00000065  4B                dec bx                                              ; next time
00000066  75EE              jnz Loop_Palette_2

; wait for a keypress
00000068  32E4              xor ah,ah                                           ; Function 00h = Get Keystroke
0000006A  CD16              int 0x16                                            ; Keyboard Interrupt

; reset to the original video mode
0000006C  58                pop ax                                              ; restore the original mode
0000006D  B400              mov ah,0x0                                          ; Function 00h = Set Video Mode
0000006F  CD10              int 0x10                                            ; Video Interrupt

; return to the boot sector
00000071  6A00              push byte +0x0                                      ; segment = 0000h
00000073  68937C            push word 0x7c93                                    ; offset = 7C93h

00000076  CB                retf


; some interesting data:
00000077  FPU_Data_1        dw  00B4h
00000079  FPU_Data_2        dw  0000h
0000007B  FPU_Data_3        dw  0004h
0000007D  FPU_Data_4        dw  0005h
0000007F  FPU_Data_5        dw  0130h               ; some pixel position multiplier
00000081  FPU_Data_6        dw  0005h

; some interesting FPU function:
00000083  9BDBE3            finit
00000086  2EDF06772C        fild word [cs:FPU_Data_1]
0000008B  D9EB              fldpi
0000008D  DEF9              fdivp st1
0000008F  2EDF067D2C        fild word [cs:FPU_Data_4]
00000094  DEC9              fmulp st1
00000096  2EDF067F2C        fild word [cs:FPU_Data_5]
0000009B  DEC9              fmulp st1
0000009D  2EDF06812C        fild word [cs:FPU_Data_6]
000000A2  DEC1              faddp st1
000000A4  D9FE              fsin
000000A6  2EDF067B2C        fild word [cs:FPU_Data_3]
000000AB  DEC9              fmulp st1
000000AD  2EDF1E792C        fistp word [cs:FPU_Data_2]
000000B2  2EA1792C          mov ax,[cs:FPU_Data_2]                              ; return value in ax
000000B6  C3                ret


Display_Raw_Picture:

; copys a raw picture from ds:0000h to A000h:0000h
; picture must be 360*400 resolution with 4 bits per pixel

000000B7  06                push es                                             ; of course store register contents
000000B8  60                pushaw

000000B9  B800A0            mov ax,0A000h                                       ; = VGA buffer
000000BC  8EC0              mov es,ax                                           ; es will point to it

000000BE  33FF              xor di,di                                           ; destination = A000h:0000h
000000C0  33F6              xor si,si                                           ; source = ds:0000h
000000C2  B9007D            mov cx,0x7d00                                       ; size = 32000 * 2 bytes
000000C5  FC                cld
000000C6  F3A5              rep movsw                                           ; copy!

000000C8  61                popaw                                               ; restore the register contents
000000C9  07                pop es
000000CA  C3                ret


Erase_VGA_memory:                                                               ; (unused)

; erasing the VGA memory
000000CB  06                push es
000000CC  60                pushaw
000000CD  B800A0            mov ax,0A000h                                       ; = VGA buffer
000000D0  8EC0              mov es,ax
000000D2  33FF              xor di,di
000000D4  33C0              xor ax,ax                                           ; store zeroes
000000D6  B9007D            mov cx,0x7d00                                       ; size = 32000 * 2 bytes
000000D9  FC                cld
000000DA  F3AB              rep stosw

000000DC  61                popaw                                               ; restore the register contents
000000DD  07                pop es

000000DE  C3                ret


Set_VGA_Palette_2:                                                              ; (unused)
; sets a new palette (source = ds:FC00h) using the Digital-Analog Converter Registers
000000DF  32C0              xor al,al                                           ; register zero = Palette
000000E1  BAC803            mov dx,0x3c8                                        ; 3C8h  PEL Address Register
000000E4  EE                out dx,al                                           ; select register 0, writing palette to data port
000000E5  42                inc dx                                              ; 3C8h  PEL Address Register
000000E6  B90003            mov cx,768                                          ; data (palette) size = 768 bytes
000000E9  BE00FC            mov si,0xfc00                                       ; ds:FC00h (FF00h was the first palette)
000000EC  F36E              rep outsb                                           ; write out
000000EE  C3                ret

000000EF  C3                ret                                                 ; JUNK


Set_VGA_Palette:
; sets a new palette (source = ds:FF00h) using the Digital-Analog Converter Registers
000000F0  1E                push ds
000000F1  8CD8              mov ax,ds                                           ; get data segment
000000F3  05F00F            add ax,0xff0                                        ;  + FF0h, =  + 63,75 KB
000000F6  BE0000            mov si,0x0                                          ; offset = 0000h
000000F9  8ED8              mov ds,ax                                           ; segment = somewhere at end of memory + 0FF0h
000000FB  32C0              xor al,al                                           ; register zero = Palette
000000FD  BAC803            mov dx,0x3C8                                        ; 3C8h  PEL Address Register
00000100  EE                out dx,al                                           ; select register 0, writing palette to data port
00000101  42                inc dx                                              ; 3C9h  PEL Data Register
00000102  B90003            mov cx,768                                          ; data (palette) size = 768 bytes
00000105  F36E              rep outsb                                           ; write out!
00000107  1F                pop ds
00000108  C3                ret


Clear_768_bytes_Buffer:
; clearing es:di
00000109  06                push es                                             ; store es even it won't be modified
0000010A  8CC0              mov ax,es                                           ;   this is a joke
0000010C  8EC0              mov es,ax                                           ;   is it (these 2 instructions have no effect)
0000010E  B90003            mov cx,768                                          ; size = 768 bytes
00000111  32C0              xor al,al                                           ; overwrite it with zeroes
00000113  F3AA              rep stosb
00000115  07                pop es
00000116  C3                ret


Wait_Refresh_Cycle:
; waits for refresh cycles, must be eax * 19E5h / 64h times
00000117  60                pushaw
00000118  66BBE5190000      mov ebx,0x19e5
0000011E  66B964000000      mov ecx,0x64
00000124  66F7E3            mul ebx                                             ; * 19E5h
00000127  66F7F1            div ecx                                             ; / 64h
0000012A  668BC8            mov ecx,eax
0000012D  E461              in al,0x61                                          ; System Control Port
0000012F  2410              and al,00010000b                                    ; bit 4: toggles with each refresh request
00000131  8AE0              mov ah,al
Wait_Refresh_Cycle_Loop:
00000133  E461              in al,0x61                                          ; System Control Port
00000135  2410              and al,00010000b                                    ; bit 4: toggles with each refresh request
00000137  3AC4              cmp al,ah                                           ; always a full refresh cycle (1 to 0 and 0 to 1)
00000139  74F8              jz Wait_Refresh_Cycle_Loop
0000013B  8AE0              mov ah,al
0000013D  6649              dec ecx                                             ; in a loop
0000013F  75F2              jnz Wait_Refresh_Cycle_Loop
00000141  61                popaw
00000142  C3                ret


Clone_Palette:
; bl = multiplier (x16) for each palette color
00000143  06                push es                                             ; of course store segment registers
00000144  1E                push ds
00000145  33C0              xor ax,ax                                           ; (junk code)
00000147  8CC0              mov ax,es
00000149  05F00F            add ax,0xff0                                        ;  + FF0h, palette 1
0000014C  BF0000            mov di,0x0                                          ; (destination offset = 0000h)
0000014F  8EC0              mov es,ax
00000151  8CD8              mov ax,ds
00000153  05C00F            add ax,0xfc0                                        ;  + FC0h, palette 2
00000156  BE0000            mov si,0x0                                          ; (source offset = 0000h)
00000159  8ED8              mov ds,ax
0000015B  33ED              xor bp,bp                                           ; bp will be used as index
Multiply_Palette_Loop:
0000015D  33C0              xor ax,ax
0000015F  3E8A02            mov al,[ds:bp+si]                                   ; get source palette color
00000162  F6E3              mul bl                                              ; multiplier
00000164  C1E805            shr ax,0x5                                          ; * 16
00000167  268803            mov [es:bp+di],al                                   ; store the modified color
0000016A  45                inc bp                                              ; next palette color
0000016B  81FD0003          cmp bp,768                                          ; already the whole palette?
0000016F  75EC              jnz Multiply_Palette_Loop
00000171  1F                pop ds                                              ; restore segment registers
00000172  07                pop es
00000173  C3                ret


Wait_For_Vertical_Retrace_Sync:
; waits until vertrical retrace is cleared
00000174  BADA03            mov dx,0x3da                                        ; 3DAh Input Status #1 Register
Vertical_Retrace_loop:
00000177  EC                in al,dx                                            ; (read it)
00000178  A808              test al,00001000b                                   ;      bit 3: Vertical Retrace in progress if set
0000017A  75FB              jnz Vertical_Retrace_loop                           ; wait until it is synced
Vertical_Retrace_loop2:
0000017C  EC                in al,dx                                            ; second time
0000017D  A808              test al,00001000b
0000017F  74FB              jz Vertical_Retrace_loop2
00000181  C3                ret


Get_Font_Pointer:
00000182  06                push es
00000183  55                push bp
00000184  B83011            mov ax,0x1130                                       ; 11h = Get Font Information
00000187  B703              mov bh,0x3                                          ; 03h ROM 8x8 double dot font pointer
00000189  CD10              int 0x10                                            ; get it
0000018B  8BF5              mov si,bp                                           ; ES:BP = specified pointer
0000018D  5D                pop bp
0000018E  06                push es                                             ; ds:bp will point to the font table
0000018F  1F                pop ds
00000190  07                pop es
00000191  C3                ret


Display_KryptosLogic_Message:
00000192  60                pushaw
00000193  BFE92D            mov di,KryptosLogic_Message                         ; write out the message
00000196  33ED              xor bp,bp                                           ; index
00000198  2E8B0E7F2C        mov cx,[cs:FPU_Data_5]                              ; initial value 304
0000019D  49                dec cx                                              ; -1
0000019E  83E909            sub cx,9                                            ; -9 (why not)
000001A1  51                push cx                                             ; store that initial value

Next_Message_Character:
000001A2  83C107            add cx,7                                            ; +7, pixelz?
000001A5  81F93001          cmp cx,0x130                                        ; in the range?
000001A9  7F2B              jg End_Text_Message
000001AB  83F900            cmp cx,byte +0x0                                    ; negative value?
000001AE  7E23              jng Next_Character
000001B0  81FDE800          cmp bp,233-1                                        ; index > strlen(Message)?
000001B4  7F20              jg End_Text_Message                                 ; if yes done!
000001B6  2E8A3B            mov bh,[cs:bp+di]                                   ; otherwise get the next character
000001B9  2E890E7F2C        mov [cs:FPU_Data_5],cx                              ; store some run data
000001BE  33C0              xor ax,ax
000001C0  B3FF              mov bl,0xff
000001C2  8BD1              mov dx,cx
000001C4  05AF00            add ax,0xaf
000001C7  E80801            call word Display_Text_In_Line
000001CA  40                inc ax
000001CB  4A                dec dx
000001CC  B370              mov bl,0x70
000001CE  8BD1              mov dx,cx
000001D0  E8FF00            call word Display_Text_In_Line
Next_Character:
000001D3  45                inc bp                                              ; next character (index++)
000001D4  EBCC              jmp short Next_Message_Character                    ; to print out

End_Text_Message:
000001D6  2E8F067F2C        pop word [cs:FPU_Data_5]                            ; restore that initial value
000001DB  83F920            cmp cx,byte +0x20                                   ; if cx > 20h
000001DE  7F07              jg End_Text_Message_Done
000001E0  2EC7067F2C3001    mov word [cs:FPU_Data_5],0x130                      ; restore original value
End_Text_Message_Done:
000001E7  61                popaw
000001E8  C3                ret


; 1E9h
KryptosLogic_Message:
db  "KryptosLogic.com proudly presents, a Piotr Bania project: -> KON-BOOT <- a Windows and Linux password hacking utility"
db  "                    *** stay tuned for new releases!!! ***     >>> www.kryptoslogic.com ..... www.piotrbania.com <<<"



Display_Text_In_Line:                                                           ; or something

; store register contents
000002D2  06                push es
000002D3  60                pushaw

000002D4  6800A0            push word 0xA000                                    ; = VGA buffer
000002D7  07                pop es                                              ; es will point to it

000002D8  52                push dx
000002D9  69C04001          imul ax,ax,word 0x140                               ; pixel position * width (320)
000002DD  5A                pop dx
000002DE  8BF8              mov di,ax                                           ; destination
000002E0  03FA              add di,dx                                           ; + line offset
000002E2  0FB6C7            movzx ax,bh
000002E5  C1E003            shl ax,0x3
000002E8  03F0              add si,ax
000002EA  8AC3              mov al,bl
000002EC  B90800            mov cx,8                                            ; 8 lines

Next_Line:
000002EF  8A1C              mov bl,[si]
000002F1  B401              mov ah,0x1
000002F3  BD0700            mov bp,0x7
000002F6  84DC              test ah,bl
000002F8  7403              jz 0x2fd
000002FA  268803            mov [es:bp+di],al
000002FD  D0E4              shl ah,1
000002FF  4D                dec bp
00000300  73F4              jnc 0x2f6
00000302  46                inc si
00000303  81C74001          add di,320                                          ; next line, +320 pixels
00000307  E2E6              loop Next_Line

; restore register contents and exit
00000309  61                popaw
0000030A  07                pop es

0000030B  C3                ret


; fill with nops
times 1024-($-$$) db 90h
