Paolo Amoroso's Journal

Tech projects, hobby programming, and geeky thoughts of Paolo Amoroso

Working on Suite8080 and using the Z80MBC2 encouraged me to learn Intel 8080 and Z80 Assembly.

Now I'm dipping my toes into x86 Assembly, which I've always been curious about and attracted by. An additional motivation is discovering MikeOS, a lovely real-mode operating system in x86 Assembly that's surprisingly easy to read and understand.

Therefore, I put together an environment to cross-develop and run x86 code.

Requirements

My desktop daily driver is an ASUS Chromebox 3, with the Crostini Linux container of chromeOS that lets me run most Linux software. Any emulation and development tools must therefore be available for Linux.

Intel x86 Assembly is close enough to 8080 Assembly that x86 code looks familiar. To leverage this similarity and avoid the complexity of x86 segmentation, for the time being I want to develop 16-bit real-mode programs that fit into the single segment of a .COM executable.

The obvious choice for an operating system to run these programs is MS-DOS. Why? Because its rich environment strikes the right balance between complexity and functionality.

So the emulator must run a full MS-DOS environment and boot from media images. Which enables coding for the bare metal, a PC with no operating system.

As for the Assembly tools, I prefer to cross-develop on Linux. Although I'm a retrocmputing enthusiast, for writing and building code I want the convenience of a modern system.

MS-DOS emulation

QEMU would have been my first choice for x86 emulation but has compatibility issues with Crostini, as virtualizing in a virtual environment is tricky.

A bit of research led me to DOSBox-X, which runs fine on Crostini as it emulates rather than virtualize. DOSBox-X is a fork of DOSBox with a more fleshed out MS-DOS environment. Plus it can boot from media images.

DOSBox-X running under chromeOS on my Chromebox looks like this:

DOSBox-X session under chromeOS on an ASUS Chromebox 3.

Installing DOSBox-X on the Chromebox was straightforward. However, the Flatpak package carried almost a gigabyte worth of dependencies that nearly filled the Crostini file system. I had to resize the container from 7.5 to 10 GB to accommodate all the files and leave enough free space.

A feature I like is the emulator can mount a directory tree of the Linux file system as an MS-DOS disk. This is handy for quickly transferring cross-assembled binaries to MS-DOS.

DOSBox-X has rendering issues on chromOS, i.e. the menu bar and items flicker randomly. A workaround is to turn off the menu bar.

I tested DOSBox-X booting by checking out MikeOS, which runs well.

Assembly development

There's a vast assortment of x86 assemblers but I skipped the research by picking NASM for Linux.

I like this popular tool because it's rich of features and comes with extensive documentation. It also has a clean, non verbose syntax and can generate MS-DOS .COM programs.

To test the full cross-development and emulation toolchain I used NASM to assemble an x86 real-mode hello world demo, copied it to a directory DOSBox-X mounts as a disk, and ran it under MS-DOS. Success! A simple and low friction workflow.

#Assembly #MSDOS #chromeOS #retrocomputing #x86

Discuss... Email | Reply @amoroso@fosstodon.org

First reading about Flet made me jump over my chair as it's what I was long looking for, a solution to my web and Android development needs. Flet is an opinionated, Flutter-based GUI framework for creating multi-user web, desktop, and mobile applications.

What I was looking for is an easy way of creating simple web and Android apps in Python. Web frameworks such as Django are overkill and too low level for me, and in most cases require JavaScript or other non-Python frontend code.

As for mobile, although there are Python frameworks for Android development like Kiwi and BeeWare, they come with the ballast of a heavy Java and Android SDK toolchain.

Flet overcomes these issues. It enables creating web apps that hide a web framework under the hood. And, without touching Java, Flet can make also PWAs that run on Android and other mobile platforms. All from the same fully Python code base. Plus, deploying Flet web apps to my favorite Python environment, Replit, is well supported and straightforward.

I'm closely following the development of Flet and will experiment with the framework.

#Android #Python

Discuss... Email | Reply @amoroso@fosstodon.org

I develop programs for the Z80-MBC2 in Intel 8080 Assembly with the Suite8080 8080 assembler. Aside from the binary compatibility, the Z80-MBC2 is a Z80 system, so I wondered what Assembly mnemonics and register set the CP/M development tools work with.

It turns out my favorite CP/M debugger, the SID symbolic debugger, comes in two versions specialized on the CPU, SID and ZSID.

SID accepts as input and outputs 8080 mnemonics and registers, ZSID Z80 mnemonics and registers. For example, in this CP/M 3.0 SID session on the Z80-MBC2 I loaded my Twirl 8080 program and disassembled it with SID's l (list) command:

A>sid f:twirl.com
CP/M 3 SID - Version 3.0
NEXT MSZE  PC  END
0180 0180 0100 D4FF
#l
  0100  MVI  C,09
  0102  LXI  D,0139
  0105  CALL 0005
  0108  LXI  H,0142
  010B  MVI  B,08
  010D  PUSH H
  010E  PUSH B
  010F  MVI  C,09
  0111  LXI  D,013E
  0114  CALL 0005
  0117  POP  B7

The output contains 8080 mnemonics. An analogous ZSID session running the same disassembly command outputs Z80 mnemonics:

A>zsid f:twirl.com
SID VERS 1.4
NEXT  PC  END
0180 0100 CDFF
#l
  0100  LD   C,09
  0102  LD   DE,0139
  0105  CALL 0005
  0108  LD   HL,0142
  010B  LD   B,08
  010D  PUSH HL
  010E  PUSH BC
  010F  LD   C,09
  0111  LD   DE,013E
  0114  CALL 0005
  0117  POP  BC

SID thus lets me work in a 8080 environment on a Z80 system.

#z80mbc2 #Suite8080 #CPM #Assembly

Discuss... Email | Reply @amoroso@fosstodon.org

I've started writing a new Suite8080 demo in Intel 8080 Assembly, a CP/M program to move an ASCII character across the screen with vi's cursor keys h, j, k, and l. It's my first interactive CP/M program and does raw non-blocking I/O to read key presses.

#Assembly #Suite8080

Discuss... Email | Reply @amoroso@fosstodon.org

Back in the early days of blogging, the tech press bashed RSS out of existence as it was supposedly too complex for ordinary users. To the point new bloggers don't even know what RSS is, some recent blogging platforms don't support RSS, and new personal and corporate blogs sometimes don't provide RSS feeds.

But if your blog doesn't have RSS or Atom, you shoot yourself in the foot.

You completely give up control of your traffic to search engines and social platforms. Along with email newsletters, RSS is among the few options remaining to bloggers for establishing a direct communication channel and relationship with readers. With no gatekeepers.

The readers who subscribe to your RSS feed always see all of your posts. No matter what Google, Facebook, or Twitter decide.

What if only a minority of readers subscribe to your RSS feed? Is it still worth it?

They are the readers you want. The superfans who share your work. They may be bloggers themselves and link to your posts from theirs, or enable other opportunities such as guest blogging or podcast interviews.

Those few RSS subscribers are much more engaged and valuable than the many social media users who don't read or click links.

I've seen two primary objections to RSS feeds.

The first is, if readers get the content in a feed without visiting the website, blogs can’t be monetized with ads. Aside from the growing use of ad blockers, bloggers can provide partial RSS feeds that contain only snippets of the posts. This way the readers have to visit the blogs to access the full text.

Another objection is RSS feeds make web scraping and content stealing easier. This is a legitimate concern. But, if a blog is valuable enough, the lack of an RSS feed is only a minor inconvenience for determined scrapers.

#blogging

Discuss... Email | Reply @amoroso@fosstodon.org

ChromeOS 104 delivered the ability to access USB serial devices from Android, an option for controlling the Z80-MBC2 computer from an Android terminal emulator app.

I didn't realize chromeOS 104 improved the support for accessing USB serial devices also from web apps implementing the WebUSB API. On my Chromebox, version 104 is the first that enables controlling the Z80-MBC2 from the web. Here's a CP/M 3.0 session in a serial terminal emulator web app:

USB Web Serial terminal emulator web app running a Z80-MBC2 CP/M 3.0 session on chromeOS.

Up to chromeOS 104, web terminals failed to connect to the Z80-MBC2 as they didn't detect the USB device. With version 104 I tested the following terminal apps, most of which work:

These apps operate the same way. A connection button brings up a system dialog listing the serial devices, like the Z80-MBC2's CP2102 chip. Once connected, the apps behave like other terminal emulators.

Although useful as an additional option for controlling the Z80-MBC2 on chromeOS, these web terminals are experimental or basic apps, have limited functionality, and miss major features like XMODEM file transfer.

#z80mbc2 #sbc #Android #chromeOS

Discuss... Email | Reply @amoroso@fosstodon.org

I discontinued my old Blogger blog and, going forward, I'll post only to this new blog hosted at Write.as. After initially meaning to maintain both, I had been considering mothballing the old blog for months. The joy of using Write.as finally drove home I can't stand Blogger anymore.

#blogging

Discuss... Email | Reply @amoroso@fosstodon.org

I decided what to work on next on Suite8080, the suite of Intel 8080 Assembly cross-development tools I'm writing in Python. I'll add two features, the ability for the assembler to trim trailing uninitialized data and a macro assembler script.

Trimming uninitialized data

Consider this 8080 Assembly code, which declares a 1024 bytes uninitialized data area at the end of the program:

# . . .

data:        ds    1024
             end

For this ds directive, the Suite8080 assembler asm80 emits a sequence of 1024 null bytes at the end of the binary program. The executable file is thus longer and may be slower to load on the host system, typically CP/M.

The Digital Research CP/M assemblers, ASM.COM and MAC.COM, strip such trailing uninitialized data from binaries. After asking for feedback to r/asm, I decided to do the same with asm80. I should be able to implement this optimization by adding just one line of Python, so the feature is a low-hanging fruit.

Macro assembler

asm80 can accept source files from standard input, which makes it possible to combine the assembler with an external macro preprocessor to get a macro assembler. Thanks to its ubiquity, M4 is the clear choice for a preprocessor.

Assuming prog.asm is an 8080 Assembly source file containing M4 macros, this shell pipe can assemble it with asm80:

$ cat prog.asm | m4 | asm80 - -o prog.com

The - option accepts input from standard input and -o sets the file name of the output binary program.

The other Suite8080 feature I'm going to implement is a mac80 helper script in Python to wrap such a shell pipe and make assembling macro files more convenient. In other words, syntactic sugar wrapping asm80 and M4.

The script will use the Python subprocess module to set up the pipe, feed the proprocessed source to the assembler, and not much else.

#Suite8080 #Python

Discuss... Email | Reply @amoroso@fosstodon.org

The Python feed of my old blog Moonshots Beyond the Cloud has long been aggregated by Planet Python. But I'm no longer going to update that blog, so I removed the old feed from Planet Python and submitted the Python feed of my new blog, Paolo Amoroso's Journal.

#Python #blogging

Discuss... Email | Reply @amoroso@fosstodon.org

ChromeOS 104 landed on my Chromebox delivering a pleasant surprise, the ability to access serial USB devices from Android apps.

When I plugged the Z80-MBC2 Z80 homebrew computer into the Chromebox under chromeOS 104, the system popped up this notification allowing me to connect the device to Android or Linux, not just Linux as before:

chromeOS notification allowing to connect a Z80-MBC2 serial USB device to Linux or Android.

The notifcation confirms the detection of the Z80-MBC2's CP2102 chipset and says:

USB device detected

Open Settings to connect CP2102 USB to UART Bridge Controller to Linux or Android apps

Connect to Linux Connect to Android

I had long been looking forward to accessing the Z80-MBC2 from Android. I researched a great terminal emulator app, Serial USB Terminal, which can connect to serial USB devices, features basic ANSI support, and can transfer files via XMODEM. Although the app runs fine on the Chromebox, I never figured how to connect to the Z80-MBC2. It turns out it wasn't possible, until chromeOS 104.

Selecting the notification's option to connect to Android prompts to run Serial USB Terminal, optionally setting it as the default app for Android connections.

I interacted a bit with the Z80-MBC2 from the Android terminal emulator and it's usable. Here's what a CP/M 3.0 session looks like in the app in landscape tablet mode, the window layout that works best with a terminal:

Serial USB Terminal Android app running a Z80-MBC2 CP/M 3.0 session on chromeOS.

Input goes in a text field separate from the terminal output. It feels awkward on the desktop but natural on mobile devices with touch interfaces.

Serial USB Terminal's ANSI support seems limited or incomplete, but I haven't checked extensively.

I tried transferring a file via XMODEM from the terminal emulator to the Z80-MBC2 under CP/M 3.0. But, as with Crostini Linux, nothing happens and the XMODEM transfer doesn't work. More experimentation may provide clues on the XMODEM issue.

So far I haven't played with the Z80-MBC2 much from Android, but it's great to have another option for controlling the device.

#z80mbc2 #sbc #Android #chromeOS

Discuss... Email | Reply @amoroso@fosstodon.org

Enter your email to subscribe to updates.