The C64 OS Programmer's Guide is being written

This guide is being written and released and few chapters at a time. If a chapter seems to be empty, or if you click a chapter in the table of contents but it loads up Chapter 1, that's mostly likely because the chapter you've clicked doesn't exist yet.

Discussion of development topics are on-going about what to put in this guide. The discusssions are happening in the C64 OS Community Support Discord server, available to licensed C64 OS users.

C64 OS PROGRAMMER'S GUIDE

Library Reference: network.lib

Overview

The network.lib is a coordination library for managing the C64 OS network stack. Its primary job is to load the cnp.lib, which implements the the socket API and the Commodore Network Protocol (CNP). The network.lib loads and stores network settings, loads and configures the network hardware driver and connects the driver to the cnp.lib.

The Network Utility retrieves and modifies the network settings via the network.lib. But the Network Utility itself is responsible for saving the network settings to storage.

Name network.lib
code ne
size 5 pages
Link Yes
Unlink Yes
Emits Memory Warnings No

Related libraries

Network Settings

Network settings are stored in network.t in the system's settings directory (//os/settings/).

The file consists of 10 lines ended by a carriage return ($0d). The first 3 lines are integers encoded as a single byte by shifting the value into a human-readable range of PETSCII. The last 7 lines are strings of PETSCII.

Line Description Type Encoding Length
0 Driver page size Int PETSCII "0" ($32) added to it 1 byte
1 Initial baud rate code Int PETSCII "a" ($41) added to it 1 byte
2 Maximum baud rate code Int PETSCII "a" ($41) added to it 1 byte
3 Network Hardware Driver filename String PETSCII 1 to 16 characters
4 Wifi SSID String PETSCII 1 to 32 characters
5 Wifi Password String PETSCII 1 to 32 characters
6 CNP Host String PETSCII 1 to 20 characters
7 CNP Port String PETSCII 1 to 5 characters
8 CNP Username String PETSCII 1 to 16 characters
9 CNP Password String PETSCII 1 to 16 characters

Network Status

The status of the network is persisted between Fast App Switching banks, even when the current App bank does not have the network stack loaded. Its bits can be checked to determine whether the operating system's network settings are configured or not, and whether the operating system is online or not. Being online means that the network hardware has an active connection to a CNP server.

The network.lib sends a network status message (mc_ntwrk) to the Application, and to the Utility if one is open, whenever any network status bit changes. Your Application can listen for these messages to know when the operating system goes online or offline and respond accordingly.

Constant Value Description
ns_nhcf %00000001 Network hardware driver loaded
ns_nhsp %00000010 Network hardware initialized
ns_trcf %00000100 Transport layer configured
ns_trup %00001000 Transport layer connected
ns_cpcf %00010000 CNP configured
ns_cpup %00100000 CNP connected

Description of how the network status bits are used and what they mean:

ns_nhcf

This bit is set when the network hardware driver has been specified, is loaded into memory, and the network hardware driver is able to communicate with the corresponding hardware. The test for the ability to communicate with the hardware is provided by the driver itself.

ns_nhsp

This bit is set when the hardware's speed and other parameters have been initialized. It's used internally by the driver to know when it needs to initialize the hardware and when that step can be skipped. This is used primarily when a modem connected via RS-232 needs to have its communications speed changed, and the driver has to adjust its own speed to match.

ns_trcf

The transport layer is the network hardware's internal ability to access the internet via TCP/IP. For example, if the modem connects to the internet by WiFi, the transport layer is the modem's connection to the wireless access point. If the modem uses ethernet, it is the modem's physical ethernet link and its ability to acquire an IP address.

C64 OS does not provide support for configuring the ethernet settings on those modems which use ethernet. They must either provide their own means of configuring the connection or use automatic resolution, such as DHCP, to acquire an IP address.

This bit is set when a Wifi SSID and Password have been provided by the user. If the driver does not have the ability to set the SSID and password of the hardware, these values have to be provided anyway, even if they are bogus. (This may change in a future version of C64 OS.)

ns_trup

This bit is set when the transport layer is connected. The driver is provided with the Wifi SSID and password and it can provide those to the network hardware device. The driver is responsible for reading information about the transport layer connection from the hardware, such as the SSID that the wifi modem is connected to, or in theory the IP-address, gateway or other information that the ethernet hardware has acquired for its transport layer. (Ethernet connections and reporting need improvement in C64 OS.)

ns_cpcf

This bit is set when the host, port and access credentials for a CNP server have been provided. OpCoders Inc. provides a CNP server to connect to, with a subscription to Network Proxy Services. Access credentials can be configured by logging into your account at c64os.com. The host and port are provided in the instructions on the same page.

Alternatively, the CNP server is open source. It can be downloaded, modified, and configured to run on different cloud infrastructure.

ns_cpup

This bit is set when the network hardware has an active connection open to a CNP server, has successfully authenticated, and the cnp.lib is able to communicate with the CNP server.

Networking and Fast App Switching

If the user switches to an App bank where the network stack is not loaded (neither the network.lib, the cnp.lib nor the network hardware driver), only the ns_nhcf bit goes low. This indicates that the network hardware driver is not loaded into memory.

Because all network hardware devices supported by C64 OS are smart network devices, they are able to internally maintain their own TCP/IP connection to the CNP server, even when the Commodore 64 does not have a network hardware driver active in memory for communicating with the hardware.

When Fast App Switching, the Switcher calls nhdpause on the network hardware driver before freezing the Application to the REU. This allows the driver to assert hardware flow control which prevents the hardware from attempting to send data to the computer while the computer doesn't have a driver that can handle the incoming data. When the Switcher thaws an App from the REU, it forwards all of the network status bits to the new bank, except for ns_nhcf. If the new bank already has ns_nhcf set, then the driver is already available in this bank, and Switcher calls nhdresum on the driver. The driver unasserts hardware flow control and network data can resume being processed.

The system status bar reports the operating system as online whenever the ns_cpup bit is set, regardless of whether the current App bank has the network stack loaded in.

While the network stack is loaded in the current App bank, and the CNP server connection is established, a keep-alive message is sent periodically to maintain the CNP server connection. If you Fast App Switch to an App bank where the network stack is not loaded in, or if you drop to BASIC (where the network stack is never active), after some period of inactivity (typically 10 minutes), the CNP server will close the TCP/IP connection to the network hardware.

Whenever C64 OS is Fast Rebooted, or the user Fast App Switches back to a bank in which the network stack is available, the network hardware driver notices that the carrier detect signal (or its equivalent) is no longer asserted. This is communicated to the network.lib which promptly lowers the ns_cpup status bit and sends an mc_ntwrk message. All open sockets are closed automatically when the CNP connection is lost.

The network.lib also automatically opens the Network Utility in response to going offline. The user should be able to click the "Start" button under the CNP tab to resume the CNP connection, bring the operating system back online, and continue normal network operations.

Library Routines


Link and Unload

When this library is linked to the KERNAL it automatically loads the cnp.lib and binds itself to several routines provided by the cnp.lib. Additionally, it sets the workspace variable cnplibpg to the page address where the cnp.lib was relocated.

;defined by //os/s/:network.s

cnplibpg = $0244

It is critically important to use the slunload flag when unloading network.lib. This will automatically unload any loaded network hardware driver and unloads the cnp.lib and sets cnplibpg back to 0.

Unloading the network.lib sends mc_ntwrk network status messages.

Load Settings (loadset_)

Purpose Load network settings. Optionally perform a full network boot.
Jump offset $06
Communications registers A, X, Y
Stack requirements 16+
Zero page usage $1e, $1f (plus others used by cnp.lib, the NHD, the KERNAL file accesses, etc.)
Registers affected A, X, Y
Input parameters C → Clear to load network settings only.

C → Set to load settings and perform a full network boot.
Output parameters C ← SET = An error occurred.

Description: This routine loads and parses the values stored in the network.t settings file found in //os/settings/. If the file does not exist, the carry is returned set, indicating an error.

The network settings are loaded into statically allocated buffers inside the network.lib. Upon loading the settings, the ns_trcf and ns_cpcf bits are set if all of their corresponding fields have content.

If this routine is called with the carry clear, it only loads the settings and returns with the carry set if the settings file does not exist, or clear to indicate that the settings were successfully loaded in.

If this routine is called with the carry set, it first tries to load in the settings, and then if the settings were successfully loaded, it begins a long, complex, and asynchronous process of booting the network. If the full network boot option is specified, but there is an error loading the network settings, the Network Utility is automatically loaded so the user can see that the network is not configured, and is guided towards configuring it.

Similarly, if the network settings are configured, and the network boot process begins, if somewhere down the chain of asynchronous stages the network fails to boot, the Network Utility is opened. This allows the user to see how the network is currently configured and resolve any configuration issues. Opening the Network Utility guides the user towards what needs to be done and makes it easier to manually start the CNP connection and go online.

Because booting the network is multi-stage and each stage is asynchronous, this routine returns before the network is actually booted. It is necessary for the Application to listen for mc_ntwrk messages to keep informed about changes to the network status.

Read a network setting (readset_)

Purpose Read a network setting
Jump offset $09
Communications registers A, X, Y
Stack requirements 2
Zero page usage None
Registers affected A, X, Y
Input parameters X → network setting index
Output parameters RegPtr → pointer to the network setting buffer

Description: The network.lib stores the network settings in statically allocated buffers within its own memory space. This routine is used to request a pointer to the buffer inside network.lib which holds the requested settings data.

You will probably never be required to use this routine. This routine is used by the Network Utility to fetch the settings buffers from the network.lib, which it uses directly as the string buffers for the TKInput text fields. Thus, as the user interacts with the Network Utility, typing in a new Wifi SSID, for example, the TKInput is editing the data directly in the settings buffer provided by the network.lib.

The network.lib does not implement writing its settings to //os/settings/:network.t. The network settings are written by the Network Utility after it has changed them.

Network Settings Constants

This network settings constants correspond with the line numbers in the network.t settings file described above. Each of the string buffers is 1 byte longer than the maximum number of characters that can be held in that settings field. The extra byte allows the string buffer to hold a NULL terminating byte.

Buffer sizes and buffer overruns

If you do call readset and use it to access the network settings buffers, it is critically important that the buffers not be overrun.

It is safest to attach the buffer to a TKInput object and specify its maximum buffer size as listed below. TKInput is carefully designed to prevent the buffer from being overrun, while handling selections, insertions, copying, pasting and validation.

;defined in //os/s/:network.s
Constant Value Description Buffer size
nhdpgsz 0 Network driver page size 1 byte
inibaud 1 Initial baud rate code 1 byte
maxbaud 2 Maximum baud rate code 1 byte
nhddrvr 3 Network hardware driver filename 16 bytes
wifinam 4 Wifi name (SSID) 32 bytes
wifipas 5 Wifi password 32 bytes
cnphost 6 CNP host 20 bytes
cnpport 7 CNP port 5 bytes
cnpuser 8 CNP username 16 bytes
cnppass 9 CNP password 16 bytes


Load Network Hardware Driver (loadnhd_)

Purpose Load a network hardware
Jump offset $0c
Communications registers Carry
Stack requirements 8+
Zero page usage $1e, $1f
Registers affected A, X, Y
Input parameters None
Output parameters C ← Set on error

Description: This routine is used to load a configured network hardware driver, and bind the network.lib and the cnp.lib to the new driver.

You will not typically ever call this routine manually. It's called by the Network Utility when it first starts up, and then again if you change the selected driver and save. This routine is called as part of the full network boot up.

The first thing it does is unload any currently loaded network hardware driver. Unloading a network hardware driver consists of calling its unlink routine, allowing the driver to clean itself up and to pause any data flow from the hardware. Then the memory the driver was loaded into is freed, the workspace variable ndrvpg is set to #0 (NULL) indicating that no driver is loaded. And lastly it unsets the ns_nhcf network status bit. The mc_ntwrk message is not sent at this time.

After unloading any previously loaded driver, it then checks to see if the settings specify a driver to load. If there is no specified driver, then the mc_ntwrk message is sent and the carry is returned set, to indicate an error. The error is that this routine is supposed to load a network driver, but it could not because one is not specified in the network settings.

Otherwise, the new driver is loaded and relocated. The relocation address of the loaded driver is set into the workspace variable ndrvpg. If the specified driver file fails to load or relocate, then any memory that was allocated for it is freed, ndrvpg is set back to #0, the mc_ntwrk message is sent out and the carry is returned set, to indicate an error loading the driver.

If the specified driver succeeds in being loaded and relocated, then the jump table in the network.lib is updated with the relocated page address of the driver, to bind the library to the new driver. The network.lib's jump table to the network hardware driver consists of the following routines:

  • nhdunlnk
  • sethand
  • dataget
  • setrate
  • ssidstat
  • opensock

Initially, the driver's incoming data handlers are configured, by calling its sethand routine, so that its online and offline datastreams are both handled by the network.lib. It then calls bindnhd in the cnp.lib. The cnp.lib binds itself to the new driver, and sets itself as the handler for the online data stream.

After the new driver has been installed, it sets the ns_nhcf network status bit and the mc_ntwrk message is sent.

For more information about these routines, see Chapter 7: Using Drivers → Network Hardware.

;defined in //os/s/:network.s

ndrvpg   = $0804

Configure the driver's baud rate (confbaud_)

Purpose Configure the driver's communication speed
Jump offset $0f
Communications registers Carry, A
Stack requirements 4+
Zero page usage Whatever the driver uses
Registers affected A, X, Y
Input parameters None
Output parameters C ← Set on error
A ← Error code
0 = Carrier Detected
1 = Baud Match Test Failed

Description: This routine is used to configure the driver's communications speed, to step the driver up from the hardware's default or initial speed to its preferred speed for C64 OS.

You will not typically ever call this routine manually. It's called by the Network Utility when it first starts up, and then again if you change the selected driver and save. This routine is called as part of the full network boot up.

The first thing it does is sets the driver only to the initial communications speed of the hardware, but calling the driver's setrate routine with the carry clear.

A communications test is then run by the driver. If the test fails, this routine then attempts to the set the speed of the driver to the max. baud rate, to see if that matches the hardware. The final communications test is performed.

If the first communications test was successful, then it tells the driver to step the modem up. The driver does this by sending the command to the modem to set its new communications speed, and then the driver itself changes its communications speed. The final communications test is performed.

In either case, whether the initial communications test failed or succeeded, the success or failure of the second communications test sets ns_nhsp network status bit and the mc_ntwrk message is sent.

There is one exceptional case. If the hardware is already online, (i.e., a modem's carrier detect signal is asserted) then the communications test can't be run. In this case it is assumed that the hardware is online because of a previous instance of C64 OS bringing it online, but then the OS losing its network status information, for example, because of a reboot (without a fast reboot via the REU.) In this case, the driver only is configured for the maximum baud rate, and the ns_nhsp network status bit is set.

It is possible that the assumption is wrong. If the modem was taken online by some non-C64-OS telecommunications software, and the hardware's baud rate is not set to the maximum baud rate specified in the C64 OS network settings, then the driver will not be able to communicate with the hardware. In this case, the only way to make the two align is by forcing the modem to disconnect first. How this is accomplished depends on the hardware. Some modems have a reset button, some modems reset automatically when the computer is reset. The original telecommunications software could be used to tell the modem to disconnect, etc.

Connect the network hardware to a Wifi access point (joinwifi_)

Purpose Connect the network hardware to a Wifi access point
Jump offset $12
Communications registers Carry, A, X, Y
Stack requirements 4+
Zero page usage Whatever the driver uses
Registers affected A, X, Y
Input parameters RegPtr → Next stage callback
C → Clear = Read current SSID
C → Set = Join SSID
Output parameters

When reading the SSID

C ← Always clear

When joining an SSID

C ← Set on error
A ← Error code
0 = Carrier Detected
1 = SSID/Password not configured

Description: This routine is used to read what SSID the network hardware is current connected to, and to tell the network hardware to join an SSID. The feedback from the modem is asynchronous, and flow continues when the callback routine is called.

You will not typically ever call this routine manually. It's called by the Network Utility when the user clicks the cycle button or the join button under the Wifi tab. This routine is also called as part of the full network boot up. The cycle button calls this routine to read the SSID, the join button calls this routine to join an SSID.

If the ns_trcf network status bit is unset, this routine returns with the carry set immediately, and the error code in the accumulator as 1, indicating that it cannot proceed because the SSID and password fields are not configured.

The network.lib's response buffer is cleared and the ssidstat routine of the driver is called. Network.lib passes to ssidstat a RegPtr to a structure which holds pointers to the buffers for the SSID and password.

If the network hardware is already online, it returns with the carry set and the accumulator is set to 0 indicating carrier is detected. In this case, the ns_trup network status bit is set, the mc_ntwrk message is sent. But this routine returns with the carry set, and the accumulator is set to 0. The callback will not be called, because no commands could be sent to the network hardware.

If the call to ssidstat returns with the carry set and the accumulator is not 0, then some other error occurred. This routine returns both with the carry set and with the accumulator holding the driver's error code. The callback will not be called.

If ssidstat returns with the carry clear, then the command to either read or set the SSID was sent to the modem. The response will come later when the callback is called.

The callback is called with the response code in the accumulator. If the response is "0" (PETSCII "0", not integer $00) then the SSID was joined. The default callback sets the ns_trup network status bit and proceeds by calling cnpsrvr. The default callback is used by the full network boot process. Otherwise the Network Utility provides its own callback.

Connect or disconnect from the CNP server (cnpsrvr_)

Purpose Join/Part from the CNP server
Jump offset $15
Communications registers Carry, A, X, Y
Stack requirements 5+
Zero page usage Whatever the cnp.lib and driver uses
Registers affected A, X, Y
Input parameters RegPtr → Next stage callback
C → Clear = Join the CNP Server
C → Set = Part from the CNP Server
Output parameters C ← Set on error
A ← Error code
0 = Carrier Detected
1 = CNP settings not configured

Description: This routine is used to connect to or disconnect from the CNP server. Feedback from the connection attempt is asynchronous and flow continues when the callback routine is called.

When connecting, the driver is told to open a TCP/IP socket. When the socket opens, the callback from this routine must hand control of the socket over to the cnp.lib. That can be done by calling the cnpctrl routine. The cnp.lib takes over, sends the access credentials, and then continues to manage the socket.

You will not typically ever call this routine manually. It's called by the Network Utility when the user clicks the start or stop button under the CNP tab. This routine is also called as part of the full network boot up. The stop button calls this routine to terminate a CNP server connection, the start button calls this routine to open a connection to the CNP server and pass control over to the cnp.lib.

If the ns_cpcf network status bit is unset, this routine returns with the carry set immediately, and the error code in the accumulator as 1, indicating that it cannot proceed because the CNP settings are not configured.

The network.lib's response buffer is cleared and the opensock routine of the network hardware driver is called. Network.lib passes to opensock a RegPtr to a structure which holds pointers to the buffers for the CNP server's host and port. The host can usually be either a domain name or an IP address.

If the network hardware is already online, it returns with the carry set. In this case, the ns_cpup network status bit is set, the mc_ntwrk message is sent. This routine returns with the carry set and the accumulator set to 0. The callback will not be called.

In the network hardware driver, the opensock routine is used to open a socket if the carry is passed in clear. It is also used to close a socket by passing the carry in set. This is a TCP/IP socket, not a CNP socket. The network hardware must support TCP/IP and offer functionality to open at least one TCP/IP socket.

If the call to opensock returns with the carry clear, the command was sent to the modem. This routine also returns with the carry clear, but the response from the network hardware driver comes later when the callback is called.

The callback is called with the response code in the accumulator. If the response is "1" (PETSCII "1", not integer $01) then the socket was opened. The default callback proceeds by calling cnpctrl. If the response code was not "1" then the default callback launches the Network Utility. The default callback is used by the full network boot process. Otherwise the Network Utility provides its own callback.

Pass control of the TCP/IP socket over to cnp.lib (cnpctrl_)

Purpose Pass control to cnp.lib to authenticate
Jump offset $18
Communications registers Carry, X, Y
Stack requirements 4+
Zero page usage Whatever the cnp.lib uses
Registers affected A, X, Y
Input parameters C → Set = Allow network.lib to handle an auto-disconnect
C → Clear = Specify a custom auto-disconnect callback
RegPtr → custom auto-disconnect callback
Output parameters None

Description: This routine is used to transfer control of a just-opened TCP/IP socket to the cnp.lib.

You will not typically ever call this routine manually. It's called by the Network Utility after the user clicked the start button under the CNP tab and then the network hardware driver successfully opened the TCP/IP socket. This routine is also called as part of the full network boot up.

There is a condition under which the TCP/IP socket to the CNP server may unexpectedly close. When this routine is called there are two options, one is to allow the network.lib to handle the disconnection. This option is used by the full network boot. The other option is to pass in the carry clear to specify a custom disconnect handler. The Network Utility specifies a custom disconnect handler. A pointer to the custom handler routine is passed in a RegPtr.

This routine calls sessbgn (session begin) in the cnp.lib and passes a RegPtr to a struct which holds pointers to the settings buffers for the CNP access credentials, i.e., the username and password. The authentication attempt is synchronous, even though sending the actual credentials and getting the response is asynchronous.

sessbgn returns with the carry clear when the access credentials are sent. At this point, before the access credentials are accepted or not, the ns_cpup network status bit is set and the mc_ntwrk message is sent.

sessbgn returns with the carry set if the access credentials could not be sent. The accumulator comes back 0 if the ns_cpup bit is already set. This is not really an error, it just means the access credentials didn't need to be sent again, and the cnp.lib in this app bank has taken control over the TCP/IP socket. The mc_ntwrk message is sent so that the App or Utility get notified that this app bank is online.

sessbgn may also return with the carry set if the hardware driver indicates that the carrier is not up. That is, if the TCP/IP socket is not open, then the carry is set and the accumulator comes back as 1. If this happens, the disconnect handler is is called immediately.

The default disconnect handler provided by network.lib reclaims the communications over the TCP/IP socket from the cnp.lib. Even though the socket is now closed, in order for cnp.lib to have control over the network hardware driver's online data stream it has to have sessbgn called again. It does this by calling sessend with the carry set on the cnp.lib. Then it clears the ns_cpup network status bit and sends the mc_ntwrk message. Then it opens the Network Utility automatically so the user can deal with the issue.

Incorrect access credentials

But what happens if the access credentials are not correct?

Because the access credentials are sent over the network, this is done asynchronously. When everything is configured correctly the access credentials will be accepted. Therefore, once sessbgn returns with the carry clear, indicating that it has sent the credentials, the network status changes and C64 OS goes online.

The access credentials are off course still buffered and being streamed up to the CNP server at the speed of the network hardware. If the access credentials are not accepted, for example, if they were typed in wrong or if the user changed them in their account settings at https://www.c64os.com/c64os/account/#cnpaccess

Previous Section: Library Reference


Next Chapter: Using Toolkit

Table of Contents



This document is subject to revision updates.

Last modified: Jun 13, 2025