Skip to content

Instantly share code, notes, and snippets.

@benbek
Created December 9, 2016 21:57
Show Gist options
  • Save benbek/c4c9eeb329d76eec55ef33b6b62342a7 to your computer and use it in GitHub Desktop.
Save benbek/c4c9eeb329d76eec55ef33b6b62342a7 to your computer and use it in GitHub Desktop.
OpenU 80286 Assembly exercise, July 2008 Raw
;; MAMAN 15
;; Question 1
P286N
IDEAL
DOSSEG
MODEL SMALL
STACK 100h
MAXIMUM = 20 ; Maximum characters to read off the keyboard
DATASEG
CODESEG
; Shared variables
caller db 'p' ; 'm' means main program, 'p' means procedure
charCount db 0 ; How many characters have been read
old_isr1ch dd ? ; Reference to the old 1Ch interrupt
; INTERRUPT 1CH
; Our ISR1Ch
PROC myisr1ch FAR
pusha
push es ; Stores the es register seperately
mov dl, [caller] ; 'caller' is initialized with 'p'
cmp dl, 'm' ; so the procedure will run only after the
jne @@ret ; main program has run. So we check it here
xor ax, ax
push 40h
pop es ; ES points at keyboard queue
@@ReadQueue:
mov bx, [es:1ah] ; BX = head
@@polling:
cmp bx, [es:1ch]; Is the queue empty?
je @@polling
mov al, [es:bx] ; AL contains character
add bx, 2 ; Moving on to the next character in queue
cmp bx, [es:82h]; Are we at the end of the queue?
jb @@continue_print
@@reset_head: ; Progresses the pointer to beginning of queue
mov bx, [es:80h]
@@continue_print:
mov [es:1ah], bx; Updating the top of queue
push 0b800h
pop ds ; Printing the character
mov [ds:(25*80)*2], al
mov [ds:((25*80)*2)+1], 4;The red color
; This happens after a character was read
@@UpdateVariables:
mov dl, [CharCount]
add dl, 1
mov [CharCount], dl ; Increase the character count by one
mov dl, 'p'
mov [caller], dl ; Set procedure as last caller
@@ret:
pop es
popa
jmp [dword old_isr1ch] ; Call old interrupt
ENDP myisr1ch
START:
mov ax, @data
mov ds, ax
; As the question prohibits me from accessing the screen using
; BIOS/DOS interrupts, I cannot alter the screen mode. So I
; assume the screen is in text mode.
; Store the old interrupt reference
mov al, 1ch
mov ah, 35h
int 21h
mov [word cs:old_isr1ch], bx ; Offset is in BX
mov [word cs:old_isr1ch+2], es ; Segment is in ES
; Modify the interrupt reference
mov ah, 25h
mov al, 1ch
mov dx, offset myisr1ch
push seg myisr1ch
pop ds
int 21h
xor ax, ax
push 40h
pop es ; ES points at keyboard queue
ReadFromQueue:
mov bx, [es:1ah] ; BX = head
@@polling:
cmp bx, [es:1ch]; Is the queue empty?
je @@polling
mov dl, [caller]
cmp dl, 'p' ; Check if the caller is the procedure
jne @@ContinueWithoutPrinting
mov al, [es:bx] ; AL contains character
; Moving on to the next character in queue
add bx, 2
cmp bx, [es:82h]; Are we at the end of the queue?
jb @@continue_print
@@reset_head: ; If so, we'll progress the pointer to the
mov bx, [es:80h]; beginning of the queue
@@continue_print:
mov [es:1ah], bx; Updating the top of queue
push 0b800h
pop ds ; Print out the character
mov [ds:0], al
mov [ds:1], 14 ; The yellow color
; This happens after a character was read
@@ContinueWithoutPrinting:
mov dl, [CharCount]
add dl, 1
mov [CharCount], dl ; Increase the character count by one
mov dl, 'm'
mov [caller], dl ; Set main program as last caller
; Waits for the procedure to read next character
WaitForProcedure:
mov dl, [caller]
cmp dl, 'p'
jne WaitForProcedure
; Procedure has finished running, check if we hit our MAXIMUM limit
mov dl, [CharCount]
cmp dl, MAXIMUM
je EXIT ; Our limit has been hit, finish the program
jmp ReadFromQueue ; There are some more characters to read
; Finish the program
EXIT:
mov ax, 4c00h
int 21h
End START
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment