; GAG INSTALLER
; El Gestor de Arranque Grafico (this means: 'the Graphical Boot Manager')
; Installation program (menues, etc).
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU Library General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;
;(C)1998-2004 Raster Software Vigo
Code segment public
ASSUME CS:Code, DS:Code, ES:Code
org 100h
;if TEST_VAR is set to 1, Return to DOS code will be added
;(only for testing purposes. Remove in distribution files)
TEST_VAR = 0
; if LOAD_FILE is set to 1, the program will read the instructions from a
; DOS file instead of using the physical sectors in the disk, in order to
; do tests
LOAD_FILE = 0
Prog1 PROC NEAR
JMP start2
org 11Bh
; ***********************************
; * GAG installer signature *
; ***********************************
start: DB 0 ; keyboard type. 0=QWERTY 1=AZERTY 2=QWERTZ 3=DVORAK
DB "GAG",0
; ***************************
; * Main Program *
; ***************************
start2: MOV AH,0h
MOV AL,12h ; graphic mode 12h
INT 10h
IF TEST_VAR EQ 1
MOV AX,DS
ADD AX,1000h
MOV SEGM,AX ; use the next segment to store the messages
ELSE
MOV AX,1000h
MOV SEGM,AX ; use the 1000 segment to store the messages
ENDIF
PUSH CS
POP DS
MOV AX,0A000h
MOV ES,AX
CALL loadins ; load the messages
CALL palette ; change the palete
inic1: CALL clean1 ; clear the screen
MOV DX,0
MOV BL,1
MOV BH,80
MOV AL,6h
CALL prmsg
MOV DX,1
MOV BL,2
CALL prmsg
MOV DX,2
MOV BL,4
MOV AL,82h
CALL prmsg
; Print the menu
MOV DX,3
MOV BH,28
MOV BL,10
CALL prmsg
MOV DX,4
MOV BL,11
CALL prmsg
MOV DX,5
MOV BL,12
CALL prmsg
MOV DX,6
MOV BL,13
CALL prmsg
MOV DX,36
MOV BL,14
CALL prmsg
minic: CALL waitkey
IF TEST_VAR EQ 1
CMP AL,65 ; return if uppercase A is pressed
JNZ msig5b
JMP finel
ENDIF
msig5b: CMP AL,49 ; '1' pressed
JNZ msig6
MOV AX,[instrc]
JMP manual
msig6: CMP AL,50 ; '2' pressed
JNZ msig7
MOV AX,[faq]
JMP manual
msig7: CMP AL,51 ; '3' pressed
JNZ msig8
MOV AX,[license]
JMP manual
msig8: CMP AL,52 ; '4' pressed
JNZ msig9
JMP inst
msig9: CMP AL,53 ; '5' pressed
JNZ msig10
JMP uninst
msig10: JMP minic
; ************************************************
; * UNINST *
; * Puts a new MBR code, uninstalling GAG *
; ************************************************
uninst: CALL clean1
MOV DX,0
MOV BL,1
MOV BH,80
MOV AL,6h
CALL prmsg
MOV DX,1
MOV BL,2
CALL prmsg
MOV AL,82h
MOV DX,37
MOV BL,12
CALL prmsg
unibc: CALL waitkey
CMP AL,49 ; key 1?
JZ unin1
CMP AL,48 ; key 0?
JNZ unibc
JMP inic1
unin1:
PUSH DS
PUSH ES
PUSH CS
PUSH CS
POP DS
POP ES
MOV AH,2
MOV DH,0
MOV DL,80h
MOV BX, offset sector
MOV CX,01h
MOV AL,1
INT 13h; we load the MBR into the SECTOR buffer
PUSH CS
PUSH CS
POP DS
POP ES
MOV SI,offset mbrcode ; origin: MBR boot code
MOV DI,offset sector ; destination: SECTOR buffer
MOV CX,0D2h ; 210 words (to save the partition table)
REPZ
MOVSW ; copy the code
MOV word ptr [sector+512],0AA55h ; stores the boot signature
PUSH CS
PUSH CS
POP DS
POP ES
MOV AH,3
MOV DH,0
MOV DL,80h
MOV BX, offset sector
MOV CX,01h
MOV AL,1
INT 13h; we save the MBR from the SECTOR buffer
POP ES
POP DS
CALL clean1
MOV DX,0
MOV BL,1
MOV BH,80
MOV AL,6h
CALL prmsg
MOV DX,1
MOV BL,2
CALL prmsg
MOV AL,82h
MOV DX,38
MOV BL,12
CALL prmsg
CALL waitkey
JMP inic1
; ************************************************
; * INST *
; * Start the instalation of GAG *
; ************************************************
inst: CALL clean1 ; clear the screen
MOV DX,0
MOV BL,1
MOV BH,80
MOV AL,6h
CALL prmsg
MOV DX,1
MOV BL,2
CALL prmsg
; MOV DX,33 ; Warning message
; MOV BL,11
; MOV BH,80
; MOV AL,82h
; CALL prmsg
; MOV DX,34
; MOV BL,12
; CALL prmsg
; MOV DX,35
; MOV BL,14
; CALL prmsg
; CALL waitkey
CALL clean1 ; asks for keyboard type
MOV DX,0
MOV BL,1
MOV BH,80
MOV AL,6h
CALL prmsg
MOV DX,1
MOV BL,2
CALL prmsg
MOV DX,8
MOV BL,5
MOV AL,82h
CALL prmsg
MOV DX,9
MOV BL,10
MOV BH,18
CALL prmsg
MOV DX,10
MOV BL,11
CALL prmsg
MOV DX,11
MOV BL,12
CALL prmsg
MOV DX,40
MOV BL,13
CALL prmsg
MOV DX,43
MOV BL,14
CALL prmsg
MOV DX,32
MOV BL,15
CALL prmsg
inst1: CALL waitkey
CMP AL,49 ; key 1
JNZ inst2
MOV byte ptr start,0 ; QWERTY keyboard
JMP inst6
inst2: CMP AL,50 ; key 2
JNZ inst3
MOV byte ptr start,1 ; AZERTY keyboard
JMP inst6
inst3: CMP AL,51 ; key 3
JNZ inst4
MOV byte ptr start,2 ; QWERTZ keyboard
JMP inst6
inst4: CMP AL,52 ; key 4
JNZ inst4b
MOV byte ptr start,3 ; DVORAK keyboard
JMP inst6
inst4b: CMP AL,53 ; key 5
JNZ inst4c
MOV byte ptr start,4; Rusian keyboard
JMP inst6
inst4c: CMP AL,54; key 6
JNZ inst1
JMP inic1 ; return
inst6: CALL clean1
MOV DX,0
MOV BL,1
MOV BH,80
MOV AL,6h
CALL prmsg ; now we show all the available languajes
MOV DX,1
MOV BL,2
CALL prmsg
MOV DX,13
MOV BL,5
MOV AL,82h
CALL prmsg
MOV DX,42
MOV BL,10
MOV BH,14
CALL prmsg
MOV DX,15
MOV BL,11
CALL prmsg
MOV DX,17
MOV BL,12
CALL prmsg
MOV DX,41
MOV BL,13
CALL prmsg
MOV DX,20
MOV BL,14
CALL prmsg
MOV DX,22
MOV BL,15
CALL prmsg
MOV DX,24
MOV BL,16
CALL prmsg
MOV DX,26
MOV BL,17
CALL prmsg
MOV DX,28
MOV BL,18
CALL prmsg
MOV DX,30
MOV BL,19
CALL prmsg
MOV DX,14
MOV BL,10
MOV BH,40
CALL prmsg
MOV DX,16
MOV BL,11
CALL prmsg
MOV DX,18
MOV BL,12
CALL prmsg
MOV DX,19
MOV BL,13
CALL prmsg
MOV DX,21
MOV BL,14
CALL prmsg
MOV DX,23
MOV BL,15
CALL prmsg
MOV DX,25
MOV BL,16
CALL prmsg
MOV DX,27
MOV BL,17
CALL prmsg
MOV DX,29
MOV BL,18
CALL prmsg
MOV DX,39
MOV BL,19
CALL prmsg
MOV DX,31
MOV BL,24
MOV BH,80
CALL prmsg
inst7: CALL waitkey
CMP AL,"0"
JA inst7b
JNE inst7
JMP inic1 ; if 0 is pressed, return
inst7b:
CMP AL,"9"
JA inst7c
SUB AL,"1"; convert AL in a number between 0 and 8
JMP inst8b
inst7c:
OR AL,32 ; convert keystroke into lowercase
CMP AL,"a" ; key lower than "a"?
JB inst7
CMP AL,"z" ; key greater than "z"?
JA inst7
JNZ inst8
JMP inic1 ; if Z is pressed, return
inst8: SUB AL,"a" ; convert AL in a number between 0 and 25
ADD AL,9; convert AL in a number between 9 and 34
inst8b:
CMP AL,numlang
JAE inst7 ; if the key pressed is too big, ignore it
MOV SI,offset sector
ADD SI,449
ROL AL,1 ; multiply AL by two
AND AL,0FEh
MOV AH,0
ADD SI,AX
MOV CL,[SI] ; initial head
INC SI
MOV CH,[SI] ; initial track
PUSH ES
MOV AX,SEGM
MOV [inst10],AX
MOV ES,AX
MOV AL,[sector+448] ; number of tracks to read
MOV BX,100h ; load offset
CALL readtr
MOV AL,DS:[011Bh] ; read the selected keyboard
MOV ES:[11Bh],AL ; put the keyboard type into GAG
POP ES
CMP CL,0
JNZ inst9
DB 0EAh
DW 100h
inst10 DW 1000h ; Jumps to GAG
inst9: CALL clean1
MOV DX,12
MOV BL,12
MOV BH,80
MOV AL,82h
CALL PRMSG
inst11: JMP inst11
; ************************************************
; * MANUAL *
; * Shows a text, stored with the other messages *
; * and allows to navigate in it. The first line *
; * is given in AX, and the end of the document *
; * is marked with a 00h character. *
; ************************************************
manual: MOV DX,AX
MOV [inilin],AX
manua0: PUSH DX
MOV byte ptr [whatdo],3 ; both movements: previous and next page
CALL clean1
MOV DX,0
MOV BL,1
MOV BH,80
MOV AL,6h
CALL prmsg
MOV DX,1
MOV BL,2
CALL prmsg
MOV DX,7
MOV BL,29
MOV AL,07h
CALL prmsg
POP DX
PUSH DX
PUSH DS
CALL findmsg
MOV AX,SEGM
MOV DS,AX
MOV DX,0801h ; row 8, column 1
MOV AH,2 ; set cursor
MOV BH,0
PUSH DX
PUSH SI
INT 10h
POP SI
POP DX
MOV CX,19 ; show up to 20 lines in screen
manua1: MOV AL,[SI]
CMP AL,0 ; end of document?
JNZ manua2
POP DS
AND byte ptr [whatdo],2 ; only previous page
JMP manu1 ; wait for keystroke
manua2: CMP AL,13 ; Carriage return?
JNZ manua3
INC DH ; next line
MOV AH,2 ; set cursor
MOV BH,0
PUSH DX
PUSH CX
PUSH SI
INT 10h
POP SI
POP CX
POP DX
INC SI
LOOP manua1 ; if we haven't done all the lines, continue
POP DS
JMP manu1
manua3: CMP AL,32
JB manua4 ; if is a non-printable character, jump it
MOV AH,0Eh
MOV BX,82h
PUSH SI
PUSH CX
PUSH DX
INT 10h
POP DX
POP CX
POP SI
manua4: INC SI
JMP manua1
manu1: POP DX
CMP DX,[inilin] ; actual line equal to initial line?
JNE manu2
AND byte ptr [whatdo],1 ; only next page
manu2: PUSH DX
CALL waitkey
POP DX
CMP AL,13 ; return key?
JNZ manu3
MOV AL,[whatdo]
AND AL,1
JZ manu2 ; already in the end of the document
ADD DX,19
JMP manua0 ; reprint the document in the new position
manu3: OR AL,32 ; converts keystroke into lowercase
CMP AL," "
JNZ manu4
JMP inic1
manu4: CMP AL,"m"
JNZ manu5
MOV AL,[whatdo]
AND AL,2
JZ manu2 ; already in the top of the document
SUB DX,19
JMP manua0 ; reprint the document in the new position
manu5: JMP manu1
; *****************************************
; * FINEL *
; * This routine is used to return to DOS *
; *****************************************
IF TEST_VAR EQ 1
finel: MOV AH,0h ; routine to return to DOS (only for testing)
MOV AL,3h
INT 10h ; change to text mode
RET
ENDIF
; *****************************************
; * LOADINS *
; * Loads the messages, instructions and *
; * the FAQ (Frequently asked questions) *
; * in 1000:0000 *
; *****************************************
loadins:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
IF LOAD_FILE EQ 1 ; Load from a file?
MOV AX,3D00h
MOV DX,offset namefile
MOV CL,0
INT 21h
PUSH AX
PUSH AX
POP BX
MOV AX,SEGM
MOV DS,AX
MOV AH,3Fh
MOV CX,65535
MOV DX,0
INT 21h
POP BX
MOV AH,3Eh
INT 21h
JMP ldretu
namefile DB "messages.msg",0
ELSE
PUSH ES
PUSH DS
POP ES
MOV BL,3 ; try 3 times
loads1: PUSH BX
MOV AX,0201h ; read 1 sector
MOV CX,0001h ; first cylinder, first sector
MOV DX,0000h ; first head, first drive
MOV BX,offset sector
INT 13h
JNC loads2 ; jump to loads2 if the sector is right loaded
POP BX
DEC BL
JNZ loads1
loads4: POP ES
MOV DX,12
MOV BX,01h
MOV AL,2
CALL PRMSG
loads3: JMP loads3
loads2: POP BX
MOV AL,[sector+504]
MOV AH,[sector+505] ; offset for instructions
MOV instrc,AX
MOV AL,[sector+506]
MOV AH,[sector+507] ; offset for faq
MOV faq,AX
MOV AL,[sector+508]
MOV AH,[sector+509] ; offset for license
MOV license,AX
MOV AX,SEGM
MOV ES,AX
MOV BX,0
MOV CL,[sector+501] ; head to start to read instructions
MOV CH,[sector+502] ; track to start to read instructions
MOV AL,[sector+503] ; number of tracks to read
CALL readtr
CMP CL,0
JNZ loads4 ; error when reading
POP ES
ENDIF
ldretu: POP DS
POP DX
POP CX
POP BX
POP AX
RET
; ***************************************************
; * READTR *
; * Reads AL tracks in ES:BX starting with track CH *
; * and head CL. Returns CL=1 if there's read error *
; ***************************************************
readtr: PUSH AX
PUSH DX
PUSH BX
PUSH CX
MOV AL,3 ; try up to three times
readt1: PUSH AX
MOV AX,0212h ; Read 18 sectors (one track)
MOV DH,CL ; Read CL head
MOV DL,0 ; Drive A:
MOV CL,1 ; From first sector
INT 13h
JNC readt2
POP AX
POP CX
POP BX
POP DX
PUSH DX
PUSH BX
PUSH CX
DEC AL
JNZ readt1
POP AX
POP AX
POP AX
POP AX ; empty stack
MOV CL,1 ; error
RET
readt2: POP AX ; empty stack
POP CX
POP BX
POP DX
POP AX
DEC AL ; readed another track
JZ readt3 ; all tracks readed
ADD BH,36
XOR CL,1 ; next head
JNZ readtr ; read next track
INC CH ; next track
JMP readtr ; read next track
readt3: MOV CL,0 ; no error
RET
; ***************************************************
; * FINDMSG *
; * Returns in SI the address of the message number *
; * given in DX. *
; ***************************************************
findmsg:
PUSH DS
PUSH CX
PUSH AX
PUSH BX
PUSH DX
MOV SI,0
MOV AX,SEGM ; messages'segment
MOV DS,AX
MOV CX,0
fndms1: CMP CX,DX ; message found?
JZ fndms3
fndms2: MOV AL,[SI] ; get char of message
INC SI
CMP AL,13 ; Carriage Return?
JNZ fndms2
INC CX
MOV AL,[SI]
CMP AL,10 ; Line Feed
JNZ fndms1 ; if not, test if its the message number
INC SI ; jump it
JMP fndms1
fndms3: POP DX
POP BX
POP AX
POP CX
POP DS
RET
; *************************************************
; * PRMSG *
; * Prints the message number DX in the line BL *
; * of the screen, column BH (centered if BH=80), *
; * and with the colour indicated in AL. *
; *************************************************
prmsg: PUSH SI
PUSH BX
PUSH DS
PUSH CX
PUSH AX
CALL findmsg ; search the message
MOV AX,SEGM ; messages'segment
MOV DS,AX
prmsg1: CMP BH,80
JNZ prmsg2
PUSH SI
MOV AL,0
prmsg3: CMP byte ptr [SI],13
JZ prmsg4
CMP byte ptr [SI],10
JZ prmsg4
INC AL
INC SI
JMP prmsg3
prmsg4:
ROR AL,1
AND AL,07Fh
MOV AH,40
SUB AH,AL
POP SI
JMP prmsg5
prmsg2: MOV AH,BH
prmsg5: MOV DL,AH
MOV DH,BL
MOV AH,2
MOV BH,0
INT 10h ; set cursor
prmsg6: MOV AL,[SI]
CMP AL,13
JZ prmsg7
CMP AL,10
JZ prmsg7
POP BX
PUSH BX
MOV BH,0
MOV AH,0Eh
INT 10h ; Teletype output
INC SI
JMP prmsg6
prmsg7: POP AX
POP CX
POP DS
POP BX
POP SI
RET
printchar:
PUSH BX
PUSH CX
PUSH DX
PUSH AX
MOV DL,79
MOV DH,20
MOV AH,2
MOV BH,0
INT 10h ; set cursor
POP AX
PUSH AX
ADD AL,65
MOV AH,0Eh
MOV BX,0007h
INT 10h ; Teletype output
POP AX
POP DX
POP CX
POP BX
RET
; ************************************************
; * WINDOW *
; * creates a window with AX pixels of heigh and *
; * BX chars of width, starting in SI. *
; ************************************************
window: PUSH DX
PUSH BX
PUSH AX
PUSH SI
MOV DX,AX
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],0C0h
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],03Fh
MOV AL,9
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wnbuc1: MOV AL,11
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wnbuc1
MOV byte ptr ES:[SI],0FCh
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],03h
MOV AL,9
CALL setcolor
MOV byte ptr ES:[SI],0h
POP SI
ADD SI,80 ; next line
PUSH SI
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],0C0h
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],03Fh
MOV AL,9
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wnbuc2: MOV AL,11
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wnbuc2
MOV byte ptr ES:[SI],0F8h
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],03h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],04h
MOV AL,8
CALL setcolor
MOV byte ptr ES:[SI],0h
POP SI
ADD SI,80 ; next line
PUSH SI
MOV CX,DX
wnbuc3: PUSH CX
MOV AL,04
CALL setcolor
MOV byte ptr ES:[SI],30h
MOV AL,02
CALL setcolor
MOV byte ptr ES:[SI],0CFh
MOV AL,09
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wnbuc4: MOV AL,02h
CALL setcolor
MOV byte ptr ES:[SI],0FFh
MOV AL,0Dh
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
LOOP wnbuc4
MOV AL,01h
CALL setcolor
MOV byte ptr ES:[SI],0Ch
MOV AL,02h
CALL setcolor
MOV byte ptr ES:[SI],0F3h
MOV AL,0Ch
CALL setcolor
MOV byte ptr ES:[SI],0h
POP CX
POP SI
ADD SI,80
PUSH SI
LOOP wnbuc3
POP SI
PUSH SI
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],0C0h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],1Fh
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],20h
MOV AL,8
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wnbuc5: MOV AL,00001110b
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wnbuc5
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],03h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],0FCh
MOV AL,12
CALL setcolor
MOV byte ptr ES:[SI],0h
POP SI
ADD SI,80
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],0C0h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],3Fh
MOV AL,12
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wnbuc6: MOV AL,14
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wnbuc6
MOV byte ptr ES:[SI],0FCh
MOV AL,2
CALL setcolor
MOV byte ptr ES:[SI],03h
MOV AL,12
CALL setcolor
MOV byte ptr ES:[SI],0h
POP AX
POP BX
POP DX
RET
; ***************************************************
; * SETMASK *
; * Set the pixel mask to the value indicated in AL *
; ***************************************************
setmask:
PUSH DX
PUSH AX
MOV AX,8
MOV DX,3CEh
OUT DX,AL
POP AX
INC DX
OUT DX,AL
POP DX
RET
; ****************************************************
; * SETCOLOR *
; * Set the pixel color to the value indicated in AL *
; ****************************************************
setcolor:
PUSH DX
PUSH AX
MOV AX,2
MOV DX,3C4h
OUT DX,AL
POP AX
INC DX
OUT DX,AL
POP DX
RET
; ************************************
; * CLEAN1 *
; * cleans the screen in two windows *
; ************************************
clean1: MOV AL,15
CALL setcolor
MOV SI,0
MOV CX,38400
cbuc1: MOV byte ptr ES:[SI],0
INC SI
LOOP cbuc1
MOV SI,10080
MOV BX,78
MOV AX,320
PUSH DX
PUSH BX
PUSH AX
PUSH SI
MOV DX,AX
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],03Fh
MOV AL,11
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wcbuc1: MOV AL,11
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wcbuc1
MOV byte ptr ES:[SI],0FCh
MOV AL,11
CALL setcolor
MOV byte ptr ES:[SI],0h
POP SI
ADD SI,80 ; next line
PUSH SI
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],03Fh
MOV AL,11
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wcbuc2: MOV AL,11
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wcbuc2
MOV byte ptr ES:[SI],0F8h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],04h
MOV AL,10
CALL setcolor
MOV byte ptr ES:[SI],0h
POP SI
ADD SI,80 ; next line
PUSH SI
MOV CX,DX
wcbuc3: PUSH CX
MOV AL,04
CALL setcolor
MOV byte ptr ES:[SI],30h
MOV AL,02
CALL setcolor
MOV byte ptr ES:[SI],0Fh
MOV AL,09
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wcbuc4: MOV AL,02h
CALL setcolor
MOV byte ptr ES:[SI],0FFh
MOV AL,0Dh
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
LOOP wcbuc4
MOV AL,01h
CALL setcolor
MOV byte ptr ES:[SI],0Ch
MOV AL,02h
CALL setcolor
MOV byte ptr ES:[SI],0F0h
MOV AL,0Ch
CALL setcolor
MOV byte ptr ES:[SI],0h
POP CX
POP SI
ADD SI,80
PUSH SI
LOOP wcbuc3
POP SI
PUSH SI
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],1Fh
MOV AL,4
CALL setcolor
MOV byte ptr ES:[SI],20h
MOV AL,10
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wcbuc5: MOV AL,00001110b
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wcbuc5
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],0FCh
MOV AL,14
CALL setcolor
MOV byte ptr ES:[SI],0h
POP SI
ADD SI,80
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],3Fh
MOV AL,14
CALL setcolor
MOV byte ptr ES:[SI],0h
INC SI
MOV CX,BX
wcbuc6: MOV AL,14
CALL setcolor
MOV byte ptr ES:[SI],0h
MOV AL,1
CALL setcolor
MOV byte ptr ES:[SI],0FFh
INC SI
LOOP wcbuc6
MOV byte ptr ES:[SI],0FCh
MOV AL,14
CALL setcolor
MOV byte ptr ES:[SI],0h
POP AX
POP BX
POP DX
RET
; ***********************
; * PALETTE *
; * changes the palette *
; ***********************
palette:
PUSH ES
PUSH DS
POP ES
MOV AX,1012h
MOV BX,0h
MOV CX,10h
MOV DX,offset paleta
INT 10h
MOV AX,1002h
MOV DX,offset paleta2
INT 10h
POP ES
RET
; **********************************************************************
; * WAITKEY *
; * waits for a keystroke and return it in AL. *
; **********************************************************************
waitkey:
MOV AH,1
INT 16h
JZ waitkey
MOV AH,0
INT 16h
; code for keyboard translation, used to add support for
; AZERTY and QWERTZ keyboards.
PUSH SI
CMP byte ptr DS:[11Bh],0 ; QWERTY type?
JNZ azlpn1
MOV SI,offset kbtabl0
JMP azlp
azlpn1: CMP byte ptr DS:[11Bh],1 ; AZERTY type?
JNZ azlpn2
MOV SI,offset kbtabl1
JMP azlp
azlpn2: CMP byte ptr DS:[11Bh],2 ; QWERTZ type?
JNZ azlpn3
MOV SI,offset kbtabl2
JMP azlp
azlpn3: CMP byte ptr DS:[11Bh],3 ; DVORAK type?
JNZ azlpn4
MOV SI,offset kbtabl3
JMP azlp
azlpn4: MOV SI,offset kbtabl0 ; Rusian type. Here we use the QWERTY type
azlp: CMP byte ptr [SI],0 ; end of table?
JZ azend ; end loop
CMP AL,DS:[SI] ; key found?
JZ azfnd
INC SI
INC SI ; next key in the table
JMP azlp ; close loop
azfnd: INC SI
MOV AL,DS:[SI] ; change the readed key for the translated key
azend: POP SI
; end of keyboard translation support code
endkey: RET
; ****************************************
; * Tables for QWERTZ and AZERTY support *
; ****************************************
; KBTABL points to the translation tables. Them contains the ASCII
; code readed from the keyboard and the ASCII code translated.
; Table for QWERTY keyboards.
kbtabl0:
DB 0 ; end of table
; Table for AZERTY keyboards.
kbtabl1:
DB "A","Q" ; 'A' key is translated as 'Q' key
DB "Q","A" ; 'Q' key is translated as 'A' key
DB "a","q","q","a","W","Z","Z","W","w","z","z","w"
DB ":","M","M",":",";","m","m",";"
DB 0 ; end of table
; Table for QWERTZ keyboards.
kbtabl2:
DB "Z","Y" ; 'Z' key is translated as 'Y' key
DB "Y","Z" ; 'Y' key is translated as 'Z' key
DB "z","y","y","z"
DB 0 ; end of table
kbtabl3:
; Table for DVORAK keyboards
DB "-", "[" , "=", "]" , "q", "'" , "w", ","
DB "e", "." , "r", "p" , "t", "y" , "y", "f"
DB "u", "g" , "i", "c" , "o", "r" , "p", "l"
DB "[", "/" , "]", "=" , "s", "o" , "d", "e"
DB "f", "u" , "g", "i" , "h", "d" , "j", "h"
DB "k", "t" , "l", "n" , ";", "s" , "'", "-"
DB "z", ";" , "x", "q" , "c", "j" , "v", "k"
DB "b", "x" , "n", "b" , ",", "m"
DB ".", "v" , "/", "z" , "_", "{" , "+", "}"
DB "Q", 34 , "W", "<" , "E", ">" , "R", "P" ; 34 is the ASCII code for " simbol
DB "T", "Y" , "Y", "F" , "U", "G" , "I", "C"
DB "O", "R" , "P", "L" , "{", "?" , "}", "+"
DB "S", "O" , "D", "E" , "F", "U" , "G", "I"
DB "H", "D" , "J", "H" , "K", "T" , "L", "N"
DB ":", "S" ,34, "_" , "Z", ":" , "X", "Q"
DB "C", "J" , "V", "K" , "B", "X" , "N", "B"
DB "<", "W" , ">", "V" , "?", "Z"
DB 0 ;end of dvorak table
;*********************************************************
;* MBRCODE *
;* Contains the boot code installed in the MBR when GAG *
;* is uninstalled. *
;*********************************************************
mbrcode:
CLD
XOR AX,AX
MOV DS,AX
MOV ES,AX
MOV SI,7C00h ; start address of the code
MOV DI,600h ; address 0000:0600h
MOV CX,100h ; 256 words
REPZ
MOVSW ; relocates the code
DB 0EAh ; Far jump to 0000:067B
DW 067Bh
DW 0h
icopy0: DB " Reboot your computer.",90h ; address 0000:0617h
icopy1: DB "Disk error.",90h ; address 0000:062Eh
icopy2: DB "No boot sector found.",90h ; 0000:063A
icopy3: DB "No active partition found.",90h ; 0000:0650
DB 16,0,1,0 ; address 0000:066Bh. LBA table
DB 0,7Ch,0,0 ; address 0000:066Fh. Segment:offset
DB 0,0,0,0,0,0,0,0 ; address 0000:0673h. Logical sector
; 0000:067B
; Boot Code
XOR AX,AX
MOV DS,AX
MOV ES,AX
MOV SI,7DBEh ; First entry in the partition table
MOV CX,4 ; max. 4 entries
lobuc: CMP byte ptr DS:[SI],80h ; active?
JZ safe ; Boot that partition
ADD SI,10h ; next entry
LOOP lobuc
MOV DI,0650h ; error, no active partition!
JMP error
safe: MOV DL,80h ; here we load the boot sector of the active partition
MOV AH,41h
MOV BX,55AAh
INT 13h ; test for BIOS extensions
JC safeb
CMP BX,0AA55h
JNE safeb
MOV DI,0673h ; address for LBA data
MOV CX,DS:[SI+8]
MOV DS:[DI],CX
MOV CX,DS:[SI+10]
MOV DS:[DI+2],CX
MOV AH,42h
MOV SI,066Bh ; start of LBA table
MOV BX,3 ; try 3 times max
hload3: PUSH AX
PUSH SI
PUSH BX
MOV DL,80h
INT 13h
JNC hrun3b
POP BX
POP SI
POP AX
DEC BX
JNZ hload3
MOV DI,062Eh ; error reading a sector!
JMP error
hrun3b: POP BX
POP SI
POP AX
JMP hrun4
safeb: MOV DL,80h ; CHS mode
MOV DH,DS:[SI+1] ; head
MOV CX,DS:[SI+2] ; sector and track
MOV BX,3 ; try 3 times max
hload2: PUSH BX
PUSH CX
PUSH DX
MOV BX,7C00h ; address where we load the boot sector
MOV AX,0201h ; one sector
INT 13h
JNC hrun2
POP DX
POP CX
POP BX
DEC BX
JNZ hload2
MOV DI,062Eh ; error reading a sector!
JMP error
hrun2: POP DX
POP CX
POP BX
;Here we test the MBR signature and other things
hrun4: CMP word ptr DS:[7DFEh],0AA55h ; MBR signature?
JZ hrun3
MOV DI,063Ah ; error, no boot sector found!
JMP error
hrun3: DB 0EAh
DW 7C00h
DW 0h
;Error shows the error message in DI
error: MOV AH,0Eh
MOV BX,7
MOV AL,[DI]
CMP AL,90h ; end?
JE errcon
PUSH DI
INT 10h
POP DI
INC DI
JMP error
errcon: MOV DI,0617h ; end of message
err2: MOV BX,7
MOV AL,[DI]
CMP AL,90h
JE mbuc
PUSH DI
INT 10h
POP DI
INC DI
JMP err2
mbuc: JMP mbuc ; locks the machine to allows user to read it.
; ********************************************************************
; * This is the 16 colour palette used by GAG's icons (order: R,G,B) *
; ********************************************************************
paleta DB 0,0,0 ; 0 Black
DB 32,32,32 ; 1 gray
DB 48,48,48 ; 2 White
DB 48,32,32 ; 3 pink
DB 63,63,63 ; 4 brigth white
DB 48,0,0 ; 5 Red
DB 0,48,0 ; 6 Green
DB 56,44,2 ; 7 orange
DB 43,31,8 ; 8 dark orange
DB 50,50,0 ; 9 Yellow
DB 0,0,48 ; A Blue
DB 32,0,0 ; B Dark red
DB 0,48,48 ; C Cyan
DB 48,16,16 ; D dark pink
DB 10,9,28 ; E dark blue
DB 0,32,0 ; F dark green
paleta2 DB 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
; *************************************************************************
; * and this is the 10 colour palette used by the text and windows of GAG *
; *************************************************************************
DB 0,0,0,32,32,32,48,48,48,48,0,0,63,63,63,48,0,48,0,48,0,63,0,0
DB 63,40,0,48,32,0
numlang DB 20 ; Number of languages availables
instrc DW 15
faq DW 415
license DW 691
whatdo DB 0 ; used in the file reader
inilin DW 0
COORDX DB 0
COORDY DB 0
SEGM DW 0 ; segment where to load the messages
sector DB 512 DUP(0)
Prog1 ENDP
Code ends
END Prog1
syntax highlighted by Code2HTML, v. 0.9.1