@; line plotting function
@; ----------------------

@; params:
@;   start  r0  preserved
@;   x1     r1
@;   y1     r2
@;   x2     r3  preserved
@;   y2     r4  [sp. #0]
@;   colour r5  [sp, #4]

@; regs:
@;   xd     r6
@;   xs     r7
@;   yd     r8
@;   ys     r9
@;   p      r10
@;   point  r11

@;   log2width r14
.set LOG2WIDTH, 7 @; width = 128

    .text
    .align 2

@; line plot
    .global line
line:
    stmfd   sp!, {r4-r11, lr} @; 9 regs
    ldr     r4, [sp, #36]  @; y2
    ldr     r5, [sp, #40]  @; colour

@; set up frame size and adjust parameters
    mov     r14, #LOG2WIDTH

    subs    r6, r3, r1
    rsbmi   r6, r6, #0     @; xd = abs(x2-x1)
    mov     r7, #1
    rsbmi   r7, r7, #0     @; -1

    subs    r8, r4, r2
    rsbmi   r8, r8, #0     @; yd = abs(y2-y1)
    mov     r9, #1
    rsbmi   r9, r9, #0     @; -1

    cmp     r6, r8
    ble     line_steep

line_shallow:
    mov     r10, r6
    add     r8, r8, #1
line_shallow_loop:
    cmp     r3, r1
    ldmeqfd sp!, {r4-r11, pc} @; exit
@; plot (x1, y1)
    add     r11, r1, r2, lsl r14
    strb    r5, [r0, r11]
@; decide next point
    add     r1, r1, r7
    subs    r10, r10, r8
    bpl     line_shallow_loop
    add     r10, r10, r6
    add     r2, r2, r9
    b       line_shallow_loop

line_steep:
    mov     r10, r8
    add     r6, r6, #1
line_steep_loop:
    cmp     r4, r2
    ldmeqfd sp!, {r4-r11, pc} @; exit
@; plot (x1, y1)
    add     r11, r1, r2, lsl r14
    strb    r5, [r0, r11]
@; decide next point
    add     r2, r2, r9
    subs    r10, r10, r6
    bpl     line_steep_loop
    add     r10, r10, r8
    add     r1, r1, r7
    b       line_steep_loop
