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



 

 

                                                        back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)