ass_messages/messages.asm

205 lines
3.9 KiB
NASM
Raw Normal View History

2021-10-04 15:59:48 +00:00
org 0x7C00 ; The boot code on a drive always gets loaded at address 0x7C00
bits 16 ; .bin defaults to 16 bits
2021-10-04 15:59:48 +00:00
;; FIXME: possible problem with HEIGHT being defined
;; as one less than what VIDEO_MODE implies?
WIDTH equ 0x50 ; 60
HEIGHT equ 0x18 ; 24 (?)
VIDEO_MODE equ 0x3 ; 80x25 screen, text mode
;; see http://www.ctyme.com/intr/int-10.htm for interrupts
start:
;; Use color mode
mov ax, VIDEO_MODE
int 10h
;; Clear screen
2021-10-04 15:59:48 +00:00
mov ah, 0x06 ; scroll screen up
mov al, 0x00 ; lines to scroll (0 = clear)
mov bh, 0x0F ; bg/fg colour
mov cx, 0x0000 ; upper row number, left col number (both 0)
mov dh, HEIGHT ; lower row number (24)
mov dl, WIDTH ; right col number (80)
int 0x10
;; Set cursor to bottom of screen
2021-10-04 15:59:48 +00:00
mov ah, 0x02 ; set cursor position
mov bh, 0x00 ; page number
mov dh, HEIGHT ; row (bottommost row)
mov dl, 0x00 ; col (leftmost col)
int 0x10
2021-10-04 15:59:48 +00:00
mov sp, 0x2000 ; initialise stack pointer
.loop:
2021-10-04 15:59:48 +00:00
mov ah, 0x00 ; Read character
int 0x16
cmp al, 0x0d ; newline
je .newline
cmp al, 0x08 ; delete character
je .change_color_mode
cmp al, 0x1b ; escape character
je .beep
jmp .nonewline
.change_color_mode:
2021-10-04 15:59:48 +00:00
call .readbyte
mov [color_mode], al
jmp .loop
.newline:
2021-10-04 15:59:48 +00:00
;; Scroll up window
mov ah, 0x06
mov al, 0x01
mov bh, 0x0F
mov cx, 0x0000
mov dh, HEIGHT
mov dl, WIDTH
int 0x10
;; Get current cursor position
mov bh, 0x00
mov ah, 0x03
int 0x10
;; Move cursor to beginning of screen
mov dl, 0x00
mov ah, 0x02
int 0x10
jmp .loop
2019-09-18 22:37:09 +00:00
.beep:
2021-10-04 15:59:48 +00:00
call .readduration
mov ah, 0
push ax
mov al, 182 ; Prepare the speaker for the
out 43h, al ; note.
call .readbyte
mov ah, 0
sal ax, 5 ; multiply by 32
add ax, 1140
out 42h, al ; Output low byte.
mov al, ah ; Output high byte.
out 42h, al
in al, 61h ; Turn on note (get value from
; port 61h).
or al, 00000011b ; Set bits 1 and 0.
out 61h, al ; Send new value.
;; mov bx, 50000 ; Pause for duration of note.
pop bx
push ax
mov ax, 3125
mul bx
mov bx, ax
pop ax
2019-09-30 23:23:27 +00:00
2019-09-18 22:37:09 +00:00
.pause1:
2021-10-04 15:59:48 +00:00
mov cx, 65535
2019-09-18 22:37:09 +00:00
.pause2:
2021-10-04 15:59:48 +00:00
dec cx
jne .pause2
dec bx
jne .pause1
in al, 61h ; Turn off note (get value from
; port 61h).
and al, 11111100b ; Reset bits 1 and 0.
out 61h, al ; Send new value.
jmp .loop
2019-09-18 22:37:09 +00:00
.nonewline:
2021-10-04 15:59:48 +00:00
;; Write character
mov ah, 0x09
2021-10-04 15:59:48 +00:00
mov bh, 0x00
mov bl, [color_mode]
mov cx, 0x01
int 0x10
2021-10-04 15:59:48 +00:00
;; Get current cursor position
mov ah, 0x03
int 0x10
2021-10-04 15:59:48 +00:00
cmp dl, WIDTH
jge .eol
jmp .noeol
.eol:
2021-10-04 15:59:48 +00:00
;; Scroll up window
mov ah, 0x06
mov al, 0x01
mov bh, 0x0F
mov cx, 0x0000
mov dh, HEIGHT
mov dl, WIDTH
int 0x10
;; Move cursor to beginning of screen
mov bh, 0
mov dh, HEIGHT
mov dl, 0x00
mov ah, 0x02
int 0x10
jmp .loop
.noeol:
2021-10-04 15:59:48 +00:00
;; Move cursor forward
inc dl
mov ah, 0x02
int 0x10
jmp .loop
;; Reads two characters from the keyboard buffer and converts them into a single byte
;;
;; The conversion happens as follows:
;; ASCII 'a' is subtracted from each character (so 'a' = 0, 'b' = 1, ...)
;; the first character is shifted left by 4
;; the shifted and non-shifted values are then or'ed together to form a byte
;;
;; CLOBBERS
;; - ax
;; - bl
.readbyte:
mov ah, 0x00 ; Read character
int 0x16
2019-09-20 16:48:46 +00:00
2021-10-04 15:59:48 +00:00
;; Read character is in al
sub al, 'a' ; Normalise
mov bl, al
shl bl, 0x4 ; First character is upper 4 bits
2019-09-20 16:48:46 +00:00
2021-10-04 15:59:48 +00:00
mov ah, 0x00 ; Read character
int 0x16
;; Read character is in al
sub al, 'a' ; Normalise
or al, bl ; Combine both characters
ret
2019-09-30 23:23:27 +00:00
.readduration:
2021-10-04 15:59:48 +00:00
;; Read duration (0-16 supported)
mov ah, 0x00
int 0x16
;; Read character is in al
sub al, 'a'
ret
2019-09-30 23:23:27 +00:00
halt: hlt
2019-08-06 15:36:37 +00:00
color_mode: db 0x02
2021-10-04 15:59:48 +00:00
;; Magic number must be in the last 2 bytes of the sector so
;; fill the binary with zeroes until it is 510 bytes in size
;; (magic number will use up the remaining 2)
times 510 - ($ - $$) db 0
2021-10-04 15:59:48 +00:00
dw 0xAA55 ;; Magic number to mark sector as bootable