start:
    ; rsp points *at* the top element
    mov rbp, 2048
    mov rsp, 2048 - 2

    lit interrupt_table
    or rfl, rfl, 1 << Fl_Int

    or rfl, Rfl, 1 << Fl_Vcd

    mov16 r0, 512
    mov16 r1, 1
    int Int_DiskRead

main_loop:
    hlt
    jmp main_loop

interrupt_table:
    ; size
    d16 1 
    data keyboard_interrupt
    nop

keyboard_interrupt:
    and rfl, rfl, !(1 << Fl_Int)
    ; push rbp
    add rsp, rsp, 2
    mov u16 [rsp], rbp
    mov rbp, Rsp
    ; push r0
    add rsp, rsp, 2
    mov u16 [rsp], r0
    ; push r1
    add rsp, rsp, 2
    mov u16 [rsp], r1
    ; push r2
    add rsp, rsp, 2
    mov u16 [rsp], r2
    ; push r3
    add rsp, rsp, 2
    mov u16 [rsp], r3

    in r0, Device_Keyboard

    cmp r0, 44
    mov r1, rfl
    and r1, r1, 1 << Fl_Eq
    jnz r1, .L0

    cmp r0, 42
    mov16 r1, rfl
    and r1, r1, 1 << Fl_Eq
    jnz r1, .L1

    cmp r0, 40
    mov r1, rfl
    and r1, r1, 1 << Fl_Eq
    jnz r1, .L2

    jmp .L3

.L0:
    mov R0, ' '
    call put_char
    jmp .L4

.L1:
    mov r1, screen_x
    cmp r1, 0
    mov r2, rfl
    and r2, r2, 1 << Fl_Eq
    jnz r2, .L4
    sub r1, r1, 1
    mov screen_x, R1
    ; mov r0, ' '
    call put_char
    mov16 r1, screen_x
    sub r1, r1, 1
    mov screen_x, R1
    jmp .L4

.L2:
    mov r1, screen_y
    add r1, r1, 1
    mov screen_y, R1
    mov r1, 0
    mov screen_x, R1
    jmp .L4

.L3:
    add r0, r0, 'A' - 4
    call put_char
    jmp .L4

.L4:

    ; pop r3
    mov r3, u16 [rsp]
    sub rsp, rsp, 2
    ; pop r2
    mov r2, u16 [rsp]
    sub rsp, rsp, 2
    ; pop r1
    mov r1, u16 [rsp]
    sub rsp, rsp, 2
    ; pop r0
    mov r0, u16 [rsp]
    sub rsp, rsp, 2
    mov rsp, rbp
    ; pop rbp
    mov rbp, u16 [rsp]
    sub rsp, rsp, 2
    or rfl, rfl, 1 << Fl_Int
    iret

put_char:
    ; push rbp
    add rsp, rsp, 2
    mov u16 [rsp], rbp
    mov rbp, rsp
    ; push r1
    add rsp, rsp, 2
    mov u16 [rsp], r1
    ; push r2
    add rsp, rsp, 2
    mov u16 [rsp], r2

    mov r2, screen_y
    mul r2, r2, vcd_width_in_ch
    mov r1, screen_x
    add r1, r1, 0x0c00
    add r1, r1, r2
    mov r1, r0

    mov r1, screen_x
    add r1, r1, 1
    mov screen_x, r1

    cmp r1, vcd_width_in_ch
    mov r2, rfl
    and r2, r2, 1 << Fl_Eq
    jnz r2, .L0
    jmp .L1

.L0:
    mov r1, screen_y
    add r1, r1, 1
    mov screen_y, r1
    mov r1, 0
    mov screen_x, r1

.L1:
    ; pop r1
    mov r1, u16 [rsp]
    sub rsp, rsp, 2
    ; pop r2
    mov r2, u16 [rsp]
    sub rsp, rsp, 2
    mov rsp, rbp
    ; pop rbp
    mov rbp, u16 [rsp]
    sub rsp, rsp, 2
    ret

screen_x:
    d16 0
screen_y:
    d16 0

; vim: syntax=nasm