Add detailed comments and rename `xcharput` to `op_47_xcharput` in `charput.inc`...
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Tue, 17 Feb 2026 15:09:51 +0000 (17:09 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Tue, 17 Feb 2026 15:09:51 +0000 (17:09 +0200)
emulator/charput.inc

index 4572389..050df56 100644 (file)
 ; Memory layout after execution:
 ;   Character drawn at (x, y) in destination image
 
-xcharput:
-       mov     eax, [es:edi]   ; chary
-       mov     [chary], eax
-       mov     ecx, [es:edi+4] ; charx
-       mov     eax, [es:edi+8] ; addrdest
-       add     eax, [xms_addr]
-       mov     ebx, [es:eax]
-       mov     [sizex], ebx
-       add     eax, 8
-       add     eax, ecx
-       push    eax
-       sub     edx, edx
-       mov     eax, [chary]
-       mul     dword [sizex]
-       pop     ebx
-       add     eax, ebx
-       mov     [addrdst], eax
-       mov     eax, [es:edi+12]
-       add     eax, [xms_addr]
-       mov     [addrsrc], eax
-       mov     al, [es:edi+16]
-       mov     [colorbg], al
-       mov     al, [es:edi+20]
-       mov     [colorfg], al
-       add     edi, 24
+op_47_xcharput:
+       mov     eax, [es:edi]       ; eax = y coordinate (top of stack)
+       mov     [chary], eax        ; store y coordinate
+       mov     ecx, [es:edi+4]     ; ecx = x coordinate (second on stack)
+       mov     eax, [es:edi+8]     ; eax = addrdest (destination image virtual address)
+       add     eax, [xms_addr]     ; convert virtual address to physical address
+       mov     ebx, [es:eax]       ; ebx = destination image width from image header
+       mov     [sizex], ebx        ; store destination image width (stride)
+       add     eax, 8              ; skip past image header (width + height = 8 bytes)
+       add     eax, ecx            ; add x offset to base of pixel data
+       push    eax                 ; save partial destination address on x86 stack
+       sub     edx, edx            ; clear edx for multiplication
+       mov     eax, [chary]        ; eax = y coordinate
+       mul     dword [sizex]       ; eax = y * image width (row offset in bytes)
+       pop     ebx                 ; ebx = base + x offset
+       add     eax, ebx            ; eax = final destination pixel address
+       mov     [addrdst], eax      ; store destination address for character drawing
+       mov     eax, [es:edi+12]    ; eax = addrsrc (source font data virtual address)
+       add     eax, [xms_addr]     ; convert virtual address to physical address
+       mov     [addrsrc], eax      ; store source font data address
+       mov     al, [es:edi+16]     ; al = background color value
+       mov     [colorbg], al       ; store background color
+       mov     al, [es:edi+20]     ; al = foreground color value
+       mov     [colorfg], al       ; store foreground color
+       add     edi, 24             ; pop all six arguments off the data stack
 
-       mov     [linenum], 8
+       mov     [linenum], 8        ; linenum = 8 (number of rows in character glyph)
 charl1:
-       mov     eax, [addrsrc]
-       mov     bx, [es:eax]
-       mov     edx, [addrdst]
-       mov     cx, 8
+       mov     eax, [addrsrc]      ; eax = current source font data address
+       mov     bx, [es:eax]        ; bx = current row bitmap (8 bits used)
+       mov     edx, [addrdst]      ; edx = current destination pixel address
+       mov     cx, 8               ; cx = 8 (number of pixels per row)
 charl2:
-       dec     cx
-       bt      bx, cx
-       jnc     charl3
-       mov     al, [colorfg]
-       jmp     charl4
+       dec     cx                  ; decrement bit index (process bits 7 down to 0)
+       bt      bx, cx              ; test bit cx of the row bitmap
+       jnc     charl3              ; if bit is 0 (clear), use background color
+       mov     al, [colorfg]       ; bit is 1 (set): al = foreground color
+       jmp     charl4              ; skip to pixel write
 charl3:
-       mov     al, [colorbg]
+       mov     al, [colorbg]       ; bit is 0 (clear): al = background color
 charl4:
-       mov     [es:edx], al
-       inc     edx
-       cmp     cx, 0
-       jne      charl2
+       mov     [es:edx], al        ; write pixel color to destination
+       inc     edx                 ; advance destination to next pixel (next column)
+       cmp     cx, 0               ; check if all 8 pixels in this row are done
+       jne      charl2             ; if not, process next pixel
 
-       mov     eax, [sizex]
-       add     [addrdst], eax
-       inc     [addrsrc]
-       dec     [linenum]
-       mov     al, [linenum]
-       cmp     al, 0
-       jne     charl1
+       mov     eax, [sizex]        ; eax = image width (stride)
+       add     [addrdst], eax      ; advance destination to next row
+       inc     [addrsrc]           ; advance source to next byte (next row bitmap)
+       dec     [linenum]           ; decrement remaining line count
+       mov     al, [linenum]       ; al = remaining lines
+       cmp     al, 0               ; check if all 8 rows are done
+       jne     charl1              ; if not, draw next row
 
-       jmp     emu
+       jmp     emu                 ; return to emulation loop
 
 colorfg db 0
 colorbg db 0