Programming the MEGA65 — Chapter 17: Major Peripherals

Oct 4, 2026 · Updated Oct 11, 2026 · @Craig Taylor

Introduction

This chapter covers the MEGA65's remaining connections to the outside world: the IEC serial bus for printers, the cartridge port, Ethernet, the serial UART, the real-time clock, and the video and audio outputs. Some correspond to C64 peripherals West described; Ethernet and the clock are new. The C64's user port and cassette port have no MEGA65 equivalent.

Printers and the IEC Bus

The IEC serial port at the rear is the same bus the C64 used, and Commodore printers and plotters connect to it exactly as before, usually as device 4 or 5. Output is sent by opening a channel to the printer and printing to it, or by redirecting all screen output with CMD:

10 OPEN 4, 4          : REM PRINTER ON DEVICE 4
20 PRINT#4, "MEGA65 PRINTER TEST"
30 CMD 4 : LIST       : REM SEND A LISTING TO THE PRINTER
40 PRINT#4 : CLOSE 4  : REM RESTORE SCREEN OUTPUT AND CLOSE

The secondary address selects a printer mode on Commodore printers; for example, 7 selects upper and lower case on many models. Consult the printer's own manual for its modes and control codes.

The same bus carries disk drives and modern devices such as SD2IEC, as Chapter 15 described. Bus activity slows the CPU temporarily, so timing-sensitive code should not run during IEC transfers.

The Cartridge Port

The expansion port accepts C64 cartridges. Switching the MEGA65 on with a C64 cartridge in place starts it in GO64 mode, where most C64 cartridges run, though the Book warns that not all C64 software is compatible (MEGA65 Book, p. 3-13). Cartridges made for the MEGA65 can instead start in MEGA65 mode. Cartridge ROM is mapped into the 28-bit address space from $4000000 upward, where MEGA65-mode software can reach it with flat addressing or MAP, as Chapter 5 described.

Switch the computer off before inserting or removing a cartridge.

Ethernet

The MEGA65 has an Ethernet port. Its everyday use is file transfer with M65Connect and mega65_ftp, as Chapter 14 described, but programs can also send and receive their own network frames.

The Ethernet controller lives in the MEGA65 I/O personality. Its main registers are (MEGA65 Book, Appendix: Ethernet controller):

Register Purpose
$D6E0 Control: controller reset, transmitter reset, receive and transmit status
$D6E1 Receive and transmit buffer queue control and status
$D6E2, $D6E3 Length of the frame to transmit
$D6E4 Command register
$D6E5 Receive filtering: broadcast, multicast, CRC checking, promiscuous mode
$D6E9 onward The MAC address

Frames are built in, and received into, buffers that appear in place of part of the I/O area when the Ethernet I/O personality is selected with the knock $45, $54 described in Chapter 5. The MEGA65 has no built-in MAC address: it uses the one set on the configuration utility's Network page, and networking does not work while that is all zeros (MEGA65 Book, p. 4-7).

Writing a network stack, even a simple one for UDP, is a substantial project. Community libraries implement TCP/IP for the MEGA65, and the Book's Ethernet appendix documents the controller in full.

The UART

The C65 included a UART, a serial port controller, and the MEGA65 keeps its registers at $D600-$D606 (MEGA65 Book, register appendix):

Register Contents
$D600 Data: the byte received or to send
$D601 Status: receive ready, framing and parity errors
$D602 Control: enable transmit and receive, character size, parity
$D603, $D604 Baud rate divisor
$D605, $D606 Interrupt masks and flags (not yet implemented on the MEGA65)

This is not the C64's user-port RS-232. On current boards, R3 to R6, the core does not connect this UART to any external connector, so programs cannot use it for serial communication (mega65-core, September 2026). For connecting to a PC, the usual route is the USB serial connection used by the development tools, which belongs to the serial monitor, not to this UART.

The Real-Time Clock

The real-time clock keeps the date and time while the MEGA65 is off, running from a coin-cell battery. On early R3A boards the battery is required; on R6 boards it is optional, and the clock keeps time for several days without one (MEGA65 Book, setting up). BASIC reads it through TI$ and DT$; programs can also read its registers directly at $FFD7110 (MEGA65 Book, pp. B-265, X-3):

Address Contents (binary-coded decimal)
$FFD7110 Seconds
$FFD7111 Minutes
$FFD7112 Hours
$FFD7113 Day of month
$FFD7114 Month
$FFD7115 Year
$FFD7116 Day of week, 0 to 6
$FFD7140-$FFD717F (R3);
$FFD7150-$FFD715F (R4 and later)
Battery-backed RAM: 64 bytes on R3 boards, 16 bytes on R4 and later

The values are BCD, so $59 means 59 seconds. In BASIC:

10 RT = $FFD7110
20 S = PEEK(RT) : M = PEEK(RT + 1) : H = PEEK(RT + 2) AND $7F
30 PRINT RIGHT$(HEX$(H), 2); ":"; RIGHT$(HEX$(M), 2); ":"; RIGHT$(HEX$(S), 2)

Printing the last two digits of each value's HEX$ shows its BCD digits directly. Bit 7 of the hours register is a flag, not part of the hour, so the program masks it off, as the ROM does (mega65-core, September 2026; MEGA65 ROM source, read_rtc). The battery-backed RAM survives power-off and can store a few settings. It is small, 64 bytes on R3 boards and only 16 on R4 and later, and the Book suggests it for machine configuration, so programs should use it sparingly (mega65-core, September 2026, mega65r4_i2c.vhdl). Boards from R4 onward have extra RTC registers, documented in the Book.

The clock on R4 and later boards

On R4, R5 and R6 boards the CPU does not reach the clock chip, an RV-3032, directly. The core reads the chip's registers over its I2C bus again and again, a full pass taking a few milliseconds, and keeps a copy. Reading $FFD71xx returns that copy. Writing queues the value and the core sends it to the chip on its next pass, but it holds only one pending write at a time (mega65-core, mega65r4_i2c.vhdl, September 2026). In practice:

Saving four bytes of settings in BASIC therefore looks like this:

10 FOR I = 0 TO 3
20 READ V : POKE $FFD7150 + I, V
30 SLEEP 0.05                     : REM LET THE CORE SEND IT
40 NEXT
50 DATA 1, 2, 3, 4

Video and Audio Outputs

The MEGA65 drives a VGA connector and a digital video connector at the same time. The digital output can also carry sound, which the configuration utility's Video page turns on or off; some DVI monitors need it off (MEGA65 Book, p. 4-6).

Setting Effect on programs
PAL, 720 × 576 at 50 Hz 312 VIC-II raster lines; 50 frames per second
NTSC, 720 × 480 at 60 Hz 263 VIC-II raster lines, numbered 0 to 262; 60 frames per second
CRT emulation Purely visual; no effect on programs

Bit 7 of $D06F is set in NTSC mode, so a program can adapt timing, as Chapters 8 and 13 showed. The user can switch modes in the Freezer while a program runs.

Development cores add a 15 kHz output for CRT monitors such as the Commodore 1084S: composite sync on the VGA connector's horizontal-sync pin, with RGB on its colour pins. It is enabled by the cable, which must bridge VGA pins 12 and 15 with a 470 Ω resistor; the wiring is otherwise the same as the cable used by the C64 core. With V400 set it also interlaces this output, though not yet correctly. It is not in release 0.97 cores (mega65-core PR #934).

Audio leaves through the 3.5mm jack, which has a headphone amplifier, and through the digital video connector. The Book says the configuration utility's Audio amplifier setting turns the jack's amplifier off for line-level equipment, but on current cores it has no effect on the jack: it controls only the speaker amplifier chip on R3 boards, and development cores rename it accordingly (MEGA65 Book, configuration utility, Audio page; mega65-core PR #893; issue #735). Chapter 13 covers the mixer that feeds both.

Summary

The appendices that follow gather reference tables used throughout the book.