qwardes
qwardes

Reputation: 51

How to get alpha character (α) in DOS/Asembler?

I'm in college and have few Asembler classes. My teacher gave us code below:

.286
.model small
.data
.stack 64h
.cide
main:
 MOV AX,0B800H
 MOV ES,AX
 MOV ES:[240], 7C03H
 MOV AH,1h
 INT 21h

 MOV AX,4C00H
 INT 21h
end main

It simply puts red heart on gray beck ground on the screen. My homework is to change that heart to α. He also linked this site: https://www.rapidtables.com/code/text/alt-codes.html in the example. There, code for α is 224 (E0), but when I change 7C03H to 7CE0H I get Ó instead of α. I've tried every number from 0 to 255, but none work. From what I see nothing from int 21h and int 10h, allows more than 1 byte for character.

I did some googling and found that DOS is using code page 852, which doesnt have an α.

Can I somehow change the code page, in this program or is it impossible to get α? My program doesn't need to look exactly like the example. I can use other interrupts like 10h,21h or 16h.

Upvotes: 3

Views: 159

Answers (1)

Sep Roland
Sep Roland

Reputation: 39506

Changing code pages

The Slavic (Latin II) code page 852 does not contain Greek characters other than the ß (Beta) which is used in the German language.
One solution to displaying Greek characters is to switch code pages with DOS. The DOS standard code page 437 does contain some Greek characters.

If NLSFUNC is not installed:

  • From the command prompt you would use mode con cp select=437.

If NLSFUNC is installed:

  • From the command prompt you would use chcp 437.
  • From within an application you would use the DOS.SetGlobalCodePage function 6602h.

Either way, the system needs the correct configuration in order to support multiple code pages. Below is an excerpt of what my configuration files contain:

CONFIG.SYS:

DEVICE=C:\DOS\DISPLAY.SYS CON=(EGA,850,2)
COUNTRY=032,850,C:\DOS\COUNTRY.SYS
INSTALL=C:\DOS\NLSFUNC.EXE

AUTOEXEC.BAT:

C:\DOS\MODE.COM CON CODEPAGE PREPARE=((437 850) C:\DOS\EGA.CPI)
C:\DOS\MODE.COM CON CODEPAGE SELECT=850
C:\DOS\KEYB.COM BE,850,C:\DOS\KEYBOARD.SYS

Next is a demonstration program that shows how to swith to code page 437 from within an application. The program clearly proves that it does not matter how you get the character to the screen (via DOS, BIOS, or VRAM). The switch goes into effect immediately and even characters that were already on the screen change accordingly.

; Changing code pages from within an application (c) 2021 Sep Roland
; ( With the intention to display Greek characters ... )
; Assemble with FASM

        ORG     256

; If NLSFUNC is not installed, changing code pages is not an option
        xor     bx, bx
        mov     ax, 1400h       ; NLSFUNC.CheckInstallationStatus
        int     2Fh             ; -> AL
        cmp     al, 0FFh
        jne     Print           ; Nlsfunc is NOT installed

; No need to change if Active Code Page is 437
        mov     ax, 6601h       ; DOS.GetGlobalCodePage
        int     21h             ; -> BX DX CF
        jc      Print
        cmp     bx, 437         ; Is Active Code Page == 437 ?
        je      Print

; Temporarily changing the Active Code Page to 437
        push    bx              ; (1)
        mov     bx, 437
        mov     ax, 6602h       ; DOS.SetGlobalCodePage
        int     21h             ; -> CF
        pop     bx              ; (1)
        jc      Print

; Test the character range from 224 to 239
        call    Greek

; Restore previous Active Code Page
        mov     ax, 6602h       ; DOS.SetGlobalCodePage
        int     21h             ; -> CF
        jmp     Exit

Print:  call    Greek

Exit:   mov     ax, 4C00h       ; DOS.TerminateWithReturnCode
        int     21h
; ------------------------------
Greek:  pusha

        mov     dx, .msg1
        mov     ah, 09h         ; DOS.DisplayString
        int     21h
        mov     dl, 224
.a:     mov     ah, 02h         ; DOS.DisplayOutput
        int     21h
        inc     dl
        cmp     dl, 240
        jb      .a

        mov     dx, .msg2
        mov     ah, 09h         ; DOS.DisplayString
        int     21h
        mov     al, 224
.b:     mov     ah, 0Eh         ; BIOS.Teletype
        int     10h
        inc     al
        cmp     al, 240
        jb      .b

        mov     dx, .msg3
        mov     ah, 09h         ; DOS.DisplayString
        int     21h
        mov     bh, 0
        mov     ah, 03h         ; BIOS.GetCursorPosition
        int     10h             ; -> CX, DL is Column, DH is Row
        mov     al, 160
        mul     dh
        mov     dh, 0
        add     ax, dx
        add     ax, dx
        mov     di, ax
        push    es              ; (1)
        mov     ax, 0B800h
        mov     es, ax
        mov     ax, 0EE0h       ; YellowOnBlack ASCII 224
.c:     stosw
        inc     al
        cmp     al, 240
        jb      .c
        pop     es              ; (1)

        mov     dx, .msg4
        mov     ah, 09h         ; DOS.DisplayString
        int     21h

        mov     ah, 00h         ; BIOS.GetKeyboardKey
        int     16h             ; -> AX

        popa
        ret
; - - - - - - - - - - - - - - - 
.msg1   db      13, 10, 'DOS  : $'
.msg2   db      13, 10, 'BIOS : $'
.msg3   db      13, 10, 'VRAM : $'
.msg4   db      13, 10, 'Press any key', 13, 10, '$'
; ------------------------------

Don't remove the BIOS.GetKeyboardKey call. If you do, you won't have a chance to actually see the Greek characters...

Upvotes: 3

Related Questions