
	ASSUME	CS:CSEG
;********************************************************************
CSEG	SEGMENT	DWORD PUBLIC USE32 'CODE'

DATALEN	EQU	20000H

;void crtcout(int crtcreg, int data)

CRTCREG	EQU	4
DATA	EQU	8

	PUBLIC	CRTCOUT
CRTCOUT	PROC	NEAR
	MOV	DX,440H
	MOV	AL,[ESP+CRTCREG]
	OUT	DX,AL
	MOV	DL,42H
	MOV	EAX,[ESP+DATA]
	OUT	DX,AX
	RET

CRTCOUT	ENDP

;void save_r(char *buffer)

BUFFER	EQU	36

	PUBLIC	SAVE_R
SAVE_R	PROC	NEAR
	PUSHAD
	MOV	AX,130H
	MOV	DS,AX
	XOR	ESI,ESI
	MOV	EDI,[ESP+BUFFER]
	MOV	ECX,DATALEN/4
	REP	MOVSD
	MOV	AX,14H
	MOV	DS,AX
	POPAD
	RET

SAVE_R	ENDP

;void load_r(char *buffer)

	PUBLIC	LOAD_R
LOAD_R	PROC	NEAR
	PUSHAD
	MOV	ESI,[ESP+BUFFER]
	MOV	AX,130H
	MOV	ES,AX
	XOR	EDI,EDI
	MOV	ECX,DATALEN/4
	REP	MOVSD
	MOV	AX,14H
	MOV	ES,AX
	POPAD
	RET

LOAD_R	ENDP

;int print_3(int x, int y, int col, char *str, int len)

X	EQU	36
Y	EQU	40
COL	EQU	44
STR	EQU	48
LEN	EQU	52

	PUBLIC	PRINT_3
PRINT_3	PROC	NEAR
	XOR	EAX,EAX
	PUSHAD
	DEC	BYTE PTR [ESP+LEN]
	JS	NULL_STRING
	MOV	ESI,[ESP+STR]
	MOV	AL,[ESP+COL]
	AND	AL,0FH
	CMP	AL,8
	JNC	SHORT REVERSE
	XOR	AL,7
REVERSE:
	LEA	ECX,[EAX*2]
	LEA	EAX,[EAX+ECX*8]
	MOV	AH,AL
	MOV	ECX,EAX
	SHL	ECX,16
	MOV	CX,AX
	XOR	EAX,EAX
	MOV	AH,[ESP+Y]
	SHL	EAX,3			; (y*0x800)
	MOV	AL,[ESP+X]
	LEA	EDI,[EAX*4]		; (y*0x800+x)*4
	MOV	AX,104H
	MOV	ES,AX
	MOV	AL,10H
	MOV	FS,AX
	MOV	EBP,OFFSET BIT_PATTERN
NEXT_LETTER:
	LODSB
	MOV	BL,AL
	CMP	AL,81H
	JC	JIS_8BIT
	CMP	AL,0A0H
	JC	SHORT SHIFT_JIS
	CMP	AL,0E0H
	JC	JIS_8BIT
	CMP	AL,0FDH
	JNC	JIS_8BIT
SHIFT_JIS:
	MOV	BH,BL
	LODSB
	CMP	AL,40H
	JC	NOT_SHIFT_JIS
	CMP	AL,0FDH
	JNC	NOT_SHIFT_JIS
	CMP	AL,7FH
	JZ	NOT_SHIFT_JIS
	DEC	BYTE PTR [ESP+LEN]
	SETS	BYTE PTR [ESP+28]
	PUSH	ESI
	MOV	BL,AL
	MOV	AH,2
	CALL	PWORD PTR FS:[0A0H]
	MOV	AX,100H
	MOV	DX,1010H
	CALL	PWORD PTR FS:[0A0H]
	MOV	EDX,200H-8
	REPT	16
	XOR	EAX,EAX
	LODSB
	MOV	EAX,[EBP+EAX*4]
	XOR	EAX,ECX
	STOSD
	XOR	EAX,EAX
	LODSB
	MOV	EAX,[EBP+EAX*4]
	XOR	EAX,ECX
	STOSD
	ADD	EDI,EDX
	ENDM
	SUB	EDI,200H*16-8
	JMP	CONTINUE
NOT_SHIFT_JIS:
	DEC	ESI
JIS_8BIT:
	PUSH	ESI
	XOR	EAX,EAX
	MOV	DX,810H
	CALL	PWORD PTR FS:[0A0H]
	MOV	EDX,200H-4
	REPT	16
	XOR	EAX,EAX
	LODSB
	MOV	EAX,[EBP+EAX*4]
	XOR	EAX,ECX
	STOSD
	ADD	EDI,EDX
	ENDM
	SUB	EDI,200H*16-4
CONTINUE:
	POP	ESI
	MOV	AX,14H
	MOV	DS,AX
	DEC	BYTE PTR [ESP+LEN]
	JNS	NEXT_LETTER
	MOV	FS,AX
	MOV	ES,AX
NULL_STRING:
	POPAD
	RET

	ALIGN	4
BIT_PATTERN:
	DD	000000000H,0F0000000H,00F000000H,0FF000000H
	DD	000F00000H,0F0F00000H,00FF00000H,0FFF00000H
	DD	0000F0000H,0F00F0000H,00F0F0000H,0FF0F0000H
	DD	000FF0000H,0F0FF0000H,00FFF0000H,0FFFF0000H
	DD	00000F000H,0F000F000H,00F00F000H,0FF00F000H
	DD	000F0F000H,0F0F0F000H,00FF0F000H,0FFF0F000H
	DD	0000FF000H,0F00FF000H,00F0FF000H,0FF0FF000H
	DD	000FFF000H,0F0FFF000H,00FFFF000H,0FFFFF000H
	DD	000000F00H,0F0000F00H,00F000F00H,0FF000F00H
	DD	000F00F00H,0F0F00F00H,00FF00F00H,0FFF00F00H
	DD	0000F0F00H,0F00F0F00H,00F0F0F00H,0FF0F0F00H
	DD	000FF0F00H,0F0FF0F00H,00FFF0F00H,0FFFF0F00H
	DD	00000FF00H,0F000FF00H,00F00FF00H,0FF00FF00H
	DD	000F0FF00H,0F0F0FF00H,00FF0FF00H,0FFF0FF00H
	DD	0000FFF00H,0F00FFF00H,00F0FFF00H,0FF0FFF00H
	DD	000FFFF00H,0F0FFFF00H,00FFFFF00H,0FFFFFF00H
	DD	0000000F0H,0F00000F0H,00F0000F0H,0FF0000F0H
	DD	000F000F0H,0F0F000F0H,00FF000F0H,0FFF000F0H
	DD	0000F00F0H,0F00F00F0H,00F0F00F0H,0FF0F00F0H
	DD	000FF00F0H,0F0FF00F0H,00FFF00F0H,0FFFF00F0H
	DD	00000F0F0H,0F000F0F0H,00F00F0F0H,0FF00F0F0H
	DD	000F0F0F0H,0F0F0F0F0H,00FF0F0F0H,0FFF0F0F0H
	DD	0000FF0F0H,0F00FF0F0H,00F0FF0F0H,0FF0FF0F0H
	DD	000FFF0F0H,0F0FFF0F0H,00FFFF0F0H,0FFFFF0F0H
	DD	000000FF0H,0F0000FF0H,00F000FF0H,0FF000FF0H
	DD	000F00FF0H,0F0F00FF0H,00FF00FF0H,0FFF00FF0H
	DD	0000F0FF0H,0F00F0FF0H,00F0F0FF0H,0FF0F0FF0H
	DD	000FF0FF0H,0F0FF0FF0H,00FFF0FF0H,0FFFF0FF0H
	DD	00000FFF0H,0F000FFF0H,00F00FFF0H,0FF00FFF0H
	DD	000F0FFF0H,0F0F0FFF0H,00FF0FFF0H,0FFF0FFF0H
	DD	0000FFFF0H,0F00FFFF0H,00F0FFFF0H,0FF0FFFF0H
	DD	000FFFFF0H,0F0FFFFF0H,00FFFFFF0H,0FFFFFFF0H
	DD	00000000FH,0F000000FH,00F00000FH,0FF00000FH
	DD	000F0000FH,0F0F0000FH,00FF0000FH,0FFF0000FH
	DD	0000F000FH,0F00F000FH,00F0F000FH,0FF0F000FH
	DD	000FF000FH,0F0FF000FH,00FFF000FH,0FFFF000FH
	DD	00000F00FH,0F000F00FH,00F00F00FH,0FF00F00FH
	DD	000F0F00FH,0F0F0F00FH,00FF0F00FH,0FFF0F00FH
	DD	0000FF00FH,0F00FF00FH,00F0FF00FH,0FF0FF00FH
	DD	000FFF00FH,0F0FFF00FH,00FFFF00FH,0FFFFF00FH
	DD	000000F0FH,0F0000F0FH,00F000F0FH,0FF000F0FH
	DD	000F00F0FH,0F0F00F0FH,00FF00F0FH,0FFF00F0FH
	DD	0000F0F0FH,0F00F0F0FH,00F0F0F0FH,0FF0F0F0FH
	DD	000FF0F0FH,0F0FF0F0FH,00FFF0F0FH,0FFFF0F0FH
	DD	00000FF0FH,0F000FF0FH,00F00FF0FH,0FF00FF0FH
	DD	000F0FF0FH,0F0F0FF0FH,00FF0FF0FH,0FFF0FF0FH
	DD	0000FFF0FH,0F00FFF0FH,00F0FFF0FH,0FF0FFF0FH
	DD	000FFFF0FH,0F0FFFF0FH,00FFFFF0FH,0FFFFFF0FH
	DD	0000000FFH,0F00000FFH,00F0000FFH,0FF0000FFH
	DD	000F000FFH,0F0F000FFH,00FF000FFH,0FFF000FFH
	DD	0000F00FFH,0F00F00FFH,00F0F00FFH,0FF0F00FFH
	DD	000FF00FFH,0F0FF00FFH,00FFF00FFH,0FFFF00FFH
	DD	00000F0FFH,0F000F0FFH,00F00F0FFH,0FF00F0FFH
	DD	000F0F0FFH,0F0F0F0FFH,00FF0F0FFH,0FFF0F0FFH
	DD	0000FF0FFH,0F00FF0FFH,00F0FF0FFH,0FF0FF0FFH
	DD	000FFF0FFH,0F0FFF0FFH,00FFFF0FFH,0FFFFF0FFH
	DD	000000FFFH,0F0000FFFH,00F000FFFH,0FF000FFFH
	DD	000F00FFFH,0F0F00FFFH,00FF00FFFH,0FFF00FFFH
	DD	0000F0FFFH,0F00F0FFFH,00F0F0FFFH,0FF0F0FFFH
	DD	000FF0FFFH,0F0FF0FFFH,00FFF0FFFH,0FFFF0FFFH
	DD	00000FFFFH,0F000FFFFH,00F00FFFFH,0FF00FFFFH
	DD	000F0FFFFH,0F0F0FFFFH,00FF0FFFFH,0FFF0FFFFH
	DD	0000FFFFFH,0F00FFFFFH,00F0FFFFFH,0FF0FFFFFH
	DD	000FFFFFFH,0F0FFFFFFH,00FFFFFFFH,0FFFFFFFFH

PRINT_3	ENDP

CSEG	ENDS
;********************************************************************
	END
