format binary as 'img'

; --------------------------------------------------------------------------
; -- Constants
; --------------------------------------------------------------------------

    SECTOR_BOOT    = 0x7C00
    SECTOR_KERNEL  = 0x7E00;0x1000
    BIOS_SIGNATURE = 0xAA55

; -- GENERAL

    BYTE_LENGHTB  = 1	   ; in bytes
    BYTE_LENGHT   = 1 * 8  ; in bits
    WORD_LENGHTB  = 2
    WORD_LENGHT   = 2 * 8
    DWORD_LENGHTB = 4
    DWORD_LENGHT  = 4 * 8

; -- VIDEO
		  ; AARRGGBB
    COLOR_BLACK = 0x00000000
    COLOR_BLUE	= 0x000000FF
    COLOR_GREEN = 0x0000FF00
    COLOR_RED	= 0x00FF0000
    COLOR_WHITE = 0x00FFFFFF

    video_buf = 0x00010000
    video_ptr equ ModeInfoBlock.PhysBasePtr




; --------------------------------------------------------------------------
; -- Boot
; --------------------------------------------------------------------------

org 0
use16
	jmp boot

  ; Bios Parameter Block
  bpbOEM	       db "zero    " ; OEM identifier (Cannot exceed 8 bytes)
  bpbBytesPerSector    dw 512
  bpbSectorsPerCluster db 1
  bpbReservedSectors   dw 1
  bpbNumberOfFATs      db 2
  bpbRootEntries       dw 224
  bpbTotalSectors      dw 2880
  bpbMedia	       db 0xF0
  bpbSectorsPerFAT     dw 9
  bpbSectorsPerTrack   dw 18
  bpbHeadsPerCylinder  dw 2
  bpbHiddenSectors     dd 0
  bpbTotalSectorsBig   dd 0
  bsDriveNumber        db 0
  bsUnused	       db 0
  bsExtBootSignature   db 0x29
  bsSerialNumber       dd 0xa0a1a2a3
  bsVolumeLabel        db "MOS FLOPPY "
  bsFileSystem	       db "FAT12   "

    boot:

; -- reset segs

	mov ax,0x07C0
	mov ds,ax
	mov es,ax
	mov fs,ax
	xor ax,ax
	mov ss,ax
	mov sp,0xFFFF

; -- Read floppy disk

    @@: mov ah,0	   ; Reset floppy disk function
	mov dl,0	   ; drive 0 = floppy drive
	int 0x13	   ;
	jc  @b		   ; CF: 1 error, 0 ok

	mov bx,0x7E0	    ; ES:BX Buffer to read sectors to
	mov es,bx	   ; 0800:0000h ( ES = 0800h, BX = 0000h )
	xor bx,bx
	mov ah,2	   ; Reading Sectors
	mov al,1	   ; number of sectors to read
	mov ch,0	   ; track (cylinder) number
	mov cl,2	   ; sector (bits 0-5). (bits 6-7 HD only)
	mov dh,0	   ; head number
	mov dl,0	   ; drive number (00h = A:) (bit 7 set for hard disks)
	int 0x13	   ; Return: AH = status, AL = number of sectors read, CF = 1 failure, 0 successful

	mov dx,0x03F2	   ; -- Turn floppy off
	mov al,0
	out dx,al

	jmp (SECTOR_KERNEL shr 4):0

	; Fill this sector up  
	rb 510-($-$$)
	dw BIOS_SIGNATURE


; --------------------------------------------------------------------------
; -- Kernel 16bits
; --------------------------------------------------------------------------

org 0;SECTOR_KERNEL
use16
    kernel_16:

	push cs
	pop  ds
	mov ax,ds
	mov es,ax
	mov fs,ax
	mov gs,ax
	mov ss,ax
	mov sp,0xFFFF

; -- A20 enable

	mov ax,0x2401
	int 0x15

; -- VBE

	mov di,ModeInfoBlock
	mov ax,0x4F01
	mov cx,0x4145 ; 145 = 32bits
	int 10h

	;cmp byte[ModeInfoBlock.BitsPerPixel],32
	;je $

	mov ax,0x4F02
	mov bx,0x4145  ; 0x4000 = set LFB; 145 = 1280*1024*32bits
	int 10h

; -- load GDT

	cli
	lgdt [gdtr]

; -- enable PM (Protected Mode)

	mov eax,cr0
	or  eax,1
	mov cr0,eax    ; enable PM
	jmp 0x08:@f
align 4
@@:
use32
	hlt
	jmp $

	mov ax,0x10    ; GDT_DATA_SEGMENT_SELECTOR
	mov ds,ax
	mov es,ax
	mov fs,ax
	mov gs,ax
	mov ss,ax
	mov esp,0x00FFFFFF

; -- Kernel Go!!!


; --------------------------------------------------------------------------
; -- Kernel 32bits
; --------------------------------------------------------------------------

    kernel_32:



	mov  edi,[video_ptr]

	push COLOR_WHITE ; color
	push 2	 ; height
	push 2	; width
	push 50   ; y
	push 50   ; x
	call drawfillrect
	;mov  eax,-1
	;call drawchar2

	;hlt
	;jmp $






; --------------------------------------------------------------------------
; -- VGA
; --------------------------------------------------------------------------

;
; 0xFFFFFF = RGB
; FF,FF,FF = BGR
; 0x145    = 1280x1024x32bits(4bytes)
;
; -----------------------------------------------------------------------
; Functions:
;
; + putpixel: Put a pixel on the screen.
;       in     ( video_ptr edi, x ebx, y eax, color ecx )
;       change ( eax, edx, edi )
; + putpixel2: Put a pixel on the screen (other moveTo algoritm).
;       in     ( video_ptr edi, x ebx, y eax, color ecx )
;       change ( eax, ebp, edx )
; + clrscr: Clear screen.
;       in ( video_ptr edi, color eax )
;       change ( ecx )
; + moveTo: Move the video buffer position to x,y coord.
;       in     ( x ebx, y eax )
;       out    ( position edi )
;       change ( eax, edx, edi )
; + drawfillrect: Draw a filled rectangle.
;       in     ( video_ptr edi, x push, y push, width push, height push, color push )
;       change ( eax, ebx, ecx, edx, edi )
; -----------------------------------------------------------------------


; + moveTo: move the current video buffer position to x,y coord.
;       in     ( x ebx, y eax )
;       out    ( position edi )
;       change ( eax, edx, edi )

    moveToXY:
	mov edi,[video_ptr]
	mov edx,eax
	shl eax,10		; y * 1024  (y1)
	shl edx,8		; y * 256   (y2)
	add eax,edx		; y1 + y2   (y3)
	add eax,ebx		; y3 + x    (r)
	shl eax,2		; r * 4(bytes)
	add edi,eax		; (1024 * y + 256 * y + x) * 4
	ret

; + clrscr: Clear screen.
;       in ( video_ptr edi, color eax )
;       change ( ecx )

    clrscr:
	mov edi,[video_ptr]
	mov ecx,1280*1024
	rep stosd

	ret

; + putpixel: Put a pixel on the screen.
;       in     ( video_ptr edi, x ebx, y eax, color ecx )
;       change ( eax, edx, edi )

    putpixel:
	call moveToXY
	mov  dword[edi],ecx
	ret

; + putpixel2: Put a pixel on the screen (other moveTo algorithm).
;       in     ( video_ptr edi, x ebx, y eax, color ecx )
;       change ( eax, ebp, edx )

    putpixel2:
	mov ebp,ebx
	mov edx,[scr_width]
	mul edx 		; width * y
	add eax,ebp		; y + x     (r)
	mov edx,4
	mul edx 		; r * 4
	mov dword[edi+eax],ecx	; (width * y + x) * 4
	ret

; + drawfillrect: Draw a filled rectangle.
;       in     ( video_ptr edi, x push, y push, width push, height push, color push )
;       change ( eax, ebx, ecx, edx, edi )

    drawfillrect:
	mov  ebx,[esp+1*4] ;x
	mov  eax,[esp+2*4] ;y
	add  eax,[esp+4*4]
	call moveToXY
	mov  ecx,[esp+4*4] ;h
	mov  eax,[esp+5*4] ;c
	mov  edx,[esp+3*4] ;w
  .for: mov  ebx,edx
    @@: mov  dword[edi+ebx*4],eax ;c
	dec  ebx
	jnz  @b
	sub  edi,1280*4    ; goto next y:  y-width*4bytes (edi = y)
	dec  ecx
	jnz  .for
	ret  5*4

    drawchar2:
	mov  ebx,a
	xor  ecx,ecx
  .nxty:push ecx
			xor ecx,ecx
		.nxtx:	cmp dword[ebx],0
			je  @f
			mov dword[edi+ecx*4],-1 ; set color
		     @@:add ebx,4
			inc ecx
			cmp ecx,8
			jne .nxtx
	pop  ecx
	add  edi,1280*4
	inc  ecx
	cmp  ecx,8
	jne  .nxty
	ret

    drawchar:
	add  edi,1280*4*8
	add  edi,8*4
	mov  ebx,a
	add  ebx,8*8*4
	mov  ecx,8
  .nxty:push ecx
			mov  ecx,8
		.nxtx:	cmp dword[ebx],0
			je  @f
			mov dword[edi+ecx*4],-1 ; set color
		     @@:sub ebx,4
			dec ecx
			jns .nxtx
	pop  ecx
	sub  edi,1280*4
	dec  ecx
	jns  .nxty
	ret

    drawstring:
	mov   esi,text
    .nc:
	movzx ebx,byte[esi]
	test  ebx,ebx
	je    .done
	;sub   ebx,'a'
	;neg   ebx
	mov   ebx,[keys+4]  ; 0 = a, 4 = b ( theoricaly :( )
		xor ecx,ecx
	.for1:	push ecx ; height loop
			xor ecx,ecx
		.for2:	; width loop
			cmp dword[ebx+ecx*4],0
			je  @f
			mov dword[edi+ecx*4],-1 ; set color
		     @@:add ebx,4
			inc ecx
			cmp ecx,8
			jne .for2
		pop  ecx
		add ebx,8*4
		add edi,1280*4
		inc ecx
		cmp ecx,8
		jne .for1
	sub  edi,1280*4*8
	add  edi,8*4
	inc  esi
	jmp  .nc ; next char
 .done:
	ret

align 4

  text db 'ababba',0





; --------------------------------------------------------------------------
; -- Vars
; --------------------------------------------------------------------------


; -- System
align 4

gdtr:	dw gdt_size ; limit
	dd gdt	    ; base

align 4 ; important bits 1:0 are used for RPL when performing jmp
gdt:
	dq 0 ; 0x00 null descriptor
	;  (  limit  ) (     base     ) (P,DPL,DT,Type)(G,DB,0,AVL,limit)(base)
	db 0xFF, 0xFF, 0x00, 0x00, 0x00,  1001'1010b,	  1100'1111b,	  0x00 ; 0x08 code segment selector
	db 0xFF, 0xFF, 0x00, 0x00, 0x00,  1001'0011b,	  1100'1111b,	  0x00 ; 0x10 data segment selector
gdt_size = $-gdt-1

;idtr:   dw idt_size ; limit
;        dd idt      ; base
;align 4
;idt:
;        ;  (  base  ) (P,DPL,01110b ) (0) (selector) (base) ; selector = kernel segment
;        db 0x00, 0x00,  1000'1110b,    0, 0x00, 0x00, 0, 0
;        db 0x00, 0x00,  1000'1110b,    0, 0x00, 0x00, 0, 0
;idt_size = $-idt-1

align 4

	scr_width  dd 1280
	scr_height dd 1024
	scr_lenght dd 1280*1024*4

	keys dd a,b,0

a dd 0,0,0,0,0,0,0,0
  dd 0,0,0,0,0,0,0,0
  dd 0,0,1,1,1,0,0,0
  dd 0,0,0,0,0,1,0,0
  dd 0,0,1,1,1,1,0,0
  dd 0,1,0,0,0,1,0,0
  dd 0,1,0,0,0,1,0,0
  dd 0,0,1,1,1,0,1,0

b dd 0,1,1,0,0,0,0,0
  dd 0,0,1,0,0,0,0,0
  dd 0,0,1,0,0,0,0,0
  dd 0,0,1,0,1,1,1,0
  dd 0,0,1,1,0,0,0,1
  dd 0,0,1,0,0,0,0,1
  dd 0,0,1,1,0,0,0,1
  dd 0,1,1,0,1,1,1,0





; --------------------------------------------------------------------------
; -- Structs
; --------------------------------------------------------------------------

; -- VBE

    PMInfoBlock:

	.Signature	db 'PMID'  ; PM Info Block Signature
	.EntryPoint	dw ?	   ; Offset of PM entry point within BIOS
	.PMInitialize	dw ?	   ; Offset of PM initialization entry point
	.BIOSDataSel	dw 0	   ; Selector to BIOS data area emulation block
	.A0000Sel	dw 0xA000  ; Selector to access A0000h physical mem
	.B0000Sel	dw 0xB000  ; Selector to access B0000h physical mem
	.B8000Sel	dw 0xB800  ; Selector to access B8000h physical mem
	.CodeSegSel	dw 0xC000  ; Selector to access code segment as data
	.InProtectMode	db 0	   ; Set to 1 when in protected mode
	.Checksum	db ?	   ; Checksum byte for structure

	PMInfoBlockSize = $ - PMInfoBlock


    VbeInfoBlock:

	.VbeSignature	   db 'VESA'   ; VBE Signature
	.VbeVersion	   dw 0300h ; VBE Version
	.OemStringPtr	   dd ? ; VbeFarPtr to OEM String
	.Capabilities	   db 4 dup (?) ; Capabilities of graphics controller
	.VideoModePtr	   dd ? ; VbeFarPtr to VideoModeList
	.TotalMemory	   dw ? ; Number of 64kb memory blocks

	; Added for VBE 2.0+

	.OemSoftwareRev    dw ? ; VBE implementation Software revision
	.OemVendorNamePtr  dd ? ; VbeFarPtr to Vendor Name String
	.OemProductNamePtr dd ? ; VbeFarPtr to Product Name String
	.OemProductRevPtr  dd ? ; VbeFarPtr to Product Revision String
	.Reserved db 222   dup (?) ; Reserved for VBE implementation scratch

	;   area

	.OemData db 256    dup (?) ; Data Area for OEM Strings

	VbeInfoBlockSize = $ - VbeInfoBlock


    ModeInfoBlock:

	; Mandatory information for all VBE revisions

	.ModeAttributes      dw ? ; mode attributes
	.WinAAttributes      db ? ; window A attributes
	.WinBAttributes      db ? ; window B attributes
	.WinGranularity      dw ? ; window granularity
	.WinSize	     dw ? ; window size
	.WinASegment	     dw ? ; window A start segment
	.WinBSegment	     dw ? ; window B start segment
	.WinFuncPtr	     dd ? ; real mode pointer to window function
	.BytesPerScanLine    dw ? ; bytes per scan line

	; Mandatory information for VBE 1.2 and above

	.XResolution	     dw ? ; horizontal resolution in pixels or characters
	.YResolution	     dw ? ; vertical resolution in pixels or characters
	.XCharSize	     db ? ; character cell width in pixels
	.YCharSize	     db ? ; character cell height in pixels
	.NumberOfPlanes      db ? ; number of memory planes
	.BitsPerPixel	     db ? ; bits per pixel
	.NumberOfBanks	     db ? ; number of banks
	.MemoryModel	     db ? ; memory model type
	.BankSize	     db ? ; bank size in KB
	.NumberOfImagePages  db ? ; number of images
	.Reserved	     db 1 ; reserved for page function

	; Direct Color fields (required for direct/6 and YUV/7 memory models)

	.RedMaskSize	     db ? ; size of direct color red mask in bits
	.RedFieldPosition    db ? ; bit position of lsb of red mask
	.GreenMaskSize	     db ? ; size of direct color green mask in bits
	.GreenFieldPosition  db ? ; bit position of lsb of green mask
	.BlueMaskSize	     db ? ; size of direct color blue mask in bits
	.BlueFieldPosition   db ? ; bit position of lsb of blue mask
	.RsvdMaskSize	     db ? ; size of direct color reserved mask in bits
	.RsvdFieldPosition   db ? ; bit position of lsb of reserved mask
	.DirectColorModeInfo db ? ; direct color mode attributes

	; Mandatory information for VBE 2.0 and above

	.PhysBasePtr	     dd ? ; physical address for flat memory frame buffer
	.Reserved1	     dd 0 ; Reserved - always set to 0
	.Reserved2	     dw 0 ; Reserved - always set to 0

	; Mandatory information for VBE 3.0 and above

	.LinBytesPerScanLine   dw ? ; bytes per scan line for linear modes
	.BnkNumberOfImagePages db ? ; number of images for banked modes
	.LinNumberOfImagePages db ? ; number of images for linear modes
	.LinRedMaskSize        db ? ; size of direct color red mask (linear modes)
	.LinRedFieldPosition   db ? ; bit position of lsb of red mask (linear modes)
	.LinGreenMaskSize      db ? ; size of direct color green mask  (linear modes)
	.LinGreenFieldPosition db ? ; bit position of lsb of green mask (linear modes)
	.LinBlueMaskSize       db ? ; size of direct color blue mask  (linear modes)
	.LinBlueFieldPosition  db ? ; bit position of lsb of blue mask (linear modes)
	.LinRsvdMaskSize       db ? ; size of direct color reserved mask (linear modes)
	.LinRsvdFieldPosition  db ? ; bit position of lsb of reserved mask (linear modes)
	.MaxPixelClock	       dd ? ; maximum pixel clock (in Hz) for graphics mode
	.Reserved3   db 189 dup (?) ; remainder of ModeInfoBlock

	ModeInfoBlockSize = $ - ModeInfoBlock


    ;Fill the disk image up (1.4Mb)
    ;times (0x0167E00-($-kernel)) db 0



