; Changes russian characters (128-175 and 224-239) to English equivalent ; -Main Procedures: ; -change_characters - change russian characters in video memory ; -TIMER_USER_ROUTINE - Processing at each Timer Interrupt(1c) ; -user_int_09 - processing at each keyboard interrupt ; -user_int_2f - communicate with the previous copy of itself ; -INIT_PROC - Initialize program and make resident. Not ; retained in memory with resident portion ; RUS_CGA SEGMENT PUBLIC 'CODE' ASSUME CS:RUS_CGA ; ORG 80h length_string LABEL byte ORG 81h command_string LABEL byte ORG 100H start: JMP begin ;INITIALIZE & MAKE RESIDENT ; ; Program Save Area for Interrupts and Data ; BIOS_TIMER_EXIT DW ?,? ;BIOS INTERRUPT POINTERS FOR TIMER EXIT bios_int_09 DW ?,? ;bios pointers for keyboard itterrupt prev_int_2f DW ?,? ;poiters for previous int 2f regime DB 0 ; 0 for keyboard interrupt to work ; 1 for timer interrupt to work firstchain DB 65,66,86,71,68,69,74,90,73,73,75,76,77,78,79,80 ; 128-175 DB 82,83,84,85,70,72,67,211,206,209,34,89,39,69,85,65 DB 97,98,118,103,100,101,106,122,105,105,107,108,109,110,111,112 secondchain DB 114,115,116,117,102,104,99,192,193,194,34,121,39,101,117,97 ;224-239 ; ; change_characters PROC NEAR push ax ; save registers push bx push cx push dx push si push ds push es mov ax,cs mov ds,ax mov ah,0fh ; read video state int 10h cmp al,3 ja exit_timer ; only text mode 0-3 cmp ah,40 jz _40 mov cx,2000 ; 80 colomns jmp continue _40: mov cx,1000 ; 40 colomns continue: mov ax,0b800h ; segment address of video memory mov es,ax mov ax,2000 ; get address of video memory mov bl,bh sub bh,bh mul bx ; 1000(2000) * N of page mov si,ax loop1: mov al,es:[si] cmp al,128 jb exit cmp al,175 ja second mov bx, OFFSET firstchain - 128 jmp SHORT change second: cmp al,224 jb exit cmp al,239 ja exit mov bx, OFFSET secondchain - 224 change: xlat mov es:[si],al exit: add si,2 loop loop1 exit_timer: pop es pop ds pop si pop dx pop cx pop bx pop ax ret change_characters ENDP ; ; Timer Exit Routine ; -Uses INT 1C, but chains interrupt in the event additional user routines ; are installed timer_user_routine PROC NEAR cmp regime, 1 jnz timer_done call change_characters timer_done: jmp dword ptr bios_timer_exit ;chain to next routine or exit ; to finish timer interrupt timer_user_routine ENDP user_int_09 PROC NEAR cmp regime, 0 jnz key_done push ax in al, 60h cmp al, 36h ; right shift pop ax jnz key_done call change_characters key_done: jmp dword ptr bios_int_09 user_int_09 ENDP user_int_2f PROC NEAR cmp ax, 4542h ; the message from the next copy? jnz com_done cmp bx, 5249h jnz com_done mov cs:regime, dl mov bx, 0 com_done: jmp dword ptr prev_int_2f user_int_2f ENDP ; ; Initialize Program and Make Resident ; INIT_PROC PROC NEAR MESSAGE DB 'Russian characters in CGA, E. Rudnyi', 0ah, 0ah, 0dh DB 'RUSCGA [C|K]',0ah, 0dh DB 'K - uses the keyboard interrupt (default),', 0ah, 0dh DB ' press RIGHT SHIFT to change russian characters', 0ah, 0dh DB 'C - uses the timer interrupt,', 0ah, 0dh DB ' changes russian characters continuously', 0ah, 0dh, '$' there_is_mes DB 0ah, 'RUSCGA have been already installed', 0ah, 0dh, '$' timer_mode DB 'now in the timer mode', 0ah, 0dh, '$' keyboard_mode DB 'now in the keyboard mode', 0ah, 0dh, '$' ; begin: ASSUME ds:RUS_CGA mov ax,cs mov ds,ax mov ch, 0 mov cl, length_string mov si, 0 loop_string: cmp command_string[si], 32 ; space jnz check_character inc si loop loop_string jmp default check_character: mov dl, command_string[si] or dl, 20h cmp dl, 63h ; c or C jnz default mov dl, 1 ; set timer mode mov regime, dl jmp communicate default: mov dl, 0 ; set not 'c' character communicate: mov ax, 4542h ; communicate with previous copy mov bx, 5249h int 2fh cmp bx, 0 ; there is a copy jz there_is mov ah,35h ; get vector mov al,1ch int 21h mov bios_timer_exit,bx ; routine using mov bios_timer_exit[2],es ; timer exit mov dx,offset timer_user_routine ; set timer exit mov ah,25h ; set vector mov al,1ch int 21h ; mov ah,35h ; get vector mov al,09h int 21h mov bios_int_09,bx ; routine using mov bios_int_09[2],es ; keyboard exit mov dx,offset user_int_09 ; set keyboard exit mov ah,25h ; set vector mov al,09h int 21h mov ah,35h ; get vector mov al,2fh int 21h mov prev_int_2f,bx mov prev_int_2f[2],es mov dx,offset user_int_2f mov ah,25h ; set vector mov al,2fh int 21h mov dx,OFFSET message ;print intro mov ah,9 int 21h mov dx,OFFSET init_proc ;end of resident portion int 27h ; terminate and stay resident there_is: mov dx, OFFSET message mov ah, 9 int 21h mov dx, OFFSET there_is_mes int 21h ; print message cmp regime, 1 jz t_mode mov dx, OFFSET keyboard_mode jmp done t_mode: mov dx, OFFSET timer_mode done: int 21h mov ax, 4c00h int 21h ; terminate INIT_PROC ENDP RUS_CGA ENDS END start