Warm tip: This article is reproduced from serverfault.com, please click

How can I find text mode page buffer in TASM?

发布于 2020-12-16 16:02:45

I'm trying to send some characters to page 1 of text mode by its memory address, but I find no suitable result, I calculated the page 1 address like this "0B800h + 1000h = 0C800h".

This is my code:

        IDEAL

        MODEL   small
        STACK   256

        DATASEG


exCode          DB      0
x_var           db      219


        CODESEG


Start:  
        mov     ax, @data       ; Initialize DS to address
        mov     ds, ax          ;  of data segment
        

        ; Page 1
        mov     ax, 0501h
        int     10h

        ;Page 1 buffer -> es
        mov     ax, 0C800h
        mov     es, ax
        
        mov     si, offset x_var

        mov     di, (10*80*2)+(10*2)

        cld

        lodsb
        stosb

        ; wait for any key press: 
        mov ah, 0
        int 16h

        ;Page 0 again
        mov     ax, 0500h
        int     10h


Exit:
        mov     ah, 04Ch        ; DOS function: Exit program
        mov     al, [exCode]    ; Return exit code value
        int     21h             ; Call DOS.  Terminate program

        END     Start           ; End of program / entry point
Questioner
Ahmed Crow
Viewed
1
Michael Petch 2020-12-17 02:06:06

The problem is in the calculation of the segment. If you are in an 80x25 text mode then each text page is 4096 bytes (01000h) in size. You can't add 01000h to 0b800h. You need to shift 01000h right by 4 bits (or divide by 16 decimal) to convert the value to number of 16 byte paragraphs and then add it to the 0b800h segment value. 01000h shifted right 4 bits is 0100h. Add that to 0b800h and you get 0b900h (0b800h+0100h) as the segment where page 1 starts. Thus:

mov     ax, 0C800h
mov     es, ax

Should be:

mov     ax, 0B900h
mov     es, ax

Notes

  • When using the BIOS to change video pages you can determine the number of bytes each video page takes by looking at the 16-bit WORD value at memory address 0000h:044ch in the BIOS Data Area (BDA). You can read that value and shift it right 4 bits and then add it to the base video address (0b800h in the case of video mode 03h).