This repository has been archived by the owner on Oct 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rick.asm
93 lines (71 loc) · 4.49 KB
/
rick.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
bits 16 ; 16 bits, real mode
org 0x7c00 ; move to MBR start address
; .text
_start: mov ah, 00h ; set video mode
mov al, 13h ; 320x200 graphic 256/256K col. VGA
int 10h ; video services
xor bl, bl ; set y = 0
global img ; img is accessible globally
print_img: cmp bl, [img.height] ; if all lines have been written
je end
push bx ; save y
xor cl, cl ; initialize x = 0, as arg1
call print_row
pop bx ; get back row number
inc bl ; iterate to the next line
jmp print_img ; loop over lines
print_row: cmp cl, [img.width] ; if not all pixels have been written
jb print_row_pixel
ret
print_row_pixel: push bx ; save y
push cx ; save x
call get_color
pop cx ; restore x
pop bx ; restore y
movzx dx, bl ; set y in dx
push bx ; save y
push cx ; save x
call print_pixel ; print pixel(ax: color, cx: x, dx: y)
pop cx ; restore x
pop bx ; restore y
inc cl ; increase pixel index
jmp print_row ; loop over the next pixel
get_color: mov al, bl ; y
mov ah, [img.width] ; width
mul ah ; y * width
add ax, cx ; (y * width) + x = pixel number
xor bx, bx ; clean up for division
xor cx, cx ; clean up for division
xor dx, dx ; clean up for division
mov bx, 2h ; set divisor to 2, as colors are encoded over 4 bits
div bx ; ((y * width) + x) / 2 = pixel byte number
mov bx, img.pixels ; &pixels
add bx, ax ; &pixels[pixel byte]
mov bl, [bx] ; pixels[pixel byte]
mov al, 4 ; bits to shift
mul dx ; ax = 0 || ax = 4
mov cl, al ; cl for dynamic shift number
shr bl, cl ; shift pixel color if it's an odd pixel
and bl, 0fh ; keep 4 last bits, in case there was no shifting
mov al, bl ; return pixel color
ret
print_pixel: mov ah, 0ch ; write graphics pixel
mov bh, 0 ; page number
int 10h ; video services
ret
; .rodata
img:
.width db 27 ; image width must be < 256
.height db 29 ; image height must be < 256
; Colors are encoded over 4 bits.
; Hence, each byte has the color of two pixels:
; | px1 | px2 |
; | 0000 | 0000 |
; | A | A |
; So, you have to set: (width x height) / 2 bytes.
; See available colors -> https://en.wikipedia.org/wiki/BIOS_color_attributes
; PS: little endian, so if you want to display pixels 0x0123, you have to write 0x3210
.pixels db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x66,0x66,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x66,0x66,0x66,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x66,0x66,0x66,0x66,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6f,0xcc,0xcc,0xcc,0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc6,0xcc,0xcc,0x6c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcf,0x0c,0xcc,0xc0,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcc,0xcc,0xcc,0xcc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcc,0xcc,0xcc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcf,0xfc,0xcf,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcc,0xcc,0xcc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xcc,0xcc,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x70,0xff,0xff,0xff,0x87,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x00,0x78,0xf7,0x7f,0xf7,0x7f,0x87,0x88,0xf0,0xff,0xff,0xff,0xff,0x80,0x88,0x78,0xf7,0x77,0x7f,0x87,0x88,0x88,0xf0,0xff,0xff,0xff,0x80,0x88,0x88,0x00,0x7f,0xf7,0x00,0x88,0x88,0x08,0xff,0xff,0xff,0x0f,0x88,0x88,0x88,0xf0,0x77,0x0f,0x88,0x88,0x88,0x08,0xff,0xff,0xff,0x80,0x88,0x88,0x08,0x7f,0xff,0x80,0x88,0x88,0x88,0xf0,0xff,0xff,0x0f,0x88,0x08,0x88,0xf0,0xf7,0x0f,0x88,0x08,0x88,0x08,0xff,0xff,0xff,0x80,0x88,0x80,0x08,0x7f,0xff,0x80,0x88,0x80,0x88,0x08,0xff,0xff,0x0f,0x88,0x08,0x88,0x00,0xf7,0x00,0x88,0x88,0x80,0x88,0xf0,0xff,0xff,0x80,0x88,0x80,0x88,0x70,0x0f,0x88,0x88,0x08,0x88,0x08,0xff,0xff,0x0f,0x88,0x08,0x88,0x08,0xf7,0x80,0x88,0x08,0x80,0x88,0xf0,0xff,0xff,0x80,0x88,0x88,0xcc,0x70,0x00,0x88,0xcc,0x0c,0x80,0x08,0xff,0xff,0x0f,0x88,0x00,0xcc,0x0c,0x07,0x88,0xc8,0xcc,0x88,0x88,0xf0,0xff,0xff,0x80,0x80,0xc8,0x8c,0x78,0x80,0x88,0xc8,0x8c,0x88,0xf0,0xff,0xff,0x0f,0x88,0x88,0x80,0x88,0x07,0x88,0x88,0x08,0x80,0x08,0xff,0xff,0xff,0x0f,0x00,0x80,0x88,0x78,0x88,0x88,0x88,0x08,0x00,0xff,0xff,0xff,0xff,0xff,0x0f,0x88,0x88,0x87,0x88,0x88,0x88,0xf0,0xff,0xff,0xff,0x0f
; .text
end: times 510-($-$$) db 0 ; padding
dw 0xAA55 ; Boot signature