; pf.asm
bits 16
global tmpmain
global Putcharrm
global Putcharpm
global Move
global Set

buff: times 0x08 db 0x00

tmpmain:
    mov ax,500
    push ax
    mov ax,0xff
    push ax
    mov ax,buff
    push ax
    call dec2str
    add sp,0x06
    mov bx,buff

 .loop:
    nop
    jmp .loop

; Putcharrm :: int8 -> void
Putcharrm:
    enter 0x00,0x000
    push bx

    mov ax,[bp+4]
    mov ah,0x0e
    xor bx,bx
    int 0x10

    pop bx
    leave
    ret

; Putcharpm :: int8 -> void
    enter 0x00,0x00

    mov ax,[bp+4]
    out byte 0xe9,al

    leave
    ret

; dec2str :: int8 *buf -> int8 sz -> int16 num -> void
dec2str:
   enter 0x08,0x00
   %define buf       bp-6
   %define divisor   bp-8
   ;pusha

   mov ax,10000
   mov word [divisor],ax

   mov di,0x0005
   push di
   xor ax,ax
   mov byte al,'0'
   push ax
   lea di,[buf]
   ;mov di,buf
   push di
   call Set
   mov sp,0x06

   lea di,[buf]
   ;mov di,buf
   add di,0x05
   mov byte [di],0x00

   lea di,[buf]       ; di=buf
   ;mov di,buf       ; di=buf
   mov ax,[bp+6]
   xor bx,bx
   mov bl,al           ; bl =sz
   mov si,[bp+8]       ; si=num

   mov cx,0x04
   xor dx,dx

 .loop:
    cmp bl,0x00
    jz .end
    dec bl

    mov ax,si
    mov word si,[divisor]
    xor dx,dx
    div si
    mov si,dx
    add al,0x30
    or ax,0x00ff
    stosb

    mov word ax,[divisor]
    xor dx,dx
    push cx
    mov cx,10
    div cx
    pop cx
    mov word [divisor],ax
    loop .loop

 .end:
   xor ax,ax
   mov al,dl
   add al,0x30
   or ax,0x00ff
   stosb

   lea di,[buf]
   ;mov di,buf
 .lp:
   nop
   jmp .lp

   mov bx,di
   xor ax,ax
   mov al,'0'
   repe scasb
   mov dx,di
   sub dl,bl       ; dl = # of zeroes to remove
   xor bx,bx
   mov bl,0x05
   sub bl,dl       ; bl = # bytes to copy
   mov si,di       ; si = src
   mov di,[bp+4]   ; di = dst

   push bx
   push si
   push di
   call Move
   add sp,0x06

   ;popa
   add sp,0x08
   leave
   ret

; hex2str :: int8 *buf -> int8 sz -> int16 num -> void
hex2str:
    enter 0x00,0x00
    ;pusha

    mov di,0x04
    push di
    xor ax,ax
    mov byte al,'0'
    push ax
    mov di,[bp+4]
    push di
    call Set
    mov sp,0x06

    add di,0x03        ; di=dst      
    mov ax,[bp+6]
    xor bx,bx
    mov bl,al           ; bl =sz
    mov si,[bp+8]       ; si=num

    mov cx,0x04
    xor dx,dx
 .loop:
    cmp bl,0x00
    jz .end
    dec bl

    mov dx,si
    shr si,0x04
    and dx,0x0f

    cmp dl,0x09
    jg .hex

 .dec:
    add dl,0x30
    jmp .next

 .hex:
    add dl,(0x66-0x0f)

 .next:
    mov byte [di],dl
    dec di
    loop .loop

 .end:
   ;popa
   leave
   ret

; move :: int8 *dst -> int8 src -> int16 n -> int16
Move:
   enter 0x00,0x00
   push cx
   push di
   push si

   mov di,[bp+4]     ; di=dest
   mov si,[bp+6]     ; si=src
   mov cx,[bp+8]     ; cx=counter
   mov ax,cx

   rep movsb

   pop si
   pop di
   pop cx

   leave
   ret

; Set :: int8 *dst -> int8 ch -> int16 n -> void
Set:
   enter 0x00,0x00
   push bx
   push cx
   push di

   mov di,[bp+4]     ; di=dst
   mov bx,[bp+6]
   xor ax,ax
   mov al,bl         ; al=ch
   mov cx,[bp+8]     ; cx=count

   rep stosb

   pop di
   pop cx
   pop bx

   leave
   ret



