Skip to content

Instantly share code, notes, and snippets.

@Trinitek
Created November 9, 2014 06:46
Show Gist options
  • Save Trinitek/098c9c9887d236d38539 to your computer and use it in GitHub Desktop.
Save Trinitek/098c9c9887d236d38539 to your computer and use it in GitHub Desktop.
Mode 0x13 tests using FASM's macro functions
; structure test
org 0x100
struc Point x,y {
.x dw x
.y db y
}
struc Line x1,y1,x2,y2 {
.pointA Point x1,y1
.pointB Point x2,y2
}
macro screenMode mode {
push ax
mov ax, mode
int 0x10
pop ax
}
macro fillScreen color {
push ax
push cx
push di
xor di, di
mov cx, 320*200
mov al, color
rep stosb
pop di
pop cx
pop ax
}
macro pointToPtr point {
mov ax, point
call proc_pointToPtr
}
macro drawLine startPoint,endPoint {
if startPoint in <si>
else
push si
mov si, startPoint
end if
if endPoint in <di>
else
push di
mov di, endPoint
end if
call proc_drawLine
if endPoint in <di>
else
pop di
end if
if startPoint in <si>
else
pop si
end if
}
macro pause {
push ax
xor ax, ax
int 0x16
pop ax
}
macro for lbl,start {
if start in <cx>
lbl:
push cx
else
mov cx, start
lbl:
push cx
end if
}
macro endFor lbl {
pop cx
loop lbl
}
; === code ===
main:
; set screen
screenMode 0x13
; setup vga pointers
mov ax, 0xA000
mov es, ax
xor di, di
; plot point to screen
pointToPtr pointA
mov di, ax
mov al, 15
stosb
pause
; display pattern
mov [pointA.x], 0
mov [pointA.y], 0
mov cx, 65535
.putPixel:
pointToPtr pointA
mov di, ax
mov al, 15
stosb
inc [pointA.x]
inc [pointA.y]
loop .putPixel
pause
; display filled box without macros
fillScreen 0
define originX 20
define originY 20
mov [pointA.x], originX
mov [pointA.y], originY
mov cx, 30
.drawY:
push cx
mov cx, 50
.drawX:
pointToPtr pointA
mov di, ax
mov al, 15
stosb
inc [pointA.x]
loop .drawX
mov [pointA.x], originX
inc [pointA.y]
pop cx
loop .drawY
pause
; display filled box with macros
fillScreen 0
define originX 40
define originY 30
mov [pointA.x], originX
mov [pointA.y], originY
for .drawY2,60
for .drawX2,10
pointToPtr pointA
mov di, ax
mov al, 15
stosb
inc [pointA.x]
endFor .drawX2
mov [pointA.x], originX
inc [pointA.y]
endFor .drawY2
pause
; draw lines
fillScreen 0
drawLine lineA.pointA, lineA.pointB
pause
;drawLine lineB.pointA, lineB.pointB
;drawLine lineB.pointB, lineB.pointA
;pause
drawLine lineC.pointA, lineC.pointB
pause
; return to dos
pause
screenMode 0x03
ret
proc_pointToPtr:
push si
push dx
mov si, ax
; vertical offset
mov al, [si+2]
mov ah, 0
mov dx, 320
mul dx
; horizontal offset
add ax, word [si]
pop dx
pop si
ret
proc_drawLine:
; draw line using the "rise over run" tactic
push ax
push bx
push cx
push dx
push di
define startPoint si
define endPoint di
define xVar bx
; find "rise"
; y2-y1
mov al, byte [endPoint+2]
sub al, byte [startPoint+2]
mov ah, 0
mov word [.rise], ax
; find "run"
; x2-x1
mov ax, word [endPoint]
sub ax, word [startPoint]
mov word [.run], ax
mov dh, 0
mov xVar, word [startPoint]
for .write, [.run]
; multiply "rise" and x
; ax = rise*x
mov ax, word [.rise]
mul xVar
; find slope
; ax = (rise*x)/run
xor dx, dx
idiv word [.run]
mov word [.slope], ax
; add vertical offset
; full ax required to multiply 16-bit x, but only al is used
add al, [startPoint+2]
; save x,y to point
mov word [.point.x], xVar
mov byte [.point.y], al
; draw point on screen
pointToPtr .point
mov di, ax
mov al, 15
stosb
; increment x
inc xVar
endFor .write
pop di
pop dx
pop cx
pop bx
pop ax
ret
.rise dw ?
.run dw ?
.slope dw ?
.vertOfs db ?
.point Point ?,?
; === data ===
pointA Point 5,5
lineA Line 7,28,74,33
lineB Line 67,4,5,99
lineC Line 50,50,75,150
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment