Population

My Library

    A.N Edition

    This is my own library. I found out in MASM it is very inconvenient as we don't have a standard built-in

    library like c, c++. So I decide to write my own version. Although it may not be as efficient as others do,

    at least they are my own version. This is an accumulative version that I continually add new codes.

    B.Idea of program

    1¡£ Basic idea:

    Try to write as many as possible c,c++ similar simple functions in MASM.

    2¡£ Major function

    A. INPUTNUMBER

    ;INPUT: NONE
    ;OUTPUT: BY AX, AND DX A VALID INTEGER, DX WILL BE INITIALIZE TO 0, BEFORE KEYIN BY USER

    It is very easy to use "cin" in c, but behind scene, there is a lot job is going to be done for a single number input.

    This version is incomplete, as I have not solved big number input, say number bigger than 65535. I originally thought to use

    DX to represent the big part. But it seems there is some problem.

    B. GCD, LCM

    These two functions are just for fun! I want to practice Euclide Algorithm. Do people ever want to find out "Greatest Common

    Divisor" or "Least Common Multiplication"? LCM use GCD to calculate.

    C. DISPLAYINTEGER

    This is my favorite. As I spent so much time to try to find out dividing mechanism. DX must be 0, otherwise there will be overflow.

    ¡¡

    TITLE  MYLIB
    COMMENT #	THIS IS MY LIBRARY ALTHOUGH MANY FUNCTIONS ARE JUST QUITE SAME AS
    		# EXAMPLE GIVEN IN GRAPHIC, BUT I PREFER TO WRITE IT AGAIN BY MYSELF

    DIM	        EQU 15
    CELLSIZE	EQU 8;
    VERTICAL_BAR    EQU	0BAH
    HORIZONTAL_BAR	EQU	0CDH
    UPPER_LEFT	EQU	0C9H
    UPPER_RIGHT	EQU	0BBH
    MODULUS EQU  00FFFH
    MULTIPLIER EQU 16807
    SCALOR	EQU  5
    SHIFTOR	EQU  12
    CHARSCOPE	EQU  127

    .DOSSEG
    .MODEL SMALL

    .DATA

    MSGOVERFLOW DB "OVERFLOW!", "$"
    MSGINVALIDNUMBER  DB "INVALID NUMBER!","$"
    MSGNEGATIVENUMBER DB "NEGATIVE NUMBER!", "$"
    MSGDECRYPTIONFAILED	DB "DECRYPTION FAILED", "$"

    .CODE

    PUBLIC ENTERGRAPHIC
    PUBLIC ENTERTEXT
    PUBLIC WAITRETURN
    PUBLIC DRAWBOX
    PUBLIC DRAWVERLINE
    PUBLIC DRAWHORLINE
    PUBLIC DRAWGRID
    PUBLIC FILLGRID
    PUBLIC DRAWBOARD
    PUBLIC DISPLAYINTEGER
    PUBLIC GCD
    PUBLIC LCM
    PUBLIC RETURN
    PUBLIC SPACE
    PUBLIC INPUTNUMBER
    PUBLIC DRAWHORIZONTAL
    PUBLIC DRAWVERTICAL
    PUBLIC SHOWCHAR
    PUBLIC CLEARSCREEN
    PUBLIC STRCPY
    PUBLIC STRCMP
    PUBLIC DISPLAYINTEGERB
    PUBLIC DISPLAYINTEGERH
    PUBLIC WAITRIGHTBTN
    PUBLIC WAITLEFTBTN
    PUBLIC MOUSERELEASE
    PUBLIC MOUSESHOW
    PUBLIC MOUSEHIDE
    PUBLIC MOUSEINIT
    PUBLIC MOUSEPOS
    PUBLIC GETCELLINDEX
    PUBLIC MOUSECLICK
    PUBLIC FACTORIAL
    PUBLIC INPUTNSTR
    PUBLIC SUBSTRING
    PUBLIC DISPLAYSTR
    PUBLIC RAND
    PUBLIC ENCRYPTION
    PUBLIC DECRYPTION

    ;FUNCTION: DECRIPT A STRING PASSED BY STACK WITH PRE-DEFINED SCALOR AND SHIFTOR
    ;INPUT: BY STACK THE STRING TO BE DECRIPTED
    ;OUTPUT: NONE
    DECRYPTION	PROC  NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		PUSH DI
    		PUSH SI
    		MOV BX, [BP+4]; BX IS POINTING TO STRING
    L77:
    		XOR AX, AX
    		MOV  AL, [BX];
    		CMP AL, "$"
    		JE	L70; THE END OF STRING
    		;SUB AL, SHIFTOR
    		;XOR DX, DX; PREPARE CALULATE MOD
    		MOV SI, SCALOR; SI IS SCALOR
    		;MOV CX, CHARSCOPE

    		;DIV CX; GET MOD DIV BY CHARSCOPE
    		;MOV DI, DX; DI KEEP THE OLD MOD
    		MOV DI, AX;
    		MOV CX, SCALOR;
    		DEC CX; LESS 1; CX IS COUNTER AND SCALOR

    L76:
    		MOV AX, CHARSCOPE
    		MUL CX
    		ADD AX, DI; SUB OLD MOD
    		SUB AX, SHIFTOR

    		XOR DX, DX
    		DIV SI; DIV SCALOR TO SEE IF REMAINDER IS 0
    		CMP DX, 0
    		JE	L75; SUCCEED AND ...
    		DEC CX
    		CMP CX, 0
    		JGE	L76

    		;THIS SHOULD NOT HAPPEN!!!
    		MOV DX, OFFSET MSGDECRYPTIONFAILED
    		CALL SHOWMSG
    		INC BX
    		JMP L77

    L75:
    		MOV [BX], AL; AL THE QUOTIENT
    		INC BX; NEXT
    		JMP L77
    L70:
    		POP SI
    		POP DI
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 2
    DECRYPTION	ENDP

    ;ENCRIPT A STRING PASSED BY STACK WITH PRE-DEFINED SCALOR AND SHIFTOR
    ;OUTPUT: NONE
    ;INPUT: BY STACK THE STRING ENDED WITH "$"
    ENCRYPTION	PROC NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		MOV BX, [BP+4]; BX IS POINTING THE STRING
    		XOR DX, DX
    L79:
    		XOR CX, CX
    		MOV  CL, [BX]
    		CMP CL, "$"
    		JE	L78; DON'T CHANGE "$"
    		MOV AX, SCALOR

    		MUL CX
    		ADD AX, SHIFTOR
    		MOV CX, CHARSCOPE
    		XOR DX, DX
    		DIV CX
    		MOV [BX], DL
    		INC BX
    		JMP L79
    L78:
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET	2
    ENCRYPTION	ENDP

    ;FUNCTION: GENERATING RANDOM NUMBERS AND THE OUTPUT CONTINUALLY
    ;INPUT: AX THE SEED, IF FIRST TIME THE STARTING SEED
    ;OUTPUT: AX THE MOD
    RAND	PROC	NEAR
    		PUSH BX
    		PUSH DX
    		XOR DX, DX
    		MOV BX, MULTIPLIER
    		MUL BX
    		MOV BX, MODULUS
    		DIV BX
    		MOV AX, DX
    		POP DX
    		POP BX
    		RET
    RAND	ENDP

    ;FUNCTION: THIS IS A JOKE! I USE 09H INT TO DISPLAY
    ;INPUT: BY STACK, THE STRING
    ;OUTPUT: NONE
    DISPLAYSTR	PROC	NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH DX
    		MOV DX, [BP+4]
    		MOV AH, 09H
    		INT 21H
    		POP DX
    		POP AX
    		POP BP
    		RET 2
    DISPLAYSTR	ENDP

    ;FUNCTION: INPUT MAX N NUMBER OF CHAR FROM KEYBOARD AND ADD "$" AT END
    ;INPUT: CHAR BUFFER, N NUMBER ALL FROM STACK
    ;OUTPUT: NONE
    INPUTNSTR	PROC	NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		MOV BX, [BP+6]; THE ARRAY
    		MOV CX, [BP+4]; THE COUNTER
    		DEC CX; AS WE CAN ONLY ALLOW MAX N-1 CHAR
    L63:
    		MOV AH, 01H
    		INT 21H
    		CMP AL, 0DH; THE RETURN
    		JE	L62; THE END OF INPUT
    		MOV [BX], AL
    		INC BX
    		LOOP L63
    L62:
    		MOV BYTE PTR [BX], "$"
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 4
    INPUTNSTR	ENDP

    ;FUNCTION: SEARCH A SUB STRING IN A TARGET STRING WHICH ARE PASSED BY STACK
    ;INPUT: BY STACK, TARGET STR, SUB STR
    ;OUTPUT: AX, 0 FOR NOT MATCH, 1 FOR MATCH
    SUBSTRING	PROC	NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH DI
    		PUSH SI
    		MOV DI, [BP+6]; THE TARGET STR
    		MOV SI, [BP+4]; THE SUB STR
    L66:
    		CMP BYTE PTR [DI], "$"
    		JE	L65; THE END OF COMP
    		CMP BYTE PTR [SI], "$"; FOUND!
    		JMP FOUNDSUBSTR; RIGHT?
    		MOV BYTE PTR AL, [DI]
    		CMP BYTE PTR [SI], AL
    		JNE  L64; NOT SAME, SO ADVANCE
    		INC SI
    		INC DI
    		JMP L66

    L64:
    		MOV SI, [BP+4]; SUBSTRING STARTOVER
    		INC DI; TARGET ADVANCE
    		JMP L66

    L65:
    		CMP BYTE PTR [SI], "$"
    		JE	FOUNDSUBSTR
    		JMP NOTFOUNDSUBSTR

    FOUNDSUBSTR:
    		MOV AX, 1
    		JMP ENDSEARCHING

    NOTFOUNDSUBSTR:
    		MOV AX, 0;

    ENDSEARCHING:
    		POP SI
    		POP DI
    		POP BP

    		RET 4
    SUBSTRING	ENDP

    ;FUNCTION: RETURN VALUE OF FACTORIAL INPUT FROM STACK
    ;INPUT: BY STACK, AN POSITIVE INTEGER
    ;OUTPUT: BY STACK THE VALUE OF FACTORIAL
    FACTORIAL	PROC	NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH DX
    		MOV AX, [BP+4]
    		CMP AX, 00H;
    		JL	MINUSVALUE
    		CMP AX, 00H
    		JE	L69
    		MOV BX, AX
    		DEC BX
    		PUSH BX
    		CALL FACTORIAL
    		POP BX
    		XOR DX, DX; MAKE SURE DX IS 0
    		MUL BX
    		MOV [BP+4], AX
    		JMP FACTORIAL_
    MINUSVALUE:
    		MOV AH, 09H
    		MOV DX, OFFSET MSGNEGATIVENUMBER
    		INT 21H
    		JMP FACTORIAL_

    L69:
    		MOV AX, 01H
    		MOV [BP+4], AX

    FACTORIAL_:
    		POP DX
    		POP CX
    		POP AX
    		POP BP
    		RET
    FACTORIAL	ENDP

    ;FUNCTION: INTERNAL METHOD CALC ARRAY INDEX, BY GIVING OFFSET OF X, Y
    ;INPUT: OFFSET OF X,OFFSET OF Y, DIM OF GRID, CELLSIZE
    ;OUTPUT: ROW, COL BY STACK, ROW =-1 INDICATE OUTSIDE, OR ON GRIDLINE!!!
    CALCINDEX	PROC NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		PUSH SI

    		;FIRST SEE IF OFFSET IS MINUS
    		MOV BX, [BP+10]; BX IS X OFFSET
    		CMP BX, 00H
    		JL OUTBOUNDS; IF OFFSET IS MINUS, OUTSIDE

    		MOV BX, [BP+8]; BX IS Y OFFSET
    		CMP BX, 00H
    		JL OUTBOUNDS; IF OFFSET IS MINUS, OUTSIDE

    		;FIRST CALC BOUNDS TO SEE IF IT IS OUTSIDE WHICH IS EASIEST
    		MOV AX, [BP+6]; THE DIM
    		MOV CX, [BP+4]; THE CELL SIZE

    		;A TEST
    		;ADD CX, 2; AS THERE ARE 2 LINES
    		;A TEST

    		INC CX; AS THERE ARE ONE LINE TO BE ADDED
    		MUL CX;

    		;NOT NECESSARY
    		;INC AX; AS THERE IS ONE LINE AT BOUND, AX IS BOUNDSIZE

    		;NOW COMPARE BOUNDS WITH X
    		MOV BX, [BP+10]; BX IS X OFFSET
    		CMP AX, BX
    		JL OUTBOUNDS

    		;NOW COMPARE BOUNDS WITH Y
    		MOV BX, [BP+8]; BX IS Y OFFSET
    		CMP AX, BX
    		JL OUTBOUNDS

    		;NOW FIRST CALC Y, OR ROW INDEX
    		MOV AX, [BP+8]; Y OFFSET

    		XOR DX, DX; MAKE SURE DX IS 0 BEFORE DIVIDING!!!
    		DIV CX;
    		CMP DX, 00H; TO SEE IF IT IS ON GRID LINE!
    		JE OUTBOUNDS; ON GRIDLINE IS SAME EFFECT AS OUTSIDE
    		MOV SI, AX; THE QUOTIENT IS INDEX OF ROW; BUT UNLESS COL IS NOT ON GRIDLINE
    		MOV AX, [BP+10]; THE OFFSET X
    		XOR	DX, DX; CLEAR DX BEFORE DIV
    		DIV CX
    		CMP DX, 00H
    		JE OUTBOUNDS
    		MOV [BP+10], SI; THE ROW INDEX
    		MOV [BP+8], AX; THE COL INDEX
    		JMP CALCINDEX_
    OUTBOUNDS:
    		MOV AX, -1;
    		MOV [BP+10], AX

    CALCINDEX_:
    		POP SI
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 4
    CALCINDEX	ENDP

    ;FUNCTION: GET ROW,COL OF A GRID BY GIVING LEFTTOP COOR, X POS,Y POS, CELLSIZE,
    ;          DIMENSION OF GRID
    ;INPUT: ORIGIN X,ORIGIN Y, MOUSEPOS X, MOUSEPOS Y, DIM OF GRID, CELLSIZE
    ;OUTPUT: BX=ROW, SI=COL; IF OUTSIDE, BX=-1
    GETCELLINDEX	PROC NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH CX
    		PUSH DX
    		MOV AX, [BP+14]; X ORIGIN
    		MOV CX, [BP+10]; MOUSE POS X
    		SUB CX, AX; XPOS - X ORIGIN
    		PUSH CX; PASS OFFSET X
    		MOV AX, [BP+12]; THE Y ORIGIN
    		MOV DX, [BP+8]; MOUSE POS Y
    		SUB DX, AX; YPOS - Y ORIGIN
    		PUSH DX; PASS OFFSET Y
    		MOV AX, [BP+6]; DIM
    		PUSH AX
    		MOV AX, [BP+4]; CELLSIZE
    		PUSH AX
    		CALL CALCINDEX
    		POP SI; COL IS FIRST
    		POP BX; ROW IS SECOND??

    		POP DX
    		POP CX
    		POP AX
    		POP BP
    		RET 12
    GETCELLINDEX	ENDP

    ;FUNCTION: TO GET COORDINATE OF MOUSE
    ;OUTPUT: CX=X, DX=Y
    ;INPUT: NONE
    MOUSEPOS	PROC NEAR
    		PUSH AX
    		PUSH BX
    		MOV AX, 03H
    		INT 33H
    		POP BX
    		POP AX
    		RET
    MOUSEPOS	ENDP

    ;FUNCTION: RETURN UNTIL RIGHT MOUSE BUTTON IS CLICKED
    ;INPUT: NONE
    ;OUTPUT: NONE
    WAITRIGHTBTN	PROC	NEAR
    		PUSH BX
    		PUSH CX
    		PUSH DX
    WAITCLICK3:
    		CALL MOUSECLICK
    		CMP BX, 02H
    		JNE WAITCLICK3
    		POP DX
    		POP CX
    		POP BX
    		RET
    WAITRIGHTBTN	ENDP

    ;FUNCTION: RETURN UNTIL LEFT MOUSE BUTTON IS CLICKED
    ;INPUT: NONE
    ;OUTPUT: NONE
    WAITLEFTBTN	PROC	NEAR
    		PUSH BX
    		PUSH CX
    		PUSH DX
    WAITCLICK4:
    		CALL MOUSECLICK
    		CMP BX, 01H
    		JNE WAITCLICK4
    		POP DX
    		POP CX
    		POP BX
    		RET
    WAITLEFTBTN	ENDP

    ;FUNCTION: RETURN UNTIL MOUSE BUTTON IS CLICKED
    ;INPUT: NONE
    ;OUTPUT: BX IS STATE OF BUTTON, CX=X, DX=Y
    MOUSECLICK	PROC	NEAR
    		PUSH AX
    		MOV AX, 03H
    WAITCLICK1:
    		INT 33H
    		CMP BX, 00H
    		JE WAITCLICK1
    		POP AX
    		RET
    MOUSECLICK	ENDP

    ;FUNCTION: RETURN UNTIL MOUSE BUTTON IS RELEASED
    ;INPUT: NONE
    ;OUTPUT: BX IS STATE OF BUTTON, CX=X, DX=Y
    MOUSERELEASE	PROC	NEAR
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		MOV AX, 03H
    WAITCLICK2:
    		INT 33H
    		CMP BX, 00H
    		JNE	WAITCLICK2
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		RET
    MOUSERELEASE	ENDP

    ;FUNCTION: SHOW MOUSE
    ;INPUT: NONE
    ;OUTPUT: NONE
    MOUSESHOW	PROC NEAR
    		PUSH AX
    		MOV AX, 01H
    		INT 33H
    		POP AX
    		RET
    MOUSESHOW	ENDP

    ;FUNCTION: HIDE MOUSE
    ;INPUT: NONE
    ;OUTPUT: NONE
    MOUSEHIDE	PROC NEAR
    		PUSH AX
    		MOV AX, 02H
    		INT 33H
    		POP AX
    		RET
    MOUSEHIDE	ENDP

    ;FUNCTION: INITIALIZE MOUSE DRIVER
    ;INPUT: NONE
    ;OUTPUT: NONE
    MOUSEINIT	PROC NEAR
    		PUSH AX
    		MOV AX, 00H
    		INT 33H
    		CMP AX, -1; -1 MEANS OK
    		JE MOUSEINIT_
    		PUSH DS
    		PUSH DX
    		MOV AX, CS
    		MOV DS, AX
    		MOV AH, 09H
    		MOV DX, OFFSET MOUSEERRORMSG
    		INT 21H
    		POP DX
    		POP DS
    		MOV AX, 04C01H
    		INT 21H

    MOUSEINIT_:
    		POP AX
    		RET
    MOUSEERRORMSG DB "!!!!!!!MOUSE DRIVER NOT INITIALIZED!"
    			  DB "TERMINATING PROGRAM!!! 0DH, 0AH", "$"
    MOUSEINIT	ENDP

    ;FUNCTION: DISPLAY A INTEGER IN BINARY FORM
    ;INPUT: BY STACK A INTEGER
    ;OUTPUT: NONE
    DISPLAYINTEGERB	PROC NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		XOR BX, BX
    		MOV BX, [BP+4]; THE NUMBER IN BX
    		MOV CX, 4
    		MOV AH, 02H
    L20:
    		PUSH CX
    		MOV CX, 4; SPLIT INTO 4X4 TO INSERT SPACE IN BETWEEN
    L4BITS:
    		MOV DL, 00H
            	RCL BX, 1
    		ADC DL, 30H
    		INT 21H
    		LOOP L4BITS
    		POP CX
    		CALL SPACE

    		LOOP L20
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 2
    DISPLAYINTEGERB ENDP

    ;FUNCTION: DISPLAY A INTEGER IN HEXIDECMAL
    ;INPUT: BY STACK A INTEGER
    ;OUTPUT: NONE
    DISPLAYINTEGERH	PROC	NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
            MOV BX, [BP+4];
            MOV CX, 4;

    L129:
    		PUSH CX; CANNOT ROL BX, 4???!!!
    		MOV CX, 4
    L128:
            ROL BX, 1;
    		LOOP L128
    		POP CX; RESTORE CX

    		MOV AX, BX
    		MOV DX, 0FH; DX AS MASK
    		AND AX, DX; AX GET THE HEX
    		MOV DL, 00H
    		CMP AX, 9
            	JS  ADD30H
    		MOV DL, 17
    ADD30H:
    		ADD DL, 30H
    		ADD DL, AL; ADD THE HEX TO
    		MOV AH, 02H
    		INT 21H
                    LOOP L129
    		MOV DL, 'H'
    		INT 21H
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 2
    DISPLAYINTEGERH	ENDP

    ;FUNCTION: CMP STRING BYTE BY BYTE
    ;INPUT: BY STACK THE TWO STRING ADD
    ;OUTPUT: AX, 0=EQUAL, 1=FIRST BIGGER, -1=SECOND BIGGER
    STRCMP	PROC	NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH SI
    		PUSH DI
    		PUSH ES
    		MOV DI, [BP+6]; THE FIRST
    		MOV SI, [BP+4]; THE SECOND
    		MOV AX, DS
    		MOV ES, AX
    BEGINCMP:
    		;CMP BYTE [DI], [SI]

    		JG	FIRSTBIG
    		;JL	SECONDBIG
    		;JMP ENDCMP
    FIRSTBIG:
    		MOV AX, 1
    		JMP ENDCMP
    SECONDBIG:
    		MOV AX, -1
    		JMP ENDCMP
    ENDCMP:
    		MOV AX, 0
    		POP ES
    		POP DI
    		POP SI
    		POP BP
    		RET
    STRCMP	ENDP

    ;FUNCTION: COPY STRING TERMINATED WITH "$"
    ;OUTPUT: NONE
    ;INPUT:BY STACK, DEST ADD, SOURCE ADD
    STRCPY	PROC	NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH SI
    		PUSH DI
    		PUSH ES
    		MOV SI, [BP+4]; SOURCE
    		MOV DI, [BP+6]; DEST
    		MOV AX, DS
    		MOV ES, AX

    		REP MOVSB; MOV BYTE BY BYTE UNTIL "$"

    		POP ES
    		POP DI
    		POP SI
    		POP AX
    		POP BP
    		RET 4
    STRCPY	ENDP

    ;FUNCTION: CLEAR SCREEN BY WRITE 0 TO VIDEO MEMORY
    ;OUTPUT: NONE
    ;INPUT: NONE
    CLEARSCREEN	PROC NEAR
    		PUSH AX
    		PUSH BX
    		PUSH CX

    		PUSH ES

    		MOV CX, 64000
    		XOR BX, BX
    		MOV AX, 0A000H
    		MOV ES, AX
    		XOR AL, AL
    L59:
    		MOV ES:[BX], AL
    		INC BX
    		LOOP L59

    		POP ES

    		POP CX
    		POP BX
    		POP AX
    		RET
    CLEARSCREEN	ENDP

    ;DRAW VERTICAL BAR
    ;INPUT:NONE
    ;OUTPUT: NONE
    DRAWVERTICAL	PROC	NEAR
    		PUSH DX
    		MOV DL, VERTICAL_BAR
    		CALL SHOWCHAR
    		POP DX
    		RET
    DRAWVERTICAL	ENDP

    ;DRAW HORIZONTAL BAR
    ;INPUT:NONE
    ;OUTPUT: NONE
    DRAWHORIZONTAL	PROC	NEAR
    		PUSH DX
    		MOV DL, HORIZONTAL_BAR
    		CALL SHOWCHAR
    		POP DX
    		RET
    DRAWHORIZONTAL	ENDP

    ;FUNCTION: SHOW A CHAR
    ;INPUT: ONE CHAR IN DL
    ;OUTPUT: NONE
    SHOWCHAR	PROC	NEAR
    		PUSH AX
    		MOV AH, 02H
    		INT 21H
    		POP AX
    		RET
    SHOWCHAR	ENDP

    ;FUNCTION: GET A KEYED IN VALID INTEGER FROM USER
    ;INPUT: NONE
    ;OUTPUT: BY AX, AND DX A VALID INTEGER, DX WILL BE INITIALIZE TO 0,
    ;BEFORE KEYIN BY USER
    INPUTNUMBER	PROC NEAR
    		PUSH BX
    		PUSH CX
    		MOV AH, 00H
    		MOV BX, 00H
    		MOV DX, 00H
    		MOV CX, 00H; CX STORE THE OLD NUMBER
    NOMORE:
    		MOV AH, 01H
    		INT 21H
    		MOV BL, AL; STORE NEW NUMBER
    		MOV AX, CX
    		CMP BL, 0DH
    		JE	ENDINPUTLOOP
    		CMP BL, 30H
    		JL	NOTINTEGER
    		CMP BL, 39H
    		JG	NOTINTEGER
    		SUB BL, 30H

    		MOV CX, 10
    		MUL CX; MUL OLD NUMBER BY 10
    		CMP DX, 00H
    		JNE	L19
    		ADD AX, BX; ADD NEW NUMBER
    		JO	L19
    		MOV CX, AX; AND DX REMAINS UNCHANGED IF THERE IS ANY NUMBER
    		JMP NOMORE
    L19:
    		MOV DX, OFFSET MSGOVERFLOW
    		CALL SHOWMSG
    		JMP ENDALL
    NOTINTEGER:
    		MOV AH, 09H
    		MOV DX, OFFSET MSGINVALIDNUMBER
    		INT 21H
    		JMP ENDALL
    ENDINPUTLOOP:
    		MOV AX, CX
    ENDALL:
    		POP CX
    		POP BX
    		RET
    INPUTNUMBER ENDP

    ;FUNCTION: SHOW A STRING MESSAGE
    ;OUTPUT: NONE
    ;INPUT: DX CONTAIN THE OFFSET OF MSG
    SHOWMSG	PROC	NEAR
    		PUSH AX
    		MOV AH, 09H
    		INT 21H
    		CALL RETURN;
    		POP AX
    		RET
    SHOWMSG	ENDP

    SPACE	PROC	NEAR
    		PUSH AX
    		PUSH DX
    		MOV AH, 02
    		MOV DL, ' '
    		INT 21H
    		POP DX
    		POP AX
    		RET
    SPACE	ENDP

    ;FUNCTION: RETURN TO NEW LINE;(VERY FUNNY?)
    ;INPUT: NONE
    ;OUTPUT: NONE
    RETURN	PROC	NEAR
    		PUSH AX
    		PUSH DX
    		MOV AH, 02H
    		MOV DL, 0DH
    		INT 21H
    		MOV DL, 0AH
    		INT 21H
    		POP DX
    		POP AX
    		RET
    RETURN ENDP

    ;FUNCTION: FIND THE LEAST COMMON MULTIPLICATION
    ;INPUT: BY STACK, TWO NUMBERS
    ;OUTPUT; BY STACK, THE LEAST COMMON MULTIPLICATION
    LCM	 PROC NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH DX
    		MOV AX, [BP+6]; THE FIRST NUMBER
    		MOV DX, [BP+4]; THE SECONDE NUMBER
    		PUSH AX
    		PUSH DX
    		CALL GCD; TO FIND THEIR GCD
    		MUL DX; FIND THE MULTIPLICATION OF TWO NUMBER
    		POP BX; BX IS THE GCD
    		DIV BX; THIS GET THE LCM
    		MOV [BP+6], AX
    		POP DX
    		POP BX
    		POP AX
    		POP BP
    		RET 2
    LCM ENDP

    ;FUNCTION: DISPLAY A INTEGER IN ASCII
    ;INPUT: BY STACK A INTEGER
    ;OUTPUT: NONE
    DISPLAYINTEGER	PROC
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		MOV AX, [BP+4]; THE INTEGER
    		MOV BX, 10; THE DIVISOR
    		MOV CX, 00H
    DIVIDINGLOOP:
    		MOV DX, 00H
    		DIV BX
    		PUSH DX
    		INC CX;
    		CMP AX, 00H
    		JNE	DIVIDINGLOOP

    		MOV AH, 02H
    DISPLAYLOOP:
    		POP DX;
    		ADD DX, 30H
    		INT 21H
    		LOOP DISPLAYLOOP;
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET	2;
    DISPLAYINTEGER	ENDP

    ;GREATEST COMMON DIVISOR
    ;INPUT: BY STACK, TWO INTEGER
    ;OUTPUT: BY STACK GCD
    GCD	PROC NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		MOV AX, [BP+6]; THE DIVIDANT
    		MOV BX, [BP+4]; THE DIVISOR

    GCDLOOP:
    		MOV DX, 00H; IMPORTANT
    		DIV BX
    		CMP DX, 00H
    		JE	OUTGCDLOOP
    		MOV AX, BX; DIVISOR BECOME DIVIDANT
    		MOV BX, DX; THE REMAINDER BECOME DIVISOR
    		JMP GCDLOOP
    OUTGCDLOOP:
    		MOV [BP+6], BX
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP	BP
    		RET 2;
    GCD ENDP

    ; INPUT: NONE
    ; OUTPUT: NONE
    ; FUNCTION: CHANGE TO GRAPHIC MODE
    ENTERGRAPHIC PROC
    		PUSH AX
    		MOV AX, 0A000H
    		MOV ES, AX
    		MOV AH, 00H
    		MOV AL, 13H
    		INT 10H
    		;CALL REFRESH
    		POP AX
    		RET
    ENTERGRAPHIC ENDP

    ;INPUT: NONE
    DRAWBOARD	PROC
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		MOV AX, 20
    		PUSH AX; X
    		PUSH AX; Y
    		MOV AX, 8
    		PUSH AX; 8 ROW
    		PUSH AX; 8 COL
    		MOV AX, 20; WIDTH
    		PUSH AX
    		MOV AX, 11
    		PUSH AX; COLOR
    		CALL INTERNALDRAWGRID

    		MOV CX, 0
    LOCAL10:
    		CMP CX, 8
    		JE OUTLOCAL10
    		MOV BX, CX
    		PUSH CX; SAVE ROW NUMBER
    		MOV CX, 0; START THE NEW COL
    LOCAL11:
    		CMP CX, 8
    		JE ENDOUTER
    		; THE PARAM ARE SAME
    		MOV AX, 20
    		PUSH AX; X
    		PUSH AX; Y
    		PUSH BX; ROW
    		PUSH CX; COL
    		MOV AX, 20; WIDTH
    		PUSH AX

    		;THE FOLLOWING IS COLOR BY  ROW AND COL
    		MOV AX, CX;

    		AND AX, 1
    		CMP AX, 0
    		JE COLEVEN
    		;COL IS ODD
    		MOV AX, BX

    		AND AX, 1
    		CMP AX, 0
    		JE BLACKDRAW; ODD+EVEN=BLACK
    		JMP WHITEDRAW; ODD +ODD = WHITE

    COLEVEN:
    		MOV AX, BX

    		AND AX, 1
    		CMP AX, 0
    		JE WHITEDRAW ; EVEN+EVEN = WHITE
    		JMP BLACKDRAW ; EVEN +ODD = BLACK

    WHITEDRAW:

    		MOV AX, 15; WHITE
    		JMP NEXTDRAW
    BLACKDRAW:
    		MOV AX, 8; BLACK

    NEXTDRAW:
    		PUSH AX
    		CALL FILLGRID
    ENDINNER:
    		INC CX
    		JMP LOCAL11

    ENDOUTER:
    		POP CX
    		INC CX
    		JMP LOCAL10
    OUTLOCAL10:

    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		RET
    DRAWBOARD ENDP

    ;INPUT X, Y, ROW, COL, WIDTH, COLOR
    INTERNALDRAWGRID	PROC
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		PUSH SI
    		PUSH DI

    		MOV AX, [BP+12]; Y
    		MOV BX, 320
    		MUL BX
    		ADD AX, [BP+14]; +X
    		MOV BX, AX; BX HOLDS THE OFFSET
    		MOV SI, [BP+10]; THE ROW
    		MOV DI, [BP+8]; THE COL

    		MOV AX, [BP+6]; THE GRIDLENGTH
    		MUL SI; CAL ROW LENGTH
    		ADD SI, AX; PLUS THE ROW LINE WIDTH
    		INC SI; ONE MORE LINE FOR ROW, AS 15 ROW HAS 16 LINE, SI IS THE HEIGHT

    		MOV AX, [BP+6]; GRIDLENGTH TO PREPARE TO CAL COL LENGTH
    		MUL DI; CAL COL LEN
    		ADD DI, AX; DI IS LENGTH OF COL
    		INC DI; ONE MORE LINE, DI IS THE WIDTH OF GRID IN TOTAL

    		MOV DX, [BP+4]; COLOR
    		MOV CX, [BP+10]; THE ROW NUMBER
    		INC CX; ONE MORE LINE
    		PUSH BX

    ROWLOOP:
    		PUSH CX; SAVE CX FOR INNER LOOP
    		PUSH BX; SAVE OFFSET
    		MOV CX, DI; THE WIDTH OF EACH ROW LINE
    HORLINELOOP:
    		MOV ES:[BX], DL
    		INC BX
    		LOOP HORLINELOOP
    		POP BX; RESTORE OFFSET

    		; CAL THE OFFSET OF NEXT ROW
    		MOV AX, [BP+6]; THE LENGTH OF EACH GRID
    		INC AX; THE DIFFERENCE OF LINE OF NEXT ROW
    		PUSH DX
    		MOV DX, 320
    		MUL DX
    		POP DX

    		ADD BX, AX; CHANGE LINE
    		POP CX; RESTORE THE ROW COUNTER
    		LOOP ROWLOOP

    		POP BX; THIS IS THE ORIGINAL OFFSET FOR COL USE
    		MOV CX, [BP+8]; THE COL NUMBER
    		INC CX; ONE MORE LINE
    COLLOOP:
    		PUSH CX
    		PUSH BX
    		MOV CX, SI; THE HEIGHT OF TOTAL GRID
    VERLINELOOP:
    		MOV ES:[BX], DL
    		ADD BX, 320
    		LOOP VERLINELOOP
    		POP BX
    		POP CX
    		; NEXT COL IS THE LENGTH OF GRID
    		MOV AX, [BP+6]; THE LENGTH OF GRID
    		INC AX; ONE MORE LINE
    		ADD BX, AX
    		LOOP COLLOOP;

    		POP DI
    		POP SI
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 12
    INTERNALDRAWGRID	ENDP

    ;INPUT ROW, COL, SIZE OF EACH CELL
    ;OUT PUT X, Y OFFSET BY STACK
    CALCOFFSET  PROC
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		MOV  CX, [BP+4]; THE SIZE OF CELL
    		INC CX; THE DIFFERENCE BTW TWO CELL

    		MOV AX, [BP+8]; THE ROW
    		MUL CX; EACH ROW OFFSET
    		MOV BX, AX; SAVE IN BX THE Y OFFSET

    		MOV AX, [BP+6]; THE COL
    		MUL CX; THE X DIFFERENCE
    		MOV [BP+8], AX; SAVE THE X
    		MOV [BP+6], BX; SAVE THE Y
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 2
    CALCOFFSET  ENDP

    REFRESH	PROC
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		MOV AX, 00H
    		MOV CX, 64000
    		MOV BX, 0
    LOCAL1:
    		MOV ES:[BX], AL
    		INC BX
    		LOOP LOCAL1
    		POP CX
    		POP BX
    		POP AX
    		RET
    REFRESH   ENDP

    ;INPUT: ORIGIN OF X,Y,ROW,COL,SIZE OF CELL,COLOR
    FILLGRID	PROC  NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		MOV CX, [BP+6]; THE SIZE OF CELL

    		MOV AX, [BP+10]; ROW INDEX
    		PUSH AX; PREPARE PARAM FOR "CALCOFFSET" CALL
    		MOV AX, [BP+8]; THE COL INDEX
    		PUSH AX
    		PUSH CX; PASS THE SIZE
    		CALL CALCOFFSET
    		POP BX; IT IS Y OFFSET
    		ADD BX, [BP+12]; PLUS ORIGINAL Y
    		POP AX; THE NEW X
    		ADD AX, [BP+14]; PLUS ORIGINAL X
    		MOV DX, [BP+4]; THE COLOR
    		INC AX
    		INC BX
    		PUSH AX; X
    		PUSH BX; Y
    		PUSH CX; THE SIZE OF BOX
    		PUSH DX; THE COLOR OF BOX
    		CALL DRAWBOX
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 12
    FILLGRID	ENDP

    ; INPUT X,Y
    DRAWGRID	PROC NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		MOV AX, [BP+6]; THE X
    		PUSH AX
    		MOV AX, [BP+4]; THE Y
    		PUSH AX
    		MOV AX, DIM
    		PUSH AX
    		PUSH AX
    		MOV AX, CELLSIZE
    		PUSH AX
    		MOV AX, 0EH; THE COLOR OF YELLOW
    		PUSH AX
    		CALL INTERNALDRAWGRID
    		POP AX
    		POP BP
    		RET 4;
    DRAWGRID ENDP

    ;INPUT: X,Y,LENGTH,COLOR BY STACK
    ;OUTPUT: NONE
    ;FUNCTION: DRAW HORIZONTAL LINE WITH STARTING COORDINATE, LENGTH, COLOR,
    DRAWHORLINE	PROC
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH ES
    		MOV AX, 0A000H
    		MOV ES, AX
    		MOV AX, [BP+8]; THE Y
    		MOV BX, 320
    		MUL BX
    		ADD AX, [BP+10]; X
    		MOV BX, AX; BX HOLDS THE OFFSET ORIGIN
    		MOV CX, [BP+6]; THE LENGTH
    		MOV AX, [BP+4]
    HLINE:
    		MOV ES:[BX], AL; DRAW THE LINE
    		INC BX
    		LOOP HLINE
    		POP ES
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 8
    DRAWHORLINE	ENDP

    DRAWVERLINE	PROC
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH ES
    		MOV AX, [BP+8]; THE Y
    		MOV BX, 320
    		MUL BX
    		ADD AX, [BP+10]; ADD THE X
    		MOV BX, AX; BX HOLDS THE OFFSET
    		MOV CX, [BP+6]; THE LENGTH
    		MOV AX, [BP+4]; THE COLOR
    VLINE:
    		MOV ES:[BX], AL
    		ADD BX, 320
    		LOOP VLINE
    		POP ES
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 8
    DRAWVERLINE	ENDP

    ENTERTEXT PROC
    		PUSH AX
    		MOV AH, 00H
    		MOV AL, 03H
    		INT 10H
    		MOV AX, 0B800H
    		MOV ES, AX
    		POP AX
    		RET
    ENTERTEXT ENDP

    ;INPUT: NONE
    ;OUTPUT: NONE
    ;FUNCTION SIMPLY WAIT FOR ANY KEY TO BE PRESSED
    WAITRETURN  PROC
    		PUSH AX
    		XOR AX, AX
    		MOV AH, 01H
    CHECK:
    		INT 21H
    		CMP AL, 0DH
    		JNE CHECK
    		POP AX
    		RET
    WAITRETURN  ENDP

    ;INPUT: X, Y, LENGTH, COLOR BY STACK
    ;OUTPUT: NONE
    ;FUNCTION: DRAW A BOX OF WHICH THE LEFTTOP HAS COORDINATE OF (X,Y),LENGTH, COLOR
    ;SAVE ES INTERNALLY,
    DRAWBOX     PROC  NEAR
    		PUSH BP
    		MOV BP, SP
    		PUSH AX
    		PUSH BX
    		PUSH CX
    		PUSH DX
    		PUSH ES
    		MOV AX, 0A000H
    		MOV ES, AX
    		MOV BX, [BP+10]; X
    		MOV AX, [BP+8]; Y

    		MOV CX, 320
    		MUL CX
    		ADD BX, AX; BX IS OFFSET=320* Y + X
    		MOV AX, [BP+4]; COLOR
    		MOV CX, [BP+6]; R
    		MOV DX, CX ;DX SAVE LENGTH

    BOXLOOP:
    		PUSH CX; SAVE OUTTER COUNTER
    		PUSH BX; SAVE OFFSET
    		MOV CX, DX; NEW START
    SINGLELOOP:
    		MOV ES:[BX], AL
    		INC BX
    		LOOP SINGLELOOP
    		POP BX
    		ADD BX, 320;NEXT LINE
    		POP CX
    		LOOP BOXLOOP
    		POP ES
    		POP DX
    		POP CX
    		POP BX
    		POP AX
    		POP BP
    		RET 8
    DRAWBOX     ENDP

    END

¡¡

¡¡