Acorn ANFS 4.21 (variant 1) Memory Map

← Acorn NFS and Acorn ANFS

Addresses outside the ROM used by Acorn ANFS 4.21 (variant 1) at run time — zero-page workspace, RAM buffers, and memory-mapped I/O. For the code that lives at &E000 upward, see the disassembly listing.

Zero page

Address Name Access Description
&0000 zp_ptr_lo R/W
&0001 zp_ptr_hi R/W
&0002 zp_work_2 R/W
&0003 zp_work_3 R/W
&0010 zp_temp_10 R/W
&0011 zp_temp_11 R/W
&0012 tube_data_ptr R/W
&0013 tube_data_ptr_hi R/W
&0014 tube_claim_flag R/W
&0015 tube_claimed_id R/W
&0020 tx_buffer_scratch R/W
&0026 parse_separator_flag R/W
&0063 zp_0063 R/W

(false ref from inline string data)

&0078 zp_0078 R/W

(false ref from inline string data)

&0097 escapable R/W

b7=respond to Escape flag

&0098 need_release_tube R/W

b7=need to release Tube

&0099 prot_flags R/W

PFLAGS: printer / protocol status flags.

&009A net_tx_ptr R/W

NetTx control block pointer (low)

&009B net_tx_ptr_hi R/W

NetTx control block pointer (high)

&009C net_rx_ptr R/W

NetRx control blocks pointer (low byte). Pairs with net_rx_ptr_hi.

&009D net_rx_ptr_hi R/W

NetRx control blocks pointer (high byte). Pairs with net_rx_ptr (low).

&009E nfs_workspace R/W

General NFS workspace pointer (low)

&009F nfs_workspace_hi R/W

General NFS workspace pointer (high)

&00A0 nmi_tx_block R/W

NMI TX block pointer (low byte). Address of the TX control block currently being transmitted by the NMI handler.

&00A1 nmi_tx_block_hi R/W

Block to be transmitted (high)

&00A2 port_buf_len R/W

Open port buffer length (low)

&00A3 port_buf_len_hi R/W

Open port buffer length (high)

&00A4 open_port_buf R/W

Open port buffer address (low)

&00A5 open_port_buf_hi R/W

Open port buffer address (high)

&00A6 port_ws_offset R/W

Port workspace offset

&00A7 rx_buf_offset R/W

Receive buffer offset

&00A8 ws_page R/W

Multi-purpose workspace page

&00A9 svc_state R/W

Multi-purpose service state

&00AA osword_flag R/W

OSWORD param byte

&00AB ws_ptr_lo R/W

Workspace indirect pointer (lo)

&00AC ws_ptr_hi R/W

Workspace indirect pointer (hi)

&00AD table_idx R/W

OSBYTE/palette table index counter

&00AE work_ae R/W

Indexed workspace (multi-purpose scratch)

&00AF addr_work R/W

Address work byte for comparison (indexed)

&00B0–&00B3 fs_load_addr R/W

WORK: load/start address (4 bytes)

&00B1 fs_load_addr_hi R/W
&00B2 fs_load_addr_2 R/W
&00B3 fs_load_addr_3 R/W
&00B4 fs_work_4 R/W
&00B5 fs_work_5 R/W

FS scratch byte 5. Multi-purpose: *Wipe iteration counter, parsed FS station number, spool drive number, etc.

&00B6 fs_work_6 R/W

FS scratch byte 6. Multi-purpose: *Wipe end-of-buffer offset, parsed FS network number, etc.

&00B7 fs_work_7 R/W
&00B8 fs_error_ptr R/W
&00B9 fs_crflag R/W
&00BA fs_spool_handle R/W
&00BB fs_options R/W
&00BC fs_block_offset R/W
&00BD fs_last_byte_flag R/W
&00BE fs_crc_lo R/W
&00BF fs_crc_hi R/W
&00C0 txcb_ctrl R/W
&00C1 txcb_port R/W
&00C2 txcb_dest R/W
&00C4 txcb_start R/W
&00C7 txcb_pos R/W
&00C8 txcb_end R/W
&00CC fs_ws_ptr R/W

FS workspace page pointer (lo, always 0)

&00CD nfs_temp R/W
&00CE rom_svc_num R/W
&00CF fs_spool0 R/W
&00D0 vdu_status R/W

VDU status register (OSBYTE &75)

&00ED tx_imm_idx_base R/W
&00EF osbyte_a_copy R/W
&00F0 osword_pb_ptr R/W
&00F1 osword_pb_ptr_hi R/W
&00F3 os_text_ptr_hi R/W
&00F7 osrdsc_ptr_hi R/W
&00FD brk_ptr R/W
&00FF escape_flag R/W

RAM workspace

Address Name Access Description
&0212–&0213 vec_filev R/W

FILEV pointer (lo, hi, rom). Patched to ANFS's FILE handler at init.

&0214–&0215 vec_argsv R/W

ARGSV pointer (lo, hi, rom). Patched to ANFS's ARGS handler at init.

&0216–&0217 vec_bgetv R/W

BGETV pointer (lo, hi, rom). Patched to ANFS's BGET handler at init.

Note: standard layout (the alternate vec_bgetv_alt slot is also used by some routines).

&0218–&0219 vec_bputv R/W

BPUTV pointer (lo, hi, rom). Patched to ANFS's BPUT handler at init.

&021A–&021B vec_bgetv_alt R/W

Alternate BGETV slot (lo, hi, rom). Some ANFS routines use this in addition to the standard vec_bgetv at &0216.

&021C–&021D vec_gbpbv R/W

GBPBV pointer (lo, hi, rom). Patched to ANFS's GBPB handler at init.

&021E–&021F vec_fscv R/W

FSCV pointer (lo, hi, rom). Patched to ANFS's FSC handler at init.

&0350 vdu_screen_mode R

VDU screen mode set by the OS.

&0351 vdu_display_start_hi R

VDU display start address (high byte).

&0355 vdu_mode R

VDU current output stream selector. Determines whether OSWRCH writes to the screen, printer, serial port, etc. ANFS reads this to decide whether to wrap *HELP syntax lines for serial output.

&0D07 nmi_romsel R/W

ROM-bank number patched into the NMI shim. The NMI handler runs in the active sideways slot, so the shim begins by paging in the NFS ROM bank (this byte) before dispatching to the body.

&0D0C nmi_jmp_lo R/W

NMI dispatch JMP-target low byte. Patched by set_nmi_vector and install_nmi_handler. The NMI shim does JMP (nmi_jmp_lo) to reach the current handler.

&0D0D nmi_jmp_hi R/W

NMI dispatch JMP-target high byte. Paired with nmi_jmp_lo. Only set_nmi_vector writes this; install_nmi_handler leaves it alone (same-page optimisation).

&0D0E–&0D10 set_nmi_vector R

NMI vector update (both bytes). STY nmi_jmp_hi then STA nmi_jmp_lo, writing the full 16-bit NMI handler address into the JMP-target slot. Falls through to nmi_rti.

&0D11–&0D13 install_nmi_handler R

NMI vector update (low byte only). STA nmi_jmp_lo only, leaving the existing high byte at nmi_jmp_hi in place. Same-page optimisation used when the next handler is in the same page as the current one. Falls through to nmi_rti.

&0D14–&0D1E nmi_rti R

NMI exit shim. Restores the previous ROM bank, pulls Y and A off the stack, reads BIT econet_nmi_enable (INTON, re-enables /NMI), and RTIs. Reached either as a fall-through from set_nmi_vector / install_nmi_handler, or as a direct branch from any NMI handler that has finished early.

&0D20 tx_dst_stn R/W

Destination station for next TX scout/ACK frame.

&0D21 tx_dst_net R/W

Destination network for next TX scout/ACK frame.

&0D22 tx_src_stn R/W

Source-station byte (our station ID). Set during init from econet_station_id.

&0D23 tx_src_net R/W

Source-network byte for outgoing scout/ACK frames (typically 0 for local network).

&0D24 tx_ctrl_byte R/W

Control byte for next TX scout frame.

&0D25 tx_port R/W

Destination port for next TX scout frame.

&0D26 tx_data_start R/W

Start of TX data buffer (used by scout/data frame construction).

&0D2A tx_data_len R/W

Length of the TX data buffer payload, used during scout/data frame construction.

&0D2E–&0D39 scout_buf R/W

Base of the 12-byte RX scout data buffer. Holds the most recently received scout frame during reception and ACK transmission.

&0D2F scout_src_net R/W

Scout source network byte (scout_buf+1).

&0D30 scout_ctrl R/W

Scout control byte (scout_buf+2). Carries the immediate-op code (&81..&88) for port-0 scouts; checked by immediate_op.

&0D31 scout_port R/W

Scout port byte (scout_buf+3).

&0D32–&0D39 scout_data R/W

Scout data payload base (scout_buf+4). Holds the 4-byte remote address for JSR / UserProc / OSProc immediate ops.

&0D3D rx_src_stn R/W

Source station of the received scout frame. First address byte read by nmi_rx_scout and validated against our station ID.

&0D3E rx_src_net R/W

Source network of the received scout frame. Read by nmi_rx_scout_net; used for the local-network match (0 = local, &FF = broadcast).

&0D3F rx_ctrl R/W

Control byte of the received scout frame.

&0D40 rx_port R/W

Port byte of the received scout frame. Matched against the open RXCB list to find a listener (or the immediate-op port range &80..&88).

&0D41 rx_remote_addr R/W

Remote address byte for received TX setup.

&0D42 rx_extra_byte R/W

Extra trailing RX data byte.

&0D43 saved_nmi_lo R/W

Saved next NMI handler address (low byte). Written by ack_tx_write_dest from the (A=lo, Y=hi) pair on entry, then consumed when the next NMI fires.

&0D44 saved_nmi_hi R/W

Saved next NMI handler address (high byte). Paired with saved_nmi_lo.

&0D4A tx_flags R/W

TX path control flags. Bit 7: TX path is active (used by nmi_error_dispatch to choose between RX-error reset and TX-fail dispatch). Bit 0: handshake-data pending. Bit 1: data-RX into Tube buffer (selected by install_data_rx_handler).

&0D4B nmi_next_lo R/W

Next NMI handler address (low byte). Saved by the scout / data-RX handler; consumed by ack_tx when installing the post-ACK NMI handler.

&0D4C nmi_next_hi R/W

Next NMI handler address (high byte). Paired with nmi_next_lo.

&0D4F tx_index R/W

Index into the TX buffer (current byte position).

&0D50 tx_length R/W

Total length of the TX data payload.

&0D60 tx_complete_flag R/W

TX completion semaphore. Bit 7 set by the NMI TX-completion handler; polled by wait_net_tx_ack to detect frame completion.

&0D61 econet_flags R/W

Econet control flags. Bit 7: port-list active. Bit 2: halt requested.

&0D62 econet_init_flag R/W

Econet-initialised flag. Bit 7 set when the NMI shim has been installed; checked at every NMI to reject pre-init interrupts.

&0D63 tube_present R/W

Tube co-processor presence flag. Probed at init via OSBYTE &EA; read by every TX/RX path that needs to forward data through the Tube.

&0D64 ws_0d64 R/W

ANFS workspace byte (role TBD).

&0D65 tx_op_type R/W

Deferred-work / TX-operation type flag. Set by NMI handlers to mark pending work; polled by svc5_irq_check as the dispatch trigger.

&0D66 exec_addr_lo R/W

Remote execution address (low byte). Stored by remote-JSR / immediate-op paths; consumed when the queued operation runs.

&0D67 exec_addr_hi R/W

Remote execution address (high byte). Paired with exec_addr_lo.

&0D68 ws_0d68 R/W

ANFS workspace byte (role TBD).

&0D69 ws_0d69 R/W

ANFS workspace byte (role TBD).

&0D6A ws_0d6a R/W

ANFS workspace byte (role TBD).

&0D6B spool_buf_idx R/W

Spool / printer buffer write index.

&0D6C fs_flags R/W

Filing-system status flags. Bit 7: NFS is currently the selected FS; cleared when another FS takes over.

&0D6D tx_retry_count R/W

Transmit retry count (default &FF = 255). Settable via OSWORD &13 PB[1].

&0D6E rx_wait_timeout R/W

Receive wait timeout (default &28 = 40). Settable via OSWORD &13 PB[2].

&0D6F peek_retry_count R/W

Machine peek retry count (default &0A = 10). Settable via OSWORD &13 PB[3].

&0D71 spool_control_flag R/W

Multi-purpose: spool-buffer control flag (printer spooling); also doubles as the bridge-routing-table status byte read by init_bridge_poll (&FF = uninitialised, anything else = bridge already polled).

&0D72 bridge_status R/W

Bridge station number (&FF = no bridge). Set by the bridge-discovery scout reply; checked before any cross-network operation.

&0DF0–&0DFF rom_ws_pages R

MOS per-ROM workspace page table (16 bytes, one per sideways-ROM slot). Each entry is the high byte of the page allocated to that ROM's absolute workspace.

&0F03 fs_cmd_csd R/W

TXCB port byte / CSD (current selected directory) handle. Pre-HAZEL counterpart of hazel_txcb_network.

&0F05 fs_cmd_data R/W

TX buffer data start / FS reply data. Pre-HAZEL counterpart of hazel_txcb_data.

&10F3–&10FE filename_buf R/W

Filename display buffer (12 bytes). Used by directory listing and *Info to format filenames.

Filing system workspace (HAZEL)

Address Name Access Description
&C000–&C00A hazel_fs_station R/W

Filing-system state block (&C000&C00A).

Eleven bytes of currently-selected-FS context kept in HAZEL: station / network of the FS, saved prefix station, multi-purpose CSD/library/boot-type slots, FS flags, messages flag, pending-state, error code, last-error, and *OPT addend. The first two bytes (hazel_fs_station, hazel_fs_network) are the FS address used for every TX scout.

&C001 hazel_fs_network R/W

FS network number (sub-byte of the &C000 FS context block).

&C003 hazel_fs_context_copy R/W

Multi-purpose sub-byte of the &C000 block: CSD handle / matched-entry index / Y-indexed base into FS context block.

&C004 hazel_fs_prefix_stn R/W

Multi-purpose sub-byte of the &C000 block: saved-prefix station / library handle / boot type.

&C008 hazel_fs_error_code R/W

FS error code (sub-byte of the &C000 block).

&C009 hazel_fs_last_error R/W

Last FS error byte (sub-byte of the &C000 block).

&C014 hazel_retry_counter R/W

Retry counter for the current Econet TX/RX cycle.

&C030–&C032 hazel_parse_buf R/W

Three-byte parse-buffer used for command-line matching (e.g. *OPT, *FS).

&C038–&C050 hazel_rtc_buffer R/W

OSWORD &0E real-time-clock result buffer.

&C0F7 hazel_fs_reply_byte R/W

Latched first byte of the most recent FS reply.

&C100 hazel_txcb_port R/W

TXCB byte 0: port number for the next TX scout.

&C101 hazel_txcb_func_code R/W

TXCB byte 1: function code (FS command number).

&C102 hazel_txcb_station R/W

TXCB byte 2: destination station.

&C103 hazel_txcb_network R/W

TXCB byte 3: multi-purpose. TXCB destination network (TX setup) / reply function code (RX context) / fs_cmd_csd buffer base (other paths).

&C104 hazel_txcb_lib R/W

TXCB byte 4: library handle terminator / transfer-length param 1.

&C105 hazel_txcb_data R/W

TXCB byte 5: first reply-data byte / data start.

&C106 hazel_txcb_flag R/W

TXCB byte 6: direction flag.

&C107 hazel_txcb_count R/W

TXCB byte 7: data count / lock flag.

&C108 hazel_txcb_result R/W

TXCB byte 8: result / transfer-size lo.

&C200–&C20F hazel_fcb_addr_lo R/W

FCB parallel array (16 entries): file position byte 0 (low). Indexed by channel 0..15; cleared by alloc_fcb_slot on FCB allocation.

&C210–&C21F hazel_fcb_addr_mid R/W

FCB parallel array (16 entries): file position byte 1 (mid).

&C220–&C22F hazel_fcb_addr_hi R/W

FCB parallel array (16 entries): file position byte 2 (high).

&C230–&C23F hazel_fcb_slot_attr R/W

FCB parallel array (16 entries): slot occupancy + channel attribute. Tested for zero by alloc_fcb_slot as the slot-free check; set non-zero on allocation.

&C240–&C24F hazel_fcb_state_byte R/W

FCB parallel array (16 entries): multi-purpose state byte. Holds station number for non-OSFIND channels, or open-mode flags for channels created by OSFIND.

&C250–&C25F hazel_fcb_network R/W

FCB parallel array (16 entries): network number per channel.

&C260–&C26F hazel_fcb_status R/W

FCB parallel array (16 entries): per-channel status flags. Heavily used: bit 6 = connection active (set_conn_active / clear_conn_active toggle).

&C271 hazel_fs_lib_flags R/W

FS library / option flags. Bit 2 = auto-boot, bit 7 = library-directory pending. Cleared / tested by Cat / Lcat / Ex / Lex paths.

&C2C8 hazel_cur_fcb_index R/W

Current FCB index used by the FCB-scan loop in process_all_fcbs. Followed by the channel attribute / reference, byte-counter, buffer pointer and a small block of transfer-state scratch bytes used during file I/O.

&C2CD hazel_sentinel_cd R/W

Sentinel/scratch byte at HAZEL+&CD, used by the FCB-scan loop in process_all_fcbs.

&C2CE hazel_sentinel_ce R/W

Sentinel/scratch byte at HAZEL+&CE, used by the FCB-scan loop in process_all_fcbs.

&C2D9 hazel_ctx_buffer R/W

HAZEL context buffer (saved register / state block used during FCB processing).

Memory-mapped I/O

Address Name Access Description
&FE18 econet_station_id R

Econet station ID register / INTOFF latch. Read: station DIP-switch byte (1..254) AND INTOFF side-effect (disables NMIs from /NMI input).

ANFS reads this on every NMI entry as the first instruction of the shim, both to capture the station ID and to stop NMIs from re-firing during the body of the handler.

&FE20 econet_nmi_enable R

Econet NMI-enable register / INTON latch. Read: re-enables NMIs (INTON side-effect; the value read is ignored).

Used by the NMI-exit shim before RTI so the next /NMI edge re-triggers the handler.

&FE28 master_romsel_shadow R

Master 128 ROMSEL shadow register. Read-only mirror of the current sideways-ROM selection (the actual ROMSEL is at &FE30).

&FE2B master_break_type_shadow R

Master 128 last-break-type hardware shadow. Reflects the value left by the last reset (cold / warm / power-on).

&FE34 acccon R/W

Master 128 ACCCON access-control register.

Bit-by-bit (write-only):

Bit Name Effect when set
7 IRR IRQ-on-VSYNC mask
6 TST Test mode
5 IFJ I/O is JIM
4 ITU Internal Tube
3 Y HAZEL paged in (&C000-&DFFF is hidden RAM)
2 X LYNNE paged in (&3000-&7FFF is shadow RAM)
1 E shadow RAM owns screen
0 D shadow RAM for the OS display

ANFS uses bit 7 (IRR) as a deferred-work latch via TRB/TSB.

&FE38 master_intoff R

Master 128 INTOFF mirror (NMI-disable side effect). Reading any byte here disables /NMI re-entry; the byte value itself is irrelevant.

&FE3C master_inton R

Master 128 INTON mirror (NMI-enable side effect). Reading any byte here re-enables /NMI; the byte value itself is irrelevant.

&FEA0 adlc_cr1 R/W

ADLC control register 1 / status register 1. Write: CR1 (or CR3 if AC=1). Read: SR1.

SR1 bits: RDA (b0), S2RQ (b1), LOOP (b2), FD (b3), CTS (b4), TUF (b5), TDRA (b6), IRQ (b7).

&FEA1 adlc_cr2 R/W

ADLC control register 2 / status register 2. Write: CR2 (or CR4 if AC=1). Read: SR2.

SR2 bits: AP (b0), FV (b1), RX_IDLE (b2), RX_ABRT (b3), ERR (b4), DCD (b5), OVRN (b6), RDA (b7).

&FEA2 adlc_tx R/W

ADLC TX FIFO continue / RX FIFO read. Write: byte to TX FIFO with LAST_DATA = 0 (continue frame). Read: next byte from RX FIFO.

&FEA3 adlc_tx2 R/W

ADLC TX FIFO terminate / RX FIFO read. Write: final byte of frame (LAST_DATA = 1; ADLC appends CRC + closing flag). Read: next byte from RX FIFO.

MOS extended-vector trampolines

Address Name Access Description
&FF1B–&FF1D ev_filev R

FILEV extended-vector dispatcher (file operations: OSFILE, OSFIND).

&FF1E–&FF20 ev_argsv R

ARGSV extended-vector dispatcher (file argument operations: OSARGS).

&FF21–&FF23 ev_bgetv R

BGETV extended-vector dispatcher (single-byte read: OSBGET).

&FF24–&FF26 ev_bputv R

BPUTV extended-vector dispatcher (single-byte write: OSBPUT).

&FF27–&FF29 ev_gbpbv R

GBPBV extended-vector dispatcher (block transfer: OSGBPB).

&FF2A–&FF2C ev_findv R

FINDV extended-vector dispatcher (open / close: OSFIND).

&FF2D–&FF2F ev_fscv R

FSCV extended-vector dispatcher (filing-system control: OSFSC, *commands).

Indexing-base addresses (wrap into ZP)

Address Name Access Description
&FFB0 nmi_buf_idx_base R

NMI buffer indexing-base. Used by the NMI RX setup as STA nmi_buf_idx_base,Y with Y values that wrap into low memory; the bytes at &FFB0 themselves aren't read or written.

&FFBD fcb_workspace_idx_base R

FCB-workspace indexing-base (wraps into ZP). Used by loop_save_fcb_workspace as the base of LDA &FFBD,X with X=&F7..&FF; the effective address wraps to &00B4..&00BC (= fs_work_4+0..+8). The byte at &FFBD itself is never read.