..

Week of the 06/18/2022 - #26

Contents

tech

  • 80x86 programing + ANSI art
  • More about TextDemos
  • Writing to VGA in C
  • Sound for demos

80x86 programing + ANSI art

So .. I wanted to write an 8086 assembly file which displays an ANSI image. To do so I:

  • used the Moebius ANSI editor to generate an .xb (XBIN) file
  • to simplify my life I chose an image that fits in the stadard screen (80x25)
  • I used the Kaitai IDE to generate a .ksy file to be able to parse the .xb image and extract the image data
  • Used kaitai to generate a Python parser to read XBIN files (kaitai-struct-compiler xbin.xsy --target python) which generates xb.py
  • I wrote a small Python program to extract the raw image data into a file (see below)
  • Finally I wrote a small assembly language program for NASM to output the image into the screen

Kaitai specification for XBIN

This spec file is not the complete specification for XBIN. It has several limitations to the type of .xb files it can parse. They are:

  • can’t handle compressed images
  • assumes that if there are fonts its 256 characters (has_512_chars = 0)
meta:
  id: xb
  file-extension: "xb"
  endian: le
  title: XBIN ANSI file
  license: CC0-1.0
doc: |
  XBIN File format
seq:
  - id: hdr
    type: header
  - id: palette
    type: palette
  - id: font
    type: font
  - id: content
    type: content
  - id: sauce
    type: sauce
types:
  header:
    seq:
      - id: magic
        contents: 'XBIN'
      - id: eof_char
        type: u1
      - id: width
        type: u2
      - id: height
        type: u2
      - id: font_size
        type: u1
      - id: flags
        type: u1
    instances:
      has_512_chars:
        value: (flags & 0b00010000) >> 4
      non_blink:
        value: (flags & 0b00001000) >> 3
      compress:
        value: (flags & 0b00000100) >> 2
      font:
        value: (flags & 0b00000010) >> 1
      palette:
        value: (flags & 0b00000001)
  rgb:
    seq:
      - id: red
        type: u1
      - id: green
        type: u1
      - id: blue
        type: u1
  palette:
    seq:
      - id: palette
        type: rgb
        repeat: expr
        repeat-expr: 16
  font:
    seq:
      - id: font
        type: u1
        repeat: expr
        repeat-expr: _root.hdr.font_size*256
  char:
    seq:
      - id: char
        type: u1
      - id: attr
        type: u1
  content:
    seq:
      - id: content
        type: char
        terminator: 0x1A
  sauce:
    seq:
      - id: magic
        contents: 'SAUCE'
      - id: version
        type: u2
      - id: title
        type: str
        size: 35
        encoding: ascii
      - id: author
        type: str
        encoding: ascii
        size: 20
      - id: group
        type: str
        encoding: ascii
        size: 20
      - id: date
        type: str
        encoding: ascii
        size: 8
      - id: file_size
        type: u4
      - id: data_type
        type: u1

Python program to read image and extract character/attribute data

This is the Python program which reads a file called ansi.xb and generates a file called content.bin with the character/attribut content of the image.

from xb import Xb

# Read file
ansi = Xb.from_file('ansi.xb')

# Print width / height
print(ansi.hdr.width)
print(ansi.hdr.height)

# calculate size
size = ansi.hdr.height * ansi.hdr.width * 2

# read content area
ansi.content.content._io.seek(0)
content = ansi.content.content._io.read_bytes_full()

# output to a file
filename = 'content.bin'
open(filename, 'wb').write(content)

The Nasm program to display the image on the screen

; Image size
%define image_width         80
%define image_height        25

org 100h
s:
    mov ax, 0x03            ; setup VGA
	int 0x10

    cld                     ; clear direction flag used by movsw
    lea si, [ansi]          ; load source index with image address
    lea di, 0               ; load destination index with 0
    mov ax, 0xb800          ; load es with 0xb800 (VGA screen memory segment)
    push ax
    pop es
    ; load cx with number of words to move
    mov cx, image_width*image_height
    rep movsw               ; move it
    ret

ansi:
    incbin "content.bin", 0, 2*image_width*image_height

The program works as follow:

  • setup mode 0x3 (80x25 chars)
  • copy from the current data segment the image in ansi label into b800:0000 which is the VGA text memory using the movsw instruction.
  • to compile you can use: nasm dispansi.asm -fbin -o dispansi.com

References

More about TextDemos

Text Mode Demo Contest Logo

  • Text mode Demo Contest 20 site is a site with lots of text mode demos. From the site: “TMDC is a pseudo-annual demo-making contest held over the internet. After tAAt ry announced they would stop organizing TMDC after the 10th edition, members of the Northern Dragons offered themselves to keep TMDC alive.”

From the site you can download a lot of very cool text demos. You can also download a demo template to get you started: Text Demo template @Pouet.

  • tmdc @taat.foi - This is the old TMDC site with 90 old demos from 1996 - 2008. You can also download all from that site.
  • LibCaca - libcaca is a graphics library that outputs text instead of pixels, so that it can work on older video cards or text terminals. It is not unlike the famous AAlib library, with the following improve
  • TextFX - The Art and Science of Text Mode Conversion - TextFX textmode graphics library, revision 8. Written by the master of textmode: Jari Komppa a.k.a. sol_hsa from Trauma group.
  • TextGL - This is a software-based opengl subset (which means it’s not an opengl implementation, it just looks a bit like it). This rendering engine was used in the TMDC winning demo “Litterae Finis”.

Some cool textmode demos

Writing to VGA in C

  • Using Borland Turbo C - 256-Color VGA Programming in C. A five-part tutorial on VGA programming for the DOS operating system.
  • LET’S COMPILE LIKE IT’S 1992 - I have been tinkering with the vanilla source code of Wolfenstein 3D from 1992. Even though it is more than 20 years old and has rotten for modern systems, you can still compile it if you recreate the environment.
  • How to build DOS COM files with GCC - This is how you can compile .COM programs in Linux. It is surprisingly harder than you would expect. A complete game for DOS written this way.
  • Simply write DOS programs on Linux w/ GCC! part I - A video tutorial expanding on the ideas of the previous article. A playlist with a couple more videos
  • VGA Text mode - Wikipedia entry on VGA text mode.
  • BIOS Int 10h - Wikipedia article. “INT 10h, INT 10H or INT 16 is shorthand for BIOS interrupt call 10hex, the 17th interrupt vector in an x86-based computer system. The BIOS typically sets up a real mode interrupt handler at this vector that provides video services. Such services include setting the video mode, character and string output, and graphics primitives (reading and writing pixels in graphics mode).”
  • BIOS interrupt call - wikipedia article with the listing of most BIOS interrupts and its use.
  • Ralf Brown’s Interrupt List - A pretty comprehensive list of interrupts. From the site: “The interrupt list is a comprehensive listing of interrupt calls, I/O ports, memory locations, far-call interfaces, and more for IBM PCs and compatible machines, both documented and undocumented. Nearly eight megabytes of information in ASCII text files!”
  • Linux Kernel Boot Process - A very detailed explenation on how Linux boots. It might have relevant code on how to use protected mode and how to initialize VGA.

Sound for demos