hex="A B C D E F"; for cp in cp437 cp850; do echo "code page: $cp;"; for l in $(seq 3 9) $hex; do echo -n "(#$l) "; for col in $(seq 0 7); do echo -en "\x$l$col "; done;echo -n " "; for col in 8 9 $hex; do echo -en "\x$l$col "; done; echo; done | iconv -f $cp -t utf-8; echo; done code page: cp437; (#3) 0 1 2 3 4 5 6 7 8 9 : ; < = > ? (#4) @ A B C D E F G H I J K L M N O (#5) P Q R S T U V W X Y Z [ \ ] ^ _ (#6) ` a b c d e f g h i j k l m n o (#7) p q r s t u v w x y z { | } ~ (#8) Ç ü é â ä à å ç ê ë è ï î ì Ä Å (#9) É æ Æ ô ö ò û ù ÿ Ö Ü ¢ £ ¥ ₧ ƒ (#A) á í ó ú ñ Ñ ª º ¿ ⌐ ¬ ½ ¼ ¡ « » (#B) ░ ▒ ▓ │ ┤ ╡ ╢ ╖ ╕ ╣ ║ ╗ ╝ ╜ ╛ ┐ (#C) └ ┴ ┬ ├ ─ ┼ ╞ ╟ ╚ ╔ ╩ ╦ ╠ ═ ╬ ╧ (#D) ╨ ╤ ╥ ╙ ╘ ╒ ╓ ╫ ╪ ┘ ┌ █ ▄ ▌ ▐ ▀ (#E) α ß Γ π Σ σ µ τ Φ Θ Ω δ ∞ φ ε ∩ (#F) ≡ ± ≥ ≤ ⌠ ⌡ ÷ ≈ ° ∙ · √ ⁿ ² ■   code page: cp850; (#3) 0 1 2 3 4 5 6 7 8 9 : ; < = > ? (#4) @ A B C D E F G H I J K L M N O (#5) P Q R S T U V W X Y Z [ \ ] ^ _ (#6) ` a b c d e f g h i j k l m n o (#7) p q r s t u v w x y z { | } ~ (#8) Ç ü é â ä à å ç ê ë è ï î ì Ä Å (#9) É æ Æ ô ö ò û ù ÿ Ö Ü ø £ Ø × ƒ (#A) á í ó ú ñ Ñ ª º ¿ ® ¬ ½ ¼ ¡ « » (#B) ░ ▒ ▓ │ ┤ Á Â À © ╣ ║ ╗ ╝ ¢ ¥ ┐ (#C) └ ┴ ┬ ├ ─ ┼ ã Ã ╚ ╔ ╩ ╦ ╠ ═ ╬ ¤ (#D) ð Ð Ê Ë È ı Í Î Ï ┘ ┌ █ ▄ ¦ Ì ▀ (#E) Ó ß Ô Ò õ Õ µ þ Þ Ú Û Ù ý Ý ¯ ´ (#F) ­ ± ‗ ¾ ¶ § ÷ ¸ ° ¨ · ¹ ³ ² ■   > echo "æ ≈" | iconv -f utf8 -t cp437 | od -An -toC -a 221 040 040 040 367 012 dc1 sp sp sp w nl > echo "ae-ligature: 'æ', approximately-same-as: '≈'" | iconv -f utf8 -t cp437 | od -An -txC -a 61 65 2d 6c 69 67 61 74 75 72 65 3a 20 27 91 27 a e - l i g a t u r e : sp ' dc1 ' 2c 20 61 70 70 72 6f 78 69 6d 61 74 65 6c 79 2d , sp a p p r o x i m a t e l y - 73 61 6d 65 2d 61 73 3a 20 27 f7 27 0a s a m e - a s : sp ' w ' nl > echo "ae-ligature: 'æ', approximately-same-as: '≈'" | iconv -f utf8 -t cp850 ae-ligature: '�', approximately-same-as: 'iconv: illegal input sequence at position 43 $ echo $'\374\350\355\367' | iconv -f cp437 -t utf8 ⁿΦφ≈ sh-5.1$ echo '€' | iconv -f utf8 -t iso8859-15 | iconv -f iso8859-15 -t utf8 € sh-5.1$ echo '€' | iconv -f utf8 -t iso8859-1 | iconv -f iso8859-1 -t utf8 iconv: illegal input sequence at position 0 $ echo $TERM xterm-256color ... console/terminal emulated by my xfce4-terminal program, xterm, (xvterm,…) a more simple program like this. The original DOS and ROM-BIOS character page is to my knowledge cp437, operating systems like OS/2 offered to use cp850 as well, probably an even elder standard than cp437. What I do certainly remember is that characters like ^n, the greek letter Phi and the approximately-is character were present, so cp850 excluded by each of these examples "ⁿΦ≈". More modern 1-Byte character sets do not offer certain-selected special characters like ^n or the very-most used greek letters nor special characters to draw boxes or frames "╚ ╔ ─ └ ". These are iso-8859-1 and iso-8859-15, the first standard charset of the German OS/2 Warp installation, the latter introduced long after the times of OS/2 Warp 4, ›-15‹ introducing the euro sign '€' and a few other new characters. The cp437 character set can be read at a ROM BIOS memory address at any computer that boots by BIOS and AFAIK (as far as probably is) not UEFI. Look with a hex editor at an address like 0xF0000 or 0xE0000. One Byte is one line of eight pixels, look if the highest significant bit was equivalent to right most pixel, that would be the logic of x86/PC computers LSB least significant Byte/Bit to come first. The real mode as present at boot time and for BIOS-calls (via interrupts, intr assembler instruction) addressed memory in segments of 64K, so segment 0xE000 goes from 0xE0000 to 0xEFFFF, 0xE7320 written for example as E000:7320 or E700:0320, both values are added with a shift of four bits, equivalent to multiplying by 2^4 = 16. Known memory adresses of the graphics card were B8000 for the text mode (1-Byte: cp437-character, 1-Byte: colour, foregroung, background, and blinking-on). So "Mov AX,0xB800; Mov ES,AX; Xor DI,DI; Mov CX,2000; Mov AX, ((7+1*4)*256)+177; REP StosW;" iff text mode was 80x25 characters. CP437 character number #177, we knew it as well, the three dimming characters to mix colors like blue and white, the Digital Research GEM graphical user interface created a more pleasant background colour by mixing dark blue (color #1, red, green, blue - if not the contrary direction) with white (all three colours additively mixed together). Press under MS/PC-DOS or FreeDOS the Alt key, keep it pressed and enter [1] [7] [7] on the Num-Lock keypad at the very right of your keyboard, note: you must not use the usual number keys to attain cp437 character values. Under Linux/Unix and the emulated consoles there (like vt800) you can get the first 26 control chatacters (ascii charset) by pressing ctrl-A, ctrl-B, for \001, \002, etc.. Ctrl-D gives an end to your input, cat: enter as first character on the line, bash: same, saves you from typing »exit↵«. So the two-Byte value to load into ax for a coloured character is just a guess, try it out whether the foreground colour comes into the lower four bits of the upper byte of the AX register (AH). You could try with a Qemu, a machine emulating BIOS, and write the inline code (assembler code translated into a string of Bytes) at address #000000 of your disk image (dd if=.. of=mydisk). The first bytes before the partition table are simply machine code that is executed in order to jump to the location where the boot loader, today Grub or Lilo or SysLinux, probably even loading something from disk, with BIOS interrupt of course. Note: instead of "REP StosW;" it should be possible to use "myloop: StosW; LoopNZ myloop;", affects CX which is decremented on every step, so contains 80*25. Use as86 or the like instead of the Linux commnd as (file extension: .a), because in traditional Intel-Style assembler notation the target operand comes left-most/first, to-say the result-holding operand or in compiler-writer´s speech the L-value, that is a value that can obtain output. An R-value, compiler wrier´s speak, on the contrary is a value that is to be merely read, f.i. 1*4+7 is an R-value, you can not store anything at there, an R-value made of an arithmetic expression. A valient excample for an L-value is f.i. 'myvar', you can assign a value to it, and the compiler writer knows, an L-value does not just have a value to read out, it has a memory address that can be written ((That is for instance/f.i. the .data section as by objdump -h /tmp/tioc or /bin/csh, the .bss section is AFAIK typically read-only and the .text section contains the »object code«, that is your hand-written assembler code translated/compiled by the assembler ›as86‹ or ›as‹ into object code, if you just take a few bytes of object code, you would call it »inline«. tools.ix2w.org had a www page that was able to translate high-level language like C/C++ into assembly and probably also inline code.)). For ›as‹ like *.a used to output intermediary assembly of a gcc/clang program "", the result comes into the right-written argument, so "mov &ebx,&eax;" would do an "&eax := &ebx" assign register &eax the value read from &ebx (32-bit, extended bx). Traditional style was: "Mov EAX, EBX" (›as86‹, or ›as‹ with ".arch i486; .code16;"), gcc -m16 needed to be the FreeDOS version of gcc for that to work, but as -16 shall work" wiki.osdev.org/Inline_Assembly, asm(".att_syntax prefix") dort %eax und %%eax: assembler instructions within a C-program, I never had it with success for gcc, used wcc Watcom C Compiler or something like Turbo Pascal. "wcc -q -bt=os2v2 -bc (console program) -fr=cpl12.err (file to store error messages) -fo=cpl1.obj myprog1.c; wcc -q -bcl=os2v2 -bc -fe=cpl1.exe cpl1.obj cpl2.obj;" » AT&T(GAS) and x86 assembly syntax « https://freedos.org/ https://winhistory.de/downloads/downloads.htm https://openwatcom.org/ as referred to by dev.ix2w.org. https://www.elstel.org/OS2Warp/InstallUpdate.html note OS/2 is a protected mode operating system, the example with $B800:0000 will not work as an OS/2-*.exe but as a virtual 86 mode dos program that can be executed, also if you booted OS/2 from floppy! { real mode - 16bit / protected mode - 32bit } https://asm.sourceforge.net/ ,x86dis, nasm, as86, as by binutils/GNU. https://en.wikibooks.org/wiki/X86_Assembly https://github.com/namantam1/x86-assembly https://www.tutorialspoint.com/assembly_programming/assembly_basic_syntax.htm https://sourceware.org/binutils/docs/as https://ee209-2019-spring.github.io/references/gnu-assembler.pdf DosBox, Qemu, Wine (Windows, including Windows 3.1/DOS_5.0 emulation) Lilo, Grub, SysLinux (more for bootable CDs), DOS: config.sys (CODEPAGE=cp437), autoexec.bat »as -16«: .code16, .syntax no_register_prefix, .att_syntax, .intel_syntax, .arch i686). »gcc -save-temps -o tioc tioc.c« ... see how your own program is compiled, look around for *.A, your own assembly files should not be auto-deleted by »make clean« or something the-like, so call them *.a. You can write a procedure used in C or C++ with ›as‹, bind the .obj/.o file together, state it the same way as an *.c input file to the gcc-compiler, file-type auto-recognized. note_1: probably reading /dev/mem as root would give the linear address space without 4K-wise 4K-page reordering (80386 protected mode usually uses a »page table«, that means not every 4K-block of memory has it`s logical address where its physical 4096_Byte-divisible (no remainder after integer-division) would be. Used for swapping (›swapon -s; free -m;‹) note_2: In assembly language there is always one_instruction - one_line_of_text‼ Comments usually come directly afterwards the command, like this: movl %ebx, %eax # here comes a comment why you wanna do it like this. mov eax, ebx ; here comes a comment why you wanna do it like this. ›as‹ comment characters: "#@;|!" (x86, ARM, ¿29k?, …), "--" v850, "/* ... */" The -save-temps will produce code like ›movl %ebx, %eax« — “l” stands for long, the C data type ›long myvar1, myvar2; int my32bit;‹ à »gcc -m32«, use gcc-libc32 or install 32bit libs as secondary (machine) arch(itecture) in Debian; You could test f.i. in OpenWatcom how many bits an ›int‹, a ›long‹, and a ›short‹ as well as a ›long long‹ all available as ›signed long‹ and ›unsigned long‹, »printf("xx: %lu\n",sizeof(long));« by using OpenWatcom and Wine or DosBox. note_3: Under MS-Dos there were two valient proprietary assemblers: Tasm and Masm Masm ... the Microsoft Assembler, Tasm the Turbo Assembler, packed with Borland/Turbo Pascal nasm, today-a linux program, remembers of the name of the old DOS Masm assembler. # locale; export LANG=C; export LANG=de_AT.iso8895-15; LANG=pt_BR.UTF-8; // iconv --to ??: # ~~~ set the timezone across reboots ~~~ > find /etc/ -type l | xargs ls -l | grep zone lrwxrwxrwx 1 root root 33 Mär 14 2022 /etc/localtime -> /usr/share/zoneinfo/Europe/Vienna > su; # change to ›superuser/root‹; you will need a password; many linux boot-cds allow: »sudo su« > ln -fs /usr/share/zoneinfo/Europe/Lisbon /etc/localtime # ~~~ change the time zone temporarily ~~~ > tzselect; TZ='Europe/Vienna'; export TZ; > date; date --utc; Di 05 Aug 2025 04:03:38 CEST Di 05 Aug 2025 02:03:38 UTC # ~~~ usage of your serial RS232 port COM1 / usage of your printer at the parallel cable LPT1 ~~~ DOS: type myfile.txt >COM1 Linux: cat myfile.txt >/dev/ttyS0 Linux/Wine, I don´t know about DosBox/Linux (uses virtual 86 mode): > ls -l ~/.wine/dosdevices/ c: -> ../drive_c com1 -> /dev/ttyS0 lpt1 -> /dev/lp0 # serial RS232 cables were typically used to connect a 64K modem that connected to the internet or another computer via the landline phone line # serial RS232 cables were also used directly between two computers, called null modem cables, like a crossover ethernet cable RJ45 stty -F /dev/ttyUSB0 speed 1200 raw; stty -F /dev/ttyUSB0 -cmspar cs8 parenb oddp cstopb inpck parmrk; stty -F /dev/ttyUSB0 --all | grep -Eo ".par[^ ]*|.oddp|.evenp|.cs[78]|.cstopb|.inpck|.parmrk"; stty -F /dev/ttyUSB0 speed 9600 cooked; stty -F /dev/ttyUSB0 > cat /dev/ttyS0 >myfile.txt # at the other end of the cross-over RS232 cable connecting two computers Linux: lrzsz DOS: txzm (https://www.bttr-software.de/freesoft/comm1.htm) Linux: picocom / minicom / cutecom, Linux ADSL internet: pppd - point to point tunneling protocol DOS: procomm # sending AT commands at dos, AT commands can dial a phone number, there are two signalling modes/ways to convert a phone number into sound as sent over a landline phone connection Linux: telnet DOS: telemate (http://www.starbase21.net/telemate.html), Windows: ¿putty? # utf-8 uses multi-byte characters for all non-ascii chars (ascii: first 128/7bit) // cp850 & cp437 use one byte per character # #255/chr(255) can effectively be used as special, invisible space character and as a »no-line-breaking-space« > echo -n $'==\xFF==' | iconv -f cp437; // --> == == > { echo -en "\xFF = " | iconv -f cp437; h2t "- -"; } | txtfmt > { echo -n $'\xFF = ' | iconv -f cp437; h2t "- -"; } | txtfmt --oct #194;#160; = - -#10; # new line: character number 10, chr(10), which is a 12 in the octal number system, also written as "\n" \302\240 = - -\012 > grep thinsp ~/elstel/uploads/wngklu/htsyms.txt; | txtfmt --oct thinspace: '\342\200\211', no-break-space: ' ', shy: > echo -n $'\342\200\211' | txtfmt --oct; # This is a program written by me, you dont have that at Linux, use »od -An -txC -toC -c«. \342\200\211 # .html: This is a long text guaranteed to always stay on the same line. h2t() { echo "$@" | w3m -O utf-8 -T text/html -dump; } # The lines #3..#7 belong to the ascii code, which is only 7bit or 128 characters, upper half are extensions > echo -en "\xD5 = " | iconv -f cp437; h2t "ı"; ı = ı ei() { echo -n "ı&#$i; "; }; es() { echo -n " / "; }; h2t "$(for i in 769 768 771 770 780 807; do ei $i; done; es; for i in 772 775 778; do ei $i; done; es; for i in 7624 7625 7620 7621 7622 7623; do ei $i; done; echo " / i̧"; )" ı́ ı̀ ı̃ ı̂ ı̌ ı̧ / ı̄ ı̇ ı̊ / ı᷈ ı᷉ ı᷄ ı᷅ ı᷆ ı᷇ / i̧