From f1343c5d1e3e58957ddf14505d525ced356cea5b Mon Sep 17 00:00:00 2001 From: winston Date: Sat, 27 Nov 2010 12:48:52 +0000 Subject: [PATCH] Merge gnubinutils branch r372:398 into trunk --- Makefile | 27 ++ README.TXT | 48 +++ build | 67 ---- buildtools/map2sym | 24 ++ flash/flashprog.asm | 366 ------------------ flash/flashwrite.asm | 76 ---- flash/w5100config.asm | 39 -- .../msgrom.asm => include/ctrlchars.inc | 8 +- rom/fs_defs.asm => include/fcntl.inc | 0 rom/flashconf.asm => include/flashconf.inc | 0 rom/moduledefs.asm => include/moduledefs.inc | 0 rom/sockdefs.asm => include/sockdefs.inc | 10 +- rom/spectranet.asm => include/spectranet.inc | 3 - rom/fs_statdefs.asm => include/stat.inc | 0 rom/sysdefs.asm => include/sysdefs.inc | 2 + include/sysvars.inc | 125 ++++++ rom/zxromcalls.asm => include/zxrom.inc | 15 + rom/zxsysvars.asm => include/zxsysvars.inc | 0 installer/Makefile | 50 +++ rom/rommodconfig_en.asm => installer/base.asm | 39 +- installer/baseinst.asm | 144 +++++++ installer/installer.asm | 210 ++++++++++ installer/installer.ld | 39 ++ .../modules.asm | 40 +- make.inc | 14 + modules/Makefile | 16 + modules/basext/Makefile | 4 + modules/basext/boot.asm | 45 ++- modules/basext/build | 5 - modules/basext/commands.asm | 128 +++--- modules/basext/{defs.asm => defs.inc} | 2 + modules/basext/info.asm | 121 +++--- modules/basext/init.asm | 104 ++--- modules/basext/listdir.asm | 96 +++-- modules/basext/loader.asm | 124 +++--- modules/basext/parseurl.asm | 77 ++-- modules/basext/snaphandler.asm | 62 --- modules/basext/strings_en.asm | 47 ++- modules/basext/tapetrap.asm | 70 ++-- modules/basext/vectors.asm | 8 +- modules/config/Makefile | 29 ++ modules/config/build | 5 - modules/config/config.asm | 43 -- ...fig_interface.asm => config_interface.inc} | 0 modules/config/configbasic.asm | 62 +-- modules/config/configdata.asm | 182 +++++---- .../config/{configdefs.asm => configdefs.inc} | 0 modules/config/dumpconfig.asm | 86 ++-- modules/config/flashwrite.asm | 17 +- modules/config/fs_config_ui.asm | 91 +++-- modules/config/fs_strings_en.asm | 81 ++-- modules/config/gen_copycfg.asm | 21 +- modules/config/if_config_ui.asm | 120 +++--- modules/config/if_configmain.asm | 14 +- modules/config/{if_defs.asm => if_defs.inc} | 0 modules/config/if_menu_ui.asm | 91 ----- modules/config/if_saveconfig.asm | 14 +- modules/config/if_strings_en.asm | 110 ++++-- modules/config/init.asm | 50 +-- modules/config/makenewcfg.asm | 6 +- modules/config/sa_flashwrite.asm | 10 +- modules/config/sa_if_saveconfig.asm | 8 +- modules/config/standalone_ifconfig.asm | 29 +- modules/config/vectors.asm | 23 +- modules/make.inc | 21 + modules/messages/Makefile | 4 + modules/messages/build | 5 - modules/messages/getmsg.asm | 30 +- modules/messages/messages_en.asm | 125 +++--- modules/messages/vectors.asm | 4 +- modules/modules.ld | 37 ++ modules/snapman/Makefile | 4 + modules/snapman/build | 5 - modules/snapman/directory.asm | 51 +-- modules/snapman/inputloop.asm | 78 ++-- modules/snapman/loadsna.asm | 91 ++--- modules/snapman/memory.asm | 29 +- modules/snapman/savesna.asm | 88 +++-- modules/snapman/screen.asm | 298 +++++++------- .../basext.asm => snapman/snapheader.inc} | 43 +- modules/snapman/snapman.asm | 39 -- .../snapman/{snapmandefs.asm => snapman.inc} | 0 modules/snapman/strings_en.asm | 54 ++- modules/snapman/utils.asm | 7 +- modules/snapman/vectors.asm | 16 +- modules/streams/Makefile | 5 + modules/streams/buffer.asm | 45 ++- modules/streams/chanmgr.asm | 188 +++++---- modules/streams/commands.asm | 43 +- modules/streams/ctrlchan.asm | 98 ++--- modules/streams/{streamdefs.asm => defs.inc} | 2 + modules/streams/fileio.asm | 67 ++-- modules/streams/flowcontrol.asm | 25 +- modules/streams/init.asm | 54 +-- modules/streams/io.asm | 150 ++++--- modules/streams/memory.asm | 23 +- .../{streamvars.asm => streamvars.inc} | 0 modules/streams/string_en.asm | 27 +- modules/streams/vectors.asm | 7 +- rom/Makefile | 90 +++++ rom/basicextn.asm | 174 +++++---- rom/basstart.asm | 30 +- rom/build | 52 --- rom/config.asm | 95 ----- rom/configutil.asm | 14 - rom/datarom.asm | 40 -- rom/datarom_es.asm | 41 -- rom/debug.asm | 142 ------- rom/dhcp_data.asm | 58 +++ rom/dhcpclient.asm | 168 ++++---- rom/{dhcpdefs.asm => dhcpdefs.inc} | 28 +- rom/dns.asm | 111 +++--- rom/{dnsdefs.asm => dnsdefs.inc} | 7 - rom/extractsym.pl | 26 -- rom/inetinit.asm | 25 +- rom/jumptable.asm | 19 +- rom/modman.ld | 32 ++ rom/page0.ld | 75 ++++ rom/page1.ld | 33 ++ rom/pagealloc.asm | 19 +- rom/progtrap.asm | 29 +- rom/reset.asm | 71 ++-- rom/rom.asm | 75 ---- rom/romconfigmain.asm | 156 ++++---- rom/romconfigutil_en.asm | 6 - rom/romconfstrings_en.asm | 72 ++-- rom/romimage.asm | 11 - rom/romimage_es.asm | 11 - rom/romprog.asm | 110 ------ rom/romprog_es.asm | 110 ------ rom/save7ffd.asm | 91 +++-- rom/startmsg.asm | 22 +- rom/sysvars.asm | 228 ----------- rom/tnfs.asm | 52 --- rom/tnfs_core.asm | 218 ++++++----- rom/{tnfs_defs.asm => tnfs_defs.inc} | 0 rom/tnfs_directory.asm | 60 +-- rom/tnfs_file.asm | 84 ++-- rom/tnfs_init.asm | 31 +- rom/tnfs_mount.asm | 41 +- rom/{tnfs_sysvars.asm => tnfs_sysvars.inc} | 0 rom/tnfs_vectors.asm | 29 +- rom/trapdispatch.asm | 25 +- rom/ui_funcs.asm | 7 + rom/ui_input.asm | 80 ++-- rom/ui_keyscan.asm | 50 +-- rom/ui_output_stub.asm | 31 +- rom/utility.asm | 53 ++- rom/utility_impl.asm | 120 +++--- rom/utilnmi.asm | 80 ++-- rom/utilnmi_en.asm | 45 ++- rom/utilromvectors.asm | 2 +- rom/vfs.asm | 150 ++++--- rom/w5100_buffer.asm | 105 ++--- rom/w5100_defines.asm | 211 ---------- rom/w5100_defs.inc | 208 ++++++++++ rom/w5100_genintfunc.asm | 12 +- rom/w5100_ifconfig.asm | 43 +- rom/w5100_rxtx.asm | 113 +++--- rom/w5100_sockalloc.asm | 112 +++--- rom/w5100_sockctrl.asm | 26 +- rom/w5100_sockinfo.asm | 26 +- rom/zeropage.asm | 54 +-- rom/zxpaging.asm | 82 ---- rom/zxromdefs.asm | 17 - syslib/Makefile | 43 ++ syslib/debug.asm | 130 +++++++ syslib/dispatcher.asm | 84 ++++ {rom => syslib}/flashwrite.asm | 50 +-- {rom => syslib}/pager.asm | 78 +--- {rom => syslib}/ui_charset.asm | 343 ++++++++-------- {rom => syslib}/ui_lookup.asm | 5 +- {rom => syslib}/ui_menu.asm | 34 +- {rom => syslib}/ui_output.asm | 128 +++--- utils/Makefile | 10 + utils/bin2tzx.c | 24 +- utils/flashwrite.asm | 76 ---- utils/fsconfig.asm | 12 - z88dk/Makefile | 16 + {libhttp => z88dk/libhttp}/Makefile | 10 +- {libhttp => z88dk/libhttp}/addFormData.c | 0 {libhttp => z88dk/libhttp}/allocURI.c | 0 {libhttp => z88dk/libhttp}/base64enc.c | 0 {libhttp => z88dk/libhttp}/freeFormData.c | 0 {libhttp => z88dk/libhttp}/freeURI.c | 0 {libhttp => z88dk/libhttp}/freeheaders.c | 0 {libhttp => z88dk/libhttp}/getheader.c | 0 {libhttp => z88dk/libhttp}/htrecv.c | 0 {libhttp => z88dk/libhttp}/include/http.h | 0 {libhttp => z88dk/libhttp}/parseURI.c | 0 {libhttp => z88dk/libhttp}/parseproto.c | 0 {libhttp => z88dk/libhttp}/postsize.c | 0 {libhttp => z88dk/libhttp}/readData.c | 0 {libhttp => z88dk/libhttp}/readHeaders.c | 0 {libhttp => z88dk/libhttp}/request.c | 0 .../libspectranet}/Makefile | 9 +- .../libspectranet}/addbasicext.asm | 0 .../libspectranet}/deconfig.asm | 0 .../libspectranet}/exit_success.asm | 0 .../libspectranet}/expect2num.asm | 0 .../libspectranet}/expectnum.asm | 0 .../libspectranet}/expectstringexp.asm | 0 .../libspectranet}/find_int1.asm | 0 .../libspectranet}/find_int2.asm | 0 .../libspectranet}/get_ifconfig_gw.asm | 0 .../libspectranet}/get_ifconfig_inet.asm | 0 .../libspectranet}/get_ifconfig_netmask.asm | 0 .../libspectranet}/gethwaddr.asm | 0 .../libspectranet}/ifconfig_gw.asm | 0 .../libspectranet}/ifconfig_inet.asm | 0 .../libspectranet}/ifconfig_netmask.asm | 0 .../libspectranet}/include/basicext.h | 0 .../libspectranet}/include/spectranet.h | 0 .../libspectranet}/ipstring2long.asm | 0 .../libspectranet}/ipstring2long_callee.asm | 0 .../libspectranet}/libspectranet.lst | 0 .../libspectranet}/libspectranet_np.lst | 0 .../libspectranet}/long2ipstring.asm | 0 .../libspectranet}/long2ipstring_callee.asm | 0 .../libspectranet}/mac2string.asm | 0 .../libspectranet}/mac2string_callee.asm | 0 .../libspectranet}/makesources.pl | 0 .../libspectranet}/next_char.asm | 0 .../libspectranet}/pagein.asm | 0 .../libspectranet}/pageout.asm | 0 .../libspectranet}/sethwaddr.asm | 0 .../libspectranet}/setpagea.asm | 0 .../libspectranet}/setpageb.asm | 0 .../libspectranet}/spectranet.asm | 0 .../libspectranet}/statement_end.asm | 0 .../libspectranet}/string_fetch.asm | 0 .../libspectranet}/string_fetch_callee.asm | 0 .../libspectranet}/testbasext.c | 0 .../libspectranet}/testlibsn.c | 0 .../libspectranet}/zxromdefs.asm | 0 z88dk/make.inc | 13 + {socklib => z88dk/socklib}/Makefile | 10 +- {socklib => z88dk/socklib}/accept.asm | 0 {socklib => z88dk/socklib}/accept_callee.asm | 0 {socklib => z88dk/socklib}/bind.asm | 0 {socklib => z88dk/socklib}/bind_callee.asm | 0 {socklib => z88dk/socklib}/connect.asm | 0 {socklib => z88dk/socklib}/connect_callee.asm | 0 {socklib => z88dk/socklib}/gethostbyname.asm | 0 {socklib => z88dk/socklib}/include/netdb.h | 0 {socklib => z88dk/socklib}/include/sockpoll.h | 0 .../socklib}/include/sys/socket.h | 0 {socklib => z88dk/socklib}/libsocket.lst | 0 {socklib => z88dk/socklib}/libsocket_np.lst | 0 {socklib => z88dk/socklib}/listen.asm | 0 {socklib => z88dk/socklib}/listen_callee.asm | 0 {socklib => z88dk/socklib}/makesources.pl | 0 {socklib => z88dk/socklib}/muxserver.c | 0 {socklib => z88dk/socklib}/nonmuxserver.c | 0 {socklib => z88dk/socklib}/np_testsocks.c | 0 {socklib => z88dk/socklib}/pollall.asm | 0 {socklib => z88dk/socklib}/pollfd.asm | 0 {socklib => z88dk/socklib}/recv.asm | 0 {socklib => z88dk/socklib}/recv_callee.asm | 0 .../socklib}/recvfrom_callee.asm | 0 {socklib => z88dk/socklib}/send.asm | 0 {socklib => z88dk/socklib}/send_callee.asm | 0 {socklib => z88dk/socklib}/sendto_callee.asm | 0 {socklib => z88dk/socklib}/sockclose.asm | 0 {socklib => z88dk/socklib}/socket.asm | 0 {socklib => z88dk/socklib}/socket_callee.asm | 0 {socklib => z88dk/socklib}/spectranet.asm | 0 {socklib => z88dk/socklib}/testclient.c | 0 {socklib => z88dk/socklib}/testsocks.c | 0 {socklib => z88dk/socklib}/testudpserv.c | 0 270 files changed, 5447 insertions(+), 5176 deletions(-) create mode 100644 Makefile create mode 100644 README.TXT delete mode 100755 build create mode 100755 buildtools/map2sym delete mode 100644 flash/flashprog.asm delete mode 100644 flash/flashwrite.asm delete mode 100644 flash/w5100config.asm rename modules/messages/msgrom.asm => include/ctrlchars.inc (90%) rename rom/fs_defs.asm => include/fcntl.inc (100%) rename rom/flashconf.asm => include/flashconf.inc (100%) rename rom/moduledefs.asm => include/moduledefs.inc (100%) rename rom/sockdefs.asm => include/sockdefs.inc (92%) rename rom/spectranet.asm => include/spectranet.inc (99%) rename rom/fs_statdefs.asm => include/stat.inc (100%) rename rom/sysdefs.asm => include/sysdefs.inc (98%) create mode 100644 include/sysvars.inc rename rom/zxromcalls.asm => include/zxrom.inc (87%) rename rom/zxsysvars.asm => include/zxsysvars.inc (100%) create mode 100644 installer/Makefile rename rom/rommodconfig_en.asm => installer/base.asm (67%) create mode 100644 installer/baseinst.asm create mode 100644 installer/installer.asm create mode 100644 installer/installer.ld rename rom/rommodconfig_es.asm => installer/modules.asm (66%) create mode 100644 make.inc create mode 100644 modules/Makefile create mode 100644 modules/basext/Makefile delete mode 100755 modules/basext/build rename modules/basext/{defs.asm => defs.inc} (97%) delete mode 100644 modules/basext/snaphandler.asm create mode 100644 modules/config/Makefile delete mode 100755 modules/config/build delete mode 100644 modules/config/config.asm rename modules/config/{config_interface.asm => config_interface.inc} (100%) rename modules/config/{configdefs.asm => configdefs.inc} (100%) rename modules/config/{if_defs.asm => if_defs.inc} (100%) delete mode 100644 modules/config/if_menu_ui.asm create mode 100644 modules/make.inc create mode 100644 modules/messages/Makefile delete mode 100755 modules/messages/build create mode 100644 modules/modules.ld create mode 100644 modules/snapman/Makefile delete mode 100755 modules/snapman/build rename modules/{basext/basext.asm => snapman/snapheader.inc} (59%) delete mode 100644 modules/snapman/snapman.asm rename modules/snapman/{snapmandefs.asm => snapman.inc} (100%) create mode 100644 modules/streams/Makefile rename modules/streams/{streamdefs.asm => defs.inc} (97%) rename modules/streams/{streamvars.asm => streamvars.inc} (100%) create mode 100644 rom/Makefile delete mode 100755 rom/build delete mode 100644 rom/config.asm delete mode 100644 rom/configutil.asm delete mode 100644 rom/datarom.asm delete mode 100644 rom/datarom_es.asm delete mode 100644 rom/debug.asm create mode 100644 rom/dhcp_data.asm rename rom/{dhcpdefs.asm => dhcpdefs.inc} (74%) rename rom/{dnsdefs.asm => dnsdefs.inc} (87%) delete mode 100755 rom/extractsym.pl create mode 100644 rom/modman.ld create mode 100644 rom/page0.ld create mode 100644 rom/page1.ld delete mode 100644 rom/rom.asm delete mode 100644 rom/romconfigutil_en.asm delete mode 100644 rom/romimage.asm delete mode 100644 rom/romimage_es.asm delete mode 100644 rom/romprog.asm delete mode 100644 rom/romprog_es.asm delete mode 100644 rom/sysvars.asm delete mode 100644 rom/tnfs.asm rename rom/{tnfs_defs.asm => tnfs_defs.inc} (100%) rename rom/{tnfs_sysvars.asm => tnfs_sysvars.inc} (100%) create mode 100644 rom/ui_funcs.asm delete mode 100644 rom/w5100_defines.asm create mode 100644 rom/w5100_defs.inc delete mode 100644 rom/zxpaging.asm delete mode 100644 rom/zxromdefs.asm create mode 100644 syslib/Makefile create mode 100644 syslib/debug.asm create mode 100644 syslib/dispatcher.asm rename {rom => syslib}/flashwrite.asm (89%) rename {rom => syslib}/pager.asm (61%) rename {rom => syslib}/ui_charset.asm (90%) rename {rom => syslib}/ui_lookup.asm (96%) rename {rom => syslib}/ui_menu.asm (87%) rename {rom => syslib}/ui_output.asm (82%) create mode 100644 utils/Makefile delete mode 100644 utils/flashwrite.asm delete mode 100644 utils/fsconfig.asm create mode 100644 z88dk/Makefile rename {libhttp => z88dk/libhttp}/Makefile (64%) rename {libhttp => z88dk/libhttp}/addFormData.c (100%) rename {libhttp => z88dk/libhttp}/allocURI.c (100%) rename {libhttp => z88dk/libhttp}/base64enc.c (100%) rename {libhttp => z88dk/libhttp}/freeFormData.c (100%) rename {libhttp => z88dk/libhttp}/freeURI.c (100%) rename {libhttp => z88dk/libhttp}/freeheaders.c (100%) rename {libhttp => z88dk/libhttp}/getheader.c (100%) rename {libhttp => z88dk/libhttp}/htrecv.c (100%) rename {libhttp => z88dk/libhttp}/include/http.h (100%) rename {libhttp => z88dk/libhttp}/parseURI.c (100%) rename {libhttp => z88dk/libhttp}/parseproto.c (100%) rename {libhttp => z88dk/libhttp}/postsize.c (100%) rename {libhttp => z88dk/libhttp}/readData.c (100%) rename {libhttp => z88dk/libhttp}/readHeaders.c (100%) rename {libhttp => z88dk/libhttp}/request.c (100%) rename {libspectranet => z88dk/libspectranet}/Makefile (85%) rename {libspectranet => z88dk/libspectranet}/addbasicext.asm (100%) rename {libspectranet => z88dk/libspectranet}/deconfig.asm (100%) rename {libspectranet => z88dk/libspectranet}/exit_success.asm (100%) rename {libspectranet => z88dk/libspectranet}/expect2num.asm (100%) rename {libspectranet => z88dk/libspectranet}/expectnum.asm (100%) rename {libspectranet => z88dk/libspectranet}/expectstringexp.asm (100%) rename {libspectranet => z88dk/libspectranet}/find_int1.asm (100%) rename {libspectranet => z88dk/libspectranet}/find_int2.asm (100%) rename {libspectranet => z88dk/libspectranet}/get_ifconfig_gw.asm (100%) rename {libspectranet => z88dk/libspectranet}/get_ifconfig_inet.asm (100%) rename {libspectranet => z88dk/libspectranet}/get_ifconfig_netmask.asm (100%) rename {libspectranet => z88dk/libspectranet}/gethwaddr.asm (100%) rename {libspectranet => z88dk/libspectranet}/ifconfig_gw.asm (100%) rename {libspectranet => z88dk/libspectranet}/ifconfig_inet.asm (100%) rename {libspectranet => z88dk/libspectranet}/ifconfig_netmask.asm (100%) rename {libspectranet => z88dk/libspectranet}/include/basicext.h (100%) rename {libspectranet => z88dk/libspectranet}/include/spectranet.h (100%) rename {libspectranet => z88dk/libspectranet}/ipstring2long.asm (100%) rename {libspectranet => z88dk/libspectranet}/ipstring2long_callee.asm (100%) rename {libspectranet => z88dk/libspectranet}/libspectranet.lst (100%) rename {libspectranet => z88dk/libspectranet}/libspectranet_np.lst (100%) rename {libspectranet => z88dk/libspectranet}/long2ipstring.asm (100%) rename {libspectranet => z88dk/libspectranet}/long2ipstring_callee.asm (100%) rename {libspectranet => z88dk/libspectranet}/mac2string.asm (100%) rename {libspectranet => z88dk/libspectranet}/mac2string_callee.asm (100%) rename {libspectranet => z88dk/libspectranet}/makesources.pl (100%) rename {libspectranet => z88dk/libspectranet}/next_char.asm (100%) rename {libspectranet => z88dk/libspectranet}/pagein.asm (100%) rename {libspectranet => z88dk/libspectranet}/pageout.asm (100%) rename {libspectranet => z88dk/libspectranet}/sethwaddr.asm (100%) rename {libspectranet => z88dk/libspectranet}/setpagea.asm (100%) rename {libspectranet => z88dk/libspectranet}/setpageb.asm (100%) rename {libspectranet => z88dk/libspectranet}/spectranet.asm (100%) rename {libspectranet => z88dk/libspectranet}/statement_end.asm (100%) rename {libspectranet => z88dk/libspectranet}/string_fetch.asm (100%) rename {libspectranet => z88dk/libspectranet}/string_fetch_callee.asm (100%) rename {libspectranet => z88dk/libspectranet}/testbasext.c (100%) rename {libspectranet => z88dk/libspectranet}/testlibsn.c (100%) rename {libspectranet => z88dk/libspectranet}/zxromdefs.asm (100%) create mode 100644 z88dk/make.inc rename {socklib => z88dk/socklib}/Makefile (87%) rename {socklib => z88dk/socklib}/accept.asm (100%) rename {socklib => z88dk/socklib}/accept_callee.asm (100%) rename {socklib => z88dk/socklib}/bind.asm (100%) rename {socklib => z88dk/socklib}/bind_callee.asm (100%) rename {socklib => z88dk/socklib}/connect.asm (100%) rename {socklib => z88dk/socklib}/connect_callee.asm (100%) rename {socklib => z88dk/socklib}/gethostbyname.asm (100%) rename {socklib => z88dk/socklib}/include/netdb.h (100%) rename {socklib => z88dk/socklib}/include/sockpoll.h (100%) rename {socklib => z88dk/socklib}/include/sys/socket.h (100%) rename {socklib => z88dk/socklib}/libsocket.lst (100%) rename {socklib => z88dk/socklib}/libsocket_np.lst (100%) rename {socklib => z88dk/socklib}/listen.asm (100%) rename {socklib => z88dk/socklib}/listen_callee.asm (100%) rename {socklib => z88dk/socklib}/makesources.pl (100%) rename {socklib => z88dk/socklib}/muxserver.c (100%) rename {socklib => z88dk/socklib}/nonmuxserver.c (100%) rename {socklib => z88dk/socklib}/np_testsocks.c (100%) rename {socklib => z88dk/socklib}/pollall.asm (100%) rename {socklib => z88dk/socklib}/pollfd.asm (100%) rename {socklib => z88dk/socklib}/recv.asm (100%) rename {socklib => z88dk/socklib}/recv_callee.asm (100%) rename {socklib => z88dk/socklib}/recvfrom_callee.asm (100%) rename {socklib => z88dk/socklib}/send.asm (100%) rename {socklib => z88dk/socklib}/send_callee.asm (100%) rename {socklib => z88dk/socklib}/sendto_callee.asm (100%) rename {socklib => z88dk/socklib}/sockclose.asm (100%) rename {socklib => z88dk/socklib}/socket.asm (100%) rename {socklib => z88dk/socklib}/socket_callee.asm (100%) rename {socklib => z88dk/socklib}/spectranet.asm (100%) rename {socklib => z88dk/socklib}/testclient.c (100%) rename {socklib => z88dk/socklib}/testsocks.c (100%) rename {socklib => z88dk/socklib}/testudpserv.c (100%) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0c5780e --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +SUBDIRS = syslib rom modules installer utils + +.PHONY: subdirs $(SUBDIRS) + +.PHONY: clean + +.PHONY: z88dk + +subdirs: $(SUBDIRS) + +z88dk: + $(MAKE) -C z88dk + +$(SUBDIRS): + $(MAKE) -C $@ + +clean: + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean; \ + done + +rom: syslib + +modules: syslib + +installer: syslib rom modules utils + diff --git a/README.TXT b/README.TXT new file mode 100644 index 0000000..c00fd29 --- /dev/null +++ b/README.TXT @@ -0,0 +1,48 @@ +BUILDING THE SPECTRANET ROMs/MODULES +------------------------------------ + +Pre-requisites: +A Unix build environment (Linux, BSD, Mac OSX, Windows with Cygwin, Windows +with MinGW etc) +GNU binutils for Z80 (assembler, linker, ar, ranlib etc) +Perl for some build scripts (my intention is to remove this requirement) + +To build: +In the top level directory, type "make" + +To install: +A firmware programmer is generated in the directory 'installer'. This +must be run on a ZX Spectrum with a Spectranet. Two versions exist - a +version that programs just the base ROM set (first four pages), and +a version that programs the base ROM set and standard modules (basext, +streams, msgrom, config and snapman). + +Run 'bin2tzx' to convert the install.bin / base.bin files to TZX files +to load via the Spectrum's tape port. Alternatively, to update a Spectranet +that is already programmed, load via ethernet using the 'ethup' utility: + + On the Spectrum: + CLEAR 26999 + (press NMI button or short the NMI pins on the bare board) + (Select 'Load arbitrary data...') + + On the build machine: + ethup install.bin 27000 + + Then on the Spectrum, exit the NMI menu and: + RANDOMIZE USR 27000 + +Or if you have the computer with the build mounted via TNFS or some other +filesystem, on the Spectrum: + + CLEAR 26999 + %aload "install.bin" CODE 27000 + RANDOMIZE USR 27000 + +DEVELOPING +---------- +If you intend to work on the ROM sources or modules, it's advisable to +also generate the dependencies, by running 'buildtoos/makedeps'. This +will ensure if you alter an include file, everything that depends on it +gets rebuilt the next time 'make' is run. + diff --git a/build b/build deleted file mode 100755 index dfa28a3..0000000 --- a/build +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh -BUILDROOT=`pwd` -UTILS="$BUILDROOT/utils" -BASEROM="$BUILDROOT/rom" -MODULES="$BUILDROOT/modules" -WEBHOST=providence.alioth.net:/var/www/vhosts/spectrum/www/downloads -BUILDOUT="$BUILDROOT/build.out" -TMPDIR="$BUILDROOT/tmp" -BIN2TZX="$UTILS/bin2tzx" - -echo "**** BUILDING UTILITIES" -cd $UTILS -make bin2tzx -if [ "$?" != "0" ]; then - echo - echo "Failed to build utilities" - exit -fi - -echo "**** BUILDING BASE ROM" - -rm -f $BUILDOUT - -cd $BASEROM -./build $1 -if [ "$?" != "0" ]; then - echo - echo "Build failed!" - exit -fi - -cd $MODULES - -echo "**** BUILDING MODULES" -for dir in * -do - if [ -d $dir ]; then - cd $dir - if [ -e build ]; then - ./build $1 - if [ "$?" != "0" ]; then - echo - echo "Build failed in $dir" - exit - fi - fi - cd .. - fi -done - -cd $BUILDROOT -if [ "$1" == "public" ]; then - echo "**** CREATING TZX FILES AND UPLOADING" - - for fname in `cat $BUILDOUT` - do - TZX=$TMPDIR/`basename $fname .out`.tzx - $BIN2TZX $fname $TZX - scp $fname $TZX $WEBHOST - if [ "$?" != "0" ]; then - echo - echo "Copy failed to $WEBHOST" - exit - fi - done -fi - diff --git a/buildtools/map2sym b/buildtools/map2sym new file mode 100755 index 0000000..3ef7a29 --- /dev/null +++ b/buildtools/map2sym @@ -0,0 +1,24 @@ +#!/usr/bin/perl +my $mapfile=shift; +my $outputfile=shift; +if(!$outputfile) +{ + print("Usage: map2sym \n"); + exit -1; +} + +open FHND, "< $mapfile" or die("Unable to open $mapfile: $!"); +open SYMHND, "> $outputfile" or die("Unable to write to $outputfile: $!"); +while(my $line=) +{ + chomp $line; + if($line =~ /^\s{1,}0x[a-zA-Z0-9]{1,}\s{1,}(F|J)_/) + { + $line=~s/^\s{1,}//g; + my ($addr, $symbol)=split(/\s{1,}/, $line, 2); + print SYMHND "$symbol equ $addr\n"; + } +} +close(FHND); +close(SYMHND); + diff --git a/flash/flashprog.asm b/flash/flashprog.asm deleted file mode 100644 index 4cf2040..0000000 --- a/flash/flashprog.asm +++ /dev/null @@ -1,366 +0,0 @@ -; Simple flash programmer for programming the Spectranet flash over -; the network. Values are hard coded at present; this is just a development -; tool to allow me to reprogram the flash ROM without needing to dig it out -; and put it in the flash programmer. -; -; It just dumbly programs 16K worth of data that gets sent over the network. -; It can either be left in one of the pages of the flash chip itself, and -; LDIR'd to its proper location, or stored on a DivIDE or other device and -; loaded when needed. -; -; It must run independently of the flash chip since we're going to erase and -; rewrite it! The easiest method is just run from RAM. -; -; Data is loaded just after the program's last used address. -; - include "../rom/w5100_defines.asm" - - org 0xF000 ; start with RAND USR 61440 - di - - ld a, 1 ; page in spectranet memory - ld bc, 0x80EF - out (c), a - - call F_clear ; clear screen, setup print routine - call F_w5100init ; initialize ethernet - ld hl, STR_send - call F_print - - ; Ethernet setup is just hardcoded here; this is a simple single - ; purpose program. If you're looking at this for an example - ; of how to program for the Spectranet, this is a terrible example. - ; Don't follow it! It's done like this to be able to bootstrap - ; the board with a new flash program with very little other - ; support. Real programs should use the socket library. -.open - ld a, 0x40 ; W5100 register page - call F_setpageA - ld a, S_MR_TCP|S_MR_NDMC ; Create a TCP socket, no delayed ACK - ld (Sn_MR), a ; as socket 0 - ld a, 2000 / 256 ; port 2000 - ld (Sn_PORT1), a ; lsb of port address - ld a, 2000 % 256 - ld (Sn_PORT0), a ; msb of port address - ld a, S_CR_OPEN ; open the socket - ld (Sn_CR), a - ld a, (Sn_SR) ; check status - cp S_SR_SOCK_INIT ; Open successfully? - jr z, .listen ; if so listen for a new connection - ld a, S_CR_CLOSE ; else give up - ld (Sn_CR), a - jp J_giveup -.listen - ld hl, STR_open ; tell the user that we're ready - call F_print - ld a, S_CR_LISTEN - ld (Sn_CR), a ; listen - ld a, (Sn_SR) ; status register check - cp S_SR_SOCK_LISTEN - jr z, .listening ; Status changed successfully - ld a, S_CR_CLOSE ; if not give up - ld (Sn_CR), a - jp J_giveup -.listening - ld a, (Sn_SR) ; Read status register - cp S_SR_SOCK_ESTABLISHED ; and wait until something connects - jr nz, .listening -.rxdata - call F_pollsocket ; poll socket for incoming data -.recvaddrs - ld de, v_reqaddr ; fill the address/size params - ld bc, 4 ; 4 bytes of data - call F_copyrxbuf ; fill receive buffer - ld hl, STR_dest - call F_print - ld hl, (v_reqaddr) - call F_printhex - ld hl, STR_len - call F_print - ld hl, (v_reqsize) - call F_printhex - ld hl, v_reqaddr ; duplicate requested addr/length params - ld de, v_calladdr - ldi - ldi - ldi - ldi -.recvdata - call F_pollsocket ; on exit h = msb of register pointer - ld de, (v_reqaddr) ; address to copy to - ld bc, 1024 ; up to 1k at a time (it can be less) - call F_copyrxbuf ; get data, bc=length actually copied - ld hl, (v_reqaddr) - add hl, bc - ld (v_reqaddr), hl ; update memory pointer - ld hl, (v_reqsize) - sbc hl, bc ; deduct bytes copied - ld a, h ; zero bytes left? - or l - jr z, .recvdone - ld (v_reqsize), hl ; save bytes remaining - jr .recvdata -.recvdone - ld hl, Sn_CR ; command register - ld (hl), S_CR_CLOSE ; close the socket - ld a, (v_calladdr+1) ; check to see if this is a SCREEN$ - cp 0x40 ; MSB is 0x40 for SCREEN$ - jp z, .open ; get another - ld hl, STR_recvdone - call F_print - - ; calling 0x007C forces a pageout through the normal return - ; mechanism, or has no effect if not paged in. - call 0x007C - - ; now we can just use the ROM keyscan routine. Poll until we - ; find something of interest. -.getkeyloop - call F_pollkeys - cp 'j' ; jump to routine - jr z, .jump - cp 'f' - jr z, .flash - cp 'r' - jr z, .return - jr .getkeyloop - - ; Jump to the start address of the block of data we just got. -.jump - ld hl, (v_calladdr) - jp (hl) - -.return - ld bc, 0x8000|PAGERPORT ; page in our memory - ld a, 1 - out (c), a - ret - -.flash di - ld a, 1 ; page in our memory - ld bc, 0x8000 | PAGERPORT - out (c), a - ld hl, STR_erasing - call F_print - - ; Erase sector 0 of the flash chip. - call F_FlashEraseSectorZero - jr c, .erasefailed - - ; Now map in page 1 and 2 of ROM, so the first three pages - ; are in a contiguous block. - ld a, 1 ; chip 0 page 1 - call F_setpageA - ld a, 2 ; chip 0 page 2 - call F_setpageB - ld hl, STR_writing - call F_print - - ; now write a 16k block from the start address on up. - ld hl, (v_calladdr) ; get the start address - ld de, 0 ; start from the bottom - ld bc, 0x3000 ; 12k of data to write in this first chunk -.writeloop - ld a, (hl) - call F_FlashWriteByte - jr c, .writefailed - inc hl - inc de - dec bc - ld a, b - or c - jr nz, .writeloop - push hl ; now map in the remaining page - ld a, 3 - call F_setpageB - pop hl ; hl will be pointing at the right byte - ld de, 0x2000 ; start of page B - ld bc, 0x1000 ; 4k of data left to go -.writeloop2 - ld a, (hl) - call F_FlashWriteByte - jr c, .writefailed - inc hl - inc de - dec bc - ld a, b - or c - jr nz, .writeloop2 - - ld hl, STR_donewriting - call F_print - halt - -.erasefailed - ld hl, STR_erasedied - call F_print - halt -.writefailed - push hl - ld hl, STR_writedied - call F_print - pop hl - call F_printhex - halt - -J_giveup - ld hl, STR_givenup - call F_print - halt - -F_pollsocket - ld a, (Sn_RX_RSR0) ; MSB of received bytes register - ld hl, Sn_RX_RSR1 ; LSB of received bytes register - or (hl) ; OR together to see if zero - jr z, F_pollsocket ; keep polling while zero - ret - -F_print - ld a, (hl) - and a - ret z - call putc_5by8 - inc hl - jr F_print - -; a modified version of baze's 16 bit integer hex conversion, which prints -; the result when done. Number to display is in hl. -F_printhex - ld de, STR_hex -Num2Hex ld a,h - call Num1 - ld a,h - call Num2 - ld a,l - call Num1 - ld a,l - call Num2 - ld hl, STR_hex - call F_print - ret - -Num1 rra - rra - rra - rra -Num2 or 0xF0 - daa - add a,0xA0 - adc a,0x40 - - ld (de),a - inc de - ret - -; Simple cls routine -F_clear - ld hl, 16384 - ld de, 16385 - ld bc, 6144 - ld (hl), 0 - ldir - ld (hl), 56 ; attribute for white - ld bc, 767 - ldir - xor a - ld (v_column), a - ld (v_rowcount), a - ld hl, 16384 - ld (v_row), hl - ret - -; Use the Speccy rom plus a lookup table to turn a keypress (0-z) -; into an option. -F_pollkeys -.poll - call 0x28E ; Spectrum ROM key poll routine - ld a, e ; result is in E, move to A to test - cp 0xFF ; No key pressed - jr z, .poll - push de ; save for later -.pollkeyup - call 0x28E - ld a, e - cp 0xFF - jr nz, .pollkeyup - pop de - ld hl, LK_keys ; Look up the key that was pressed - ld d, 0 - add hl, de - ld a, (hl) - ret - -; Set paging area A. Page to load in A. -F_setpageA - push bc - ld bc, 0x8000|PAGEA - ld (v_pga), a ; save the page we've just paged. - out (c), a ; page it in - pop bc - ret - -; Set paging area B. As for area A. -F_setpageB - push bc - ld bc, 0x8000|PAGEB - ld (v_pgb), a - out (c), a ; page it in - pop bc - ret - -; asm modules - TODO: Eventually, these should be the same versions as -; the ROM versions, but for now, the experimental ones are the ones we -; have. - include "../experiments/print5by8.asm" - include "w5100config.asm" - include "flashwrite.asm" - include "../rom/w5100_buffer.asm" - include "../rom/ui_charset.asm" - block 0xF800-$,0xFF - include "../rom/ui_lookup.asm" - -STR_send defb "Opening socket...",0 -STR_open defb "Done\n",0 -STR_dest defb "Receiving data:\n destination = ",0 -STR_len defb "\n length = ",0 -STR_givenup defb "\nFailed (giving up)",0 -STR_recvdone defb "\nTransfer complete\nPress J to jump, F to flash, R to return\n",0 -STR_erasing defb "Erasing flash sector 0\n",0 -STR_writing defb "Writing data...\n",0 -STR_donewriting defb "Complete.\n",0 -STR_erasedied defb "Erase failed\n",0 -STR_writedied defb "Write failed: src addr = ",0 - -v_pr_wkspc defw 0 -v_column defb 0 -v_rowcount defb 0 -v_row defw 0 -v_pga defb 0 -v_pgb defb 0 -v_chipsel defb 0 -v_sockptr defw 0 -v_copylen defw 0 -v_copied defw 0 -v_reqaddr defw 0 ; sent over the net -v_reqsize defw 0 ; sent over the net -v_calladdr defw 0 ; address to call on completion -v_length defw 0 ; length of data sent to us -STR_hex defb 0,0,0,0,0 ; 5 bytes to include the NUL - -; various definitions -CHIPSEL equ 0xED -PAGEA equ 0xE9 -PAGEB equ 0xEB -PAGERPORT equ 0xEF - - ; Simple key value lookup table. -LK_keys defb 'b', 'h', 'y', '6', '5', 't', 'g', 'v' ; 0-7 - defb 'n', 'j', 'u', '7', '4', 'r', 'f', 'c' ; 8-15 - defb 'm', 'k', 'i', '8', '3', 'e', 'd', 'x' ; 16-23 - defb 255, 'l', 'o', '9', '2', 'w', 's', 'z' ; 24-31 - defb 255, 255, 'p', '0', '1', 'q', 'a' ; 32-38 - block $+32-$, #ff - - -END defb 0 - diff --git a/flash/flashwrite.asm b/flash/flashwrite.asm deleted file mode 100644 index 1a9cf7d..0000000 --- a/flash/flashwrite.asm +++ /dev/null @@ -1,76 +0,0 @@ -; Simple flash writer for the Am29F010 (and probably any 1 megabit flash -; with 16kbyte sectors) -; Pass the page in A -; On error, carry flag set. -F_FlashEraseSectorZero - ld a, 0xAA ; unlock code 1 - ld (0x555), a ; unlock addr 1 - ld a, 0x55 ; unlock code 2 - ld (0x2AA), a ; unlock addr 2 - ld a, 0x80 ; erase cmd 1 - ld (0x555), a ; erase cmd addr 1 - ld a, 0xAA ; erase cmd 2 - ld (0x555), a ; erase cmd addr 2 - ld a, 0x55 ; erase cmd 3 - ld (0x2AA), a ; erase cmd addr 3 - ld a, 0x30 ; erase cmd 4 - ld (0x0000), a ; erase sector address - - ld hl, 0 -.wait - bit 7, (hl) ; test DQ7 - should be 1 when complete - jr nz, .complete - bit 5, (hl) ; test DQ5 - should be 1 to continue - jr z, .wait - bit 7, (hl) ; test DQ7 again - jr z, .borked - -.complete - or 0 ; clear carry flag - ret - -.borked - scf ; carry flag = error - ret - -; F_FlashWriteByte -; Write the byte in A to the address pointed at by DE. -; On return, carry flag set = error -F_FlashWriteByte - push bc - ld c, a ; save A - - ld a, #AA ; unlock 1 - ld (0x555), a ; unlock address 1 - ld a, 0x55 ; unlock 2 - ld (0x2AA), a ; unlock address 2 - ld a, 0xA0 ; Program - ld (0x555), a ; Program address - ld a, c ; retrieve A - ld (de), a ; program it - -.wait - ld a, (de) ; read programmed address - ld b, a ; save status - xor c - bit 7, a ; If bit 7 = 0 then bit 7 = data - jr z, .byteComplete - - bit 5, b ; test DQ5 - jr z, .wait - - ld a, (de) ; read programmed address - xor c - bit 7, a ; Does DQ7 = programmed data? 0 if true - jr nz, .borked - -.byteComplete - pop bc - or 0 ; clear carry flag - ret - -.borked - pop bc - scf ; error = set carry flag - ret - diff --git a/flash/w5100config.asm b/flash/w5100config.asm deleted file mode 100644 index 398344e..0000000 --- a/flash/w5100config.asm +++ /dev/null @@ -1,39 +0,0 @@ - ; w5100config test code. - ; Set MAC addr, gateway, subnet etc. -F_w5100init - ; Page in the W5100 - ; Chip selects put RAM in area B, W5100 in area A - ld a, 0x40 ; registers are in page 0 of the W5100 - call F_setpageA ; page it into area A - - ; Perform a software reset by setting the reset flag in the MR. - ld a, MR_RST - ld (MR), a - - ; Set memory mapped mode, all options off. - xor a - ld (MR), a - - ; Copy configuration to W5100 - ld hl, CFG_gateway - ld de, GAR0 ; first byte of config. data area - ld bc, SIPR3-MR - ldir - - ; set up the socket buffers: 2k per socket buffer. - ld a, 0x55 - ld (TMSR), a - ld (RMSR), a - - ; set the IMR - ld a, %11101111 - ld (IMR), a - - ret - -; Configuration data. -CFG_gateway defb 172,16,0,1 -CFG_subnet defb 255,255,255,0 -CFG_hwaddr defb 0xAA,0x17,0x0E,0x00,0x3B,0xA6 -CFG_ipaddr defb 172,16,0,200 -STR_cfg defb "Config: ",0 diff --git a/modules/messages/msgrom.asm b/include/ctrlchars.inc similarity index 90% rename from modules/messages/msgrom.asm rename to include/ctrlchars.inc index 698d3a8..d262c69 100644 --- a/modules/messages/msgrom.asm +++ b/include/ctrlchars.inc @@ -19,9 +19,7 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - include "../../rom/spectranet.asm" - org 0x2000 - include "vectors.asm" - include "messages_en.asm" - include "getmsg.asm" + +NEWLINE equ 0x0A ; Unix style newline +ZXNEWLINE equ 0x0D ; ZX print routine newline diff --git a/rom/fs_defs.asm b/include/fcntl.inc similarity index 100% rename from rom/fs_defs.asm rename to include/fcntl.inc diff --git a/rom/flashconf.asm b/include/flashconf.inc similarity index 100% rename from rom/flashconf.asm rename to include/flashconf.inc diff --git a/rom/moduledefs.asm b/include/moduledefs.inc similarity index 100% rename from rom/moduledefs.asm rename to include/moduledefs.inc diff --git a/rom/sockdefs.asm b/include/sockdefs.inc similarity index 92% rename from rom/sockdefs.asm rename to include/sockdefs.inc index 4d4fa1e..0494b2d 100644 --- a/rom/sockdefs.asm +++ b/include/sockdefs.inc @@ -46,10 +46,8 @@ NO_RECOVERY equ 0xEE NO_ADDRESS equ 0xED DNS_TIMEOUT equ 0xEC -; Error return codes - DHCP -DHCP_NAK equ 0xCF -DHCP_OPTNOTFOUND equ 0xCE -DHCP_TIMEOUT equ 0xCD -DHCP_BAD_XID equ 0xCC -DHCP_INTERRUPTED equ 0xCB +; Socket types +SOCK_STREAM equ 0x01 +SOCK_DGRAM equ 0x02 +SOCK_RAW equ 0x03 diff --git a/rom/spectranet.asm b/include/spectranet.inc similarity index 99% rename from rom/spectranet.asm rename to include/spectranet.inc index ba8d5d8..ca56abe 100644 --- a/rom/spectranet.asm +++ b/include/spectranet.inc @@ -120,9 +120,6 @@ RESALLOC equ 0x3EED ; Definitions -SOCK_STREAM equ 1 -SOCK_DGRAM equ 2 - ALLOCFD equ 1 FREEFD equ 0 ALLOCDIRHND equ 3 diff --git a/rom/fs_statdefs.asm b/include/stat.inc similarity index 100% rename from rom/fs_statdefs.asm rename to include/stat.inc diff --git a/rom/sysdefs.asm b/include/sysdefs.inc similarity index 98% rename from rom/sysdefs.asm rename to include/sysdefs.inc index 9167606..f673df5 100644 --- a/rom/sysdefs.asm +++ b/include/sysdefs.inc @@ -58,3 +58,5 @@ RESRVD5_VECTOR equ 0x200E ; Page definitions LOWEST_PAGE equ 0xC1 +DATAROM equ 0x01 +UTILROM equ 0x02 diff --git a/include/sysvars.inc b/include/sysvars.inc new file mode 100644 index 0000000..0ff65c3 --- /dev/null +++ b/include/sysvars.inc @@ -0,0 +1,125 @@ +fs_scratchpad: equ 0x00003500 +NMISTACK: equ 0x000038FE +buf_moduleworkspace: equ 0x00003900 +TABLE_basext: equ 0x00003A00 +buf_message: equ 0x00003B00 +buf_workspace: equ 0x00003D00 +v_column: equ 0x00003F00 +v_row: equ 0x00003F01 +v_rowcount: equ 0x00003F03 +v_pr_wkspc: equ 0x00003F04 +v_pr_pga: equ 0x00003F05 +v_pga: equ 0x00003F06 +v_pgb: equ 0x00003F07 +v_utf8: equ 0x00003F08 +v_trappage: equ 0x00003F09 +v_trapaddr: equ 0x00003F0A +v_trapcomefrom: equ 0x00003F0C +v_sockptr: equ 0x00003F0E +v_copylen: equ 0x00003F10 +v_copied: equ 0x00003F12 +FDBASE: equ 0x00003F14 +v_fd1hwsock: equ 0x00003F14 +v_fd2hwsock: equ 0x00003F15 +v_fd3hwsock: equ 0x00003F16 +v_fd4hwsock: equ 0x00003F17 +v_fd5hwsock: equ 0x00003F18 +v_fd6hwsock: equ 0x00003F19 +v_fd7hwsock: equ 0x00003F1A +v_fd8hwsock: equ 0x00003F1B +v_fd9hwsock: equ 0x00003F1C +MAX_FDS: equ 0x00000005 +MAX_FD_NUMBER: equ 0x00000018 +v_lastpolled: equ 0x00003F1D +v_virtualmr: equ 0x00003F1E +v_virtualport: equ 0x00003F1F +v_workspace: equ 0x00003F21 +v_bufptr: equ 0x00003F29 +v_stringptr: equ 0x00003F2B +v_stringlen: equ 0x00003F2D +v_buf_pga: equ 0x00003F2F +v_buf_pgb: equ 0x00003F30 +v_seed: equ 0x00003F31 +v_dnsserial: equ 0x00003F33 +v_dnsfd: equ 0x00003F35 +v_fieldptr: equ 0x00003F36 +v_ansprocessed: equ 0x00003F38 +v_nameserver1: equ 0x00003F39 +v_nameserver2: equ 0x00003F3D +v_nameserver3: equ 0x00003F41 +v_nsend: equ 0x00003F45 +v_dnssockinfo: equ 0x00003F45 +v_cur_resolver: equ 0x00003F4D +v_queryresult: equ 0x00003F4F +v_querylength: equ 0x00003F51 +v_dnsretries: equ 0x00003F53 +v_dhcpfd: equ 0x00003F54 +v_dhcpsockinfo: equ 0x00003F55 +v_dhcpxid: equ 0x00003F5D +v_dhcpserver: equ 0x00003F61 +v_dhcpreqaddr: equ 0x00003F65 +v_dhcplease: equ 0x00003F69 +v_nspointer: equ 0x00003F6D +v_vfs_curmount: equ 0x00003F6F +v_vfs_dirhandle: equ 0x00003F70 +v_vfs_curfd: equ 0x00003F71 +v_trapfd: equ 0x00003F72 +v_trap_blklen: equ 0x00003F73 +v_vfs_sockinfo: equ 0x00003F75 +v_bankm: equ 0x00003F7D +v_bank678: equ 0x00003F7E +v_asave: equ 0x00003F7F +v_hlsave: equ 0x00003F80 +v_desave: equ 0x00003F82 +v_bcsave: equ 0x00003F84 +v_ixsave: equ 0x00003F86 +v_pagerws: equ 0x00003F88 +v_localport: equ 0x00003F8A +v_sockfd: equ 0x00003F8C +v_connfd: equ 0x00003F8D +v_rst8vector: equ 0x00003F8E +v_interpflags: equ 0x00003F90 +v_tabletop: equ 0x00003F91 +v_errnr_save: equ 0x00003F93 +v_chaddsave: equ 0x00003F94 +v_origpageb: equ 0x00003F96 +VFSVECBASE: equ 0x00003F97 +v_fs1page: equ 0x00003F97 +v_fs2page: equ 0x00003F98 +v_fs3page: equ 0x00003F99 +v_fs4page: equ 0x00003F9A +FDVECBASE: equ 0x00003F9B +v_fd1page: equ 0x00003F9B +v_fd2page: equ 0x00003F9C +v_fd3page: equ 0x00003F9D +v_fd4page: equ 0x00003F9E +v_fd5page: equ 0x00003F9F +v_fd6page: equ 0x00003FA0 +v_fd7page: equ 0x00003FA1 +v_fd8page: equ 0x00003FA2 +v_fd9page: equ 0x00003FA3 +VECOFFS: equ 0x00000087 +DIRVECBASE: equ 0x00003FA4 +MAX_DIRHNDS: equ 0x00000009 +v_dhnd1page: equ 0x00003FA4 +v_dhnd2page: equ 0x00003FA5 +v_dhnd3page: equ 0x00003FA6 +v_dhnd4page: equ 0x00003FA7 +v_dhnd5page: equ 0x00003FA8 +v_dhnd6page: equ 0x00003FA9 +v_dhnd7page: equ 0x00003FAA +v_dhnd8page: equ 0x00003FAB +v_dhnd9page: equ 0x00003FAC +v_mountnumber: equ 0x00003FAD +v_vfspgb_vecsave: equ 0x00003FAE +v_vfs_workspace: equ 0x00003FAF +VFSJUMP: equ 0x00003FB1 +vectors: equ 0x00003FB4 +pagealloc: equ 0x00003FD4 +ROMVECOFFS: equ 0x000000B2 +v_util_pgb: equ 0x00003FED +v_port7ffd: equ 0x00003FEE +v_border: equ 0x00003FEF +v_machinetype: equ 0x00003FF0 +v_intcount: equ 0x00003FF1 +v_configptr: equ 0x00003FF3 diff --git a/rom/zxromcalls.asm b/include/zxrom.inc similarity index 87% rename from rom/zxromcalls.asm rename to include/zxrom.inc index 70c079a..41bc8e7 100644 --- a/rom/zxromcalls.asm +++ b/include/zxrom.inc @@ -25,6 +25,8 @@ ; Disassembly", but prepended with 'ZX' so that when browsing the code ; it's immediately obvious where they come from. +CALLBAS equ 0x0010 ; Spectranet CALLBAS restart + ZX_PRINT_A_1 equ 0x0010 ; Prints a character to the current stream ZX_GET_CHAR equ 0x0018 ; The 'collect a character' restart ZX_NEXT_CHAR equ 0x0020 ; The 'collect next character' restart @@ -40,6 +42,19 @@ ZX_STMT_R_1 equ 0x1B7D ; Fetch new line number unless a further stmt ZX_STMT_NEXT equ 0x1BF4 ; Get next statement (or finish with error C) ZX_NEXT_2NUM equ 0x1C79 ; Evaluate next 2 numbers ZX_FIND_INT2 equ 0x1E99 ; Find 2 byte integer +ZX_STK_FETCH equ 0x2BF1 +ZX_EXPT_EXP equ 0x1C8C +ZX_EXPT1_NUM equ 0x1C82 +ZX_NEXT2_NUM equ 0x1C79 +ZX_FIND_INT1 equ 0x1E94 +ZX_RECLAIM_1 equ 0x19E5 +ZX_MAKE_ROOM equ 0x1655 + +; Token definitions +TOKEN_CODE equ 0xAF +TOKEN_SCREEN equ 0xAA +TOKEN_LINE equ 0xCA + ; Keyboard routines. ZX_KEY_SCAN equ 0x028E ; Finds keyboard 'scan code' diff --git a/rom/zxsysvars.asm b/include/zxsysvars.inc similarity index 100% rename from rom/zxsysvars.asm rename to include/zxsysvars.inc diff --git a/installer/Makefile b/installer/Makefile new file mode 100644 index 0000000..cb14895 --- /dev/null +++ b/installer/Makefile @@ -0,0 +1,50 @@ +INSOBJS = installer.o base.o modules.o +INSOUT = installer.bin +INSLDFLAGS = -T installer.ld -L ../syslib +INSLIBS = -lpager -lromui -lflashwrite +INSMAP = -Map installer.bin.map +INSTZX = installer.tzx + +BASEOBJS = baseinst.o base.o +BASEOUT = baseinst.bin +BASEMAP = -Map baseinst.bin.map +BASETZX = baseinst.tzx + +BASEDEPS = page0.bin page1.bin page2.bin page3.bin jumptable.bin +MODDEPS = basext.module streams.module msgrom.module config.module snapman.module + +INSTADDR = 27000 +BIN2TZX = ../utils/bin2tzx + +all: installer base basetzx instzx + +installer: $(INSOBJS) + $(LD) -o $(INSOUT) $(INSOBJS) $(INSLDFLAGS) $(INSLIBS) $(INSMAP) + +base: $(BASEOBJS) + $(LD) -o $(BASEOUT) $(BASEOBJS) $(INSLDFLAGS) $(INSLIBS) $(BASEMAP) + +tzxfiles: basetzx installtzx + +basetzx: $(BASETZX) + +instzx: $(INSTZX) + +$(BASETZX): + $(BIN2TZX) $(BASEOUT) $(BASETZX) $(INSTADDR) + +$(INSTZX): + $(BIN2TZX) $(INSOUT) $(INSTZX) $(INSTADDR) + +base.o: $(BASEDEPS) + +$(BASEDEPS): + $(MAKE) -C ../rom + +modules.o: $(MODDEPS) + +$(MODDEPS): + $(MAKE) -C ../modules + +include ../make.inc + diff --git a/rom/rommodconfig_en.asm b/installer/base.asm similarity index 67% rename from rom/rommodconfig_en.asm rename to installer/base.asm index b41a0f6..15849f1 100644 --- a/rom/rommodconfig_en.asm +++ b/installer/base.asm @@ -1,6 +1,6 @@ ;The MIT License ; -;Copyright (c) 2008 Dylan Smith +;Copyright (c) 2010 Dylan Smith ; ;Permission is hereby granted, free of charge, to any person obtaining a copy ;of this software and associated documentation files (the "Software"), to deal @@ -20,15 +20,32 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. -; ROM module utility. -; This runs from fixed workspace. It is stored in flash, but copied out -; to RAM since it has to program the flash. +; Includes the binary objects needed for the base 4 pages +.data +.globl PAGE0 +PAGE0: +.incbin "page0.bin" +.globl PAGE0LEN +PAGE0LEN: equ $-PAGE0 +.globl PAGE1 +PAGE1: +.incbin "page1.bin" +.globl PAGE1LEN +PAGE1LEN: equ $-PAGE1 +.globl PAGE2 +PAGE2: +.incbin "page2.bin" +.globl PAGE2LEN +PAGE2LEN: equ $-PAGE2 +.globl PAGE3 +PAGE3: +.incbin "page3.bin" +.globl PAGE3LEN +PAGE3LEN: equ $-PAGE3 +.globl JUMPTABLE +JUMPTABLE: +.incbin "jumptable.bin" +.globl JUMPTABLELEN +JUMPTABLELEN: equ $-JUMPTABLE - include "spectranet.asm" - org 0x3000 - include "romconfigmain.asm" - include "romconfstrings_en.asm" - include "ui_menu.asm" - include "flashwrite.asm" - include "sysvars.asm" diff --git a/installer/baseinst.asm b/installer/baseinst.asm new file mode 100644 index 0000000..6421cb0 --- /dev/null +++ b/installer/baseinst.asm @@ -0,0 +1,144 @@ +;The MIT License +; +;Copyright (c) 2010 Dylan Smith +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in +;all copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +;THE SOFTWARE. +.include "ctrlchars.inc" +.include "spectranet.inc" + +; Spectranet firmware installer. +.section main +F_main: + ld hl, 0 + add hl, sp + ld (v_stack), hl ; save stack + call F_pagein ; page in and disable interrupts + + call F_erase + call F_writepages + + jp F_exit +.text +;--------------------------- +; Erase all the sectors that we will occupy. +F_erase: + ld hl, STR_erase0 + call F_print + xor a + call F_FlashEraseSector + ret nc +.erasefail: + ld hl, STR_erasefailed + call F_print + jp F_exit + +F_writepages: + ld hl, STR_page0 + call F_print + ld a, 0x00 + call F_setpageB + ld hl, PAGE0 + ld de, 0x2000 + ld bc, PAGE0LEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_page1 + call F_print + ld a, 0x01 + call F_setpageB + ld hl, PAGE1 + ld de, 0x2000 + ld bc, PAGE1LEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_page2 + call F_print + ld a, 0x02 + call F_setpageB + ld hl, PAGE2 + ld de, 0x2000 + ld bc, PAGE2LEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_page3 + call F_print + ld a, 0x03 + call F_setpageB + ld hl, PAGE3 + ld de, 0x2000 + ld bc, PAGE3LEN + call F_FlashWriteBlock + jr c, .writefailed + + ld hl, STR_jumptable + call F_print + ld hl, JUMPTABLE + ld de, 0x2F00 + ld bc, JUMPTABLELEN + call F_FlashWriteBlock + + ret nc + +.writefailed: + ld hl, STR_writefailed + call F_print + jp F_exit + +;--------------------- +; Restore stack and leave. +F_exit: + ld sp, (v_stack) + ld bc, CTRLREG + xor a + out (c), a + ei + ret + +F_pagein: + di + ld bc, CTRLREG + ld a, 1 + out (c), a + ret + +F_print: +.loop: + ld a, (hl) + and a + ret z + call F_putc_5by8_impl + inc hl + jr .loop + +.data +STR_erase0: defb "Erasing sector 0",NEWLINE,0 +STR_erasefailed: defb "Erase failed.",NEWLINE,0 +STR_page0: defb "Writing page 0", NEWLINE,0 +STR_page1: defb "Writing page 1", NEWLINE,0 +STR_page2: defb "Writing page 2", NEWLINE,0 +STR_page3: defb "Writing page 3", NEWLINE,0 +STR_jumptable: defb "Writing jump table", NEWLINE,0 +STR_writefailed: defb "Write failed.",NEWLINE,0 + +.bss +v_stack: defw 0 + diff --git a/installer/installer.asm b/installer/installer.asm new file mode 100644 index 0000000..b439ba1 --- /dev/null +++ b/installer/installer.asm @@ -0,0 +1,210 @@ +;The MIT License +; +;Copyright (c) 2010 Dylan Smith +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in +;all copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +;THE SOFTWARE. +.include "ctrlchars.inc" +.include "spectranet.inc" + +; Spectranet firmware installer. +.section main +F_main: + ld hl, 0 + add hl, sp + ld (v_stack), hl ; save stack + call F_pagein ; page in and disable interrupts + + call F_erase + call F_writepages + + jp F_exit +.text +;--------------------------- +; Erase all the sectors that we will occupy. +F_erase: + ld hl, STR_erase0 + call F_print + xor a + call F_FlashEraseSector + jr c, .erasefail + ld hl, STR_erase1 + call F_print + ld a, 4 + call F_FlashEraseSector + jr c, .erasefail + ld hl, STR_erase2 + call F_print + ld a, 8 + call F_FlashEraseSector + ret nc +.erasefail: + ld hl, STR_erasefailed + call F_print + jp F_exit + +F_writepages: + ld hl, STR_page0 + call F_print + ld a, 0x00 + call F_setpageB + ld hl, PAGE0 + ld de, 0x2000 + ld bc, PAGE0LEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_page1 + call F_print + ld a, 0x01 + call F_setpageB + ld hl, PAGE1 + ld de, 0x2000 + ld bc, PAGE1LEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_page2 + call F_print + ld a, 0x02 + call F_setpageB + ld hl, PAGE2 + ld de, 0x2000 + ld bc, PAGE2LEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_page3 + call F_print + ld a, 0x03 + call F_setpageB + ld hl, PAGE3 + ld de, 0x2000 + ld bc, PAGE3LEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_jumptable + call F_print + ld hl, JUMPTABLE + ld de, 0x2F00 + ld bc, JUMPTABLELEN + call F_FlashWriteBlock + jp c, .writefailed + + ld hl, STR_basext + call F_print + ld a, 0x04 + call F_setpageB + ld hl, BASEXT + ld de, 0x2000 + ld bc, BASEXTLEN + call F_FlashWriteBlock + jr c, .writefailed + + ld hl, STR_streams + call F_print + ld a, 0x05 + call F_setpageB + ld hl, STREAMS + ld de, 0x2000 + ld bc, STREAMSLEN + call F_FlashWriteBlock + jr c, .writefailed + + ld hl, STR_messages + call F_print + ld a, 0x06 + call F_setpageB + ld hl, MESSAGES + ld de, 0x2000 + ld bc, MESSAGESLEN + call F_FlashWriteBlock + jr c, .writefailed + + ld hl, STR_config + call F_print + ld a, 0x07 + call F_setpageB + ld hl, CONFIG + ld de, 0x2000 + ld bc, CONFIGLEN + call F_FlashWriteBlock + jr c, .writefailed + + ld hl, STR_snapman + call F_print + ld a, 0x08 + call F_setpageB + ld hl, SNAPMAN + ld de, 0x2000 + ld bc, SNAPMANLEN + call F_FlashWriteBlock + ret nc + +.writefailed: + ld hl, STR_writefailed + call F_print + jp F_exit + +;--------------------- +; Restore stack and leave. +F_exit: + ld sp, (v_stack) + ld bc, CTRLREG + xor a + out (c), a + ei + ret + +F_pagein: + di + ld bc, CTRLREG + ld a, 1 + out (c), a + ret + +F_print: +.loop: + ld a, (hl) + and a + ret z + call F_putc_5by8_impl + inc hl + jr .loop + +.data +STR_erase0: defb "Erasing sector 0",NEWLINE,0 +STR_erase1: defb "Erasing sector 1",NEWLINE,0 +STR_erase2: defb "Erasing sector 2",NEWLINE,0 +STR_erasefailed: defb "Erase failed.",NEWLINE,0 +STR_page0: defb "Writing page 0", NEWLINE,0 +STR_page1: defb "Writing page 1", NEWLINE,0 +STR_page2: defb "Writing page 2", NEWLINE,0 +STR_page3: defb "Writing page 3", NEWLINE,0 +STR_jumptable: defb "Writing jump table", NEWLINE,0 +STR_basext: defb "Adding basext module",NEWLINE,0 +STR_streams: defb "Adding streams module", NEWLINE,0 +STR_messages: defb "Adding messages module",NEWLINE,0 +STR_config: defb "Adding config module",NEWLINE,0 +STR_snapman: defb "Adding snapman module",NEWLINE,0 +STR_writefailed: defb "Write failed.",NEWLINE,0 + +.bss +v_stack: defw 0 + diff --git a/installer/installer.ld b/installer/installer.ld new file mode 100644 index 0000000..e1992c9 --- /dev/null +++ b/installer/installer.ld @@ -0,0 +1,39 @@ +/* Spectranet modules LD script */ +OUTPUT_FORMAT("binary") +OUTPUT_ARCH("z80") +MEMORY { + main : ORIGIN = 27000, LENGTH = 0x0080 + lut : ORIGIN = 0x6A00, LENGTH = 0x002C + installer : ORIGIN = 0x6A2D, LENGTH = 0xFFFF-0x6A2D +} +SECTIONS +{ +.main : { + *(.main) + *(main) + __Hmain = .; + } > main +.lookup : { + *(.lookup) + *(lookup) + __Hlookup = .; + } > lut +.text : { + *(.text) + *(text) + __Htext = .; + } > installer +.data : { + __Ldata = .; + *(.data) + *(data) + __Hdata = .; + } > installer +.bss : { + __Lbss = .; + *(.bss) + *(bss) + __Hbss = .; + } > installer +} + diff --git a/rom/rommodconfig_es.asm b/installer/modules.asm similarity index 66% rename from rom/rommodconfig_es.asm rename to installer/modules.asm index 3416fce..6abfa3f 100644 --- a/rom/rommodconfig_es.asm +++ b/installer/modules.asm @@ -1,6 +1,6 @@ ;The MIT License ; -;Copyright (c) 2008 Dylan Smith +;Copyright (c) 2010 Dylan Smith ; ;Permission is hereby granted, free of charge, to any person obtaining a copy ;of this software and associated documentation files (the "Software"), to deal @@ -20,15 +20,31 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. -; ROM module utility. -; This runs from fixed workspace. It is stored in flash, but copied out -; to RAM since it has to program the flash. - - include "spectranet.asm" - org 0x3000 - include "romconfigmain.asm" - include "romconfstrings_es.asm" - include "ui_menu.asm" - include "flashwrite.asm" - include "sysvars.asm" +; Incldes the binary objects for the modules. +.data +.globl BASEXT +BASEXT: +.incbin "basext.module" +.globl BASEXTLEN +BASEXTLEN: equ $-BASEXT +.globl STREAMS +STREAMS: +.incbin "streams.module" +.globl STREAMSLEN +STREAMSLEN: equ $-STREAMS +.globl MESSAGES +MESSAGES: +.incbin "msgrom.module" +.globl MESSAGESLEN +MESSAGESLEN: equ $-MESSAGES +.globl CONFIG +CONFIG: +.incbin "config.module" +.globl CONFIGLEN +CONFIGLEN: equ $-CONFIG +.globl SNAPMAN +SNAPMAN: +.incbin "snapman.module" +.globl SNAPMANLEN +SNAPMANLEN: equ $-SNAPMAN diff --git a/make.inc b/make.inc new file mode 100644 index 0000000..2929c50 --- /dev/null +++ b/make.inc @@ -0,0 +1,14 @@ +AS = z80-unknown-coff-as +LD = z80-unknown-coff-ld +RM = rm +ASFLAGS = -I../include +MAPFILE = $(OUT).map + +.PHONY: clean + +%.o : %.asm + $(AS) $(ASFLAGS) $< -o $@ + +clean: + $(RM) -f *.o *.module *.bin *.map *.xinc *.tzx + diff --git a/modules/Makefile b/modules/Makefile new file mode 100644 index 0000000..61523e8 --- /dev/null +++ b/modules/Makefile @@ -0,0 +1,16 @@ +SUBDIRS = snapman messages config basext streams + +.PHONY: subdirs $(SUBDIRS) + +.PHONY: clean + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) -C $@ + +clean: + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean; \ + done + diff --git a/modules/basext/Makefile b/modules/basext/Makefile new file mode 100644 index 0000000..b6ab04d --- /dev/null +++ b/modules/basext/Makefile @@ -0,0 +1,4 @@ +ASOBJS = boot.o commands.o info.o init.o listdir.o loader.o parseurl.o strings_en.o tapetrap.o vectors.o +OUT = basext.module +include ../make.inc + diff --git a/modules/basext/boot.asm b/modules/basext/boot.asm index 1b79bd7..5688bc8 100644 --- a/modules/basext/boot.asm +++ b/modules/basext/boot.asm @@ -21,21 +21,30 @@ ;THE SOFTWARE. ; Handles post-BASIC initialization, allowing the machine to boot -; from a file named boot.zx. +; from a file named boot.zx0. ; ; This routine does the following: -; If SHIFT is held, it tries to load 'boot.zx' off the currently +; If SHIFT is held, it tries to load 'boot.zx0' off the currently ; mounted filesystem, using the normal BASIC loader that is contained ; in this module. The return stack is altered such that everything is ; skipped (the (c) message, entry into the editor etc) up to the point -; where lines get interpreted. If 'boot.zx' is loaded and was saved +; where lines get interpreted. If 'boot.zx0' is loaded and was saved ; with a LINE parameter, this line is jumped to (by putting CONTINUE ; into the interpreter and setting OLDPPC to NEWPPC). If the LINE ; parameter was not used, the BASIC program loaded is listed. ; ; On error, the stack is restored back to its original state such that ; we re-enter BASIC at the point the (c) message is generated. -F_boot +.include "spectranet.inc" +.include "defs.inc" +.include "sysvars.inc" +.include "zxrom.inc" +.include "zxsysvars.inc" +.include "ctrlchars.inc" +.include "../config/config_interface.inc" +.text +.globl F_boot +F_boot: call F_shouldboot ; set zero flag if we should boot ret nz ; no, do nothing. ld hl, STR_bootmsg @@ -64,25 +73,25 @@ F_boot ld hl, INTERPWKSPC xor a ; file type = 0 (BASIC) call F_tbas_loader ; Try to load the file - jr c, .err ; leave here if the loader had an error + jr c, .err1 ; leave here if the loader had an error ld hl, (ZX_NEWPPC) ; get the value of NEWPPC ld a, h ; Is NEWPPC unset? or l - jr z, .leave + jr z, .leave1 ld (ZX_OLDPPC), hl ; Put in OLDPPC so 'CONTINUE' jumps ld a, 0xE8 ; keyword 'CONTINUE' rst CALLBAS defw 0x0F81 ; ADD-CHAR - ld a, '\n' + ld a, NEWLINE rst CALLBAS defw 0x0F81 -.leave +.leave1: pop hl ; get NMI stack pointer ld sp, hl ; and restore it ret -.err +.err1: pop hl ; get NMI stack pointer pop de ; now restore return address ld de, 0x1299 @@ -96,27 +105,29 @@ F_boot ; F_shouldboot: See if we should boot (either configured to do so or ; SHIFT is pressed down) Zero flag is set if we should boot, non zero ; return if not. -F_shouldboot +.globl F_shouldboot +F_shouldboot: ld de, ROM_ID ; section ID ld hl, CFG_FINDSECTION ; go and find it rst MODULECALL_NOPAGE - jr c, .bootonshift ; we don't have a section, jump forward. + jr c, .bootonshift2 ; we don't have a section, jump forward. ld a, AUTOBOOT ; get 'autoboot' option ld hl, CFG_GETCFBYTE rst MODULECALL_NOPAGE - jr c, .bootonshift ; not found, take no action + jr c, .bootonshift2 ; not found, take no action and a ; if set to zero, then don't autoboot - jr z, .bootonshift + jr z, .bootonshift2 xor a ; set the zero flag to signal 'boot' ret -.bootonshift +.bootonshift2: ld bc, 0xFEFE ; read SHIFT through V in a, (c) cp 0xBE ; SHIFT pressed? ret - -STR_bootmsg defb "Booting...\n",0 -STR_loaderr defb "Error loading boot.zx\n",0 + +.data +STR_bootmsg: defb "Booting...",NEWLINE,0 +STR_loaderr: defb "Error loading boot.zx",NEWLINE,0 diff --git a/modules/basext/build b/modules/basext/build deleted file mode 100755 index fca94dc..0000000 --- a/modules/basext/build +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -echo `pwd`/basext.out >> ../../build.out -sjasmplus basext.asm --lst=basext.lst -exit $? - diff --git a/modules/basext/commands.asm b/modules/basext/commands.asm index 8412ada..f74c8c4 100644 --- a/modules/basext/commands.asm +++ b/modules/basext/commands.asm @@ -21,13 +21,19 @@ ;THE SOFTWARE. ; TNFS BASIC extensions - include "../../rom/zxromdefs.asm" - +.include "zxrom.inc" +.include "spectranet.inc" +.include "defs.inc" +.include "fcntl.inc" +.include "sysvars.inc" +.include "zxsysvars.inc" +.text ;--------------------------------------------------------------------------- ; F_tbas_mount ; BASIC interpreter for "mount" ; Syntax: %mount mountpoint, "url" -F_tbas_mount +.globl F_tbas_mount +F_tbas_mount: ; Syntax and runtime rst CALLBAS defw ZX_EXPT1_NUM @@ -55,35 +61,36 @@ F_tbas_mount ld ix, INTERPWKSPC ; where to place the mount struct ld hl, INTERPWKSPC+10 ; location of the string to parse call F_parseurl - jr c, .badurl + jr c, .badurl1 rst CALLBAS ; fetch the mount point defw ZX_FIND_INT2 -.mount +.mount1: ld a, c ; mount point in BC call MOUNT jp c, J_tbas_error ; display the error message jp EXIT_SUCCESS -.badurl +.badurl1: ld a, EBADURL jp J_tbas_error ; Copy a BASIC string to a C string. ; BASIC string in DE, C string (dest) in HL -F_basstrcpy +.globl F_basstrcpy +F_basstrcpy: ld a, b ; end of string? or c - jr z, .terminate + jr z, .terminate2 ld a, (de) ld (hl), a inc hl inc de dec bc jr F_basstrcpy -.terminate +.terminate2: xor a ; put the null on the end ld (hl), a inc hl @@ -92,7 +99,8 @@ F_basstrcpy ;---------------------------------------------------------------------------- ; F_tbas_umount ; Umount the mounted filesystem. -F_tbas_umount +.globl F_tbas_umount +F_tbas_umount: rst CALLBAS defw ZX_EXPT1_NUM ; 1 parameter - mount point number call STATEMENT_END @@ -108,7 +116,8 @@ F_tbas_umount ;---------------------------------------------------------------------------- ; F_tbas_chdir ; Handle changing directory -F_tbas_chdir +.globl F_tbas_chdir +F_tbas_chdir: rst CALLBAS defw ZX_EXPT_EXP ; expect a string expression call STATEMENT_END @@ -127,7 +136,8 @@ F_tbas_chdir ; F_tbas_aload: Loads an arbitary file from the TNFS filesystem. ; The syntax is %aload "filename" CODE address. This allows the user ; to load an arbitrary file with no ZX formatting into memory. -F_tbas_aload +.globl F_tbas_aload +F_tbas_aload: rst CALLBAS defw ZX_EXPT_EXP ; expect a string expression cp TOKEN_CODE ; expect CODE @@ -158,31 +168,32 @@ F_tbas_aload ; F_tbas_load: Loads a ZX file (BASIC, CODE etc.) ; The syntax is as for ZX BASIC LOAD, except %load. ; TODO: CODE et al. -F_tbas_load +.globl F_tbas_load +F_tbas_load: rst CALLBAS defw ZX_EXPT_EXP ; expect a string expression cp TOKEN_CODE ; Check for CODE... - jr z, .loadcode + jr z, .loadcode6 call STATEMENT_END ; If not, statment end for BASIC. ;------ runtime for BASIC ------ xor a ; type 0x00 is BASIC -.loader +.loader6: push af ; save type rst CALLBAS defw ZX_STK_FETCH ; fetch the filename ld a, b ; check for empty string or c - jr nz, .havefilename + jr nz, .havefilename6 ld hl, STR_BOOTDOTZX ld de, INTERPWKSPC ld bc, STR_BOOTDOTZXLEN ldir - jr .loadbasic -.havefilename + jr .loadbasic6 +.havefilename6: ld hl, INTERPWKSPC call F_basstrcpy ; copy + convert to C string -.loadbasic +.loadbasic6: ; Now call the loader routine with the filename in HL ld hl, INTERPWKSPC pop af ; get type id @@ -190,7 +201,7 @@ F_tbas_load jp c, J_tbas_error jp EXIT_SUCCESS -.loadcode +.loadcode6: ; TODO - code to a specific address. rst CALLBAS defw ZX_NEXT_CHAR @@ -198,21 +209,22 @@ F_tbas_load ;------ runtime for CODE with no addr ------- ld a, 3 ; type=CODE - jr .loader ; get the filename then load. + jr .loader6 ; get the filename then load. ;---------------------------------------------------------------------------- ; F_tbas_save: Save a ZX file (BASIC, CODE etc.) ; The syntax is as for ZX BASIC SAVE. ; TODO: CODE et al. -F_tbas_save +.globl F_tbas_save +F_tbas_save: rst CALLBAS defw ZX_EXPT_EXP ; fetch the file name cp TOKEN_CODE ; for CODE - jr z, .savecode + jr z, .savecode7 cp TOKEN_SCREEN ; for SCREEN$ - jr z, .savescreen + jr z, .savescreen7 cp TOKEN_LINE ; then for LINE - jr z, .savebasline + jr z, .savebasline7 call STATEMENT_END ; a basic BASIC save. @@ -225,10 +237,10 @@ F_tbas_save call F_tbas_mktapheader ld hl, 0xFFFF ; set param1 to >32767 ld (INTERPWKSPC+OFFSET_PARAM1), hl - jr .makebasicblock + jr .makebasicblock7 ; Deal with SAVE "filename" CODE -.savecode +.savecode7: rst CALLBAS defw ZX_NEXT2_NUM ; check for 2 numbers call STATEMENT_END ; then end of command. @@ -240,7 +252,7 @@ F_tbas_save rst CALLBAS defw ZX_FIND_INT2 ; and the start push bc ; and save that, too -.savecodemain +.savecodemain7: rst CALLBAS defw ZX_STK_FETCH ; and get the filename ld a, 3 ; type = 3 - CODE @@ -253,7 +265,7 @@ F_tbas_save jp c, J_tbas_error jp EXIT_SUCCESS -.savescreen +.savescreen7: rst CALLBAS defw ZX_NEXT_CHAR ; advance to the end of the line call STATEMENT_END @@ -263,9 +275,9 @@ F_tbas_save push hl ; on the stack ld hl, 16384 ; followed by the start address push hl - jr .savecodemain ; and do as for CODE + jr .savecodemain7 ; and do as for CODE -.savebasline +.savebasline7: rst CALLBAS defw ZX_NEXT_CHAR rst CALLBAS @@ -284,7 +296,7 @@ F_tbas_save call F_tbas_mktapheader ; Create the header ld hl, (v_bcsave) ; get LINE parameter ld (INTERPWKSPC+OFFSET_PARAM1), hl ; Put it into parameter 1 -.makebasicblock +.makebasicblock7: ; Fill in the header, length and length without vars ld hl, (ZX_E_LINE) ; get the length of the BASIC prog @@ -305,11 +317,12 @@ F_tbas_save ; F_tbas_ls ; List a directory ; Two forms - either %cat or %cat "directory" -F_tbas_ls +.globl F_tbas_ls +F_tbas_ls: cp 0x0d - jr z, .noargs + jr z, .noargs8 cp ':' - jr z, .noargs + jr z, .noargs8 ; we have an argument supplied. rst CALLBAS @@ -324,7 +337,7 @@ F_tbas_ls ld hl, INTERPWKSPC jp F_listdir -.noargs +.noargs8: call STATEMENT_END ; --------- runtime ---------- @@ -333,13 +346,14 @@ F_tbas_ls xor a ld (INTERPWKSPC+1), a ld hl, INTERPWKSPC -.makecat +.makecat8: jp F_listdir ;--------------------------------------------------------------------------- ; F_tbas_tapein ; Handle the %tapein command, which takes a filename as a parameter. -F_tbas_tapein +.globl F_tbas_tapein +F_tbas_tapein: rst CALLBAS defw ZX_EXPT_EXP ; expect a string expression call STATEMENT_END @@ -354,7 +368,8 @@ F_tbas_tapein ;---------------------------------------------------------------------------- ; F_tbas_info ; Handle the %info command -F_tbas_info +.globl F_tbas_info +F_tbas_info: rst CALLBAS defw ZX_EXPT_EXP ; expect a string call STATEMENT_END @@ -369,7 +384,8 @@ F_tbas_info ;---------------------------------------------------------------------------- ; F_tbas_fs ; Sets the current filesystem. -F_tbas_fs +.globl F_tbas_fs +F_tbas_fs: rst CALLBAS defw ZX_EXPT1_NUM ; expect one number - the FS number call STATEMENT_END @@ -386,7 +402,8 @@ F_tbas_fs ;---------------------------------------------------------------------------- ; F_loadsnap ; Loads a snapshot file. -F_loadsnap +.globl F_loadsnap +F_loadsnap: rst CALLBAS defw ZX_EXPT_EXP ; filename string call STATEMENT_END @@ -404,7 +421,8 @@ F_loadsnap ;---------------------------------------------------------------------------- ; F_tbas_mv ; Moves (renames) a file. -F_tbas_mv +.globl F_tbas_mv +F_tbas_mv: rst CALLBAS defw ZX_EXPT_EXP ; source filename cp ',' ; and a comma @@ -433,7 +451,8 @@ F_tbas_mv ;--------------------------------------------------------------------------- ; F_tbas_rm: Removes a file -F_tbas_rm +.globl F_tbas_rm +F_tbas_rm: rst CALLBAS defw ZX_EXPT_EXP ; file to remove call STATEMENT_END @@ -452,7 +471,8 @@ F_tbas_rm ; F_tbas_zxprint ; Prints a C string to the current ZX channel ; HL = pointer to string -F_tbas_zxprint +.globl F_tbas_zxprint +F_tbas_zxprint: ld a, (hl) and a ret z @@ -464,7 +484,8 @@ F_tbas_zxprint ;---------------------------------------------------------------------------- ; handle errors and return control to BASIC. ; A=tnfs error number -J_tbas_error +.globl J_tbas_error +J_tbas_error: push af ; save error number call F_geterrstr ; get the error string pop af @@ -474,7 +495,8 @@ J_tbas_error ; F_tnfs_geterrstr ; Enter with A=error number ; Exits with HL=pointer to null terminated error string -F_geterrstr +.globl F_geterrstr +F_geterrstr: ld h, 0xFC ; ID of messages module ld l, a ; Set the message ID to fetch ld de, 0x3000 ; buffer @@ -483,11 +505,15 @@ F_geterrstr rst MODULECALL_NOPAGE ld hl, 0x3000 ; address of the message ret +.data +.globl STR_BOOTDOTZX +.globl STR_BOOTDOTZXLEN +STR_proto: defb "tnfs",0 +STR_BOOTDOTZX: defb "boot.zx",0 +STR_BOOTDOTZXEND: -STR_proto defb "tnfs",0 -STR_BOOTDOTZX defb "boot.zx",0 -STR_BOOTDOTZXLEN equ $-STR_BOOTDOTZX +STR_BOOTDOTZXLEN equ STR_BOOTDOTZXEND-STR_BOOTDOTZX -EBADURL equ 0x28 -EBADFS equ 0x29 +EBADURL: equ 0x28 +EBADFS: equ 0x29 diff --git a/modules/basext/defs.asm b/modules/basext/defs.inc similarity index 97% rename from modules/basext/defs.asm rename to modules/basext/defs.inc index 5ddae66..9017a85 100644 --- a/modules/basext/defs.asm +++ b/modules/basext/defs.inc @@ -33,4 +33,6 @@ STACK_DE equ NMISTACK-8 STACK_HL equ NMISTACK-6 AUTOBOOT equ 0x81 ; Config ID for autoboot flag +ROM_ID equ 0xFD +INTERPWKSPC equ 0x3000 diff --git a/modules/basext/info.asm b/modules/basext/info.asm index 3a66bf3..ab1e6ba 100644 --- a/modules/basext/info.asm +++ b/modules/basext/info.asm @@ -21,11 +21,17 @@ ;THE SOFTWARE. ; Routines for the %info command. - +.include "defs.inc" +.include "zxrom.inc" +.include "spectranet.inc" +.include "fcntl.inc" +.include "sysvars.inc" +.text ;--------------------------------------------------------------------------- ; F_showfileinfo ; Shows information on a file. -F_showfileinfo +.globl F_showfileinfo +F_showfileinfo: ld hl, INTERPWKSPC call F_basstrcpy ; prepare BASIC string for use @@ -36,16 +42,16 @@ F_showfileinfo ld a, (INTERPWKSPC+256+1) ; get file type flags bit 7, a ; test for regular file - jr nz, .rfinfo + jr nz, .rfinfo1 bit 6, a ; test for directory - jp nz, .dirinfo + jp nz, .dirinfo1 - ld a, 0x26 ; Unknown file type - TODO - errno.asm + ld a, 0x26 ; Unknown file type - TODO - errno.asm1 scf ret -.rfinfo +.rfinfo1: ld a, 2 rst CALLBAS defw 0x1601 ; set channel @@ -71,45 +77,45 @@ F_showfileinfo ret c ; failed top open the file! ld (v_vfs_curfd), a ; save the FD -.gethdrinfo +.gethdrinfo1: ld de, INTERPWKSPC ; we no longer need the filename call F_tbas_getheader - jr c, .nottap ; Not a TAP file (or an error) - call .hdrinfo + jr c, .nottap1 ; Not a TAP file (or an error) + call .hdrinfo1 ; At this point we list any remaining blocks, some of which may ; lack normal headers, so we have to do it in a new block of code. ; Seek forward past the data block and try to analyze the rest ; of the TAP file. -.getblocks +.getblocks1: ld de, INTERPWKSPC ld bc, 2 ; read the length value ld a, (v_vfs_curfd) call READ - jr c, .cleanuperr ; shouldn't die here. + jr c, .cleanuperr1 ; shouldn't die here. ld hl, (INTERPWKSPC) ; get the length of the block -.seeknextblock +.seeknextblock1: ld de, 0 ; and make dehl = 32 bit version of it ld a, (v_vfs_curfd) ld c, SEEK_CUR ; and seek forwards that many bytes call LSEEK - jr c, .cleanuperr + jr c, .cleanuperr1 ld de, INTERPWKSPC ; see if we've got another header call F_tbas_getheader - jr nc, .disphdr + jr nc, .disphdr1 cp TBADLENGTH - jr z, .dispnonhdr ; suspected headerless block + jr z, .dispnonhdr1 ; suspected headerless block cp TBADTYPE - jr z, .dispnonhdr + jr z, .dispnonhdr1 cp EOF ; reached end of file? - jr z, .done -.disphdr - call .hdrinfo ; show the header information - jr .getblocks + jr z, .done1 +.disphdr1: + call .hdrinfo1 ; show the header information + jr .getblocks1 -.dispnonhdr +.dispnonhdr1: ld hl, STR_headerless ; print "Headerless block" call F_tbas_zxprint ld de, 0 ; most significant word is always 0 @@ -123,30 +129,30 @@ F_showfileinfo ld hl, (INTERPWKSPC) ld de, TNFS_HDR_LEN-2 ; already read this much, subtract from sbc hl, de ; the block size. TODO: block sizes - jr .seeknextblock ; smaller than a standard header! + jr .seeknextblock1 ; smaller than a standard header! -.done +.done1: ld a, (v_vfs_curfd) call VCLOSE ret -.nottap +.nottap1: cp TBADLENGTH - jr z, .data + jr z, .data1 cp TBADTYPE - jr z, .data -.cleanuperr + jr z, .data1 +.cleanuperr1: push af ; store original error ld a, (v_vfs_curfd) call CLOSE pop af ret -.data +.data1: ld hl, STR_data call F_tbas_zxprint call F_lf - jr .done + jr .done1 -.dirinfo +.dirinfo1: ld a, 2 rst CALLBAS defw 0x1601 ; set channel @@ -165,26 +171,26 @@ F_showfileinfo ret ; A should be the block type as returned by getheader -.hdrinfo +.hdrinfo1: and a - jr z, .program + jr z, .program1 cp 1 - jr z, .numarray + jr z, .numarray1 cp 2 - jr z, .strarray + jr z, .strarray1 cp 3 - jr z, .code + jr z, .code1 ld hl, STR_unknown call F_tbas_zxprint -.continue +.continue1: ld hl, INTERPWKSPC+4 ; Filename in the TAP block ld b, 10 -.fnloop ; Print the filename of this TAP block +.fnloop1: ; Print the filename of this TAP block ld a, (hl) rst CALLBAS defw 16 inc hl - djnz .fnloop + djnz .fnloop1 call F_lf ld hl, STR_blksize @@ -209,24 +215,25 @@ F_showfileinfo call F_lf ret -.program +.program1: ld hl, STR_basic - jr .pr -.numarray + jr .pr1 +.numarray1: ld hl, STR_numarray - jr .pr -.strarray + jr .pr1 +.strarray1: ld hl, STR_strarray - jr .pr -.code + jr .pr1 +.code1: ld hl, STR_code -.pr +.pr1: call F_tbas_zxprint - jr .continue + jr .continue1 ; F_lf: Print an "enter" -F_lf +.globl F_lf +F_lf: ld a, 0x0d rst CALLBAS defw 16 @@ -236,10 +243,11 @@ F_lf ; F_print32 ; Converts the 32 bit value in DEHL to ASCII and displays it on the ; current ZX channel. -F_print32 +.globl F_print32 +F_print32: ld ix, INTERPWKSPC+512 ld (ix), 0 -.divloop +.divloop3: inc ix ld c, 10 call F_div32 @@ -249,21 +257,22 @@ F_print32 or l ; has DEHL reached 0? or d or e - jr nz, .divloop -.loop + jr nz, .divloop3 +.loop3: ld a, (ix) and a ret z rst CALLBAS defw 16 dec ix - jr .loop + jr .loop3 ; Modified version of baze's 32 bit divide routine -F_div32 +.globl F_div32 +F_div32: xor a ld b, 32 -.loop +.loop4: add hl,hl rl e rl d @@ -272,6 +281,6 @@ F_div32 jr c,$+4 sub c inc l - djnz .loop + djnz .loop4 ret diff --git a/modules/basext/init.asm b/modules/basext/init.asm index ed8e724..479e529 100644 --- a/modules/basext/init.asm +++ b/modules/basext/init.asm @@ -19,10 +19,15 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "spectranet.inc" +.include "defs.inc" +.include "zxrom.inc" +.include "ctrlchars.inc" +.text ;------------------------------------------------------------------------ ; F_init: Initializes the interpreter -F_init +.globl F_init +F_init: ; force USR 0 mode on 128K machines (due to +2a/+3 BASIC ; incompatibilities) ld bc, 0x7FFD @@ -33,12 +38,12 @@ F_init out (c), a ld hl, PARSETABLE ld b, NUMCMDS -.loop +.loop1: push bc call ADDBASICEXT pop bc - jr c, .installerror - djnz .loop + jr c, .installerror1 + djnz .loop1 ; Install the default LOAD "" trap. call F_initbootfile @@ -46,79 +51,80 @@ F_init ld hl, STR_basicinit call PRINT42 ret -.installerror +.installerror1: ld hl, STR_basinsterr call PRINT42 ret -STR_basicinit defb "BASIC extensions installed\n",0 -STR_basinsterr defb "Failed to install BASIC extensions\n",0 +.data +STR_basicinit: defb "BASIC extensions installed",NEWLINE,0 +STR_basinsterr: defb "Failed to install BASIC extensions",NEWLINE,0 -NUMCMDS equ 13 -PARSETABLE -P_mount defb 0x0b +NUMCMDS: equ 13 +PARSETABLE: +P_mount: defb 0x0b defw CMD_MOUNT - defb TNFS_PAGE + defb 0xFF defw F_tbas_mount ; Mount routine -P_umount defb 0x0b +P_umount: defb 0x0b defw CMD_UMOUNT - defb TNFS_PAGE + defb 0xFF defw F_tbas_umount ; Umount routine -P_chdir defb 0x0b +P_chdir: defb 0x0b defw CMD_CHDIR - defb TNFS_PAGE + defb 0xFF defw F_tbas_chdir ; Chdir routine -P_cat defb 0x0b +P_cat: defb 0x0b defw CMD_LS ; Display a directory - defb TNFS_PAGE + defb 0xFF defw F_tbas_ls -P_aload defb 0x0b +P_aload: defb 0x0b defw CMD_ALOAD ; Arbitrary load - defb TNFS_PAGE + defb 0xFF defw F_tbas_aload -P_load defb 0x0b +P_load: defb 0x0b defw CMD_LOAD ; Standard LOAD command - defb TNFS_PAGE + defb 0xFF defw F_tbas_load -P_save defb 0x0b +P_save: defb 0x0b defw CMD_SAVE ; Standard SAVE command - defb TNFS_PAGE + defb 0xFF defw F_tbas_save -P_tapein defb 0x0b +P_tapein: defb 0x0b defw CMD_TAPEIN ; Set up a tape trap for a TAP file - defb TNFS_PAGE + defb 0xFF defw F_tbas_tapein -P_info defb 0x0b +P_info: defb 0x0b defw CMD_INFO ; Give information on a file - defb TNFS_PAGE + defb 0xFF defw F_tbas_info -P_fs defb 0x0b +P_fs: defb 0x0b defw CMD_FS - defb TNFS_PAGE + defb 0xFF defw F_tbas_fs -P_loadsnap defb 0x0b +P_loadsnap: defb 0x0b defw CMD_LOADSNAP - defb TNFS_PAGE + defb 0xFF defw F_loadsnap -P_mv defb 0x0b +P_mv: defb 0x0b defw CMD_MV ; Rename a file - defb TNFS_PAGE + defb 0xFF defw F_tbas_mv -P_rm defb 0x0b +P_rm: defb 0x0b defw CMD_RM ; Remove a file - defb TNFS_PAGE + defb 0xFF defw F_tbas_rm -CMD_MOUNT defb "%mount",0 -CMD_UMOUNT defb "%umount",0 -CMD_CHDIR defb "%cd",0 -CMD_LS defb "%cat",0 -CMD_ALOAD defb "%aload",0 -CMD_LOAD defb "%load",0 -CMD_SAVE defb "%save",0 -CMD_TAPEIN defb "%tapein",0 -CMD_INFO defb "%info",0 -CMD_FS defb "%fs",0 -CMD_LOADSNAP defb "%loadsnap",0 -CMD_MV defb "%mv",0 -CMD_RM defb "%rm",0 +CMD_MOUNT: defb "%mount",0 +CMD_UMOUNT: defb "%umount",0 +CMD_CHDIR: defb "%cd",0 +CMD_LS: defb "%cat",0 +CMD_ALOAD: defb "%aload",0 +CMD_LOAD: defb "%load",0 +CMD_SAVE: defb "%save",0 +CMD_TAPEIN: defb "%tapein",0 +CMD_INFO: defb "%info",0 +CMD_FS: defb "%fs",0 +CMD_LOADSNAP: defb "%loadsnap",0 +CMD_MV: defb "%mv",0 +CMD_RM: defb "%rm",0 diff --git a/modules/basext/listdir.asm b/modules/basext/listdir.asm index 9c6c3af..d3c2cb4 100644 --- a/modules/basext/listdir.asm +++ b/modules/basext/listdir.asm @@ -19,30 +19,37 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "stat.inc" +.include "fcntl.inc" +.include "spectranet.inc" +.include "defs.inc" +.include "zxrom.inc" +.include "ctrlchars.inc" +.include "sysvars.inc" +.text -; Routine that lists directories. - include "../../rom/fs_statdefs.asm" ; Show the directory listing. HL = directory to open. -F_listdir +.globl F_listdir +F_listdir: call OPENDIR ; open the directory jp c, J_tbas_error ld (v_vfs_dirhandle), a ; save the directory handle ld a, 2 rst CALLBAS ; set channel to 2 defw 0x1601 -.catloop +.catloop1: ld a, (v_vfs_dirhandle) ; get the dir handle back ld de, INTERPWKSPC ; location for result call READDIR ; read dir - jr c, .readdone ; read is probably at EOF + jr c, .readdone1 ; read is probably at EOF call F_statentry ; show some information about it ld hl, INTERPWKSPC call F_tbas_zxprint ; print a C string to #2 - ld a, '\r' ; newline + ld a, ZXNEWLINE ; newline rst CALLBAS defw 0x10 - jr .catloop -.readdone + jr .catloop1 +.readdone1: push af ; save error code while ld a, (v_vfs_dirhandle) ; we close the dir handle call CLOSEDIR @@ -54,56 +61,58 @@ F_listdir jp EXIT_SUCCESS ; Expects the filename to be in INTERPWKSPC -F_statentry +.globl F_statentry +F_statentry: ld hl, INTERPWKSPC ld de, INTERPWKSPC+256 ; where to put the data call STAT - jr c, .staterr + jr c, .staterr2 ld ix, INTERPWKSPC+256 ld a, (ix+(STAT_MODE+1)) ; Check file mode MSB and S_IFDIR / 256 ; check directory flag - jr z, .isfile + jr z, .isfile2 ld hl, STR_dir call F_tbas_zxprint - jr .continue -.isfile + jr .continue2 +.isfile2: call F_showsize ld a, ' ' rst CALLBAS defw 0x0010 -.continue +.continue2: ret -.staterr +.staterr2: ld hl, STR_staterr jp F_tbas_zxprint ; print it and return. -STR_staterr defb " Err ",0 -STR_dir defb " Dir ",0 +STR_staterr: defb " Err ",0 +STR_dir: defb " Dir ",0 ;---------------------------------------------------------------------- ; F_showsize ; Create a 4 digit decimal with the correct ending (b, k, M or G) ; TODO: This routine is particularly naive and hardly optimized ; for space (or anything else). (Low priority TODO). -F_showsize +.globl F_showsize +F_showsize: ld a, (ix+(STAT_SIZE+3)) ; MSB of size ld b, a and 0xC0 ; >= 2^30 - jr nz, .gigs + jr nz, .gigs3 cpl ; check lower half and b ; of 4th stat byte for megs - jr nz, .megs + jr nz, .megs3 ld a, (ix+(STAT_SIZE+2)) ld b, a and 0xF0 ; >= 2^20 - jr nz, .megs + jr nz, .megs3 cpl ; check lower half of and b ; 3rd stat byte for kilos - jr nz, .kilos + jr nz, .kilos3 ld a, (ix+(STAT_SIZE+1)) and 0xFC ; >= 2^10 - jr nz, .kilos + jr nz, .kilos3 ld l, (ix+STAT_SIZE) ; less than 1K ld h, (ix+(STAT_SIZE+1)) call F_decimal @@ -111,7 +120,7 @@ F_showsize rst CALLBAS defw 0x0010 ret -.kilos +.kilos3: ld l, (ix+(STAT_SIZE+1)) ; 1K to 1023K ld h, (ix+(STAT_SIZE+2)) srl h @@ -123,26 +132,26 @@ F_showsize rst CALLBAS defw 0x0010 ret -.megs +.megs3: ld l, (ix+(STAT_SIZE+2)) ; 1M to 1023M ld h, (ix+(STAT_SIZE+3)) ld b, 4 -.megloop +.megloop3: srl h rr l - djnz .megloop + djnz .megloop3 call F_decimal ld a, 'M' rst CALLBAS defw 0x0010 ret -.gigs +.gigs3: ld l, (ix+(STAT_SIZE+4)) ; 1G to 4G ld h, 0 ld b, 6 -.gigloop +.gigloop3: srl l - djnz .gigloop + djnz .gigloop3 call F_decimal ld a, 'G' rst CALLBAS @@ -151,36 +160,37 @@ F_showsize ;---------------------------------------------------------------------- ; F_decimal -; Modified version of http://baze.au.com/misc/z80bits.html#5.1 +; Modified version of http://baze.au3.com3/misc/z80bits.html3#5.13 ; by baze. ; HL = number to convert -F_decimal +.globl F_decimal +F_decimal: ld e, 0 ld bc, -1000 ; maximum value passed will be 9999 - call .num1 + call .num14 ld bc, -100 - call .num1 + call .num14 ld c, -10 - call .num1 + call .num14 ld c, b ld e, 1 ; print a zero if it's the last digit -.num1 +.num14: ld a, '0'-1 -.num2 +.num24: inc a add hl, bc - jr c, .num2 + jr c, .num24 sbc hl, bc bit 0, e - jr nz, .zerocont + jr nz, .zerocont4 cp '0' - jr nz, .nonz + jr nz, .nonz4 ld a, ' ' - jr .zerocont -.nonz + jr .zerocont4 +.nonz4: ld e, 1 -.zerocont +.zerocont4: rst CALLBAS defw 0x0010 ret diff --git a/modules/basext/loader.asm b/modules/basext/loader.asm index cee9bae..557c49f 100644 --- a/modules/basext/loader.asm +++ b/modules/basext/loader.asm @@ -19,7 +19,13 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "fcntl.inc" +.include "spectranet.inc" +.include "zxrom.inc" +.include "defs.inc" +.include "sysvars.inc" +.include "zxsysvars.inc" +.text ; TAP load/save functions ;------------------------------------------------------------------------ ; F_tbas_readrawfile @@ -28,7 +34,8 @@ ; Parameters: HL = pointer to filename ; DE = memory location to place the result ; Returns with carry set and A=error number on error. -F_tbas_readrawfile +.globl F_tbas_readrawfile +F_tbas_readrawfile: push de ; save pointer ld e, O_RDONLY ; LOADing is read only ld d, 0x00 ; No file flags @@ -36,16 +43,16 @@ F_tbas_readrawfile pop de ret c ld (v_vfs_curfd), a ; save the filehandle -.readloop +.readloop1: ld a, (v_vfs_curfd) ; restore filehandle ld bc, 512 ; read max 512 bytes call READ - jr nc, .readloop ; keep going until nothing more can be read + jr nc, .readloop1 ; keep going until nothing more can be read cp EOF ; End of file? - jr nz, .failed ; No - something went wrong + jr nz, .failed1 ; No - something went wrong ld a, (v_vfs_curfd) ; Close the file jp VCLOSE -.failed +.failed1: push af ; preserve return code ld a, (v_vfs_curfd) call VCLOSE ; close the file @@ -60,7 +67,8 @@ F_tbas_readrawfile ; Parameters HL = pointer to filename ; DE = memory address to load to for CODE files ; A = type to expect -F_tbas_loader +.globl F_tbas_loader +F_tbas_loader: ld (INTERPWKSPC+21), a ; save the type parameter ld (v_desave), de ; save address ld e, O_RDONLY ; Open file read only @@ -74,28 +82,28 @@ F_tbas_loader ld ix, INTERPWKSPC+3 ; start of "tape" header in a TAP file ld a, (INTERPWKSPC+21) ; get the type byte cp (ix+0) ; check that it's the right type - jr nz, .wrongtype + jr nz, .wrongtype2 and a ; type 0? BASIC program - jr nz, .testcode ; No, test for CODE + jr nz, .testcode2 ; No, test for CODE call F_tbas_loadbasic ; Load a BASIC program jp c, J_cleanuperror ; handle errors -.cleanup +.cleanup2: ld a, (v_vfs_curfd) call VCLOSE ret -.testcode +.testcode2: cp 0x03 ; type CODE - jr nz, .unktype ; not a type we know + jr nz, .unktype2 ; not a type we know ld de, (INTERPWKSPC+OFFSET_PARAM1) ; get the start address ld bc, (INTERPWKSPC+OFFSET_LENGTH) ; and the expected length call F_tbas_loadblock ; and load the TAP block - jr .cleanup -.wrongtype + jr .cleanup2 +.wrongtype2: ; TODO: handle CODE files ld a, TBADTYPE scf ret -.unktype +.unktype2: ld a, TUNKTYPE scf ret @@ -108,7 +116,8 @@ F_tbas_loader ; and places the complete header into the memory address specified ; by DE. On error, it returns with carry set and A containing the error ; number. On success, the file type is returned in A. -F_tbas_getheader +.globl F_tbas_getheader +F_tbas_getheader: push de ; save pointer ld a, (v_vfs_curfd) ; get the current file descriptor ld bc, TNFS_HDR_LEN ; 19 bytes (length + ZX header block) @@ -117,23 +126,23 @@ F_tbas_getheader ret c ; error occurred in read ld a, (hl) cp 0x13 ; first byte must be 0x13 - jr nz, .wronglen + jr nz, .wronglen3 inc hl ld a, (hl) ; second byte must be 0x00 and a - jr nz, .wronglen + jr nz, .wronglen3 inc hl ld a, (hl) ; type must be 0x00 - "header" and a - jr nz, .wrongblktype + jr nz, .wrongblktype3 inc hl ld a, (hl) ; return the type byte ret ; TODO: Check the checksum etc. -.wronglen +.wronglen3: ld a, TBADLENGTH scf ret -.wrongblktype +.wrongblktype3: ld a, TBADTYPE scf ret @@ -144,7 +153,8 @@ F_tbas_getheader ; Parameters: DE = where to copy in memory ; BC = expected length ; v_vfs_curfd contains the file descriptor -F_tbas_loadblock +.globl F_tbas_loadblock +F_tbas_loadblock: push de ; save destination ptr push bc ; save length ld de, INTERPWKSPC ; get the length from TAP block @@ -158,12 +168,12 @@ F_tbas_loadblock dec hl ; which should be length in ZX header + 2 dec hl sbc hl, bc ; zero flag is set if length is correct - jr nz, .lengtherr -.loadloop + jr nz, .lengtherr4 +.loadloop4: ld a, (v_vfs_curfd) ; get file descriptor call READ ret -.lengtherr +.lengtherr4: ld a, TMISMCHLENGTH ; Length of data block doesn't match header scf ret @@ -171,10 +181,11 @@ F_tbas_loadblock ;---------------------------------------------------------------------------- ; F_tbas_loadbasic ; Load a program written in BASIC. -; Parameters: IX points to the "tape" header (i.e. TAP block + 2) +; Parameters: IX points to the "tape" header (i.e4. TAP block + 2) ; v_vfs_curfd contains the file descriptor ; Much of this is modelled on the ZX ROM loader. -F_tbas_loadbasic +.globl F_tbas_loadbasic +F_tbas_loadbasic: ld hl, (ZX_E_LINE) ; End marker of current variables area ld de, (ZX_PROG) ; Destination address dec hl @@ -198,13 +209,13 @@ F_tbas_loadbasic ld h, (ix+0x0e) ; Check for LINE number ld a, h and 0xC0 - jr nz, .loadblock ; No line number - skip to loader + jr nz, .loadblock5 ; No line number - skip to loader ld l, (ix+0x0d) ; HL = line number ld (ZX_NEWPPC), hl ; set line number to jump to xor a ld (ZX_NSPPC), a ; Statement number 0 -.loadblock +.loadblock5: pop bc ; fetch the length pop de ; fetch the start @@ -216,7 +227,8 @@ F_tbas_loadbasic ; Parameters A = type ; DE = filename ; BC = filename length -F_tbas_mktapheader +.globl F_tbas_mktapheader +F_tbas_mktapheader: push de push bc ; Create the header @@ -227,26 +239,26 @@ F_tbas_mktapheader ld (INTERPWKSPC+2), a ; is a header block, set to 0x00 ld a, 10 ; > 10 chars in the filename? cp b - jr nc, .continue + jr nc, .continue6 ld c, 10 ; copy max of 10 -.continue +.continue6: ld b, c ; prepare to copy string ld hl, INTERPWKSPC+4 -.loop +.loop6: ld a, (de) ; copy the string ld (hl), a inc de inc hl - djnz .loop + djnz .loop6 ld a, 10 ; find remaining bytes sub c - jr z, .exit ; nothing to do! + jr z, .exit6 ; nothing to do! ld b, a ; A now contains the loop count -.spaces +.spaces6: ld (hl), 0x20 ; fill the rest with spaces inc hl - djnz .spaces -.exit + djnz .spaces6 +.exit6: pop bc pop de ld hl, 0 ; make the parameters default to 0 @@ -260,9 +272,10 @@ F_tbas_mktapheader ; Writes a file from a %SAVE command. The header must be complete and stored ; in INTERPWKSPC. ; Parameters: DE = pointer to filename -; BC = length of filename (i.e. from ZX_STK_FETCH) +; BC = length of filename (i.e6. from ZX_STK_FETCH) ; On error returns with carry set and A = errno. -F_tbas_writefile +.globl F_tbas_writefile +F_tbas_writefile: ld hl, INTERPWKSPC+21 ; convert filename to a C string call F_basstrcpy @@ -297,25 +310,25 @@ F_tbas_writefile call WRITE ; write it out jp c, J_cleanuperror -.writedata +.writedata7: ld a, (INTERPWKSPC+OFFSET_TYPE) ; find the type of block we´re saving and a ; if zero, it is BASIC - jr nz, .testcode ; if not jump forward + jr nz, .testcode7 ; if not jump forward ld hl, (ZX_PROG) ; find the start of the program - jr .save -.testcode + jr .save7 +.testcode7: cp 3 ; type CODE - jr nz, .badtype ; TODO: character/number arrays + jr nz, .badtype7 ; TODO: character/number arrays ld hl, (INTERPWKSPC+OFFSET_PARAM1) ; get the start address -.save +.save7: ld bc, (INTERPWKSPC+OFFSET_LENGTH) ; length push hl ; save values so we can calculate the push bc ; checksum (TODO optimize) -.saveloop +.saveloop7: ld a, (v_vfs_curfd) ; get file descriptor call WRITE - jr c, .cleanuperror ; exit on error -.done + jr c, .cleanuperror7 ; exit on error +.done7: pop bc ; retrieve original size pop hl ; and start address ld a, 0xFF ; start with 0xFF for data block @@ -329,11 +342,11 @@ F_tbas_writefile ld a, (v_vfs_curfd) ; close the file. call VCLOSE ret -.badtype +.badtype7: ld a, TBADTYPE scf jp J_cleanuperror -.cleanuperror +.cleanuperror7: pop bc ; restore stack pop hl jp J_cleanuperror @@ -345,8 +358,9 @@ F_tbas_writefile ; BC = size ; A = initial byte ; Result is returned in A. -F_tbas_mkchecksum -.loop +.globl F_tbas_mkchecksum +F_tbas_mkchecksum: +.loop8: xor (hl) ; the checksum is made just by XORing each inc hl ; byte. dec bc @@ -354,12 +368,12 @@ F_tbas_mkchecksum ld a, b or c ; BC = 0? ld a, e ; restore A - jr nz, .loop + jr nz, .loop8 ret ;---------------------------------------------------------------------------- ; Generic 'clean up and leave' -J_cleanuperror +J_cleanuperror: push af ; save error code ld a, (v_vfs_curfd) ; and attempt to close the file call VCLOSE diff --git a/modules/basext/parseurl.asm b/modules/basext/parseurl.asm index aa20430..9f4513f 100644 --- a/modules/basext/parseurl.asm +++ b/modules/basext/parseurl.asm @@ -19,16 +19,19 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "defs.inc" +.include "sysvars.inc" +.text ; Parse URLs for mounting filesystems. ;-------------------------------------------------------------------------- ; F_parseurl: Break up incoming string into null-terminated strings. ; Parameters: IX - points to memory where the mount structure will be held ; HL - pointer to string -F_parseurl +.globl F_parseurl +F_parseurl: call F_findfstype ; if there's an fs type token - jr nc, .continue ; then continue + jr nc, .continue1 ; then continue push hl ; otherwise ld hl, STR_defaulttype ; make a copy of the default fs ld de, v_workspace ; type token in memory that's not @@ -37,25 +40,25 @@ F_parseurl pop hl ld (ix+0), v_workspace%256 ld (ix+1), v_workspace/256 - jr .finduser -.continue + jr .finduser1 +.continue1: ld (ix+0), e ; set the host arg ld (ix+1), d -.finduser +.finduser1: call F_finduser ; User specified in the string? - jr c, .findhost + jr c, .findhost1 ld (ix+6), e ld (ix+7), d call F_findpasswd ; Is there a password? - jr c, .findhost + jr c, .findhost1 ld (ix+8), e ld (ix+9), d -.findhost +.findhost1: call F_findhost ; There *must* be a host. ret c ld (ix+2), e ld (ix+3), d -.path ; The remainder is the path - just +.path1: ; The remainder is the path - just ld (ix+4), l ; set the next argument to the current ld (ix+5), h ; value of HL and return. ret @@ -65,21 +68,22 @@ F_parseurl ; with carry reset, DE pointing at the start address, and HL pointing ; at the start of the next bit of the string to parse. ; If not return with carry set and HL set to its original value. -F_findfstype +.globl F_findfstype +F_findfstype: push hl -.loop +.loop2: ld a, (hl) and a jr z, J_notfound cp ':' ; look for colon token followed by... inc hl - jr nz, .loop ; Not found, next... + jr nz, .loop2 ; Not found, next... ld a, (hl) ; See if we have an "/" cp '/' - jr z, .found + jr z, .found2 inc hl - jr .loop ; no, continue -.found + jr .loop2 ; no, continue +.found2: dec hl ; convert tokens to nulls xor a ld (hl), a ; delete the colon @@ -90,7 +94,7 @@ F_findfstype inc hl pop de ; return start address in DE ret -J_notfound +J_notfound: pop hl ; restore HL scf ; indicate "no fstype found" ret @@ -98,9 +102,10 @@ J_notfound ;------------------------------------------------------------------------- ; See if there's a user. The hostname part of the string can be ; user@host, user:pw@host or just host. -F_finduser +.globl F_finduser +F_finduser: push hl -.loop +.loop3: ld a, (hl) and a ; end of string jr z, J_notfound @@ -111,19 +116,19 @@ F_finduser cp '@' ; host separator? jr z, J_found inc hl - jr .loop ; no - check the next char -J_found + jr .loop3 ; no - check the next char +J_found: pop de ; DE = start of string ld a, d ; make sure the arg is at least 1 char cp h - jr nz, .done + jr nz, .done3 ld a, e cp l - jr nz, .done + jr nz, .done3 ex de, hl ; oops - reset HL to the start of the string scf ; indicate not found ret -.done +.done3: xor a ld (hl), a inc hl @@ -131,9 +136,10 @@ J_found ;------------------------------------------------------------------------- ; See if there's a password. -F_findpasswd +.globl F_findpasswd +F_findpasswd: push hl -.loop +.loop4: ld a, (hl) and a jr z, J_notfound @@ -142,31 +148,32 @@ F_findpasswd cp '@' jr z, J_found inc hl - jr .loop + jr .loop4 ;------------------------------------------------------------------------ ; Find the hostname -F_findhost +.globl F_findhost +F_findhost: push hl -.loop +.loop5: ld a, (hl) and a - jr z, .addpath + jr z, .addpath5 cp '/' jr z, J_found inc hl - jr .loop + jr .loop5 ; if we hit the end of the string while parsing the hostname ; we can assume the user wants to mount the root. -.addpath +.addpath5: inc hl ld (hl), '/' inc hl ld (hl), 0 pop de ret - -STR_defaulttype +.data +STR_defaulttype: defb "tnfs",0 -deftypelen equ 5 +deftypelen: equ 5 diff --git a/modules/basext/snaphandler.asm b/modules/basext/snaphandler.asm deleted file mode 100644 index 4079f3b..0000000 --- a/modules/basext/snaphandler.asm +++ /dev/null @@ -1,62 +0,0 @@ -;The MIT License -; -;Copyright (c) 2009 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -;------------------------------------------------------------------------ - -; Snapshot handler routines. - -;------------------------------------------------------------------------ -; F_detectsnap -; Determine if the filename passed in HL is a snapshot file we can handle -; and call the correct routine to handle it. On error, it returns. -; If no error is encountered, the snapshot is run. -F_detectsnap - ; simple detection - look at the size to see if it's 48K or 128K - push hl ; save the filename pointer - ld de, INTERPWKSPC ; where to put the data from stat - call STAT - pop hl - ret c ; can't stat the file - - ld d, 0 ; no flags - ld e, O_RDONLY ; file mode = RO - call OPEN ; open the snapshot - ret c ; and return on error. - ld (v_snapfd), a ; save the FD - - ld (v_stacksave), sp ; Save the current stack pointer - ld sp, v_snapstack ; Set the stack for snapshot loading. - - ld hl, (INTERPWKSPC+8) ; Less than 64K in size? - ld a, h - or l - jr z, .fortyeight - - call F_loadsna128 ; Load a 128K snapshot - ld sp, (v_stacksave) ; Restore the stack - ret -.fortyeight - call F_loadsna48 - ld sp, (v_stacksave) - ret - - diff --git a/modules/basext/strings_en.asm b/modules/basext/strings_en.asm index 70e7c04..8a86dcf 100644 --- a/modules/basext/strings_en.asm +++ b/modules/basext/strings_en.asm @@ -21,21 +21,36 @@ ;THE SOFTWARE. ; Strings (English) - -STR_filetype defb "File type: ",0 -STR_tap defb "TAP file",0 -STR_data defb "Data",0 -STR_basic defb "Program: ",0 -STR_numarray defb "Number array: ",0 -STR_strarray defb "String array: ",0 -STR_code defb "Bytes: ",0 -STR_unknown defb "Unknown: ",0 -STR_size defb "File size: ",0 -STR_blksize defb "Block size : ",0 -STR_param1 defb "Paramater 1: ",0 -STR_param2 defb "Parameter 2: ",0 -STR_directory defb "Directory: size ",0 -STR_bytes defb " bytes",0 -STR_headerless defb "Headerless block: ",0 +.data +.globl STR_filetype +.globl STR_tap +.globl STR_data +.globl STR_basic +.globl STR_numarray +.globl STR_strarray +.globl STR_code +.globl STR_unknown +.globl STR_size +.globl STR_blksize +.globl STR_param1 +.globl STR_param2 +.globl STR_directory +.globl STR_bytes +.globl STR_headerless +STR_filetype: defb "File type: ",0 +STR_tap: defb "TAP file",0 +STR_data: defb "Data",0 +STR_basic: defb "Program: ",0 +STR_numarray: defb "Number array: ",0 +STR_strarray: defb "String array: ",0 +STR_code: defb "Bytes: ",0 +STR_unknown: defb "Unknown: ",0 +STR_size: defb "File size: ",0 +STR_blksize: defb "Block size : ",0 +STR_param1: defb "Paramater 1: ",0 +STR_param2: defb "Parameter 2: ",0 +STR_directory: defb "Directory: size ",0 +STR_bytes: defb " bytes",0 +STR_headerless: defb "Headerless block: ",0 diff --git a/modules/basext/tapetrap.asm b/modules/basext/tapetrap.asm index 5c4b622..269c0f7 100644 --- a/modules/basext/tapetrap.asm +++ b/modules/basext/tapetrap.asm @@ -19,13 +19,18 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "defs.inc" +.include "spectranet.inc" +.include "fcntl.inc" +.include "sysvars.inc" +.text ; Initialize and handle tape traps. ;--------------------------------------------------------------------------- ; F_settrap: Sets up tape traps for the named file. ; This must be called immediately after ZX_STK_FETCH to get the string. -F_settrap +.globl F_settrap +F_settrap: ld hl, INTERPWKSPC call F_basstrcpy ; get the string from the interpreter @@ -50,13 +55,13 @@ F_settrap call SETTRAP ret -TAPETRAPBLOCK +TAPETRAPBLOCK: defb 0xFF ; this page defw F_loadbytes ; function to call defw 0x0564 ; address at time of NMI defw 0x0562 ; address to trap with NMI -DEFAULTTRAPBLOCK +DEFAULTTRAPBLOCK: defb 0xFF ; this page defw F_bootfile ; function to call defw 0x0564 ; address at time of NMI @@ -65,7 +70,8 @@ DEFAULTTRAPBLOCK ;--------------------------------------------------------------------------- ; F_releasetrap: Closes the file associated with the tape trap and disables ; the trap itself. -F_releasetrap +.globl F_releasetrap +F_releasetrap: push ix ld a, 1 out (254), a @@ -87,9 +93,11 @@ F_releasetrap ; On return, the carry flag is the *opposite* to normal Spectranet code - ; the routines that call loadbytes expect carry to be set if there's NOT ; an error. -F_loadbytes +.globl F_loadbytes +F_loadbytes: push ix ; store address -F_loadbytes_nopush ; (if IX has already been pushed) +.globl F_loadbytes_nopush +F_loadbytes_nopush: ; (if IX has already been pushed) ld ix, 4 ; point IX at the stacked registers add ix, sp @@ -104,30 +112,30 @@ F_loadbytes_nopush ; (if IX has already been pushed) push ix call READ ; get the "flag" byte. pop ix - jr c, .cleanuperror1 + jr c, .cleanuperror14 ld a, (INTERPWKSPC) ; compare the flag byte read with the flag cp (ix+1) ; passed in A to LD-BYTES - jr nz, .skip ; if they aren't the same skip the block + jr nz, .skip4 ; if they aren't the same skip the block ld c, (ix+6) ; get the requested length into ld b, (ix+7) ; BC pop de ; and the address into DE ld h, b ; remaining length in HL ld l, c -.readloop +.readloop4: ld a, (v_trapfd) push hl push ix call READ pop ix pop hl - jr c, .cleanuperror2 + jr c, .cleanuperror24 sbc hl, bc ; decrement length remaining ld b, h ; update requested bytes ld c, l - jr nz, .readloop ; continue until 0 bytes remain + jr nz, .readloop4 ; continue until 0 bytes remain ld a, (v_trapfd) ld bc, 3 ; now read the "check sum" + next block length @@ -135,28 +143,28 @@ F_loadbytes_nopush ; (if IX has already been pushed) push ix call READ pop ix - jr c, .checkeof ; EOF? + jr c, .checkeof4 ; EOF? ld hl, (INTERPWKSPC+1) ; Get the length of the next block and copy ld (v_trap_blklen), hl ; to the length storage. -.success +.success4: ld (ix+2), 1 ; set carry flag in return stack jp PAGETRAPRETURN -.checkeof +.checkeof4: cp EOF ; End of file - not an error condition - jr nz, .cleanuperror2 + jr nz, .cleanuperror24 call F_releasetrap ; Close the file and release the trap ld (ix+2), 1 ; Signal success to ROM jp PAGETRAPRETURN -.cleanuperror1 +.cleanuperror14: pop hl ; restore the stack (originally ix) -.cleanuperror2 +.cleanuperror24: call F_releasetrap ; Release the trap and close files ld (ix+2), 0 ; reset the carry flag to signal error jp PAGETRAPRETURN -.skip ; TODO: when seek() is working... +.skip4: ; TODO: when seek() is working... call F_releasetrap pop de ; restore stack pop ix @@ -165,10 +173,10 @@ F_loadbytes_nopush ; (if IX has already been pushed) ld (ix+2), 0 ; ensure C is cleared jp PAGETRAPRETURN -J_trapreturn +J_trapreturn: ;--------------------------------------------------------------------------- -J_cleanup_traperr +J_cleanup_traperr: push af ld a, (v_trapfd) call VCLOSE @@ -177,7 +185,8 @@ J_cleanup_traperr ;-------------------------------------------------------------------------- ; F_initbootfile: Sets up LOAD "" -F_initbootfile +.globl F_initbootfile +F_initbootfile: ld hl, DEFAULTTRAPBLOCK ; Program the CPLD NMI trap call SETTRAP ret @@ -187,7 +196,8 @@ F_initbootfile ; Handles the case of an unsolicited LOAD "". It will try to load the file ; "boot" in the current working directory. If the file doesn't exist, it ; releases the trap and returns control to the tape loader. -F_bootfile +.globl F_bootfile +F_bootfile: push ix ld hl, DEFAULTFILE ; first copy the filename into memory ld de, INTERPWKSPC ; that's accessable by the FS module @@ -198,28 +208,28 @@ F_bootfile ld d, 0x00 ; no flags ld e, O_RDONLY ; read only call OPEN - jr c, .usetape ; On error, simply pass control back to the + jr c, .usetape6 ; On error, simply pass control back to the ; ROM tape loader. ld (v_trapfd), a ; save the file descriptor ld de, v_trap_blklen ; read the TAP block length to "prime the ld bc, 2 ; system" as it were. call READ - jr c, .cleanupusetape ; any errors, then clean up and use tape. (EOF + jr c, .cleanupusetape6 ; any errors, then clean up and use tape. (EOF ; considered an error at this point too) ld hl, TAPETRAPBLOCK ; Reprogram the NMI trap. call SETTRAP jp F_loadbytes_nopush ; and go to loadbytes to do the work. -.cleanupusetape +.cleanupusetape6: ld a, (v_trapfd) call VCLOSE ; close the file -.usetape +.usetape6: pop ix jp PAGETRAPRETURN -DEFAULTFILE - defb "boot.zx",0 -DEFAULTFILELEN equ $-DEFAULTFILE +DEFAULTFILE: + defb "boot.zx6",0 +DEFAULTFILELEN: equ $-DEFAULTFILE diff --git a/modules/basext/vectors.asm b/modules/basext/vectors.asm index 4cc507d..9062f1e 100644 --- a/modules/basext/vectors.asm +++ b/modules/basext/vectors.asm @@ -21,7 +21,8 @@ ;THE SOFTWARE. ; BASIC extensions vector table -ROM_ID equ 0xFD +.include "defs.inc" +.section vectors defb 0xAA ; This is a code ROM defb ROM_ID ; ROM ID = 0xFD defw F_init ; RESET vector @@ -33,7 +34,6 @@ ROM_ID equ 0xFD defw STR_ident ; Pointer to a string that identifies this mod ret ;jp F_snaptest ; Modulecall - block 0x2020-$,0xFF - -STR_ident defb "VFS BASIC extensions",0 +.data +STR_ident: defb "VFS BASIC extensions",0 diff --git a/modules/config/Makefile b/modules/config/Makefile new file mode 100644 index 0000000..a680deb --- /dev/null +++ b/modules/config/Makefile @@ -0,0 +1,29 @@ +ASOBJS = configbasic.o configdata.o fs_config_ui.o fs_strings_en.o gen_copycfg.o if_config_ui.o if_configmain.o if_saveconfig.o if_strings_en.o init.o vectors.o +LIBS = -lromui +LIBPATH = -L ../../syslib +FLOBJS = flashwrite.o +FLLDFLAGS = -Ttext 0x3000 $(LIBPATH) -Map $(FLMAP) +FLLIBS = -lflashwrite +FLOUT = flashwrite.bin +FLMAP = $(FLOUT).map +DUMPOBJS = dumpconfig.o +DUMPOUT = dumpconfig.bin +DUMPLDFLAGS = -Ttext 0x8000 +SAOBJS = standalone_ifconfig.o gen_copycfg.o if_config_ui.o if_strings_en.o sa_if_saveconfig.o sa_flashwrite.o +SAOUT = ifconfig.bin +SALDFLAGS = -Ttext 0x8000 $(LIBPATH) +SALIBS = -lflashwrite -lromui +OUT = config.module + +all: flash module dumpcfg standalone +include ../make.inc + +flash: $(FLOBJS) + $(LD) -o $(FLOUT) $(FLOBJS) $(FLLDFLAGS) $(FLLIBS) + +dumpcfg: $(DUMPOBJS) + $(LD) -o $(DUMPOUT) $(DUMPOBJS) $(DUMPLDFLAGS) + +standalone: $(SAOBJS) + $(LD) -o $(SAOUT) $(SAOBJS) $(SALDFLAGS) $(SALIBS) + diff --git a/modules/config/build b/modules/config/build deleted file mode 100755 index 76a4573..0000000 --- a/modules/config/build +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -echo `pwd`/config.out >> ../../build.out -sjasmplus config.asm --lst=config.lst -exit $? - diff --git a/modules/config/config.asm b/modules/config/config.asm deleted file mode 100644 index cb43d48..0000000 --- a/modules/config/config.asm +++ /dev/null @@ -1,43 +0,0 @@ -;The MIT License -; -;Copyright (c) 2009 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; Filesystem Configuration Utility module - org 0x2000 - include "vectors.asm" ; Vector table - include "init.asm" ; Initialization routines - include "gen_copycfg.asm" ; Config copier - include "fs_strings_en.asm" ; English strings - include "fs_config_ui.asm" ; User interface - include "if_configmain.asm" ; Interface configuration - include "if_config_ui.asm" ; Interface cf. UI - include "if_strings_en.asm" ; English strings - include "if_saveconfig.asm" - include "configdata.asm" ; get/set config data - include "configbasic.asm" ; BASIC commands - include "configdefs.asm" ; definitions - include "../../rom/spectranet.asm" ; spectranet lib defs - include "../../rom/sysvars.sym" ; system vars defs - include "../../rom/flashconf.asm" ; flash config defs - include "../../rom/zxromdefs.asm" ; ZX rom entry points - include "if_defs.asm" ; defines - include "flashwrite.asm" ; must be the last included - diff --git a/modules/config/config_interface.asm b/modules/config/config_interface.inc similarity index 100% rename from modules/config/config_interface.asm rename to modules/config/config_interface.inc diff --git a/modules/config/configbasic.asm b/modules/config/configbasic.asm index bd16ef7..920902b 100644 --- a/modules/config/configbasic.asm +++ b/modules/config/configbasic.asm @@ -19,7 +19,11 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "zxrom.inc" +.include "spectranet.inc" +.include "sysvars.inc" +.include "configdefs.inc" +.text ; Simple BASIC interface to allow the setting/getting of config values. ; The format of all set commands is: ; %cfgset section,id,value @@ -29,7 +33,8 @@ ; To commit, %cfgcommit, to abandon, %cfgabandon ;-------------------------------------------------------------------------- ; F_cfgcommit. Takes no args. Commits configuration to flash. -F_cfgcommit +.globl F_cfgcommit +F_cfgcommit: call STATEMENT_END ; runtime @@ -39,7 +44,8 @@ F_cfgcommit ;-------------------------------------------------------------------------- ; F_cfgabandon. Abandons RAM copy of configuration. -F_cfgabandon +.globl F_cfgabandon +F_cfgabandon: call STATEMENT_END ; runtime @@ -49,7 +55,8 @@ F_cfgabandon ;-------------------------------------------------------------------------- ; F_cfgset ; Sets byte and word values -F_cfgset +.globl F_cfgset +F_cfgset: ; Syntax check time call F_cfgset_common @@ -85,7 +92,8 @@ F_cfgset ;-------------------------------------------------------------------------- ; F_cfgset_string ; Sets a string -F_cfgset_string +.globl F_cfgset_string +F_cfgset_string: ; Syntax check time call F_cfgset_common @@ -114,7 +122,8 @@ F_cfgset_string ;-------------------------------------------------------------------------- ; Common syntax checks -F_cfgset_common +.globl F_cfgset_common +F_cfgset_common: rst CALLBAS defw ZX_EXPT1_NUM ; check for section ID cp ',' ; comma @@ -132,8 +141,9 @@ F_cfgset_common ; F_prepwrite ; Actions that have to be done for any writeable cfg item. ; Section to use in DE -F_prepwrite - call F_copyconfig +.globl F_prepwrite +F_prepwrite: + call F_cond_copyconfig ld d, (ix+1) ld e, (ix+0) call F_findsection @@ -146,7 +156,8 @@ F_prepwrite ; IX+3 = id ; IX+4 = value or pointer to string ; note all values are 16 bit -F_do_cfgset_byte +.globl F_do_cfgset_byte +F_do_cfgset_byte: call F_prepwrite jr c, F_handle_error ld a,(ix+2) @@ -155,7 +166,8 @@ F_do_cfgset_byte call F_setCFByte jp EXIT_SUCCESS -F_do_cfgset_word +.globl F_do_cfgset_word +F_do_cfgset_word: call F_prepwrite jr c, F_handle_error ld a,(ix+2) @@ -165,7 +177,8 @@ F_do_cfgset_word call F_setCFWord jp EXIT_SUCCESS -F_do_cfgset_string +.globl F_do_cfgset_string +F_do_cfgset_string: call F_prepwrite jr c, F_handle_error ld a,(ix+2) @@ -178,12 +191,13 @@ F_do_cfgset_string ;------------------------------------------------------------------------- ; F_cfgnew ; Create a brand new config (wiping any that may already exist) -F_cfgnew +.globl F_cfgnew +F_cfgnew: ; Syntax time call STATEMENT_END ; no args ; Run time - call F_copyconfig ; not necessary to actually copy it but + call F_cond_copyconfig ; not necessary to actually copy it but ; this sets up sysvars ready so we can commit call F_createnewconfig ; overwrite whatever's already there with jp EXIT_SUCCESS ; a new config. @@ -191,14 +205,15 @@ F_cfgnew ;------------------------------------------------------------------------ ; F_cfgnewsec ; Create a new section with the ID supplied. -F_cfgnewsec +.globl F_cfgnewsec +F_cfgnewsec: ; Syntax time rst CALLBAS defw ZX_EXPT1_NUM ; expect a single 16 bit number call STATEMENT_END ; run time - call F_copyconfig ; ensure config is in RAM + call F_cond_copyconfig ; ensure config is in RAM rst CALLBAS ; get the argument defw ZX_FIND_INT2 ; which is now in BC. ld d, b @@ -209,31 +224,34 @@ F_cfgnewsec ;------------------------------------------------------------------------- ; Copy a BASIC string to a C string. ; BASIC string in DE, C string (dest) in HL -F_basstrcpy +.globl F_basstrcpy +F_basstrcpy: ld a, b ; end of string? or c - jr z, .terminate + jr z, .terminate12 ld a, (de) ld (hl), a inc hl inc de dec bc jr F_basstrcpy -.terminate +.terminate12: xor a ; put the null on the end ld (hl), a inc hl ret -F_handle_error +.globl F_handle_error +F_handle_error: ; TODO: integrate with messages module ld hl, STR_cfgerr jp REPORTERR -J_badid +J_badid: ld hl, STR_badid jp REPORTERR -STR_cfgerr +.data +STR_cfgerr: defb "Configuration error",0 -STR_badid +STR_badid: defb "Bad config ID",0 diff --git a/modules/config/configdata.asm b/modules/config/configdata.asm index 35487bc..e11b345 100644 --- a/modules/config/configdata.asm +++ b/modules/config/configdata.asm @@ -19,58 +19,77 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "configdefs.inc" +.include "sysvars.inc" +.include "spectranet.inc" +.text ; Find, read and insert configuration data. -; include "debug.asm" +; include "debug.asm"A +;----------------------------------------------------------------------- +; F_cond_copyconfig: Conditionally copy the configuration (if it's not +; been copied already) +.globl F_cond_copyconfig +F_cond_copyconfig: + call F_getsysvar ; see if we've already copied it + inc hl + ld a, 1 + cp (hl) ; if Z we've already made a copy + ret z + ld (hl), 1 ; Indicate a copy has been made. + jp F_copyconfig + ;----------------------------------------------------------------------- ; F_findsection: Finds where in memory a configuration section lives ; and returns the address in HL. ; Section ID to find is in DE. ; Carry is set if the section was not found. -F_findsection +.globl F_findsection +F_findsection: call F_mappage call F_findsection_core jp F_leave -F_findsection_core +.globl F_findsection_core +F_findsection_core: ld hl, CONFIG_BASE_ADDR ; Start here. ld a, (hl) inc hl or (hl) ; check that there's actually data - jr z, .notfound ; no configuration data at all + jr z, .notfound2 ; no configuration data at all -.findloop +.findloop2: inc hl ; point to first section ld a, (hl) ; compare against DE inc hl cp e - jr nz, .findnext + jr nz, .findnext2 ld a, (hl) cp d - jr nz, .findnext + jr nz, .findnext2 inc hl ; HL points at the section size ld (v_configptr), hl ; save the pointer ret -.findnext +.findnext2: cp 0xFF ; Check we've not hit the end. - jr z, .checkend -.findnext1 + jr z, .checkend2 +.findnext12: inc hl ld c, (hl) ; LSB of the section size word inc hl ld b, (hl) ; MSB add hl, bc ; point HL at the next entry - jr .findloop -.checkend + jr .findloop2 +.checkend2: dec hl ld a, (hl) cp 0xFF - jr z, .notfound + jr z, .notfound2 inc hl ; undo the DEC operation - jr .findnext1 + jr .findnext12 -.notfound +.notfound2: scf ret @@ -78,7 +97,8 @@ F_findsection_core ; F_createsection: Creates a new empty section. ; DE = id of section to create ; Carry is set if the section can't be created. -F_createsection +.globl F_createsection +F_createsection: call F_mappage push de call F_findsection_core ; does the section already exist? @@ -112,7 +132,8 @@ F_createsection ;------------------------------------------------------------------------- ; F_createnewconfig ; Creates a brand new empty config area. -F_createnewconfig +.globl F_createnewconfig +F_createnewconfig: call F_mappage xor a @@ -128,7 +149,8 @@ F_createnewconfig ; F_getcfgstring: Get an item that is a string. ; A = id of item to get. ; DE = where to place the result -F_getCFString +.globl F_getCFString +F_getCFString: ex af, af' ; get arg call F_mappage @@ -137,19 +159,20 @@ F_getCFString pop de jp c, F_leave inc hl -.cpstring +.cpstring5: ldi ld a, (hl) and a - jr nz, .cpstring -.addnull + jr nz, .cpstring5 +.addnull5: ld (de), a ; put the NULL on the end jp F_leave ;------------------------------------------------------------------------- ; F_getCFWord: Get a 2 byte configuration item into HL ; A = id of the item. -F_getCFWord +.globl F_getCFWord +F_getCFWord: ex af, af' ; get arg call F_mappage @@ -165,7 +188,8 @@ F_getCFWord ;------------------------------------------------------------------------- ; F_getCFByte: Get a 1 byte configuration item into A ; A = id of the item -F_getCFByte +.globl F_getCFByte +F_getCFByte: ex af, af' ; get arg call F_mappage @@ -179,11 +203,12 @@ F_getCFByte ; F_addCFByte: Add 1 byte configuration item. ; A = id of the item ; C = value to add -F_addCFByte +.globl F_addCFByte +F_addCFByte: push af and 0xC0 cp 0x80 ; check that this is a valid byte id - jr nz, .error + jr nz, .error8 push bc ld hl, (v_configptr) ; set HL to where room is to be made inc hl @@ -193,14 +218,14 @@ F_addCFByte call F_makeroom pop hl pop bc - jr c, .error + jr c, .error8 pop af ld (hl), a ; id of the item inc hl ld (hl), c ; value of the item jp F_leave -.error +.error8: pop af scf jp F_leave @@ -209,11 +234,12 @@ F_addCFByte ; F_addCFWord: Add 2 byte configuration item. ; A = id of the item ; BC = value to add -F_addCFWord +.globl F_addCFWord +F_addCFWord: push af and 0xC0 cp 0xC0 ; check that this is a valid word id - jr nz, .error + jr nz, .error9 push bc ld hl, (v_configptr) ; set HL to where room is to be made inc hl @@ -223,7 +249,7 @@ F_addCFWord call F_makeroom pop hl pop bc - jr c, .error + jr c, .error9 pop af ld (hl), a ; id of the item inc hl @@ -232,7 +258,7 @@ F_addCFWord ld (hl), b jp F_leave -.error +.error9: pop af scf jp F_leave @@ -240,18 +266,20 @@ F_addCFWord ;------------------------------------------------------------------------- ; F_addCFString: Adds a string value. Null terminated string should be ; pointed to by DE, with its ID in A -F_addCFString +.globl F_addCFString +F_addCFString: ex af, af' ; get arg call F_mappage call F_addCFString_core jp F_leave -F_addCFString_core +.globl F_addCFString_core +F_addCFString_core: push de push af and 0xC0 and a ; check that this is a valid string id - jr nz, .error + jr nz, .error11 ex de, hl ld bc, 0xFF @@ -268,7 +296,7 @@ F_addCFString_core call F_makeroom pop hl ; get address of 1st byte of new space pop bc - jr c, .error + jr c, .error11 pop af ld (hl), a inc hl @@ -277,7 +305,7 @@ F_addCFString_core ldir ; copy the string ret -.error +.error11: pop af pop de ret @@ -286,7 +314,8 @@ F_addCFString_core ; F_setCFString ; Config strings can be variable length so we delete it first and recreate ; it. -F_setCFString +.globl F_setCFString +F_setCFString: ex af, af' call F_mappage push af @@ -301,21 +330,22 @@ F_setCFString ; F_setCFWord ; Set or change a word value. ; A = byte ID, BC = new value -F_setCFWord +.globl F_setCFWord +F_setCFWord: ex af, af' call F_mappage push af push bc call F_findcfgitem pop bc - jp c, .add ; not found, add it + jp c, .add13 ; not found, add it pop af inc hl ; point at word's LSB ld (hl), c inc hl ld (hl), b jp F_leave -.add +.add13: pop af jp F_addCFWord @@ -323,19 +353,20 @@ F_setCFWord ; F_setCFByte ; Change a byte value. ; A = byte ID, C = new value -F_setCFByte +.globl F_setCFByte +F_setCFByte: ex af, af' call F_mappage push af push bc call F_findcfgitem ; get the address of the byte pop bc - jr c, .add ; Not found, add it + jr c, .add14 ; Not found, add it pop af inc hl ; point at value ld (hl), c jp F_leave -.add +.add14: pop af jp F_addCFByte @@ -345,71 +376,74 @@ F_setCFByte ; Finds a configuration item with the supplied ID. ; Returns with HL set to the address of the item on success. Carry set ; on error. -F_findcfgitem +.globl F_findcfgitem +F_findcfgitem: ld hl, (v_configptr) ld c, (hl) ; LSB of section size inc hl ld b, (hl) ; MSB of section size inc hl -.findloop +.findloop15: ld e, a ; save A ld a, b or c ; check that the section is not done - jr z, .notfound + jr z, .notfound15 ld a, e ; restore A cp (hl) ; Is this the section we're after? ret z ; Found - return. bit 7, (hl) ; String value? - jr z, .skipstring + jr z, .skipstring15 bit 6, (hl) ; Word or byte? inc hl dec bc inc hl dec bc - jr z, .findloop ; byte is skipped at this stage + jr z, .findloop15 ; byte is skipped at this stage inc hl dec bc - jr .findloop ; word is skipped at this stage -.skipstring + jr .findloop15 ; word is skipped at this stage +.skipstring15: ld e, a ; save A inc hl dec bc xor a ; find the next NULL terminator cpir ld a, e - jr .findloop + jr .findloop15 -.notfound +.notfound15: scf ret ;------------------------------------------------------------------------- ; F_rmcfgitem ; A = config item to remove -F_rmcfgitem +.globl F_rmcfgitem +F_rmcfgitem: ex af, af' ; retrieve arg in A call F_mappage call F_rmcfgitem_core jp F_leave -F_rmcfgitem_core +.globl F_rmcfgitem_core +F_rmcfgitem_core: call F_findcfgitem ret c ; Not found bit 7, (hl) ; String value? - jr z, .rmstring + jr z, .rmstring17 bit 6, (hl) ; Word or byte? - jr z, .compact2 + jr z, .compact217 ld bc, 3 call F_compact ret -.compact2 +.compact217: ld bc, 2 call F_compact ret -.rmstring +.rmstring17: push hl ; find the length of the ld bc, 0xFF ; string. xor a @@ -425,7 +459,8 @@ F_rmcfgitem_core ; F_compact ; Compact the configuration area by BC bytes, deleting the item (that's BC ; bytes long) at HL. -F_compact +.globl F_compact +F_compact: ex de, hl ld ix, (v_configptr) ld l, (ix+0) @@ -461,7 +496,8 @@ F_compact ; F_makeroom ; Makes some space for a new configuration item. ; BC = how much to make -F_makeroom +.globl F_makeroom +F_makeroom: ; update sizes ld hl, (v_totalcfgsz) ld (v_hlsave), hl ; save it for later @@ -502,7 +538,8 @@ F_makeroom ret ; returns with C set if the size is too great. -F_checkcfgsize +.globl F_checkcfgsize +F_checkcfgsize: ld a, MAXCFGSZ/256 cp h ret c @@ -514,7 +551,8 @@ F_checkcfgsize ;------------------------------------------------------------------------ ; F_abandonConfig: Abandon the RAM copy of the configuration (mark it ; uncopied, so further accesses to config go to flash) -F_abandonConfig +.globl F_abandonConfig +F_abandonConfig: call F_getsysvar inc hl ld (hl), 0 ; reset "RAM copy" flag @@ -522,12 +560,13 @@ F_abandonConfig ;------------------------------------------------------------------------ ; F_commitConfig: Commits the configuration in RAM to flash. -F_commitConfig +.globl F_commitConfig +F_commitConfig: call F_getsysvar ; make sure that a RAM copy has been made inc hl ld a, 1 cp (hl) - jr nz, .notpaged + jr nz, .notpaged22 ld (hl), 0 ; clear down "RAM copy" flag ; copy the flash programmer @@ -541,7 +580,7 @@ F_commitConfig ret -.notpaged ; do not write flash if it hasn't already +.notpaged22: ; do not write flash if it hasn't already scf ; been copied to RAM. ret @@ -549,7 +588,8 @@ F_commitConfig ; F_mappage ; Maps the page. If we've copied the configuration, RAM should be mapped, ; if not, flash. -F_mappage +.globl F_mappage +F_mappage: push af push hl call F_getsysvar @@ -558,7 +598,7 @@ F_mappage inc hl ld a, (hl) ; has a shadow copy been made? cp 1 ; 1 = yes - jr nz, .getflash + jr nz, .getflash23 ld a, CFG_RAM_PAGE ; set page A to the flash config call SETPAGEA @@ -567,14 +607,15 @@ F_mappage pop af ret -.getflash +.getflash23: ld a, CFG_FLASH_PAGE call SETPAGEA pop hl pop af ret -F_getsysvar +.globl F_getsysvar +F_getsysvar: ld a, (v_pgb) ; what's our page? rlca rlca @@ -583,7 +624,8 @@ F_getsysvar ld l, a ret ; hl points at private area -F_leave +.globl F_leave +F_leave: push af push hl call F_getsysvar diff --git a/modules/config/configdefs.asm b/modules/config/configdefs.inc similarity index 100% rename from modules/config/configdefs.asm rename to modules/config/configdefs.inc diff --git a/modules/config/dumpconfig.asm b/modules/config/dumpconfig.asm index 4db6f5c..e3e7e5e 100644 --- a/modules/config/dumpconfig.asm +++ b/modules/config/dumpconfig.asm @@ -19,32 +19,30 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - -; Dump the contents of the configuration flash. - include "../../rom/spectranet.asm" - include "configdefs.asm" - - org 0x8000 +.include "spectranet.inc" +.include "configdefs.inc" +.include "ctrlchars.inc" +.text call PAGEIN call CLEAR42 ld a, CFG_FLASH_PAGE call SETPAGEA -.start +.start0: ld hl, str_size call PRINT42 ld hl, CONFIG_BASE_ADDR call F_printint16 inc hl inc hl -.configsections +.configsections0: ld a, (hl) inc hl ld c, (hl) inc a inc c or c - jp z, .done + jp z, .done0 dec hl push hl @@ -66,15 +64,15 @@ ld b, (hl) inc hl ; hl now at first byte of config ld (v_remaining), bc -.sectionloop +.sectionloop0: ld a, b or c ; read whole section? - jr z, .configsections ; go back to the conig sections loop + jr z, .configsections0 ; go back to the conig sections loop bit 7, (hl) - jr z, .string ; bit 7 = 0 = string + jr z, .string0 ; bit 7 = 0 = string bit 6, (hl) - jr nz, .word ; bit 6 = 0 = byte + jr nz, .word0 ; bit 6 = 0 = byte push hl ld hl, str_byteid @@ -92,9 +90,9 @@ dec bc dec bc ld (v_remaining), bc ; update remaining bytes - jr .sectionloop + jr .sectionloop0 -.string +.string0: push hl ld hl, str_stringid call PRINT42 @@ -108,22 +106,22 @@ ld bc, (v_remaining) dec bc -.printloop +.printloop0: ld a, (hl) and a - jr z, .printdone + jr z, .printdone0 call PUTCHAR42 inc hl dec bc and a ; string end? - jr .printloop -.printdone + jr .printloop0 +.printdone0: inc hl dec bc ld (v_remaining), bc ; update remaining - jr .sectionloop + jr .sectionloop0 -.word +.word0: push hl ld hl, str_wordid call PRINT42 @@ -142,17 +140,18 @@ dec bc dec bc ld (v_remaining), bc - jp .sectionloop + jp .sectionloop0 -.done +.done0: ld hl, str_end call PRINT42 -J_exit +J_exit: jp PAGEOUT ; print 16 bits pointed to by HL -F_printint16 +.globl F_printint16 +F_printint16: push hl inc hl ld a, (hl) @@ -161,7 +160,8 @@ F_printint16 ld hl, workspace call PRINT42 pop hl -F_printint8 ; and just do 8 bits +.globl F_printint8 +F_printint8: ; and just do 8 bits push hl ld a, (hl) ld hl, workspace @@ -171,10 +171,11 @@ F_printint8 ; and just do 8 bits pop hl ret -F_dumpbytes +.globl F_dumpbytes +F_dumpbytes: ld hl, 0x1000 ld b, 0x20 -.loop +.loop3: push bc push hl ld a, (hl) @@ -185,19 +186,20 @@ F_dumpbytes pop hl pop bc inc hl - djnz .loop + djnz .loop3 ret - -str_size defb "Config size: ",0 -str_section defb "\n\n--- SectionID: ",0 -str_sectionsize defb "\nSecsize : ",0 -str_stringid defb "\nStringID: ",0 -str_string defb "\nString : ",0 -str_byteid defb "\nByteID : ",0 -str_byte defb " Byte: ",0 -str_wordid defb "\nWordID : ",0 -str_word defb " Word: ",0 -str_end defb "\n---End of configuration.",0 -v_remaining defw 0 -workspace defb 0 +.data +str_size: defb "Config size: ",0 +str_section: defb NEWLINE,NEWLINE,"--- SectionID: ",0 +str_sectionsize: defb NEWLINE,"Secsize : ",0 +str_stringid: defb NEWLINE,"StringID: ",0 +str_string: defb NEWLINE,"String : ",0 +str_byteid: defb NEWLINE,"ByteID : ",0 +str_byte: defb " Byte: ",0 +str_wordid: defb NEWLINE,"WordID : ",0 +str_word: defb " Word: ",0 +str_end: defb NEWLINE,"---End of configuration.",0 +.bss +v_remaining: defw 0 +workspace: defb 0 diff --git a/modules/config/flashwrite.asm b/modules/config/flashwrite.asm index b0048aa..85f2ad8 100644 --- a/modules/config/flashwrite.asm +++ b/modules/config/flashwrite.asm @@ -19,11 +19,13 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.text -FLASHPROGSTART - ; Flash writer. This *MUST* be at the end because we change ORG - org 0x3000 -F_updateflash +FLASHPROGSTART: +.globl F_updateflash +F_updateflash: di ld a, (v_pga) push af @@ -31,10 +33,10 @@ F_updateflash push af ld a, 0x1C ; last sector of flash call F_FlashEraseSector - jr c, .cleanup + jr c, .cleanup1 ld a, 0x1C ; start page to write call F_writesector -.cleanup +.cleanup1: ex af, af' ; preserve flags pop af call SETPAGEB @@ -44,6 +46,3 @@ F_updateflash ei ret - include "../../rom/flashwrite.asm" -FLASHPROGLEN equ $-0x3000 - diff --git a/modules/config/fs_config_ui.asm b/modules/config/fs_config_ui.asm index 874dc78..08d3bc8 100644 --- a/modules/config/fs_config_ui.asm +++ b/modules/config/fs_config_ui.asm @@ -19,14 +19,16 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "ctrlchars.inc" +.include "flashconf.inc" +.include "sysvars.inc" -; Configuration UI functions. - ; Various library functions. - include "../../rom/ui_menu.asm" - +.text ;--------------------------------------------------------------------------- ; Handle BASIC entry/exit -F_start +.globl F_start +F_start: call STATEMENT_END ; runtime @@ -35,24 +37,26 @@ F_start ;--------------------------------------------------------------------------- ; Main configuration menu. -F_fsconfigmain - call F_copyconfig +.globl F_fsconfigmain +F_fsconfigmain: + call F_cond_copyconfig ld a, 0x1D ; first configuration table ld (v_workspace), a -.fsconfigloop +.fsconfigloop2: call CLEAR42 call F_showfs ld hl, MENU_setfs call F_genmenu ld hl, MENU_setfs call F_getmenuopt - jr z, .fsconfigloop ; user has not finished + jr z, .fsconfigloop2 ; user has not finished ret ;--------------------------------------------------------------------------- ; F_showfs ; Shows details of two mountpoints. -F_showfs +.globl F_showfs +F_showfs: ld a, (v_workspace) ; form the base address ld h, a ld l, 0x00 ; HL = 0x10.. @@ -72,7 +76,8 @@ F_showfs ; Shows a configuration. (A tedious routine...) ; HL = base address of configuration set. ; A = intended mount point -F_showconfig +.globl F_showconfig +F_showconfig: push af ld (v_hlsave), hl ; keep a copy ld hl, STR_curfs @@ -113,25 +118,27 @@ F_showconfig ;--------------------------------------------------------------------------- ; F_printifset: Only prints the item if it's actually set to something. -F_printifset +.globl F_printifset +F_printifset: ld a, (hl) cp 0xFF ; Not set at all? - jr z, .notset + jr z, .notset5 and a ; Set to null? - jr nz, .printit + jr nz, .printit5 ld hl, STR_null - jr .printit -.notset + jr .printit5 +.notset5: ld hl, STR_unset -.printit +.printit5: call PRINT42 -F_cr - ld a, '\n' +.globl F_cr +F_cr: + ld a, NEWLINE jp PUTCHAR42 ; Menu definitions -MENU_setfs +MENU_setfs: defw STR_show0and1, F_show0and1 defw STR_show1and2, F_show1and2 defw STR_chgproto, F_chgproto @@ -145,18 +152,21 @@ MENU_setfs ;---------------------------------------------------------------------------- ; F_show0and1 ; Show details for FS0 and FS1 -F_show0and1 +.globl F_show0and1 +F_show0and1: ld a, 0x1D ; MSB for FS0 ld (v_workspace), a xor a ; set zero flag ret -F_show1and2 +.globl F_show1and2 +F_show1and2: ld a, 0x1E ; MSB for FS2A ld (v_workspace), a xor a ret -F_chgproto +.globl F_chgproto +F_chgproto: call F_askfsnum jr c, zeroexit ; user abandoned push hl @@ -165,7 +175,8 @@ F_chgproto ld c, 6 ; max size jp F_getprotostring -F_chghost +.globl F_chghost +F_chghost: call F_askfsnum jr c, zeroexit ; user abandoned push hl @@ -174,7 +185,8 @@ F_chghost ld c, 41 ; max size jp F_getprotostring -F_chgrempath +.globl F_chgrempath +F_chgrempath: call F_askfsnum jr c, zeroexit ; user abandoned push hl @@ -182,18 +194,20 @@ F_chgrempath ld de, DEF_FS_SRCPTH0 % 256 ; requested address ld c, 48 ; max size -F_getprotostring +.globl F_getprotostring +F_getprotostring: call F_cr ; carriage return call PRINT42 ; print requested string pop hl ; get the base address add hl, de ; calculate address of protocol string ex de, hl call INPUTSTRING -zeroexit +zeroexit: xor a ; set Z ret -F_chguserpasswd +.globl F_chguserpasswd +F_chguserpasswd: call F_askfsnum jr c, zeroexit push hl @@ -212,7 +226,8 @@ F_chguserpasswd ld c, 16 jp F_getprotostring ; will pop HL -F_saveexit +.globl F_saveexit +F_saveexit: ld hl, STR_updating call PRINT42 @@ -225,17 +240,19 @@ F_saveexit jr c, borked ld hl, STR_flashdone call PRINT42 -F_abandon +.globl F_abandon +F_abandon: or 1 ; reset zero flag ret -borked +borked: ld hl, STR_writebork call PRINT42 jr F_abandon ;---------------------------------------------------------------------------- ; F_askfsnum: Ask the user to enter a filesystem number. -F_askfsnum +.globl F_askfsnum +F_askfsnum: ld hl, STR_fsnum call PRINT42 ld c, 2 ; Only one character @@ -243,24 +260,24 @@ F_askfsnum call INPUTSTRING ld a, (v_workspace+1) and a ; user abandoned? - jr z, .abandon + jr z, .abandon16 sub '0' ; convert to int cp 4 - jr nc, .invalid ; too big! + jr nc, .invalid16 ; too big! ccf ; reset carry ld l, 0 ; set LSB rra ; half and set carry if odd rr l ; and suck into msb of L - add 0x1D ; set MSB + add a, 0x1D ; set MSB ld h, a ; HL now points at base address ret -.invalid +.invalid16: ld hl, STR_invalidfs call PRINT42 jr F_askfsnum -.abandon +.abandon16: scf ret diff --git a/modules/config/fs_strings_en.asm b/modules/config/fs_strings_en.asm index 212bf3e..d082c64 100644 --- a/modules/config/fs_strings_en.asm +++ b/modules/config/fs_strings_en.asm @@ -21,35 +21,62 @@ ;THE SOFTWARE. ; English strings for the configuration utility. +.include "ctrlchars.inc" +.data +.globl STR_ident +.globl STR_basicinit +.globl STR_basinsterr +.globl STR_curfs +.globl STR_under +.globl STR_proto +.globl STR_host +.globl STR_rempath +.globl STR_user +.globl STR_unset +.globl STR_null +.globl STR_passwd +STR_ident: defb "Configtool 1.0",0 +STR_basicinit: defb "configtool initialized",NEWLINE,0 +STR_basinsterr: defb "Failed to initialize configtool",NEWLINE,0 -STR_ident defb "Configtool 1.0",0 -STR_basicinit defb "configtool initialized\n",0 -STR_basinsterr defb "Failed to initialize configtool\n",0 +STR_curfs: defb "Current settings for FS",0 +STR_under: defb NEWLINE,"========================",NEWLINE,NEWLINE,0 +STR_proto: defb "Proto: ",0 +STR_host: defb "Host : ",0 +STR_rempath: defb "Path : ",0 +STR_user: defb "User : ",0 +STR_unset: defb "Not set",0 +STR_null: defb "Null",0 +STR_passwd: defb "Password: ",0 -STR_curfs defb "Current settings for FS",0 -STR_under defb "\n========================\n\n",0 -STR_proto defb "Proto: ",0 -STR_host defb "Host : ",0 -STR_rempath defb "Path : ",0 -STR_user defb "User : ",0 -STR_unset defb "Not set",0 -STR_null defb "Null",0 -STR_passwd defb "Password: ",0 +.globl STR_show0and1 +.globl STR_show1and2 +.globl STR_chguser +.globl STR_chgproto +.globl STR_chghost +.globl STR_chgpath +.globl STR_saveexit +.globl STR_abandon +STR_show0and1: defb "Show details for FS 0 and 1",0 +STR_show1and2: defb "Show details for FS 2 and 3",0 +STR_chgproto: defb "Select protocol for an FS",0 +STR_chghost: defb "Select a host for an FS",0 +STR_chgpath: defb "Select the path on the host",0 +STR_chguser: defb "Set user/password for the host",0 +STR_saveexit: defb "Save configuration and exit",0 +STR_abandon: defb "Abandon changes and exit",0 -STR_show0and1 defb "Show details for FS 0 and 1",0 -STR_show1and2 defb "Show details for FS 2 and 3",0 -STR_chgproto defb "Select protocol for an FS",0 -STR_chghost defb "Select a host for an FS",0 -STR_chgpath defb "Select the path on the host",0 -STR_chguser defb "Set user/password for the host",0 -STR_saveexit defb "Save configuration and exit",0 -STR_abandon defb "Abandon changes and exit",0 +.globl STR_fsnum +.globl STR_invalidfs +STR_fsnum: defb "Filesystem (0-3): ",0 +STR_invalidfs: defb "Invalid FS number.",NEWLINE,0 -STR_fsnum defb "Filesystem (0-3): ",0 -STR_invalidfs defb "Invalid FS number.\n",0 - -STR_updating defb "Updating flash...\n",0 -STR_flashdone defb "Complete.\n",0 -STR_erasebork defb "Erase failed!\n",0 -STR_writebork defb "Write failed!\n",0 +.globl STR_updating +.globl STR_flashdone +.globl STR_erasebork +.globl STR_writebork +STR_updating: defb "Updating flash...",NEWLINE,0 +STR_flashdone: defb "Complete.",NEWLINE,0 +STR_erasebork: defb "Erase failed!",NEWLINE,0 +STR_writebork: defb "Write failed!",NEWLINE,0 diff --git a/modules/config/gen_copycfg.asm b/modules/config/gen_copycfg.asm index 44bb999..f1b1af2 100644 --- a/modules/config/gen_copycfg.asm +++ b/modules/config/gen_copycfg.asm @@ -25,20 +25,17 @@ ; This allows the configuration to be edited. (The next step is to erase ; the last 16k sector, then copy back the updated configuration plus the ; existing content in the remainder of the last sector of flash). -F_copyconfig - call F_getsysvar ; see if we've already copied it - inc hl - ld a, 1 - cp (hl) ; if Z we've already made a copy - ret z - ld (hl), 1 ; Indicate a copy has been made. +.include "spectranet.inc" +.text +.globl F_copyconfig +F_copyconfig: - ld hl, .copier ; first, copy to RAM workspace + ld hl, .copier1 ; first, copy to RAM workspace ld de, 0x3000 ; fixed workspace page at 0x3000 - ld bc, .copierend-.copier + ld bc, copiersz ldir jp 0x3000 -.copier +.copier1: ld a, 0xDC ; chip 3 page 0x1C - RAM call SETPAGEA ; page it into page area A ld a, 0x1C ; chip 0 page 0x1C - flash @@ -73,7 +70,7 @@ F_copyconfig ldir call POPPAGEB ; reset page B settings before returning (to page B!) - ret ; configuration settings are in RAM mapped in page AA -.copierend +.copierend1: +copiersz equ .copierend1 - .copier1 diff --git a/modules/config/if_config_ui.asm b/modules/config/if_config_ui.asm index 4af1252..c292e65 100644 --- a/modules/config/if_config_ui.asm +++ b/modules/config/if_config_ui.asm @@ -19,7 +19,12 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "if_defs.inc" +.include "spectranet.inc" +.include "flashconf.inc" +.include "ctrlchars.inc" +.include "sysvars.inc" +.text ;------------------------------------------------------------------------- ; Configuration user interface. ; This essentially forms a program that gets run from ROM page 1, paged @@ -30,7 +35,8 @@ ; Show the current configuration. This is a rather tedious routine that ; does a lot of calls to the print a string routine and various conversion ; routines. -F_showcurrent +.globl F_showcurrent +F_showcurrent: call CLEAR42 ld hl, STR_currset ; print 'Current settings' @@ -41,32 +47,32 @@ F_showcurrent call PRINT42 ld hl, 0x1000 + INITFLAGS bit INIT_STATICIP, (hl) - jr z, .yes + jr z, .yes1 ld hl, STR_no call PRINT42 - jr .continue -.yes + jr .continue1 +.yes1: ld hl, STR_yes call PRINT42 -.continue +.continue1: ; Print IPv4 settings. ld hl, TABLE_config -.showconfig +.showconfig1: ld e, (hl) inc hl ld d, (hl) inc hl ld a, d ; End of table encountered? or e - jr z, .printhwaddr ; yes; null terminator. + jr z, .printhwaddr1 ; yes; null terminator. push hl ; save current pointer ex de, hl call PRINT42 ; print the string that was pointed to. pop hl ld a, (0x1000 + INITFLAGS) ; should we print an address? bit INIT_STATICIP, a ; non zero = static IP configuration - jr z, .bydhcp + jr z, .bydhcp1 ld e, (hl) ; get low order of configuration address inc hl ld d, (hl) ; high order of configuration address @@ -76,20 +82,20 @@ F_showcurrent ld de, buf_workspace call LONG2IPSTRING ; convert it to a string ld hl, buf_workspace ; and print it. -.printresult +.printresult1: call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 pop hl - jr .showconfig ; continue with next entry -.bydhcp + jr .showconfig1 ; continue with next entry +.bydhcp1: inc hl ; point hl at next entry inc hl push hl ; save it ld hl, STR_bydhcp - jr .printresult + jr .printresult1 -.printhwaddr +.printhwaddr1: ; print the current hardware (MAC) address ld hl, STR_currhwaddr call PRINT42 @@ -98,7 +104,7 @@ F_showcurrent call MAC2STRING ld hl, buf_workspace call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ; print the current hostname @@ -107,12 +113,12 @@ F_showcurrent ld hl, 0x1000 + HOSTNAME ld a, (hl) ; has it ever been set? cp 0xFF - jr nz, .printhost + jr nz, .printhost1 ld hl, STR_vunset -.printhost +.printhost1: ld hl, 0x1000 + HOSTNAME call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ret @@ -120,20 +126,21 @@ F_showcurrent ; F_setdhcp: ; Ask the user whethe to use DHCP or not. ; Called by F_getmenuopt. -F_setdhcp +.globl F_setdhcp +F_setdhcp: ld hl, STR_dhcpquestion call PRINT42 -.keyloop +.keyloop2: call GETKEY cp 'y' - jr nz, .noty + jr nz, .noty2 ld hl, 0x1000 + INITFLAGS res INIT_STATICIP, (hl) ; set 'use static IP' to 0 xor a ; return 0 (non terminal menu option) ret -.noty +.noty2: cp 'n' - jr nz, .keyloop ; try again + jr nz, .keyloop2 ; try again ld hl, 0x1000 + INITFLAGS set INIT_STATICIP, (hl) ; set 'use static ip' bit xor a ; return 0 (non terminal menu option) @@ -142,16 +149,17 @@ F_setdhcp ;----------------------------------------------------------------------- ; F_setipaddr ; Asks the user for an IP address. -F_setipaddr +.globl F_setipaddr +F_setipaddr: ld hl, STR_abort call PRINT42 -.askloop +.askloop3: ld hl, STR_askip call PRINT42 call F_getipstr - jr c, .askloop ; try again + jr c, .askloop3 ; try again ld de, 0x1000 + IP_ADDRESS -copyquad +copyquad: ld hl, buf_hex ; copy the address into config area ld a, (hl) and a ; nothing there? @@ -163,54 +171,59 @@ copyquad xor a ; set zero flag ret -F_setnetmask +.globl F_setnetmask +F_setnetmask: ld hl, STR_abort call PRINT42 -.askloop +.askloop4: ld hl, STR_asknetmask call PRINT42 call F_getipstr - jr c, .askloop + jr c, .askloop4 ld de, 0x1000 + IP_SUBNET jr copyquad -F_setgateway +.globl F_setgateway +F_setgateway: ld hl, STR_abort call PRINT42 -.askloop +.askloop5: ld hl, STR_askgw call PRINT42 call F_getipstr - jr c, .askloop + jr c, .askloop5 ld de, 0x1000 + IP_GATEWAY jr copyquad -F_setpridns +.globl F_setpridns +F_setpridns: ld hl, STR_abort call PRINT42 -.askloop +.askloop6: ld hl, STR_askpridns call PRINT42 call F_getipstr - jr c, .askloop + jr c, .askloop6 ld de, 0x1000 + PRI_DNS jr copyquad -F_setsecdns +.globl F_setsecdns +F_setsecdns: ld hl, STR_abort call PRINT42 -.askloop +.askloop7: ld hl, STR_asksecdns call PRINT42 call F_getipstr - jr c, .askloop + jr c, .askloop7 ld de, 0x1000 + SEC_DNS jr copyquad ;------------------------------------------------------------------------- ; F_getipstr ; Get an IP-like string (i.e. inet addr, netmask, gateway) -F_getipstr +.globl F_getipstr +F_getipstr: ld c, 16 ; maximum length of an IP address string ld de, buf_addr call INPUTSTRING @@ -229,10 +242,11 @@ F_getipstr ;----------------------------------------------------------------------- ; F_sethwaddr ; Get a hardware address from the user. -F_sethwaddr +.globl F_sethwaddr +F_sethwaddr: ld hl, STR_abort call PRINT42 -.askloop +.askloop9: ld hl, STR_askhw call PRINT42 ld c, 18 ; hw address is 18 bytes long @@ -244,22 +258,23 @@ F_sethwaddr ret z ; nothing entered, so do nothing ld de, buf_hex call STRING2MAC - jr c, .badmac ; carry set? Couldn't interpret address + jr c, .badmac9 ; carry set? Couldn't interpret address ld hl, buf_hex ld de, 0x1000 + HW_ADDRESS ld bc, 6 ldir xor a ; ensure Z is set ret -.badmac +.badmac9: ld hl, STR_invalidip call PRINT42 - jr .askloop + jr .askloop9 ;----------------------------------------------------------------------- ; F_sethostname ; Sets the computer's hostname -F_sethostname +.globl F_sethostname +F_sethostname: ld hl, STR_abort call PRINT42 ld hl, STR_askhostname @@ -280,11 +295,13 @@ F_sethostname ;----------------------------------------------------------------------- ; F_cancelconfig: ; Bale out of the menu. -F_cancelconfig +.globl F_cancelconfig +F_cancelconfig: or 1 ; reset zero flag ret - -MENU_config +.data +.globl MENU_config +MENU_config: defw STR_dhcp, F_setdhcp defw STR_ipaddr, F_setipaddr defw STR_netmask, F_setnetmask @@ -296,7 +313,8 @@ MENU_config defw STR_save, F_saveconfig defw STR_cancel, F_cancelconfig defw 0,0 -TABLE_config +.globl TABLE_config +TABLE_config: defw STR_currip, 0x1000+IP_ADDRESS defw STR_currmask, 0x1000+IP_SUBNET defw STR_currgw, 0x1000+IP_GATEWAY diff --git a/modules/config/if_configmain.asm b/modules/config/if_configmain.asm index cd680fc..1bff142 100644 --- a/modules/config/if_configmain.asm +++ b/modules/config/if_configmain.asm @@ -19,18 +19,22 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.text ; The configuration utility main routine. -F_ifconfig +.globl F_ifconfig +F_ifconfig: call STATEMENT_END ; no args ;--- runtime --- call F_if_configmain jp EXIT_SUCCESS -F_if_configmain - call F_copyconfig -.menuloop +.globl F_if_configmain +F_if_configmain: + call F_cond_copyconfig +.menuloop2: call F_showcurrent ld hl, STR_choose call PRINT42 @@ -39,7 +43,7 @@ F_if_configmain ld hl, MENU_config call F_getmenuopt - jr z, .menuloop + jr z, .menuloop2 ret diff --git a/modules/config/if_defs.asm b/modules/config/if_defs.inc similarity index 100% rename from modules/config/if_defs.asm rename to modules/config/if_defs.inc diff --git a/modules/config/if_menu_ui.asm b/modules/config/if_menu_ui.asm deleted file mode 100644 index dd6a7af..0000000 --- a/modules/config/if_menu_ui.asm +++ /dev/null @@ -1,91 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; Simple menu system routines. - -;-------------------------------------------------------------------------- -; F_genmenu -; Generates a menu screen. -; Parameters: HL = pointer to menu structure, that should be a null terminated -; list of pointers to strings that define the choices. -F_genmenu - ld b, 'A' ; first option is 'A' -.loop - ld e, (hl) ; get pointer into DE - inc hl - ld d, (hl) - inc hl - inc hl ; go past the call address - inc hl - ld a, d - or e ; check to see whether we've just got the last one - ret z - ld a, '[' - call PUTCHAR42 ; print [ - ld a, b - call PUTCHAR42 ; print the option - ld a, ']' - call PUTCHAR42 ; print ] - ld a, ' ' - call PUTCHAR42 ; and one space separator - ex de, hl ; get string pointer into hl - call PRINT42 ; print the menu option - ex de, hl ; move the menu pointer back - ld a, '\n' ; print a CR - call PUTCHAR42 - inc b ; update option character - jr .loop - -;------------------------------------------------------------------------- -; F_getmenuopt: -; Wait for the user to press a key, then call the appropriate routine. -F_getmenuopt - ld (v_hlsave), hl ; save HL without disturbing stack -.getkey - call GETKEY ; wait for key to be pressed - ld hl, (v_hlsave) - sub 'a' ; ASCII a = 0 - jr c, .getkey ; key pressed was < 'a' -.loop - push af - ld a, (hl) - inc hl - or (hl) ; Null terminator? - jr z, .outofrange - inc hl ; hl points at call entry - pop af - and a ; A=0? - jr z, .callopt - dec a - inc hl ; advance past string pointer - inc hl - jr .loop -.outofrange - pop af ; fix stack - jr .getkey ; try again -.callopt - ld e, (hl) ; get call address into DE - inc hl - ld d, (hl) - ex de, hl - jp (hl) ; jump to the routine - diff --git a/modules/config/if_saveconfig.asm b/modules/config/if_saveconfig.asm index f563292..843643e 100644 --- a/modules/config/if_saveconfig.asm +++ b/modules/config/if_saveconfig.asm @@ -19,11 +19,21 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.data +.globl FLASHPROGSTART +.globl FLASHPROGLEN +FLASHPROGSTART: +.incbin "flashwrite.bin" +FLASHPROGEND: +FLASHPROGLEN equ FLASHPROGEND-FLASHPROGSTART +.text ;----------------------------------------------------------------------- ; F_saveconfig ; Saves the configuration the user just entered. -F_saveconfig +.globl F_saveconfig +F_saveconfig: ld hl, STR_saving call PRINT42 @@ -34,7 +44,7 @@ F_saveconfig ldir call 0x3000 ret nc -.bork +.bork1: call PRINT42 call GETKEY ; give the user a chance to see the msg or 1 diff --git a/modules/config/if_strings_en.asm b/modules/config/if_strings_en.asm index 8efc219..366a65c 100644 --- a/modules/config/if_strings_en.asm +++ b/modules/config/if_strings_en.asm @@ -22,43 +22,81 @@ ; ; English language messages for configuring the Spectranet. ; -STR_choose defb "\n\nChoose a configuration option:\n",0 -STR_dhcp defb "Enable/disable DHCP",0 -STR_ipaddr defb "Change IP address",0 -STR_netmask defb "Change netmask", 0 -STR_gateway defb "Change default gateway", 0 -STR_hostname defb "Change hostname", 0 -STR_pridns defb "Change primary DNS",0 -STR_secdns defb "Change secondary DNS",0 -STR_hwaddr defb "Change hardware address", 0 -STR_save defb "Save changes and exit",0 -STR_cancel defb "Cancel changes and exit",0 +.include "ctrlchars.inc" +.data +.globl STR_choose +.globl STR_dhcp +.globl STR_ipaddr +.globl STR_netmask +.globl STR_gateway +.globl STR_hostname +.globl STR_pridns +.globl STR_secdns +.globl STR_hwaddr +.globl STR_save +.globl STR_cancel +STR_choose: defb NEWLINE,NEWLINE,"Choose a configuration option:",NEWLINE,0 +STR_dhcp: defb "Enable/disable DHCP",0 +STR_ipaddr: defb "Change IP address",0 +STR_netmask: defb "Change netmask", 0 +STR_gateway: defb "Change default gateway", 0 +STR_hostname: defb "Change hostname", 0 +STR_pridns: defb "Change primary DNS",0 +STR_secdns: defb "Change secondary DNS",0 +STR_hwaddr: defb "Change hardware address", 0 +STR_save: defb "Save changes and exit",0 +STR_cancel: defb "Cancel changes and exit",0 -STR_currset defb "Current configuration\n=====================\n",0 -STR_usedhcp defb "Use DHCP : ",0 -STR_currip defb "IP address : ",0 -STR_currmask defb "Netmask : ",0 -STR_currgw defb "Default gateway : ",0 -STR_currhwaddr defb "Hardware address : ",0 -STR_currhost defb "Hostname : ",0 -STR_currpridns defb "Primary DNS : ",0 -STR_currsecdns defb "Secondary DNS : ",0 -STR_no defb "No\n",0 -STR_yes defb "Yes\n",0 -STR_bydhcp defb "Set by DHCP",0 -STR_vunset defb "[unset]",0 +.globl STR_currset +.globl STR_usedhcp +.globl STR_currip +.globl STR_currmask +.globl STR_currgw +.globl STR_currhwaddr +.globl STR_currhost +.globl STR_currpridns +.globl STR_currsecdns +.globl STR_no +.globl STR_yes +.globl STR_bydhcp +.globl STR_vunset +STR_currset: defb "Current configuration",NEWLINE,"=====================",NEWLINE,0 +STR_usedhcp: defb "Use DHCP : ",0 +STR_currip: defb "IP address : ",0 +STR_currmask: defb "Netmask : ",0 +STR_currgw: defb "Default gateway : ",0 +STR_currhwaddr: defb "Hardware address : ",0 +STR_currhost: defb "Hostname : ",0 +STR_currpridns: defb "Primary DNS : ",0 +STR_currsecdns: defb "Secondary DNS : ",0 +STR_no: defb "No",NEWLINE,0 +STR_yes: defb "Yes",NEWLINE,0 +STR_bydhcp: defb "Set by DHCP",0 +STR_vunset: defb "[unset]",0 -STR_abort defb "Enter on a blank line aborts\n",0 -STR_invalidip defb "\nSorry, that wasn't a valid address.\n",0 -STR_dhcpquestion defb "\nUse DHCP? (Y/N): ",0 -STR_askip defb "\nIP address: ",0 -STR_asknetmask defb "\nNetmask: ",0 -STR_askgw defb "\nGateway: ",0 -STR_askhw defb "\nHardware address: ",0 -STR_askhostname defb "\nHostname: ",0 -STR_askpridns defb "\nPrimary DNS: ",0 -STR_asksecdns defb "\nSecondary DNS: ",0 +.globl STR_abort +.globl STR_invalidip +.globl STR_dhcpquestion +.globl STR_askip +.globl STR_asknetmask +.globl STR_askgw +.globl STR_askhw +.globl STR_askhostname +.globl STR_askpridns +.globl STR_asksecdns +STR_abort: defb "Enter on a blank line aborts",NEWLINE,0 +STR_invalidip: defb NEWLINE,"Sorry, that wasn't a valid address.",NEWLINE,0 +STR_dhcpquestion: defb NEWLINE,"Use DHCP? (Y/N): ",0 +STR_askip: defb NEWLINE,"IP address: ",0 +STR_asknetmask: defb NEWLINE,"Netmask: ",0 +STR_askgw: defb NEWLINE,"Gateway: ",0 +STR_askhw: defb NEWLINE,"Hardware address: ",0 +STR_askhostname: defb NEWLINE,"Hostname: ",0 +STR_askpridns: defb NEWLINE,"Primary DNS: ",0 +STR_asksecdns: defb NEWLINE,"Secondary DNS: ",0 -STR_saving defb "\nSaving configuration...",0 -STR_done defb "Done\n",0 +.globl STR_saving +.globl STR_done +STR_saving: defb NEWLINE,"Saving configuration...",0 +STR_done: defb "Done",NEWLINE,0 diff --git a/modules/config/init.asm b/modules/config/init.asm index 97d2b6c..2c61265 100644 --- a/modules/config/init.asm +++ b/modules/config/init.asm @@ -19,17 +19,20 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.text ; Initialize the module - install our BASIC command -F_init +.globl F_init +F_init: ld hl, PARSETABLE ld b, numcmds -.loop +.loop1: push bc call ADDBASICEXT pop bc - jr c, .installerror - djnz .loop + jr c, .installerror1 + djnz .loop1 ; init local 8 byte sysvar area. call F_getsysvar @@ -39,51 +42,52 @@ F_init ld hl, STR_basicinit call PRINT42 ret -.installerror +.installerror1: ld hl, STR_basinsterr call PRINT42 ret -PARSETABLE -numcmds equ 8 -P_fsconfig defb 0x0b ; Trap C Nonsense in BASIC +.data +PARSETABLE: +numcmds: equ 8 +P_fsconfig: defb 0x0b ; Trap C Nonsense in BASIC defw CMD_FSCONFIG defb 0xFF ; this page defw F_start -P_ifconfig defb 0x0b ; Trap C Nonsense in BASIC +P_ifconfig: defb 0x0b ; Trap C Nonsense in BASIC defw CMD_IFCONFIG defb 0xFF ; this page defw F_ifconfig -P_cfgset defb 0x0b +P_cfgset: defb 0x0b defw CMD_CFGSET defb 0xFF defw F_cfgset -P_cfgsetstr defb 0x0b +P_cfgsetstr: defb 0x0b defw CMD_CFGSET_STR defb 0xFF defw F_cfgset_string -P_cfgcommit defb 0x0b +P_cfgcommit: defb 0x0b defw CMD_CFGCOMMIT defb 0xFF defw F_cfgcommit -P_cfgabandon defb 0x0b +P_cfgabandon: defb 0x0b defw CMD_CFGABANDON defb 0xFF defw F_cfgabandon -P_cfgnew defb 0x0b +P_cfgnew: defb 0x0b defw CMD_CFGNEW defb 0xFF defw F_cfgnew -P_cfgnewsec defb 0x0b +P_cfgnewsec: defb 0x0b defw CMD_CFGNEWSEC defb 0xFF defw F_cfgnewsec -CMD_FSCONFIG defb "%fsconfig",0 -CMD_IFCONFIG defb "%ifconfig",0 -CMD_CFGSET defb "%cfgset",0 -CMD_CFGSET_STR defb "%cfgset$",0 -CMD_CFGCOMMIT defb "%cfgcommit",0 -CMD_CFGABANDON defb "%cfgabandon",0 -CMD_CFGNEW defb "%cfgnew",0 -CMD_CFGNEWSEC defb "%cfgnewsec",0 +CMD_FSCONFIG: defb "%fsconfig",0 +CMD_IFCONFIG: defb "%ifconfig",0 +CMD_CFGSET: defb "%cfgset",0 +CMD_CFGSET_STR: defb "%cfgset$",0 +CMD_CFGCOMMIT: defb "%cfgcommit",0 +CMD_CFGABANDON: defb "%cfgabandon",0 +CMD_CFGNEW: defb "%cfgnew",0 +CMD_CFGNEWSEC: defb "%cfgnewsec",0 diff --git a/modules/config/makenewcfg.asm b/modules/config/makenewcfg.asm index 52e84cd..6cfe65c 100644 --- a/modules/config/makenewcfg.asm +++ b/modules/config/makenewcfg.asm @@ -55,9 +55,9 @@ J_exit jp PAGEOUT str_creating - defb "Creating new configuration\n",0 + defb "Creating new configuration",NEWLINE,0 str_commiterr - defb "Unable to commit to flash\n",0 + defb "Unable to commit to flash",NEWLINE,0 str_done - defb "Done.\n",0 + defb "Done.",NEWLINE,0 diff --git a/modules/config/sa_flashwrite.asm b/modules/config/sa_flashwrite.asm index 6823b4b..064bc5c 100644 --- a/modules/config/sa_flashwrite.asm +++ b/modules/config/sa_flashwrite.asm @@ -20,18 +20,16 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. -F_updateflash +.globl F_updateflash +F_updateflash: di ld a, 0x1C ; last sector of flash call F_FlashEraseSector - jr c, .cleanup + jr c, .cleanup1 ld a, 0x1C ; start page to write call F_writesector -.cleanup +.cleanup1: ld a, 2 out (254), a ei ret - - include "../../rom/flashwrite.asm" - diff --git a/modules/config/sa_if_saveconfig.asm b/modules/config/sa_if_saveconfig.asm index a58c7a5..34b55a7 100644 --- a/modules/config/sa_if_saveconfig.asm +++ b/modules/config/sa_if_saveconfig.asm @@ -19,11 +19,13 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "spectranet.inc" +.text ;----------------------------------------------------------------------- ; F_saveconfig ; Saves the configuration the user just entered. -F_saveconfig +.globl F_saveconfig +F_saveconfig: ld a, 4 out (254), a ld hl, STR_saving @@ -33,7 +35,7 @@ F_saveconfig ld a, 3 out (254), a ret nc -.bork +.bork1: call PRINT42 call GETKEY ; give the user a chance to see the msg or 1 diff --git a/modules/config/standalone_ifconfig.asm b/modules/config/standalone_ifconfig.asm index 64f5c64..b150ec7 100644 --- a/modules/config/standalone_ifconfig.asm +++ b/modules/config/standalone_ifconfig.asm @@ -21,23 +21,22 @@ ;THE SOFTWARE. ; Standalone configuration utility. - - org 0x8000 +.include "spectranet.inc" +.text di call PAGEIN - call F_if_configmain + call F_copyconfig +.menuloop2: + call F_showcurrent + ld hl, STR_choose + call PRINT42 + ld hl, MENU_config + call F_genmenu + + ld hl, MENU_config + call F_getmenuopt + jr z, .menuloop2 + ei jp PAGEOUT - include "gen_copycfg.asm" - include "if_configmain.asm" - include "if_config_ui.asm" - include "if_menu_ui.asm" - include "if_strings_en.asm" - include "sa_if_saveconfig.asm" - include "sa_flashwrite.asm" - include "../../rom/spectranet.asm" - include "../../rom/sysvars.asm" - include "../../rom/flashconf.asm" - include "if_defs.asm" - diff --git a/modules/config/vectors.asm b/modules/config/vectors.asm index de6cc5c..9c978c4 100644 --- a/modules/config/vectors.asm +++ b/modules/config/vectors.asm @@ -23,17 +23,18 @@ ; Filesystem Configuration Utility module ; This is a ROM module. -sig defb 0xAA ; This is a ROM module -romid defb 0xFE ; ID = 0xFE -reset defw F_init ; reset vector -mount defw 0xFFFF ; not a filesystem - defw 0xFFFF - defw 0xFFFF - defw 0xFFFF - defw 0xFFFF -idstr defw STR_ident ; ROM identity string +.section vectors +sig: defb 0xAA ; This is a ROM module +romid: defb 0xFE ; ID = 0xFE +reset: defw F_init ; reset vector +mount: defw 0xFFFF ; not a filesystem + defw 0xFFFF + defw 0xFFFF + defw 0xFFFF + defw 0xFFFF +idstr: defw STR_ident ; ROM identity string -modcall +modcall: ex af, af' ; preserve any args in A xor a cp l ; 0x00? Configuration menu. @@ -41,7 +42,7 @@ modcall inc a cp l ; 0x01 - jp z, F_copyconfig + jp z, F_cond_copyconfig inc a cp l ; 0x02 diff --git a/modules/make.inc b/modules/make.inc new file mode 100644 index 0000000..1ff1da6 --- /dev/null +++ b/modules/make.inc @@ -0,0 +1,21 @@ +AS = z80-unknown-coff-as +LD = z80-unknown-coff-ld +RM = rm +ASFLAGS = -I../../include +MAPFILE = $(OUT).map +LDFLAGS = -T ../modules.ld -Map $(MAPFILE) -L ../../syslib +INSTALLDIR = ../../installer +CP = cp -f + +.PHONY: clean + +module: $(ASOBJS) + $(LD) -o $(OUT) $(ASOBJS) $(LDFLAGS) $(LIBPATH) $(LIBS) + $(CP) $(OUT) $(INSTALLDIR) + +%.o : %.asm + $(AS) $(ASFLAGS) $< -o $@ + +clean: + $(RM) -f *.o *.module *.bin *.map + diff --git a/modules/messages/Makefile b/modules/messages/Makefile new file mode 100644 index 0000000..d9519eb --- /dev/null +++ b/modules/messages/Makefile @@ -0,0 +1,4 @@ +ASOBJS = getmsg.o messages_en.o vectors.o +OUT = msgrom.module +include ../make.inc + diff --git a/modules/messages/build b/modules/messages/build deleted file mode 100755 index faabf0b..0000000 --- a/modules/messages/build +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -echo `pwd`/msgrom.out >> ../../build.out -sjasmplus msgrom.asm --lst=msgrom.lst -exit $? - diff --git a/modules/messages/getmsg.asm b/modules/messages/getmsg.asm index c1c8b58..d2146d6 100644 --- a/modules/messages/getmsg.asm +++ b/modules/messages/getmsg.asm @@ -19,41 +19,43 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.text ; Get an error message. -F_getmessage +.globl F_getmessage +F_getmessage: ld a, l ; Get message ID from caller. bit 7, a ; MSB set? - jr z, .lowtable + jr z, .lowtable1 ld hl, STR_HITABLE - ld bc, HITABLE_END - STR_HITABLE + ld bc, HITABLE_LEN sub HITABLE_LOWEST - jr .continue -.lowtable - ld hl, STR_SUCCESS ; pointer at start of table - ld bc, ERR_TABLE_END - STR_SUCCESS -.continue + jr .continue1 +.lowtable1: + ld hl, STRING_TABLE ; pointer at start of table + ld bc, ERR_TABLE_LEN +.continue1: and a ; code 0 (success?) ret z ; return now. push de ; Save destination address ld d, a ; set counter xor a ; reset A to search for terminator -.findloop +.findloop1: cpir ; find next null - jp po, .nomsg ; cpir ran out of data? + jp po, .nomsg1 ; cpir ran out of data? dec d ; decrement loop counter - jr nz, .findloop ; if Z is not set go for another run + jr nz, .findloop1 ; if Z is not set go for another run pop de ; get destination address back xor a -.strcpy +.strcpy1: ldi cp (hl) ; End of the string? - jr nz, .strcpy + jr nz, .strcpy1 ld (de), a ; stick the null on the end ret -.nomsg +.nomsg1: pop de scf ret diff --git a/modules/messages/messages_en.asm b/modules/messages/messages_en.asm index b43374c..23c3b86 100644 --- a/modules/messages/messages_en.asm +++ b/modules/messages/messages_en.asm @@ -21,69 +21,78 @@ ;THE SOFTWARE. ; String table - -STRING_TABLE -STR_SUCCESS defb "Success",0 ; 0x00 -STR_EPERM defb "Operation not permitted",0 ; 0x01 -STR_ENOENT defb "No such file or directory",0 ; 0x02 -STR_EIO defb "I/O error",0 ; 0x03 -STR_ENXIO defb "No such device or address",0 ; 0x04 -STR_E2BIG defb "Too many arguments",0 ; 0x05 -STR_EBADF defb "Bad file descriptor",0 ; 0x06 -STR_EAGAIN defb "Operation would block",0 ; 0x07 -STR_ENOMEM defb "Out of memory",0 ; 0x08 -STR_EACCES defb "Permission denied",0 ; 0x09 -STR_EBUSY defb "Device or resource busy",0 ; 0x0A -STR_EEXIST defb "File exists",0 ; 0x0B -STR_ENOTDIR defb "Not a directory",0 ; 0x0C -STR_EISDIR defb "Is a directory",0 ; 0x0D -STR_EINVAL defb "Invalid argument",0 ; 0x0E -STR_ENFILE defb "File table overflow",0 ; 0x0F -STR_EMFILE defb "Too many open files",0 ; 0x10 -STR_EFBIG defb "File too large",0 ; 0x11 -STR_ENOSPC defb "Filesystem full",0 ; 0x12 -STR_ESPIPE defb "Attempt to seek on a pipe",0 ; 0x13 -STR_EROFS defb "Read only filesystem",0 ; 0x14 -STR_ENAMETOOLONG defb "Filename too long",0 ; 0x15 -STR_ENOSYS defb "Not implemented",0 ; 0x16 -STR_ENOTEMPTY defb "Directory not empty",0 ; 0x17 -STR_ELOOP defb "Too many links",0 ; 0x18 -STR_ENODATA defb "No data available",0 ; 0x19 -STR_ENOSTR defb "Out of streams",0 ; 0x1A -STR_EPROTO defb "Protocol error",0 ; 0x1B -STR_EBADFD defb "File descriptor state bad",0 ; 0x1C -STR_EUSERS defb "Too many users",0 ; 0x1D -STR_ENOBUFS defb "No buffer space available",0 ; 0x1E -STR_EALREADY defb "Operation already running",0 ; 0x1F -STR_ESTALE defb "Stale TNFS handle",0 ; 0x20 -STR_EOF defb "End of file",0 ; 0x21 +.data +.globl STRING_TABLE +STRING_TABLE: +STR_SUCCESS: defb "Success",0 ; 0x00 +STR_EPERM: defb "Operation not permitted",0 ; 0x01 +STR_ENOENT: defb "No such file or directory",0 ; 0x02 +STR_EIO: defb "I/O error",0 ; 0x03 +STR_ENXIO: defb "No such device or address",0 ; 0x04 +STR_E2BIG: defb "Too many arguments",0 ; 0x05 +STR_EBADF: defb "Bad file descriptor",0 ; 0x06 +STR_EAGAIN: defb "Operation would block",0 ; 0x07 +STR_ENOMEM: defb "Out of memory",0 ; 0x08 +STR_EACCES: defb "Permission denied",0 ; 0x09 +STR_EBUSY: defb "Device or resource busy",0 ; 0x0A +STR_EEXIST: defb "File exists",0 ; 0x0B +STR_ENOTDIR: defb "Not a directory",0 ; 0x0C +STR_EISDIR: defb "Is a directory",0 ; 0x0D +STR_EINVAL: defb "Invalid argument",0 ; 0x0E +STR_ENFILE: defb "File table overflow",0 ; 0x0F +STR_EMFILE: defb "Too many open files",0 ; 0x10 +STR_EFBIG: defb "File too large",0 ; 0x11 +STR_ENOSPC: defb "Filesystem full",0 ; 0x12 +STR_ESPIPE: defb "Attempt to seek on a pipe",0 ; 0x13 +STR_EROFS: defb "Read only filesystem",0 ; 0x14 +STR_ENAMETOOLONG: defb "Filename too long",0 ; 0x15 +STR_ENOSYS: defb "Not implemented",0 ; 0x16 +STR_ENOTEMPTY: defb "Directory not empty",0 ; 0x17 +STR_ELOOP: defb "Too many links",0 ; 0x18 +STR_ENODATA: defb "No data available",0 ; 0x19 +STR_ENOSTR: defb "Out of streams",0 ; 0x1A +STR_EPROTO: defb "Protocol error",0 ; 0x1B +STR_EBADFD: defb "File descriptor state bad",0 ; 0x1C +STR_EUSERS: defb "Too many users",0 ; 0x1D +STR_ENOBUFS: defb "No buffer space available",0 ; 0x1E +STR_EALREADY: defb "Operation already running",0 ; 0x1F +STR_ESTALE: defb "Stale TNFS handle",0 ; 0x20 +STR_EOF: defb "End of file",0 ; 0x21 ; Non-protocol error messages -STR_TIMEOUT defb "Operation timed out",0 ; 0x22 -STR_NOTMOUNTED defb "Filesystem not mounted",0 ; 0x23 -STR_BADLENGTH defb "Incorrect header length",0 ; 0x24 -STR_BADTYPE defb "Incorrect block type",0 ; 0x25 -STR_UNKTYPE defb "Unknown file type",0 ; 0x26 -STR_MISMCHLEN defb "Data block length mismatch",0 ; 0x27 -STR_EBADURL defb "Bad URL",0 ; 0x28 -STR_EBADFS defb "Bad filesystem number",0 ; 0x29 +STR_TIMEOUT: defb "Operation timed out",0 ; 0x22 +STR_NOTMOUNTED: defb "Filesystem not mounted",0 ; 0x23 +STR_BADLENGTH: defb "Incorrect header length",0 ; 0x24 +STR_BADTYPE: defb "Incorrect block type",0 ; 0x25 +STR_UNKTYPE: defb "Unknown file type",0 ; 0x26 +STR_MISMCHLEN: defb "Data block length mismatch",0 ; 0x27 +STR_EBADURL: defb "Bad URL",0 ; 0x28 +STR_EBADFS: defb "Bad filesystem number",0 ; 0x29 + +ERR_TABLE_END: +STR_UNKNOWN: defb "Unknown error",0 -ERR_TABLE_END -STR_UNKNOWN defb "Unknown error",0 +.globl ERR_TABLE_LEN +ERR_TABLE_LEN equ ERR_TABLE_END - STRING_TABLE ; Base rom messages -STR_HITABLE +.globl STR_HITABLE +.globl HITABLE_LOWEST +STR_HITABLE: HITABLE_LOWEST equ 0xEC -STR_DNS_TIMEOUT defb "DNS timeout",0 ; 0xEC -STR_NO_ADDRESS defb "No address",0 ; 0xED -STR_NO_RECOVERY defb "No recovery",0 ; 0xEE -STR_HOST_NOT_FOUND defb "Host not found",0 ; 0xEF +STR_DNS_TIMEOUT: defb "DNS timeout",0 ; 0xEC +STR_NO_ADDRESS: defb "No address",0 ; 0xED +STR_NO_RECOVERY: defb "No recovery",0 ; 0xEE +STR_HOST_NOT_FOUND: defb "Host not found",0 ; 0xEF defb 0,0,0,0,0,0,0,0,0,0 ; 0xF0-0xF9 -STR_ECONNREFUSED defb "Connection refused",0 ; 0xFA -STR_ETIMEDOUT defb "Socket timeout",0 ; 0xFB -STR_ECONNRESET defb "Connection reset by peer",0 ; 0xFC -STR_ESBADF defb "Bad socket descriptor",0 ; 0xFD -STR_ESNFILE defb "Invalid socket descriptor",0 ; 0xFE -STR_EUNK defb "General socket error",0 ; 0xFF -HITABLE_END +STR_ECONNREFUSED: defb "Connection refused",0 ; 0xFA +STR_ETIMEDOUT: defb "Socket timeout",0 ; 0xFB +STR_ECONNRESET: defb "Connection reset by peer",0 ; 0xFC +STR_ESBADF: defb "Bad socket descriptor",0 ; 0xFD +STR_ESNFILE: defb "Invalid socket descriptor",0 ; 0xFE +STR_EUNK: defb "General socket error",0 ; 0xFF +HITABLE_END: + +.globl HITABLE_LEN +HITABLE_LEN equ HITABLE_END - STR_HITABLE diff --git a/modules/messages/vectors.asm b/modules/messages/vectors.asm index 24360ab..53154b1 100644 --- a/modules/messages/vectors.asm +++ b/modules/messages/vectors.asm @@ -21,6 +21,7 @@ ;THE SOFTWARE. ; BASIC extensions vector table +.section vectors defb 0xAA ; This is a code ROM defb 0xFC ; ROM ID = 0xFC defw 0xFFFF ; RESET vector @@ -31,5 +32,6 @@ defw 0xFFFF defw STR_ident ; Pointer to a string that identifies this mod jp F_getmessage -STR_ident defb "String table",0 +.data +STR_ident: asciz "String table" diff --git a/modules/modules.ld b/modules/modules.ld new file mode 100644 index 0000000..b59c2e5 --- /dev/null +++ b/modules/modules.ld @@ -0,0 +1,37 @@ +/* Spectranet modules LD script */ +OUTPUT_FORMAT("binary") +OUTPUT_ARCH("z80") +MEMORY { + pageb : ORIGIN = 0x2000, LENGTH = 0x1000 +} +SECTIONS +{ +.vectors : { + *(.vectors) + *(vectors) + __Hvectors = .; + } > pageb +.isr : { + *(.isr) + *(isr) + __Hisr = .; + } > pageb +.text : { + *(.text) + *(text) + __Htext = .; + } > pageb +.data : { + __Ldata = .; + *(.data) + *(data) + __Hdata = .; + } > pageb +.bss : { + __Lbss = .; + *(.bss) + *(bss) + __Hbss = .; + } > pageb +} + diff --git a/modules/snapman/Makefile b/modules/snapman/Makefile new file mode 100644 index 0000000..99a1a0e --- /dev/null +++ b/modules/snapman/Makefile @@ -0,0 +1,4 @@ +ASOBJS = directory.o inputloop.o loadsna.o memory.o savesna.o screen.o strings_en.o utils.o vectors.o +OUT = snapman.module +include ../make.inc + diff --git a/modules/snapman/build b/modules/snapman/build deleted file mode 100755 index 6e0b138..0000000 --- a/modules/snapman/build +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -echo `pwd`/snapman.out >> ../../build.out -sjasmplus snapman.asm --lst=snapman.lst -exit $? - diff --git a/modules/snapman/directory.asm b/modules/snapman/directory.asm index 1b6baae..4acdc25 100644 --- a/modules/snapman/directory.asm +++ b/modules/snapman/directory.asm @@ -21,12 +21,16 @@ ;THE SOFTWARE. ; Read the current directory and filter files found. - include "../../rom/fs_statdefs.asm" +.include "stat.inc" +.include "spectranet.inc" +.include "snapman.inc" +.text ;------------------------------------------------------------------------- ; F_loaddir ; Load the contents of a directory into memory. -F_loaddir +.globl F_loaddir +F_loaddir: call F_loading xor a ; initialize vars ld (v_numdirs), a @@ -44,16 +48,16 @@ F_loaddir ld (WORKSPACE), hl ; put it somewhere the FS module can see ld hl, WORKSPACE ; and set this as the param to OPENDIR call OPENDIR - jr c, .err + jr c, .err1 ld (v_dhnd), a ; save the directory handle -.readloop +.readloop1: ld de, v_dirwkspc call READDIR ; Get the next directory entry - jr c, .readdone ; Probably EOF + jr c, .readdone1 ; Probably EOF call F_filterdir ; Decide whether to store or discard ld a, (v_dhnd) ; Restore dirhandle - jr .readloop -.readdone + jr .readloop1 +.readdone1: ld a, (v_dhnd) call CLOSEDIR ld hl, (v_snaptr) ; terminate lists @@ -66,7 +70,7 @@ F_loaddir ld (hl), 0 call F_clearloading ret -.err +.err1: call F_clearloading ret ; TODO - report errors @@ -74,30 +78,31 @@ F_loaddir ; F_filterdir ; Looks at the directory entry in v_dirwkspc, stats it, and adds it to the ; appropriate list. -F_filterdir +.globl F_filterdir +F_filterdir: ld hl, v_dirwkspc ld de, v_statinfo call STAT ret c ; TODO - error handling ld a, (v_statinfo+STAT_MODE+1) ; Get high order of MODE bits and S_IFDIR / 256 ; compare with high order mask for isdir - jr nz, .directory -.file + jr nz, .directory2 +.file2: ld hl, v_statinfo+STAT_SIZE ld de, c_48ksnap call F_cp32 ; Look for a file the size of a 48k snap - jr z, .checkfilename + jr z, .checkfilename2 ; TODO - check whether machine is 128K ld hl, v_statinfo+STAT_SIZE ld de, c_128ksnap1 call F_cp32 - jr z, .checkfilename + jr z, .checkfilename2 ld hl, v_statinfo+STAT_SIZE ld de, c_128ksnap2 call F_cp32 ret nz -.checkfilename +.checkfilename2: ld hl, (v_snaptr) ld de, (v_snanextentry) call F_addentry @@ -108,7 +113,7 @@ F_filterdir ld (v_numsnas), a ret -.directory +.directory2: ld hl, (v_dirptr) ; current end of directory table ld de, (v_dirnextentry) call F_addentry @@ -118,14 +123,15 @@ F_filterdir inc a ld (v_numdirs), a ret -c_48ksnap defw 0xC01B,0x0000 -c_128ksnap1 defw 0x001F,0x0002 -c_128ksnap2 defw 0x401F,0x0002 +c_48ksnap: defw 0xC01B,0x0000 +c_128ksnap1: defw 0x001F,0x0002 +c_128ksnap2: defw 0x401F,0x0002 ;----------------------------------------------------------------------- ; F_addentry ; Adds an entry to a string table -F_addentry +.globl F_addentry +F_addentry: push hl push de ld hl, v_dirwkspc ; point at filename to copy @@ -144,14 +150,15 @@ F_addentry ; 32 bit compare between two memory locations ; HL = pointer to location 1 ; DE = pointer to location 2 -F_cp32 +.globl F_cp32 +F_cp32: ld b, 4 ; number of iterations -.loop +.loop4: ld a, (de) cp (hl) ret nz ; no compare inc de inc hl - djnz .loop + djnz .loop4 ret diff --git a/modules/snapman/inputloop.asm b/modules/snapman/inputloop.asm index f70418e..5316fd2 100644 --- a/modules/snapman/inputloop.asm +++ b/modules/snapman/inputloop.asm @@ -22,9 +22,14 @@ ;------------------------------------------------------------------------ ; Handle user interaction for the snapshot manager. +.include "spectranet.inc" +.include "snapman.inc" +.include "sysvars.inc" +.text ; Create the user interface and enter the input loop. -F_startui +.globl F_startui +F_startui: call F_fetchpage jp c, F_nopage call CLEAR42 @@ -43,21 +48,22 @@ F_startui ;---------------------------------------------------------------------- ; Main UI loop -F_mainloop +.globl F_mainloop +F_mainloop: call F_inputloop ; call UI control input loop, wait for a key ld b, a ; save the keypress in B ld c, 0 ; use C as a counter ld hl, INPUTTABLE -.getactionloop +.getactionloop2: ld a, (hl) and a ; check for "end of list" jr z, F_mainloop ; invalid key, ignore it cp b ; See if the key press is recognised. - jr z, .handlekey + jr z, .handlekey2 inc c ; inc. counter inc hl - jr .getactionloop -.handlekey + jr .getactionloop2 +.handlekey2: rlc c ; double the counter to form the offset ld b, 0 ; in BC ld hl, INPUTADDRS ; Calculate the address of the address @@ -66,10 +72,10 @@ F_mainloop inc hl ld d, (hl) ; and MSB ex de, hl ; put it in hl - ld de, .return + ld de, .return2 push de ; effectively, we want to CALL (HL) jp (hl) -.return +.return2: ld a, (v_inputflags) bit 0, a ; signal to leave? jr z, F_mainloop ; ...no, so continue @@ -80,7 +86,8 @@ F_mainloop ;------------------------------------------------------------------------ ; F_exit ; Leave the main input loop, by setting the 'done' flag. -F_exit +.globl F_exit +F_exit: ld a, (v_inputflags) set 0, a ld (v_inputflags), a @@ -88,12 +95,13 @@ F_exit ;------------------------------------------------------------------------ ; F_enterpressed -F_enterpressed +.globl F_enterpressed +F_enterpressed: call F_getselected ret z ; nothing to do - no entries ld a, (v_viewflags) and 1 ; bit 1 set - directory mode - jr z, .loadsnap + jr z, .loadsnap4 ld de, WORKSPACE ; copy directory name to where the call F_strcpy ; FS module will be able to see it ld hl, WORKSPACE @@ -106,7 +114,7 @@ F_enterpressed ld de, v_dirtable ld a, (v_numdirs) jp F_makeselection ; make the selection and return. -.loadsnap +.loadsnap4: ld de, WORKSPACE push hl call F_strcpy ; copy the filename into common workspace @@ -115,14 +123,16 @@ F_enterpressed call F_strcpy ld hl, WORKSPACE ; filename pointed to by HL call F_loadsnap ; load the snapshot -F_error ; ends up here if there is an error +.globl F_error +F_error: ; ends up here if there is an error ld a, 2 out (254), a ret ;------------------------------------------------------------------------ ; F_saveas -F_saveas +.globl F_saveas +F_saveas: ld hl, STR_filename ld de, v_strbuf ld c, FNAMESZ @@ -133,7 +143,8 @@ F_saveas ld hl, v_strbuf call F_strcpy ; filename. ld hl, v_strbuf -F_saveas2 +.globl F_saveas2 +F_saveas2: ld de, WORKSPACE ; and copy it to the workspace call F_strcpy ; so the FS module can see it too ld hl, WORKSPACE @@ -145,20 +156,21 @@ F_saveas2 ;------------------------------------------------------------------------ ; F_save -F_save +.globl F_save +F_save: ld a, (v_viewflags) ; directory view or file view? and 1 - jr nz, .needfilename + jr nz, .needfilename8 call F_getselected jr z, F_saveas ld (v_hlsave), hl ; save the pointer but don't disturb stack ld de, v_curfilename call F_strcmp ; selected = current? - jr nz, .confirm -.save + jr nz, .confirm8 +.save8: ld hl, (v_hlsave) jp F_saveas2 -.confirm +.confirm8: ld hl, STR_cfoverwrite ld de, v_strbuf ld c, 2 @@ -170,8 +182,8 @@ F_save ld hl, (v_hlsave) ld de, v_curfilename call F_strcpy ; set this as the current file - jr .save -.needfilename + jr .save8 +.needfilename8: ld a, (v_curfilename) ; Already have a filename? and a ; if zero, no jr z, F_saveas @@ -181,7 +193,8 @@ F_save ; HL = pointer to prompt string ; DE = pointer to buffer in which to return the data ; C = size of input buffer -F_userinput +.globl F_userinput +F_userinput: push bc push hl ld bc, 0x1600 ; line 24, col 0 @@ -203,7 +216,8 @@ F_userinput ;---------------------------------------------------------------------- ; F_rename ; Renames a snapshot file. -F_rename +.globl F_rename +F_rename: ld a, (v_viewflags) ; check we are in snapshot view rra ; if LSB = 1 we are in directory view ret c ; so leave. @@ -241,7 +255,8 @@ F_rename ;---------------------------------------------------------------------- ; F_erase ; Erases a snapshot file. -F_erase +.globl F_erase +F_erase: ld a, (v_viewflags) ; check we are in snapshot view rra ; if LSB = 1 we are in directory view ret c ; so leave. @@ -277,26 +292,29 @@ F_erase ;---------------------------------------------------------------------- ; F_switchdirview ; Switch between directory and file views. -F_switchdirview +.globl F_switchdirview +F_switchdirview: ld a, (v_viewflags) xor 1 ; flip "dir view" bit ld (v_viewflags), a ; and save rra ; push lsb into the carry flag jr c, showdir ; switch from file to dir view -F_snapview +.globl F_snapview +F_snapview: ld de, v_snatable ld a, (v_numsnas) -makesel +makesel: ld hl, BOXSTARTADDR ; start address of the box ld bc, BOXDIMENSIONS ; box dimensions jp F_makeselection ; make the selection and return. -showdir +showdir: ld de, v_dirtable ld a, (v_numdirs) jr makesel ; We end up here if the allocated page wasn't found. -F_nopage +.globl F_nopage +F_nopage: ld hl, STR_nomempage call PRINT42 ret diff --git a/modules/snapman/loadsna.asm b/modules/snapman/loadsna.asm index 9ed0cb3..463fd19 100644 --- a/modules/snapman/loadsna.asm +++ b/modules/snapman/loadsna.asm @@ -20,43 +20,27 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. -; Functions to load .SNA (snapshot) files - -; SNA file definitions -HEADER equ 0x3000 -SNA_I equ HEADER -SNA_HLALT equ HEADER+1 -SNA_DEALT equ HEADER+3 -SNA_BCALT equ HEADER+5 -SNA_AFALT equ HEADER+7 -SNA_HL equ HEADER+9 -SNA_DE equ HEADER+11 -SNA_BC equ HEADER+13 -SNA_IY equ HEADER+15 -SNA_IX equ HEADER+17 -SNA_EIDI equ HEADER+19 -SNA_R equ HEADER+20 -SNA_AF equ HEADER+21 -SNA_SP equ HEADER+23 -SNA_IM equ HEADER+25 -SNA_BORDER equ HEADER+26 -HEADERSZ equ 27 -SNA_PC equ HEADER+27 ; 128K .SNA file - program counter -SNA_7FFD equ HEADER+29 ; value of port 0x7FFD -SNA_TRDOS equ HEADER+30 ; TR-DOS flagm +; Functions to load .SNA0 (snapshot) files +.include "snapheader.inc" +.include "snapman.inc" +.include "fcntl.inc" +.include "spectranet.inc" +.text ;------------------------------------------------------------------------ ; F_loadsnap ; Determine if the filename passed in HL is a snapshot file we can handle ; and call the correct routine to handle it. On error, it returns. ; If no error is encountered, the snapshot is run. -F_loadsnap_modcall +.globl F_loadsnap_modcall +F_loadsnap_modcall: ex de, hl push hl ; if called from another program set the ld de, v_curfilename ; current filename in case the user enters call F_strcpy ; the UI. pop hl -F_loadsnap +.globl F_loadsnap +F_loadsnap: ; simple detection - look at the size to see if it's 48K or 128K push hl ; save the filename pointer ld de, v_statinfo ; where to put the data from stat @@ -76,12 +60,12 @@ F_loadsnap ld hl, (v_statinfo+8) ; Less than 64K in size? ld a, h or l - jr z, .fortyeight + jr z, .fortyeight2 call F_loadsna128 ; Load a 128K snapshot ld sp, (v_stacksave) ; Restore the stack ret -.fortyeight +.fortyeight2: call F_loadsna48 ld sp, (v_stacksave) ret @@ -90,7 +74,8 @@ F_loadsnap ; F_loadsna48: Load a 48K snapshot. File handle is in (v_snapfd) ; On error carry is set and A=errno ; On success, snapshot is launched (effectively, we don't return) -F_loadsna48 +.globl F_loadsna48 +F_loadsna48: di ; don't want the stack getting meddled by int ld a, (v_snapfd) ld de, HEADER ; where to put the header @@ -110,7 +95,8 @@ F_loadsna48 ld a, (v_snapfd) ; close the fd call VCLOSE -J_unloadheader +.globl J_unloadheader +J_unloadheader: ; At this point we've successfully loaded the snapshot file. ; First deal with the screen. call F_restorescreen @@ -131,15 +117,15 @@ J_unloadheader ld iy, (SNA_IY) ld a, (SNA_IM) ; Set the interrupt mode and a - jr nz, .im1 + jr nz, .im13 im 0 - jr .imdone -.im1 cp 1 - jr nz, .im2 + jr .imdone3 +.im13: cp 1 + jr nz, .im23 im 1 - jr .imdone -.im2 im 2 -.imdone + jr .imdone3 +.im23: im 2 +.imdone3: ld a, (SNA_I) ; Set the I register ld i, a ld a, (SNA_BORDER) ; Set the border colour @@ -149,17 +135,18 @@ J_unloadheader pop af ld hl, SNA_EIDI ; Interrupt state bit 2, (hl) ; nz = enable interrupts - jr z, .noei ; interrupts are currently disabled anyway + jr z, .noei3 ; interrupts are currently disabled anyway ld hl, (SNA_HL) ; Set HL ld sp, (SNA_SP) ; and SP, finally EI and return via UNPAGE ei ; and EI at the last possible moment. jp 0x007C -.noei +.noei3: ld hl, (SNA_HL) ld sp, (SNA_SP) ; Snapshot's stack pointer jp 0x007C ; unpage - -J_snapdie + +.globl J_snapdie +J_snapdie: push af ; preserve error status ld a, 2 out (254), a @@ -170,21 +157,22 @@ J_snapdie ;------------------------------------------------------------------------- ; F_readscreen: Read the screen memory into Spectranet RAM -F_readscreen +.globl F_readscreen +F_readscreen: ld a, 0xDA ; first page call PUSHPAGEA ; switch and store page number ld de, 0x1000 ld bc, 0x1000 ld a, (v_snapfd) call READ - jr c, .restoreerr + jr c, .restoreerr4 ld a, 0xDB call SETPAGEA ld de, 0x1000 ld bc, 0xB00 ld a, (v_snapfd) call READ -.restoreerr +.restoreerr4: call POPPAGEA ret @@ -193,7 +181,8 @@ F_readscreen ; File descriptor in (v_snapfd) ; On error carry is set and A=errno ; On success, snapshot is launched (effectively, we don't return) -F_loadsna128 +.globl F_loadsna128 +F_loadsna128: ld a, (v_snapfd) ld de, HEADER ; where to put the header ld bc, HEADERSZ ; length of the header @@ -231,16 +220,16 @@ F_loadsna128 ; Load the pages except the paged page, and pages 2 and 5 ld d, 0 ; start with page 0 -.pageloadloop +.pageloadloop5: ld a, (SNA_7FFD) ; find out what page is paged in 0xC000 and 7 ; to know which to skip loading cp d - jr z, .next + jr z, .next5 ld a, d cp 2 ; also skip pages 2 and 5 - jr z, .next + jr z, .next5 cp 5 - jr z, .next + jr z, .next5 ld bc, 0x7FFD ; now page in the page that should be out (c), d ; loaded. @@ -251,11 +240,11 @@ F_loadsna128 call READ pop de jp c, J_snapdie -.next +.next5: inc d ; increment page number ld a, d cp 8 ; finished? - jr nz, .pageloadloop + jr nz, .pageloadloop5 ; Now load the reaming page - for this we need to seek backwards ; to where it's stored... given that SNA files can be of two lengths diff --git a/modules/snapman/memory.asm b/modules/snapman/memory.asm index b7e25fc..38ce5dd 100644 --- a/modules/snapman/memory.asm +++ b/modules/snapman/memory.asm @@ -19,16 +19,20 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.text ;------------------------------------------------------------------------- ; F_init: Initialize the snapshot manager. -F_init +.globl F_init +F_init: call F_allocpage - jr c, .failed + jr c, .failed1 ld hl, STR_initialized call PRINT42 ret -.failed +.failed1: ld hl, STR_failed call PRINT42 ret @@ -36,7 +40,8 @@ F_init ; Claim our memory page, functions to fetch etc. ; Note: Ought to be a library function. -F_allocpage +.globl F_allocpage +F_allocpage: ld a, (v_pgb) ; Find our identity call RESERVEPAGE ret c ; Failed to reserve a page! @@ -66,7 +71,8 @@ F_allocpage ;----------------------------------------------------------------------------- ; F_fetchpage ; Gets our page of RAM and puts it in page area A. -F_fetchpage +.globl F_fetchpage +F_fetchpage: push af push hl ld a, (v_pgb) ; get our ROM number and calculate @@ -77,7 +83,7 @@ F_fetchpage ld l, a ld a, (hl) ; fetch the page number and a ; make sure it's nonzero - jr z, .nopage + jr z, .nopage3 inc l ; point hl at "page number storage" ex af, af' ld a, (v_pga) @@ -88,7 +94,7 @@ F_fetchpage pop af or a ; ensure carry is cleared ret -.nopage +.nopage3: pop hl ; restore the stack pop af ld a, 0xFF ; TODO: ENOMEM return code @@ -99,7 +105,8 @@ F_fetchpage ; F_isallocated ; Tests to see if we have a memory page allocated already. ; Returns nonzero if we have a page -F_isallocated +.globl F_isallocated +F_isallocated: push hl ld a, (v_pgb) ; get our ROM number rlca ; multiply by 8 to find our @@ -115,8 +122,10 @@ F_isallocated ;--------------------------------------------------------------------------- ; F_restorepage ; Restores page A to its original value. -F_leave -F_restorepage +.globl F_leave +F_leave: +.globl F_restorepage +F_restorepage: push af push hl ld a, (v_pgb) ; calculate the offset... diff --git a/modules/snapman/savesna.asm b/modules/snapman/savesna.asm index 2b95947..7e868f4 100644 --- a/modules/snapman/savesna.asm +++ b/modules/snapman/savesna.asm @@ -21,7 +21,13 @@ ;THE SOFTWARE. ; Save snapshots in SNA format. +.include "fcntl.inc" +.include "snapheader.inc" +.include "snapman.inc" +.include "spectranet.inc" +.include "sysvars.inc" +.text ;-------------------------------------------------------------------------- ; F_savesna48 ; Save a 48K snapshot. Null terminated filename pointed to by HL. @@ -30,29 +36,30 @@ SAVERAM equ 0x3600 MAINSPSAVE equ 0x35FE TEMPSP equ 0x81FE -F_snaptest +.globl F_snaptest +F_snaptest: ld hl, STR_saving call PRINT42 ld hl, STR_filename ld de, 0x3000 xor a -.loop +.loop1: ldi cp (hl) - jr nz, .loop -.done + jr nz, .loop1 +.done1: ld (de), a ld hl, 0x3000 call F_savesna - jr c, .borked + jr c, .borked1 ld a, (v_border) ; Restore the border out (254), a call F_restorescreen ; Restore the screen ld a, (SNA_EIDI) ; Re.enable interrupts? and a ; No - jr nz, .retei ; If yes, then EI on ret + jr nz, .retei1 ; If yes, then EI on ret ld sp, NMISTACK-14 ; Set SP to where the stack was pop af ex af, af' @@ -62,12 +69,12 @@ F_snaptest pop hl ld sp, (NMISTACK) jp UNPAGE ; RET -.borked +.borked1: ld a, 2 out (254), a ret -.retei +.retei1: ld sp, NMISTACK-14 pop af ex af, af' @@ -82,7 +89,8 @@ F_snaptest ; HL = pointer to filename string ; Entry to the NMI saves the folowing at NMISTACK-4: ; hl, de, bc, af, af' -F_savesna +.globl F_savesna +F_savesna: ld d, O_CREAT | O_TRUNC ; Flags ld e, O_WRONLY ; File mode call OPEN ; Open the snapshot file @@ -116,7 +124,7 @@ F_savesna exx ld a, i ; also sets P/V flag if IFF2 is ld (SNA_I), a ; set (interrupts enabled) - call pe, .setei + call pe, .setei2 ld a, (v_border) ; Copy the border colour into ld (SNA_BORDER), a ; the snapshot header. @@ -125,31 +133,31 @@ F_savesna ld hl, 0x3600 ld de, 0x3601 ld bc, 258 ; table is actually 0x100 bytes - ld (hl), F_im2 % 256 ; LSB of IM 2 routine. + ld (hl), F_im2_lsb ; LSB of IM 2 routine. ldir ld a, 0x36 ; MSB of the table ld i, a ; set the vector table ld hl, 0 ld (v_intcount), hl ; reset IM 1 counter to detect IM 1 - ld hl, .continue ; "Return" address + ld hl, .continue2 ; "Return" address push hl ; on the stack so RETN retn ; takes us just to the next addr. -.continue +.continue2: xor a ld (SNA_IM), a ; clear IM x ei halt ; wait for an interrupt ld a, (SNA_IM) ; Did the IM 2 routine update and a ; the interrupt mode? - jr nz, .donewithinterrupts ; Done. + jr nz, .donewithinterrupts2 ; Done. inc a ld (SNA_IM), a ; set interrupt mode 1 ; Now it's all over bar the shouting. -.donewithinterrupts +.donewithinterrupts2: di ; Restore the I register @@ -159,26 +167,26 @@ F_savesna ; Detect whether we're saving a 48K or a 128K snapshot ld a, (v_machinetype) and 1 ; Bit 1 set = 128K - jr nz, .save128snap + jr nz, .save128snap2 - call .savemain ; save header and memory -.writedone + call .savemain2 ; save header and memory +.writedone2: ld a, (v_snapfd) ; close the file call VCLOSE ret -.writeerr +.writeerr2: push af ld a, (v_snapfd) call VCLOSE pop af ret -.setei +.setei2: ld a, 4 ld (SNA_EIDI), a ret -.save128snap +.save128snap2: ; copy port 0x7FFD value to the header ld a, (v_port7ffd) ld (SNA_7FFD), a @@ -193,27 +201,27 @@ F_savesna ld (SNA_PC), de ; Set the PC xor a ld (SNA_TRDOS), a ; TRDOS always 0 - call .savemain ; the header + 48K - jr c, .writeerr + call .savemain2 ; the header + 48K + jr c, .writeerr2 ld hl, SNA_PC ; Save the 128K second header ld bc, 4 ; (4 bytes long) ld a, (v_snapfd) call WRITE - jr c, .writeerr + jr c, .writeerr2 ; Save the 128K pages at 0xC000. ld a, (SNA_7FFD) ; Skip the page we've aready and 7 ; saved (as it was in 0xC000) ld e, a xor a ; start from page 0 -.save128loop +.save128loop2: cp e ; skip the page that was already - jr z, .next ; saved, also skip pages 2 and 5 + jr z, .next2 ; saved, also skip pages 2 and 5 cp 0x02 - jr z, .next + jr z, .next2 cp 0x05 - jr z, .next + jr z, .next2 ld bc, 0x7FFD ; set the page we want to save out (c), a @@ -223,25 +231,25 @@ F_savesna ld bc, 0x4000 ld a, (v_snapfd) call WRITE - jr c, .writeerr128 + jr c, .writeerr1282 pop de pop af -.next +.next2: inc a cp 0x08 ; all pages have been saved - jr nz, .save128loop + jr nz, .save128loop2 ld a, (SNA_7FFD) ; restore 128K paging but with and 0xF7 ; but ensure the normal screen ld bc, 0x7FFD ; is in use for the NMI menu out (c), a - jr .writedone + jr .writedone2 -.writeerr128 +.writeerr1282: pop de pop de ; don't overwrite AF - jr .writeerr + jr .writeerr2 -.savemain +.savemain2: ; TODO: Something ought to be done with the R register, really. ; Save the interrupts-and-stuff block. ld hl, HEADER @@ -262,25 +270,27 @@ F_savesna ;---------------------------------------------------------------------- ; F_savesavedscreen ; Save the screen that was copied to 0xDA:000 to 0xDB:AFF -F_savesavedscreen +.globl F_savesavedscreen +F_savesavedscreen: ld a, 0xDA ; first page call PUSHPAGEA ; set it and save current page ld hl, 0x1000 ld bc, 0x1000 ld a, (v_snapfd) call WRITE - jr c, .restoreerr + jr c, .restoreerr3 ld a, 0xDB call SETPAGEA ld hl, 0x1000 ld bc, 0xB00 ld a, (v_snapfd) call WRITE -.restoreerr +.restoreerr3: call POPPAGEA ; restore original page ret -F_restorescreen +.globl F_restorescreen +F_restorescreen: ld a, 0xDA call PUSHPAGEA ld hl, 0x1000 diff --git a/modules/snapman/screen.asm b/modules/snapman/screen.asm index 0015a48..2caeac1 100644 --- a/modules/snapman/screen.asm +++ b/modules/snapman/screen.asm @@ -19,14 +19,20 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "ctrlchars.inc" +.include "spectranet.inc" +.include "snapman.inc" +.include "sysvars.inc" +.text ;------------------------------------------------------------------------ ; F_makeselection ; HL = start address of box ; B = number of lines the box has ; C = maximum column number (32 cols) ; DE = address of first item to show -F_makeselection +.globl F_makeselection +F_makeselection: ld (v_selstart), hl ; initialize variables ld (v_maxcolumn), bc ld (v_stringtable), de @@ -49,7 +55,8 @@ F_makeselection add a, b ; and add to the number of 8 px columns inc a ld (v_42colsperln),a ; then save. -F_reinitselection +.globl F_reinitselection +F_reinitselection: call F_clearattrs call F_cleararea ; clear the box ld hl, (v_selstart) @@ -77,7 +84,8 @@ F_reinitselection ; Constrained print routine. Print from the start column to the maximum ; column or until NULL, whichever is earliest. ; HL = pointer to string -F_cprint +.globl F_cprint +F_cprint: xor a ld (v_rowcount), a ; prevent 42 col routine scroll ld a, (v_startcolumn) ; get the 32 column position and @@ -88,25 +96,26 @@ F_cprint add a, b ld (v_column), a ; set Spectranet 42 col print routine col ld b, 0 -.loop +.loop3: ld a, (hl) and a - jr z, .cr + jr z, .cr3 call PUTCHAR42 inc hl inc b ; increment 'columns printed so far' ld a, (v_42colsperln) cp b ; reached the limit? - jr nz, .loop -.cr - ld a, '\n' + jr nz, .loop3 +.cr3: + ld a, NEWLINE call PUTCHAR42 ret ;------------------------------------------------------------------------ ; F_bytesperline ; Calculates bytes per line. HL = start address of the line. -F_bytesperline +.globl F_bytesperline +F_bytesperline: push bc ld a, l and 0x1F @@ -125,12 +134,13 @@ F_bytesperline ; HL = pointer to first line to scroll ; B = number of lines to scroll ; C = 0 = scroll normal way, nonzero scroll reverse -F_scrollforward +.globl F_scrollforward +F_scrollforward: push bc ; save counter - call .advance ; advance one line (need to scroll + call .advance5 ; advance one line (need to scroll push hl ; box size minus 1) - jr z, .moveloopthird -.moveloop + jr z, .moveloopthird5 +.moveloop5: push bc ; save line counter ld a, l sub 32 ; address of next line up @@ -142,19 +152,19 @@ F_scrollforward pop hl inc h pop bc - djnz .moveloop -.nextline + djnz .moveloop5 +.nextline5: pop hl pop af ; get counter dec a ret z ; all lines scrolled push af ; save counter - call .advance + call .advance5 push hl - jr nz, .moveloop + jr nz, .moveloop5 -.moveloopthird +.moveloopthird5: push bc ld a, l or 0xE0 ; set top 3 bits of LSB @@ -168,37 +178,38 @@ F_scrollforward pop hl inc h pop bc - djnz .moveloopthird - jr .nextline + djnz .moveloopthird5 + jr .nextline5 -.advance +.advance5: ld a, l and 0xE0 cp 0xE0 ; about to go into the next third? - jr z, .nnextthird + jr z, .nnextthird5 ld a, 32 add a, l ; next line ld l, a ld b, 8 ; number of iterations per line ret -.nnextthird +.nnextthird5: ld a, l and 0x1F ; clear 3 most significant bits ld l, a ; set LSB of pointer ld a, h - add 8 + add a, 8 ld h, a ; set MSB of pointer ld b, 8 ; move 8 lines xor a ret -F_scrollreverse +.globl F_scrollreverse +F_scrollreverse: dec b push bc - call .retreat ; up one line, scroll box size - 1 + call .retreat6 ; up one line, scroll box size - 1 push hl - jr z, .nextthird -.moveloop + jr z, .nextthird6 +.moveloop6: push bc ld a, 32 add a, l ; calculate next line @@ -210,25 +221,25 @@ F_scrollreverse pop hl inc h pop bc - djnz .moveloop -.nextline + djnz .moveloop6 +.nextline6: pop hl pop af dec a ; decrement line counter ret z ; and leave if we've finished all lines push af ; store counter - call .retreat + call .retreat6 push hl - jr nz, .moveloop + jr nz, .moveloop6 -.moveloopthird +.moveloopthird6: push bc ld a, l and 0x1F ; clear 3 bits of LSB ld e, a ld a, h - add 0x08 ; add 0x08 to the MSB of copy to pointer + add a, 0x08 ; add 0x08 to the MSB of copy to pointer ld d, a ; DE now equals address of next row push hl ld bc, (v_movebytes) @@ -236,19 +247,19 @@ F_scrollreverse pop hl inc h pop bc - djnz .moveloopthird - jr .nextline + djnz .moveloopthird6 + jr .nextline6 -.retreat +.retreat6: ld a, l ; about to cross a third boundary? and 0xE0 - jr z, .nextthird + jr z, .nextthird6 ld a, l sub 32 ; move up a line ld l, a ld b, 8 ret -.nextthird +.nextthird6: ld a, l or 0xE0 ; set top 3 bits of the pointer ld l, a ; set LSB of pointer @@ -263,13 +274,14 @@ F_scrollreverse ; F_cleararea: Clears a defined area. ; HL = Start address ; B = Number of lines to clear -F_cleararea +.globl F_cleararea +F_cleararea: ld hl, (v_selstart) ; start of area ld bc, (v_maxcolumn) ; counter into B push bc ; save counter push hl ld b, 8 ; clear 8 scanlines -.clearloop +.clearloop7: push bc ; save line counter ld d, h ld e, l @@ -283,51 +295,53 @@ F_cleararea pop hl inc h pop bc ; retrieve counter - djnz .clearloop -.nextline + djnz .clearloop7 +.nextline7: pop hl pop af ; get counter dec a - jr z, .savelastline ; all lines cleared + jr z, .savelastline7 ; all lines cleared push af ; save counter ld a, l and 0xE0 cp 0xE0 ; about to go into the next third? - jr z, .nextthird + jr z, .nextthird7 ld a, 32 add a, l ; next line ld l, a push hl ld b, 8 ; number of iterations per line - jr .clearloop + jr .clearloop7 -.nextthird +.nextthird7: ld a, l and 0x1F ; clear 3 most significant bits ld l, a ; set LSB of pointer ld a, h - add 8 + add a, 8 ld h, a ; set MSB of pointer push hl ; save HL ld b, 8 ; move 8 lines - jr .clearloop + jr .clearloop7 -.savelastline +.savelastline7: ld (v_selend), hl ; save the bottom row address ret ;------------------------------------------------------------------------ ; F_clearline ; Clears a line. HL = start address. -F_clearline +.globl F_clearline +F_clearline: ld bc, (v_movebytes) ; put current box width in ; ...clears a line BC bytes long. -F_clearline2 +.globl F_clearline2 +F_clearline2: ld (v_clearbytes), bc ; our "how much to clear" var. ld b, 8 -.clearloop +.clearloop9: push bc ld d, h ld e, l @@ -341,7 +355,7 @@ F_clearline2 pop hl inc h pop bc - djnz .clearloop + djnz .clearloop9 ret ;------------------------------------------------------------------------ @@ -349,18 +363,20 @@ F_clearline2 ; Moves selection bar down. ; A = 0 - move bar down ; Otherwise, it moves up. -F_movebar +.globl F_movebar +F_movebar: call F_clearbar ld de, 32 ; Next row and a ; Is A = 0? - jr z, .down + jr z, .down10 sbc hl, de - jr .move -.down + jr .move10 +.down10: add hl, de -.move +.move10: ld (v_baraddr), hl ; Save the new row pointer -F_putbar_impl +.globl F_putbar_impl +F_putbar_impl: ld d, h ld e, l inc e @@ -370,9 +386,11 @@ F_putbar_impl ld (hl), SELECTED_ATTR ; Colour to draw ldir ret -F_clearbar +.globl F_clearbar +F_clearbar: ld hl, (v_baraddr) ; current start address of bar -F_clearbar2 +.globl F_clearbar2 +F_clearbar2: push af ld a, (v_barlen) ; how long the bar is ld b, 0 @@ -390,7 +408,8 @@ F_clearbar2 ;------------------------------------------------------------------------ ; F_putbar ; Draws the bar at the current start address. -F_putbar +.globl F_putbar +F_putbar: ld hl, (v_baraddr) ld a, (v_barlen) jp F_putbar_impl @@ -398,7 +417,8 @@ F_putbar ;------------------------------------------------------------------------ ; F_fbuf2attr ; Convert pixel buffer addresses to attribute addresses -F_fbuf2attr +.globl F_fbuf2attr +F_fbuf2attr: ld a, l ; get LSB of frame buffer address and 0xE0 ; mask out bottom bits rlca ; and move to lowest 3 bits @@ -427,11 +447,12 @@ F_fbuf2attr ;------------------------------------------------------------------------ ; F_clearattrs ; Clears the entire background area -F_clearattrs +.globl F_clearattrs +F_clearattrs: ld hl, (v_selstart) call F_fbuf2attr ld a, (v_sellines) -.clearloop +.clearloop16: push hl call F_clearbar2 ld bc, 32 @@ -439,46 +460,47 @@ F_clearattrs add hl, bc dec a and a - jr nz, .clearloop + jr nz, .clearloop16 ret ;------------------------------------------------------------------------ ; F_inputloop ; Deal with keyboard input. -F_inputloop -.inputloop +.globl F_inputloop +F_inputloop: +.inputloop17: call GETKEY ; get the actual key ld hl, 0x1000 ; wait some more time so that -.loop ; multi key contacts on Spectrum + / 128 +.loop17: ; multi key contacts on Spectrum + / 128 dec hl ; membranes all make. Use a delay loop ld a, h ; rather than halt so this routine works or l ; with interrupts disabled. - jr nz, .loop + jr nz, .loop17 call GETKEY ; to close all the contacts... push af ; save it call KEYUP ; and wait for keyup pop af cp 0x0A ; KEY_DOWN - jr z, .bardown + jr z, .bardown17 cp 0x0B ; KEY_UP - jr z, .barup + jr z, .barup17 ret -.bardown +.bardown17: ld a, (v_sellines) ; hit the bottom? dec a ; convert to 'index' ld b, a ld a, (v_barpos) cp b - jr z, .scrolldown + jr z, .scrolldown17 ld a, (v_numitems) ; check we're not at the end and a - jr z, .inputloop ; no items + jr z, .inputloop17 ; no items dec a ld b, a ld a, (v_selecteditem) cp b - jr z, .inputloop ; selection is at the end + jr z, .inputloop17 ; selection is at the end inc a ; increment selection ld (v_selecteditem), a ld a, (v_barpos) @@ -486,11 +508,11 @@ F_inputloop ld (v_barpos), a ; update position xor a call F_movebar - jr .inputloop -.barup + jr .inputloop17 +.barup17: ld a, (v_barpos) and a - jr z, .scrollup + jr z, .scrollup17 dec a ld (v_barpos), a ld a, (v_selecteditem) ; decrement the selected item index @@ -498,18 +520,18 @@ F_inputloop ld (v_selecteditem), a inc a ; ensure A is nonzero call F_movebar - jr .inputloop + jr .inputloop17 -.scrolldown +.scrolldown17: ld a, (v_numitems) and a - jr z, .inputloop ; no items + jr z, .inputloop17 ; no items dec a ld b, a ; compare the last item index ld a, (v_selecteditem) ; with the current cp b - jr z, .inputloop ; already at the last item + jr z, .inputloop17 ; already at the last item ld a, (v_selecteditem) ; Increment the selected item index. inc a ld (v_selecteditem), a @@ -536,12 +558,12 @@ F_inputloop ld (v_row), hl ; set print routine to bottom line row pop hl ; now get the string back call F_cprint - jp .inputloop + jp .inputloop17 -.scrollup +.scrollup17: ld a, (v_selecteditem) ; check we've not hit zero and a - jp z, .inputloop + jp z, .inputloop17 dec a ld (v_selecteditem), a ; update the selected item ld hl, (v_stringtable) ; string table start address @@ -567,14 +589,15 @@ F_inputloop ld (v_row), hl ; set the print routine's row address pop hl ; get the string pointer call F_cprint - jp .inputloop + jp .inputloop17 ;-------------------------------------------------------------------------- ; F_setbarloc ; Sets the bar location to a determined point in the list (which must ; already be initialized, along with the selection box) ; A = index of string to select -F_setbarloc +.globl F_setbarloc +F_setbarloc: ld b, a ; save 'goto' location ; first find out whether the bar is going to remain within @@ -588,14 +611,14 @@ F_setbarloc ld a, (v_selecteditem) ; get the selected item index add a, c ; and calculate the index of the bottom item cp b ; Is the request for an item past what - jr c, .newselection ; we can see on the screen? - jr z, .newselection + jr c, .newselection18 ; we can see on the screen? + jr z, .newselection18 ld c, (hl) ; get the number of lines in the box sub c ; and calculate index of top item cp b ; is out of bounds low. - jr c, .movebar + jr c, .movebar18 -.newselection +.newselection18: push bc ; save desired index call F_cleararea ; clear the box ready to repaint it ld hl, (v_stringtable) ; calculate new position in the string @@ -612,7 +635,7 @@ F_setbarloc xor a ; move bar to the top jp F_putbarat ; (only need this if putbarat is moved) -.movebar +.movebar18: ; The item is actually visible already - select it. ld c, a ; then calculate where the bar actually ld a, b ; should be relative to the top @@ -623,7 +646,8 @@ F_setbarloc ;------------------------------------------------------------------------- ; F_putbarat: Draws the bar at the specified relative location in A -F_putbarat +.globl F_putbarat +F_putbarat: call F_clearbar ; clear the existing bar ld (v_barpos), a ; save the bar position @@ -645,7 +669,8 @@ F_putbarat ; Puts the text in the selection box. ; HL = address of first character cell ; DE = pointer to the first item in the string table to print -F_puttext +.globl F_puttext +F_puttext: ld a, l ; Initialize the position of the 42 col and 0xE0 ; print routine to the top of the box. ld l, a @@ -654,7 +679,7 @@ F_puttext ex de, hl ; get first item to print ld a, (v_sellines) ; number of lines we can fit ld b, a -.printloop +.printloop20: ld e, (hl) ; low order of string lookup inc hl ld d, (hl) ; high order of string lookup @@ -669,13 +694,14 @@ F_puttext pop bc pop de ex de, hl - djnz .printloop + djnz .printloop20 ret ;-------------------------------------------------------------------------- ; F_getselected ; Returns a pointer to the selected item in HL -F_getselected +.globl F_getselected +F_getselected: ld a, (v_numitems) ; check there's something there and a ret z ; if nothing return with Z set @@ -694,11 +720,12 @@ F_getselected ;------------------------------------------------------------------------- ; F_addstring ; Adds a string to the selection -F_addstring +.globl F_addstring +F_addstring: push hl ; save pointer ld a, (v_numitems) ; Make room in the string table cp 0x7F ; but make sure there is room. - jr z, .noroom + jr z, .noroom22 rlca ; - find the last entry ld hl, (v_stringtable) @@ -728,15 +755,15 @@ F_addstring ld (hl), a pop hl ; get string pointer -.strcpy +.strcpy22: ld a, (hl) ld (de), a and a - jr z, .redraw + jr z, .redraw22 inc hl inc de - jr .strcpy -.redraw + jr .strcpy22 +.redraw22: ld a, (v_numitems) inc a ld (v_numitems), a ; update last item index @@ -746,7 +773,7 @@ F_addstring call F_setbarloc ret -.noroom +.noroom22: pop hl scf ret @@ -755,10 +782,11 @@ F_addstring ; F_printat: Move PRINT42 location. ; B = row ; C = column -F_printat +.globl F_printat +F_printat: ld a, b and 0x18 ; find the third of the screen - add 0x40 ; add MSB of the screen address + add a, 0x40 ; add MSB of the screen address ld h, a ld a, b and 0x07 ; find where we are within that 1/3rd @@ -776,19 +804,22 @@ F_printat ;------------------------------------------------------------------------ ; F_loading ; Show "Loading..." -F_loading +.globl F_loading +F_loading: ld bc, 0x1600 call F_printat ld hl, STR_loading call PRINT42 ret -F_clearloading +.globl F_clearloading +F_clearloading: ld bc, 0x1600 call F_printat ld bc, 32 call F_clearline2 ret -F_saving +.globl F_saving +F_saving: ld bc, 0x1600 call F_printat ld hl, STR_saving @@ -798,7 +829,8 @@ F_saving ;----------------------------------------------------------------------- ; F_putcurfile ; Prints the currently file name. -F_printcurfile +.globl F_printcurfile +F_printcurfile: ld bc, 0x1500 call F_printat ld bc, 32 @@ -808,10 +840,10 @@ F_printcurfile ld hl, v_curfilename ld a, (hl) and a - jr z, .none + jr z, .none27 call PRINT42 ret -.none +.none27: ld hl, STR_nofile call PRINT42 ret @@ -819,7 +851,8 @@ F_printcurfile ;------------------------------------------------------------------------ ; F_printcwd ; Prints the current working directory -F_printcwd +.globl F_printcwd +F_printcwd: ld bc, 0x1404 call F_printat ld bc, MAXDIRSTR @@ -832,38 +865,41 @@ F_printcwd ld hl, WORKSPACE call F_strlen cp MAXDIRSTR ; too long to fit in the bit of screen? - jr nc, .truncstr + jr nc, .truncstr28 call PRINT42 ; no, so just print it ret -.truncstr +.truncstr28: sub MAXDIRSTR ld c, a ; should be starting form. ld b, 0 add hl, bc add a, 3 cp MAXDIRSTR ; still too long with the ... added? - call nc, .truncmore + call nc, .truncmore28 push hl ld hl, STR_dotdotdot call PRINT42 pop hl call PRINT42 ret -.truncmore +.truncmore28: sub MAXDIRSTR ld c, a add hl, bc ret -STR_dotdotdot defb "...",0 +.data +STR_dotdotdot: .asciz "..." +.text ;------------------------------------------------------------------------ ; F_strlen ; String length returned in A for the string at HL -F_strlen +.globl F_strlen +F_strlen: push hl xor a ld bc, 0x100 -.loop +.loop29: cpir ld a, c cpl @@ -872,9 +908,10 @@ F_strlen ;------------------------------------------------------------------------ ; F_makestaticUI -F_makestaticui +.globl F_makestaticui +F_makestaticui: ld hl, UI_STRINGS -.loop +.loop30: ld b, (hl) ; get screen position to print at inc hl ld c, (hl) @@ -889,16 +926,17 @@ F_makestaticui pop hl call PRINT42 ; print the string inc hl ; point HL at the start of the next item - jr .loop + jr .loop30 ;----------------------------------------------------------------------- ; F_findstring ; Finds the index of a string in the box, returns it in A. ; Carry flag set if the string was found. -F_findstr +.globl F_findstr +F_findstr: ld hl, (v_stringtable) ld c, 0 ; counter -.findloop +.findloop31: ld e, (hl) inc hl ld d, (hl) @@ -914,11 +952,11 @@ F_findstr push bc call F_strcmp ; is this the string? pop bc - jr z, .found + jr z, .found31 inc c ld hl, (v_hlsave) - jr .findloop -.found + jr .findloop31 +.found31: ld a, c scf ret diff --git a/modules/basext/basext.asm b/modules/snapman/snapheader.inc similarity index 59% rename from modules/basext/basext.asm rename to modules/snapman/snapheader.inc index 3ab68a8..0609063 100644 --- a/modules/basext/basext.asm +++ b/modules/snapman/snapheader.inc @@ -20,25 +20,28 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. -; Creates the BASIC extensions module. - include "../../rom/spectranet.asm" - include "../../rom/sysvars.sym" - include "../../rom/zxsysvars.asm" - include "../../rom/fs_defs.asm" - include "../config/config_interface.asm" - include "defs.asm" -INTERPWKSPC equ 0x3000 -TNFS_PAGE equ 0xFF +; Functions to load .SNA0 (snapshot) files - org 0x2000 - include "vectors.asm" ; vector table - include "init.asm" ; initialization routines - include "commands.asm" ; Command routines - include "loader.asm" ; Load/save routines - include "tapetrap.asm" ; tape traps - include "info.asm" ; %info command - include "strings_en.asm" ; Strings - include "parseurl.asm" ; Mount point URL parser - include "listdir.asm" ; List directory - include "boot.asm" ; Boot loader +; SNA file definitions +HEADER equ 0x3000 +SNA_I equ HEADER +SNA_HLALT equ HEADER+1 +SNA_DEALT equ HEADER+3 +SNA_BCALT equ HEADER+5 +SNA_AFALT equ HEADER+7 +SNA_HL equ HEADER+9 +SNA_DE equ HEADER+11 +SNA_BC equ HEADER+13 +SNA_IY equ HEADER+15 +SNA_IX equ HEADER+17 +SNA_EIDI equ HEADER+19 +SNA_R equ HEADER+20 +SNA_AF equ HEADER+21 +SNA_SP equ HEADER+23 +SNA_IM equ HEADER+25 +SNA_BORDER equ HEADER+26 +HEADERSZ equ 27 +SNA_PC equ HEADER+27 ; 128K .SNA0 file - program counter +SNA_7FFD equ HEADER+29 ; value of port 0x7FFD +SNA_TRDOS equ HEADER+30 diff --git a/modules/snapman/snapman.asm b/modules/snapman/snapman.asm deleted file mode 100644 index 9445c33..0000000 --- a/modules/snapman/snapman.asm +++ /dev/null @@ -1,39 +0,0 @@ -;The MIT License -; -;Copyright (c) 2009 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; Snapshot Manager. - org 0x2000 ; ROM module start point. - include "vectors.asm" ; Vector/signature table. - include "memory.asm" ; Memory allocation and initialization - include "utils.asm" ; utility functions - include "screen.asm" ; Screen functions - include "directory.asm" ; Read and stat files in the directory - include "inputloop.asm" ; Input loop and handling functions - include "strings_en.asm" ; String table - include "loadsna.asm" ; Loads snapshots - include "savesna.asm" ; Saves snapshots - - include "../../rom/spectranet.asm" ; Spectranet defines - include "../../rom/sysvars.sym" ; System vars - include "../../rom/fs_defs.asm" ; Filesystem defs - include "snapmandefs.asm" ; Defines - diff --git a/modules/snapman/snapmandefs.asm b/modules/snapman/snapman.inc similarity index 100% rename from modules/snapman/snapmandefs.asm rename to modules/snapman/snapman.inc diff --git a/modules/snapman/strings_en.asm b/modules/snapman/strings_en.asm index 7f84aa1..f9dff11 100644 --- a/modules/snapman/strings_en.asm +++ b/modules/snapman/strings_en.asm @@ -19,8 +19,27 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "ctrlchars.inc" -UI_STRINGS defb 0,5,"- SPECTRANET SNAPSHOT MANAGER -",0 +.data +.globl UI_STRINGS +.globl INPUTTABLE +.globl INPUTADDRS +.globl STR_filename +.globl STR_cfoverwrite +.globl STR_loading +.globl STR_saving +.globl STR_cwd +.globl STR_ident +.globl STR_initialized +.globl STR_failed +.globl STR_nomempage +.globl STR_curfile +.globl STR_nofile +.globl STR_newname +.globl STR_cferase +.globl CHAR_YES +UI_STRINGS: defb 0,5,"- SPECTRANET SNAPSHOT MANAGER -",0 defb 1,0,"Use arrow keys to move, Enter to select",0 defb 3,28,"[D] Directory/",0 defb 4,32,"file view",0 @@ -31,8 +50,8 @@ UI_STRINGS defb 0,5,"- SPECTRANET SNAPSHOT MANAGER -",0 defb 18,28,"[Q] Quit",0 defb 20,0,"Dir: ",0 defb 0xFF,0xFF -INPUTTABLE defb "qd",0x0d,"csre",0 -INPUTADDRS defw F_exit +INPUTTABLE: defb "qd",0x0d,"csre",0 +INPUTADDRS: defw F_exit defw F_switchdirview defw F_enterpressed defw F_saveas @@ -40,17 +59,18 @@ INPUTADDRS defw F_exit defw F_rename defw F_erase -CHAR_YES equ 'y' -STR_filename defb "Filename: ",0 -STR_cfoverwrite defb "Overwrite selected file? (y/n): ",0 -STR_loading defb "Loading...",0 -STR_saving defb "Saving...",0 -STR_cwd defb ".",0 -STR_ident defb "Snapshot manager 1.0",0 -STR_initialized defb "Snapshot manager initialized\n",0 -STR_failed defb "Snapmgr. failed to alloc memory\n",0 -STR_nomempage defb "No page was allocated!\n",0 -STR_curfile defb "Current: ",0 -STR_nofile defb "(none)",0 -STR_newname defb "New name> ",0 -STR_cferase defb "Erase the selected file? (y/n): ",0 +CHAR_YES: equ 'y' +STR_filename: defb "Filename: ",0 +STR_cfoverwrite: defb "Overwrite selected file? (y/n): ",0 +STR_loading: defb "Loading...",0 +STR_saving: defb "Saving...",0 +STR_cwd: defb ".",0 +STR_ident: defb "Snapshot manager 1.0",0 +STR_initialized: defb "Snapshot manager initialized",NEWLINE,0 +STR_failed: defb "Snapmgr. failed to alloc memory",NEWLINE,0 +STR_nomempage: defb "No page was allocated!",NEWLINE,0 +STR_curfile: defb "Current: ",0 +STR_nofile: defb "(none)",0 +STR_newname: defb "New name> ",0 +STR_cferase: defb "Erase the selected file? (y/n): ",0 + diff --git a/modules/snapman/utils.asm b/modules/snapman/utils.asm index a87696f..7ade1c2 100644 --- a/modules/snapman/utils.asm +++ b/modules/snapman/utils.asm @@ -20,11 +20,13 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.text ; Utility functions. ;------------------------------------------------------------------------- ; F_strcpy ; Copy a string from HL to DE -F_strcpy +.globl F_strcpy +F_strcpy: ld a, (hl) and a ldi @@ -34,7 +36,8 @@ F_strcpy ;------------------------------------------------------------------------- ; F_strcmp ; Compare a string with another. Strings pointed to by HL and DE -F_strcmp +.globl F_strcmp +F_strcmp: ld a, (de) cpi ret nz diff --git a/modules/snapman/vectors.asm b/modules/snapman/vectors.asm index f163ce1..3878043 100644 --- a/modules/snapman/vectors.asm +++ b/modules/snapman/vectors.asm @@ -21,6 +21,9 @@ ;THE SOFTWARE. ; Snapshot manager extensions vector table +.include "snapheader.inc" +.section vectors +.vectorstart: defb 0xAA ; This is a code ROM defb 0xFB ; ROM ID = 0xFC defw F_init ; RESET vector @@ -31,18 +34,25 @@ defw 0xFFFF defw STR_ident ; Pointer to a string that identifies this mod jp F_modulecall - block 0x2020-$,0xFF +.fillstart: + .fill 0x20-(.fillstart-.vectorstart), 1, 0xFF +.section isr ;----------------------------------------------------------------------- ; F_im2 - Detect interrupt mode 2 ISR -F_im2 +.globl F_im2 +.globl F_im2_lsb +F_im2_lsb equ 0x20 +F_im2: push af ld a, 2 ld (SNA_IM), a pop af reti -F_modulecall +.text +.globl F_modulecall +F_modulecall: ld a, l and a ; call 0 = start UI jp z, F_startui diff --git a/modules/streams/Makefile b/modules/streams/Makefile new file mode 100644 index 0000000..a1d90ec --- /dev/null +++ b/modules/streams/Makefile @@ -0,0 +1,5 @@ +ASOBJS = vectors.o init.o commands.o string_en.o memory.o chanmgr.o io.o buffer.o fileio.o ctrlchan.o flowcontrol.o +OUT = streams.module +# LIBS = -ldebug +include ../make.inc + diff --git a/modules/streams/buffer.asm b/modules/streams/buffer.asm index eb3eb46..256df53 100644 --- a/modules/streams/buffer.asm +++ b/modules/streams/buffer.asm @@ -19,7 +19,9 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "defs.inc" +.include "spectranet.inc" +.text ; Buffer management routines. ; Note - the memory we want to use should be paged into area A. @@ -40,30 +42,31 @@ ;-------------------------------------------------------------------------- ; F_findfreebuf - Returns the number of the first free buffer found. ; Carry set if no buffer available. -F_findfreebuf +.globl F_findfreebuf +F_findfreebuf: push hl ld b, 0x1F ; number of buffers available -.findloop +.findloop1: ld hl, 0x1000 ; address to start from in metadata page -.next +.next1: ld a, (hl) cp b - jr z, .inuse + jr z, .inuse1 inc l ; check second buffer ld a, (hl) cp b - jr z, .inuse + jr z, .inuse1 ld a, 7 ; advance by 7 bytes add a, l - jr z, .free ; this buffer number wasn't found, it's free + jr z, .free1 ; this buffer number wasn't found, it's free ld l, a - jr .next -.inuse - djnz .findloop ; try the next buffer number + jr .next1 +.inuse1: + djnz .findloop1 ; try the next buffer number pop hl scf ; we ran out of attempts ret -.free +.free1: pop hl ld a, b ; get result into A and a ; clear possible carry (from the add op) @@ -72,7 +75,8 @@ F_findfreebuf ;--------------------------------------------------------------------------- ; F_feedbuffer ; Adds the byte in A to the buffer for the stream in L -F_feedbuffer +.globl F_feedbuffer +F_feedbuffer: ex af, af' ; save A call F_findmetadata ; IX = pointer to metadata @@ -82,14 +86,14 @@ F_feedbuffer ld e, (ix+STRM_WRITEPTR); DE = current buffer pointer ex af, af' ; get byte back cp 0x0d ; Spectrum ENTER? - jr nz, .cont + jr nz, .cont2 ld (de), a ; Convert it to 0x0d 0x0a inc e ld a, 0x0a ld (de), a jr F_flushbuffer -.cont +.cont2: ld (de), a ; write the value into the buffer ld a, 0xFE ; it would be easier to flush one byte later cp e ; but we must leave enough room for CRLF @@ -104,7 +108,8 @@ F_feedbuffer ; Flushes the given buffer ; DE = current buffer pointer ; IX = current buffer info pointer -F_flushbuffer +.globl F_flushbuffer +F_flushbuffer: ; TODO ; This needs to work with all kinds of streams, not just SOCK_STREAM ld (ix+STRM_WRITEPTR), 0 ; reset buffer pointer @@ -119,17 +124,17 @@ F_flushbuffer ; BC now = length ; A now = file descriptor bit 0, (ix+STRM_FLAGS) ; Check "is a file" flag - jr nz, .filewrite + jr nz, .filewrite3 call SEND ; Send the data - jr c, .borked + jr c, .borked3 ret -.borked +.borked3: ld a, 2 ; todo - proper error handling out (254), a ret -.filewrite +.filewrite3: ; TODO: File I/O does not yet handle writing a buffer in page A ; because that's where the VFS mods put their data. So copy the ; data first. However, VFS modules ought to be able to cope with @@ -141,6 +146,6 @@ F_flushbuffer pop bc ; restore the length ld hl, INTERPWKSPC ; start of new buffer call WRITE - jr c, .borked + jr c, .borked3 ret diff --git a/modules/streams/chanmgr.asm b/modules/streams/chanmgr.asm index 903bfd0..a86dd85 100644 --- a/modules/streams/chanmgr.asm +++ b/modules/streams/chanmgr.asm @@ -19,7 +19,15 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "spectranet.inc" +.include "zxrom.inc" +.include "zxsysvars.inc" +.include "sysvars.inc" +.include "defs.inc" +.include "ctrlchars.inc" +.include "streamvars.inc" +.include "sockdefs.inc" +.text ; Channel manager - handles creation and deletion of channels ;------------------------------------------------------------------------ @@ -39,10 +47,11 @@ ; byte 3: read buffer pointer ; byte 4: file descriptor ; byte 5: flags (bit 0 = socket or file) -F_connect_impl +.globl F_connect_impl +F_connect_impl: call F_fetchpage ; fetch our memory call c, F_allocpage - jr c, .memerr ; one already + jr c, .memerr1 ; one already pop bc ; Get stream number ld (v_bcsave), bc ; save it @@ -55,17 +64,17 @@ F_connect_impl ld hl, INTERPWKSPC+5 ; Try to look up the supplied ld de, INTERPWKSPC ; hostname call GETHOSTBYNAME - jr c, .sockerr3 + jr c, .sockerr31 ld c, SOCK_STREAM ; Now try to connect to the host - call SOCKET ; open the socket... - jr c, .sockerr3 + jr c, .sockerr31 ld (INTERPWKSPC+4), a ; save the socket number pop bc ; get port number ld de, INTERPWKSPC ; address of IP address call CONNECT - jr c, .sockerr4 + jr c, .sockerr41 ; All was well, so a channel can now be created and a stream ; attached. @@ -81,11 +90,11 @@ F_connect_impl ld l, a call F_findfreebuf ; create a write buffer - jr c, .nobufcleanup + jr c, .nobufcleanup1 ld (hl), a ; save the buffer number inc l call F_findfreebuf ; create a read buffer - jr c, .nobufcleanup + jr c, .nobufcleanup1 ld (hl), a inc l @@ -101,7 +110,7 @@ F_connect_impl call F_leave ; restore memory page A jp EXIT_SUCCESS -.memerr +.memerr1: pop hl ; restore the stack pop hl pop hl @@ -109,22 +118,23 @@ F_connect_impl ld hl, STR_nomem jp REPORTERR ; Report "Out of memory" -.sockerr ; TODO - better error routine +.sockerr1: ; TODO - better error routine pop hl -.sockerr1 +.sockerr11: pop hl -.sockerr2 +.sockerr21: pop hl -.sockerr3 +.sockerr31: pop hl -.sockerr4 +.sockerr41: call F_leave ld hl, STR_sockerr jp REPORTERR -.nobufcleanup +.nobufcleanup1: ld a, (INTERPWKSPC+4) ; get the socket number back -NOBUFCLEANUP +.globl NOBUFCLEANUP +NOBUFCLEANUP: call CLOSE ; and close it ld a, (v_bcsave) ; clear down our data structure rlca @@ -144,37 +154,40 @@ NOBUFCLEANUP ; Implementation of the close routine. ; This routine is jumped into from the BASIC interpreter, argument is on ; the stack. -F_close_impl +.globl F_close_impl +F_close_impl: call F_fetchpage pop hl ; Get channel number from stack. ld a, l ld (v_curchan), a ; store current channel value call F_close_main - jr c, .closeerr + jr c, .closeerr2 call F_leave call EXIT_SUCCESS -.closeerr +.closeerr2: call F_leave ld hl, STR_closeerr jp REPORTERR -F_close_main +.globl F_close_main +F_close_main: call F_findmetadata_a -F_close_ix +.globl F_close_ix +F_close_ix: ld a, (ix+STRM_FD) ; fetch the FD and a ; Valid FD? ret z ; Stream not open, do nothing. ld l, (ix+STRM_FLAGS) ; get the flags push ix bit BIT_ISFILE, l ; is a file? - jr nz, .isfile + jr nz, .isfile4 bit BIT_ISDIR, l ; is a directory? - jr nz, .isdir + jr nz, .isdir4 bit BIT_ISCTRL, l ; control channel? - jr nz, .closedone ; nothing to do. + jr nz, .closedone4 ; nothing to do. call CLOSE ; close the socket -.closedone +.closedone4: pop hl ; get chan metadata start address ld d, h ld e, l @@ -187,21 +200,22 @@ F_close_ix call F_freemem ; Mark memory as free pop af ret -.isfile +.isfile4: call VCLOSE - jr .closedone -.isdir + jr .closedone4 +.isdir4: call CLOSEDIR - jr .closedone + jr .closedone4 ;------------------------------------------------------------------------ ; F_listen_impl ; Implementation of the listen command ; Arguments on the stack: port number, channel number -F_listen_impl +.globl F_listen_impl +F_listen_impl: call F_fetchpage ; fetch our memory call c, F_allocpage - jr c, .memerr ; one already + jr c, .memerr5 ; one already pop bc ; Get stream number ld (v_bcsave), bc ; save it @@ -209,14 +223,14 @@ F_listen_impl ; create the socket and make it listen. ld c, SOCK_STREAM call SOCKET - jr c, .sockerr + jr c, .sockerr5 ld (INTERPWKSPC), a ; save the socket number pop de ; get the port number call BIND ; and bind to the socket - jr c, .sockerr + jr c, .sockerr5 ld a, (INTERPWKSPC) ; fd call LISTEN ; make it listen - jr c, .sockerr + jr c, .sockerr5 ; a listening socket has been created - now create the BASIC ; structures @@ -239,12 +253,12 @@ F_listen_impl set 6, (ix+IOWCHAN) call F_leave jp EXIT_SUCCESS -.sockerr +.sockerr5: pop bc ; fix the stack call F_leave ld hl, STR_sockerr jp REPORTERR -.memerr +.memerr5: pop bc ; fix the stack pop bc ld hl, STR_nomem @@ -253,10 +267,11 @@ F_listen_impl ;------------------------------------------------------------------------ ; F_ctrl_impl ; Set up a control channel. Desired stream in A. -F_ctrl_impl +.globl F_ctrl_impl +F_ctrl_impl: call F_fetchpage ; fetch our memory call c, F_allocpage - jr c, .memerr ; one already + jr c, .memerr6 ; one already ex af, af' call F_findmetadata_a ; find the metadata area @@ -269,14 +284,15 @@ F_ctrl_impl set 5, (ix+IOWCHAN) call F_leave jp EXIT_SUCCESS -.memerr +.memerr6: ld hl, STR_nomem jp REPORTERR ;------------------------------------------------------------------------ ; F_accept_impl ; Accepts an incoming connection -F_accept_impl +.globl F_accept_impl +F_accept_impl: call F_fetchpage pop bc ; Get stream number @@ -292,7 +308,7 @@ F_accept_impl ld l, a ; form the pointer in HL ld a, (hl) ; get the fd and try to accept call ACCEPT - jr c, .sockerr + jr c, .sockerr7 ld (INTERPWKSPC), a ; save the fd ; Now create the metadata for this socket - like with connect, @@ -308,11 +324,11 @@ F_accept_impl ld l, a call F_findfreebuf ; create a write buffer - jr c, .nobufcleanup + jr c, .nobufcleanup7 ld (hl), a ; save the buffer number inc l call F_findfreebuf ; create a read buffer - jr c, .nobufcleanup + jr c, .nobufcleanup7 ld (hl), a inc l @@ -325,20 +341,21 @@ F_accept_impl call F_leave ; restore memory page A jp EXIT_SUCCESS -.sockerr +.sockerr7: ld hl, STR_sockerr jp REPORTERR -.memerr +.memerr7: ld hl, STR_nomem jp REPORTERR -.nobufcleanup +.nobufcleanup7: ld a, (INTERPWKSPC) ; clean up the socket jp NOBUFCLEANUP ;------------------------------------------------------------------------ ; F_createchan ; Creates the channel in BASIC and connects it to a stream -F_createchan +.globl F_createchan +F_createchan: ld (v_asave), a ; Save the argument call F_allocmem ; Allocate memory in ZX RAM push hl ; save the returned address @@ -369,9 +386,12 @@ F_createchan ldir ; copy the stub pop ix ; get start addr into IX ld a, (v_asave) ; get the stream number - ld (ix+IOWCHAN), a ; Set write ID +; ld (ix + IOWCHAN), a ; Set write ID + ld (ix + 3), a set 7, a ; set MSB - ld (IX+IORCHAN), a ; Set read ID +; ld (ix + IORCHAN), a ; Set read ID + ld (ix + 0x0b), a + pop hl ; retrieve the 2nd byte address ld de, (ZX_CHANS) ; get CHANS sysvar and a ; and calculate the offset @@ -395,12 +415,13 @@ F_createchan ; Allocates memory for the new stream. ; Stream number should be in v_asave. ; Returns the address of the memory block in HL -F_allocmem +.globl F_allocmem +F_allocmem: call F_has_zxprog_fallen ; check local vars are valid ld hl, (stream_memptr) ; look for a free memory slot ld a, h or l - jr z, .makeroom ; Make a new one + jr z, .makeroom9 ; Make a new one dec l ; Point at the top most entry dec l ; on the list of free blocks. ld e, (hl) ; We have a slot, get its @@ -409,21 +430,21 @@ F_allocmem dec l ; rewind HL to point at current entry ld a, memptr_bottom % 256 ; have we hit the bottom? cp l - jr nz, .updatememptr + jr nz, .updatememptr9 ld hl, 0 ; no free blocks - clear the pointer -.updatememptr +.updatememptr9: ld (stream_memptr), hl ; zero it, since there's no slots ex de, hl - jr .setusedblock + jr .setusedblock9 -.makeroom +.makeroom9: ld hl, (ZX_PROG) ; get the start of the program area ld bc, (original_zx_prog) ld a, b or c - jr nz, .makeroom1 + jr nz, .makeroom19 ld (original_zx_prog), hl ; save the original PROG variable -.makeroom1 +.makeroom19: dec hl ; pointer to where to make space ld bc, CHAN_LEN ; request this many bytes rst CALLBAS @@ -432,10 +453,10 @@ F_allocmem ld (current_zx_prog), de ; save current PROG address inc hl ; point at 1st byte of channel area -.setusedblock +.setusedblock9: ld a, (v_asave) ; get stream number rlca ; multiply by 2 - add chmemptr_bottom % 256 ; and add the bottom offset + add a, chmemptr_bottom % 256 ; and add the bottom offset ex de, hl ; move block address to DE ld h, chmemptr_bottom / 256 ; get address to save the block ld l, a ; address into HL @@ -449,9 +470,10 @@ F_allocmem ;-------------------------------------------------------------------------- ; F_freemem ; Puts the block associated with this stream in the free block list. -F_freemem +.globl F_freemem +F_freemem: rlca ; multiply by 2 the stream number - add chmemptr_bottom % 256 ; add the offset + add a, chmemptr_bottom % 256 ; add the offset ld h, chmemptr_bottom / 256 ld l, a ; HL = address ld e, (hl) @@ -461,9 +483,9 @@ F_freemem ld hl, (stream_memptr) ld a, h or l - jr nz, .saveblockaddr + jr nz, .saveblockaddr10 ld hl, memptr_bottom ; First entry -.saveblockaddr +.saveblockaddr10: ld (hl), e ; save the address of the free inc l ; block. ld (hl), d @@ -474,12 +496,13 @@ F_freemem ;------------------------------------------------------------------------ ; F_reclaim_strmem ; Gets the ZX ROM to reclaim all the memory we used for channel stubs. -F_reclaim_strmem +.globl F_reclaim_strmem +F_reclaim_strmem: ld de, (original_zx_prog) ; First byte to reclaim ld hl, (current_zx_prog) ; First byte to leave untouched rst CALLBAS defw ZX_RECLAIM_1 ; move the BASIC program back -J_resetvars +J_resetvars: ld hl, 0 ld (current_zx_prog), hl ; clear down the variables ld (original_zx_prog), hl @@ -490,7 +513,8 @@ J_resetvars ; F_has_zxprog_fallen ; If ZX_PROG is smaller than current_zx_prog it is likely the user ; has done NEW. At this point we should reset everything. -F_has_zxprog_fallen +.globl F_has_zxprog_fallen +F_has_zxprog_fallen: or a ; make sure carry is cleared ld hl, (ZX_PROG) ld de, (current_zx_prog) @@ -500,7 +524,7 @@ F_has_zxprog_fallen ; ZX_PROG has fallen so something (NEW, likely) has just ; killed all of our streams. ld a, 1 -.closeall +.closeall12: ld (v_curchan), a call F_findmetadata_a ld a, (ix+STRM_FD) ; open stream? @@ -509,11 +533,12 @@ F_has_zxprog_fallen ld a, (v_curchan) inc a cp 0x10 ; last possible stream is 0x0F - jr nz, .closeall + jr nz, .closeall12 jr J_resetvars ; reset our sysvars ; debugging -F_debugA +.globl F_debugA +F_debugA: push af push hl push de @@ -522,7 +547,7 @@ F_debugA call ITOH8 ld hl, 0x3600 call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 pop bc pop de @@ -531,24 +556,31 @@ F_debugA ret ;-------------- - -IOROUTINE +.globl IOROUTINE +.globl IOWCHAN +.globl IOWROUTINE_LEN +.globl IORROUTINE +.globl IORCHAN +.globl IOROUTINE_LEN +.globl CHAN_LEN +.globl IORROUTINE_LEN +IOROUTINE: ld h, STREAM_ROM_ID ; our ROM ID -IOWCHAN equ ($+1)-IOROUTINE ; the byte to modify +IOWCHAN: equ ($+1)-IOROUTINE ; the byte to modify ld l, 0 ; will be modified to provide channel call MODULECALL ret IOWROUTINE_LEN equ $-IOROUTINE -IORROUTINE +IORROUTINE: ld h, STREAM_ROM_ID -IORCHAN equ ($+1)-IOROUTINE +IORCHAN: equ ($+1)-IOROUTINE ld l, 0 call MODULECALL bit 0, l ; need to do stack munging? - jr z, .munge + jr z, .munge13 ret -.munge +.munge13: ld sp, (ZX_ERR_SP) ; Clear machine stack pop de ; Remove ED-ERROR pop de ; Old value of SP is restored @@ -556,6 +588,6 @@ IORCHAN equ ($+1)-IOROUTINE ret IOROUTINE_LEN equ $-IOROUTINE -CHAN_LEN equ (IOROUTINE_LEN * 2) + 5 +CHAN_LEN equ IOROUTINE_LEN + IOROUTINE_LEN + 5 IORROUTINE_LEN equ $-IORROUTINE diff --git a/modules/streams/commands.asm b/modules/streams/commands.asm index 398825a..a3d89cd 100644 --- a/modules/streams/commands.asm +++ b/modules/streams/commands.asm @@ -19,14 +19,20 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "spectranet.inc" +.include "zxrom.inc" +.include "zxsysvars.inc" +.include "sysvars.inc" +.include "streamvars.inc" +.text ; BASIC extensions ;-------------------------------------------------------------------------- ; F_connect: Receives the %connect command, opens a socket, ; and connects it to a host. ; Syntax is %connect stream,"hostname",port -F_connect +.globl F_connect +F_connect: rst CALLBAS defw ZX_NEXT_CHAR cp '#' ; # means channel number @@ -72,7 +78,8 @@ F_connect ; F_listen ; Opens a socket that listens. ; %listen #n,port -F_listen +.globl F_listen +F_listen: rst CALLBAS defw ZX_NEXT_CHAR cp '#' ; # means channel number @@ -95,7 +102,8 @@ F_listen ;------------------------------------------------------------------------- ; F_accept ; Accepts an incoming connection -F_accept +.globl F_accept +F_accept: rst CALLBAS defw ZX_NEXT_CHAR cp '#' ; # means channel number @@ -118,7 +126,8 @@ F_accept ;------------------------------------------------------------------------- ; F_fopen: Opens a file ; Syntax is %fopen #stream, "filename","filemode" -F_fopen +.globl F_fopen +F_fopen: rst CALLBAS defw ZX_NEXT_CHAR cp '#' ; # means channel number @@ -164,7 +173,8 @@ F_fopen ;------------------------------------------------------------------------ ; F_opendir: Opens a directory ; Syntax is %opendir #stream, "dirname" -F_opendir +.globl F_opendir +F_opendir: rst CALLBAS defw ZX_NEXT_CHAR cp '#' ; # means channel number @@ -198,7 +208,8 @@ F_opendir ;------------------------------------------------------------------------- ; F_close: Closes an open stream. ; Syntax is %close stream -F_close +.globl F_close +F_close: rst CALLBAS defw ZX_NEXT_CHAR cp '#' ; expect channel number @@ -219,7 +230,8 @@ F_close ;------------------------------------------------------------------------ ; F_oneof: Sets the line number to go to on EOF. ; Syntax is %oneof linenumber -F_oneof +.globl F_oneof +F_oneof: rst CALLBAS defw ZX_EXPT1_NUM ; Line number call STATEMENT_END @@ -232,7 +244,7 @@ F_oneof ld (oneof_line), bc ; set the line number call F_leave jp EXIT_SUCCESS -J_memerr +J_memerr: call F_leave ld hl, STR_nomem jp REPORTERR @@ -240,7 +252,8 @@ J_memerr ;-------------------------------------------------------------------------- ; F_ctrt: Opens a control channel. ; Syntax is: %control #n -F_ctrl +.globl F_ctrl +F_ctrl: rst CALLBAS defw ZX_NEXT_CHAR cp '#' ; expect channel number @@ -261,7 +274,8 @@ F_ctrl ;-------------------------------------------------------------------------- ; F_reclaim: Reclaims stream memory ; Syntax is %reclaim -F_reclaim +.globl F_reclaim +F_reclaim: call STATEMENT_END ; No arguments. ; Runtime @@ -274,17 +288,18 @@ F_reclaim ;-------------------------------------------------------------------------- ; Copy a BASIC string to a C string. ; BASIC string in DE, C string (dest) in HL -F_basstrcpy +.globl F_basstrcpy +F_basstrcpy: ld a, b ; end of string? or c - jr z, .terminate + jr z, .terminate10 ld a, (de) ld (hl), a inc hl inc de dec bc jr F_basstrcpy -.terminate +.terminate10: xor a ; put the null on the end ld (hl), a inc hl diff --git a/modules/streams/ctrlchan.asm b/modules/streams/ctrlchan.asm index 3dcbf94..e5ae50f 100644 --- a/modules/streams/ctrlchan.asm +++ b/modules/streams/ctrlchan.asm @@ -33,17 +33,23 @@ ; byte 1: current command ; byte 2: state of current cmd ; byte 3: stream to act upon - +.include "zxrom.inc" +.include "zxsysvars.inc" +.include "spectranet.inc" +.include "defs.inc" +.text ;------------------------------------------------------------------------- ; Control stream entry point -F_control +.globl F_control +F_control: bit 7, l jr nz, F_read_ctrlstream ; F_write_ctrlstream ; Sets the function of the control stream. This allows the BASIC ; programmer do something like "INPUT#4;"command";a%". ; Enter with L=stream -F_write_ctrlstream +.globl F_write_ctrlstream +F_write_ctrlstream: ex af, af' call F_findmetadata ; find our metadata table ex af, af' @@ -55,12 +61,13 @@ F_write_ctrlstream ;------------------------------------------------------------------------- ; F_read_ctrlstream -F_read_ctrlstream +.globl F_read_ctrlstream +F_read_ctrlstream: call F_findmetadata ; stream metadata now pointed to by IX ld hl, ZX_TV_FLAG ; the mode is considered unchanged res 3, (hl) -.isinkey ; The control stream only works with +.isinkey3: ; The control stream only works with ld hl, (ZX_ERR_SP) ; INPUT#, make INKEY$ a no-op ld e, (hl) inc hl @@ -68,21 +75,21 @@ F_read_ctrlstream and a ld hl, 0x107F ; Compare with ED_ERROR sbc hl, de - jp nz, .wasinkey + jp nz, .wasinkey3 ld a, (ix+OFS_CURCMD) ; find out the command in use cp CMD_POLLALL jp z, J_pollall and a - jr z, .nocmd + jr z, .nocmd3 -.badcmd +.badcmd3: ld hl, STR_badcmd ; Unknown command jp F_sendbuf -.nocmd +.nocmd3: ld hl, STR_nocmd jp F_sendbuf -.wasinkey +.wasinkey3: xor a ; Z and C reset - no data ld l, 1 ; Don't fix the stack jp F_leave @@ -93,64 +100,64 @@ F_read_ctrlstream ; Note that not all sockets may be being used by BASIC, some may be used ; by ROM modules or other machine code programs. If a socket that's ; ready is not for a BASIC stream it gets ignored. -J_pollall +J_pollall: ld a, (ix+OFS_CURSTATE) ; check current state and a ; if is zero, do the actual poll - jr nz, .retsockstate ; return the socket state + jr nz, .retsockstate3 ; return the socket state ld (ix+OFS_CURSTATE), 1 ; set current state flag to "get status" ; Check to find out whether there is pending data already ; in the buffer. -.checkbufs +.checkbufs3: ; start with HL pointing at the first potential FD ld hl, BUFMETADATA+STRM_FLAGS+BUFDATASZ ld b, 15 ; maximum number of iterations ld c, a ; store fd -.findloop_buf +.findloop_buf3: xor a ; check flags for the stream cp (hl) ; - for a socket, should all be zero - jr nz, .nextbuf + jr nz, .nextbuf3 dec l ; point at the read buffer current dec l ; pointer cp (hl) - jr nz, .bufrdy ; a buffer still has stuff in it + jr nz, .bufrdy3 ; a buffer still has stuff in it inc l inc l ; restore HL -.nextbuf +.nextbuf3: ld a, BUFDATASZ ; move to the next channel info add a, l ld l, a - djnz .findloop_buf + djnz .findloop_buf3 ; no buffers have pending data, poll the sockets. call POLLALL ; poll all open sockets - jr z, .none ; nothing waiting + jr z, .none3 ; nothing waiting ld (ix+OFS_CURDATA), c ; save socket state ; start with HL pointing at the first potential FD ld hl, BUFMETADATA+STRM_FLAGS+BUFDATASZ ld b, 15 ; maximum number of iterations ld c, a ; store fd -.findloop +.findloop3: xor a ; check flags for the stream cp (hl) ; - for a socket, should all be zero - jr nz, .next + jr nz, .next3 ld a, c ; check FD = stream's FD dec l cp (hl) - jr z, .foundchan + jr z, .foundchan3 inc l -.next +.next3: ld a, BUFDATASZ ; move to the next channel info add a, l ld l, a - djnz .findloop - jr .checkbufs ; something not ready for us, but check + djnz .findloop3 + jr .checkbufs3 ; something not ready for us, but check ; our buffers too. -.bufrdy +.bufrdy3: set BIT_RECV, (ix+OFS_CURDATA) -.foundchan +.foundchan3: ld a, 16 ; maximum stream number sub b ; subtract where we got to ld hl, INTERPWKSPC ; and convert it to a string @@ -159,54 +166,55 @@ J_pollall ld hl, INTERPWKSPC ; and send it to BASIC's input buffer. jp F_sendbuf -.retsockstate +.retsockstate3: ld (ix+OFS_CURSTATE), 0 ; reset state flags ld a, (ix+OFS_CURDATA) ; get the socket's state bit BIT_RECV, a ; Received data? - jr nz, .recv + jr nz, .recv3 bit BIT_DISCON, a ; Disconnected? - jr nz, .discon + jr nz, .discon3 bit BIT_CONN, a ; Connected? - jr nz, .connected + jr nz, .connected3 ld hl, STR_unk jp F_sendbuf -.recv +.recv3: ld hl, STR_recv jp F_sendbuf -.discon +.discon3: ld hl, STR_discon jp F_sendbuf -.connected +.connected3: ld hl, STR_conn jp F_sendbuf -.none +.none3: ld hl, STR_zero jp F_sendbuf ;------------------------------------------------------------------------- ; Send the command buffer. Buffer is at (HL) -F_sendbuf +.globl F_sendbuf +F_sendbuf: ld a, (hl) and a ; end of buffer? - jr z, .bufdone + jr z, .bufdone4 push hl rst CALLBAS defw 0x0F85 ; ZX_ADD_CHAR - put a character into pop hl ; INPUT's buffer. inc hl jr F_sendbuf -.bufdone +.bufdone4: ld a, 0x0d ; put a CR as the last item ld l, 0 ; and signal "munge the stack" scf jp F_leave ; done. ; Some pre-defined strings to return to BASIC. -STR_badcmd defb "err Bad command",0 -STR_nocmd defb "err No command",0 -STR_unk defb "unknown",0 -STR_recv defb "recv",0 -STR_discon defb "disconn",0 -STR_conn defb "conn",0 -STR_zero defb "0",0 +STR_badcmd: defb "err Bad command",0 +STR_nocmd: defb "err No command",0 +STR_unk: defb "unknown",0 +STR_recv: defb "recv",0 +STR_discon: defb "disconn",0 +STR_conn: defb "conn",0 +STR_zero: defb "0",0 diff --git a/modules/streams/streamdefs.asm b/modules/streams/defs.inc similarity index 97% rename from modules/streams/streamdefs.asm rename to modules/streams/defs.inc index c743694..a508ab2 100644 --- a/modules/streams/streamdefs.asm +++ b/modules/streams/defs.inc @@ -57,3 +57,5 @@ BUFDATASZ equ 8 ; Command definitions for the control channel CMD_POLLALL equ 'p' +STREAM_ROM_ID equ 0x02 +INTERPWKSPC equ 0x3000 diff --git a/modules/streams/fileio.asm b/modules/streams/fileio.asm index e3b4894..62d6eae 100644 --- a/modules/streams/fileio.asm +++ b/modules/streams/fileio.asm @@ -19,7 +19,11 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "fcntl.inc" +.include "spectranet.inc" +.include "defs.inc" +.include "sysvars.inc" +.text ; File manager - handles opening and closing of files ;-------------------------------------------------------------------------- @@ -32,10 +36,11 @@ ; Third: r, w or rw (string) ; This function must restore the stack. Like F_connect_impl, it also ; initializes the strean's info structure. -F_fileopen_impl +.globl F_fileopen_impl +F_fileopen_impl: call F_fetchpage ; fetch our memory call c, F_allocpage ; allocate it if it's not been done - jr c, .memerr ; Could not allocate + jr c, .memerr1 ; Could not allocate pop bc ; Fetch the stream number ld (v_bcsave), bc ; and save it. @@ -52,7 +57,7 @@ F_fileopen_impl ld hl, INTERPWKSPC ; pointer to the filename call OPEN ; Try to open the file. - jr c, .openerror + jr c, .openerror1 push af ;:Save the FD we got back @@ -69,11 +74,11 @@ F_fileopen_impl ; TODO: Allocate only one buffer for RO on WO files call F_findfreebuf ; create a write buffer - jr c, .nobufcleanup + jr c, .nobufcleanup1 ld (hl), a ; save the buffer number inc l call F_findfreebuf ; create a read buffer - jr c, .nobufcleanup + jr c, .nobufcleanup1 ld (hl), a inc l @@ -88,19 +93,19 @@ F_fileopen_impl pop de ; get the file mode flags back ld a, O_RDONLY cp e ; Read only file? - jr nz, .writeable + jr nz, .writeable1 set BIT_RDONLY, (hl) ; set read only bit in our flags -.writeable +.writeable1: call F_leave ; restore memory page A jp EXIT_SUCCESS -.openerror +.openerror1: ; TODO: Proper error message here (indirect call to BASEXT rom) pop de ; restore the stack ld hl, STR_fileerr jp REPORTERR -.memerr +.memerr1: pop hl ; unwind the stack pop hl pop hl @@ -109,7 +114,7 @@ F_fileopen_impl ld hl, STR_nomem jp REPORTERR -.nobufcleanup +.nobufcleanup1: pop af ; get FD call VCLOSE ; close the file jp NOBUFCLEANUP ; clean up our structures @@ -117,32 +122,33 @@ F_fileopen_impl ;------------------------------------------------------------------------- ; F_getfilemode: Parses the filemode string pointed to by HL with length ; BC, and returns the VFS filemode flags in E. -F_getfilemode +.globl F_getfilemode +F_getfilemode: ld b, c ; set byte counter ld de, 0 ; clear flags register -.loop +.loop2: ld a, (hl) cp 'r' ; Read? - jr nz, .next + jr nz, .next2 set 0, e ; Set the read flag -.next cp 'w' ; Write? - jr nz, .next1 +.next2: cp 'w' ; Write? + jr nz, .next12 set 1, e ; Set the write flag -.next1 +.next12: cp 'a' ; Append? - jr nz, .next2 + jr nz, .next22 set 0, d -.next2 +.next22: cp 'c' ; Create? - jr nz, .next3 + jr nz, .next32 set 1, d -.next3 +.next32: cp 't' ; Truncate? - jr nz, .next4 + jr nz, .next42 set 3, d -.next4 +.next42: inc hl - djnz .loop + djnz .loop2 bit 1, e ; If the file is writeable, we need ret z ; to ensure there are sensible defaults for @@ -156,10 +162,11 @@ F_getfilemode ; F_opendir_impl ; Opens a directory ; There's no need to create a buffer for a directory. -F_opendir_impl +.globl F_opendir_impl +F_opendir_impl: call F_fetchpage ; fetch our memory call c, F_allocpage ; allocate it if it's not been done - jr c, .memerr ; Could not allocate + jr c, .memerr3 ; Could not allocate pop bc ; Fetch the stream number ld (v_bcsave), bc ; and save it. @@ -171,7 +178,7 @@ F_opendir_impl ld hl, INTERPWKSPC call OPENDIR ; try to open the dir - jr c, .opendirerr + jr c, .opendirerr3 push af ;:Save the FD we got back @@ -184,7 +191,7 @@ F_opendir_impl rlca ; stream information area rlca ld h, 0x10 ; HL points at it. - add 4 ; point A at the fd byte + add a, 4 ; point A at the fd byte ld l, a ; HL = fd byte pop af ld (hl), a ; set directory descriptor @@ -194,14 +201,14 @@ F_opendir_impl call F_leave jp EXIT_SUCCESS ; done -.memerr +.memerr3: pop hl ; restore stack pop hl pop hl ld hl, STR_nomem jp REPORTERR -.opendirerr +.opendirerr3: ; TODO: get proper error code call F_leave ld hl, STR_direrr diff --git a/modules/streams/flowcontrol.asm b/modules/streams/flowcontrol.asm index be7f655..b8b5a30 100644 --- a/modules/streams/flowcontrol.asm +++ b/modules/streams/flowcontrol.asm @@ -19,10 +19,17 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "zxsysvars.inc" +.include "zxrom.inc" +.include "defs.inc" +.include "ctrlchars.inc" +.include "spectranet.inc" +.include "streamvars.inc" +.text ; Handle BASIC flow control -F_eofhandler +.globl F_eofhandler +F_eofhandler: call F_fetchpage ld hl, (oneof_line) ld (ZX_NEWPPC), hl ; set line number @@ -33,7 +40,8 @@ F_eofhandler jp EXIT_SUCCESS ; Munge the stack to cause the program to continue. -F_basic_continue +.globl F_basic_continue +F_basic_continue: ld hl, (ZX_RAMTOP) dec hl dec hl @@ -47,18 +55,19 @@ F_basic_continue ei jp 0x007C ; and page out via this address. -F_showzxstack +.globl F_showzxstack +F_showzxstack: push ix push hl push de push bc push af - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ld ix, (ZX_ERR_SP) ld b, 8 -.loop +.loop3: push bc ld hl, 0x3000 push ix @@ -91,14 +100,14 @@ F_showzxstack ld hl, 0x3000 call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 inc ix inc ix ld hl, (ZX_RAMTOP) pop bc - djnz .loop + djnz .loop3 pop af pop bc diff --git a/modules/streams/init.asm b/modules/streams/init.asm index e66caad..9acc960 100644 --- a/modules/streams/init.asm +++ b/modules/streams/init.asm @@ -19,82 +19,84 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - -INTERPWKSPC equ 0x3000 +.include "defs.inc" +.include "spectranet.inc" +.text ;----------------------------------------------------------------------------- ; F_init: Initializes the interpreter -F_init +.globl F_init +F_init: ld hl, PARSETABLE ld b, NUMCMDS -.loop +.loop1: push bc call ADDBASICEXT pop bc - jr c, .installerror - djnz .loop + jr c, .installerror1 + djnz .loop1 ld hl, STR_basicinit call PRINT42 ret -.installerror +.installerror1: ld hl, STR_basinsterr call PRINT42 ret NUMCMDS equ 9 STREAMPAGE equ 0xFF ; This ROM -PARSETABLE -P_connect defb 0x0b +PARSETABLE: +P_connect: defb 0x0b defw CMD_CONNECT defb STREAMPAGE defw F_connect -P_close defb 0x0b +P_close: defb 0x0b defw CMD_CLOSE defb STREAMPAGE defw F_close -P_listen defb 0x0b +P_listen: defb 0x0b defw CMD_LISTEN defb STREAMPAGE defw F_listen -P_accept defb 0x0b +P_accept: defb 0x0b defw CMD_ACCEPT defb STREAMPAGE defw F_accept -P_fopen defb 0x0b +P_fopen: defb 0x0b defw CMD_FOPEN defb STREAMPAGE defw F_fopen -P_opendir defb 0x0b +P_opendir: defb 0x0b defw CMD_OPENDIR defb STREAMPAGE defw F_opendir -P_oneof defb 0x0b +P_oneof: defb 0x0b defw CMD_ONEOF defb STREAMPAGE defw F_oneof -P_reclaim defb 0x0b +P_reclaim: defb 0x0b defw CMD_RECLAIM defb STREAMPAGE defw F_reclaim -P_ctrl defb 0x0b +P_ctrl: defb 0x0b defw CMD_CONTROL defb STREAMPAGE defw F_ctrl -CMD_CONNECT defb "%connect",0 -CMD_CLOSE defb "%close",0 -CMD_LISTEN defb "%listen",0 -CMD_ACCEPT defb "%accept",0 -CMD_FOPEN defb "%fopen",0 -CMD_OPENDIR defb "%opendir",0 -CMD_ONEOF defb "%oneof",0 -CMD_RECLAIM defb "%reclaim",0 -CMD_CONTROL defb "%control",0 +CMD_CONNECT: defb "%connect",0 +CMD_CLOSE: defb "%close",0 +CMD_LISTEN: defb "%listen",0 +CMD_ACCEPT: defb "%accept",0 +CMD_FOPEN: defb "%fopen",0 +CMD_OPENDIR: defb "%opendir",0 +CMD_ONEOF: defb "%oneof",0 +CMD_RECLAIM: defb "%reclaim",0 +CMD_CONTROL: defb "%control",0 diff --git a/modules/streams/io.asm b/modules/streams/io.asm index a518a68..2d7cfdd 100644 --- a/modules/streams/io.asm +++ b/modules/streams/io.asm @@ -20,7 +20,15 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. ; IO routines for streams -J_modcall +.include "spectranet.inc" +.include "streamvars.inc" +.include "zxsysvars.inc" +.include "sysvars.inc" +.include "zxrom.inc" +.include "defs.inc" +.text +.globl J_modcall +J_modcall: call F_fetchpage ; get our memory page bit 5, l ; Control stream? jp nz, F_control @@ -34,7 +42,8 @@ J_modcall ;---------------------------------------------------------------------------- ; F_input ; Process input to a stream. -F_input +.globl F_input +F_input: push hl ld hl, ZX_TV_FLAG ; the mode is considered unchanged res 3, (hl) @@ -44,9 +53,9 @@ F_input ld d, (ix+STRM_WRITEBUF); get tx buffer number ld a, (ix+STRM_WRITEPTR); get tx buffer pointer and a ; if nonzero, flush the buffer - call nz, .flush + call nz, .flush1 -.isinkey +.isinkey1: push hl ld hl, (ZX_ERR_SP) ; fetch the current ERR_SP ld e, (hl) @@ -56,45 +65,45 @@ F_input ld hl, 0x107F ; Compare with ED_ERROR sbc hl, de pop hl - jp nz, .doinkey + jp nz, .doinkey1 -.input +.input1: ld d, (ix+STRM_READBUF) ; get the read buffer number ld e, (ix+STRM_READPTR) ; and the pointer ld a, (ix+STRM_FD) ; get the fd ld (v_asave), a ; save it for the loop operation xor a ; Is the buffer pointer at cp e ; the start of the buffer? - jr z, .getdata ; Yes - so read more data from the network + jr z, .getdata1 ; Yes - so read more data from the network ld b, (ix+STRM_REMAINING) ; remaining bytes in buffer ex de, hl ; and put the buffer pointer in HL - jr .unloadloop + jr .unloadloop1 -.getdata +.getdata1: ld a, (v_asave) ; Get the descriptor ld bc, 255 ; read up to 255 chars ld l, (ix+STRM_FLAGS) ; check flags bit bit BIT_ISFILE, l ; is a file? - jr nz, .readfromfile + jr nz, .readfromfile1 bit BIT_ISDIR, l ; is a directory? - jr nz, .readdir + jr nz, .readdir1 push de ; save bufptr call RECV pop hl ; retrieve bufptr into hl -.readdone - jp c, .readerr -.readdirdone +.readdone1: + jp c, .readerr1 +.readdirdone1: ld b, c ; get the length returned into B for djnz -.unloadloop +.unloadloop1: ld a, (hl) cp 0x0d ; This is how the Interface 1 does it... - jr z, .checkformore ; Either a CR + jr z, .checkformore1 ; Either a CR cp 0x0a - jr z, .checkformore ; or a linefeed + jr z, .checkformore1 ; or a linefeed cp '"' - call z, .addquote ; Escape the " character to prevent error C + call z, .addquote1 ; Escape the " character to prevent error C push hl push bc rst CALLBAS @@ -102,14 +111,14 @@ F_input pop bc pop hl inc l - djnz .unloadloop + djnz .unloadloop1 ld d, (ix+STRM_READBUF) ; reset everything to get the next set ld e, 0 ; of bytes ld (ix+STRM_READPTR), e ld (ix+STRM_REMAINING), e - jr .getdata ; go get it + jr .getdata1 ; go get it -.addquote ; small routine to add an extra " +.addquote1: ; small routine to add an extra " push hl ; character to the input stream to push bc ; prevent C Nonsense in BASIC rst CALLBAS @@ -119,98 +128,98 @@ F_input ld a, '"' ret -.readfromfile +.readfromfile1: push de push ix call READ pop ix pop hl ; unloadloop uses hl as pointer - jr .readdone -.readdir + jr .readdone1 +.readdir1: ld de, INTERPWKSPC ; %opendir does not allocate a buffer call READDIR ; so use temporary workspace. - jp c, .readerr ; + jp c, .readerr1 ; ld hl, INTERPWKSPC -.readdirloop +.readdirloop1: ld a, (hl) ; never have a partial read doing READDIR. and a ; End of string? - jr z, .exitnopop ; Return to BASIC + jr z, .exitnopop1 ; Return to BASIC push hl rst CALLBAS ; Feed INPUT defw 0x0F85 pop hl inc hl - jr .readdirloop + jr .readdirloop1 -.exitnopop +.exitnopop1: ld a, 0x0d ; BASIC expects this to end INPUT ld l, 0 ; signal "munge the stack" scf jp F_leave -.checkformore +.checkformore1: dec b ; do what djnz would have done if it xor a ; had got to the end... cp b ; no more chars left? - jr z, .cleardown + jr z, .cleardown1 inc l ; next byte in the buffer ld a, (hl) ; see what it is cp 0x0d - jr z, .checklastcr + jr z, .checklastcr1 cp 0x0a - jr z, .checklastcr -.saveposition + jr z, .checklastcr1 +.saveposition1: ld (ix+STRM_READPTR), l ; save the current position ld (ix+STRM_REMAINING), b ; save bytes remaining - jr .exitnopop -.cleardown + jr .exitnopop1 +.cleardown1: ld (ix+STRM_READPTR), 0 ; clear bufpos ld (ix+STRM_REMAINING), 0 ; clear bufsz - jr .exitnopop + jr .exitnopop1 -.checklastcr +.checklastcr1: dec b ; have we finally finished? xor a cp b - jr z, .cleardown ; yes, just leave now. + jr z, .cleardown1 ; yes, just leave now. inc l ; otherwise advance the buffer - jr .saveposition ; and save where we got to + jr .saveposition1 ; and save where we got to -.flush +.flush1: dec a ; make actual end position, not new char pos ld e, a ; make buffer LSB call F_flushbuffer ret -.doinkey +.doinkey1: ld a, (ix+STRM_FD) ; get the socket ld (v_asave), a ; save it call POLLFD ; anything to receive? - jr c, .readerr ; Read error? - jr z, .nodata ; No hay nada + jr c, .readerr1 ; Read error? + jr z, .nodata1 ; No hay nada ld a, (v_asave) ; get the fd back ld de, INTERPWKSPC ld bc, 1 ; read one byte call RECV - jr c, .readerr + jr c, .readerr1 ld a, (INTERPWKSPC) ld l, 1 ; signal "don't munge the stack" scf ; signal 'character available' ret -.nodata +.nodata1: xor a ; carry and zero reset - no data ld l, 1 ; signal "don't munge the stack" jp F_leave -.readerrpop +.readerrpop1: pop hl ; fix the stack -.readerr ; TODO error handling +.readerr1: ; TODO error handling ld hl, (oneof_line) ; see if we have a line number to go to ld a, h or l - jr nz, .eof_jump + jr nz, .eof_jump1 ld hl, INTERPWKSPC call ITOH8 @@ -220,17 +229,18 @@ F_input ld l, 1 ; signal "don't munge the stack" jp F_leave -.eof_jump +.eof_jump1: ld (ZX_NEWPPC), hl ; set the line number xor a ld (ZX_NSPPC), a ; and statement number to 0 - jp .exitnopop ; exit *without* error + jp .exitnopop1 ; exit *without* error ;-------------------------------------------------------------------------- ; F_ctrlstream ; Handle a control stream (read only) - at the moment, only listening ; sockets. -F_ctrlstream +.globl F_ctrlstream +F_ctrlstream: ld a, l ; convert the function and 0x0F ; number to the stream number rlca @@ -246,14 +256,14 @@ F_ctrlstream ld hl, ZX_TV_FLAG ; the mode is considered unchanged res 3, (hl) - jr z, .nodata ; Socket has no events + jr z, .nodata2 ; Socket has no events ld a, '1' ; indicate event ld l, 1 ; signal "don't munge the stack" scf ; signal 'character available' ret -.nodata +.nodata2: xor a ; carry and zero reset - no data ld l, 1 ; signal "don't munge the stack" jp F_leave @@ -261,9 +271,11 @@ F_ctrlstream ;------------------------------------------------------------------------- ; F_findmetadata ; Finds the data block for the stream in L -F_findmetadata +.globl F_findmetadata +F_findmetadata: ld a, l ; convert the function number to the -F_findmetadata_a ; stream number. +.globl F_findmetadata_a +F_findmetadata_a: ; stream number. and 0x0F rlca rlca @@ -274,29 +286,3 @@ F_findmetadata_a ; stream number. pop ix ; transfer the address to IX ret -;F_debugprint -; ld (0x3200), ix -; pop ix -; inc ix -; inc ix -; push ix -; push af -; push bc -; push de -; push hl -; ld h, (ix-1) -; ld l, (ix-2) -; call PRINT42 -; pop hl -; pop de -; pop bc -; pop af -; ld ix, (0x3200) -; ret -;STR_CHECKFORMORE defb "checkformore\n",0 -;STR_READDONE defb "readdone\n",0 -;STR_INPUT defb "input\n",0 -;STR_CLEARDOWN defb "cleardown\n",0 -;STR_SAVEPOS defb "savepos\n",0 - - diff --git a/modules/streams/memory.asm b/modules/streams/memory.asm index 5e18a8a..350b352 100644 --- a/modules/streams/memory.asm +++ b/modules/streams/memory.asm @@ -19,11 +19,14 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "spectranet.inc" +.include "sysvars.inc" +.text ; Claim our memory page, functions to fetch etc. ; Note: Ought to be a library function. -F_allocpage +.globl F_allocpage +F_allocpage: ld a, (v_pgb) ; Find our identity call RESERVEPAGE ret c ; Failed to reserve a page! @@ -53,7 +56,8 @@ F_allocpage ;----------------------------------------------------------------------------- ; F_fetchpage ; Gets our page of RAM and puts it in page area A. -F_fetchpage +.globl F_fetchpage +F_fetchpage: push af push hl ld a, (v_pgb) ; get our ROM number and calculate @@ -64,7 +68,7 @@ F_fetchpage ld l, a ld a, (hl) ; fetch the page number and a ; make sure it's nonzero - jr z, .nopage + jr z, .nopage2 inc l ; point hl at "page number storage" ex af, af' ld a, (v_pga) @@ -75,7 +79,7 @@ F_fetchpage pop af or a ; ensure carry is cleared ret -.nopage +.nopage2: pop hl ; restore the stack pop af ld a, 0xFF ; TODO: ENOMEM return code @@ -86,7 +90,8 @@ F_fetchpage ; F_isallocated ; Tests to see if we have a memory page allocated already. ; Returns nonzero if we have a page -F_isallocated +.globl F_isallocated +F_isallocated: push hl ld a, (v_pgb) ; get our ROM number rlca ; multiply by 8 to find our @@ -102,8 +107,10 @@ F_isallocated ;--------------------------------------------------------------------------- ; F_restorepage ; Restores page A to its original value. -F_leave -F_restorepage +.globl F_leave +F_leave: +.globl F_restorepage +F_restorepage: push af push hl ld a, (v_pgb) ; calculate the offset... diff --git a/modules/streams/streamvars.asm b/modules/streams/streamvars.inc similarity index 100% rename from modules/streams/streamvars.asm rename to modules/streams/streamvars.inc diff --git a/modules/streams/string_en.asm b/modules/streams/string_en.asm index 5a44e9f..f63dba5 100644 --- a/modules/streams/string_en.asm +++ b/modules/streams/string_en.asm @@ -19,15 +19,24 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "ctrlchars.inc" ; English strings - -STR_basicinit defb "BASIC streams support initialized\n",0 -STR_basinsterr defb "BASIC streams initialization failed\n",0 -STR_nomem defb "Out of memory pages",0 -STR_sockerr defb "Socket error",0 -STR_closeerr defb "Could not close socket",0 -STR_nobuferr defb "Out of buffers",0 -STR_fileerr defb "Error opening file",0 -STR_direrr defb "Error opening directory",0 +.data +.globl STR_basicinit +.globl STR_basinsterr +.globl STR_nomem +.globl STR_sockerr +.globl STR_closeerr +.globl STR_nobuferr +.globl STR_fileerr +.globl STR_direrr +STR_basicinit: defb "BASIC streams support initialized",NEWLINE,0 +STR_basinsterr: defb "BASIC streams initialization failed",NEWLINE,0 +STR_nomem: defb "Out of memory pages",0 +STR_sockerr: defb "Socket error",0 +STR_closeerr: defb "Could not close socket",0 +STR_nobuferr: defb "Out of buffers",0 +STR_fileerr: defb "Error opening file",0 +STR_direrr: defb "Error opening directory",0 diff --git a/modules/streams/vectors.asm b/modules/streams/vectors.asm index d6f2b39..db9e7c1 100644 --- a/modules/streams/vectors.asm +++ b/modules/streams/vectors.asm @@ -22,6 +22,8 @@ ; BAISC streams support ; Vector table +.include "defs.inc" +.section vectors defb 0xAA ; This is a code ROM defb STREAM_ROM_ID ; Rom ID 0x01 defw F_init ; RESET vector @@ -32,5 +34,6 @@ defw 0xFFFF defw STR_ident ; Pointer to a string that identifies this mod jp J_modcall ; we have a module call routine -STR_ident - defb "Streams 1.0",0 +.data +STR_ident: + defb "Streams 1.00",0 diff --git a/rom/Makefile b/rom/Makefile new file mode 100644 index 0000000..c69d955 --- /dev/null +++ b/rom/Makefile @@ -0,0 +1,90 @@ +MAP2SYM = ../buildtools/map2sym + +P0OBJS = zeropage.o reset.o trapdispatch.o w5100_ifconfig.o w5100_genintfunc.o w5100_buffer.o w5100_sockalloc.o w5100_sockctrl.o w5100_rxtx.o dns.o utility.o ui_input.o ui_output_stub.o progtrap.o basicextn.o pagealloc.o vfs.o w5100_sockinfo.o +P0OUT = page0.bin +P0LDFLAGS = -T page0.ld -Map $(P0OUT).map -L ../syslib +P0LIBS = -lpager + +P1OBJS = ui_keyscan.o ui_funcs.o +P1OUT = page1.bin +P1LDFLAGS = -T page1.ld -Map $(P1OUT).map -L ../syslib +P1LIBS = -lromui + +P2OBJS = utilromvectors.o utility_impl.o utilnmi.o save7ffd.o utilnmi_en.o +P2OUT = page2.bin +P2LDFLAGS = -T ../modules/modules.ld -Map $(P2OUT).map -L ../syslib +P2LIBS = -lromui + +P3OBJS = tnfs_vectors.o tnfs_init.o tnfs_core.o tnfs_mount.o tnfs_file.o tnfs_directory.o inetinit.o dhcpclient.o dhcp_data.o basstart.o startmsg.o +P3OUT = page3.bin +P3LDFLAGS = -T ../modules/modules.ld -Map $(P3OUT).map + +MODMANOBJS = romconfigmain.o romconfstrings_en.o +MODMANOUT = modman.bin +MODMANLDFLAGS = -T modman.ld -L ../syslib -Map $(MODMANOUT).map +MODMANLIBS = -lromui -lflashwrite + +JPTABLEOBJS = jumptable.o +JPTABLEOUT = jumptable.bin +JPTABLELDFLAGS = -Ttext 0x0000 + +DATEFILE = date.xinc +VERFILE = ver.xinc +P3SYMS = page3.xinc +P2SYMS = page2.xinc +P1SYMS = page1.xinc +P0SYMS = page0.xinc + +INSTALLDIR = ../installer +CP = cp -f + +all: page0 page1 page2 page3 jptable + +page0: ver p1syms p2syms p3syms $(P0OBJS) + $(LD) -o $(P0OUT) $(P0OBJS) $(P0LDFLAGS) $(P0LIBS) + $(CP) $(P0OUT) $(INSTALLDIR) + +page1: $(P1OBJS) + $(LD) -o $(P1OUT) $(P1OBJS) $(P1LDFLAGS) $(P1LIBS) + $(CP) $(P1OUT) $(INSTALLDIR) + +page2: modman $(P2OBJS) + $(LD) -o $(P2OUT) $(P2OBJS) $(P2LDFLAGS) $(P2LIBS) + $(CP) $(P2OUT) $(INSTALLDIR) + +page3: date ver $(P3OBJS) + $(LD) -o $(P3OUT) $(P3OBJS) $(P3LDFLAGS) $(P3LIBS) + $(CP) $(P3OUT) $(INSTALLDIR) + +modman: $(MODMANOBJS) + $(LD) -o $(MODMANOUT) $(MODMANOBJS) $(MODMANLDFLAGS) $(MODMANLIBS) + +jptable: p0syms $(JPTABLEOBJS) + $(LD) -o $(JPTABLEOUT) $(JPTABLEOBJS) $(JPTABLELDFLAGS) + $(CP) $(JPTABLEOUT) $(INSTALLDIR) + +date: $(DATEFILE) +$(DATEFILE): + echo "blddate: defb \"`date`\",0x0a,0" > $(DATEFILE) + +ver: $(VERFILE) +$(VERFILE): + echo "bldstr: defb \"`whoami`@`hostname` R`svn info .|grep -m 1 Rev|cut -d " " -f 2`\",0x0a,0" > $(VERFILE) + +p0syms: page0 $(P0SYMS) +$(P0SYMS): + $(MAP2SYM) $(P0OUT).map $(P0SYMS) + +p1syms: page1 $(P1SYMS) +$(P1SYMS): + $(MAP2SYM) $(P1OUT).map $(P1SYMS) + +p2syms: page2 $(P2SYMS) +$(P2SYMS): + $(MAP2SYM) $(P2OUT).map $(P2SYMS) + +p3syms: page3 $(P3SYMS) +$(P3SYMS): + $(MAP2SYM) $(P3OUT).map $(P3SYMS) + +include ../make.inc diff --git a/rom/basicextn.asm b/rom/basicextn.asm index 2e825bd..f0cbab8 100644 --- a/rom/basicextn.asm +++ b/rom/basicextn.asm @@ -33,6 +33,11 @@ ; handler works and some sample code. ; Melbourne House for the Complete Shadow ROM disassembly, which was very ; instructive in this endeavour. +.include "sysvars.inc" +.include "zxrom.inc" +.include "zxsysvars.inc" +.include "spectranet.inc" + ;--------------------------------------------------------------------------- ; F_addbasext: Adds a new BASIC command or extension. ; Parameters: HL = pointer to info table for new command. @@ -42,7 +47,9 @@ ; byte 3 - ROM page (0 if none) ; byte 4,5 - pointer to routine to call ; Carry flag is set if we have run out of space. -F_addbasicext +.text +.globl F_addbasicext +F_addbasicext: ld de, (v_tabletop) ; get the current table pointer ld a, 0xFB ; last byte possible cp e @@ -68,7 +75,8 @@ F_addbasicext ; has passed us something of interest. ; Note that changing the Spectranet system variable 'v_rst8vector' allows ; you to completely replace this routine with something else. -J_rst8handler +.globl J_rst8handler +J_rst8handler: ld a, (v_tabletop) ; Check there's something to do and a ; if the LSB of tabletop is 0, nothing to do jp z, J_rst8done @@ -76,11 +84,11 @@ J_rst8handler rst CALLBAS defw ZX_GET_ERR ; get the error code (which may be in ZX ROM) cp 0x0B ; Nonsense in BASIC? - jr z, .handled + jr z, .handled1 ; cp 0x07 ; End of file? ; jp z, J_handleeof jp J_rst8done -.handled +.handled1: ld (ZX_ERR_NR), a ; Save the error number in ZX sysvars ld (v_errnr_save), a ; and ours. ld hl, (ZX_CH_ADD) ; save current CH_ADD @@ -94,88 +102,88 @@ J_rst8handler or 1 ; set 'our command' flag ld (v_interpflags), a bit 7, (iy + D_FLAGS) ; Syntax time or runtime? - jr nz, .runtime + jr nz, .runtime1 ld a, 0xFF ; signal syntax time ld (ZX_PPC_HI), a -.runtime +.runtime1: ld b, (iy + D_SUBPPC) ; Statement counter ld c, 0 ; Quote mark counter bit 7, (iy + D_PPC_HI) ; Program area? - jr z, .progline + jr z, .progline1 push bc ; Save counters rst CALLBAS defw ZX_E_LINE_NO ; Call E_LINE_NO to update CH_ADD to 1st char pop bc rst CALLBAS defw ZX_GET_CHAR ; HL=first char in line - jr .sstat ; jump forward to the DJNZ + jr .sstat1 ; jump forward to the DJNZ ; the following mess sorts out rewinding CH_ADD and removing ; floating point values. -.progline +.progline1: ld hl, (ZX_PROG) ; get address of program -.sc_l_loop +.sc_l_loop1: ld a, (ZX_PPC_HI) ; compare with current line cp (hl) - jr nc, .testlow ; jump if <= line to be searched for -.nreport1 + jr nc, .testlow1 ; jump if <= line to be searched for +.nreport11: ld hl, STR_badcmd ; Return with our equiv of nonsense in BASIC ld a, 1 jp J_reporterr -.testlow +.testlow1: inc hl ; lsb of line number - jr nz, .line_len ; jump if current line is not the expected one + jr nz, .line_len1 ; jump if current line is not the expected one ld a, (ZX_PPC_LO) ; Compare the next byte cp (hl) - jr c, .nreport1 ; Error if the line does not exist -.line_len + jr c, .nreport11 ; Error if the line does not exist +.line_len1: inc hl ; inc the pointer ld e, (hl) inc hl ld d, (hl) ; fetch length into DE inc hl ; point to the start of the line - jr z, .sstat ; jump if the line is found + jr z, .sstat1 ; jump if the line is found add hl, de ; increment pointer to next line - jr .sc_l_loop ; continue until found -.skip_num + jr .sc_l_loop1 ; continue until found +.skip_num1: ld de, 0x06 ; length of a float add hl, de ; skip the float -.each_st +.each_st1: ld a, (hl) ; Get a char from the line cp 0x0E ; Number marker? - jr z, .skip_num ; Skip the number + jr z, .skip_num1 ; Skip the number inc hl ; point to next char cp '"' ; Quote symbol? - jr nz, .chkend ; No + jr nz, .chkend1 ; No dec c ; decrement " counter -.chkend +.chkend1: cp ':' ; Colon? - jr z, .chkeven ; Yes + jr z, .chkeven1 ; Yes cp 0xCB ; THEN token? - jr nz, .chkend_l -.chkeven + jr nz, .chkend_l1 +.chkeven1: bit 0, c ; Even number of " chars? - jr z, .sstat ; Jump if the statement is finished -.chkend_l + jr z, .sstat1 ; Jump if the statement is finished +.chkend_l1: cp 0x80 ; Line finished? - jr nz, .each_st ; No, continue the loop - jr .nreport1 ; Give an error - wrong number of quotes -.sstat - djnz .each_st ; Continue with next stmt + jr nz, .each_st1 ; No, continue the loop + jr .nreport11 ; Give an error - wrong number of quotes +.sstat1: + djnz .each_st1 ; Continue with next stmt dec hl ; HL now points to start address of stmt ld (ZX_CH_ADD), hl ; store in CH_ADD bit 7, (iy + D_FLAGS) ; Checking syntax? - jr nz, .cl_work + jr nz, .cl_work1 bit 7, (iy + D_PPC_HI) ; Give error if line is not in editing area jp z, J_err_6 ; Remove all 6 byte FP numbers put in by the ZX ROM interpreter dec hl ; balance inc below ld c, 0 ; clear C -.rcln_num +.rcln_num1: inc hl ; Point to next char ld a, (hl) ; Get char cp 0x0E ; Start of a number? - jr nz, .nextnum ; no + jr nz, .nextnum1 ; no push bc ; save BC rst CALLBAS ; call RECLAIM-2 in ZX ROM defw ZX_RECLAIM_2 ; to reclaim the number @@ -183,24 +191,25 @@ J_rst8handler ld de, (v_chaddsave) ; jp forward if the 6 bytes were and a ; reclaimed after the char pointed to sbc hl, de ; in the saved CH_ADD - jr nc, .nxt_1 + jr nc, .nxt_11 ex de, hl ; otherwise update saved ch_add ld bc, 6 ; was moved 6 bytes down and a sbc hl, bc ld (v_chaddsave), hl ; save the new value -.nxt_1 +.nxt_11: pop hl ; restore pointer and counter pop bc -.nextnum +.nextnum1: ld a, (hl) ; jump back until the line is finished cp 0x0D - jr nz, .rcln_num -.cl_work ; Clear workspace + jr nz, .rcln_num1 +.cl_work1: ; Clear workspace rst CALLBAS defw ZX_SET_WORK ; ZX SET-WORK routine call F_parser ; If this returns, command not found. -J_err_6 +.globl J_err_6 +J_err_6: ld hl, (v_chaddsave) ; restore initial CH_ADD ld (ZX_CH_ADD), hl jp J_romerr ; Main rom error handler @@ -210,66 +219,68 @@ J_err_6 ; Early escape from RST 8 routine when we've identified the error code ; isn't something we're interested in. It restores the stack and restarts ; the ZX ROM's RST8 routine. -J_rst8done +J_rst8done: ld hl, 0x000B ; return address, after 'ld hl, (CH_ADD)' ex (sp), hl ; put it on the stack, discarding old value ld hl, (ZX_CH_ADD) ; 1st instruction in ZX ROM RST8 routine - jp UNPAGE + jp PAGEOUT ;--------------------------------------------------------------------------- ; J_zxrom_exit ; This exits to the BASIC ROM, resetting our private flags. ; First stack entry should contain address where control should be returned. -J_zxrom_exit +J_zxrom_exit: xor a ld (v_interpflags), a ; reset our flags - jp UNPAGE + jp PAGEOUT ;-------------------------------------------------------------------------- ; F_statement_end / J_exit_success ; This performs 'end of statement' actions. If the statment isn't actually ; ended it triggers the ROM error routine. ; Jumping in at J_exit_success performs the post-command actions. -F_statement_end +.globl F_statement_end +F_statement_end: cp 0x0D ; ZX char for enter - jr z, .synorrun ; if so check for syntax or run time + jr z, .synorrun2 ; if so check for syntax or run time cp ':' ; The other statement end char is : - jr z, .synorrun ; If neither, return with 'nonsense' code + jr z, .synorrun2 ; If neither, return with 'nonsense' code ld hl, STR_badcmd ld a, 1 jp J_sherror -.synorrun +.synorrun2: bit 7, (iy + D_FLAGS) ; Syntax time or run time? ret nz ; Run time - return and allow exec actions. -J_exit_success +.globl J_exit_success +J_exit_success: ei ; ensure interrupts are enabled (else we hang) ld sp, (ZX_ERR_SP) ; restore the stack ld (iy + D_ERR_NR), 0xFF ; clear error status ld hl, ZX_STMT_NEXT ; return address in BASIC ROM bit 7, (iy + D_FLAGS) ; Syntax or run time? - jr z, .syntaxtime ; Do the syntax time return action + jr z, .syntaxtime2 ; Do the syntax time return action ld a, 0x7F ; Check for BREAK - port 0x7FFE in a, (0xFE) rra - jr c, .runtime ; BREAK is not being pressed + jr c, .runtime2 ; BREAK is not being pressed ld a, 0xFE ; port 0xFEFE in a, (0xFE) - jr nc, .break ; BREAK was pressed -.runtime + jr nc, .break2 ; BREAK was pressed +.runtime2: ld hl, ZX_STMT_R_1 ; ROM return address at runtime -.syntaxtime +.syntaxtime2: push hl jp J_zxrom_exit ; Page out and return to Spectrum ROM -.break +.break2: ld (iy + D_ERR_NR), 0x14 ; L - BREAK into program and fall out ; via J_romerr ;--------------------------------------------------------------------------- ; J_romerr/J_sterror ; Exit with an error with the '?' marker set to the right place. ; J_romerr also sets bit 3 of TV_FLAGS. -J_romerr +J_romerr: res 3, (iy + D_TV_FLAG) ; mode unchanged -J_sterror +J_sterror: ld sp, (ZX_ERR_SP) ; reset the stack ld hl, (ZX_CH_ADD) ; copy character reached ld (ZX_X_PTR), hl ; to the place where the ? marker should be @@ -281,14 +292,15 @@ J_sterror ; J_sherror ; Exits via J_sterror if syntax checking, or falls through into ; J_reporterr if not -J_sherror +J_sherror: bit 7, (iy + D_FLAGS) ; Syntax or runtime? jr z, J_sterror ;-------------------------------------------------------------------------- ; J_reporterr ; Reports an error message and returns control to the ZX BASIC ROM. ; Pass the error number in A, error string in HL. -J_reporterr +.globl J_reporterr +J_reporterr: push hl ; save pointer to message ld (ZX_ERR_NR), a ; save the error number xor a ; clear interpreter flags @@ -309,17 +321,17 @@ J_reporterr set 5, (iy + D_TV_FLAG) ; set TV flags accordingly res 3, (iy + D_TV_FLAG) pop hl ; get error string back -.reportloop ; string pointed to by HL is null terminated +.reportloop2: ; string pointed to by HL is null terminated ld a, (hl) ; get char and a ; null terminator? - jr z, .endreport + jr z, .endreport2 push hl rst CALLBAS defw ZX_PRINT_A_1 ; Print the character pop hl inc hl - jr .reportloop -.endreport + jr .reportloop2 +.endreport2: ld sp, (ZX_ERR_SP) ; reset stack inc sp ; ignore first address inc sp @@ -330,7 +342,7 @@ J_reporterr ;--------------------------------------------------------------------------- ; Generic default error message, morally equivalent to 'Nonsense in BASIC' ; but different so it's easy to tell we generated it. -STR_badcmd defb "Bad command",0 +STR_badcmd: defb "Bad command",0 ;=========================================================================== ; The extra command parser. @@ -342,14 +354,15 @@ STR_badcmd defb "Bad command",0 ;--------------------------------------------------------------------------- ; F_parser ; A simple command parser. -F_parser +.globl F_parser +F_parser: ld a, (v_pgb) ; get current page B ld (v_origpageb), a ; and save it ld hl, TABLE_basext ; start at the start of the parser's table -.ploop +.ploop3: ld a, (hl) ; get the error code this command responds to and a ; if it's zero, the table has ended - jr z, .notfound + jr z, .notfound3 inc hl ld e, (hl) ; get the address of the command string inc hl @@ -363,7 +376,7 @@ F_parser push de ; save table pointer call F_pstrcmp ; compare it with what's at CH_ADD pop hl ; restore table pointer into hl - jr nz, .skip ; skip fetching the address if no match + jr nz, .skip3 ; skip fetching the address if no match ld e, (hl) ; fetch address inc hl ld d, (hl) @@ -371,11 +384,11 @@ F_parser ex de, hl pop de ; fix the stack by removing return addr jp (hl) ; jump to the address specified. -.skip +.skip3: inc hl inc hl - jr .ploop -.notfound + jr .ploop3 +.notfound3: ld a, (v_origpageb) ; restore page B call F_setpageB ret @@ -384,26 +397,27 @@ F_parser ; F_pstrcmp ; HL = pointer to string to compare ; Returns with zero flag set if strings match. -F_pstrcmp +.globl F_pstrcmp +F_pstrcmp: ld de, (ZX_CH_ADD) inc de -.loop +.loop4: ld a, (de) ; is the character in the string pointed to by HL a - ; null, return, colon or space - i.e. separator character? + ; null, return, colon or space - i.e4. separator character? cp ' ' - jr z, .match + jr z, .match4 cp ':' - jr z, .match + jr z, .match4 cp 0x0D - jr z, .match + jr z, .match4 cp (hl) ; does it match the target string? inc hl ; yes, so match the next char inc de - jr z, .loop + jr z, .loop4 or 1 ; make sure zero flag is not set ret -.match +.match4: ld (ZX_CH_ADD), de ; save syntax buffer pointer in CH_ADD ld b, a ; save char ; string matched so far - check it's actually ended, too. diff --git a/rom/basstart.asm b/rom/basstart.asm index 0646a46..c4c293f 100644 --- a/rom/basstart.asm +++ b/rom/basstart.asm @@ -19,12 +19,16 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.include "sysdefs.inc" ; Basstart.asm runs module functions that should be run once BASIC has ; shown the copyright message. The basstart function gets called from ; a trap. - -F_basstart +.text +.globl F_basstart +F_basstart: call DISABLETRAP ; release the trap ; we have to do a bit of a trick here, page this page into area @@ -32,12 +36,13 @@ F_basstart ld a, (v_pgb) call SETPAGEA jp F_basstart_go-0x1000 -F_basstart_go +.globl F_basstart_go +F_basstart_go: ld hl, vectors -.searchloop +.searchloop2: ld a, (hl) and a ; last entry done? - jr z, .done + jr z, .done2 inc hl push hl @@ -49,24 +54,25 @@ F_basstart_go ld a, h ; by examining the MSB and finding and 0xF0 ; if it is between 0x20-0x2F cp 0x20 - jr nz, .continue ; not 0x20, try the next one. + jr nz, .continue2 ; not 0x20, try the next one. - ld de, .continue-0x1000 ; set up the return point + ld de, .continue2-0x1000 ; set up the return point push de ; on the stack so RET comes here jp (hl) ; and jump to the vector address -.continue +.continue2: pop hl - jr .searchloop -.done + jr .searchloop2 +.done2: jp PAGETRAPRETURN ;------------------------------------------------------------------------- ; F_basstart_setup ; Set the execution trap. -F_basstart_setup +.globl F_basstart_setup +F_basstart_setup: ld hl, STARTTRAPBLOCK jp SETTRAP -STARTTRAPBLOCK +STARTTRAPBLOCK: defb 0xFF ; this page defw F_basstart ; function to call defw 0x1299 ; stacked address at time of NMI diff --git a/rom/build b/rom/build deleted file mode 100755 index debeef0..0000000 --- a/rom/build +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# note, the order of ASMSOURCES is important. -ASMSOURCES=( sysvars rommodconfig_en rommodconfig_es datarom datarom_es \ - utilrom utilrom_es \ - tnfs rom jumptable \ - romimage romimage_es romprog \ - romprog_es ) - -rm -f *.out -rm -f *.sym -rm -f *.lst - -BUILDER=`whoami` -BUILDHOST=`hostname -s` -BUILDREV=undef - -if [ "$1" == "public" ] -then - svn up - BUILDREV=`svn info . | grep -m 1 Rev | cut -d ' ' -f 2` -fi -echo bldstr defb \"$BUILDER\@$BUILDHOST r=$BUILDREV\",0x0a,0 > ver.asm -echo blddate defb \"`date`\",0x0a,0 > date.asm - -for src in ${ASMSOURCES[@]} -do - echo "Assembling $src..." - sjasmplus $src.asm --sym=$src.sym --lst=$src.lst >.output - if [ "$?" != "0" ]; then - echo - echo "Assembly failed:" - cat .output - echo - exit 1 - fi - - # should we generate the table ROM functions? - if [ "$src" == "utilrom" ]; then - echo "Generating dependent function symbol table for rom..." - grep u_impl utilrom.sym >impl.sym - fi - - if [ "$src" == "tnfs" ]; then - echo "Generating dependent function symbol table for rom..." - grep F_machinetype tnfs.sym >>impl.sym - grep F_basstart_setup tnfs.sym >>impl.sym - fi -done - -echo "rom/romprog.out" >> ../build.out -echo "rom/romprog_es.out" >> ../build.out - diff --git a/rom/config.asm b/rom/config.asm deleted file mode 100644 index 6328159..0000000 --- a/rom/config.asm +++ /dev/null @@ -1,95 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; -; The routines here copy the flash writer into RAM, and calls the flash -; writer. - include "flashwrite.sym" -fwstart - incbin "flashwrite.out" -fwend - -;------------------------------------------------------------------------- -; F_saveconfig -; Copies the flash writer into RAM, calculates the new CRC for the config -; area, and then calls the flash writer. -; The config area in RAM should be already paged into page area A (chip 3 -; page 0x1F) -F_saveconfig - ; copy the flash writer to RAM. - ld hl, fwstart - ld de, fwdest ; defined in flashwrite.asm - ld bc, fwend-fwstart - ldir - - ld de, CONF_RAM ; calculate CRC on updated config values - ld bc, 254 ; up to 254 bytes worth (remaining 2 bytes are CRC) - call F_crc16 ; HL set to CRC - ld (CONFIGCRC_RAM), hl - call F_writeconfig - ret - -;------------------------------------------------------------------------- -; F_copyconfig -; This copies the last 16k sector of flash to the last 4 pages of RAM. -; This allows the configuration to be edited. (The next step is to erase -; the last 16k sector, then copy back the updated configuration plus the -; existing content in the remainder of the last sector of flash). -F_copyconfig - ld a, 0xDC ; chip 3 page 0x1C - RAM - call F_setpageA ; page it into page area A - ld a, 0x1C ; chip 0 page 0x1C - flash - call F_pushpageB ; it's likely this is being called from page B - ld hl, 0x2000 ; and copy - ld de, 0x1000 - ld bc, 0x1000 - ldir - ld a, 0xDD ; chip 3 page 0x1D - RAM - call F_setpageA ; page it into page area A - ld a, 0x1D ; chip 0 page 0x1D - flash - call F_setpageB ; page it into page area B - ld hl, 0x2000 ; and copy - ld de, 0x1000 - ld bc, 0x1000 - ldir - ld a, 0xDE ; chip 3 page 0x1E - RAM - call F_setpageA ; page it into page area A - ld a, 0x1E ; chip 0 page 0x1E - flash - call F_setpageB ; page it into page area B - ld hl, 0x2000 ; and copy - ld de, 0x1000 - ld bc, 0x1000 - ldir - ld a, 0xDF ; chip 3 page 0x1F - RAM - call F_setpageA ; page it into page area A - ld a, 0x1F ; chip 0 page 0x1F - flash - call F_setpageB ; page it into page area B - ld hl, 0x2000 ; and copy - ld de, 0x1000 - ld bc, 0x1000 - ldir - - call F_poppageB ; restore state of page B - ret - - - diff --git a/rom/configutil.asm b/rom/configutil.asm deleted file mode 100644 index e7402bc..0000000 --- a/rom/configutil.asm +++ /dev/null @@ -1,14 +0,0 @@ -; This is merely a version of the configuration utility that is -; run from a Spectrum's memory (and can be loaded from disc). - include "spectranet.asm" - org 0x8000 - call PAGEIN - include "configmain.asm" - jp PAGEOUT - include "ui_config.asm" - include "ui_menu.asm" - include "configlang_en.asm" - include "flashwrite.asm" - include "flashconf.asm" - include "sysvars.sym" - diff --git a/rom/datarom.asm b/rom/datarom.asm deleted file mode 100644 index 35fcfb9..0000000 --- a/rom/datarom.asm +++ /dev/null @@ -1,40 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; The data ROM. -; This lives in page 1 of flash, and provides data such as the character -; set for PUTCHAR42 and other non-code items. It gets paged into area A. - org 0x1000 - include "ui_charset.asm" - include "ui_keyscan.asm" ; keyscan routines - include "ui_output.asm" ; character generation routines - include "sysvars.sym" ; system variable declarations -ROMMODCONF_START - incbin "rommodconfig_en.out" -ROMMODCONF_END - block 0x1FD5-$,0xFF - include "ui_lookup.asm" - -; Note that the jump table gets included at 0x1F00 when the ROM image -; is built. - -DATAROM equ 0x01 ; physical flash page diff --git a/rom/datarom_es.asm b/rom/datarom_es.asm deleted file mode 100644 index 5a4c8da..0000000 --- a/rom/datarom_es.asm +++ /dev/null @@ -1,41 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; The data ROM. -; This lives in page 1 of flash, and provides data such as the character -; set for PUTCHAR42 and other non-code items. It gets paged into area A. - org 0x1000 -; include "ui_lookup.asm" - include "ui_charset.asm" - include "ui_keyscan.asm" - include "ui_output.asm" - include "sysvars.sym" -ROMMODCONF_START - incbin "rommodconfig_es.out" -ROMMODCONF_END - block 0x1FD5-$,0xFF - include "ui_lookup.asm" - -; Note that the jump table gets included at 0x1F00 when the ROM image -; is built. - -DATAROM equ 0x01 ; physical flash page diff --git a/rom/debug.asm b/rom/debug.asm deleted file mode 100644 index 7ffe967..0000000 --- a/rom/debug.asm +++ /dev/null @@ -1,142 +0,0 @@ -; Some simple debug functions. -; hl = start address, b = byte count -F_hexdump - push hl - ld a, (hl) - call F_inttohex8 - call PRINT42 - ld a, ' ' - call PUTCHAR42 - pop hl - inc hl - djnz F_hexdump - ret - -; F_inttohex8 - convert 8 bit number in A. On return hl=ptr to string -F_inttohex8 - push af - push bc - ld hl, v_workspace - ld b, a - call .Num1 - ld a, b - call .Num2 - xor a - ld (hl), a ; add null - pop bc - pop af - ld hl, v_workspace - ret - -.Num1 rra - rra - rra - rra -.Num2 or 0xF0 - daa - add a,0xA0 - adc a,0x40 - - ld (hl),a - inc hl - ret - -F_regdump - push hl - push de - push bc - push af - - ld a, '\n' - call PUTCHAR42 - - push hl - ld a, h - call F_inttohex8 - call PRINT42 - pop hl - ld a, l - call F_inttohex8 - call PRINT42 - ld a, ',' - call PUTCHAR42 - - ld a, d - call F_inttohex8 - call PRINT42 - ld a, e - call F_inttohex8 - call PRINT42 - ld a, ',' - call PUTCHAR42 - - ld a, b - call F_inttohex8 - call PRINT42 - ld a, c - call F_inttohex8 - call PRINT42 - ld a, ',' - call PUTCHAR42 - - pop af - push af - call F_inttohex8 - call PRINT42 - pop bc - push bc - ld a, c - call F_inttohex8 - call PRINT42 - ld a, '\n' - call PUTCHAR42 - - pop af - pop bc - pop de - pop hl - ret - -debugblue - push af - ld a, 1 - out (254), a - pop af - ret -debuggreen - push af - ld a, 4 - out (254), a - pop af - ret -debugred - push af - ld a, 2 - out (254), a - pop af - ret -debugmag - push af - ld a, 3 - out (254), a - pop af - ret -debugcyan - push af - ld a, 5 - out (254), a - pop af - ret -debugyel - push af - ld a, 6 - out (254), a - pop af - ret -debugblack - push af - xor a - out (254), a - pop af - ret - diff --git a/rom/dhcp_data.asm b/rom/dhcp_data.asm new file mode 100644 index 0000000..d83dd6c --- /dev/null +++ b/rom/dhcp_data.asm @@ -0,0 +1,58 @@ +;The MIT License +; +;Copyright (c) 2010 Dylan Smith +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in +;all copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +;THE SOFTWARE. +.include "dhcpdefs.inc" +.include "sysvars.inc" +.data +.globl DHCPDISCOVER_BLOCK +DHCPDISCOVER_BLOCK: +; The following is a block that can be LDIR'd into the options offset +; for a DHCPDISCOVER message. +.globl dhcp_cookie +dhcp_cookie: defb 0x63,0x82,0x53,0x63 + +; DHCP discover message options +.globl dhcp_discover +dhcp_discover: defb 0x35,0x01,0x01 ; option 0x35, 1 byte long, value=1 + +; Parameter request list - ask for the subnet, router and domain +; name server +.globl dhcp_params +dhcp_params: defb 0x37, 0x03, 0x01, 0x03, 0x06 + +; Specify the maximum message size - 768 bytes (buffer+workspace) +.globl dhcp_maxsize +dhcp_maxsize: defb 0x39, 0x02, 0x03, 0x00 + +; Lease time request - 90 days +.globl dhcp_lease +dhcp_lease: defb 0x33, 0x04, 0x00, 0x76, 0xa7, 0x00 +.globl DHCPLEASE_OFFSET +DHCPLEASE_OFFSET equ buf_message+dhcp_options+(dhcp_lease-DHCPDISCOVER_BLOCK)+2 + +; Identifier - our MAC address and hardware type +.globl dhcp_mac +dhcp_mac: defb 0x3d, 0x07, 0x01 ; remaining 6 bytes must be filled + +DHCPDISCOVER_BLOCKEND: +.globl DHCPBLOCKSZ +DHCPBLOCKSZ equ DHCPDISCOVER_BLOCKEND-DHCPDISCOVER_BLOCK + diff --git a/rom/dhcpclient.asm b/rom/dhcpclient.asm index 85d4e80..0e0549b 100644 --- a/rom/dhcpclient.asm +++ b/rom/dhcpclient.asm @@ -21,7 +21,12 @@ ;THE SOFTWARE. ; DHCP Client - +.include "spectranet.inc" +.include "sysvars.inc" +.include "dhcpdefs.inc" +.include "ctrlchars.inc" +.include "sockdefs.inc" +.text ;------------------------------------------------------------------------- ; F_dhcp ; Performs all the actions of a DHCP client, displaying helpful messages @@ -39,9 +44,10 @@ ; The DHCP client requests an IP address, subnet mask and default gateway, ; and any DNS servers. -F_dhcp +.globl F_dhcp +F_dhcp: ld bc, 0xFFFF ; delay for long enough for hw to init -.delay +.delay1: push hl ; waste a load of time push bc push de @@ -51,7 +57,7 @@ F_dhcp dec bc ld a, b or c - jr nz, .delay + jr nz, .delay1 ld hl, STR_dhcpinit call PRINT42 @@ -59,32 +65,32 @@ F_dhcp call PRINT42 ld b, 8 ; num of retries -.retrydiscover +.retrydiscover1: push bc call F_dhcpdiscover - jr c, .borked + jr c, .borked1 call F_dhcprecvoffer - jr nc, .offer + jr nc, .offer1 cp DHCP_INTERRUPTED ; BREAK pressed? - jr z, .break + jr z, .break1 ld a, '.' call PUTCHAR42 pop bc - djnz .retrydiscover + djnz .retrydiscover1 push af ; ran out of retries - ld a, '\n' ; so put a CR + ld a, NEWLINE ; so put a CR call PUTCHAR42 pop af - jr .borked ; then report the error + jr .borked1 ; then report the error -.break +.break1: pop bc ; fix stack - jr .borked + jr .borked1 -.offer +.offer1: pop bc ; fix stack ld hl, STR_dhcpoffer call PRINT42 @@ -92,10 +98,10 @@ F_dhcp ld hl, STR_dhcprequest call PRINT42 call F_dhcpsendrequest - jr c, .borked + jr c, .borked1 call F_dhcprecvack - jr c, .borked + jr c, .borked1 ld hl, STR_dhcpack call PRINT42 @@ -107,11 +113,11 @@ F_dhcp call LONG2IPSTRING ld hl, buf_workspace call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ret -.borked +.borked1: push af ld hl, STR_failed call PRINT42 @@ -120,12 +126,12 @@ F_dhcp call ITOA8 ld hl, v_workspace call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ; pause - TODO: something a bit better (perhaps a keypress?) ld bc, 0xFFFF -.bdelay +.bdelay1: dec bc push hl push de @@ -135,23 +141,24 @@ F_dhcp pop hl ld a, b or c - jr nz, .bdelay + jr nz, .bdelay1 ret -STR_dhcpinit defb "Press BREAK to interrupt.\n",0 -STR_dhcpdiscover defb "DHCPDISCOVER",0 -STR_dhcpoffer defb "\nDHCPOFFER\n",0 -STR_dhcprequest defb "DHCPREQUEST\n",0 -STR_dhcpack defb "DHCPACK\n",0 -STR_failed defb "DHCP failed with return code ",0 -STR_ipaddr defb "Allocated IP address ",0 -STR_interrupted defb "\nBREAK pressed\n",0 +STR_dhcpinit: defb "Press BREAK to interrupt.",NEWLINE,0 +STR_dhcpdiscover: defb "DHCPDISCOVER",0 +STR_dhcpoffer: defb NEWLINE,"DHCPOFFER",NEWLINE,0 +STR_dhcprequest: defb "DHCPREQUEST",NEWLINE,0 +STR_dhcpack: defb "DHCPACK",NEWLINE,0 +STR_failed: defb "DHCP failed with return code ",0 +STR_ipaddr: defb "Allocated IP address ",0 +STR_interrupted: defb NEWLINE,"BREAK pressed",NEWLINE,0 ;------------------------------------------------------------------------- ; F_dhcpdiscover ; Creates and sends the DHCPDISCOVER message. -F_dhcpdiscover +.globl F_dhcpdiscover +F_dhcpdiscover: ; Most of the DHCPDISCOVER message is zeros, so we can ; save a lot of effort by starting with a workspace set to that. ld hl, buf_message @@ -179,7 +186,7 @@ F_dhcpdiscover ; Copy the request options data to the buffer. ld hl, DHCPDISCOVER_BLOCK ld de, buf_message+dhcp_options - ld bc, DHCPDISCOVER_BLOCKEND-DHCPDISCOVER_BLOCK + ld bc, DHCPBLOCKSZ ldir ; Copy the hardware address to the memory pointed by de @@ -191,7 +198,7 @@ F_dhcpdiscover ; Re-initialize other hardware registers to zero call DECONFIG -.send +.send2: ; Send the assembled DHCP message. ld c, SOCK_DGRAM ; Datagram (UDP) socket call SOCKET @@ -201,10 +208,10 @@ F_dhcpdiscover ; The DHCP request should come from port 68 and go to port 67 ld hl, v_dhcpsockinfo ; socket info structure ld b, 4 -.fill - ld (hl), 0xFF ; dest address = 255.255.255.255 +.fill2: + ld (hl), 0xFF ; dest address = 255.2552.2552.2552 inc l - djnz .fill + djnz .fill2 ld hl, 67 ; destination port ld (v_dhcpsockinfo+4), hl inc l @@ -223,7 +230,8 @@ F_dhcpdiscover ; F_dhcprecvoffer ; Wait for a DHCPOFFER message. The assumption is that F_dhcpdiscover ; was called, and has opened a UDP socket for the DHCP messages. -F_dhcprecvoffer +.globl F_dhcprecvoffer +F_dhcprecvoffer: ; bind to port 68 for the incoming message ld a, (v_dhcpfd) ld de, 68 ; port 68 @@ -273,7 +281,8 @@ F_dhcprecvoffer ; F_dhcpsendrequest ; Turn around the data sent in the DHCPOFFER message with the right ; bits tweaked to turn it into a DHCPREQUEST. -F_dhcpsendrequest +.globl F_dhcpsendrequest +F_dhcpsendrequest: ; Most of the DHCPDISCOVER message is zeros, so we can ; save a lot of effort by starting with a workspace set to that. ld hl, buf_message @@ -301,7 +310,7 @@ F_dhcpsendrequest ; Copy the request options data to the buffer. ld hl, DHCPDISCOVER_BLOCK ld de, buf_message+dhcp_options - ld bc, DHCPDISCOVER_BLOCKEND-DHCPDISCOVER_BLOCK + ld bc, DHCPBLOCKSZ ldir ; modify the message from DISCOVER to REQUEST ld hl, buf_message+dhcp_options+6 @@ -336,7 +345,7 @@ F_dhcpsendrequest ; Replace the lease with what we were offered. ld hl, v_dhcplease - ld de, buf_message+dhcp_options+(dhcp_lease-DHCPDISCOVER_BLOCK)+2 + ld de, DHCPLEASE_OFFSET ldi ldi ldi @@ -346,14 +355,14 @@ F_dhcpsendrequest ld de, buf_message+dhcp_chaddr call GETHWADDR -.send +.send4: ; The DHCP request should come from port 68 and go to port 67 ld hl, v_dhcpsockinfo ; socket info structure ld b, 4 -.fill - ld (hl), 0xFF ; dest address = 255.255.255.255 +.fill4: + ld (hl), 0xFF ; dest address = 255.2554.2554.2554 inc l - djnz .fill + djnz .fill4 ld hl, 67 ; destination port ld (v_dhcpsockinfo+4), hl inc l @@ -371,7 +380,8 @@ F_dhcpsendrequest ;--------------------------------------------------------------------------- ; F_dhcprecvack ; Receives the DHCPACK message and extracts the fields that we require. -F_dhcprecvack +.globl F_dhcprecvack +F_dhcprecvack: ; bind to port 68 for the incoming message ld a, (v_dhcpfd) ld de, 68 ; port 68 @@ -412,46 +422,46 @@ F_dhcprecvack ld (v_nspointer), hl ld hl, buf_message+dhcp_options+4 ld b, 0 ; BC = length of option -.optloop +.optloop5: ld a, (hl) ; Option inc hl ld c, (hl) ; Length inc hl cp dhcp_opt_msg ; Message type? (usually 1st in the list) - jr z, .checkmsg + jr z, .checkmsg5 cp dhcp_opt_gateway ; Gateway address? - jr z, .copygw + jr z, .copygw5 cp dhcp_opt_netmask ; Netmask? - jr z, .copynetmask + jr z, .copynetmask5 cp dhcp_opt_dns ; DNS server? - jr z, .copydns + jr z, .copydns5 and a ; End of options? ret z ; in which case return now add hl, bc ; move hl to next option - jr .optloop -.copygw + jr .optloop5 +.copygw5: call IFCONFIG_GW ; set the gateway address - jr .optloop -.copynetmask + jr .optloop5 +.copynetmask5: call IFCONFIG_NETMASK ; set the netmask - jr .optloop -.copydns + jr .optloop5 +.copydns5: ld de, (v_nspointer) ld a, v_nsend % 256 ; address of end of nameserver memory cp e ; no more space? - jr z, .skipdns + jr z, .skipdns5 ldir ld (v_nspointer), de - jr .optloop -.skipdns + jr .optloop5 +.skipdns5: ld c, 4 add hl, bc - jr .optloop -.checkmsg + jr .optloop5 +.checkmsg5: ld a, (hl) ; Get the message type (always 1 byte long) cp dhcp_msg_ack ; check that it's a DHCPACK inc hl ; message is 1 byte long - jr z, .optloop ; if so, continue + jr z, .optloop5 ; if so, continue ld a, DHCP_NAK ; if not set error code and exit scf ret @@ -462,24 +472,25 @@ F_dhcprecvack ; HL = pointer to DHCP options block (after the magic cookie) ; DE = pointer to memory to copy the result ; B = option to search for -F_dhcpgetoption +.globl F_dhcpgetoption +F_dhcpgetoption: ld a, (hl) ; get option and a ; zero? - jr z, .notfound ; option not found + jr z, .notfound6 ; option not found inc hl ld c, (hl) ; get length of option inc hl cp b ; is it the option we're looking for? ld a, b ; save option in A ld b, 0 ; bc now = size of option - jr nz, .nextopt ; no - go for the next option + jr nz, .nextopt6 ; no - go for the next option ldir ; copy option to destination buffer ret ; done -.nextopt +.nextopt6: add hl, bc ; add length to hl to point at the next option ld b, a ; get back the option jr F_dhcpgetoption -.notfound +.notfound6: scf ; indicate option not found ld a, DHCP_OPTNOTFOUND ; return code ret @@ -489,19 +500,20 @@ F_dhcpgetoption ; Compares the XID field received in a DHCP message with the XID that ; we sent in the first instance. Carry is set if the compare fails, ; and A is set to the DHCP_BAD_XID return code on failure. -F_comparexid +.globl F_comparexid +F_comparexid: ld hl, buf_message+dhcp_xid ld de, v_dhcpxid ld b, 4 -.cmploop +.cmploop7: ld a, (de) cp (hl) - jr nz, .badxid + jr nz, .badxid7 inc hl inc de - djnz .cmploop + djnz .cmploop7 ret -.badxid +.badxid7: ld a, DHCP_BAD_XID scf ret @@ -510,14 +522,15 @@ F_comparexid ; F_waitfordhcpmsg ; Waits for DHCP data, and returns with carry set if we poll for too long ; and have not got a response. Also allows for user (keyboard) interruption. -F_waitfordhcpmsg +.globl F_waitfordhcpmsg +F_waitfordhcpmsg: ld bc, dhcp_polltime -.loop +.loop8: push bc ld bc, 0x7ffe ; read B to SPACE in a, (c) ; check for BREAK cp 0xBE - jr z, .interrupted + jr z, .interrupted8 ld a, (v_dhcpfd) call POLLFD ; data ready for this file descriptor? pop bc @@ -526,10 +539,10 @@ F_waitfordhcpmsg dec bc ld a, b or c ; check bc for zero - jr nz, .loop ; make another loop + jr nz, .loop8 ; make another loop ld a, DHCP_TIMEOUT ; error code is timeout jr F_closeonerror ; close and return -.interrupted +.interrupted8: pop bc ; restore stack ld hl, STR_interrupted call PRINT42 @@ -538,7 +551,8 @@ F_waitfordhcpmsg ;-------------------------------------------------------------------------- ; F_closeonerror ; A helper function to close and return with the carry flag set. -F_closeonerror +.globl F_closeonerror +F_closeonerror: push af ld a, (v_dhcpfd) call CLOSE diff --git a/rom/dhcpdefs.asm b/rom/dhcpdefs.inc similarity index 74% rename from rom/dhcpdefs.asm rename to rom/dhcpdefs.inc index edaccf0..82073db 100644 --- a/rom/dhcpdefs.asm +++ b/rom/dhcpdefs.inc @@ -60,26 +60,10 @@ dhcp_opt_msg equ 0x35 ; Message type dhcp_polltime equ 50000 ; how many times to poll when waiting -DHCPDISCOVER_BLOCK -; The following is a block that can be LDIR'd into the options offset -; for a DHCPDISCOVER message. -dhcp_cookie defb 0x63,0x82,0x53,0x63 - -; DHCP discover message options -dhcp_discover defb 0x35,0x01,0x01 ; option 0x35, 1 byte long, value=1 - -; Parameter request list - ask for the subnet, router and domain -; name server -dhcp_params defb 0x37, 0x03, 0x01, 0x03, 0x06 - -; Specify the maximum message size - 768 bytes (buffer+workspace) -dhcp_maxsize defb 0x39, 0x02, 0x03, 0x00 - -; Lease time request - 90 days -dhcp_lease defb 0x33, 0x04, 0x00, 0x76, 0xa7, 0x00 - -; Identifier - our MAC address and hardware type -dhcp_mac defb 0x3d, 0x07, 0x01 ; remaining 6 bytes must be filled - -DHCPDISCOVER_BLOCKEND +; Error return codes - DHCP +DHCP_NAK equ 0xCF +DHCP_OPTNOTFOUND equ 0xCE +DHCP_TIMEOUT equ 0xCD +DHCP_BAD_XID equ 0xCC +DHCP_INTERRUPTED equ 0xCB diff --git a/rom/dns.asm b/rom/dns.asm index fc2364a..e6768a9 100644 --- a/rom/dns.asm +++ b/rom/dns.asm @@ -22,6 +22,10 @@ ; ; Functions for querying DNS. ; +.include "sysvars.inc" +.include "dnsdefs.inc" +.include "w5100_defs.inc" +.include "sockdefs.inc" ;======================================================================== ; F_gethostbyname @@ -35,7 +39,9 @@ ; ; Parameters: HL = pointer to null-terminated string containing address ; DE = pointer to a buffer in which to return the result -F_gethostbyname +.text +.globl F_gethostbyname +F_gethostbyname: push hl push de call F_ipstring2long ; Was a dotted decimal IP address passed? @@ -56,7 +62,8 @@ F_gethostbyname ; DE = pointer to a 4 byte buffer in which to return result ; Returns : A = Status (carry is set on error) ; -F_dnsAquery +.globl F_dnsAquery +F_dnsAquery: ld (v_queryresult), de ; save the query result pointer ; set up the query string to resolve in the workspace area @@ -92,7 +99,7 @@ F_dnsAquery ld hl, 0 ld (v_dnssockinfo+6), hl ; make sure source port is unset -.resolveloop +.resolveloop2: ld c, SOCK_DGRAM ; Open a UDP socket call F_socket ret c ; bale out on error @@ -107,31 +114,31 @@ F_dnsAquery ld a, 3 ; number of retries ld (v_dnsretries), a -.sendquery +.sendquery2: ld a, (v_dnsfd) ld hl, v_dnssockinfo ; reset hl to the sockinfo structure ld de, buf_workspace ; point de at the workspace ld bc, (v_querylength) ; bc = length of query call F_sendto ; send the block of data - jr c, .errorcleanup ; recover if there's an error + jr c, .errorcleanup2 ; recover if there's an error ; Wait for only a finite amount of time before giving up call F_waitfordnsmsg - jr nc, .getresponse + jr nc, .getresponse2 ld a, (v_dnsretries) dec a ld (v_dnsretries), a - jr nz, .sendquery + jr nz, .sendquery2 ld a, DNS_TIMEOUT - jr .errorcleanup ; retries exhausted + jr .errorcleanup2 ; retries exhausted -.getresponse +.getresponse2: ld a, (v_dnsfd) ld hl, v_dnssockinfo ; reset hl to the socket info structure ld de, buf_message ; set de to the message buffer ld bc, 512 ; maximum message size call F_recvfrom - jr c, .errorcleanup + jr c, .errorcleanup2 ld a, (v_dnsfd) call F_sockclose @@ -140,31 +147,31 @@ F_dnsAquery ld de, buf_message ; the sent query and received ld a, (de) ; answer to check that cpi ; they are the same. If they - jr nz, .badmsg ; are different this indicates something + jr nz, .badmsg2 ; are different this indicates something inc e ; is seriously borked. ld a, (de) cpi - jr nz, .badmsg + jr nz, .badmsg2 ld a, (buf_message+dns_bitfield2) and 0x0F ; Did we successfully resolve something? - jr z, .result ; yes, so process the answer. + jr z, .result2 ; yes, so process the answer. ; TODO: query remaining resolvers ld a, HOST_NOT_FOUND scf ret -.errorcleanup +.errorcleanup2: push af ld a, (v_dnsfd) ; free up the socket we've opened call F_sockclose pop af ret -.result +.result2: call F_getdnsarec ; retrieve the A record from the answer - jr c, .noaddr + jr c, .noaddr2 ld de, (v_queryresult) ; retrieve pointer to result buffer ldi ; copy the IP address ldi @@ -173,21 +180,21 @@ F_dnsAquery xor a ; clear return status ret -.badmsg +.badmsg2: ld a, NO_RECOVERY scf ret -.noaddr +.noaddr2: ld a, NO_ADDRESS ; carry is already set ret ;======================================================================== ; F_dnsstring -; Convert a string (such as 'spectrum.alioth.net') into the format +; Convert a string (such as 'spectrum.alioth2.net2') into the format ; used in DNS queries and responses. The string is null terminated. ; ; The format adds an 8 bit byte count in front of every part of the -; complete host/domain, replacing the dots, so 'spectrum.alioth.net' +; complete host/domain, replacing the dots, so 'spectrum.alioth2.net2' ; would become [0x08]spectrum[0x06]alioth[0x03]net - the values in ; square brackets being a single byte (8 bit integer). ; @@ -195,20 +202,21 @@ F_dnsAquery ; DE - destination address of finished string ; On exit : HL - points at next byte after converted data ; DE is preserved. -F_dnsstring +.globl F_dnsstring +F_dnsstring: ld (v_fieldptr), de ; Set current field byte count pointer inc e ; Intial destination address. -.findsep +.findsep3: ld c, 0xFF ; byte counter, decremented by LDI -.loop +.loop3: ld a, (hl) ; What are we looking at? cp '.' ; DNS string field separator? - jr z, .dot + jr z, .dot3 and a ; Null terminator? - jr z, .done + jr z, .done3 ldi ; copy (hl) to (de), incrementing both - jr .loop -.dot + jr .loop3 +.dot3: push de ; save current destination address ld a, c ; low order of byte counter (255 - bytes) cpl ; turn it into the byte count @@ -218,8 +226,8 @@ F_dnsstring ld (v_fieldptr), de ; save it inc e ; and update pointer to new address inc hl ; address pointer at next character - jr .findsep ; and get next bit -.done + jr .findsep3 ; and get next bit +.done3: push de ; save current destination address xor a ; put a NULL on the end of the result ld (de), a @@ -238,47 +246,48 @@ F_dnsstring ; ; Returns: HL = pointer to IP address ; Carry flag is set if no A records were in the answer. -F_getdnsarec +.globl F_getdnsarec +F_getdnsarec: xor a ld (v_ansprocessed), a ; set answers processed = 0 ld hl, buf_message + dns_headerlen -.questionloop +.questionloop4: ld a, (hl) ; advance to the end of the question record and a ; null terminator? inc hl - jr nz, .questionloop ; not null, check the next character + jr nz, .questionloop4 ; not null, check the next character inc hl ; go past QTYPE inc hl inc hl ; go past QCLASS inc hl -.decodeanswer +.decodeanswer4: ld a, (hl) ; Test for a pointer or a label and 0xC0 ; First two bits are 1 for a pointer - jr z, .skiplabel ; otherwise it's a label so skip it + jr z, .skiplabel4 ; otherwise it's a label so skip it inc hl inc hl -.recordtype +.recordtype4: inc hl ; skip MSB ld a, (hl) ; what kind of record? cp dns_Arecord ; is it an A record? - jr nz, .skiprecord ; if not, advance HL to next answer -.getipaddr + jr nz, .skiprecord4 ; if not, advance HL to next answer +.getipaddr4: ld bc, 9 ; The IP address is the 9th byte add hl, bc ; further on in an A record response ret ; so return this. -.skiplabel +.skiplabel4: ld a, (hl) and a ; is it null? - jr z, .recordtype ; yes - process the record type + jr z, .recordtype4 ; yes - process the record type inc hl - jr .skiplabel -.skiprecord + jr .skiplabel4 +.skiprecord4: ld a, (buf_message+dns_ancount+1) ld b, a ; number of RR answers in B ld a, (v_ansprocessed) ; how many have we processed already? inc a ; pre-increment processed counter cp b ; compare answers processed with total - jr z, .baleout ; no A records found + jr z, .baleout4 ; no A records found ld (v_ansprocessed), a ld bc, 7 ; skip forward add hl, bc ; 7 bytes - now pointing at data length @@ -287,17 +296,18 @@ F_getdnsarec ld c, (hl) ; LSB inc hl add hl, bc ; advance hl to the end of the data - jr .decodeanswer ; decode the next answer -.baleout + jr .decodeanswer4 ; decode the next answer +.baleout4: scf ; set carry flag to indicate error ret ;------------------------------------------------------------------------ ; F_waitfordnsmsg ; Polls for a response from the DNS server to implement a timeout. -F_waitfordnsmsg +.globl F_waitfordnsmsg +F_waitfordnsmsg: ld bc, dns_polltime -.loop +.loop5: ld a, (v_dnsfd) push bc call F_pollfd @@ -306,7 +316,14 @@ F_waitfordnsmsg dec bc ld a, b or c - jr nz, .loop + jr nz, .loop5 scf ; indicate timeout ret +.data +query: defb 0x01,0x00 ; 16 bit flags field - std. recursive query +qdcount: defb 0x00,0x01 ; we only ever ask one question at a time +ancount: defw 0x0000 ; No answers in a query +nscount: defw 0x0000 ; No NS RRs in a query +arcount: defw 0x0000 ; No additional records +queryend: diff --git a/rom/dnsdefs.asm b/rom/dnsdefs.inc similarity index 87% rename from rom/dnsdefs.asm rename to rom/dnsdefs.inc index dedca84..5cb4ae4 100644 --- a/rom/dnsdefs.asm +++ b/rom/dnsdefs.inc @@ -26,13 +26,6 @@ ; so the fields are defined here so they get flashed into the ROM. ; See RFC 1035 for full descriptions of the fields. -query defb 0x01,0x00 ; 16 bit flags field - std. recursive query -qdcount defb 0x00,0x01 ; we only ever ask one question at a time -ancount defw 0x0000 ; No answers in a query -nscount defw 0x0000 ; No NS RRs in a query -arcount defw 0x0000 ; No additional records -queryend - ; Definitions dns_headerlen equ 12 ; 12 bytes long dns_Arecord equ 1 ; A record indicator in query/answer diff --git a/rom/extractsym.pl b/rom/extractsym.pl deleted file mode 100755 index baf50f7..0000000 --- a/rom/extractsym.pl +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl -use strict; -my $file=shift; -if(!$file) -{ - die("Usage: extractsym.pl ..."); -} - -open FHND, "< $file" or die("Could not open $file: $!"); -my %symbols; -while(my $line=) -{ - chomp $line; - my ($symbol, $value)=split(/:/, $line, 2); - $symbols{$symbol}=$value; -} -close FHND; - -while (my $sym=shift) -{ - if($symbols{$sym}) - { - print "$sym:$symbols{$sym}\n"; - } -} - diff --git a/rom/inetinit.asm b/rom/inetinit.asm index 00c2fda..73144a7 100644 --- a/rom/inetinit.asm +++ b/rom/inetinit.asm @@ -23,14 +23,19 @@ ; Called on reset/power up, these routines examine the configuration ; stored in the last page of flash, and initializes the IP settings ; accordingly. - +.include "spectranet.inc" +.include "flashconf.inc" +.include "ctrlchars.inc" +.include "sysvars.inc" ;--------------------------------------------------------------------------- ; F_inetinit ; Initializes IPv4 settings. ; Called by the reset routine in the main rom on reset/power up. ; Configuration must be copied to RAM since we are using both paging areas ; (one for the W5100 register area, and one for this code). -F_inetinit +.text +.globl F_inetinit +F_inetinit: ld a, 0x1F ; flash page containing configuration call SETPAGEA ld hl, 0x1F00 ; last 256 bytes of config @@ -57,7 +62,8 @@ F_inetinit ;------------------------------------------------------------------------ ; F_showstatic ; Show configuration if statically configured. -F_showstatic +.globl F_showstatic +F_showstatic: ld hl, STR_staticip call PRINT42 ld hl, 0x2100+IP_ADDRESS @@ -72,16 +78,17 @@ F_showstatic call F_showaddr ret -F_showaddr +.globl F_showaddr +F_showaddr: ld de, buf_workspace call LONG2IPSTRING ld hl, buf_workspace call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ret - -STR_staticip defb "I:",0 -STR_staticmask defb "M:",0 -STR_staticgw defb "G:",0 +.data +STR_staticip: defb "I:",0 +STR_staticmask: defb "M:",0 +STR_staticgw: defb "G:",0 diff --git a/rom/jumptable.asm b/rom/jumptable.asm index 0b4e63a..0bfbd99 100644 --- a/rom/jumptable.asm +++ b/rom/jumptable.asm @@ -20,9 +20,6 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - include "rom.sym" - org 0x1F00 - ; The jump table ; -------------- ; @@ -51,6 +48,12 @@ ; ; This jump table is copied to 0x3E00 on reset (the fixed upper 4k page, ; which is RAM). + +; until copied to RAM this is just data. +.include "page0.xinc" +.data +.globl X_JUMPTABLE +X_JUMPTABLE: jp F_socket jp F_sockclose jp F_listen @@ -136,9 +139,13 @@ jp F_setmountpoint ; Set the current mount point in use jp F_freemountpoint ; Free a mount point jp F_resalloc ; Allocate/free directory and file handles - +.globl X_JUMPTABLE_SIZE +X_JUMPTABLE_SIZE: equ $-X_JUMPTABLE + defb 0xff,0xff,0xff,0xff ; 8 padding bytes + defb 0xff,0xff,0xff,0xff - block 0x1FF8-$,0xFF +.globl X_UPPER_ENTRYPT +X_UPPER_ENTRYPT: ; The upper entry point. ; CALL instructions to 0x3FF8 and higher cause a ROM page-in. A small ; amount of code can live here to dispatch these calls elsewhere. @@ -146,4 +153,6 @@ ret ; A way of paging in without using an OUT jp J_hldispatch ; HLCALL - 0x3FFA jp J_ixdispatch ; IXCALL - 0x3FFD +.globl X_UPPER_ENTRYPT_SIZE +X_UPPER_ENTRYPT_SIZE: equ $-X_UPPER_ENTRYPT diff --git a/rom/modman.ld b/rom/modman.ld new file mode 100644 index 0000000..cc4f75d --- /dev/null +++ b/rom/modman.ld @@ -0,0 +1,32 @@ +/* Spectranet modules LD script */ +OUTPUT_FORMAT("binary") +OUTPUT_ARCH("z80") +MEMORY { + pageb : ORIGIN = 0x3000, LENGTH = 0x1000 +} +SECTIONS +{ +.main : { + *(.main) + *(main) + __Hmain = .; + } > pageb +.text : { + *(.text) + *(text) + __Htext = .; + } > pageb +.data : { + __Ldata = .; + *(.data) + *(data) + __Hdata = .; + } > pageb +.bss : { + __Lbss = .; + *(.bss) + *(bss) + __Hbss = .; + } > pageb +} + diff --git a/rom/page0.ld b/rom/page0.ld new file mode 100644 index 0000000..3fdcf17 --- /dev/null +++ b/rom/page0.ld @@ -0,0 +1,75 @@ +/* Spectranet modules LD script */ +OUTPUT_FORMAT("binary") +OUTPUT_ARCH("z80") +MEMORY { + pagez : ORIGIN = 0x007D, LENGTH = 0x0F83 + rst0 : ORIGIN = 0x0000, LENGTH = 0x0008 + rst8 : ORIGIN = 0x0008, LENGTH = 0x0008 + rst10 : ORIGIN = 0x0010, LENGTH = 0x0018 + rst28 : ORIGIN = 0x0028, LENGTH = 0x0008 + rst30 : ORIGIN = 0x0030, LENGTH = 0x0008 + isr : ORIGIN = 0x0038, LENGTH = 0x002E + nmi : ORIGIN = 0x0066, LENGTH = 0x0014 + unpage : ORIGIN = 0x007B, LENGTH = 0x0002 +} +SECTIONS +{ +.rst0 : { + *(.rst0) + *(rst0) + __Hrst0 = .; + } > rst0 +.rst8 : { + *(.rst8) + *(rst8) + __Hrst8 = .; + } > rst8 +.rst10 : { + *(.rst10) + *(rst10) + __Hrst10 = .; + } > rst10 +.rst28 : { + *(.rst28) + *(rst28) + __Hrst28 = .; + } > rst28 +.rst30 : { + *(.rst30) + *(rst30) + __Hrst30 = .; + } > rst30 +.isr : { + *(.isr) + *(isr) + __Hisr = .; + } > isr +.nmi : { + *(.nmi) + *(nmi) + __Hnmi = .; + } > nmi +.unpage : { + *(.unpage) + *(unpage) + __Hunpage = .; + } > unpage +.text : { + *(.text) + *(text) + __Htext = .; + } > pagez +.data : { + __Ldata = .; + *(.data) + *(data) + __Hdata = .; + } > pagez +.bss : { + __Lbss = .; + *(.bss) + *(bss) + __Hbss = .; + } > pagez +} + diff --git a/rom/page1.ld b/rom/page1.ld new file mode 100644 index 0000000..96565fc --- /dev/null +++ b/rom/page1.ld @@ -0,0 +1,33 @@ +/* Spectranet modules LD script */ +OUTPUT_FORMAT("binary") +OUTPUT_ARCH("z80") +MEMORY { + pagea : ORIGIN = 0x1000, LENGTH = 0x1000 + lut : ORIGIN = 0x1F80, LENGTH = 0x0080 +} +SECTIONS +{ +.text : { + *(.text) + *(text) + __Htext = .; + } > pagea +.data : { + __Ldata = .; + *(.data) + *(data) + __Hdata = .; + } > pagea +.bss : { + __Lbss = .; + *(.bss) + *(bss) + __Hbss = .; + } > pagea +.lookup : { + *(.lookup) + *(lookup) + __Hlookup = .; + } > lut +} + diff --git a/rom/pagealloc.asm b/rom/pagealloc.asm index c3ac2e5..fae619d 100644 --- a/rom/pagealloc.asm +++ b/rom/pagealloc.asm @@ -31,6 +31,8 @@ ; The rest of RAM should only be used after being reserved to ensure that ; you don't trample on the workspace of a ROM module. Reservation routines ; are here and work on the level of 1 page (4K). +.include "sysvars.inc" +.include "sysdefs.inc" ;--------------------------------------------------------------------------- ; F_reservepage @@ -38,30 +40,33 @@ ; Pass 0xFF if it's just a general program, and not a module. ; On return, A contains the page reserved. If no pages are free the carry ; flag is set. -F_reservepage +.text +.globl F_reservepage +F_reservepage: ld b, 25 ; number of RAM pages that can be reserved ld hl, pagealloc ; search the page allocation table for a page ex af, af' ; save A -.searchloop +.searchloop1: ld a, (hl) ; examine current page and a ; is it zero (unallocated) ? - jr z, .pagefound + jr z, .pagefound1 inc l ; advance to the next - djnz .searchloop + djnz .searchloop1 scf ; if we get here no free pages were found. ret -.pagefound +.pagefound1: ex af, af' ; get originally passed value ld (hl), a ; mark the page allocated ld a, l ; calculate the page sub pagealloc % 256 ; by looking at the table position - add LOWEST_PAGE ; and adding the lowest possible page + add a, LOWEST_PAGE ; and adding the lowest possible page ret ;-------------------------------------------------------------------------- ; F_freepage ; Frees a page. Pass the page number in A. -F_freepage +.globl F_freepage +F_freepage: ld hl, pagealloc sub LOWEST_PAGE ; find offset in table add a, l ; add table base address diff --git a/rom/progtrap.asm b/rom/progtrap.asm index 5b34f47..dbc44e8 100644 --- a/rom/progtrap.asm +++ b/rom/progtrap.asm @@ -19,6 +19,9 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "sysdefs.inc" +.include "sysvars.inc" +.include "spectranet.inc" ; This code is used to set up the programmable trap. ; The programmable trap may be anywhere in memory. When the CPU fetches @@ -34,13 +37,15 @@ ; byte 1,2 - Address to call when trap fires ; byte 3,4 - Address that trap comes from ; byte 5,6 - Address of the actual trap -F_settrap +.text +.globl F_settrap +F_settrap: ld de, v_trappage ; Copy trap details to sysvars ld a, (hl) ; check for 0xFF as the page cp 0xFF ; since this indicates 'current page B rom' - jr z, .usecurrent + jr z, .usecurrent1 ldi ; copy page -.cprest +.cprest1: ldi ; copy lsb of call address ldi ; copy msb of call address ldi ; call lsb of comefrom address @@ -60,17 +65,18 @@ F_settrap out (c), a ; write new register value ret -.usecurrent +.usecurrent1: ld a, (v_pgb) ld (de), a inc de inc hl - jr .cprest + jr .cprest1 ;-------------------------------------------------------------------------- ; F_disabletrap ; Disables the programmable trap. -F_disabletrap +.globl F_disabletrap +F_disabletrap: ld bc, CTRLREG in a, (c) ; get current control register value res BIT_PROGTRAP_EN, a ; reset the trap enable bit @@ -80,7 +86,8 @@ F_disabletrap ;-------------------------------------------------------------------------- ; F_enabletrap ; Enables the programmable trap -F_enabletrap +.globl F_enabletrap +F_enabletrap: ld bc, CTRLREG in a, (c) ; get current control register value or MASK_PROGTRAP_EN ; set the trap enable bit @@ -91,12 +98,14 @@ F_enabletrap ; J_pagetrapreturn ; Returns from a trap, restoring page area B, the stack, and unpaging ; the Spectranet -J_pagetrapreturn +.globl J_pagetrapreturn +J_pagetrapreturn: call F_poppageB ;-------------------------------------------------------------------------- ; J_trapreturn ; Returns from a trap, restoring the stack and unpaging the Spectranet -J_trapreturn +.globl J_trapreturn +J_trapreturn: pop af ex af, af' pop af @@ -105,7 +114,7 @@ J_trapreturn pop hl ld sp, (NMISTACK) ; restore SP push hl ; swap HL with the stack to put - ld hl, UNPAGE ; the page out address there for RETN + ld hl, PAGEOUT ; the page out address there for RETN ex (sp), hl ; restore hl, put page out on stack retn diff --git a/rom/reset.asm b/rom/reset.asm index 1bdae79..05b4b36 100644 --- a/rom/reset.asm +++ b/rom/reset.asm @@ -19,13 +19,20 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "sysvars.inc" +.include "sysdefs.inc" +.include "spectranet.inc" +.include "w5100_defs.inc" +.include "flashconf.inc" +.include "ctrlchars.inc" +.include "page3.xinc" ; Locations in the data rom that need to be copied. ; The jump table lives in the first 256 bytes of ROM3 -JUMPTABLE_COPYFROM equ 0x1F00 -JUMPTABLE_SIZE equ 0xF8 -UPPER_ENTRYPT equ 0x1FF8 -UPPER_ENTRYPT_SIZE equ 0x08 +JUMPTABLE_COPYFROM: equ 0x1F00 +JUMPTABLE_SIZE: equ 0xF8 +UPPER_ENTRYPT: equ 0x1FF8 +UPPER_ENTRYPT_SIZE: equ 0x08 ; Initialization routines that are run on reset. ; @@ -34,16 +41,18 @@ UPPER_ENTRYPT_SIZE equ 0x08 ; (page 0x20, chip 0). From this we can figure out what we're supposed ; to do next. ; -J_reset +.text +.globl J_reset +J_reset: ; a delay loop to allow the rubber key machine's very slow reset ; circuit to become quiescent. ld bc, 0xFFFF -.delay +.delay0: ld (ix+7), a ; a nice long instruction dec bc ld a, b or c - jr nz, .delay + jr nz, .delay0 ; Clear upper page. ld sp, NMISTACK ; use our own memory for the stack @@ -135,7 +144,7 @@ J_reset ld sp, 32767 ; lowest guaranteed stack addr ld hl, 0 ; We're done so put 0x0000 push hl ; on the stack - jp UNPAGE ; unpage (a ret instruction) + jp PAGEOUT ; unpage (a ret instruction) ;------------------------------------------------------------------------ ; F_initroms @@ -145,25 +154,26 @@ J_reset ; Note this is how the W5100 actually gets configured - for the ; Spectranet to work at all, the Spectranet utility ROM must occupy some ; page somewhere in the flash chip and get initialized. -F_initroms +.globl F_initroms +F_initroms: ld b, 1 ; start from page 2 (page 0=fixed, page 1=data) ld hl, vectors ; pointer to the valid vector table -.initloop +.initloop1: inc b ld a, 0x1F cp b ; last ROM? ret z ; finished ld a, b call F_checkromsig ; Z = valid signature found for executable - jr z, .rominit ; Valid sig found + jr z, .rominit1 ; Valid sig found cp 0xFF ; empty slot - jr z, .skip + jr z, .skip1 ld (hl), 0xFF ; "occupied but not executable" -.skip +.skip1: inc hl - jr .initloop + jr .initloop1 -.rominit +.rominit1: ; Put an entry in the vector table to indicate the ROM page has ; a valid vector table. ld a, (0x2001) ; fetch the ROM ID @@ -174,20 +184,21 @@ F_initroms ld hl, (ROM_INIT_VECTOR) ; get initialization vector from ROM ld a, 0xFF cp h ; does the vector point somewhere useful? - jr z, .returnaddr ; no - skip calling it - ld de, .returnaddr ; get return address + jr z, .returnaddr1 ; no - skip calling it + ld de, .returnaddr1 ; get return address push de ; stack it to simulate CALL jp (hl) ; and call it -.returnaddr +.returnaddr1: pop bc pop hl - jr .initloop + jr .initloop1 ;------------------------------------------------------------------------- ; F_initfs ; Initializes filesystems. ; TODO: Initialize multiple filesystems. -F_initfs +.globl F_initfs +F_initfs: ld a, CONFIGPAGE ; config page call F_setpageA ld a, (0x1000+DEF_FS_PROTO0) @@ -204,9 +215,9 @@ F_initfs ld ix, FSTAB ld a, 0 call F_mount - jr c, .error + jr c, .error2 ret -.error +.error2: ld hl, 0x3000 call F_itoh8 ld hl, 0x3000 @@ -216,7 +227,8 @@ F_initfs ;------------------------------------------------------------------------- ; F_w5100init ; Initialize the W5100 - MAC address and hardware registers. -F_w5100init +.globl F_w5100init +F_w5100init: ; Set up memory pages to configure the hardware ld a, REGPAGE ; registers are in page 0 of the W5100 call F_setpageA ; page it into area A @@ -239,17 +251,16 @@ F_w5100init ld a, %11101111 ; set the IMR ld (IMR), a ret - -STR_bootmsg +.data +STR_bootmsg: defb "Alioth Spectranet ",0 - include "ver.asm" ; include the build number file -STR_mounting - defb "FS mount\n",0 -FSTAB + include "ver.xinc" ; include the build number file +STR_mounting: + defb "FS mount",NEWLINE,0 +FSTAB: defw 0x3001 ; TODO - proper filesystem things defw 0x3007 defw 0x3030 defw 0x3060 defw 0x3070 -MOUNT equ 0x3EA8 diff --git a/rom/rom.asm b/rom/rom.asm deleted file mode 100644 index 9c801de..0000000 --- a/rom/rom.asm +++ /dev/null @@ -1,75 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; The Spectranet ROM. -;-------------------- -; The following files must be included in order, the others don't matter -; which order: -; zeropage.asm - sets ORG to 0x0000 and provides restart entry points. -; jumptable.asm - sets ORG to 0x3E00 -; sysvars.asm - sets ORG to 0x3F00 -; -; Until w5100_defines is changed to be equ instead of defines, this should -; be included before any of the network library code. -UTILROM equ 0x02 -CTRLREG equ 0x033B - - ; Routines for ROM page 0 (chip 0 page 0, lower fixed page) - include "zeropage.asm" ; Restarts - include "w5100_defines.asm" ; Definitions for network hardware - include "reset.asm" ; Initialization routines - include "trapdispatch.asm" ; Trap dispatcher - include "pager.asm" ; Memory paging routines - include "sockdefs.asm" ; Definitions for socket library - include "flashconf.asm" ; Configuration information - include "w5100_ifconfig.asm" ; Interface configuration routines - include "w5100_genintfunc.asm" ; general internal functions - include "w5100_buffer.asm" ; Transmit and receive buffers - include "w5100_sockalloc.asm" ; socket, accept, close - include "w5100_sockctrl.asm" ; bind, connect - include "w5100_rxtx.asm" ; send, recv, sendto, recvfrom, poll - include "w5100_sockinfo.asm" ; internal socket info marshalling - include "dns.asm" ; gethostbyname - include "dnsdefs.asm" ; defines for DNS -; include "zxpaging.asm" ; Control 128k ROM paging - include "utility.asm" ; Utility functions - include "ui_input.asm" ; User interface: input routines - include "ui_output_stub.asm" ; User interface: screen output - include "progtrap.asm" ; Programmable trap set routines - include "basicextn.asm" ; BASIC extension infrastructure - include "pagealloc.asm" ; page allocation - include "vfs.asm" ; VFS dispatcher - - block 0xFFF-$,0xFF - - ; Memory map for upper fixed page (chip 3 page 0) - ; note sysvars now gets pulled in by datarom.sym -; include "sysvars.sym" ; System variables (from earlier asm) - include "sysdefs.asm" ; General definitions - - ; Various definitions. - include "zxromcalls.asm" ; Defines entry points into the ZX ROM - include "zxsysvars.asm" ; Defines for system vars and IO ports - include "datarom.sym" ; Addresses of bits of data - include "impl.sym" ; Addresses of functions we need - - diff --git a/rom/romconfigmain.asm b/rom/romconfigmain.asm index b4c9571..32c1d96 100644 --- a/rom/romconfigmain.asm +++ b/rom/romconfigmain.asm @@ -21,10 +21,16 @@ ;THE SOFTWARE. ; ROM configuration utility main routine. +.include "spectranet.inc" +.include "ctrlchars.inc" +.include "sysvars.inc" +.include "sockdefs.inc" ;-------------------------------------------------------------------------- ; F_romconfigmain: Main loop -F_romconfigmain +.section main +.globl F_romconfigmain +F_romconfigmain: call CLEAR42 ld hl, STR_installed call PRINT42 @@ -36,44 +42,45 @@ F_romconfigmain ld a, 0x02 ; utility ROM call SETPAGEB ret - +.text ;-------------------------------------------------------------------------- ; F_showroms - Shows the current available ROMs. -F_showroms +.globl F_showroms +F_showroms: ld a, 0x02 ; first valid ROM slot -.disploop +.disploop2: call SETPAGEB push af ld a, (0x2000) ; check signature byte cp 0xFF ; end? - jr z, .exit ; exit routine + jr z, .exit2 ; exit routine cp 0xAA ; ROM module? - jr nz, .putdatarom ; no, list as "data" + jr nz, .putdatarom2 ; no, list as "data" pop af ; get ROM number push af - call .printid ; print its id + call .printid2 ; print its id ld hl, (0x200E) ; get the identity string call PRINT42 ; print the identity - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 pop af inc a - jr .disploop -.exit + jr .disploop2 +.exit2: pop af ret -.putdatarom +.putdatarom2: pop af push af - call .printid + call .printid2 ld hl, STR_datarom call PRINT42 pop af inc a - jr .disploop + jr .disploop2 -.printid +.printid2: ld hl, v_workspace ; workspace to load with value call ITOH8 ld a, '[' @@ -91,31 +98,33 @@ F_showroms ; Finds the first free ROM page, returning it in A. ; Search starts from the first user page, page 0x04. Returns with the ; carry flag set if no free pages are available. -F_findfirstfreepage +.globl F_findfirstfreepage +F_findfirstfreepage: ld a, 0x04 -.loop +.loop3: call SETPAGEB ex af, af' ld a, (0x2000) cp 0xFF ; FF = free page - jr z, .found + jr z, .found3 ex af, af' cp 0x1F ; Last page? - jr z, .nospace + jr z, .nospace3 inc a - jr .loop -.nospace + jr .loop3 +.nospace3: scf ret -.found - ex af, af´ +.found3: + ex af, af' and a ; make sure carry is reset ret ;----------------------------------------------------------------------- ; F_loader ; Loads some data into RAM. -F_loader +.globl F_loader +F_loader: ; Page in some RAM for the data to land. call SETPAGEA @@ -123,16 +132,16 @@ F_loader ld c, SOCK_STREAM ; open a TCP socket call SOCKET ; file descriptor in A - jp c, .borked ; or c set if failed + jp c, .borked4 ; or c set if failed ld (v_sockfd), a ; save the fd ld de, 2000 ; port 2000 call BIND ; bind to the port - jp c, .borked + jp c, .borked4 ld a, (v_sockfd) ; socket we want to listen on call LISTEN ; listen - jr c, .borked + jr c, .borked4 ; Display an informative message to the user showing the ; IP and port we are listening on. @@ -151,7 +160,7 @@ F_loader ; Wait for a connection. ld a, (v_sockfd) call ACCEPT ; block until something connects - jr c, .borked + jr c, .borked4 ld (v_connfd), a ; save the connection file descriptor ; Get the first 4 bytes which contains the start address and @@ -166,16 +175,16 @@ F_loader ; Receive the data. ld de, 0x1000 ; current address to write to ld (buf_workspace), de ; save current pointer -.recvloop +.recvloop4: ld a, (v_connfd) ld bc, 1024 ; receive up to 1K at a time call RECV - jr c, .borked + jr c, .borked4 ld hl, (buf_workspace+2) ; get remaining length sbc hl, bc ld a, h ; are we done yet? or l - jr z, .recvdone + jr z, .recvdone4 ld (buf_workspace+2), hl ; save remaining length ld hl, (buf_workspace) ; get current pointer add hl, bc ; increment it @@ -183,14 +192,14 @@ F_loader ex de, hl ld a, '.' ; progress marker call PUTCHAR42 - jr .recvloop ; get the next block -.recvdone + jr .recvloop4 ; get the next block +.recvdone4: ld a, (v_connfd) ; close the connection call CLOSE ld a, (v_sockfd) call CLOSE ret -.borked +.borked4: ld hl, buf_workspace call ITOH8 ld hl, STR_borked @@ -201,7 +210,8 @@ F_loader ret ; internal function for the above - print info of what's being tx'd to us. -F_printxfinfo +.globl F_printxfinfo +F_printxfinfo: ld hl, STR_est call PRINT42 ld hl, STR_len @@ -213,14 +223,15 @@ F_printxfinfo call ITOH8 ld hl, buf_workspace+4 call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ret ;------------------------------------------------------------------------- ; F_romconfigmenu ; Displays the ROM configuration menu. -F_configmenu +.globl F_configmenu +F_configmenu: ld hl, STR_menutitle call PRINT42 ld hl, MENU_romconfig @@ -232,7 +243,8 @@ F_configmenu ;------------------------------------------------------------------------- ; F_addmodule ; Adds a new module to the last slot in ROM, assuming there's one available -F_addmodule +.globl F_addmodule +F_addmodule: call F_findfirstfreepage ; Find the ROM page for the module jp c, J_noroom ; Report "no room" if C is set call SETPAGEB ; page it into area B @@ -258,7 +270,8 @@ F_addmodule ;------------------------------------------------------------------------- ; F_repmodule ; Replaces a module. -F_repmodule +.globl F_repmodule +F_repmodule: ld hl, STR_entermod call PRINT42 call F_getromnum ; ask for the ROM id @@ -269,7 +282,7 @@ F_repmodule call F_copysectortoram ; copy the flash sector ld a, (v_workspace) ; calculate the RAM page to use and 0x03 ; get position in the sector - add 0xDC ; add RAM page number + add a, 0xDC ; add RAM page number call F_loader ; get the new data over the net ld a, (v_workspace + 1) ; retrieve sector page di @@ -283,7 +296,7 @@ F_repmodule ;------------------------------------------------------------------------ ; Report flash write/erase failures -J_eraseborked +J_eraseborked: ld hl, STR_erasebork call PRINT42 scf @@ -294,20 +307,21 @@ J_eraseborked ; Removes a page from a sector of flash, shuffling all the ROMs down. ; Page to remove should be in (v_workspace), and A should have the sector ; first page. -F_removepage +.globl F_removepage +F_removepage: ld b, 3 ; 3 pages to copy to RAM ex af, af' ld a, 0xDC ; RAM page to start with -.loop +.loop9: push bc call F_setpageB ; page in RAM destination inc a ex af, af' ld hl, v_workspace cp (hl) ; is this the page to delete? - jr nz, .noskip + jr nz, .noskip9 inc a ; if so skip it -.noskip +.noskip9: call F_setpageA ; page in ROM source inc a ex af, af' @@ -316,7 +330,7 @@ F_removepage ld bc, 0x1000 ldir pop bc - djnz .loop + djnz .loop9 call F_setpageB ; page in the final RAM page ld hl, 0x2000 @@ -331,20 +345,20 @@ F_removepage push af ; save it di call F_FlashEraseSector ; erase it - jr c, .fail + jr c, .fail9 pop af call F_writesector ; write the modified sector back ei jr c, J_writeborked ret -.fail +.fail9: ei pop af ; restore stack jr J_eraseborked ;----------------------------------------------------------------------- ; Jump here to display a write failed message. -J_writeborked +J_writeborked: ld hl, STR_writebork call PRINT42 scf @@ -352,7 +366,8 @@ J_writeborked ;----------------------------------------------------------------------- ; F_remmodule: Removes a module. -F_remmodule +.globl F_remmodule +F_remmodule: ld hl, STR_delrom call PRINT42 call F_getromnum ; ask for the ROM id @@ -409,24 +424,26 @@ F_remmodule ;---------------------------------------------------------------------- ; F_exit: Exit the ROM utility. -F_exit +.globl F_exit +F_exit: or 1 ; reset Z flag ret ;------------------------------------------------------------------------- ; J_noroom -J_noroom +J_noroom: ld hl, STR_noroom call PRINT42 ;------------------------------------------------------------------------- ; 'Press x to exit' -F_waitforkey +.globl F_waitforkey +F_waitforkey: ld hl, STR_xtoexit call PRINT42 -.waitforkey +.waitforkey12: call GETKEY cp 'x' - jr nz, .waitforkey + jr nz, .waitforkey12 xor a ; set Z flag ret @@ -434,7 +451,8 @@ F_waitforkey ; F_getromnum ; Ask the user for a ROM slot (hex value), return it in A ; Note. First free page is also returned in A' -F_getromnum +.globl F_getromnum +F_getromnum: ld c, 3 ; buffer is 3 bytes long (2 + null) ld de, v_workspace call INPUTSTRING @@ -444,17 +462,17 @@ F_getromnum ret z call HTOI8 ; convert hex string pointed to by hl cp 4 ; must be greater than 4 - jr c, .invalid + jr c, .invalid13 push af ; save the ROM number selected call F_findfirstfreepage pop bc ; get AF back into BC for comparison cp b ; b should be <= a - jr c, .invalid + jr c, .invalid13 ex af, af' ; keep first free page in A' ld a, b ; move result into A or a ; make sure Z is not set ret -.invalid +.invalid13: ld hl, STR_notvalid call PRINT42 jr F_getromnum @@ -463,11 +481,12 @@ F_getromnum ; F_copysectortoram ; Copies 4 pages of flash to RAM. ; Parameter: A = first page. -F_copysectortoram +.globl F_copysectortoram +F_copysectortoram: ex af, af' ; save ROM page ld a, 0xDC ; first RAM page ld b, 4 ; pages to copy -.copyloop +.copyloop14: push bc call F_setpageB ; RAM into area B inc a @@ -480,10 +499,11 @@ F_copysectortoram ld bc, 0x1000 ldir pop bc - djnz .copyloop + djnz .copyloop14 ret -F_debugpages +.globl F_debugpages +F_debugpages: push af ex af, af' push af @@ -526,15 +546,15 @@ F_debugpages ex af, af' pop af ret - -STR_workspace defb "\nworkspace + 0: ",0 -STR_workspace1 defb "\nworkspace + 1: ",0 -STR_accum defb "\nA register : ",0 -STR_accum1 defb "\nA' register : ",0 +.data +STR_workspace: defb NEWLINE,"workspace + 0: ",0 +STR_workspace1: defb NEWLINE,"workspace + 1: ",0 +STR_accum: defb NEWLINE,"A register : ",0 +STR_accum1: defb NEWLINE,"A' register : ",0 ;------------------------------------------------------------------------- ; Definitions. -MENU_romconfig +MENU_romconfig: defw STR_addmodule,F_addmodule defw STR_repmodule,F_repmodule defw STR_remmodule,F_remmodule diff --git a/rom/romconfigutil_en.asm b/rom/romconfigutil_en.asm deleted file mode 100644 index b65f9e6..0000000 --- a/rom/romconfigutil_en.asm +++ /dev/null @@ -1,6 +0,0 @@ - include "spectranet.asm" - org 0x8000 - include "romconfigmain.asm" - include "romconfstrings_en.asm" - include "flashwrite.asm" - diff --git a/rom/romconfstrings_en.asm b/rom/romconfstrings_en.asm index 11ebae9..ca9a08d 100644 --- a/rom/romconfstrings_en.asm +++ b/rom/romconfstrings_en.asm @@ -21,31 +21,55 @@ ;THE SOFTWARE. ; ; ROM configuration utility - strings +.include "ctrlchars.inc" +.data +.globl STR_installed +.globl STR_datarom +STR_installed: defb "Current configuration",NEWLINE,"=====================",NEWLINE,NEWLINE,0 +STR_datarom: defb "-- data --",NEWLINE,0 -STR_installed defb "Current configuration\n=====================\n\n",0 -STR_datarom defb "-- data --\n",0 +.globl STR_menutitle +.globl STR_addmodule +.globl STR_remmodule +.globl STR_repmodule +.globl STR_exit +STR_menutitle: defb NEWLINE,NEWLINE,"ROM configuration menu",NEWLINE,"======================",NEWLINE,NEWLINE,0 +STR_addmodule: defb "Add a new ROM module",0 +STR_repmodule: defb "Replace an existing module",0 +STR_remmodule: defb "Remove a ROM module",0 +STR_exit: defb "Exit",0 -STR_menutitle defb "\n\nROM configuration menu\n======================\n\n",0 -STR_addmodule defb "Add a new ROM module",0 -STR_repmodule defb "Replace an existing module",0 -STR_remmodule defb "Remove a ROM module",0 -STR_exit defb "Exit",0 +.globl STR_send +.globl STR_port +.globl STR_xtoexit +.globl STR_borked +.globl STR_est +.globl STR_len +.globl STR_noroom +.globl STR_writingmod +STR_send: defb "Listening on ",0 +STR_port: defb " port 2000",NEWLINE,0 +STR_xtoexit: defb NEWLINE,"Press 'x' to exit.",NEWLINE,0 +STR_borked: defb NEWLINE,"Operation failed with rc=",0 +STR_est: defb "Connection established",NEWLINE,0 +STR_len: defb "Length: ",0 +STR_noroom: defb "No space left in flash.",NEWLINE,0 +STR_writingmod: defb NEWLINE,"Writing module to flash page ",0 -STR_send defb "Listening on ",0 -STR_port defb " port 2000\n",0 -STR_xtoexit defb "\nPress 'x' to exit.\n",0 -STR_borked defb "\nOperation failed with rc=",0 -STR_est defb "Connection established\n",0 -STR_len defb "Length: ",0 -STR_noroom defb "No space left in flash.\n",0 -STR_writingmod defb "\nWriting module to flash page ",0 - -STR_entermod defb "Enter hex number of ROM to replace: ",0 -STR_delrom defb "Enter hex number of ROM to delete:",0 -STR_notvalid defb "\nNot a valid ROM number.\nPlese re-enter: ",0 -STR_erasebork defb "Erase failed\n",0 -STR_writebork defb "Write failed\n",0 -STR_defragment defb "Defragmenting...\n",0 -STR_erasing defb "\nErasing...\n",0 -STR_eraseok defb "Erase complete\n",0 +.globl STR_entermod +.globl STR_delrom +.globl STR_notvalid +.globl STR_erasebork +.globl STR_writebork +.globl STR_defragment +.globl STR_erasing +.globl STR_eraseok +STR_entermod: defb "Enter hex number of ROM to replace: ",0 +STR_delrom: defb "Enter hex number of ROM to delete:",0 +STR_notvalid: defb NEWLINE,"Not a valid ROM number.",NEWLINE,"Plese re-enter: ",0 +STR_erasebork: defb "Erase failed",NEWLINE,0 +STR_writebork: defb "Write failed",NEWLINE,0 +STR_defragment: defb "Defragmenting...",NEWLINE,0 +STR_erasing: defb NEWLINE,"Erasing...",NEWLINE,0 +STR_eraseok: defb "Erase complete",NEWLINE,0 diff --git a/rom/romimage.asm b/rom/romimage.asm deleted file mode 100644 index 5164c03..0000000 --- a/rom/romimage.asm +++ /dev/null @@ -1,11 +0,0 @@ - org 0x0000 - incbin "rom.out" - block 0x1000-$,0xFF - incbin "datarom.out" - block 0x2000-$,0xFF - incbin "utilrom.out" - block 0x3000-$,0xFF - incbin "tnfs.out" - block 0x3F00-$,0xFF - incbin "jumptable.out" - diff --git a/rom/romimage_es.asm b/rom/romimage_es.asm deleted file mode 100644 index d8e1caa..0000000 --- a/rom/romimage_es.asm +++ /dev/null @@ -1,11 +0,0 @@ - org 0x0000 - incbin "rom.out" - block 0x1000-$,0xFF - incbin "datarom_es.out" - block 0x2000-$,0xFF - incbin "utilrom_es.out" - block 0x3000-$,0xFF - incbin "tnfs.out" - block 0x3F00-$,0xFF - incbin "jumptable.out" - diff --git a/rom/romprog.asm b/rom/romprog.asm deleted file mode 100644 index 12b69a4..0000000 --- a/rom/romprog.asm +++ /dev/null @@ -1,110 +0,0 @@ - org 0x8000 - di - ld bc, 0x033B - ld a, 1 - out (c), a - - call F_clear - ld hl, STR_erasing - call F_print - call F_FlashEraseSectorZero - jr c, .borked - - ld a, 1 ; chip 0 page 1 - call F_setpageA - ld a, 2 ; chip 0 page 2 - call F_setpageB - - ld hl, STR_writing - call F_print - ld hl, PAYLOAD - ld de, 0 - ld bc, 0x3000 -.writeloop - ld a, (hl) - call F_FlashWriteByte - jr c, .borked - inc hl - inc de - dec bc - ld a, b - or c - jr nz, .writeloop - ld a, 3 - call F_setpageB - ld de, 0x2000 ; start of page B - ld bc, 0x1000 ; 4k of data left to go -.writeloop2 - ld a, (hl) - call F_FlashWriteByte - jr c, .borked - inc hl - inc de - dec bc - ld a, b - or c - jr nz, .writeloop2 - - ld hl, STR_writedone - call F_print -.exit - ld bc, 0x033B - xor a - out (c), a - ei - ret - -.borked - ld hl, STR_borked - call F_print - jr .exit - -F_setpageA - push bc - ld bc, PAGEA - ld (v_pga), a ; save the page we've just paged. - out (c), a ; page it in - pop bc - ret - -; Set paging area B. As for area A. -F_setpageB - push bc - ld bc, PAGEB - ld (v_pgb), a - out (c), a ; page it in - pop bc - ret - - include "../utils/flashwrite.asm" - include "../test/test_output.asm" - include "ui_charset.asm" - -STR_erasing defb "Erasing lower flash sector\n",0 -STR_writing defb "Writing payload...\n",0 -STR_writedone defb "Write done\n",0 -STR_borked defb "Operation failed.\n",0 - block 0x8800-$,0 -col_lookup - defb 0,0,1,2,3,3,4,5,6,6,7,8,9,9,10,11,12,12,13,14,15,15 - defb 16,17,18,18,19,20,21,21,22,23,24,24,25,26,27,27,28,29,30,30,31 - - -v_column defb 0 -v_row defw 0 -v_pr_wkspc defb 0 -v_rowcount defb 0 -v_workspace defb 0,0,0,0,0,0,0 -v_pga defb 0 -v_pgb defb 0 -v_chipsel defb 0 - -; various definitions -PAGEA equ 0x003B -PAGEB equ 0x013B -PAGERPORT equ 0x033B - -PAYLOAD - incbin "romimage.out" -PAYLOAD_END - diff --git a/rom/romprog_es.asm b/rom/romprog_es.asm deleted file mode 100644 index d7afa0d..0000000 --- a/rom/romprog_es.asm +++ /dev/null @@ -1,110 +0,0 @@ - org 0x8000 - di - ld bc, 0x033B - ld a, 1 - out (c), a - - call F_clear - ld hl, STR_erasing - call F_print - call F_FlashEraseSectorZero - jr c, .borked - - ld a, 1 ; chip 0 page 1 - call F_setpageA - ld a, 2 ; chip 0 page 2 - call F_setpageB - - ld hl, STR_writing - call F_print - ld hl, PAYLOAD - ld de, 0 - ld bc, 0x3000 -.writeloop - ld a, (hl) - call F_FlashWriteByte - jr c, .borked - inc hl - inc de - dec bc - ld a, b - or c - jr nz, .writeloop - ld a, 3 - call F_setpageB - ld de, 0x2000 ; start of page B - ld bc, 0x1000 ; 4k of data left to go -.writeloop2 - ld a, (hl) - call F_FlashWriteByte - jr c, .borked - inc hl - inc de - dec bc - ld a, b - or c - jr nz, .writeloop2 - - ld hl, STR_writedone - call F_print -.exit - ld bc, 0x033B - xor a - out (c), a - ei - ret - -.borked - ld hl, STR_borked - call F_print - jr .exit - -F_setpageA - push bc - ld bc, PAGEA - ld (v_pga), a ; save the page we've just paged. - out (c), a ; page it in - pop bc - ret - -; Set paging area B. As for area A. -F_setpageB - push bc - ld bc, PAGEB - ld (v_pgb), a - out (c), a ; page it in - pop bc - ret - - include "../utils/flashwrite.asm" - include "../test/test_output.asm" - include "ui_charset.asm" - -STR_erasing defb "Erasing lower flash sector\n",0 -STR_writing defb "Writing payload...\n",0 -STR_writedone defb "Write done\n",0 -STR_borked defb "Operation failed.\n",0 - block 0x8800-$,0 -col_lookup - defb 0,0,1,2,3,3,4,5,6,6,7,8,9,9,10,11,12,12,13,14,15,15 - defb 16,17,18,18,19,20,21,21,22,23,24,24,25,26,27,27,28,29,30,30,31 - - -v_column defb 0 -v_row defw 0 -v_pr_wkspc defb 0 -v_rowcount defb 0 -v_workspace defb 0,0,0,0,0,0,0 -v_pga defb 0 -v_pgb defb 0 -v_chipsel defb 0 - -; various definitions -PAGEA equ 0x003B -PAGEB equ 0x013B -PAGERPORT equ 0x033B - -PAYLOAD - incbin "romimage_es.out" -PAYLOAD_END - diff --git a/rom/save7ffd.asm b/rom/save7ffd.asm index 519b78d..b087381 100644 --- a/rom/save7ffd.asm +++ b/rom/save7ffd.asm @@ -19,19 +19,23 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "sysvars.inc" +.include "spectranet.inc" ; Determines what value port 0x7FFD should have on a 128K machine. -MAINSPSAVE equ 0x3000 -TEMPSP equ 0x81FE -SAVERAM equ 0x3002 - +MAINSPSAVE: equ 0x3000 +TEMPSP: equ 0x81FE +SAVERAM: equ 0x3002 +.text ;----------------------------------------------------------------------- ; F_detectpages -; Detects which 128K pages are in use. The .SNA format just supports the +; Detects which 128K pages are in use. The .SNA0 format just supports the ; ROMs from 0x7FFD and not the ports used by the +3/+2A exclusively. This ; is unlikely to be a problem for the vast majority of programs. ; Returns with carry set if pages could not be detected. -F_detectpages +.text +.globl F_detectpages +F_detectpages: ; Posit that this is a 128K machine - the 128K flag will be ; reset when we find out that it's not. ld a, 1 @@ -77,44 +81,47 @@ F_detectpages ; THIS ROUTINE MUST BE COPIED TO RAM FIRST! ; Returns the value of port 7FFD bit 4 in the E register ; Returns the value of port 1FFD bit 2 in the D register -F_romdetect +.globl F_romdetect +F_romdetect: ; call PAGEOUT ; page out the Spectranet ROM ld a, (0x0008) ; examine 0x0008 in the ROM cp 0xFB ; ROM 0 for all models - jr z, .editor + jr z, .editor2 cp 0xC3 ; ROM 1 - Plus 3 - jr z, .plusthreesyn + jr z, .plusthreesyn2 cp 0x50 ; ROM 2 - Plus 3 DOS - jr z, .plusthreedos + jr z, .plusthreedos2 cp 0x2A ; BASIC (all models) - jr nz, .unknown -.basic + jr nz, .unknown2 +.basic2: ld de, 0x0210 ; Bit 2 of 1FFD, bit 4 of 7FFD - jr .exit -.editor + jr .exit2 +.editor2: ld de, 0x0000 ; Neither 1FFD nor 7FFD set - jr .exit -.plusthreedos + jr .exit2 +.plusthreedos2: ld de, 0x0200 ; only 0x1FFD set - jr .exit -.plusthreesyn + jr .exit2 +.plusthreesyn2: ld de, 0x0010 ; only 0x7FFD set -.exit +.exit2: ld bc, CTRLREG ld a, 1 ; page in Spectranet ROM out (c), a ret -.unknown +.unknown2: xor a ld (v_machinetype), a ; reset 128K flag scf - jr .exit + jr .exit2 -F_romdetect_sz equ $-F_romdetect +.globl F_romdetect_sz +F_romdetect_sz: equ $-F_romdetect ;------------------------------------------------------------------------- ; F_detectram: See what RAM page is paged in. -F_detectram +.globl F_detectram +F_detectram: ; Next detect the RAM page. For this we need to copy a small ; chunk from 0xC000 in our memory, and then put a string into ; that RAM page. Then start flipping through RAM pages with @@ -129,46 +136,46 @@ F_detectram ldir xor a ; start at page 0 -.detectloop +.detectloop4: ld bc, 0x7FFD ; port 0x7FFD out (c), a ; switch page -.snapcmp +.snapcmp4: push af - call .compare - jr nz, .next -.continue + call .compare4 + jr nz, .next4 +.continue4: pop de ld a, (v_port7ffd) ; get current flags or d ; merge in the RAM page flags ld (v_port7ffd), a ; Save the page. - jr .restoreram -.next + jr .restoreram4 +.next4: pop af inc a ; go to the next page cp 0x08 ; Gone through every page? - jr nz, .detectloop + jr nz, .detectloop4 scf ; Oops - couldn't find the string! ret -.restoreram +.restoreram4: ; Check whether paging really was happening... ld a, d ; page is in D and a ; if it's not page zero - jr nz, .restoreram2 ; then paging really happened + jr nz, .restoreram24 ; then paging really happened inc a ; if not increment the page and and 0x07 ; see if our string's still there ld bc, 0x7FFD out (c), a - call .compare + call .compare4 ld a, (v_port7ffd) ld bc, 0x7FFD ; restore RAM page if it out (c), a ; actually changed - jr nz, .restoreram2 ; and restore original RAM + jr nz, .restoreram24 ; and restore original RAM xor a ld (v_machinetype), a ; reset 128K flag scf ; return with carry set -.restoreram2 +.restoreram24: ld hl, SAVERAM ; Restore the original contents ld de, 0xC000 ; of RAM. ld bc, SNSTRINGLEN @@ -177,19 +184,19 @@ F_detectram ; This routine looks for our string in RAM. Returns with Z ; set if the string was found. -.compare +.compare4: ld hl, 0xC000 ld de, SNSTRING ld bc, SNSTRINGLEN -.cploop +.cploop4: ld a, (de) cpi ret nz ; Not matched. inc de - jp pe, .cploop + jp pe, .cploop4 ret - -SNSTRING defb "Spectranet detect 7ffd" -SNSTRINGLEN equ $-SNSTRING +.data +SNSTRING: defb "Spectranet detect 7ffd" +SNSTRINGLEN: equ $-SNSTRING diff --git a/rom/startmsg.asm b/rom/startmsg.asm index ad003a5..9e17670 100644 --- a/rom/startmsg.asm +++ b/rom/startmsg.asm @@ -19,15 +19,18 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "ctrlchars.inc" -; Basstart.asm runs module functions that should be run once BASIC has +; Basstart.asm0 runs module functions that should be run once BASIC has ; shown the copyright message. The basstart function gets called from ; a trap. ; Displays the startup message when BASIC has initialized. ; This includes the IP address. - -F_startmsg +.text +.globl F_startmsg +F_startmsg: ld hl, STR_rel call PRINT42 ld hl, bldstr @@ -45,12 +48,13 @@ F_startmsg call LONG2IPSTRING ; convert to a string ld hl, 0x3004 ; string pointer call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ret -STR_rel defb "Alioth Spectranet\nBuild: ",0 -STR_ip defb " IP: ",0 -STR_date defb " Date: ",0 - include "date.asm" - include "ver.asm" +.data +STR_rel: defb "Alioth Spectranet",NEWLINE,"Build: ",0 +STR_ip: defb " IP: ",0 +STR_date: defb " Date: ",0 +.include "date.xinc" +.include "ver.xinc" diff --git a/rom/sysvars.asm b/rom/sysvars.asm deleted file mode 100644 index 4541bb1..0000000 --- a/rom/sysvars.asm +++ /dev/null @@ -1,228 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; Buffer for filesystems, 512 bytes -fs_scratchpad equ 0x3500 - -NMISTACK equ 0x38FE - -; General purpose small workspace for ROM modules. Each ROM page gets 8 bytes -; of workspace here. Work out the ROM's workspace location by taking the -; page number and multiplying by 8 (page number left shifted 3 times). - org 0x3900 -buf_moduleworkspace - -; A table of BASIC extensions starts here. -; Entries should be structured as: -; byte 0 - ZX error code that's relevant -; byte 1,2 - pointer to command string -; byte 3 - ROM page (0 if none) -; byte 4,5 - pointer to routine to call -; The entire table should be null terminated. - org 0x3A00 -TABLE_basext - -; A 512 byte block is reserved for network messages that are used in the -; normal course of communicating with the world, for example, UDP packets -; sent to a DNS server or received from a DNS server. - org 0x3B00 -buf_message - -; A general purpose block at 0x3D00 is reserved for network functions. -; It is used as a 256-byte buffer for functions such as DNS query strings. - org 0x3D00 -buf_workspace - -; The system variables live in chip 4 page 0 which is permanently mapped -; to 0x3000-0x3FFF. Specifically, they live in the upper part of this memory, -; the lower part being available as general purpose workspace. - - org 0x3F00 -v_column defb 0 ; Current column for 42 col print. -v_row defw 0 ; Current row address for print routine -v_rowcount defb 0 ; current row number -v_pr_wkspc defb 0 ; Print routine workspace -v_pr_pga defb 0 ; page A value storage for print routine -v_pga defb 0 ; Current memory page in area A -v_pgb defb 0 ; Current memory page in area B -v_utf8 defb 0 ; utf-8 character state -v_trappage defb 0 ; Page to select on programmable trap -v_trapaddr defw 0 ; Address to call on programmable trap -v_trapcomefrom defw 0 ; Address on stack when trap is triggered -v_sockptr defw 0 ; Socket register address -v_copylen defw 0 ; Socket copied bytes -v_copied defw 0 ; Socket bytes copied so far - -; Socket mappings. These map a file descriptor (see the BSD socket library) -; to a hardware socket. The reason that hardware sockets are not used -; directly is that it'll make it mean a lot of dependent code would need -; a total rewrite if the hardware got changed. W5100 sockets work differently -; to the standard BSD library, and in any case, we don't want to limit -; ourselves to that particular IP implementation in any case. -; -; These are also used for VFS file descriptors, the idea being a write() or -; read() (etc) with a file descriptor should automatically Do The Right Thing. -; -FDBASE -v_fd1hwsock defb 0 ; hardware socket number -v_fd2hwsock defb 0 -v_fd3hwsock defb 0 -v_fd4hwsock defb 0 -v_fd5hwsock defb 0 -v_fd6hwsock defb 0 ; reserved in case of a W5300 board -v_fd7hwsock defb 0 -v_fd8hwsock defb 0 -v_fd9hwsock defb 0 -MAX_FDS equ 5 ; maximum number of file descriptors (W5100) -MAX_FD_NUMBER equ v_fd5hwsock % 256 -v_lastpolled defb 0 ; fd to start polling from -v_virtualmr defb 0 ; virtualized socket mode register value -v_virtualport defw 0 ; port for virtualized socket - -; General purpose small workspace reserved for ROM routines (for short strings, -; numbers etc.) -v_workspace defb 0,0,0,0,0,0,0,0 -v_bufptr defw 0 ; buffer pointer -v_stringptr defw 0 ; temp storage for a string pointer -v_stringlen defw 0 ; temp storage for string lengths -v_buf_pga defb 0 ; original page A value on call to gethwsock -v_buf_pgb defb 0 ; original page B storage for buffer copies - -; DNS system variables -v_seed defw 0 ; 16 bit random number seed -v_dnsserial defw 0 ; Serial number of current DNS query -v_dnsfd defb 0 ; file descriptor of DNS socket -v_fieldptr defw 0 ; field pointer for DNS strings -v_ansprocessed defb 0 ; answers processed so far -v_nameserver1 defb 0,0,0,0 ; nameserver 1 -v_nameserver2 defb 0,0,0,0 ; nameserver 2 -v_nameserver3 defb 0,0,0,0 ; nameserver 3 -v_nsend -v_dnssockinfo defb 0,0,0,0,0,0,0,0 ; DNS socket info -v_cur_resolver defw 0 ; pointer to IP address of current resolver -v_queryresult defw 0 ; address of query result buffer -v_querylength defw 0 ; query length in bytes -v_dnsretries defb 0 ; remaining retries from this server - -; DHCP system variables -v_dhcpfd defb 0 ; file descriptor of DHCP socket -v_dhcpsockinfo defb 0,0,0,0,0,0,0,0 ; DHCP socket info -v_dhcpxid defb 0,0,0,0 ; XID -v_dhcpserver defb 0,0,0,0 ; Server that replied -v_dhcpreqaddr defb 0,0,0,0 ; Our requested address -v_dhcplease defb 0,0,0,0 ; lease in seconds -v_nspointer defw 0 ; nameserver address pointer - -; TNFS/VFS system variables -v_vfs_curmount defb 0 ; mount point currently in use -v_vfs_dirhandle defb 0 ; current directory handle in use -v_vfs_curfd defb 0 ; current file handle in use -v_trapfd defb 0 ; current tape trap fd -v_trap_blklen defw 0 ; block length of next block -v_vfs_sockinfo defw 0,0 ; IP of last received packet - defw 0 ; source port - defw 0 ; dest port - -; ZX state storage -v_bankm defb 0 ; saved state of BANKM -v_bank678 defb 0 ; saved state of BANK678 - -; Temporary register storage -v_asave defb 0 -v_hlsave defw 0 -v_desave defw 0 -v_bcsave defw 0 -v_ixsave defw 0 -v_pagerws defw 0 ; register storage for the pager - -; Miscellaneous TCP variables -v_localport defw 0 ; Storage for current local port for connect -v_sockfd defb 0 ; Storage for a socket file descriptor -v_connfd defb 0 ; Storage for a socket file descriptor - -; RST8 variables for interpreter extensions -v_rst8vector defw 0 ; points to a routine to call -v_interpflags defb 0 ; flags -v_tabletop defw 0 ; Current top of interpreter table -v_errnr_save defb 0 ; Error number storage -v_chaddsave defw 0 ; Storage for CH_ADD -v_origpageb defb 0 ; Original page in paging area B - -; VFS vector table -VFSVECBASE -v_fs1page defb 0 ; Page number where the code lives -v_fs2page defb 0 -v_fs3page defb 0 -v_fs4page defb 0 - -; File descriptor vector table -FDVECBASE -v_fd1page defb 0 ; ROM number where the table lives -v_fd2page defb 0 -v_fd3page defb 0 -v_fd4page defb 0 -v_fd5page defb 0 -v_fd6page defb 0 -v_fd7page defb 0 -v_fd8page defb 0 -v_fd9page defb 0 -VECOFFS equ (FDVECBASE-FDBASE)%256 - -DIRVECBASE -MAX_DIRHNDS equ 9 -v_dhnd1page defb 0 -v_dhnd2page defb 0 -v_dhnd3page defb 0 -v_dhnd4page defb 0 -v_dhnd5page defb 0 -v_dhnd6page defb 0 -v_dhnd7page defb 0 -v_dhnd8page defb 0 -v_dhnd9page defb 0 - -; VFS workspace -v_mountnumber defb 0 ; Current selected mount point -v_vfspgb_vecsave defb 0 ; page area B original page numbers -v_vfs_workspace defw 0 ; short temp workspace for VFS code -VFSJUMP jp 0x2000 ; yes, it's self modifying code! - -; ROM table - list of ROM pages with a valid vector table (max 31) -vectors defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -pagealloc defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -ROMVECOFFS equ (vectors-2)%256 - -; Page storage -v_util_pgb defb 0 - -; Values of 0x7ffd and the border colour -v_port7ffd defb 0 -v_border defb 0 -v_machinetype defb 0 - -; Interrupt counter -v_intcount defw 0 - -; Configuration pointer -v_configptr defw 0 - -; Reserve memory above 0x3FF8 for the jump table. - block 0x3FF8-$,0xff diff --git a/rom/tnfs.asm b/rom/tnfs.asm deleted file mode 100644 index 09c6f43..0000000 --- a/rom/tnfs.asm +++ /dev/null @@ -1,52 +0,0 @@ -;The MIT License -; -;Copyright (c) 2009 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; File that builds the TNFS ROM library. - - org 0x2000 ; this is a standard ROM module. - - include "tnfs_vectors.asm" ; Vector table - include "tnfs_init.asm" - include "tnfs_core.asm" ; low level library - include "tnfs_mount.asm" ; Mount and unmount filesystems - include "tnfs_file.asm" ; File operations - include "tnfs_directory.asm" ; Directory operations - - ; These are not really anything to do with TNFS, but there's not - ; enough space in any other "core" ROM page to put them elsewhere! -; include "machinetype.asm" - include "flashconf.asm" ; Flash location defs - include "dhcpdefs.asm" ; DHCP definitions - include "sockdefs.asm" ; Socket definitions - include "inetinit.asm" ; Initialize interface - include "dhcpclient.asm" ; DHCP - include "basstart.asm" ; Post BASIC initialization - include "startmsg.asm" ; Startup message - - ; definitions - include "spectranet.asm" ; Base ROM definitions - include "sysvars.asm" ; Base system variables - include "fs_statdefs.asm" ; Definitions for stat() - include "fs_defs.asm" ; General filesystem definitions - include "tnfs_defs.asm" ; TNFS definitions - include "tnfs_sysvars.asm" ; System variables and workspaces - include "sysdefs.asm" ; system defs diff --git a/rom/tnfs_core.asm b/rom/tnfs_core.asm index d0699c7..f1e9a47 100644 --- a/rom/tnfs_core.asm +++ b/rom/tnfs_core.asm @@ -19,21 +19,29 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "tnfs_defs.inc" +.include "tnfs_sysvars.inc" +.include "spectranet.inc" +.include "sysvars.inc" +.include "fcntl.inc" +.include "sockdefs.inc" ; General TNFS core utility functions. ;------------------------------------------------------------------------ ; F_tnfs_strcpy ; Copy a null terminated string in HL to the buffer in DE, up to B bytes long ; Returns with DE set to the buffer end + 1 -F_tnfs_strcpy -.loop +.text +.globl F_tnfs_strcpy +F_tnfs_strcpy: +.loop1: ld a, (hl) ld (de), a inc de and a ; NULL terminator? ret z inc hl - djnz .loop + djnz .loop1 xor a ; if we exhaust the maximum length, ld (de), a ; make sure there's a NULL on the end. inc de @@ -46,21 +54,22 @@ F_tnfs_strcpy ; DE = pointer to string to concatenate ; BC = buffer size in bytes ; On return, carry is set if the buffer was too small -F_tnfs_strcat +.globl F_tnfs_strcat +F_tnfs_strcat: ; find the end of the first string dec bc ; guarantee that we can null terminate it -.findend +.findend2: ld a, (hl) and a - jr z, .string_end + jr z, .string_end2 inc hl dec bc ld a, b or c - jr nz, .findend + jr nz, .findend2 scf ; buffer too short ret -.string_end +.string_end2: ld a, (de) ; second string ld (hl), a and a ; null? @@ -70,7 +79,7 @@ F_tnfs_strcat dec bc ld a, b or c - jr nz, .string_end + jr nz, .string_end2 ld (hl), 0 ; add a terminator scf ; buffer too small ret @@ -82,10 +91,11 @@ F_tnfs_strcat ; DE = pointer to a buffer to store the resulting path ; In use mountpoint must be in v_curmountpt ; On return DE points to the end of the new string. -F_tnfs_abspath +.globl F_tnfs_abspath +F_tnfs_abspath: ld a, (hl) and a ; Empty string? - jr z, .donothing ; Do nothing. + jr z, .donothing3 ; Do nothing. cp '/' ; Absolute path? ld b, 255 jp z, F_tnfs_strcpy ; yes, so just copy it verbatim. @@ -93,60 +103,60 @@ F_tnfs_abspath push hl ld (v_desave), de ; save start of buffer ld a, (v_curmountpt) ; get the mount point we're working on - add v_cwd0 / 256 ; calculate the MSB + add a, v_cwd0 / 256 ; calculate the MSB ld h, a ld l, 0 ; set HL to the cwd -.cploop +.cploop3: ld a, (hl) and a ; zero? - jr z, .stringend + jr z, .stringend3 ld (de), a inc hl inc de - djnz .cploop -.stringend + djnz .cploop3 +.stringend3: ld a, 255 ; did we actually copy anything? cp b - jr z, .addslash ; no, so put on a leading / + jr z, .addslash3 ; no, so put on a leading / dec de ld a, (de) ; check for trailing / cp '/' inc de - jr z, .parsepath ; trailing / is present, nothing to do -.addslash + jr z, .parsepath3 ; trailing / is present, nothing to do +.addslash3: ld a, '/' ld (de), a ; add the trailing / inc de -.parsepath +.parsepath3: pop hl ; Build up the actual path. If we encounter a ../, remove the ; top path entry. If we encounter a ./, skip it. -.loop +.loop3: ld a, (hl) ; check for end of string and a - jr z, .addnull ; finished so add a null to the destination - call .relativepath ; check for relative path ../ or ./ - jr c, .loop ; relative path processed, don't copy any more -.copypath + jr z, .addnull3 ; finished so add a null to the destination + call .relativepath3 ; check for relative path ../ or ./ + jr c, .loop3 ; relative path processed, don't copy any more +.copypath3: ld a, (hl) ; copy the byte ld (de), a inc hl inc de cp '/' ; up to a / - jr z, .loop ; when we go for the next bit. + jr z, .loop3 ; when we go for the next bit. and a ; hit the NULL at the end? ret z ; all done - jr .copypath + jr .copypath3 -.donothing ; simply advance DE to the end of +.donothing3: ; simply advance DE to the end of ld a, (de) ; the current path string and a ret z inc de - jr .donothing + jr .donothing3 -.addnull +.addnull3: xor a ld (de), a inc de @@ -155,60 +165,60 @@ F_tnfs_abspath ; Deal with relative paths. When a ../ is encountered, the last ; dir should be removed (stopping at the start of the string). ; If a ./ is encountered it should be skipped. -.relativepath +.relativepath3: ld (v_hlsave), hl ; save pointer ld a, (hl) cp '.' - jr nz, .notrelative ; definitely not a relative path + jr nz, .notrelative3 ; definitely not a relative path inc hl ld a, (hl) cp '/' - jr z, .omit ; It's a ./ - omit it + jr z, .omit3 ; It's a ./ - omit it and a ; or a . (null), same thing - jr z, .omitnull + jr z, .omitnull3 cp '.' - jr nz, .notrelative ; It's .somethingelse + jr nz, .notrelative3 ; It's .somethingelse3 inc hl ld a, (hl) cp '/' - jr z, .relative ; relative path + jr z, .relative3 ; relative path and 0 ; null terminator? also relative path - jr z, .relativenull ; - jr .notrelative ; something else -.relative + jr z, .relativenull3 ; + jr .notrelative3 ; something else +.relative3: inc hl ; make HL point at next byte for return. -.relativenull +.relativenull3: ex de, hl ; do the work in HL push hl ; save the pointer. ld bc, (v_desave) ; get the pointer to the start of the buffer inc bc ; add 1 to it sbc hl, bc ; compare with the current address pop hl ; get current address back into HL - jr z, .relativedone ; at the root already, so do nothing + jr z, .relativedone3 ; at the root already, so do nothing dec hl ; get rid of the topmost path element ld (hl), 0 ; remove the trailing / -.chewpath +.chewpath3: dec hl ld a, (hl) ; is it a / ? cp '/' ; if so we're nearly done - jr z, .relativealmostdone + jr z, .relativealmostdone3 ld (hl), 0 ; erase char - jr .chewpath -.relativealmostdone + jr .chewpath3 +.relativealmostdone3: inc hl ; HL points at next char -.relativedone +.relativedone3: ex de, hl scf ; indicate that path copy shouldn't take place ret -.notrelative +.notrelative3: ld hl, (v_hlsave) and a ; set Z flag if zero ret -.omit +.omit3: inc hl ; advance pointer to next element of the path -.omitnull +.omitnull3: scf ; set carry ret @@ -216,11 +226,12 @@ F_tnfs_abspath ; F_tnfs_header_w ; Creates a TNFS header at a fixed address, buf_tnfs_wkspc, with the ; extant session id -F_tnfs_header_w +.globl F_tnfs_header_w +F_tnfs_header_w: push af ld a, (v_curmountpt) ; find the SID for this mount point rlca ; mutiply by two - add v_tnfs_sid0 % 256 ; and add the offset + add a, v_tnfs_sid0 % 256 ; and add the offset ld h, v_tnfs_sid0 / 256 ; set HL = pointer to SID ld l, a ld e, (hl) ; set DE to the SID @@ -232,14 +243,15 @@ F_tnfs_header_w ; Creates a TNFS header. Session ID in DE. Command in A. HL is a pointer ; to the buffer to fill. ; HL points to the end of the header on exit. -F_tnfs_header +.globl F_tnfs_header +F_tnfs_header: ld (hl), e inc hl ld (hl), d inc hl push af ld a, (v_curmountpt) ; calculate the sequence number storage - add v_tnfs_seqno0 % 256 + add a, v_tnfs_seqno0 % 256 ld e, a ld d, v_tnfs_seqno0 / 256 ld a, (de) @@ -258,12 +270,13 @@ F_tnfs_header ; just set up the connection data for the datagrams. ; Returns with carry set and A=error on error. ; HL=pointer to 4 byte IP address -F_tnfs_prepsock +.globl F_tnfs_prepsock +F_tnfs_prepsock: ld a, (v_curmountpt) ; calculate the offset to the socket info rlca ; multiply by 8 rlca rlca - add v_tnfs_sockinfo0 % 256 + add a, v_tnfs_sockinfo0 % 256 ld e, a ; set DE to the address of the sockinfo ld d, v_tnfs_sockinfo0 / 256 @@ -293,9 +306,11 @@ F_tnfs_prepsock ;------------------------------------------------------------------------ ; F_tnfs_message_w ; Sends the block of data starting at buf_tnfs_wkspc and ending at DE. -F_tnfs_message_w +.globl F_tnfs_message_w +F_tnfs_message_w: ex de, hl ; end pointer into HL for length calc -F_tnfs_message_w_hl ; entry point for when HL is already set +.globl F_tnfs_message_w_hl +F_tnfs_message_w_hl: ; entry point for when HL is already set ld de, buf_tnfs_wkspc ; start of block sbc hl, de ; calculate length ld b, h @@ -304,7 +319,8 @@ F_tnfs_message_w_hl ; entry point for when HL is already set ; F_tnfs_message ; Sends the block of data pointed to by DE for BC bytes and gets the ; response. -F_tnfs_message +.globl F_tnfs_message +F_tnfs_message: ld a, tnfs_max_retries ; number of retries ld (v_tnfs_retriesleft), a ; into memory ld (v_tnfs_tx_de), de ; save pointer @@ -314,33 +330,33 @@ F_tnfs_message rlca ; multiply by 8 to find the sockinfo rlca rlca - add v_tnfs_sockinfo0 % 256 ; LSB + add a, v_tnfs_sockinfo0 % 256 ; LSB ld h, v_tnfs_sockinfo0 / 256 ; MSB ld l, a ld (v_tnfs_tx_hl), hl ; save sockinfo pointer -.retryloop +.retryloop9: ld hl, (v_tnfs_tx_hl) ; Fetch parameters ld de, (v_tnfs_tx_de) ld bc, (v_tnfs_tx_bc) ld a, (v_tnfs_sock) ; socket descriptor call SENDTO ; send the data - jr nc, .pollstart + jr nc, .pollstart9 ret ; error, leave now ; wait for the response by polling -.pollstart +.pollstart9: call F_tnfs_poll - jr nc, .continue ; a message is ready + jr nc, .continue9 ; a message is ready ld a, (v_tnfs_retriesleft) ; get retries left dec a ; decrement it ld (v_tnfs_retriesleft), a ; and store it and a ; is it at zero? - jr nz, .retryloop - ld a, TTIMEOUT ; error code - we tried...but gave up + jr nz, .retryloop9 + ld a, TTIMEOUT ; error code - we tried...but9 gave up scf ; timed out ret -.continue +.continue9: ld ix, (v_tnfs_tx_de) ; start of the block we sent ld a, (ix+tnfs_cmd_offset) ; check the command cp TNFS_OP_READ ; and see if it's a read operation @@ -348,7 +364,7 @@ F_tnfs_message ld hl, v_vfs_sockinfo ; Address to receive remote datagram IP/port ld de, tnfs_recv_buffer ; Address to receive data ld a, (v_tnfs_sock) ; The tnfs socket - jr z, .read ; ...if the command was READ, handle it + jr z, .read9 ; ...if9 the command was READ, handle it ld bc, 1024 ; max message size call RECVFROM @@ -357,36 +373,36 @@ F_tnfs_message push bc ld b, a ld a, (v_curmountpt) ; find the sequence number storage - add v_tnfs_seqno0 % 256 + add a, v_tnfs_seqno0 % 256 ld l, a ld h, v_tnfs_seqno0 / 256 ld a, (hl) cp b ; sequence number match? if not pop bc - jr nz, .pollstart ; see if the real message is still to come + jr nz, .pollstart9 ; see if the real message is still to come ret ; read is done in two phases - first get the header, then ; once we've got that copy the data directly to the required ; memory address instead of via the tnfs buffer. -.read +.read9: ld bc, TNFS_READHEADERSZ ; just pull out the header call RECVFROM ret c ; leave on error ld a, (tnfs_recv_buffer + tnfs_seqno_offset) ld b, a ld a, (v_curmountpt) ; find the sequence number storage - add v_tnfs_seqno0 % 256 + add a, v_tnfs_seqno0 % 256 ld l, a ld h, v_tnfs_seqno0 / 256 ld a, (hl) ; Consume rest of packet when no match cp b ; sequence number match? if not - jr nz, .consume ; consume and discard the non-match data + jr nz, .consume9 ; consume and discard the non-match data ; check for error conditions ld a, (tnfs_recv_buffer+tnfs_err_offset) and a - jr nz, .leaveread + jr nz, .leaveread9 ld de, (v_read_destination) ; get destination address push de @@ -403,57 +419,58 @@ F_tnfs_message ex de, hl or a ; ensure carry is reset ret -.leaveread +.leaveread9: scf ; indicate error ret -.consume ; consume and discard data we don't want +.consume9: ; consume and discard data we don't want ld a, (v_tnfs_sock) ; if there is any data to be consumed call POLLFD ; (a non data datagram or an error datagram - jp z, .retryloop ; may not have any more data) + jp z, .retryloop9 ; may not have any more data) ld de, tnfs_recv_buffer ld bc, 256 ld a, (v_tnfs_sock) call RECV ; unload any remaining data from the socket - jr .consume + jr .consume9 ;------------------------------------------------------------------------- ; F_tnfs_poll ; Polls the tnfs fd for 1 time unit. Returns with carry set if the time ; expired. -F_tnfs_poll +.globl F_tnfs_poll +F_tnfs_poll: ld a, (v_tnfs_backoff) and a - jr z, .setstart + jr z, .setstart10 ld a, (v_tnfs_polltime) ld c, a rla ; multiply backoff time by 2 - jr nc, .setsysvar + jr nc, .setsysvar10 ld a, c ; can't back off any more, restore value - jr .setb -.setsysvar + jr .setb10 +.setsysvar10: ld (v_tnfs_polltime), a ; save new poll time -.setb +.setb10: ld b, a ei ; ensure interrupts are enabled -.loop +.loop10: push bc ld a, (v_tnfs_sock) call POLLFD pop bc - jr nz, .done ; data has arrived + jr nz, .done10 ; data has arrived halt ; timing: wait for next 50Hz interrupt - djnz .loop + djnz .loop10 scf ; poll time has expired ret -.setstart +.setstart10: inc a ld (v_tnfs_backoff), a ; set backoff flag ld a, tnfs_polltime ; initial polltime ld (v_tnfs_polltime), a - jr .setb -.done + jr .setb10 +.done10: xor a ld (v_tnfs_backoff), a ; reset backoff flag ret @@ -462,7 +479,8 @@ F_tnfs_poll ; F_tnfs_mounted ; Ask if a volume is mounted. Returns with carry reset if so, and ; carry set if not, with A set to the error number. -F_tnfs_mounted +.globl F_tnfs_mounted +F_tnfs_mounted: ld a, (v_tnfs_sock) and a ret nz ; valid handle exists, return @@ -476,7 +494,8 @@ F_tnfs_mounted ; This routine handles the assembly of the data block for all of these. ; Arguments: A = command ; HL = pointer to string argument -F_tnfs_pathcmd +.globl F_tnfs_pathcmd +F_tnfs_pathcmd: push hl call F_tnfs_header_w ; create the header in the workspace area ex de, hl ; de now points at current address @@ -488,14 +507,16 @@ F_tnfs_pathcmd ; As above but handles the return code too. ; A = current mount point ; B = command -F_tnfs_simplepathcmd +.globl F_tnfs_simplepathcmd +F_tnfs_simplepathcmd: call F_fetchpage ret c ld (v_curmountpt), a ld a, b call F_tnfs_pathcmd ; Entry point for simple exit handler -F_tnfs_simpleexit +.globl F_tnfs_simpleexit +F_tnfs_simpleexit: jp c, F_leave ld a, (tnfs_recv_buffer+tnfs_err_offset) and a @@ -506,26 +527,27 @@ F_tnfs_simpleexit ;--------------------------------------------------------------------------- ; F_tnfs_checkclose ; Checks to see if the socket should be closed, and if so, closes it. -F_tnfs_checkclose +.globl F_tnfs_checkclose +F_tnfs_checkclose: push hl push bc push af ld b,4 ld hl, v_tnfs_sid0 -.loop +.loop15: ld a, (hl) inc hl or (hl) - jr nz, .done + jr nz, .done15 inc hl - djnz .loop + djnz .loop15 ; no SIDs were found, so the socket isn't needed; close it. ld a, (v_tnfs_sock) call CLOSE xor a ld (v_tnfs_sock), a ; clear down the socket storage -.done +.done15: pop af pop bc pop hl diff --git a/rom/tnfs_defs.asm b/rom/tnfs_defs.inc similarity index 100% rename from rom/tnfs_defs.asm rename to rom/tnfs_defs.inc diff --git a/rom/tnfs_directory.asm b/rom/tnfs_directory.asm index 48f03b3..8acf04a 100644 --- a/rom/tnfs_directory.asm +++ b/rom/tnfs_directory.asm @@ -19,6 +19,13 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.include "tnfs_defs.inc" +.include "tnfs_sysvars.inc" +.include "stat.inc" +.include "fcntl.inc" +.text ; TNFS directory functions - opendir, readdir. closedir @@ -28,7 +35,8 @@ ; Arguments: HL = pointer to null-terminated string containing the path ; On success, returns the directory handle in A. ; On error, sets the carry flag and sets A to the error number. -F_tnfs_opendir +.globl F_tnfs_opendir +F_tnfs_opendir: call F_fetchpage ; get our sysvars at 0x1000 ret c @@ -39,14 +47,14 @@ F_tnfs_opendir jp c, F_leave ; return on network error ld a, (tnfs_recv_buffer+tnfs_err_offset) and a ; return code is zero? - jr z, .gethandle + jr z, .gethandle1 scf ; return with tnfs error jp F_leave -.gethandle +.gethandle1: ld a, (v_pgb) ; allocate a ld c, ALLOCDIRHND call RESALLOC ; directory handle. - jr c, .cleanupandexit + jr c, .cleanupandexit1 ld h, HANDLESPACE / 256 ; create our private sysvar addr ld a, (tnfs_recv_buffer+tnfs_msg_offset) ld (hl), a ; save TNFS handle @@ -55,7 +63,7 @@ F_tnfs_opendir ld (hl), a ld a, l ; move dirhandle into A jp F_leave ; return the directory handle -.cleanupandexit +.cleanupandexit1: push af ld a, (tnfs_recv_buffer+tnfs_msg_offset) ld b, a @@ -74,7 +82,8 @@ F_tnfs_opendir ; DE = pointer to a buffer for the result ; On success, returns with carry cleared, and the buffer at DE filled ; with the result. On error, sets the carry flag and A to the error number -F_tnfs_readdir +.globl F_tnfs_readdir +F_tnfs_readdir: call F_fetchpage ret c @@ -94,10 +103,10 @@ F_tnfs_readdir jp c, F_leave ; but return on network error ld a, (tnfs_recv_buffer+tnfs_err_offset) and a ; if rc is zero then copy the - jr z, .copybuf ; buffer to DE + jr z, .copybuf2 ; buffer to DE scf jp F_leave -.copybuf +.copybuf2: ld hl, tnfs_recv_buffer+tnfs_msg_offset ld b, 255 ; max filename length call F_restorepage ; ... in case it's 0x1000-0x1FFF @@ -109,7 +118,8 @@ F_tnfs_readdir ; Arguments: A = directory handle ; On success, returns with carry cleared. On error, returns with carry ; set and A as the error. -F_tnfs_closedir +.globl F_tnfs_closedir +F_tnfs_closedir: call F_fetchpage ret c @@ -141,7 +151,8 @@ F_tnfs_closedir ; path (which gets prepended to subsequent file operations). ; Parameters HL = path to chdir to ; Returns with carry set on error and A=error code -F_tnfs_chdir +.globl F_tnfs_chdir +F_tnfs_chdir: call F_fetchpage ret c @@ -149,27 +160,27 @@ F_tnfs_chdir ld (v_curmountpt), a ; set the mount point being worked upon ld a, TNFS_OP_STAT call F_tnfs_pathcmd ; stat the path - jr c, .error ; stat returned an error + jr c, .error4 ; stat returned an error ld a, (tnfs_recv_buffer+tnfs_err_offset) and a - jr nz, .scferror + jr nz, .scferror4 ld hl, tnfs_recv_buffer+tnfs_msg_offset+1 ; MSB of stat filemode bitfield ld a, S_IFDIR / 256 ; MSB of S_IFDIR bitfield and (hl) ; AND it all together... - jr z, .notadir ; ...if zero, it wasn't a directory. + jr z, .notadir4 ; ...if4 zero, it wasn't a directory. pop hl ld a, (v_curmountpt) - add v_cwd0 / 256 ; add the MSB of the CWD storage + add a, v_cwd0 / 256 ; add the MSB of the CWD storage ld d, a ; DE = pointer to this mount point's CWD ld e, 0 ; copy the directory we just got call F_tnfs_abspath ; as an absolute path. jp F_leave -.notadir +.notadir4: ld a, ENOTDIR -.scferror +.scferror4: scf -.error +.error4: pop hl jp F_leave @@ -178,7 +189,8 @@ F_tnfs_chdir ; Create a directory on the server. ; Parameters HL = pointer to directory name ; Returns with carry set on error and A=error code. -F_tnfs_mkdir +.globl F_tnfs_mkdir +F_tnfs_mkdir: ld b, TNFS_OP_MKDIR jp F_tnfs_simplepathcmd @@ -187,7 +199,8 @@ F_tnfs_mkdir ; Removes a directory on the server. ; Parameters HL = pointer to the directory ; Returns with carry set on error and A=error code. -F_tnfs_rmdir +.globl F_tnfs_rmdir +F_tnfs_rmdir: ld b, TNFS_OP_RMDIR jp F_tnfs_simplepathcmd @@ -195,19 +208,20 @@ F_tnfs_rmdir ; F_tnfs_getcwd ; Gets the current working directory ; Parameters DE = pointer to memory to copy result -F_tnfs_getcwd +.globl F_tnfs_getcwd +F_tnfs_getcwd: call F_fetchpage ret c - add v_cwd0 / 256 ; add the MSB of the CWD storage + add a, v_cwd0 / 256 ; add the MSB of the CWD storage ld h, a ; ld l, 0 ; HL = pointer to CWD -.cploop +.cploop7: ld a, (hl) ld (de), a and a ; null terminator? jp z, F_leave inc hl inc de - jr .cploop + jr .cploop7 diff --git a/rom/tnfs_file.asm b/rom/tnfs_file.asm index bafd06c..fda3b4f 100644 --- a/rom/tnfs_file.asm +++ b/rom/tnfs_file.asm @@ -19,8 +19,13 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.include "tnfs_sysvars.inc" +.include "tnfs_defs.inc" +.text ; TNFS file operations - open, read, write, close -; include "regdump.asm" +; include "regdump.asm0" ;-------------------------------------------------------------------------- ; F_tnfs_open ; Opens a file on the remote server. @@ -28,7 +33,8 @@ ; D - File flags (POSIX) ; E - File mode (POSIX) ; HL - Pointer to a string containing the full path to the file -F_tnfs_open +.globl F_tnfs_open +F_tnfs_open: call F_fetchpage ret c ld (v_curmountpt), a @@ -49,14 +55,14 @@ F_tnfs_open jp c, F_leave ; return on network error ld a, (tnfs_recv_buffer+tnfs_err_offset) and a - jr z, .gethandle + jr z, .gethandle1 scf ; tnfs error jp F_leave -.gethandle +.gethandle1: ld a, (v_pgb) ; Allocate a new file descriptor ld c, ALLOCFD call RESALLOC ; for this TNFS handle - jr c, .nofds + jr c, .nofds1 ld a, 0x20 ; indicate "not a socket" ld (hl), a ; and update the FD table ld h, HANDLESPACE / 256 ; now save the TNFS handle @@ -67,7 +73,7 @@ F_tnfs_open ld (hl), a ld a, l ; FD is in L, needs to be returned in A jp F_leave -.nofds +.nofds1: ld a, TNFS_OP_CLOSE ; cleanup recovery from finding no free call F_tnfs_header_w ; file descriptors - close TNFS handle ld a, (tnfs_recv_buffer+tnfs_msg_offset) @@ -86,7 +92,8 @@ F_tnfs_open ; DE - Pointer to a buffer to copy the data ; Returns with carry set on error and A=code, or carry reset on success ; with BC = actual number of bytes read -F_tnfs_read +.globl F_tnfs_read +F_tnfs_read: call F_fetchpage ret c ld (v_curfd), a ; store the FD @@ -96,7 +103,7 @@ F_tnfs_read ld h, b ; store bytes requested in HL ld l, c -.readloop +.readloop2: ld a, (v_curfd) push hl call F_tnfs_read_blk ; note: returns with our memory @@ -106,25 +113,26 @@ F_tnfs_read ld (v_bytesread), hl ex af, af' pop hl - jr nz, .readdone ; fewer bytes read than requested - jr c, .readdone ; or an error occurred + jr nz, .readdone2 ; fewer bytes read than requested + jr c, .readdone2 ; or an error occurred sbc hl, bc ; calculate bytes remaining ld b, h ; and set BC ld c, l - jr nz, .readloop ; still more to read -.readdone + jr nz, .readloop2 ; still more to read +.readdone2: ld bc, (v_bytesread) ; return bytes read in BC jp F_leave ; read complete -F_tnfs_read_blk +.globl F_tnfs_read_blk +F_tnfs_read_blk: ld (v_read_destination), de ; save destination ex af, af' ; save FD ld a, b ; cap read size at 512 bytes cp 0x02 - jr c, .continue ; less than 512 bytes if < 0x02 -.sizecap + jr c, .continue3 ; less than 512 bytes if < 0x02 +.sizecap3: ld bc, 512 ; cap at 512 bytes -.continue +.continue3: push bc ; save requested bytes ld a, TNFS_OP_READ call F_tnfs_header_w @@ -163,11 +171,12 @@ F_tnfs_read_blk ; BC = number of bytes to write ; Returns with carry set on error and A = return code. BC = bytes ; written. -F_tnfs_write +.globl F_tnfs_write +F_tnfs_write: call F_fetchpage ret c ld (v_curfd), a -.writeloop +.writeloop4: push hl push bc ld a, (v_curfd) ; load current file handle @@ -181,17 +190,18 @@ F_tnfs_write add hl, bc ; advance pointer ld b, d ; bytes remaining into BC ld c, e - jr nz, .writeloop ; next block if bytes remain + jr nz, .writeloop4 ; next block if bytes remain jp F_leave -F_tnfs_write_blk +.globl F_tnfs_write_blk +F_tnfs_write_blk: ex af, af' ld a, b ; cap write size at 512 bytes cp 0x02 - jr c, .continue ; less than 512 bytes if < 0x02 -.sizecap + jr c, .continue5 ; less than 512 bytes if < 0x02 +.sizecap5: ld bc, 512 ; cap at 512 bytes -.continue +.continue5: push hl ; save buffer pointer ld a, TNFS_OP_WRITE call F_tnfs_header_w @@ -220,10 +230,10 @@ F_tnfs_write_blk ret c ; network error ld a, (tnfs_recv_buffer+tnfs_err_offset) and a ; check for tnfs error - jr z, .getsize + jr z, .getsize5 scf ; set carry to flag error ret -.getsize +.getsize5: ld bc, (tnfs_recv_buffer+tnfs_msg_offset) ret @@ -232,7 +242,8 @@ F_tnfs_write_blk ; Closes an open file descriptor. ; Arguments A = the file descriptor ; Returns with carry set on error and A = return code. -F_tnfs_close +.globl F_tnfs_close +F_tnfs_close: call F_fetchpage ret c @@ -263,11 +274,12 @@ F_tnfs_close ; Stats a file (gets information on it). ; Arguments HL = pointer to a null-terminated string - the filename ; DE = pointer to a buffer for the result -; The result is exactly the structure defined in tnfs-protocol.txt +; The result is exactly the structure defined in tnfs-protocol.txt6 ; Returns with carry set on error and A = return code. ; An optimization would be to copy the reply directly from the ethernet ; buffer and save a buffer copy. -F_tnfs_stat +.globl F_tnfs_stat +F_tnfs_stat: call F_fetchpage ret c ld (v_curmountpt), a ; save the mount point @@ -279,10 +291,10 @@ F_tnfs_stat jp c, F_leave ; network error ld a, (tnfs_recv_buffer+tnfs_err_offset) and a - jr z, .copybuf + jr z, .copybuf7 scf ; tnfs error jp F_leave -.copybuf +.copybuf7: dec bc ; decrease BC by the size of the dec bc ; TNFS header + status byte dec bc @@ -298,7 +310,8 @@ F_tnfs_stat ; Arguments HL = pointer to null terminated source filename ; DE = pointer to null terminated destination filename ; A = mount point -F_tnfs_rename +.globl F_tnfs_rename +F_tnfs_rename: call F_fetchpage ret c ld (v_curmountpt), a @@ -322,7 +335,8 @@ F_tnfs_rename ; C = operation 0x00 = SEEK_SET, 0x01 = SEEK_CUR, 0x02 = SEEK_END ; DEHL = 32 bit signed seek position ; Returns with carry set and A=error code on error. -F_tnfs_lseek +.globl F_tnfs_lseek +F_tnfs_lseek: call F_fetchpage ret c @@ -354,7 +368,8 @@ F_tnfs_lseek ; F_tnfs_unlink ; Unlink (delete) a file. ; Parameters HL = pointer to filename -F_tnfs_unlink +.globl F_tnfs_unlink +F_tnfs_unlink: ld b, TNFS_OP_UNLINK jp F_tnfs_simplepathcmd @@ -364,7 +379,8 @@ F_tnfs_unlink ; Parameters HL = pointer to filename ; DE = 16 bit mode flags ; On error returns with carry set and A=error -F_tnfs_chmod +.globl F_tnfs_chmod +F_tnfs_chmod: call F_fetchpage ret c diff --git a/rom/tnfs_init.asm b/rom/tnfs_init.asm index ec362d4..facfd8b 100644 --- a/rom/tnfs_init.asm +++ b/rom/tnfs_init.asm @@ -19,16 +19,21 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.include "ctrlchars.inc" ; Initialization routines -F_init +.text +.globl F_init +F_init: call F_inetinit ; Initialize the interface - note not a ; TNFS function but in this area for practical ; reasons. ld a, (v_pgb) ; Who are we? call RESERVEPAGE ; Reserve a page of static RAM. - jr c, .failed + jr c, .failed1 ld b, a ; save the page number ld a, (v_pgb) ; and save the page we got rlca ; in our 8 byte area in sysvars @@ -50,17 +55,19 @@ F_init ld hl, STR_init call PRINT42 ret -.failed +.failed1: ld hl, STR_allocfailed call PRINT42 ret -STR_allocfailed defb "tnfs: No memory pages available\n",0 -STR_init defb "TNFS 1.0 initialized\n",0 - +.data +STR_allocfailed: defb "tnfs: No memory pages available",NEWLINE,0 +STR_init: defb "TNFS 1.01 initialized",NEWLINE,0 +.text ;----------------------------------------------------------------------------- ; F_fetchpage ; Gets our page of RAM and puts it in page area A. -F_fetchpage +.globl F_fetchpage +F_fetchpage: push af push hl ld a, (v_pgb) ; get our ROM number and calculate @@ -71,7 +78,7 @@ F_fetchpage ld l, a ld a, (hl) ; fetch the page number and a ; make sure it's nonzero - jr z, .nopage + jr z, .nopage2 inc l ; point hl at "page number storage" ex af, af' ld a, (v_pga) @@ -82,7 +89,7 @@ F_fetchpage pop af or a ; ensure carry is cleared ret -.nopage +.nopage2: pop hl ; restore the stack pop af ld a, 0xFF ; TODO: ENOMEM return code @@ -92,8 +99,10 @@ F_fetchpage ;--------------------------------------------------------------------------- ; F_restorepage ; Restores page A to its original value. -F_leave -F_restorepage +.globl F_leave +F_leave: +.globl F_restorepage +F_restorepage: push af push hl ld a, (v_pgb) ; calculate the offset... diff --git a/rom/tnfs_mount.asm b/rom/tnfs_mount.asm index 54c45d1..00980d7 100644 --- a/rom/tnfs_mount.asm +++ b/rom/tnfs_mount.asm @@ -19,9 +19,12 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "tnfs_defs.inc" +.include "tnfs_sysvars.inc" +.include "spectranet.inc" +.include "sysvars.inc" ; The TNFS mount and umount functions. - ;----------------------------------------------------------------------- ; F_tnfs_mount: Mount a remote filesystem. ; Parameters: IX - pointer to 10 byte VFS mount structure: @@ -34,7 +37,8 @@ ; ; On success, returns the session number in HL. On error, returns the ; error number in HL and sets the carry flag. -F_tnfs_mount +.globl F_tnfs_mount +F_tnfs_mount: call F_fetchpage ; get our private RAM page ret c ; which was allocated on startup. ld (v_curmountpt), a ; save the mount point for later @@ -44,12 +48,12 @@ F_tnfs_mount ld d, (ix+1) ld hl, STR_tnfstype ld bc, 5 -.cploop +.cploop1: ld a, (de) ; Effectively this is a "strncmp" to check cpi ; that the passed protocol is "tnfs" plus - jp nz, .notourfs ; a null. + jp nz, .notourfs1 ; a null. inc de - jp pe, .cploop + jp pe, .cploop1 ; It is now certain that the requested FS is TNFS. ld de, buf_tnfs_wkspc ; Look up the host @@ -71,7 +75,7 @@ F_tnfs_mount ld de, 0 ; no session id yet xor a ; cmd is 0x00 call F_tnfs_header ; create the header, HL now at the next byte - ld (hl), 0 ; version 1.0, little endian + ld (hl), 0 ; version 1.01, little endian inc hl ld (hl), 1 ; msb of protocol version inc hl @@ -96,18 +100,18 @@ F_tnfs_mount ld b, h ; move into bc ld c, l call F_tnfs_message ; send msg/get response - jr c, .mounterr ; clean up on error + jr c, .mounterr1 ; clean up on error ; decode the result - first, check for error conditions ld a, (tnfs_recv_buffer + tnfs_err_offset) and a ; zero = no error - jr nz, .mounterr ; clean up on error + jr nz, .mounterr1 ; clean up on error ld hl, (tnfs_recv_buffer + tnfs_sid_offset) ld d, v_tnfs_sid0 / 256 ; start with the lowest SID storage offset ld a, (v_curmountpt) ; get the intended mount point number rlca ; multiply by two - add v_tnfs_sid0 % 256 ; calculate the offset + add a, v_tnfs_sid0 % 256 ; calculate the offset ld e, a ; DE = storage for the session id ex de, hl ld (hl), e ; save the session identifier @@ -115,7 +119,7 @@ F_tnfs_mount ld (hl), d ld a, (v_curmountpt) ; now calculate the address of the CWD - add v_cwd0 / 256 ; storage area (A=MSB) + add a, v_cwd0 / 256 ; storage area (A=MSB) ld h, a ; and point HL there ld l, 0 ld (hl), '/' @@ -124,7 +128,7 @@ F_tnfs_mount ; set up mount point in VFS mount table ld a, (v_curmountpt) ; get the mount point - add VFSVECBASE % 256 ; find it in the sysvars + add a, VFSVECBASE % 256 ; find it in the sysvars ld l, a ld h, 0x3F ; point HL at the address in sysvars ld a, (v_pgb) ; Fetch our ROM number @@ -132,19 +136,20 @@ F_tnfs_mount or 1 ; reset Z and C flags - mounted OK. jp F_leave -.mounterr +.mounterr1: call F_tnfs_checkclose ; close the socket if necessary scf ; set the carry flag jp F_leave -.notourfs +.notourfs1: xor a ; signal 'not our filesystem' by setting jp F_leave ; the zero flag. -STR_tnfstype defb "tnfs",0 +STR_tnfstype: defb "tnfs",0 ;------------------------------------------------------------------------- ; F_tnfs_umount ; Unmounts the TNFS filesystem and closes the socket. -F_tnfs_umount +.globl F_tnfs_umount +F_tnfs_umount: call F_fetchpage ret c ld (v_curmountpt), a @@ -156,11 +161,11 @@ F_tnfs_umount ret c ; communications error ld a, (tnfs_recv_buffer+tnfs_err_offset) and a ; no error? - jr nz, .error + jr nz, .error2 ld a, (v_curmountpt) rlca ; calculate the SID address - add v_tnfs_sid0 % 256 + add a, v_tnfs_sid0 % 256 ld h, v_tnfs_sid0 / 256 ; hl points at the sid ld l, a ld (hl), 0 ; clear down the sid @@ -172,6 +177,6 @@ F_tnfs_umount call F_tnfs_checkclose ; close the socket if necessary jp F_leave -.error +.error2: scf ; flag the error condition jp F_leave diff --git a/rom/tnfs_sysvars.asm b/rom/tnfs_sysvars.inc similarity index 100% rename from rom/tnfs_sysvars.asm rename to rom/tnfs_sysvars.inc diff --git a/rom/tnfs_vectors.asm b/rom/tnfs_vectors.asm index c831eb2..8a5ffd1 100644 --- a/rom/tnfs_vectors.asm +++ b/rom/tnfs_vectors.asm @@ -19,16 +19,18 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "fcntl.inc" -sig defb 0xAA ; This is a ROM module -romid defb 0xFF ; for a filesystem only. -reset defw F_init ; reset vector -mount defw F_tnfs_mount ; The mount routine +.section vectors +sig: defb 0xAA ; This is a ROM module +romid: defb 0xFF ; for a filesystem only. +reset: defw F_init ; reset vector +mount: defw F_tnfs_mount ; The mount routine defw 0xFFFF defw 0xFFFF defw F_startmsg defw 0xFFFF -idstr defw STR_ident ; ROM identity string +idstr: defw STR_ident ; ROM identity string defb 0,0,0 ; no MODCALL, pad out three bytes ; The VFS table. This is a jump table for all the VFS entry points. @@ -54,13 +56,16 @@ idstr defw STR_ident ; ROM identity string jp F_tnfs_chdir ; Change directory jp F_tnfs_getcwd ; get current directory jp F_tnfs_rename ; rename - -STR_ident - defb "TNFS 1.0",0 - -F_tnfs_size ; TODO functions -F_tnfs_free -F_undef +.data +STR_ident: + defb "TNFS 1.00",0 +.text +.globl F_tnfs_size +F_tnfs_size: ; TODO functions +.globl F_tnfs_free +F_tnfs_free: +.globl F_undef +F_undef: ld a, ENOSYS ; Function not implemented scf ret diff --git a/rom/trapdispatch.asm b/rom/trapdispatch.asm index 25371e1..9ee1230 100644 --- a/rom/trapdispatch.asm +++ b/rom/trapdispatch.asm @@ -19,12 +19,18 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "sysvars.inc" +.include "zxsysvars.inc" +.include "spectranet.inc" +.include "zxrom.inc" ;--------------------------------------------------------------------------- ; do_callbas ; Not really a trap, but it handles the effects of an RST 0x10 'callbas' ; exit (which will get re-trapped by a subsequent return via RST 8) -do_callbas +.text +.globl do_callbas +do_callbas: ld e, (hl) ; Get the subroutine address into DE inc hl ld d, (hl) @@ -37,19 +43,20 @@ do_callbas push de ; the actual address in ROM we want to call ld hl, (v_hlsave) ; restore HL ld de, (v_desave) ; restore de - jp UNPAGE ; page out + jp PAGEOUT ; page out ;--------------------------------------------------------------------------- ; do_rst8 ; Figure out what needs to be done when an RST 8 trap occurs. -do_rst8 +.globl do_rst8 +do_rst8: ld (v_hlsave), hl ; save hl without disturbing stack pop hl ; get stack value - entry code push hl push af ld a, h ; check for zero - Spectrum ROM routine return or l - jr z, .returnfromzxrom ; returning from a Spectrum ROM call + jr z, .returnfromzxrom0 ; returning from a Spectrum ROM call ; This is to allow testing of RST8 routines without ; flashing a new ROM each time. @@ -57,19 +64,19 @@ do_rst8 ld hl, (v_rst8vector) ld a, h or l - jr z, .done + jr z, .done0 jp (hl) -.done +.done0: ; The call to the interpreter would end up here. ; For now just reshuffle the stack so we can pass control back ; to the ZX rom. pop af ld hl, 0x000B ; address to return to - push hl ; stack it for the RET at UNPAGE + push hl ; stack it for the RET at PAGEOUT ld hl, (ZX_CH_ADD) ; do the same as the first RST 8 instruction - jp UNPAGE ; re-enter the ZX ROM + jp PAGEOUT ; re-enter the ZX ROM -.returnfromzxrom +.returnfromzxrom0: pop af ; restore af pop hl ; fix stack ld hl, (v_hlsave) ; restore hl diff --git a/rom/ui_funcs.asm b/rom/ui_funcs.asm new file mode 100644 index 0000000..4e6d747 --- /dev/null +++ b/rom/ui_funcs.asm @@ -0,0 +1,7 @@ +; This file just serves to ensure the code for these functions gets +; pulled into the resulting binary. Code in a library that isn't referenced +; by anything doesn't get put in the resulting binary so we must define +; these values to putt the code required. +_F_putc_5by8_impl: equ F_putc_5by8_impl +_F_clear_impl: equ F_clear_impl +_F_backspace_impl: equ F_backspace_impl diff --git a/rom/ui_input.asm b/rom/ui_input.asm index bc12ec4..83e4371 100644 --- a/rom/ui_input.asm +++ b/rom/ui_input.asm @@ -27,38 +27,42 @@ ; routine, but before the ZX ROM has done the same). ; The routines are designed to work regardless of the maskable interrupt ; state. +.include "sysdefs.inc" +.include "sysvars.inc" +.include "page1.xinc" ;=========================================================================== ; Definitions - special keys returned by K_DECODE (and therefore F_getkey) -KEY_TRUEVID equ 0x04 -KEY_INVVID equ 0x05 -KEY_CAPSLOCK equ 0x06 -KEY_EDIT equ 0x07 -KEY_LEFT equ 0x08 -KEY_RIGHT equ 0x09 -KEY_DOWN equ 0x0A -KEY_UP equ 0x0B -KEY_BACKSPACE equ 0x0C -KEY_ENTER equ 0x0D -KEY_EXTEND equ 0x0E -KEY_GRAPH equ 0x0F +KEY_TRUEVID: equ 0x04 +KEY_INVVID: equ 0x05 +KEY_CAPSLOCK: equ 0x06 +KEY_EDIT: equ 0x07 +KEY_LEFT: equ 0x08 +KEY_RIGHT: equ 0x09 +KEY_DOWN: equ 0x0A +KEY_UP: equ 0x0B +KEY_BACKSPACE: equ 0x0C +KEY_ENTER: equ 0x0D +KEY_EXTEND: equ 0x0E +KEY_GRAPH: equ 0x0F ;=========================================================================== ; F_getkey: ; Waits for a key to be pressed, and returns the key in A. ; The routine returns the key on keydown. The calling routine should then ; wait for keyup before getting the next key. -F_getkey +.globl F_getkey +F_getkey: ld a, DATAROM ; key scan routines live here call F_pushpageA -.loop - call key_scan - call key_test - jr nc, .loop +.loop1: + call F_key_scan + call F_key_test + jr nc, .loop1 ld e, a ; partially decoded key is in A, copy it to E ld d, 8 ; not in 'K' cursor mode ld c, 0 ; FLAGS = 0 - call key_code ; decode keypress into actual ascii value + call F_key_code ; decode keypress into actual ascii value ld c, a call F_poppageA ; restore original page A ld a, c @@ -68,13 +72,14 @@ F_getkey ; F_keyup: ; Waits for the keyboard not being pressed anywhere that will generate ; a character. -F_keyup +.globl F_keyup +F_keyup: ld a, DATAROM ; key scan routines live here call F_pushpageA -.loop - call key_scan - call key_test - jr c, .loop ; carry set = key being pressed +.loop2: + call F_key_scan + call F_key_test + jr c, .loop2 ; carry set = key being pressed call F_poppageA ret @@ -83,36 +88,37 @@ F_keyup ; Get a string from the keyboard, and null terminate. ; Parameters: DE = pointer to memory to store the string. ; C = size of buffer (string length + 1, for the null terminator) -F_inputstring +.globl F_inputstring +F_inputstring: ld b, c ; save length in b ld (v_stringptr), de ; save the pointer ld (v_stringlen), bc ; save the string lengths -.inputloop +.inputloop3: ld a, '_' ; cursor - possible TODO - flashing cursor? call F_putc_5by8 ; display it -.keyloop +.keyloop3: call F_keyup ; wait for keyup before doing anything call F_getkey ; wait for a key to be pressed. push hl ld hl, 0x1000 ; wait some more time so that -.loop ; multi key contacts on Spectrum + / 128 +.loop3: ; multi key contacts on Spectrum + / 128 dec hl ; membranes all make. Use a delay loop ld a, h ; rather than halt so this routine works or l ; with interrupts disabled. - jr nz, .loop + jr nz, .loop3 pop hl call F_getkey ; closed. cp KEY_ENTER ; enter pressed? - jr z, .enter ; handle enter + jr z, .enter3 ; handle enter cp KEY_BACKSPACE ; backspace pressed? - jr z, .backspace ; handle it + jr z, .backspace3 ; handle it cp ' ' ; space - lowest printable character - jp m, .keyloop ; do nothing for non-printable char + jp m, .keyloop3 ; do nothing for non-printable char ex af, af' ld a, (v_stringlen) ; get remaining buffer size back cp 1 ; and if only one byte is left, - jr z, .keyloop ; don't accept more input. + jr z, .keyloop3 ; don't accept more input. call F_backspace ; backspace over the cursor ex af, af' ; get keypress back ld hl, (v_stringptr) ; get current string pointer @@ -123,12 +129,12 @@ F_inputstring ld a, (v_stringlen) ; get the remaining byte count dec a ; decrement it ld (v_stringlen), a ; save remaining length - jr .inputloop ; and wait for the next key. -.backspace + jr .inputloop3 ; and wait for the next key. +.backspace3: ld bc, (v_stringlen) ; is the cursor at the start ld a, c ; of the string? cp b - jr z, .keyloop ; yes - so just wait for another key. + jr z, .keyloop3 ; yes - so just wait for another key. ; To update the screen, the cursor and the character behind ; it must be removed, hence two calls to F_backspace. @@ -139,8 +145,8 @@ F_inputstring ld (v_stringptr), hl ; save it call F_backspace ; remove cursor call F_backspace ; remove last character - jr .inputloop -.enter + jr .inputloop3 +.enter3: call F_keyup ; wait until keyup call F_backspace ; erase the cursor ld hl, (v_stringptr) ; get the string pointer diff --git a/rom/ui_keyscan.asm b/rom/ui_keyscan.asm index d5c19a9..9942ef7 100644 --- a/rom/ui_keyscan.asm +++ b/rom/ui_keyscan.asm @@ -22,8 +22,9 @@ ; ; This file is a slightly modified version of the ZX key scanning routines ; from Matt Westcott's (gasman) Open ZX ROM. -flags2 equ 23658 -key_table +.data +flags2: equ 23658 +key_table: ; mapping from key codes (as returned in E by key_scan) to 'base characters' db "BHY65TGVNJU74RFC" db "MKI83EDX", 0x0e, "LO92WSZ" @@ -31,16 +32,17 @@ key_table ; block 0x8060-$,0 ; table of control codes produced by keys 0-9 in conjunction with caps shift -key_table_caps_digits +key_table_caps_digits: db 0x0c,0x07,0x06,0x04,0x05,0x08,0x0a,0x0b,0x09,0x0f ; 0x026a ; table of symbols / tokens produced by keys A-Z in conjunction with symbol shift -key_table_sym_letters +key_table_sym_letters: db 0xe2, '*', '?', 0xcd, 0xc8, 0xcc, 0xcb, '^' db 0xac, '-', '+', '=', '.', ',', ';', '"' db 0xc7, '<', 0xc3, '>', 0xc5, '/', 0xc9, 0x60, 0xc6, ':' - -key_scan +.text +.globl F_key_scan +F_key_scan: ; scan keyboard, returning key code(s) in DE. ; Numbering rows B-Sp=0, H-En=1, Y-P=2, 6-0=3, 1-5=4, Q-T=5, A-G=6, Cs-V=7, ; key code is rownum + ((5 - bit number) << 3). @@ -53,12 +55,12 @@ key_scan ld de,0xffff ld b,7 ; scan each of 8 rows ld a,0xfe ; with each bit in turn held low -key_scan_row +key_scan_row: push af in a,(0xfe) ld c,a ; pick apart result of IN in register C ld a,0x20 ; count down bit number in A, premultiplied by 8 -key_scan_bit +key_scan_bit: push af rr c jr c,key_scan_bit_done ; if bit is nonzero (-> carry set), key not pressed; move on @@ -67,16 +69,16 @@ key_scan_bit jr nz,key_scan_e_not_vacant ld e,a jr key_scan_bit_done -key_scan_e_not_vacant +key_scan_e_not_vacant: dec e ; e is already occupied; restore value inc d ; check if d register is vacant jr z,key_scan_d_vacant pop hl ; if not, there are too many keys; pop hl ; restore stack and exit with Z reset ret -key_scan_d_vacant +key_scan_d_vacant: ld d,a -key_scan_bit_done +key_scan_bit_done: pop af sub 8 ; if counter in A does not roll over, jr nc,key_scan_bit ; there are bits remaining to check @@ -86,7 +88,7 @@ key_scan_bit_done jr c,key_scan_row ; doesn't fall off the end of A ; keys collected; now handle shifts ld a,d - inc a ; see if d is still 0xff (i.e. only one key) + inc a ; see if d is still 0xff (i.e0. only one key) ret z ; if so, exit with Z set ld a,e cp 0x27 ; check E for caps shift @@ -96,20 +98,21 @@ key_scan_bit_done ld e,d ; if E is caps shift, switch D and E ld d,a ; and exit with Z set ret -key_scan_no_cs +key_scan_no_cs: cp 0x18 ; check E for symbol shift jr nz,key_scan_no_ss ld e,d ; if E is sym shift, switch D and E ld d,a ; and exit with Z set ret -key_scan_no_ss +key_scan_no_ss: ld a,d ; only remaining valid condition is if D is cp 0x18 ; symbol shift; check for this condition and ret ; return with Z flag indicating the result -key_test +.globl F_key_test +F_key_test: ; Test that a successful (zero flag set) response from key_scan is indeed - ; a real key (i.e. not just a shift key on its own). As described by Toni Baker + ; a real key (i.e0. not just a shift key on its own). As described by Toni Baker ; (Mastering Machine Code on your ZX Spectrum, ch11): ; i) B will be made to contain the value formerly held by D ; ii) D will be made to contain zero @@ -126,14 +129,15 @@ key_test ret nc ; return with carry reset if so cp 0x18 ; is low byte 0x18? ret z ; return with carry reset if so -key_test_not_ff +key_test_not_ff: ld hl,key_table add hl,de ld a,(hl) scf ret ; 0x0333 -key_code +.globl F_key_code +F_key_code: ; Convert base character to ASCII code, respecting shifts and current key mode. ; entry: E = base character ; B = shift code (FF, 27 or 18) @@ -157,7 +161,7 @@ key_code add a,0x20 ; otherwise, translate to lower case by adding 0x20 ret -key_code_sshift +key_code_sshift: ld a,e cp '0' ret c ; return keycode unchanged if <'0' (= space or enter) @@ -170,21 +174,21 @@ key_code_sshift jr z,key_code_at ; to make it overly complicated... sub 0x10 ; for all others, just subtract 0x10 to get the resulting ASCII symbol ret -key_code_underline +key_code_underline: ld a,'_' ret -key_code_at +key_code_at: ld a,'@' ret -key_code_sshift_letter +key_code_sshift_letter: ld d,0 ; look up letter in the table key_table_sym_letters ld hl,key_table_sym_letters - 'A' ; fiddle base address of table to count from ASCII 'A' add hl,de ld a,(hl) ret -key_code_cshift +key_code_cshift: ld a,e cp '0' ; return keycode unchanged if <'0' (space, enter or symbol shift); ret c ; NB key code for symbol shift is 0x0E = extend mode, which is correct here diff --git a/rom/ui_output_stub.asm b/rom/ui_output_stub.asm index 7d43b7e..1a3ee14 100644 --- a/rom/ui_output_stub.asm +++ b/rom/ui_output_stub.asm @@ -22,6 +22,10 @@ ; These functions just wrap the character output routines, giving a ; ROM 0 entry point to get to them. +.include "page1.xinc" +.include "sysvars.inc" +.include "sysdefs.inc" +.include "spectranet.inc" ;-------------------------------------------------------------------------- ; F_putc_5by8 @@ -29,7 +33,9 @@ ; The 'core' of the putchar routine, F_print calls this directly (handling ; the paging itself) ; The routine could probably do with improvement. -F_putc_5by8 +.text +.globl F_putc_5by8 +F_putc_5by8: call F_pr_getroutine call F_putc_5by8_impl jp F_pr_restore @@ -37,21 +43,23 @@ F_putc_5by8 ;-------------------------------------------------------------------------- ; F_print: Prints a null terminated string. ; Parameters: HL = pointer to string -F_print -.loop +.globl F_print +F_print: +.loop2: ld a, (hl) and a ; NULL? - jr z, .done + jr z, .done2 call F_putc_5by8 ; print the char inc hl - jr .loop -.done + jr .loop2 +.done2: ret ;-------------------------------------------------------------------------- ; F_clear: Clears the screen to spectranet UI colours. -F_clear +.globl F_clear +F_clear: call F_pr_getroutine call F_clear_impl jp F_pr_restore @@ -59,7 +67,8 @@ F_clear ;-------------------------------------------------------------------------- ; F_backspace: Perform a backspace (move current character position 1 ; back and delete the right most character). -F_backspace +.globl F_backspace +F_backspace: call F_pr_getroutine call F_backspace_impl jp F_pr_restore @@ -67,7 +76,8 @@ F_backspace ;-------------------------------------------------------------------------- ; The following routines just fetch and restore the ROM page where the ; output routines are kept. -F_pr_getroutine +.globl F_pr_getroutine +F_pr_getroutine: push af ld a, (v_pga) ; save page A value ld (v_pr_pga), a @@ -76,7 +86,8 @@ F_pr_getroutine pop af ret -F_pr_restore +.globl F_pr_restore +F_pr_restore: push af ld a, (v_pr_pga) call F_setpageA diff --git a/rom/utility.asm b/rom/utility.asm index 3edb04f..0763ed9 100644 --- a/rom/utility.asm +++ b/rom/utility.asm @@ -19,7 +19,9 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "sysvars.inc" +.include "sysdefs.inc" +.include "page2.xinc" ; A collection of utility functions: ; F_rand16 - Generate a 16-bit random number @@ -29,11 +31,12 @@ ; F_rand16 ; Generate a 16 bit pseudorandom number. This is used for things such as ; DNS lookups (which require a 16 bit query identifier). -; This was adapted from http://map.tni.nl/sources/external/z80bits.html#3.2 +; This was adapted from http://map.tni0.nl0/sources/external/z80bits.html0#3.20 ; which in turn was adapted from a game (not named). ; ; Pseudorandom number is returned in hl. -F_rand16 +.globl F_rand16 +F_rand16: push de push af ld de, (v_seed) @@ -48,9 +51,9 @@ F_rand16 sbc a,d ld e,a sbc hl,de - jr nc, .rand + jr nc, .rand1 inc hl -.rand ld (v_seed),hl +.rand1: ld (v_seed),hl pop af pop de ret @@ -61,7 +64,8 @@ F_rand16 ; long word. Carry set if the string isn't an IP address. ; HL = pointer to string ; DE = pointer to 4 byte buffer for return value -F_ipstring2long +.globl F_ipstring2long +F_ipstring2long: call F_util_getroutine call F_ipstring2long_u_impl jp F_util_restore @@ -71,7 +75,8 @@ F_ipstring2long ; Converts a 4 byte big-endian long word into a null terminated IP string. ; hl = pointer to 4 byte buffer containing the IP address ; de = pointer to a buffer where the IP address string will be returned -F_long2ipstring +.globl F_long2ipstring +F_long2ipstring: call F_util_getroutine call F_long2ipstring_u_impl jp F_util_restore @@ -81,7 +86,8 @@ F_long2ipstring ; Converts the MAC address pointed to by hl to a string ; Parameters: hl - address of MAC address ; de - pointer to string buffer -F_mac2string +.globl F_mac2string +F_mac2string: call F_util_getroutine call F_mac2string_u_impl jp F_util_restore @@ -92,7 +98,8 @@ F_mac2string ; Carry flag is set if the string isn't a MAC address. ; Parameters: hl - address of MAC string ; de - address of 6 byte MAC address buffer -F_string2mac +.globl F_string2mac +F_string2mac: call F_util_getroutine call F_string2mac_u_impl jp F_util_restore @@ -102,7 +109,8 @@ F_string2mac ; Carry flag set on error. Returns value in c. Either a '.' or a null ; terminates the string. (The . being a delimiter in an IP address) ; This routine undoubtedly leaves some room for improvement... -F_atoi8 +.globl F_atoi8 +F_atoi8: call F_util_getroutine call F_itoa8_u_impl jp F_util_restore @@ -113,7 +121,8 @@ F_atoi8 ; a = number to convert ; hl = pointer to string buffer. On exit, hl points to string's end. ; No null terminator is added! -F_itoa8 +.globl F_itoa8 +F_itoa8: call F_util_getroutine call F_itoa8_u_impl jp F_util_restore @@ -123,8 +132,9 @@ F_itoa8 ; Converts an 8 bit number in A to a hex string. ; Parameters: HL - buffer to fill ; This routine is a minor modification of the one at -; http://map.tni.nl/sources/external/z80bits.html -F_itoh8 +; http://map.tni7.nl7/sources/external/z80bits.html7 +.globl F_itoh8 +F_itoh8: call F_util_getroutine call F_itoh8_u_impl jp F_util_restore @@ -134,7 +144,8 @@ F_itoh8 ; Converts the ascii at (hl) and (hl+1) to an int, returned in A. ; carry flag set on error ; Modifies hl, c and a. -F_htoi8 +.globl F_htoi8 +F_htoi8: call F_util_getroutine call F_htoi8_u_impl jp F_util_restore @@ -142,12 +153,13 @@ F_htoi8 ;------------------------------------------------------------------------- ; F_crc16: ; Calculate a 16 bit CRC on an arbitrary region of memory. -; This was adapted from http://map.tni.nl/sources/external/z80bits.html +; This was adapted from http://map.tni9.nl9/sources/external/z80bits.html9 ; Parameters: DE = start address for CRC calculation ; BC = end number of bytes to check ; 16 bit CRC is returned in HL. ; Note: byte counter is modified compared to orginal code. -F_crc16 +.globl F_crc16 +F_crc16: call F_util_getroutine call F_crc16_u_impl jp F_util_restore @@ -157,14 +169,16 @@ F_crc16 ; Checks a ROM page signature for a valid vector table. Returns with the ; Z flag set if the signature is valid, NZ if not. ; Parameters: A = page to test -F_checkromsig +.globl F_checkromsig +F_checkromsig: call F_setpageB ld a, (0x2000) cp 0xAA ret ; Get and restore routines from the utility ROM where we have only stubs. -F_util_getroutine +.globl F_util_getroutine +F_util_getroutine: push af ld a, (v_pgb) ld (v_util_pgb), a @@ -173,7 +187,8 @@ F_util_getroutine pop af ret -F_util_restore +.globl F_util_restore +F_util_restore: push af ld a, (v_util_pgb) call F_setpageB diff --git a/rom/utility_impl.asm b/rom/utility_impl.asm index 0f71445..b554132 100644 --- a/rom/utility_impl.asm +++ b/rom/utility_impl.asm @@ -19,7 +19,7 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "sysvars.inc" ; A collection of utility functions: @@ -29,9 +29,11 @@ ; long word. Carry set if the string isn't an IP address. ; HL = pointer to string ; DE = pointer to 4 byte buffer for return value -F_ipstring2long_u_impl +.text +.globl F_ipstring2long_u_impl +F_ipstring2long_u_impl: ld b, 4 ; number of octets to convert -.loop +.loop1: push bc push de call F_atoi8_u_impl ; convert an octet @@ -43,13 +45,13 @@ F_ipstring2long_u_impl inc de ld hl, (v_stringptr) inc hl ; advance past the '.' - djnz .loop + djnz .loop1 dec hl ; unwind last increment ld a, (hl) and a ; if it's not a null terminator, it's not an IP! - jr nz, .setcarry ; not an IP - there's more to this string. + jr nz, .setcarry1 ; not an IP - there's more to this string. ret -.setcarry +.setcarry1: scf ret @@ -58,10 +60,11 @@ F_ipstring2long_u_impl ; Converts a 4 byte big-endian long word into a null terminated IP string. ; hl = pointer to 4 byte buffer containing the IP address ; de = pointer to a buffer where the IP address string will be returned -F_long2ipstring_u_impl +.globl F_long2ipstring_u_impl +F_long2ipstring_u_impl: ex de, hl ld b, 3 ; 3 octets separated by '.' (last has a null) -.loop +.loop2: ld a, (de) push bc call F_itoa8_u_impl ; convert byte to string (not null terminated) @@ -70,7 +73,7 @@ F_long2ipstring_u_impl ld (hl), a ; insert point inc hl inc de - djnz .loop + djnz .loop2 ld a, (de) call F_itoa8_u_impl ld (hl), 0 ; null terminator @@ -81,16 +84,17 @@ F_long2ipstring_u_impl ; Converts the MAC address pointed to by hl to a string ; Parameters: hl - address of MAC address ; de - pointer to string buffer -F_mac2string_u_impl +.globl F_mac2string_u_impl +F_mac2string_u_impl: ex de, hl ld b, 5 ; MAC is 6 bytes long, handle first 5 -.loop +.loop3: ld a, (de) call F_itoh8_u_impl ld (hl), ':' ; replace NULL with : inc hl inc de - djnz .loop + djnz .loop3 ld a, (de) call F_itoh8_u_impl ; last byte, so we have a NULL rather than : ret @@ -101,16 +105,17 @@ F_mac2string_u_impl ; Carry flag is set if the string isn't a MAC address. ; Parameters: hl - address of MAC string ; de - address of 6 byte MAC address buffer -F_string2mac_u_impl +.globl F_string2mac_u_impl +F_string2mac_u_impl: ld b, 6 -.loop +.loop4: call F_htoi8_u_impl ret c ; non hex digit encounter ld (de), a inc de inc hl inc hl ; go past the separator - djnz .loop + djnz .loop4 ret ;----------------------------------------------------------------------- @@ -118,27 +123,28 @@ F_string2mac_u_impl ; Carry flag set on error. Returns value in c. Either a '.' or a null ; terminates the string. (The . being a delimiter in an IP address) ; This routine undoubtedly leaves some room for improvement... -F_atoi8_u_impl +.globl F_atoi8_u_impl +F_atoi8_u_impl: ; go to end of string ld b, 0 -.endloop +.endloop5: ld a, (hl) and a - jr z, .endstring + jr z, .endstring5 cp '.' - jr z, .endstring + jr z, .endstring5 inc hl inc b - jr .endloop -.endstring + jr .endloop5 +.endstring5: ld (v_stringptr), hl ; save pointer to string end ld a, b cp 4 - jp p, .error + jp p, .error5 ; empty string - return with carry set and a - jr z, .error + jr z, .error5 ; units dec hl ; point at last char of string @@ -174,17 +180,17 @@ F_atoi8_u_impl ld a, (hl) sub '0' cp 3 - jp p, .error ; hundreds >=3 won't fit in a byte + jp p, .error5 ; hundreds >=3 won't fit in a byte ld b, a xor a -.hundred +.hundred5: add a, 100 - djnz .hundred + djnz .hundred5 add a, c ; add to result so far ld c, a ret -.error +.error5: scf ret @@ -194,19 +200,20 @@ F_atoi8_u_impl ; a = number to convert ; hl = pointer to string buffer. On exit, hl points to string's end. ; No null terminator is added! -F_itoa8_u_impl +.globl F_itoa8_u_impl +F_itoa8_u_impl: ld b, -100 - call .conv1 + call .conv16 ld b, -10 - call .conv1 + call .conv16 ld b, -1 -.conv1 +.conv16: ld c, '0'-1 -.conv2 +.conv26: inc c add a, b - jr c, .conv2 + jr c, .conv26 sbc a, b ld (hl), c inc hl @@ -217,25 +224,26 @@ F_itoa8_u_impl ; Converts an 8 bit number in A to a hex string. ; Parameters: HL - buffer to fill ; This routine is a minor modification of the one at -; http://map.tni.nl/sources/external/z80bits.html -F_itoh8_u_impl +; http://map.tni6.nl6/sources/external/z80bits.html6 +.globl F_itoh8_u_impl +F_itoh8_u_impl: push af push bc ld b, a - call .Num1 + call .Num17 ld a, b - call .Num2 + call .Num27 xor a ld (hl), a ; add null pop bc pop af ret -.Num1 rra +.Num17: rra rra rra rra -.Num2 or 0xF0 +.Num27: or 0xF0 daa add a,0xA0 adc a,0x40 @@ -249,15 +257,16 @@ F_itoh8_u_impl ; Converts the ascii at (hl) and (hl+1) to an int, returned in A. ; carry flag set on error ; Modifies hl, c and a. -F_htoi8_u_impl +.globl F_htoi8_u_impl +F_htoi8_u_impl: ld a, (hl) sub '0' cp 0x0A ; greater than digit 9? - jr c, .next + jr c, .next8 sub 'A'-'0'-10 ; A-F part cp 0x10 ; out of range? - jr nc, .err -.next + jr nc, .err8 +.next8: or a ; clear carry rla ; shift into upper nibble rla @@ -268,14 +277,14 @@ F_htoi8_u_impl ld a, (hl) ; next digit sub '0' cp 0x0A - jr c, .next1 + jr c, .next18 sub 'A'-'0'-10 ; A-F cp 0x10 - jr nc, .err -.next1 + jr nc, .err8 +.next18: or c ; merge in high nibble ret -.err +.err8: ccf ; carry flag = error ret @@ -283,35 +292,36 @@ F_htoi8_u_impl ;------------------------------------------------------------------------- ; F_crc16: ; Calculate a 16 bit CRC on an arbitrary region of memory. -; This was adapted from http://map.tni.nl/sources/external/z80bits.html +; This was adapted from http://map.tni8.nl8/sources/external/z80bits.html8 ; Parameters: DE = start address for CRC calculation ; BC = end number of bytes to check ; 16 bit CRC is returned in HL. ; Note: byte counter is modified compared to orginal code. -F_crc16_u_impl +.globl F_crc16_u_impl +F_crc16_u_impl: ld hl, 0xFFFF -.read +.read9: push bc ; save byte counter ld a,(de) inc de xor h ld h,a ld b,8 -.crcbyte +.crcbyte9: add hl,hl - jr nc, .next + jr nc, .next9 ld a,h xor 0x10 ld h,a ld a,l xor 0x21 ld l,a -.next - djnz .crcbyte +.next9: + djnz .crcbyte9 pop bc ; get back the byte counter dec bc ld a, b ; and see if it's got to zero or c - jr nz, .read + jr nz, .read9 ret diff --git a/rom/utilnmi.asm b/rom/utilnmi.asm index cb38bbb..d96a607 100644 --- a/rom/utilnmi.asm +++ b/rom/utilnmi.asm @@ -19,19 +19,25 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.include "ctrlchars.inc" +.include "sockdefs.inc" ; Utility ROM - NMI handler -F_nmihandler +.text +.globl F_nmihandler +F_nmihandler: call F_savescreen ; save frame buffer contents call F_detectpages ; Detect 128K mode and value of port 0x7ffd ld a, (v_machinetype) cp 1 ; 128K machine? - jr nz, .menuloop ; If not, continue + jr nz, .menuloop1 ; If not, continue ld a, (v_port7ffd) ; If so, make sure the normal screen res 3, a ; is in use. ld bc, 0x7ffd out (c), a -.menuloop +.menuloop1: ld a, 7 out (254), a ; border = white call CLEAR42 @@ -41,7 +47,7 @@ F_nmihandler call F_genmenu ld hl, MENU_nmi call F_getmenuopt ; act on user keypress - jr nz, .menuloop ; routines set Z if they want to exit + jr nz, .menuloop1 ; routines set Z if they want to exit call F_restorescreen ld a, (v_port7ffd) ; Restore port 0x7FFD @@ -55,7 +61,8 @@ F_nmihandler ;------------------------------------------------------------------------- ; F_savescreen ; Save the current Spectrum frame buffer into our static memory. -F_savescreen +.globl F_savescreen +F_savescreen: ld bc, CTRLREG ; save border colour in a, (c) and 7 @@ -78,7 +85,8 @@ F_savescreen ;--------------------------------------------------------------------------- ; F_restorescreen ; Restore the Spectrum framebuffer. -F_restorescreen +.globl F_restorescreen +F_restorescreen: ld a, 0xDA call SETPAGEA ld hl, 0x1000 @@ -96,7 +104,8 @@ F_restorescreen ;--------------------------------------------------------------------- ; F_config ; Invokes the configuration program -F_config +.globl F_config +F_config: ld hl, 0xFE00 ; module FE (configuration) call 0x00 rst MODULECALL_NOPAGE ret @@ -105,35 +114,43 @@ F_config ; F_rom ; Invokes the ROM module utility. This is stored in page 0x01 of flash ; as a binary object. -F_rom +.globl F_rom +F_rom: ld a, 0x01 call SETPAGEA ; this utility's executable code is in the ld hl, ROMMODCONF_START ; data ROM, so page it in and copy it from ld de, 0x3000 ; 0x1000 to 0x3000. - ld bc, ROMMODCONF_END - ROMMODCONF_START + ld bc, ROMMODCONF_LEN ldir call 0x3000 ; call it or 1 ; reset Z ret +.data +ROMMODCONF_START: +.incbin "modman.bin" +ROMMODCONF_LEN equ $-ROMMODCONF_START + +.text ;----------------------------------------------------------------------- ; F_loader ; Loads some data into RAM. -F_loader +.globl F_loader +F_loader: call CLEAR42 ld c, SOCK_STREAM ; open a TCP socket call SOCKET ; file descriptor in A - jp c, .borked ; or c set if failed + jp c, .borked6 ; or c set if failed ld (v_sockfd), a ; save the fd ld de, 2000 ; port 2000 call BIND ; bind to the port - jp c, .borked + jp c, .borked6 ld a, (v_sockfd) ; socket we want to listen on call LISTEN ; listen - jr c, .borked + jr c, .borked6 ; Display an informative message to the user showing the ; IP and port we are listening on. @@ -152,7 +169,7 @@ F_loader ; Wait for a connection. ld a, (v_sockfd) call ACCEPT ; block until something connects - jr c, .borked + jr c, .borked6 ld (v_connfd), a ; save the connection file descriptor ; Get the first 4 bytes which contains the start address and @@ -164,16 +181,16 @@ F_loader ; Receive the data. ld de, (buf_workspace) ; current address to write to -.recvloop +.recvloop6: ld a, (v_connfd) ld bc, 1024 ; receive up to 1K at a time call RECV - jr c, .borked + jr c, .borked6 ld hl, (buf_workspace+2) ; get remaining length sbc hl, bc ld a, h ; are we done yet? or l - jr z, .recvdone + jr z, .recvdone6 ld (buf_workspace+2), hl ; save remaining length ld hl, (buf_workspace) ; get current pointer add hl, bc ; increment it @@ -181,32 +198,33 @@ F_loader ex de, hl ld a, '.' ; progress marker call PUTCHAR42 - jr .recvloop ; get the next block -.recvdone + jr .recvloop6 ; get the next block +.recvdone6: ld a, (v_connfd) ; close the connection call CLOSE ld a, (v_sockfd) call CLOSE -.keymsg +.keymsg6: ld hl, STR_xtoexit call PRINT42 -.waitforkey ; wait for a key so the user has a chance +.waitforkey6: ; wait for a key so the user has a chance call GETKEY ; to see what happened. cp 'x' ; press 'x' to exit - jr nz, .waitforkey + jr nz, .waitforkey6 or 1 ; ensure zero flag is cleared ret -.borked +.borked6: ld hl, buf_workspace call ITOH8 ld hl, STR_borked call PRINT42 ld hl, buf_workspace call PRINT42 - jr .keymsg + jr .keymsg6 ; internal function for the above - print info of what's being tx'd to us. -F_printxfinfo +.globl F_printxfinfo +F_printxfinfo: ld hl, STR_est call PRINT42 ld hl, STR_start @@ -218,7 +236,7 @@ F_printxfinfo call ITOH8 ld hl, buf_workspace+4 call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ld hl, STR_len call PRINT42 @@ -229,11 +247,12 @@ F_printxfinfo call ITOH8 ld hl, buf_workspace+4 call PRINT42 - ld a, '\n' + ld a, NEWLINE call PUTCHAR42 ret -F_snapshot +.globl F_snapshot +F_snapshot: ld hl, 0xFB00 ; ROM ID 0xFB call 0x00 rst MODULECALL_NOPAGE ret @@ -241,11 +260,12 @@ F_snapshot ;--------------------------------------------------------------------- ; F_exit ; A very short routine for the menu to be able to set the zero flag. -F_exit +.globl F_exit +F_exit: xor a ; set zero flag ret -MENU_nmi +MENU_nmi: defw STR_config,F_config defw STR_rom,F_rom defw STR_loader,F_loader diff --git a/rom/utilnmi_en.asm b/rom/utilnmi_en.asm index c29397e..e902a14 100644 --- a/rom/utilnmi_en.asm +++ b/rom/utilnmi_en.asm @@ -19,22 +19,37 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "ctrlchars.inc" ; English NMI menu strings - -STR_config defb "Configure network settings",0 -STR_rom defb "Add and remove ROM modules",0 -STR_loader defb "Load arbitrary data to RAM",0 -STR_snapshot defb "Take snapshot",0 -STR_exit defb "Exit",0 -STR_nmimenu defb "Spectranet NMI menu\n\n",0 -STR_send defb "Listening on ",0 -STR_port defb " port 2000\n",0 -STR_start defb " Start: ",0 -STR_len defb "Length: ",0 -STR_xtoexit defb "\nPress 'x' to exit.\n",0 -STR_borked defb "\nOperation failed with rc=",0 -STR_est defb "Connection established\n",0 -STR_ident defb "Spectranet utility ROM",0 +.data +.globl STR_config +STR_config: defb "Configure network settings",0 +.globl STR_rom +STR_rom: defb "Add and remove ROM modules",0 +.globl STR_loader +STR_loader: defb "Load arbitrary data to RAM",0 +.globl STR_snapshot +STR_snapshot: defb "Take snapshot",0 +.globl STR_exit +STR_exit: defb "Exit",0 +.globl STR_nmimenu +STR_nmimenu: defb "Spectranet NMI menu",NEWLINE,NEWLINE,0 +.globl STR_send +STR_send: defb "Listening on ",0 +.globl STR_port +STR_port: defb " port 2000",NEWLINE,0 +.globl STR_start +STR_start: defb " Start: ",0 +.globl STR_len +STR_len: defb "Length: ",0 +.globl STR_xtoexit +STR_xtoexit: defb NEWLINE,"Press 'x' to exit.",NEWLINE,0 +.globl STR_borked +STR_borked: defb NEWLINE,"Operation failed with rc=",0 +.globl STR_est +STR_est: defb "Connection established",NEWLINE,0 +.globl STR_ident +STR_ident: defb "Spectranet utility ROM",0 diff --git a/rom/utilromvectors.asm b/rom/utilromvectors.asm index ff3f206..c420e31 100644 --- a/rom/utilromvectors.asm +++ b/rom/utilromvectors.asm @@ -19,7 +19,7 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.section vectors ; The Utility ROM vector table defb 0xAA defb 0x01 ; ROM ID 0x01 diff --git a/rom/vfs.asm b/rom/vfs.asm index 620dc1d..28089aa 100644 --- a/rom/vfs.asm +++ b/rom/vfs.asm @@ -57,10 +57,15 @@ ; For functions that are not implemented, an address to a short routine ; that sets the carry flag and makes A the appropriate return code should ; be provided. - include "moduledefs.asm" +.include "moduledefs.inc" +.include "sysvars.inc" +.include "sysdefs.inc" +.include "sockdefs.inc" + ;---------------------------------------------------------------------------- ; Dispatcher routines. -F_fd_dispatch +.globl F_fd_dispatch +F_fd_dispatch: ex (sp), hl ; fetch return address, saving HL push de ld d, 0x3F ; point DE at memory address containing @@ -71,14 +76,15 @@ F_fd_dispatch jr nz, J_notopen ld de, FDVECBASE ; set base address of the descriptor table jr F_dispatch -J_notopen +J_notopen: pop de pop hl - ld a, 0x06 ; TODO: errno.asm - EBADF + ld a, 0x06 ; TODO: errno.asm1 - EBADF scf ret -F_vfs_dispatch +.globl F_vfs_dispatch +F_vfs_dispatch: call F_cleanpath ; remove leading/trailing space call F_resolvemp ; See if a mount point is specified ex (sp), hl @@ -90,15 +96,16 @@ F_vfs_dispatch ld a, (de) and a ; not mounted if the VFS ROM no. was 0 jr nz, F_dispatch_3 -.notmounted +.notmounted2: pop af ; fix the stack pop de pop hl - ld a, 0x23 ; TODO: errno.asm + ld a, 0x23 ; TODO: errno.asm2 scf ret -F_dir_dispatch +.globl F_dir_dispatch +F_dir_dispatch: ex (sp), hl push de ld d, 0x3F ; point DE at the address containing @@ -115,20 +122,25 @@ F_dir_dispatch ; F_dispatch ; Find the appropriate ROM page for the file (or whatever) descriptor, ; and fetch the jump address from the jump table within. -F_dispatch_notfd +.globl F_dispatch_notfd +F_dispatch_notfd: push af jr F_dispatch_1 -F_dispatch +.globl F_dispatch +F_dispatch: push af sub FDBASE%256 -F_dispatch_1 +.globl F_dispatch_1 +F_dispatch_1: add a, e ; Calculate the address in the fd table -F_dispatch_2 +.globl F_dispatch_2 +F_dispatch_2: ld e, a ; make DE point to it ld a, (de) ; get the ROM to page and a ; ROM 0 is handled specially jr z, isasocket -F_dispatch_3 +.globl F_dispatch_3 +F_dispatch_3: ex af, af' ; save AF while copying the current page ld a, (v_pgb) ; save current page ld (v_vfspgb_vecsave), a @@ -152,38 +164,38 @@ F_dispatch_3 ; If someone access a socket via read/write rather than send/recv ; it's handled here. There are only four functions that can be done to ; a socket via the VFS interface. -isasocket +isasocket: ld a, 0xCC ; Check for READ. Note the LSB addresses cp l ; are +3 on the actual (because CALL put - jr z, .sockread ; the return address, not the actual + jr z, .sockread8 ; the return address, not the actual ld a, 0xCF ; address on the stack!) cp l - jr z, .sockwrite + jr z, .sockwrite8 ld a, 0xD8 ; POLL cp l - jr z, .sockpoll + jr z, .sockpoll8 ld a, 0xD5 ; CLOSE - jr nz, .badcall + jr nz, .badcall8 pop af pop de pop hl jp F_sockclose -.sockread +.sockread8: pop af pop de pop hl jp F_recv -.sockwrite +.sockwrite8: pop af pop de pop hl jp F_send -.sockpoll +.sockpoll8: pop af pop de pop hl jp F_pollfd -.badcall +.badcall8: pop af pop de pop hl @@ -206,15 +218,16 @@ isasocket ; - If the protocol is supported, mount the FS and return with Z and C reset ; - If the proto is supported, but the FS can't be mounted, return with C set ; - If the proto is not recognised, return with Z set -F_mount +.globl F_mount +F_mount: ; First search for a ROM that handles this protocol. ld (v_mountnumber), a ; save device number ld hl, vectors -.findrom +.findrom9: ld a, (hl) ; get ROM ID and a ; check for the terminator - jr z, .notfound ; no ROM found that handles this protocol -.testproto + jr z, .notfound9 ; no ROM found that handles this protocol +.testproto9: push hl ; save current vector table address ld a, l sub ROMVECOFFS ; subtract the base addr to get the ROM slot @@ -224,38 +237,38 @@ F_mount ld a, h ; H must be 0x20-0x2F for a valid MOUNT routine and 0xF0 ; mask out low nibble cp 0x20 ; result should be 0x20 for valid MOUNT - jr nz, .testnext - ld de, .return ; simulate CALL instruction with JP (HL) + jr nz, .testnext9 + ld de, .return9 ; simulate CALL instruction with JP (HL) push de ld a, (v_mountnumber) jp (hl) -.return - jr c, .mountfailed ; Tried but failed to mount? - jr z, .testnext ; Protocol is not ours? +.return9: + jr c, .mountfailed9 ; Tried but failed to mount? + jr z, .testnext9 ; Protocol is not ours? call F_poppageB ; restore original page B ld a, (v_mountnumber) ; get device number - add VFSVECBASE%256 ; and calculate the address in sysvars + add a, VFSVECBASE%256 ; and calculate the address in sysvars ld h, 0x3F ; MSB of the sysvars area ld l, a ; LSB - HL now has the addr of the fs table pop af ; restore ROM page number ld (hl), a ; Put the ROM number in the filesystem table pop hl ; restore the stack ret -.testnext +.testnext9: call F_poppageB ; restore stack pop af ; ROM slot number pop hl ; table pointer inc l ; and point it to the next ROM list entry - jr .findrom + jr .findrom9 -.mountfailed +.mountfailed9: ex af, af' call F_poppageB ; restore stack and page pop af ; unwind stack pop hl ; restore HL ex af, af' ret -.notfound +.notfound9: ld a, 0xFE ; TODO: proper return code here scf ret @@ -263,8 +276,9 @@ F_mount ;-------------------------------------------------------------------------- ; F_freemountpoint ; Frees a mount point, passed in A -F_freemountpoint - add VFSVECBASE % 256 ; calculate the address in sysvars +.globl F_freemountpoint +F_freemountpoint: + add a, VFSVECBASE % 256 ; calculate the address in sysvars ld h, 0x3F ; sysvars page ld l, a ld (hl), 0 ; clear it down @@ -273,7 +287,8 @@ F_freemountpoint ;-------------------------------------------------------------------------- ; F_setmountpoint ; Sets the default mountpoint in use, passed in A -F_setmountpoint +.globl F_setmountpoint +F_setmountpoint: cp 4 ; mount point must be <= 3 ccf ; flip the carry flag ret c ; so if there's an error we return with C @@ -287,7 +302,8 @@ F_setmountpoint ; Flags in C ; C bit 0 = Set=Allocate, reset=free ; C bit 1 = Set=Directory, reset=File -F_resalloc +.globl F_resalloc +F_resalloc: bit 1, c jr nz, F_allocdirhnd ;-------------------------------------------------------------------------- @@ -297,26 +313,27 @@ F_resalloc ; On return HL = address of fd. Functions that use this should set this ; to a value that means something (and bit 7 must be reset). L = actual ; fd number. -F_allocfd +.globl F_allocfd +F_allocfd: bit 0, c jr z, F_freefd push bc ld hl, v_fd1hwsock ; lowest address in fd table ld b, MAX_FDS -.findloop +.findloop13: bit 7, (hl) ; not allocated yet? - jr nz, .alloc + jr nz, .alloc13 inc l - djnz .findloop ; keep looking until none left + djnz .findloop13 ; keep looking until none left scf ; out of free file descriptors pop bc ret -.alloc +.alloc13: res 7, (hl) ; basic allocation push hl ; save FD address and FD number ld b, a ; save parameter ld a, l - add VECOFFS ; find the address of the vector table + add a, VECOFFS ; find the address of the vector table ld l, a ; and make HL point to it ld a, b ; retrieve param ld (hl), a ; set vector table page address @@ -327,13 +344,14 @@ F_allocfd ;------------------------------------------------------------------------- ; F_freefd ; Frees the file descriptor passed in A. -F_freefd +.globl F_freefd +F_freefd: push hl push af ld h, v_fd1hwsock / 256 ld l, a ld (hl), 0x80 ; Set bit 7 to mark the fd as freed. - add VECOFFS ; add the vector table offset + add a, VECOFFS ; add the vector table offset ld l, a ; and point HL to it ld (hl), 0x00 ; clear it down pop af @@ -345,23 +363,24 @@ F_freefd ; Allocates a directory handle. ; Parameters A = ROM number for the handle ; On return HL = address of the handle, L is the handle itself -F_allocdirhnd +.globl F_allocdirhnd +F_allocdirhnd: bit 0, c jr z, F_freedirhnd push bc ld hl, v_dhnd1page ld b, MAX_DIRHNDS ex af, af' -.findloop +.findloop15: ld a, (hl) and a ; 0 = free - jr z, .alloc + jr z, .alloc15 inc l - djnz .findloop + djnz .findloop15 scf ; all are used up pop bc ret -.alloc +.alloc15: ex af, af' ld (hl), a ; allocate it by setting the page number pop bc @@ -370,7 +389,8 @@ F_allocdirhnd ;----------------------------------------------------------------------- ; F_freedirhnd ; Frees the directory handle passed in A -F_freedirhnd +.globl F_freedirhnd +F_freedirhnd: push hl ld h, v_dhnd1page / 256 ld l, a @@ -385,24 +405,25 @@ F_freedirhnd ; is ^[0-3]: in regexp terms. ; HL = pointer to the string. ; Returns with A = mount point handle. -F_resolvemp +.globl F_resolvemp +F_resolvemp: push hl inc hl ; check for the : ld a, (hl) cp ':' - jr nz, .returncurrent ; Return the current mount point. + jr nz, .returncurrent17 ; Return the current mount point. dec hl ld a, (hl) ; Get the putative FS number sub '0' ; Subtract ascii '0' to make the actual number - jr c, .returncurrent + jr c, .returncurrent17 cp 4 ; Greater than 3? - jr nc, .returncurrent + jr nc, .returncurrent17 pop hl inc hl ; effectively strip off the "n:" inc hl ret -.returncurrent +.returncurrent17: pop hl ld a, (v_vfs_curmount) ret @@ -410,20 +431,21 @@ F_resolvemp ;---------------------------------------------------------------------- ; F_cleanpath ; Gets rid of leading/trailing white spaces -F_cleanpath +.globl F_cleanpath +F_cleanpath: push hl ld bc, 256 xor a cpir ; find the argument's end dec hl ; end - 1 -.spaceloop +.spaceloop18: dec hl ld a, (hl) cp ' ' - jr nz, .done + jr nz, .done18 ld (hl), 0 ; remove trailing white space - jr .spaceloop -.done + jr .spaceloop18 +.done18: pop hl ret diff --git a/rom/w5100_buffer.asm b/rom/w5100_buffer.asm index 789339f..213ffd8 100644 --- a/rom/w5100_buffer.asm +++ b/rom/w5100_buffer.asm @@ -19,7 +19,9 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "w5100_defs.inc" +.include "sysvars.inc" +.include "sockdefs.inc" ; Copy from rx buffer and copy into txbuffer. ; These routines assume 2K buffers for both tx and rx (so they don't bother @@ -41,7 +43,9 @@ ; BC = size of destination buffer ; On return BC = bytes copied ; Unchanged IX, IY, shadow registers -F_copyrxbuf +.text +.globl F_copyrxbuf +F_copyrxbuf: ; check whether page A is being used. ; (note: will use page B if this is the case) call F_checkpageA @@ -55,41 +59,41 @@ F_copyrxbuf ; checking the RX interrupt flag but RSR is still zero. ; The datasheet doesn't of course guarantee that the socket ; is actually ready to read even if the interrupt is set :-) -.testzero +.testzero1: ld l, Sn_RX_RSR0 % 256 ; (hl) = RSR's MSB ld d, (hl) inc l ld e, (hl) ld a, d or e - jr nz, .continue + jr nz, .continue1 ; note that if there's a buffer to unload, unload it. Only ; check for RST when there's no data pending. ld l, Sn_IR % 256 ; point hl at the IR, test for CONNRESET bit BIT_IR_DISCON, (hl) jp nz, J_resetbypeer_pop - jr .testzero + jr .testzero1 -.continue +.continue1: ; check whether it exceeds the buffer. If so just use value of ; BC as number of bytes to copy. If not, use the RSR as number ; of bytes to copy. ld a, b ; MSB of length of our buffer cp d ; MSB of RSR - jr c, .findoffset ; RSR > buffer - jr nz, .setlen ; RSR < buffer, set actual length to RSR + jr c, .findoffset1 ; RSR > buffer + jr nz, .setlen1 ; RSR < buffer, set actual length to RSR ld a, c ; LSB of RSR cp e ; LSB of length of our buffer - jr c, .findoffset ; RSR > buffer len + jr c, .findoffset1 ; RSR > buffer len ; BC now should equal actual size to copy -.setlen +.setlen1: ld b, d ld c, e ; de = offset when were are done here. -.findoffset +.findoffset1: ld l, Sn_RX_RD0 % 256 ; RX read pointer register for socket ld a, (hl) ; MSB of RX offset and gSn_RX_MASK / 256 ; mask with 0x07 @@ -98,39 +102,39 @@ F_copyrxbuf ld e, (hl) ; page in the correct bit of W5100 buffer memory -.setpage +.setpage1: ld (v_sockptr), hl ; Save the current socket register pointer ld a, h sub Sn_MR / 256 ; derive socket number bit 1, a ; upper page or lower page? - jr nz, .upperpage + jr nz, .upperpage1 ld a, RX_LWRDATAPAGE ; W5100 phys. address 0x6000 call F_setpageA - jr .willitblend -.upperpage + jr .willitblend1 +.upperpage1: ld a, RX_UPRDATAPAGE ; W5100 phys. address 0x7000 call F_setpageA ; Does the circular buffer wrap around? -.willitblend - dec bc ; ...to check for >, not >= +.willitblend1: + dec bc ; ...to1 check for >, not >= ld h, d ; not ex hl, de because we need to preserve it ld l, e add hl, bc inc bc ; undo previous dec ld a, h cp 0x08 ; Does copy go over 2k boundary? - jp p, .wrappedcopy ; The circular buffer wraps. + jp p, .wrappedcopy1 ; The circular buffer wraps. ; A straight copy from the W5100 buffer to our memory. -.straightcopy +.straightcopy1: ld hl, (v_sockptr) ; retrieve socket register pointer call F_getbaseaddr ; hl now = source address pop de ; retrieve destination address ld (v_copylen), bc ; preserve length ldir ; copy buffer contents -.completerx +.completerx1: ld a, REGPAGE ; Registers are in W5100 physmem 0x0000 call F_setpageA ld hl, (v_sockptr) ; retrieve socket pointer @@ -157,7 +161,7 @@ F_copyrxbuf ; Stack contains the destination address ; BC contains length to copy ; DE contains offset -.wrappedcopy +.wrappedcopy1: ld (v_copylen), bc ; save length ld hl, 0x0800 ; the highest offset you can have sbc hl, de ; hl = how many bytes before we hit the end @@ -178,7 +182,7 @@ F_copyrxbuf ld c, l pop hl ; retrieve address ldir ; transfer remainder - jr .completerx ; done + jr .completerx1 ; done ;============================================================================ ; F_copytxbuf: @@ -193,32 +197,33 @@ F_copyrxbuf ; Notes: If sending >2k of data, data should only be fed into this routine ; in chunks of <=2k a time or it'll hang. The socket library's send() ; call should do this. -F_copytxbuf +.globl F_copytxbuf +F_copytxbuf: ; check whether page A is being used. ; (note: will use page B if this is the case) call F_checkpageA -.waitformsb +.waitformsb2: ld l, Sn_IR % 256 ; point hl at the IR, test for CONNRESET bit BIT_IR_DISCON, (hl) jp nz, J_resetbypeer ld l, Sn_TX_FSR0 % 256 ; point hl at free space register ld a, b ; MSB of argment cp (hl) ; compare with FSR - jr c, .getoffset ; definitely enough free space - jr nz, .waitformsb ; Buffer MSB > FSR MSB + jr c, .getoffset2 ; definitely enough free space + jr nz, .waitformsb2 ; Buffer MSB > FSR MSB ; Buffer MSB = FSR MSB, check LSB value inc l ; (hl) = LSB of hw register -.waitforlsb +.waitforlsb2: ld l, Sn_IR % 256 ; point hl at the IR, test for CONNRESET bit BIT_IR_DISCON, (hl) jp nz, J_resetbypeer ld l, Sn_TX_FSR0 % 256 ; point hl at free space register ld a, (hl) ; get LSB of FSR cp c ; and compare with LSB of passed value - jr c, .waitforlsb ; if C > (hl) wait until it's not. + jr c, .waitforlsb2 ; if C > (hl) wait until it's not. -.getoffset +.getoffset2: ld (v_sockptr), hl ; save the socket register pointer ld (v_copylen), bc ; save the buffer length push de ; save the source buffer pointer @@ -232,38 +237,38 @@ F_copytxbuf ; page in the correct bit of W5100 buffer memory. TX buffer for ; socket 0 and 1 in page 0x0104 and for 2 and 3 in 0x0105, mapping ; socket 0 and 2 to 0x1000, 1 and 3 to 0x1800. -.setpage +.setpage2: ld a, h sub Sn_MR / 256 ; derive socket number bit 1, a ; upper page or lower page? - jr nz, .upperpage + jr nz, .upperpage2 ld a, TX_LWRDATAPAGE ; W5100 phys. address 0x4000 call F_setpageA - jr .willitblend -.upperpage + jr .willitblend2 +.upperpage2: ld a, TX_UPRDATAPAGE ; W5100 phys. address 0x5000 call F_setpageA ; add de (offset) and bc (length) and see if it's >0x0800, in ; which case buffer copy needs to wrap. -.willitblend - dec bc ; ...to check for >, not >= +.willitblend2: + dec bc ; ...to2 check for >, not >= ld h, d ; not ex hl, de because we need to preserve it ld l, e add hl, bc inc bc ; undo previous dec ld a, h cp 0x08 ; Does copy go over 2k boundary? - jp p, .wrappedcopy ; The circular buffer wraps. + jp p, .wrappedcopy2 ; The circular buffer wraps. -.straightcopy +.straightcopy2: ld hl, (v_sockptr) ; restore socket pointer call F_getbaseaddr ex de, hl ; for LDIR pop hl ; get stacked source address ldir -.completetx +.completetx2: ld a, REGPAGE ; registers in W5100 phys. 0x0000 call F_setpageA ld hl, (v_sockptr) ; get the socket pointer back @@ -285,7 +290,7 @@ F_copytxbuf jp nz, F_setpageB ; yes - restore page B and return. ret ; no, return. -.wrappedcopy +.wrappedcopy2: ld hl, 0x0800 ; the highest offset you can have sbc hl, de ; hl = how many bytes before we hit the end ld (v_copied), hl ; save it @@ -306,11 +311,11 @@ F_copytxbuf ld c, l pop hl ; retrieve source buffer ptr ldir ; transfer remainder - jr .completetx ; done + jr .completetx2 ; done -J_resetbypeer_pop +J_resetbypeer_pop: pop de -J_resetbypeer +J_resetbypeer: ld a, (v_buf_pgb) ; check to see whether to re-page area B and a ; zero? call nz, F_setpageB ; yes - restore page B and return. @@ -324,7 +329,8 @@ J_resetbypeer ; On entry: de = offset ; h = high order of socket register address ; On exit: hl = base address -F_getbaseaddr +.globl F_getbaseaddr +F_getbaseaddr: ld l, 0 ld a, h sub Sn_BASE ; a = 0x10 for skt 0, 0x11 for skt 1, 0x12 etc. @@ -336,12 +342,12 @@ F_getbaseaddr ; 0x1000-0x1FFF, so the physical address should either end up ; being 0x1000 (skt 0 and 2) or 0x1800 (skt 1 and 3) bit 0, a ; bit 0 set = odd numbered socket at 0x1800 - jr nz, .oddsock + jr nz, .oddsock3 ld h, a add hl, de ; hl = physical address ret -.oddsock - add 0x07 ; odd sockets are 0x18xx addresses +.oddsock3: + add a, 0x07 ; odd sockets are 0x18xx addresses ld h, a add hl, de ret @@ -349,15 +355,16 @@ F_getbaseaddr ;========================================================================= ; F_checkpageA ; On entry: DE = buffer start -F_checkpageA +.globl F_checkpageA +F_checkpageA: ld a, d and 0xF0 ; mask off top 4 bits cp 0x10 ; are we in 0x1000 - 0x1FFF? - jr z, .swappages ; yes, swap pages. + jr z, .swappages4 ; yes, swap pages. xor a ; reset the sysvar ld (v_buf_pgb), a ret -.swappages +.swappages4: ld a, d xor 0x30 ; flip bits 4 and 5 to convert 0x1xxx to 0x2xxx ld d, a diff --git a/rom/w5100_defines.asm b/rom/w5100_defines.asm deleted file mode 100644 index 2019ff2..0000000 --- a/rom/w5100_defines.asm +++ /dev/null @@ -1,211 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - - - ; Assumptions: The W5100 is paged into paging area A (0x1000) - ; for register manipulation. - ; Register definitions for the W5100. Offset by 0x1000 bytes. - - ; Common registers. - define MR 0x1000 ; Mode register - define GAR0 0x1001 ; Gateway addr first octet - define GAR1 0x1002 - define GAR2 0x1003 - define GAR3 0x1004 - define SUBR0 0x1005 ; Subnet mask, first octet - define SUBR1 0x1006 - define SUBR2 0x1007 - define SUBR3 0x1008 - define SHAR0 0x1009 ; Our ethernet address, first of 6 - define SHAR1 0x100A - define SHAR2 0x100B - define SHAR3 0x100C - define SHAR4 0x100D - define SHAR5 0x100E - define SIPR0 0x100F ; First octet of our IP address - define SIPR1 0x1010 - define SIPR2 0x1011 - define SIPR3 0x1012 - define IR 0x1015 ; Interrupt register - define IMR 0x1016 ; Interrupt mask - define RTR0 0x1017 ; Retry time - define RTR1 0x1018 - define RCR 0x1019 ; Retry count register - define RMSR 0x101A ; RX memory size - define TMSR 0x101B ; TX memory size - define PATR0 0x101C ; PPPoE authentication type - define PATR1 0x101D - define PTIMER 0x1028 ; PPPoE LCP request timer - define PMAGIC 0x1029 ; PPPoE LCD magic number - define UIPR0 0x102A ; Unreachable IP address 1st octet - define UIPR1 0x102B - define UIPR2 0x102C - define UIPR3 0x102D - define UPORT0 0x102E ; Unreachable port (big endian) - define UPORT1 0x102F - - ; Socket registers (base address - socket 0) - define Sn_BASE 0x04 ; amount to subtract from addr. to - ; derive buffer base - define Sn_MAX 0x48 ; high byte of highest socket reg. - define Sn_MR 0x1400 ; Socket 0 mode - define Sn_CR 0x1401 ; Socket 0 command - define Sn_IR 0x1402 ; Socket 0 interrupt - define Sn_SR 0x1403 ; Socket 0 status - define Sn_PORT0 0x1404 ; Socket 0 port (big endian) - define Sn_PORT1 0x1405 - define Sn_DHAR0 0x1406 ; socket 0 destination ethernet addr. - define Sn_DHAR1 0x1407 - define Sn_DHAR2 0x1408 - define Sn_DHAR3 0x1409 - define Sn_DHAR4 0x140A - define Sn_DHAR5 0x140B - define Sn_DIPR0 0x140C ; Socket 0 destination IP addr. - define Sn_DIPR1 0x140D - define Sn_DIPR2 0x140E - define Sn_DIPR3 0x140F - define Sn_DPORT0 0x1410 ; Socket 0 dest port (big endian) - define Sn_DPORT1 0x1411 - define Sn_MSSR0 0x1412 ; Socket 0 max segment size - define Sn_MSSR1 0x1413 - define Sn_PROTO 0x1414 ; Socket 0 proto in IP raw mode - define Sn_TOS 0x1415 ; Type of service - define Sn_TTL 0x1416 ; Socket 0 time-to-live - define Sn_TX_FSR0 0x1420 ; Socket 0 free size - define Sn_TX_FSR1 0x1421 ; (big endian) - define Sn_TX_RD0 0x1422 ; TX read pointer - define Sn_TX_RD1 0x1423 ; TX read pointer - define Sn_TX_WR0 0x1424 ; TX write pointer - define Sn_TX_WR1 0x1425 ; - define Sn_RX_RSR0 0x1426 ; Socket 0 received size - define Sn_RX_RSR1 0x1427 - define Sn_RX_RD0 0x1428 ; Socket 0 RX read pointer - define Sn_RX_RD1 0x1429 - - ; Register bit values for ORing into bitfields - ; Mode register - define MR_IND 1 ; Set for indirect bus IF mode - define MR_AI 2 ; Set for address auto increment - define MR_PPPoE 8 ; Use PPPoE - define MR_PB 16 ; Set ping block - define MR_RST 128 ; Software reset - - ; Interrupt register - define IR_S0_INT 1 ; Socket 0 interrupt enable - define IR_S1_INT 2 ; Socket 1 EI - define IR_S2_INT 4 - define IR_S3_INT 8 - define IR_PPPoE 32 ; PPPoE interrupts - define IR_UNREACH 64 ; Dest unreachable interrupt - define IR_CONFLICT 128 ; IP conflict interrupt - - ; Interrupt mask register - as interrupt register. - define IM_S0_INT 1 - define IM_S1_INT 2 - define IM_S2_INT 4 - define IM_S3_INT 8 - define IM_PPPoE 32 - define IM_UNREACH 64 - define IM_CONFLICT 128 - - ; Socket modes - define S_MR_CLOSED 0 - define S_MR_TCP 1 - define SOCK_STREAM 1 - define S_MR_UDP 2 - define SOCK_DGRAM 2 - define S_MR_IPRAW 3 - define SOCK_RAW 3 - define S_MR_MACRAW 4 - define S_MR_PPPoE 5 - define S_MR_NDMC 32 ; Use no delayed ACK - define S_MR_MULTI 128 ; enable multicasting - - ; Socket commands - define S_CR_OPEN 1 - define S_CR_LISTEN 2 - define S_CR_CONNECT 4 - define S_CR_DISCON 8 - define S_CR_CLOSE 0x10 - define S_CR_SEND 0x20 - define S_CR_SEND_MAC 0x21 - define S_CR_SEND_KEEP 0x22 - define S_CR_RECV 0x40 - - ; Interrupt register - define S_IR_CON 1 ; Connected - define S_IR_DISCON 2 ; Disconnected - define S_IR_RECV 4 ; Data received - define S_IR_TIMEOUT 8 ; Timeout occurred - define S_IR_SEND_OK 16 ; Send completed - - ; poll(2) definitions (see above) - define POLLIN 5 /* S_IR_RECV | S_IR_CON */ - define POLLHUP 2 /* S_IR_DISCON - output only */ - - ; Bit version of the above - define BIT_IR_CON 0 - define BIT_IR_DISCON 1 - define BIT_IR_RECV 2 - define BIT_IR_TIMEOUT 3 - define BIT_IR_SEND_OK 4 - - ; Status register - values, not bits - define S_SR_SOCK_CLOSED 0x00 ; Socket is closed - define S_SR_SOCK_INIT 0x13 ; Socket is initialized - define S_SR_SOCK_LISTEN 0x14 ; Listen state - define S_SR_SOCK_ESTABLISHED 0x17 ; Connection establised - define S_SR_SOCK_CLOSE_WAIT 0x1C ; CLOSE_WAIT state - define S_SR_SOCK_UDP 0x22 ; UDP socket - define S_SR_SOCK_IPRAW 0x32 ; Raw socket - define S_SR_SOCK_MACRAW 0x42 ; Raw ethernet - define S_SR_SOCK_PPPOE 0x5F ; PPPoE socket - define S_SR_SOCK_SYNSENT 0x15 ; SYN_SENT state - define S_SR_SOCK_SYNRECV 0x16 ; SYN_RECV - define S_SR_SOCK_FIN_WAIT 0x18 ; FIN_WAIT - define S_SR_SOCK_CLOSING 0x1A ; Closing the socket - define S_SR_SOCK_TIME_WAIT 0x1B ; TIME_WAIT - define S_SR_SOCK_LAST_ACK 0x1D - define S_SR_SOCK_ARP1 0x11 - define S_SR_SOCK_ARP2 0x21 - define S_SR_SOCK_ARP3 0x31 - - define REGISTER_PAGE 0x80 ; external mem page 0 - define BUFFER_PAGE 0x81 ; external mem page 1 - define MEMMGMT 0xE0 ; memory manager port - - define INVALID_SOCKNUM 4 ; >=4 is not valid. - - ; Buffer memory should be paged into area A. - define gSn_RX_BASE 0x1000 - define gSn_RX_MASK 0x07FF - define gSn_TX_BASE 0x1000 - define gSn_TX_MASK 0x07FF - -; Definitions not of the W5100 chip, rather just concerining it. -; Hardware pages -RX_LWRDATAPAGE equ 0x46 -RX_UPRDATAPAGE equ 0x47 -TX_LWRDATAPAGE equ 0x44 -TX_UPRDATAPAGE equ 0x45 -REGPAGE equ 0x40 - diff --git a/rom/w5100_defs.inc b/rom/w5100_defs.inc new file mode 100644 index 0000000..0e98abe --- /dev/null +++ b/rom/w5100_defs.inc @@ -0,0 +1,208 @@ +;The MIT License +; +;Copyright (c) 2008 Dylan Smith +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in +;all copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +;THE SOFTWARE. + + + ; Assumptions: The W5100 is paged into paging area A (0x1000) + ; for register manipulation. + ; Register definitions for the W5100. Offset by 0x1000 bytes. + + ; Common registers. +MR equ 0x1000 ; Mode register +GAR0 equ 0x1001 ; Gateway addr first octet +GAR1 equ 0x1002 +GAR2 equ 0x1003 +GAR3 equ 0x1004 +SUBR0 equ 0x1005 ; Subnet mask, first octet +SUBR1 equ 0x1006 +SUBR2 equ 0x1007 +SUBR3 equ 0x1008 +SHAR0 equ 0x1009 ; Our ethernet address, first of 6 +SHAR1 equ 0x100A +SHAR2 equ 0x100B +SHAR3 equ 0x100C +SHAR4 equ 0x100D +SHAR5 equ 0x100E +SIPR0 equ 0x100F ; First octet of our IP address +SIPR1 equ 0x1010 +SIPR2 equ 0x1011 +SIPR3 equ 0x1012 +IR equ 0x1015 ; Interrupt register +IMR equ 0x1016 ; Interrupt mask +RTR0 equ 0x1017 ; Retry time +RTR1 equ 0x1018 +RCR equ 0x1019 ; Retry count register +RMSR equ 0x101A ; RX memory size +TMSR equ 0x101B ; TX memory size +PATR0 equ 0x101C ; PPPoE authentication type +PATR1 equ 0x101D +PTIMER equ 0x1028 ; PPPoE LCP request timer +PMAGIC equ 0x1029 ; PPPoE LCD magic number +UIPR0 equ 0x102A ; Unreachable IP address 1st octet +UIPR1 equ 0x102B +UIPR2 equ 0x102C +UIPR3 equ 0x102D +UPORT0 equ 0x102E ; Unreachable port (big endian) +UPORT1 equ 0x102F + + ; Socket registers (base address - socket 0) +Sn_BASE equ 0x04 ; amount to subtract from addr. to + ; derive buffer base +Sn_MAX equ 0x48 ; high byte of highest socket reg. +Sn_MR equ 0x1400 ; Socket 0 mode +Sn_CR equ 0x1401 ; Socket 0 command +Sn_IR equ 0x1402 ; Socket 0 interrupt +Sn_SR equ 0x1403 ; Socket 0 status +Sn_PORT0 equ 0x1404 ; Socket 0 port (big endian) +Sn_PORT1 equ 0x1405 +Sn_DHAR0 equ 0x1406 ; socket 0 destination ethernet addr. +Sn_DHAR1 equ 0x1407 +Sn_DHAR2 equ 0x1408 +Sn_DHAR3 equ 0x1409 +Sn_DHAR4 equ 0x140A +Sn_DHAR5 equ 0x140B +Sn_DIPR0 equ 0x140C ; Socket 0 destination IP addr. +Sn_DIPR1 equ 0x140D +Sn_DIPR2 equ 0x140E +Sn_DIPR3 equ 0x140F +Sn_DPORT0 equ 0x1410 ; Socket 0 dest port (big endian) +Sn_DPORT1 equ 0x1411 +Sn_MSSR0 equ 0x1412 ; Socket 0 max segment size +Sn_MSSR1 equ 0x1413 +Sn_PROTO equ 0x1414 ; Socket 0 proto in IP raw mode +Sn_TOS equ 0x1415 ; Type of service +Sn_TTL equ 0x1416 ; Socket 0 time-to-live +Sn_TX_FSR0 equ 0x1420 ; Socket 0 free size +Sn_TX_FSR1 equ 0x1421 ; (big endian) +Sn_TX_RD0 equ 0x1422 ; TX read pointer +Sn_TX_RD1 equ 0x1423 ; TX read pointer +Sn_TX_WR0 equ 0x1424 ; TX write pointer +Sn_TX_WR1 equ 0x1425 ; +Sn_RX_RSR0 equ 0x1426 ; Socket 0 received size +Sn_RX_RSR1 equ 0x1427 +Sn_RX_RD0 equ 0x1428 ; Socket 0 RX read pointer +Sn_RX_RD1 equ 0x1429 + + ; Register bit values for ORing into bitfields + ; Mode register +MR_IND equ 1 ; Set for indirect bus IF mode +MR_AI equ 2 ; Set for address auto increment +MR_PPPoE equ 8 ; Use PPPoE +MR_PB equ 16 ; Set ping block +MR_RST equ 128 ; Software reset + + ; Interrupt register +IR_S0_INT equ 1 ; Socket 0 interrupt enable +IR_S1_INT equ 2 ; Socket 1 EI +IR_S2_INT equ 4 +IR_S3_INT equ 8 +IR_PPPoE equ 32 ; PPPoE interrupts +IR_UNREACH equ 64 ; Dest unreachable interrupt +IR_CONFLICT equ 128 ; IP conflict interrupt + + ; Interrupt mask register - as interrupt register. +IM_S0_INT equ 1 +IM_S1_INT equ 2 +IM_S2_INT equ 4 +IM_S3_INT equ 8 +IM_PPPoE equ 32 +IM_UNREACH equ 64 +IM_CONFLICT equ 128 + + ; Socket modes +S_MR_CLOSED equ 0 +S_MR_TCP equ 1 +S_MR_UDP equ 2 +S_MR_IPRAW equ 3 +S_MR_MACRAW equ 4 +S_MR_PPPoE equ 5 +S_MR_NDMC equ 32 ; Use no delayed ACK +S_MR_MULTI equ 128 ; enable multicasting + + ; Socket commands +S_CR_OPEN equ 1 +S_CR_LISTEN equ 2 +S_CR_CONNECT equ 4 +S_CR_DISCON equ 8 +S_CR_CLOSE equ 0x10 +S_CR_SEND equ 0x20 +S_CR_SEND_MAC equ 0x21 +S_CR_SEND_KEEP equ 0x22 +S_CR_RECV equ 0x40 + + ; Interrupt register +S_IR_CON equ 1 ; Connected +S_IR_DISCON equ 2 ; Disconnected +S_IR_RECV equ 4 ; Data received +S_IR_TIMEOUT equ 8 ; Timeout occurred +S_IR_SEND_OK equ 16 ; Send completed + + ; poll(2) definitions (see above) +POLLIN equ 5 /* S_IR_RECV | S_IR_CON */ +POLLHUP equ 2 /* S_IR_DISCON - output only */ + + ; Bit version of the above +BIT_IR_CON equ 0 +BIT_IR_DISCON equ 1 +BIT_IR_RECV equ 2 +BIT_IR_TIMEOUT equ 3 +BIT_IR_SEND_OK equ 4 + + ; Status register - values, not bits +S_SR_SOCK_CLOSED equ 0x00 ; Socket is closed +S_SR_SOCK_INIT equ 0x13 ; Socket is initialized +S_SR_SOCK_LISTEN equ 0x14 ; Listen state +S_SR_SOCK_ESTABLISHED equ 0x17 ; Connection establised +S_SR_SOCK_CLOSE_WAIT equ 0x1C ; CLOSE_WAIT state +S_SR_SOCK_UDP equ 0x22 ; UDP socket +S_SR_SOCK_IPRAW equ 0x32 ; Raw socket +S_SR_SOCK_MACRAW equ 0x42 ; Raw ethernet +S_SR_SOCK_PPPOE equ 0x5F ; PPPoE socket +S_SR_SOCK_SYNSENT equ 0x15 ; SYN_SENT state +S_SR_SOCK_SYNRECV equ 0x16 ; SYN_RECV +S_SR_SOCK_FIN_WAIT equ 0x18 ; FIN_WAIT +S_SR_SOCK_CLOSING equ 0x1A ; Closing the socket +S_SR_SOCK_TIME_WAIT equ 0x1B ; TIME_WAIT +S_SR_SOCK_LAST_ACK equ 0x1D +S_SR_SOCK_ARP1 equ 0x11 +S_SR_SOCK_ARP2 equ 0x21 +S_SR_SOCK_ARP3 equ 0x31 + +REGISTER_PAGE equ 0x80 ; external mem page 0 +BUFFER_PAGE equ 0x81 ; external mem page 1 +MEMMGMT equ 0xE0 ; memory manager port + +INVALID_SOCKNUM equ 4 ; >=4 is not valid. + + ; Buffer memory should be paged into area A. +gSn_RX_BASE equ 0x1000 +gSn_RX_MASK equ 0x07FF +gSn_TX_BASE equ 0x1000 +gSn_TX_MASK equ 0x07FF + +; Definitions not of the W5100 chip, rather just concerining it. +; Hardware pages +RX_LWRDATAPAGE equ 0x46 +RX_UPRDATAPAGE equ 0x47 +TX_LWRDATAPAGE equ 0x44 +TX_UPRDATAPAGE equ 0x45 +REGPAGE equ 0x40 + diff --git a/rom/w5100_genintfunc.asm b/rom/w5100_genintfunc.asm index 58ef9aa..42ff500 100644 --- a/rom/w5100_genintfunc.asm +++ b/rom/w5100_genintfunc.asm @@ -23,13 +23,18 @@ ; ; General internal functions for the socket library. ; +.include "w5100_defs.inc" +.include "sysvars.inc" +.include "sockdefs.inc" ; ; F_gethwsock: ; Get the hardware socket for a file descriptor. If no hardware socket ; is associated with the fd, set the carry flag and return with the error ; code in A. Otherwise, return the hardware socket register area MSB in ; H. -F_gethwsock +.text +.globl F_gethwsock +F_gethwsock: ex af, af' ld a, (v_pga) ; save current page A ld (v_buf_pga), a @@ -42,14 +47,15 @@ F_gethwsock ld h, a ; point hl at putative hardware socket and NOTSOCKMASK ; is this not a hardware socket? ret z ; OK - return with hw sock register in H -.nohwsock +.nohwsock1: ld a, ESBADF scf ret ;---------------------------------------------------------------------------- ; J_leavesockfn - jump point to restore original page A -J_leavesockfn +.globl J_leavesockfn +J_leavesockfn: ex af, af' ld a, (v_buf_pga) call F_setpageA diff --git a/rom/w5100_ifconfig.asm b/rom/w5100_ifconfig.asm index f96e126..4357027 100644 --- a/rom/w5100_ifconfig.asm +++ b/rom/w5100_ifconfig.asm @@ -23,6 +23,8 @@ ; Interface configuration functions - to abstract the W5100 away from ; software that needs to configure the interface. ; +.include "w5100_defs.inc" +.include "sysvars.inc" ;------------------------------------------------------------------------- ; F_ifconfig_ routines: F_ifconfig_inet, F_ifconfig_gw, F_ifconfig_netmask @@ -30,22 +32,26 @@ ; Parameters: HL - pointer to the 4 byte block of memory with the IPv4 ; info. ; DE is incremented by 4. -F_ifconfig_gw +.text +.globl F_ifconfig_gw +F_ifconfig_gw: call F_regpage ld de, GAR0 ; gateway address register jr J_copy_cfg -F_ifconfig_inet +.globl F_ifconfig_inet +F_ifconfig_inet: call F_regpage ld de, SIPR0 jr J_copy_cfg -F_ifconfig_netmask +.globl F_ifconfig_netmask +F_ifconfig_netmask: call F_regpage ld de, SUBR0 jr J_copy_cfg -J_copy_cfg +J_copy_cfg: ld bc, 4 ldir jp J_leavesockfn @@ -54,22 +60,26 @@ J_copy_cfg ; F_get_ifconfig routines: F_get_ifconfig_inet, gw, netmask: ; Returns the inet settings into a 4-byte buffer pointed to by DE ; in big-endian format. -F_get_ifconfig_gw +.globl F_get_ifconfig_gw +F_get_ifconfig_gw: call F_regpage ld hl, GAR0 jr J_copy_cfg -F_get_ifconfig_inet +.globl F_get_ifconfig_inet +F_get_ifconfig_inet: call F_regpage ld hl, SIPR0 jr J_copy_cfg -F_get_ifconfig_netmask +.globl F_get_ifconfig_netmask +F_get_ifconfig_netmask: call F_regpage ld hl, SUBR0 jr J_copy_cfg -F_regpage +.globl F_regpage +F_regpage: ld a, (v_pga) ; copy original page A value ld (v_buf_pga), a ld a, REGPAGE @@ -81,7 +91,8 @@ F_regpage ; Configures the W5100 hardware (MAC) address. ; Parameters: HL - pointer to a 6 byte buffer containing the hardware addr. ; Returns with carry set if the readback fails to give the same result. -F_sethwaddr +.globl F_sethwaddr +F_sethwaddr: call F_regpage push hl ; preserve buffer pointer ld de, SHAR0 ; hardware address register @@ -91,15 +102,15 @@ F_sethwaddr pop hl ld de, SHAR0 ; readback ld bc, 6 ; check 6 bytes -.readback +.readback8: ld a, (de) cpi - jr nz, .readbackerr + jr nz, .readbackerr8 inc de - jp pe, .readback ; keep going till BC=0 + jp pe, .readback8 ; keep going till BC=0 or 0 ; ensure carry is cleared jp J_leavesockfn -.readbackerr +.readbackerr8: scf jp J_leavesockfn @@ -107,7 +118,8 @@ F_sethwaddr ; F_gethwaddr ; Read the hardware address and fill a 6 byte buffer. ; Parameters: DE = pointer to buffer to fill. -F_gethwaddr +.globl F_gethwaddr +F_gethwaddr: call F_regpage ld hl, SHAR0 ld bc, 6 @@ -118,7 +130,8 @@ F_gethwaddr ; F_deconfig ; Deconfigure the interface (reset the inet, gateway and netmask fields). ; Parameters: None. -F_deconfig +.globl F_deconfig +F_deconfig: call F_regpage ld hl, GAR0 ld de, GAR1 diff --git a/rom/w5100_rxtx.asm b/rom/w5100_rxtx.asm index 45faffa..ae49aaf 100644 --- a/rom/w5100_rxtx.asm +++ b/rom/w5100_rxtx.asm @@ -20,6 +20,10 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. ; +.include "w5100_defs.inc" +.include "sysvars.inc" +.include "sockdefs.inc" + ; ; send/sendto and recv/recvfrom send data to a socket and get data ; from it. @@ -31,15 +35,17 @@ ; BC = size of source buffer ; On return, BC = number of bytes sent ; Carry flag is set on error and A contains error code. -F_send +.text +.globl F_send +F_send: call F_gethwsock ; H is socket reg. MSB address jp c, J_leavesockfn ; error finding socket if carry set ld a, b ; MSB of send buffer size cp 0x08 ; greater than 2K if compare result is pos. - jp p, .multisend ; TODO: send buffers >2k + jp p, .multisend1 ; TODO: send buffers >2k call F_copytxbuf jp J_leavesockfn -.multisend ; see TODO above! +.multisend1: ; see TODO above! ld bc, 0x7FF ; send as much as possible for now. call F_copytxbuf jp J_leavesockfn @@ -52,35 +58,37 @@ F_send ; Parameters : A = file descriptor ; DE = address of memory to fill with data ; BC = number of bytes to get -F_recv +.globl F_recv +F_recv: call F_gethwsock ; H is socket reg MSB jp c, J_leavesockfn ; carry is set if the fd is not valid ld l, Sn_IR % 256 ; get the interrupt register -.waitforrecv +.waitforrecv2: ld a, (hl) bit BIT_IR_RECV, a ; see if the recv bit is set - jr nz, .rxdata ; Data is ready + jr nz, .rxdata2 ; Data is ready bit BIT_IR_DISCON, a ; check for RST condition - jr z, .waitforrecv ; no, so keep waiting + jr z, .waitforrecv2 ; no, so keep waiting ld a, ECONNRESET ; connection reset by peer scf jp J_leavesockfn -.rxdata +.rxdata2: set BIT_IR_RECV, (hl) ; clear recv interrupt bit call F_copyrxbuf ; if BC >2k it'll get downsized by W5100 jp J_leavesockfn ;========================================================================= ; Sendto: -; send data to a non-stream socket (i.e. SOCK_DGRAM, a UDP socket). +; send data to a non-stream socket (i.e2. SOCK_DGRAM, a UDP socket). ; ; Parameters: A = file descriptor ; HL = address of 8 byte socket info structure ; DE = address of buffer to send ; BC = size of buffer to send -F_sendto +.globl F_sendto +F_sendto: ld (v_bufptr), hl ; save socket info buffer pointer call F_gethwsock ; H is socket reg. MSB address jp c, J_leavesockfn ; error finding socket if carry set @@ -92,17 +100,17 @@ F_sendto pop de ; retrieve data buffer ld a, b ; MSB of send buffer size cp 0x08 ; greater than 2K if compare result is pos. - jp p, .multisend ; TODO: send buffers >2k + jp p, .multisend3 ; TODO: send buffers >2k call F_copytxbuf jp J_leavesockfn -.multisend ; see TODO above! +.multisend3: ; see TODO above! ld bc, 0x7FF ; send as much as possible for now. call F_copytxbuf jp J_leavesockfn ;========================================================================= ; Recvfrom - receive data from a socket. Usually used for a SOCK_DGRAM -; socket, i.e. UDP. +; socket, i.e3. UDP. ; ; Parameters: A = file descriptor ; HL = address of buffer to fill with connection information @@ -111,28 +119,29 @@ F_sendto ; ; On error, the carry flag is set and the return code is returned in A. ; On successful return, BC contains the number of bytes transferred. -F_recvfrom +.globl F_recvfrom +F_recvfrom: ld (v_bufptr), hl ; save the connection buffer ptr call F_gethwsock ; H is socket reg MSB jp c, J_leavesockfn ; carry is set if the fd is not valid ld l, Sn_IR % 256 ; get the interrupt register -.waitforrecv +.waitforrecv4: ld a, (hl) bit BIT_IR_RECV, a ; see if the recv bit is set - jr nz, .rxdata ; Data is ready + jr nz, .rxdata4 ; Data is ready bit BIT_IR_DISCON, a ; check for RST condition - jr z, .waitforrecv ; no, so keep waiting + jr z, .waitforrecv4 ; no, so keep waiting ld a, ECONNRESET ; connection reset by peer scf jp J_leavesockfn -.rxdata +.rxdata4: set BIT_IR_RECV, (hl) ; clear recv interrupt bit ld l, Sn_MR % 256 ; inspect mode register ld a, (hl) cp SOCK_DGRAM ; Is this a SOCK_DGRAM (UDP) socket? - jr z, .rxudp + jr z, .rxudp4 call F_copyrxbuf ; if BC >2k it'll get downsized by W5100 ld de, (v_bufptr) ; retrieve the buffer pointer call F_sockinfo ; get socket information @@ -143,8 +152,8 @@ F_recvfrom ; first we pull off this 8 byte header and put it into the ; socket info buffer. Then we receive the data proper. ; The structure of the socket info buffer is documented in - ; w5100_sockinfo.asm. -.rxudp + ; w5100_sockinfo.asm4. +.rxudp4: push bc ; save the max length requested push de ; save the data buffer address ld bc, 8 ; length of the header @@ -185,35 +194,36 @@ F_recvfrom ; flags that caused the condition in B. If no sockets are ready, A is 0 ; and the zero flag is set. On error, the carry flag is set and A is set ; to the error. -F_poll +.globl F_poll +F_poll: ld a, (v_pga) ; save original page A ld (v_buf_pga), a ld a, REGPAGE call F_setpageA -.sockloop +.sockloop5: ld a, (de) ; get the first socket ld c, a ; save the file descriptor ld h, v_fd1hwsock / 256 ; set (hl) to point at fd map ld l, a ; (hl) = fd address ld a, (hl) ; a = hw socket MSB and SOCKMASK ; mask out closed/virtual bits - jr nz, .poll ; nonzero means it's an open hw socket + jr nz, .poll5 ; nonzero means it's an open hw socket inc de ; next socket - djnz .sockloop - jr .noneready -.poll + djnz .sockloop5 + jr .noneready5 +.poll5: ld h, a ; (hl) = socket register ld l, Sn_IR % 256 ; interrupt register ld a, (hl) and S_IR_CON|S_IR_RECV|S_IR_DISCON - jr nz, .ready ; an event has occurred + jr nz, .ready5 ; an event has occurred inc de ; next file descriptor - djnz .sockloop -.noneready + djnz .sockloop5 +.noneready5: xor a ; loop finished, no sockets were ready jp J_leavesockfn -.ready +.ready5: ld b, a ; save flags ld a, c ; retrieve fd jp J_leavesockfn @@ -233,7 +243,8 @@ F_poll ; No parameters. The first file descriptor found to be ready will be returned ; in A. If none are ready, A=0 and the zero flag is set. If an fd is ready, ; it is returned in A, and C contains the flags that triggered the condition. -F_pollall +.globl F_pollall +F_pollall: ld a, (v_pga) ; save current page A ld (v_buf_pga), a ld a, REGPAGE @@ -241,36 +252,36 @@ F_pollall ld d, v_fd1hwsock / 256 ld a, (v_lastpolled) ; get addr. of socket to start at cp MAX_FD_NUMBER+1 ; wrap if this puts us off the end - jr nz, .setaddr + jr nz, .setaddr6 ld a, v_fd1hwsock % 256 ; wrap -.setaddr +.setaddr6: ld e, a ; (de) points at socket to poll ld b, MAX_FDS -.sockloop +.sockloop6: ld a, (de) ; get hardware socket register ptr and SOCKMASK ; check it's a real socket - jr nz, .poll -.nextsock + jr nz, .poll6 +.nextsock6: inc e ; next socket ld a, MAX_FD_NUMBER+1 cp e ; wrap around to first fd? - jr nz, .continue ; no + jr nz, .continue6 ; no ld e, v_fd1hwsock % 256 ; wrap back to first file descriptor -.continue - djnz .sockloop - jr .noneready -.poll +.continue6: + djnz .sockloop6 + jr .noneready6 +.poll6: ld h, a ; (hl) = socket register call F_checksock - jr z, .nextsock ; advance to next socket fd -.ready + jr z, .nextsock6 ; advance to next socket fd +.ready6: ld c, a ; copy flags into C ld a, e ; ready fd in e inc a ld (v_lastpolled), a ; save last polled sockfd+1 dec a ; restore A to proper value jp J_leavesockfn -.noneready +.noneready6: xor a ; A=0, zero flag set jp J_leavesockfn @@ -284,7 +295,8 @@ F_pollall ; Zero flag is set if not ready. ; For a ready fd, the reason for readiness is returned in C ; Carry is set on error. -F_pollfd +.globl F_pollfd +F_pollfd: call F_gethwsock ; H is socket reg MSB jp c, J_leavesockfn ; carry is set if the fd is not valid @@ -294,7 +306,8 @@ F_pollfd ; Check a socket's interrupt and status register. Register bank must ; be set in H prior to entry. -F_checksock +.globl F_checksock +F_checksock: ld l, Sn_IR % 256 ; check interrupt register ld a, (hl) and S_IR_CON|S_IR_RECV|S_IR_DISCON @@ -302,12 +315,12 @@ F_checksock ld l, Sn_SR % 256 ; check status register for closedness ld a, (hl) cp S_SR_SOCK_CLOSE_WAIT - jr z, .closed + jr z, .closed8 and a ; 0 = S_SR_SOCK_CLOSED - jr z, .closed + jr z, .closed8 xor a ; return with Z set (and no status flags) ret -.closed +.closed8: ld a, S_IR_DISCON ; set "disconnect" flag or a ; ensure Z flag is reset ret diff --git a/rom/w5100_sockalloc.asm b/rom/w5100_sockalloc.asm index 2ac6888..1c11bbc 100644 --- a/rom/w5100_sockalloc.asm +++ b/rom/w5100_sockalloc.asm @@ -19,7 +19,9 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "w5100_defs.inc" +.include "sysvars.inc" +.include "sockdefs.inc" ; Socket allocation routines. In this file: ; F_socket @@ -45,7 +47,9 @@ ; Returns: file descriptor in A ; ; Preserves: BC -F_socket +.text +.globl F_socket +F_socket: ld a, (v_pga) ; save page A ld (v_buf_pga), a ld a, REGPAGE @@ -54,27 +58,27 @@ F_socket ; Find a free socket. HL will contain the pointer to the socket ; register. call F_hwallocsock ; carry is set when no hw sockets left. - jr nc, .foundsock -.nosockets + jr nc, .foundsock1 +.nosockets1: ld a, ESNFILE ; no more hardware sockets, sorry jp J_leavesockfn -.foundsock +.foundsock1: ld de, v_fd1hwsock ; (de) = fd map first entry ex de, hl -.findfd +.findfd1: bit 7, (hl) ; is bit 7 (not allocated) set? - jr nz, .allocfd + jr nz, .allocfd1 inc l ; next fd - jr .findfd -.allocfd + jr .findfd1 +.allocfd1: ld (hl), d ; associate the hw socket with the fd ex de, hl call F_hwopensock ; h = msb of socket register - jr nc, .sockopen ; if carry not set, socket was opened + jr nc, .sockopen1 ; if carry not set, socket was opened ld a, EBUGGERED ; TODO: better return code jp J_leavesockfn -.sockopen +.sockopen1: ld a, e ; a = file descriptor jp J_leavesockfn @@ -86,7 +90,8 @@ F_socket ; Parameters: A = file descriptor ; ; Carry flag is set if an error occurs reopening a virtual socket. -F_sockclose +.globl F_sockclose +F_sockclose: push af ld a, (v_pga) ; save page A ld (v_buf_pga), a @@ -105,25 +110,25 @@ F_sockclose ld l, Sn_MR % 256 ; check for non-stream socket ld a, (hl) and S_MR_TCP ; if it's not TCP jump forward - jr z, .close ; straight to closing the hardware resource + jr z, .close2 ; straight to closing the hardware resource ld l, Sn_SR % 256 ; check the status register ld a, (hl) cp S_SR_SOCK_INIT ; nothing has been done yet - jr z, .close ; so skip disconnect part. + jr z, .close2 ; so skip disconnect part. cp S_SR_SOCK_LISTEN ; still nothing has been done - jr z, .close ; so skip disconnect part. + jr z, .close2 ; so skip disconnect part. ld l, Sn_CR % 256 ; (hl) = socket's command register ld (hl), S_CR_DISCON ; disconnect remote host ld l, Sn_IR % 256 ; (hl) = interrupt register -.waitfordiscon +.waitfordiscon2: ld a, (hl) and S_IR_DISCON - jr z, .waitfordiscon + jr z, .waitfordiscon2 ld (hl), S_IR_DISCON ; reset interrupt register -.close +.close2: ld l, Sn_CR % 256 ; (hl) = command register ld (hl), S_CR_CLOSE ; close the socket. ex de, hl ; store socket register pointer in DE @@ -135,21 +140,21 @@ F_sockclose ; it to the first fd that we find that's in need of one. ld hl, v_fd1hwsock ld b, MAX_FDS -.vsearch +.vsearch2: bit 6, (hl) ; virtual bit set? - jr nz, .realloc ; reallocate the hardware socket to this fd + jr nz, .realloc2 ; reallocate the hardware socket to this fd inc l ; check the next fd - djnz .vsearch + djnz .vsearch2 jp J_leavesockfn ; nothing more to do - function complete. ; To reallocate a hardware socket to a file descriptor that's ; gone virtual, it must be opened. -.realloc +.realloc2: ; The hardware needs a delay before a socket is re-opened. ; TODO: write to Wiznet and see if there's a better way of doing this. ld b, 255 -.waitloop - djnz .waitloop +.waitloop2: + djnz .waitloop2 ex de, hl ; socket register pointer back to HL ld a, (v_virtualmr) ; get socket type for the socket we're doing @@ -170,10 +175,10 @@ F_sockclose cp S_SR_SOCK_LISTEN ; should be listening ex de, hl ; move sock register addr to de pop hl ; retrieve fd - jr nz, .reallocerr + jr nz, .reallocerr2 ld (hl), d ; store socket register ptr MSB in fd map jp J_leavesockfn -.reallocerr +.reallocerr2: ld a, EBUGGERED scf jp J_leavesockfn @@ -192,7 +197,8 @@ F_sockclose ; Returns: A = file descriptor of accepted connection ; ; On error carry is set and A contains the error number. -F_accept +.globl F_accept +F_accept: push af ; save the fd ld a, (v_pga) ; save page A ld (v_buf_pga), a @@ -205,34 +211,34 @@ F_accept ld d, (hl) ; d = MSB of socket register address ex de, hl ; h = MSB of socket register address ld l, Sn_SR % 256 ; (hl) = socket's SR -.waitforestablished +.waitforestablished3: ld a, (hl) cp S_SR_SOCK_CLOSE_WAIT ; a really short connection can mean we - jr z, .continue ; are in CLOSE_WAIT before we ever got + jr z, .continue3 ; are in CLOSE_WAIT before we ever got cp S_SR_SOCK_ESTABLISHED ; an opportunity to accept... - jr nz, .waitforestablished -.continue + jr nz, .waitforestablished3 +.continue3: ld l, Sn_IR % 256 ; clear the interrupt flag for this socket ld (hl), S_IR_CON ; Now allocate a new fd for the accepted connection. ld b, h ; save socket register pointer MSB ld hl, v_fd1hwsock -.findfd +.findfd3: bit 7, (hl) ; is bit 7 (not allocated) set? - jr nz, .allocfd + jr nz, .allocfd3 inc l ; next fd - jr .findfd -.allocfd + jr .findfd3 +.allocfd3: ld (hl), b ; associate new fd with accepted socket push hl ; save address of new fd ld h, b ; point hl at accepted socket to get type ld l, Sn_MR % 256 ; (hl) = socket's MR ld c, (hl) ; save MR in c call F_hwallocsock ; try to open a new hardware socket - jr c, .virtualize ; no sockets left, so virtualize the fd + jr c, .virtualize3 ; no sockets left, so virtualize the fd call F_hwopensock ; (hl) points at new registers, try to open - jr c, .virtualize ; failed + jr c, .virtualize3 ; failed ex de, hl ; get original fd address into hl ld (hl), d ; save the new listening socket's MSB in fd map ld h, b ; get MSB of original socket @@ -246,16 +252,16 @@ F_accept ld l, Sn_SR % 256 ; hl = status register ptr ld a, (hl) cp S_SR_SOCK_LISTEN ; check for listening state - jr nz, .listenfail + jr nz, .listenfail3 pop hl ; get fd back to return to caller ld a, l ; set fd number in A jp J_leavesockfn -.listenfail +.listenfail3: ld a, EBUGGERED ; set error code and return with carry set scf jp J_leavesockfn -.virtualize +.virtualize3: ex de, hl ; get original fd address ld (hl), FD_VIRTUAL ; mark as virtual ld h, b ; get MSB of socket register into H for HL @@ -274,31 +280,33 @@ F_accept ; An internal function. ; No parameters. ; On return (hl) = status register of available hardware socket. -F_hwallocsock +.globl F_hwallocsock +F_hwallocsock: ; Find a free socket. ld hl, Sn_SR ; hl points at the first socket register -.sockloop +.sockloop4: ld a, (hl) ; get status register value cp S_SR_SOCK_CLOSED ; a closed socket? - jr z, .foundsock ; yes, allocate it + jr z, .foundsock4 ; yes, allocate it inc h ; next socket register ld a, h ; check whether hardware sockets are cp Sn_MAX ; exhausted - jr nz, .sockloop ; and check the next if not. + jr nz, .sockloop4 ; and check the next if not. scf ; out of sockets - set C -.foundsock +.foundsock4: ret ; Open a hardware socket. Carry flag is set if no free sockets. ; An internal function. ; Parameters: C = socket type (SOCK_STREAM, SOCK_DGRAM, SOCK_RAW etc) ; HL = pointer to socket register area -F_hwopensock +.globl F_hwopensock +F_hwopensock: ld a, SOCK_STREAM ; for SOCK_STREAM ensure delayed ACK is off cp c - jr nz, .continue + jr nz, .continue5 set 5, c ; set 'use no delayed ACK' -.continue +.continue5: ld l, Sn_IR % 256 ; (hl) = interrupt register ld (hl), 0x1F ; clear all interrupt flags ld l, Sn_MR % 256 ; (hl) = socket mode register @@ -308,20 +316,20 @@ F_hwopensock ld l, Sn_SR % 256 ; (hl) = status register ld a, SOCK_DGRAM ; is this a UDP socket? cp c - jr z, .checkudpstat ; do status check for UDP socket. + jr z, .checkudpstat5 ; do status check for UDP socket. ld a, (hl) ; TCP socket (SOCK_STREAM) cp S_SR_SOCK_INIT ; did it initialize ok? ret z ; Bad things happened. Clean up and return an error. -.failed +.failed5: ld l, Sn_CR % 256 ; (hl) = command register so... ld (hl), S_CR_CLOSE ; clean up. scf ret -.checkudpstat +.checkudpstat5: ld a, (hl) cp S_SR_SOCK_UDP ; Successfully initialized? ret z - jr .failed + jr .failed5 diff --git a/rom/w5100_sockctrl.asm b/rom/w5100_sockctrl.asm index 6e30279..4352db1 100644 --- a/rom/w5100_sockctrl.asm +++ b/rom/w5100_sockctrl.asm @@ -19,7 +19,9 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "w5100_defs.inc" +.include "sysvars.inc" +.include "sockdefs.inc" ; Socket control routines. In this file: ; F_bind @@ -54,7 +56,9 @@ ; Parameters: A = socket fd ; DE = port ; On error, carry flag is set and A contains error number. -F_bind +.text +.globl F_bind +F_bind: call F_gethwsock ; H now is hardware socket MSB address jp c, J_leavesockfn ; carry is set on error ld l, Sn_PORT0 % 256 ; port register @@ -70,7 +74,8 @@ F_bind ; Parameters: A = socket fd ; ; On error, the carry flag is set and A contains the error number. -F_listen +.globl F_listen +F_listen: call F_gethwsock ; H is now hardware socket MSB address jp c, J_leavesockfn ; unless carry is set because of an error @@ -93,7 +98,8 @@ F_listen ; BC = port number ; On error, the carry flag is set and A contains the error number. ; On success, returns zero in A -F_connect +.globl F_connect +F_connect: call F_gethwsock ; H = socket register bank MSB ld l, Sn_DPORT0 % 256 ; destination port register ld (hl), b ; high order of port @@ -119,22 +125,22 @@ F_connect ld (hl), S_CR_CONNECT ; instruction to connect to remote host ld l, Sn_IR % 256 ; interrupt register -.waitforconn +.waitforconn3: ld a, (hl) bit BIT_IR_CON, a - jr nz, .connected + jr nz, .connected3 and a ; if not, is it zero (no flags set?) - jr z, .waitforconn + jr z, .waitforconn3 and S_IR_DISCON ; connection refused? - jr nz, .refused + jr nz, .refused3 ld a, ETIMEDOUT ; connection timed out scf jp J_leavesockfn -.refused +.refused3: ld a, ECONNREFUSED scf jp J_leavesockfn -.connected +.connected3: set BIT_IR_CON, (hl) ; reset interrupt bit xor a ; connection OK jp J_leavesockfn diff --git a/rom/w5100_sockinfo.asm b/rom/w5100_sockinfo.asm index 3e60471..44fe2a9 100644 --- a/rom/w5100_sockinfo.asm +++ b/rom/w5100_sockinfo.asm @@ -20,8 +20,13 @@ ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. ; +.include "sockdefs.inc" +.include "sysvars.inc" +.include "sysdefs.inc" +.include "w5100_defs.inc" + ; -; Sockinfo.asm: Routines to get information about a socket, analagous +; Sockinfo.asm0: Routines to get information about a socket, analagous ; to filling a struct sockaddr_t in C. ; ; The data structure that is returned looks like this: @@ -38,7 +43,8 @@ ; ; Parameters: H = High order of socket hardware register address ; DE = Address of the buffer to fill. -F_sockinfo +.globl F_sockinfo +F_sockinfo: call F_checkpageA ld l, Sn_DIPR0 % 256 ; remote IP address register ldi @@ -72,7 +78,8 @@ F_sockinfo ; ; Parameters: H = MSB of W5100 socket register area ; DE = address of the 8 byte socket info structure. -F_setsockinfo +.globl F_setsockinfo +F_setsockinfo: call F_checkpageA ex de, hl ld e, Sn_DIPR0 % 256 ; destination IP address @@ -94,7 +101,7 @@ F_setsockinfo inc hl or (hl) ex de, hl ; restore registers to expected order - jr z, .checkset ; need to set random source port? + jr z, .checkset2 ; need to set random source port? ld l, Sn_PORT0 % 256 ; hl points at source port ld a, (de) ; source port MSB ld (hl), a ; set MSB @@ -102,13 +109,13 @@ F_setsockinfo dec de ld a, (de) ld (hl), a ; set LSB - jr .leave -.checkset + jr .leave2 +.checkset2: ld l, Sn_PORT0 % 256 ; port MSB ld a, (hl) inc l ; port LSB or (hl) ; is it zero? - jr nz, .leave ; no - nothing to do + jr nz, .leave2 ; no - nothing to do ex de, hl ; yes - set the local port ld hl, v_localport ld e, Sn_PORT1 % 256 ; set local port LSB @@ -119,7 +126,7 @@ F_setsockinfo inc hl ld (v_localport), hl ex de, hl -.leave +.leave2: ld a, (v_buf_pgb) and a jp nz, F_setpageB @@ -130,7 +137,8 @@ F_setsockinfo ; Fills a struct sockaddr_in with the remote socket info ; Parameters: Socket in A ; Pointer to sockaddr_in in DE -F_remoteaddress +.globl F_remoteaddress +F_remoteaddress: call F_gethwsock jp c, J_leavesockfn ; invalid socket diff --git a/rom/zeropage.asm b/rom/zeropage.asm index d7e4e5f..6fb00cf 100644 --- a/rom/zeropage.asm +++ b/rom/zeropage.asm @@ -19,9 +19,12 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "sysdefs.inc" +.include "sysvars.inc" +.include "spectranet.inc" ; ZEROPAGE ENTRY POINTS -; This file should be included first in "rom.asm"; it sets the org. +; This file should be included first in "rom.asm0"; it sets the org. ; ; RST 0xNN instructions - This is where all the restarts live: ; 00 Reset @@ -35,32 +38,31 @@ ; ; NMI entry point at 0x0066 ; Unpage entry point at 0x007C - - org 0x0000 -RESET +.section rst0 +RESET: di ; This should be done already for a real reset. jp J_reset - block 0x08-$,0xFF -TRAPBAS +.section rst8 +TRAPBAS: jp do_rst8 - block 0x10-$,0xFF -CALLBAS +.section rst10 +CALLBAS: ld (v_hlsave), hl ld (v_desave), de pop hl jp do_callbas - block 0x28-$,0xFF -MODULECALL_NOPAGE +.section rst28 +MODULECALL_NOPAGE_28: jp J_moduledispatch - block 0x30-$,0xFF -MODULECALL +.section rst30 +MODULECALL_30: call J_moduledispatch ex (sp), hl ; throw away return to 0x3FF9 pop hl jr UNPAGE ; unpage and return to caller - block 0x38-$,0xFF -INTERRUPT +.section isr +INTERRUPT: ; 0x0038 push hl ld hl, (v_intcount) ; really, just to indicate that an inc hl ; interrupt took place @@ -69,8 +71,7 @@ INTERRUPT ei reti ; TODO - do something! - block 0x66-$,0xFF -NMI +.section nmi ; 0x0066 ld (NMISTACK), sp ; save SP ld sp, NMISTACK-4 ; set up new stack @@ -84,24 +85,25 @@ NMI ld hl, (NMISTACK) ; HL = address of the return address jr NMI2 - block 0x7B-$,0xFF ; When unpaging, put the address where you want to end up on ; the stack, and the RET instruction will set the PC to this address. +.section unpage ; 0x007B ei -UNPAGE +UNPAGE: ret -NMI2 +.text +NMI2: ld bc, CTRLREG ; test for trap enable in a, (c) and MASK_PROGTRAP_EN - jr z, .nmimenu ; not enabled + jr z, .nmimenu0 ; not enabled ld a, (v_trapcomefrom) ; get comefrom address LSB cp (hl) ; equal to low order? - jr nz, .nmimenu ; no + jr nz, .nmimenu0 ; no inc hl ; return address MSB ld a, (v_trapcomefrom+1) ; comefrom MSB cp (hl) ; equal to high order? - jr nz, .nmimenu ; no + jr nz, .nmimenu0 ; no ; Set up the environment ready to handle the trap. ld a, (v_trappage) ; get the page to page in @@ -110,17 +112,17 @@ NMI2 ld hl, (v_trapaddr) ; no paging to be done - just get the call addr jp (hl) ; jump to it -.nmimenu +.nmimenu0: ld a, 0x02 ; Utility ROM call F_setpageB ld hl, (NMI_VECTOR) ; Test NMI_VECTOR ld a, 0xFF cp h ; FF = unset - jr z, .nmidone - ld de, .nmidone ; get return address + jr z, .nmidone0 + ld de, .nmidone0 ; get return address push de ; save it, so subsequent RET comes back jp (hl) ; jump to the NMI vector -.nmidone +.nmidone0: pop af ex af, af' pop af diff --git a/rom/zxpaging.asm b/rom/zxpaging.asm deleted file mode 100644 index 9ee4a90..0000000 --- a/rom/zxpaging.asm +++ /dev/null @@ -1,82 +0,0 @@ -;The MIT License -; -;Copyright (c) 2008 Dylan Smith -; -;Permission is hereby granted, free of charge, to any person obtaining a copy -;of this software and associated documentation files (the "Software"), to deal -;in the Software without restriction, including without limitation the rights -;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -;copies of the Software, and to permit persons to whom the Software is -;furnished to do so, subject to the following conditions: -; -;The above copyright notice and this permission notice shall be included in -;all copies or substantial portions of the Software. -; -;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -;THE SOFTWARE. - -; Paging routines for 128k machines -;=================================== -; The 128k machine's main ROM in the lower 16k of the memory map is selected -; by port 0x7FFD. On +3 machines, there are 4 possible ROM pages, and -; therefore another port defined for controlling which chip is selected -; (0x1FFD). -; -; When we reset, we want the 48k BASIC ROM paged because there's a few -; routines that the Spectranet uses. The routine F_zxinit sets up the -; initial state (both pager latches reset, and the sysvars set appropriately) -; This allows us to use two routines F_pagezxbasic and F_pagezxrestore -; regardless of the machine's state. -; -; They are no-ops on 48k machines, or after 48k mode has been selected -; (and therefore harmless for non-128k machines). - -;------------------------------------------------------------------------ -; F_zxinit: Make sure the BANK settings are at the initial state. -F_zxinit - xor a - ld (ZX_BANKM), a - ld (ZX_BANK678), a - ld bc, ZX_IO_BANKM - out (c), a - ld bc, ZX_IO_BANK678 - out (c), a - ret - -;------------------------------------------------------------------------ -; F_pagezxbasic: -; Page in the ZX BASIC ROM. -F_pagezxbasic - ld a, (ZX_BANKM) - ld (v_bankm), a ; save old state - or 0x10 ; set bit 4 - ld (ZX_BANKM), a ; update Spectrum sysvar - ld bc, ZX_IO_BANKM - out (c), a ; switch pages - ld a, (ZX_BANK678) - ld (v_bank678),a ; save old state - ld a, 0x04 ; set bit 2 - ld (ZX_BANK678), a ; update +3 sysvar - ld bc, ZX_IO_BANK678 - out (c), a ; switch pages - ret - -;------------------------------------------------------------------------ -; F_pagezxrestore: -; Restore the ROM banks to their original values -F_pagezxrestore - ld a, (v_bankm) ; get old value - ld (ZX_BANKM), a ; restore sysvar - ld bc, ZX_IO_BANKM - out (c), a ; restore pager hardware - ld a, (v_bank678) ; get old +3 value - ld (ZX_BANK678), a ; restore it - ld bc, ZX_IO_BANK678 - out (c), a ; restore +3 pager hardware - ret - diff --git a/rom/zxromdefs.asm b/rom/zxromdefs.asm deleted file mode 100644 index 1c9b88f..0000000 --- a/rom/zxromdefs.asm +++ /dev/null @@ -1,17 +0,0 @@ -; ZX BASIC ROM definitions. -CALLBAS equ 0x10 -ZX_GET_CHAR equ 0x18 -ZX_NEXT_CHAR equ 0x20 -ZX_STK_FETCH equ 0x2BF1 -ZX_EXPT_EXP equ 0x1C8C -ZX_EXPT1_NUM equ 0x1C82 -ZX_NEXT2_NUM equ 0x1C79 -ZX_FIND_INT1 equ 0x1E94 -ZX_FIND_INT2 equ 0x1E99 -ZX_RECLAIM_1 equ 0x19E5 -ZX_MAKE_ROOM equ 0x1655 - -; Token definitions -TOKEN_CODE equ 0xAF -TOKEN_SCREEN equ 0xAA -TOKEN_LINE equ 0xCA diff --git a/syslib/Makefile b/syslib/Makefile new file mode 100644 index 0000000..b068fbf --- /dev/null +++ b/syslib/Makefile @@ -0,0 +1,43 @@ +AS = z80-unknown-coff-as +LD = z80-unknown-coff-ld +AR = z80-unknown-coff-ar +ARFLAGS = -cr +RANLIB = z80-unknown-coff-ranlib +ASFLAGS = -I../include + +UIOBJS = ui_menu.o ui_output.o ui_charset.o ui_lookup.o +UIOUT = libromui.a + +FWOBJS = pager.o flashwrite.o +FWOUT = libflashwrite.a + +PGROBJS = pager.o dispatcher.o +PGROUT = libpager.a + +DBGOBJS = debug.o +DBGOUT = libdebug.a + +all: libui libflashwrite libpager libdebug + +libui: $(UIOBJS) + $(AR) $(ARFLAGS) $(UIOUT) $(UIOBJS) + $(RANLIB) $(UIOUT) + +libflashwrite: $(FWOBJS) + $(AR) $(ARFLAGS) $(FWOUT) $(FWOBJS) + $(RANLIB) $(FWOUT) + +libpager: $(PGROBJS) + $(AR) $(ARFLAGS) $(PGROUT) $(PGROBJS) + $(RANLIB) $(PGROUT) + +libdebug: $(DBGOBJS) + $(AR) $(ARFLAGS) $(DBGOUT) $(DBGOBJS) + $(RANLIB) $(DBGOUT) + +%.o : %.asm + $(AS) $(ASFLAGS) $< -o $@ + +clean: + $(RM) -f *.o *.a + diff --git a/syslib/debug.asm b/syslib/debug.asm new file mode 100644 index 0000000..40a3445 --- /dev/null +++ b/syslib/debug.asm @@ -0,0 +1,130 @@ +.include "spectranet.inc" +.include "ctrlchars.inc" +.include "sysvars.inc" + +; Some simple debug functions. +; hl = start address, b = byte count +.text +.globl F_hexdump +F_hexdump: + push de + push af + ld a, (hl) + call F_inttohex8 + call PRINT42 + ld a, ' ' + call PUTCHAR42 + pop hl + inc hl + djnz F_hexdump + pop af + pop de + ret + +; F_inttohex8 - convert 8 bit number in A. On return hl=ptr to string +.globl F_inttohex8 +F_inttohex8: + push af + push bc + ld hl, v_workspace + ld b, a + call .Num1 + ld a, b + call .Num2 + xor a + ld (hl), a ; add null + pop bc + pop af + ld hl, v_workspace + ret + +.Num1: rra + rra + rra + rra +.Num2: or 0xF0 + daa + add a,0xA0 + adc a,0x40 + + ld (hl),a + inc hl + ret + +F_printhl: + push hl + inc hl + ld a, (hl) + call F_inttohex8 + call PRINT42 + pop hl + push hl + ld a, (hl) + call F_inttohex8 + call PRINT42 + pop hl + ret + +.globl F_regdump +F_regdump: + push ix + push hl + push de + push bc + push af + + ld hl, 0 + add hl, sp + + push hl + ld hl, STR_af + call PRINT42 + pop hl + call F_printhl + + inc hl + inc hl + push hl + ld hl, STR_bc + call PRINT42 + pop hl + call F_printhl + + inc hl + inc hl + push hl + ld hl, STR_de + call PRINT42 + pop hl + call F_printhl + + inc hl + inc hl + push hl + ld hl, STR_hl + call PRINT42 + pop hl + call F_printhl + + inc hl + inc hl + push hl + ld hl, STR_ix + call PRINT42 + pop hl + call F_printhl + + pop af + pop bc + pop de + pop hl + pop ix + + ret +.data +STR_ix: defb NEWLINE,"IX:",0 +STR_hl: defb NEWLINE,"HL:",0 +STR_de: defb NEWLINE,"DE:",0 +STR_bc: defb NEWLINE,"BC:",0 +STR_af: defb NEWLINE,"AF:",0 + diff --git a/syslib/dispatcher.asm b/syslib/dispatcher.asm new file mode 100644 index 0000000..24f082a --- /dev/null +++ b/syslib/dispatcher.asm @@ -0,0 +1,84 @@ +;The MIT License +; +;Copyright (c) 2008 Dylan Smith +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in +;all copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +;THE SOFTWARE. +.include "spectranet.inc" +.include "sysvars.inc" +.include "sysdefs.inc" +.text + +;-------------------------------------------------------------------------- +; J_hldispatch and J_ixdispatch: +; Dispatches a page-in from the call table, and unpages when it's done +.globl J_hldispatch +J_hldispatch: + ld (v_pagerws), hl ; save HL without disturbing the stack + ld hl, PAGEOUT ; unpage address + push hl ; this is now the return address + ld hl, (v_pagerws) ; restore hl + jp (hl) ; jump to routine. +.globl J_ixdispatch +J_ixdispatch: + ld (v_pagerws), hl ; save HL without disturbing the stack + ld hl, PAGEOUT + push hl ; this is now the return address + ld hl, (v_pagerws) ; restore hl + jp (ix) ; jump to routine. + +;------------------------------------------------------------------------- +; J_moduledispatch +; Finds the ROM module for the call to be handed off. The ROM ID is in +; H. The call number is in L. This routine just needs H (L is handled by +; the module) +.globl J_moduledispatch +J_moduledispatch: + ex af, af' ; save af + push hl ; save hl + push bc ; save bc + ld b, h ; get ROM module ID + ld hl, vectors ; start of vector table +.findcall6: + ld a, (hl) ; get ROM ID from table + and a ; check for terminator + jr z, .notfound6 + inc l ; increment table pointer + cp b ; ROM ID to look for + jr nz, .findcall6 +.found6: + ld a, l ; get vector address LSB + sub vectors % 256 - 1 ; subtract the base to get the ROM slot + pop bc + pop hl + call F_pushpageB ; select the page and stack the existing + ex af, af' ; get original AF value + call 0x2010 ; enter ROM module + ex af, af' + ld (v_hlsave), hl + call F_poppageB + ld hl, (v_hlsave) + ex af, af' + ret +.notfound6: + pop bc + pop hl + scf ; return with "function not found" + ld a, -1 + ret + diff --git a/rom/flashwrite.asm b/syslib/flashwrite.asm similarity index 89% rename from rom/flashwrite.asm rename to syslib/flashwrite.asm index 5f9c5e9..c12b04b 100644 --- a/rom/flashwrite.asm +++ b/syslib/flashwrite.asm @@ -23,6 +23,8 @@ ; Flash erase and write routines. ; Note that these routines can't actually be run from flash! They should ; be assembled to RAM instead. +.include "sysdefs.inc" +.text ;--------------------------------------------------------------------------- ; F_FlashEraseSector @@ -32,7 +34,8 @@ ; Parameters: A = page to erase (based on 4k Spectranet pages, but ; erases a 16k sector) ; Carry flag is set if an error occurs. -F_FlashEraseSector +.globl F_FlashEraseSector +F_FlashEraseSector: ; Page in the appropriate sector first 4k into page area B. ; Page to start the erase from is in A. @@ -52,19 +55,19 @@ F_FlashEraseSector ld (0x2000), a ; erase sector address ld hl, 0x2000 -.wait +.wait1: bit 7, (hl) ; test DQ7 - should be 1 when complete - jr nz, .complete + jr nz, .complete1 bit 5, (hl) ; test DQ5 - should be 1 to continue - jr z, .wait + jr z, .wait1 bit 7, (hl) ; test DQ7 again - jr z, .borked + jr z, .borked1 -.complete +.complete1: or 0 ; clear carry flag ret -.borked +.borked1: scf ; carry flag = error ret @@ -76,7 +79,8 @@ F_FlashEraseSector ; DE = destination start address ; BC = number of bytes to copy ; On error, the carry flag is set. -F_FlashWriteBlock +.globl F_FlashWriteBlock +F_FlashWriteBlock: ld a, (hl) ; get byte to write call F_FlashWriteByte ret c ; on error, return immediately @@ -96,11 +100,12 @@ F_FlashWriteBlock ; On return, carry flag set = error ; Page the appropriate flash area into one of the paging areas to write to ; it, and the address should be in that address space. -F_FlashWriteByte +.globl F_FlashWriteByte +F_FlashWriteByte: push bc ld c, a ; save A - ld a, #AA ; unlock 1 + ld a, 0xAA ; unlock 1 ld (0x555), a ; unlock address 1 ld a, 0x55 ; unlock 2 ld (0x2AA), a ; unlock address 2 @@ -109,27 +114,27 @@ F_FlashWriteByte ld a, c ; retrieve A ld (de), a ; program it -.wait +.wait3: ld a, (de) ; read programmed address ld b, a ; save status xor c bit 7, a ; If bit 7 = 0 then bit 7 = data - jr z, .byteComplete + jr z, .byteComplete3 bit 5, b ; test DQ5 - jr z, .wait + jr z, .wait3 ld a, (de) ; read programmed address xor c bit 7, a ; Does DQ7 = programmed data? 0 if true - jr nz, .borked + jr nz, .borked3 -.byteComplete +.byteComplete3: pop bc or 0 ; clear carry flag ret -.borked +.borked3: pop bc scf ; error = set carry flag ret @@ -138,11 +143,12 @@ F_FlashWriteByte ; F_writesector ; Writes 4 pages from the last 4 pages of RAM to flash, starting at the ; page specified in A -F_writesector +.globl F_writesector +F_writesector: ex af, af' ; swap with alternate set ld a, 0xDC ; RAM page 0xDC ld b, 4 ; number of pages -.loop +.loop4: push bc call F_setpageA ; Page into area A inc a ; next page @@ -155,18 +161,16 @@ F_writesector ld bc, 0x1000 push af call F_FlashWriteBlock - jr c, .failed ; restore stack and exit + jr c, .failed4 ; restore stack and exit pop af pop bc - djnz .loop ; next page + djnz .loop4 ; next page ret -.failed ; restore stack, set carry flag +.failed4: ; restore stack, set carry flag pop af pop bc scf ret - include "pager.asm" ; we need our own copy of the pager code - include "sysdefs.asm" UNPAGE equ 0x007C diff --git a/rom/pager.asm b/syslib/pager.asm similarity index 61% rename from rom/pager.asm rename to syslib/pager.asm index a3da4bc..2660ed5 100644 --- a/rom/pager.asm +++ b/syslib/pager.asm @@ -19,14 +19,18 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. - +.include "spectranet.inc" +.include "sysvars.inc" +.include "sysdefs.inc" +.text ; Paging functions. ; These functions abstract the pager, which is a CPLD function. They also ; take care of ensuring modifying one paging area doesn't affect the other. ; ; Set paging area A. Page to load in A. -F_setpageA +.globl F_setpageA +F_setpageA: push bc ld bc, PAGEA ld (v_pga), a ; save the page we've just paged. @@ -35,7 +39,8 @@ F_setpageA ret ; Set paging area B. As for area A. -F_setpageB +.globl F_setpageB +F_setpageB: push bc ld bc, PAGEB ld (v_pgb), a @@ -45,7 +50,8 @@ F_setpageB ; Set paging area A and push the page currently selected onto the stack. ; A = new page to select -F_pushpageA +.globl F_pushpageA +F_pushpageA: ld (v_pagerws), hl ld hl, (v_pga) ; get current page (and the adjacent byte) ex (sp), hl ; stack it @@ -55,7 +61,8 @@ F_pushpageA ret ; Restore page area A from the stack -F_poppageA +.globl F_poppageA +F_poppageA: ld (v_pagerws), hl pop hl ; get the return address ex (sp), hl ; get the page to restore @@ -66,7 +73,8 @@ F_poppageA ; Set paging area B and push the page currently selected onto the stack. ; A = new page to select -F_pushpageB +.globl F_pushpageB +F_pushpageB: ld (v_pagerws), hl ld hl, (v_pgb) ; get current page (and the adjacent byte) ex (sp), hl ; stack it @@ -76,7 +84,8 @@ F_pushpageB ret ; Restore page area B from the stack -F_poppageB +.globl F_poppageB +F_poppageB: ld (v_pagerws), hl pop hl ; get the return address ex (sp), hl ; get the page to restore @@ -85,58 +94,3 @@ F_poppageB ld hl, (v_pagerws) ret -;-------------------------------------------------------------------------- -; J_hldispatch and J_ixdispatch: -; Dispatches a page-in from the call table, and unpages when it's done -J_hldispatch - ld (v_pagerws), hl ; save HL without disturbing the stack - ld hl, UNPAGE ; unpage address - push hl ; this is now the return address - ld hl, (v_pagerws) ; restore hl - jp (hl) ; jump to routine. -J_ixdispatch - ld (v_pagerws), hl ; save HL without disturbing the stack - ld hl, UNPAGE - push hl ; this is now the return address - ld hl, (v_pagerws) ; restore hl - jp (ix) ; jump to routine. - -;------------------------------------------------------------------------- -; J_moduledispatch -; Finds the ROM module for the call to be handed off. The ROM ID is in -; H. The call number is in L. This routine just needs H (L is handled by -; the module) -J_moduledispatch - ex af, af' ; save af - push hl ; save hl - push bc ; save bc - ld b, h ; get ROM module ID - ld hl, vectors ; start of vector table -.findcall - ld a, (hl) ; get ROM ID from table - and a ; check for terminator - jr z, .notfound - inc l ; increment table pointer - cp b ; ROM ID to look for - jr nz, .findcall -.found - ld a, l ; get vector address LSB - sub vectors % 256 - 1 ; subtract the base to get the ROM slot - pop bc - pop hl - call F_pushpageB ; select the page and stack the existing - ex af, af' ; get original AF value - call 0x2010 ; enter ROM module - ex af, af' - ld (v_hlsave), hl - call F_poppageB - ld hl, (v_hlsave) - ex af, af' - ret -.notfound - pop bc - pop hl - scf ; return with "function not found" - ld a, -1 - ret - diff --git a/rom/ui_charset.asm b/syslib/ui_charset.asm similarity index 90% rename from rom/ui_charset.asm rename to syslib/ui_charset.asm index 46a43b0..133c90d 100644 --- a/rom/ui_charset.asm +++ b/syslib/ui_charset.asm @@ -1,4 +1,7 @@ -char_space +.data +.globl CHARSET +CHARSET: +char_space: defb 0 defb 0 defb 0 @@ -8,7 +11,7 @@ char_space defb 0 defb 0 -char_pling +char_pling: defb %00100000 defb %00100000 defb %00100000 @@ -18,7 +21,7 @@ char_pling defb %00100000 defb 0 -char_quote +char_quote: defb %01010000 defb %01010000 defb 0 @@ -28,7 +31,7 @@ char_quote defb 0 defb 0 -char_octothorpe +char_octothorpe: defb 0 defb %01010000 defb %11111000 @@ -38,7 +41,7 @@ char_octothorpe defb %01010000 defb 0 -char_buck +char_buck: defb %00100000 defb %11111000 defb %10100000 @@ -48,7 +51,7 @@ char_buck defb %00100000 defb 0 -char_percent +char_percent: defb %11001000 defb %11001000 defb %00010000 @@ -58,7 +61,7 @@ char_percent defb %10011000 defb 0 -char_ampersand +char_ampersand: defb %01110000 defb %10001000 defb %01010000 @@ -68,7 +71,7 @@ char_ampersand defb %01110100 defb 0 -char_singlequote +char_singlequote: defb %00010000 defb %00100000 defb %01000000 @@ -78,7 +81,7 @@ char_singlequote defb 0 defb 0 -char_obrace +char_obrace: defb %00100000 defb %01000000 defb %10000000 @@ -88,7 +91,7 @@ char_obrace defb %00100000 defb 0 -char_cbrace +char_cbrace: defb %00100000 defb %00010000 defb %00001000 @@ -98,7 +101,7 @@ char_cbrace defb %00100000 defb 0 -char_asterisk +char_asterisk: defb 0 defb %01010000 defb %00100000 @@ -108,7 +111,7 @@ char_asterisk defb 0 defb 0 -char_plus +char_plus: defb 0 defb %00100000 defb %00100000 @@ -118,7 +121,7 @@ char_plus defb 0 defb 0 -char_comma +char_comma: defb 0 defb 0 defb 0 @@ -128,7 +131,7 @@ char_comma defb %00100000 defb %01000000 -char_minus +char_minus: defb 0 defb 0 defb 0 @@ -138,7 +141,7 @@ char_minus defb 0 defb 0 -char_period +char_period: defb 0 defb 0 defb 0 @@ -148,7 +151,7 @@ char_period defb %00110000 defb 0 -char_slash +char_slash: defb %00001000 defb %00001000 defb %00010000 @@ -158,7 +161,7 @@ char_slash defb %10000000 defb 0 -char_zero +char_zero: defb %01110000 defb %10001000 defb %10011000 @@ -168,7 +171,7 @@ char_zero defb %01110000 defb 0 -char_one +char_one: defb %00100000 defb %01100000 defb %10100000 @@ -178,7 +181,7 @@ char_one defb %11111000 defb 0 -char_two +char_two: defb %01110000 defb %10001000 defb %00001000 @@ -188,7 +191,7 @@ char_two defb %11111000 defb 0 -char_three +char_three: defb %01110000 defb %10001000 defb %00001000 @@ -198,7 +201,7 @@ char_three defb %01110000 defb 0 -char_four +char_four: defb %00010000 defb %00110000 defb %01010000 @@ -208,7 +211,7 @@ char_four defb %00010000 defb 0 -char_five +char_five: defb %11111000 defb %10000000 defb %11110000 @@ -218,7 +221,7 @@ char_five defb %01110000 defb 0 -char_six +char_six: defb %00111000 defb %01000000 defb %10000000 @@ -228,7 +231,7 @@ char_six defb %01110000 defb 0 -char_seven +char_seven: defb %11111000 defb %00001000 defb %00001000 @@ -238,7 +241,7 @@ char_seven defb %00100000 defb 0 -char_eight +char_eight: defb %01110000 defb %10001000 defb %10001000 @@ -248,7 +251,7 @@ char_eight defb %01110000 defb 0 -char_nine +char_nine: defb %01110000 defb %10001000 defb %10001000 @@ -258,7 +261,7 @@ char_nine defb %01110000 defb 0 -char_colon +char_colon: defb 0 defb %00100000 defb 0 @@ -268,7 +271,7 @@ char_colon defb 0 defb 0 -char_semicolon +char_semicolon: defb 0 defb %00100000 defb 0 @@ -278,7 +281,7 @@ char_semicolon defb %01000000 defb 0 -char_lessthan +char_lessthan: defb %00010000 defb %00100000 defb %01000000 @@ -288,7 +291,7 @@ char_lessthan defb %00010000 defb 0 -char_equals +char_equals: defb 0 defb 0 defb %11110000 @@ -298,7 +301,7 @@ char_equals defb 0 defb 0 -char_gtthan +char_gtthan: defb %10000000 defb %01000000 defb %00100000 @@ -308,7 +311,7 @@ char_gtthan defb %10000000 defb 0 -char_quest +char_quest: defb %01110000 defb %10001000 defb %00001000 @@ -318,7 +321,7 @@ char_quest defb %00100000 defb 0 -char_at +char_at: defb %01110000 defb %10001000 defb %10111000 @@ -328,7 +331,7 @@ char_at defb %01111000 defb 0 -char_A defb %00100000 +char_A: defb %00100000 defb %01010000 defb %10001000 defb %11111000 @@ -337,7 +340,7 @@ char_A defb %00100000 defb %10001000 defb 0 -char_B defb %11110000 +char_B: defb %11110000 defb %10001000 defb %10001000 defb %11110000 @@ -346,7 +349,7 @@ char_B defb %11110000 defb %11110000 defb 0 -char_C defb %01110000 +char_C: defb %01110000 defb %10001000 defb %10000000 defb %10000000 @@ -355,7 +358,7 @@ char_C defb %01110000 defb %01110000 defb 0 -char_D +char_D: defb %11100000 defb %10010000 defb %10001000 @@ -365,7 +368,7 @@ char_D defb %11100000 defb 0 -char_E +char_E: defb %11111000 defb %10000000 defb %10000000 @@ -375,7 +378,7 @@ char_E defb %11111000 defb 0 -char_F +char_F: defb %11111000 defb %10000000 defb %10000000 @@ -385,7 +388,7 @@ char_F defb %10000000 defb 0 -char_G defb %01110000 +char_G: defb %01110000 defb %10001000 defb %10000000 defb %10000000 @@ -394,7 +397,7 @@ char_G defb %01110000 defb %01110000 defb 0 -char_H defb %10001000 +char_H: defb %10001000 defb %10001000 defb %10001000 defb %11111000 @@ -403,7 +406,7 @@ char_H defb %10001000 defb %10001000 defb 0 -char_I +char_I: defb %01110000 defb %00100000 defb %00100000 @@ -413,7 +416,7 @@ char_I defb %01110000 defb 0 -char_J +char_J: defb %00001000 defb %00001000 defb %00001000 @@ -423,7 +426,7 @@ char_J defb %01110000 defb 0 -char_K +char_K: defb %10001000 defb %10010000 defb %10100000 @@ -433,7 +436,7 @@ char_K defb %10001000 defb 0 -char_L +char_L: defb %10000000 defb %10000000 defb %10000000 @@ -443,7 +446,7 @@ char_L defb %11111000 defb 0 -char_M +char_M: defb %10001000 defb %11011000 defb %10101000 @@ -453,7 +456,7 @@ char_M defb %10001000 defb 0 -char_N +char_N: defb %10001000 defb %10001000 defb %11001000 @@ -463,7 +466,7 @@ char_N defb %10001000 defb 0 -char_O +char_O: defb %01110000 defb %10001000 defb %10001000 @@ -473,7 +476,7 @@ char_O defb %01110000 defb 0 -char_P +char_P: defb %11110000 defb %10001000 defb %10001000 @@ -483,7 +486,7 @@ char_P defb %10000000 defb 0 -char_Q +char_Q: defb %01110000 defb %10001000 defb %10001000 @@ -493,7 +496,7 @@ char_Q defb %01101000 defb 0 -char_R +char_R: defb %11110000 defb %10001000 defb %10001000 @@ -503,7 +506,7 @@ char_R defb %10001000 defb 0 -char_S +char_S: defb %01110000 defb %10001000 defb %10000000 @@ -513,7 +516,7 @@ char_S defb %01110000 defb 0 -char_T +char_T: defb %11111000 defb %00100000 defb %00100000 @@ -523,7 +526,7 @@ char_T defb %00100000 defb 0 -char_U +char_U: defb %10001000 defb %10001000 defb %10001000 @@ -533,7 +536,7 @@ char_U defb %01110000 defb 0 -char_V +char_V: defb %10001000 defb %10001000 defb %10001000 @@ -543,7 +546,7 @@ char_V defb %00100000 defb 0 -char_W +char_W: defb %10001000 defb %10001000 defb %10101000 @@ -553,7 +556,7 @@ char_W defb %10001000 defb 0 -char_X +char_X: defb %10001000 defb %10001000 defb %01010000 @@ -563,7 +566,7 @@ char_X defb %10001000 defb 0 -char_Y +char_Y: defb %10001000 defb %10001000 defb %01010000 @@ -573,7 +576,7 @@ char_Y defb %00100000 defb 0 -char_Z +char_Z: defb %11111000 defb %00001000 defb %00010000 @@ -583,7 +586,7 @@ char_Z defb %11111000 defb 0 -char_osqb +char_osqb: defb %01110000 defb %01000000 defb %01000000 @@ -593,7 +596,7 @@ char_osqb defb %01110000 defb 0 -char_backslash +char_backslash: defb %10000000 defb %10000000 defb %01000000 @@ -603,7 +606,7 @@ char_backslash defb %00001000 defb 0 -char_csqb +char_csqb: defb %01110000 defb %00010000 defb %00010000 @@ -613,7 +616,7 @@ char_csqb defb %01110000 defb 0 -char_power +char_power: defb %00100000 defb %01010000 defb %10001000 @@ -623,7 +626,7 @@ char_power defb 0 defb 0 -char_underscore +char_underscore: defb 0 defb 0 defb 0 @@ -633,7 +636,7 @@ char_underscore defb %11111100 defb 0 -char_quid +char_quid: defb %00110000 defb %01001000 defb %01000000 @@ -643,7 +646,7 @@ char_quid defb %11111000 defb 0 -char_a +char_a: defb 0 defb 0 defb %01110000 @@ -653,7 +656,7 @@ char_a defb %01111000 defb 0 -char_b +char_b: defb %10000000 defb %10000000 defb %11110000 @@ -663,7 +666,7 @@ char_b defb %11110000 defb 0 -char_c +char_c: defb 0 defb 0 defb %01111000 @@ -673,7 +676,7 @@ char_c defb %01111000 defb 0 -char_d +char_d: defb %00001000 defb %00001000 defb %01111000 @@ -683,7 +686,7 @@ char_d defb %01111000 defb 0 -char_e +char_e: defb 0 defb 0 defb %01110000 @@ -693,7 +696,7 @@ char_e defb %01111000 defb 0 -char_f +char_f: defb 0 defb %01110000 defb %10000000 @@ -703,7 +706,7 @@ char_f defb %10000000 defb 0 -char_g +char_g: defb 0 defb 0 defb %01111000 @@ -713,7 +716,7 @@ char_g defb %00001000 defb %01110000 -char_h +char_h: defb %10000000 defb %10000000 defb %11110000 @@ -723,7 +726,7 @@ char_h defb %10001000 defb 0 -char_i +char_i: defb %00100000 defb 0 defb %01100000 @@ -733,7 +736,7 @@ char_i defb %01110000 defb 0 -char_j +char_j: defb %00100000 defb 0 defb %01100000 @@ -743,7 +746,7 @@ char_j defb %00100000 defb %11000000 -char_k +char_k: defb 0 defb %10000000 defb %10010000 @@ -753,7 +756,7 @@ char_k defb %10010000 defb 0 -char_l defb %01100000 +char_l: defb %01100000 defb %00100000 defb %00100000 defb %00100000 @@ -762,7 +765,7 @@ char_l defb %01100000 defb %01110000 defb 0 -char_m +char_m: defb 0 defb 0 defb %11010000 @@ -772,7 +775,7 @@ char_m defb %10001000 defb 0 -char_n +char_n: defb 0 defb 0 defb %11110000 @@ -782,7 +785,7 @@ char_n defb %10001000 defb 0 -char_o +char_o: defb 0 defb 0 defb %01110000 @@ -792,7 +795,7 @@ char_o defb %01110000 defb 0 -char_p +char_p: defb 0 defb 0 defb %11110000 @@ -802,7 +805,7 @@ char_p defb %10000000 defb %10000000 -char_q +char_q: defb 0 defb 0 defb %01111000 @@ -812,7 +815,7 @@ char_q defb %00001000 defb %00001100 -char_r +char_r: defb 0 defb 0 defb %01110000 @@ -822,7 +825,7 @@ char_r defb %10000000 defb 0 -char_s +char_s: defb 0 defb 0 defb %01111000 @@ -832,7 +835,7 @@ char_s defb %11110000 defb 0 -char_t +char_t: defb %01000000 defb %01000000 defb %11110000 @@ -842,7 +845,7 @@ char_t defb %00111000 defb 0 -char_u +char_u: defb 0 defb 0 defb %10001000 @@ -852,7 +855,7 @@ char_u defb %01110000 defb 0 -char_v +char_v: defb 0 defb 0 defb %10001000 @@ -862,7 +865,7 @@ char_v defb %00100000 defb 0 -char_w +char_w: defb 0 defb 0 defb %10101000 @@ -872,7 +875,7 @@ char_w defb %01010000 defb 0 -char_x +char_x: defb 0 defb 0 defb %10001000 @@ -882,7 +885,7 @@ char_x defb %10001000 defb 0 -char_y +char_y: defb 0 defb 0 defb %10001000 @@ -892,7 +895,7 @@ char_y defb %01110000 defb 0 -char_z +char_z: defb 0 defb 0 defb %11111000 @@ -902,7 +905,7 @@ char_z defb %11111000 defb 0 -char_ocbk +char_ocbk: defb %00111000 defb %01000000 defb %01000000 @@ -912,7 +915,7 @@ char_ocbk defb %00111000 defb 0 -char_ccbk +char_ccbk: defb %11100000 defb %00010000 defb %00010000 @@ -922,7 +925,7 @@ char_ccbk defb %11100000 defb 0 -char_tilde +char_tilde: defb %01010000 defb %10100000 defb 0 @@ -932,7 +935,7 @@ char_tilde defb 0 defb 0 -char_copy +char_copy: defb %01110000 defb %10001000 defb %11101000 @@ -942,12 +945,12 @@ char_copy defb %01110000 defb 0 -char_block +char_block: defb 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; Aquí, hay unos carácteres de UTF-8 ; 0xC3 0x80 - 0xBF -char_A_grave ; 0x80 +char_A_grave: ; 0x80 defb %01000000 defb %00100000 defb %01110000 @@ -957,7 +960,7 @@ char_A_grave ; 0x80 defb %10001000 defb 0 -char_A_acute ; 0x81 +char_A_acute: ; 0x81 defb %00100000 defb %01000000 defb %01110000 @@ -967,7 +970,7 @@ char_A_acute ; 0x81 defb %10001000 defb 0 -char_A_circumflex ; 0x82 +char_A_circumflex: ; 0x82 defb %00100000 defb %01010000 defb %01110000 @@ -977,7 +980,7 @@ char_A_circumflex ; 0x82 defb %10001000 defb 0 -char_A_tilde ; 0x83 +char_A_tilde: ; 0x83 defb %01010000 defb %10100000 defb %01110000 @@ -987,7 +990,7 @@ char_A_tilde ; 0x83 defb %10001000 defb 0 -char_A_umlaut ; 0x84 +char_A_umlaut: ; 0x84 defb %01010000 defb %00000000 defb %01110000 @@ -997,7 +1000,7 @@ char_A_umlaut ; 0x84 defb %10001000 defb 0 -char_ANGSTROM ; 0x85 +char_ANGSTROM: ; 0x85 defb %00100000 defb %01010000 defb %01110000 @@ -1007,7 +1010,7 @@ char_ANGSTROM ; 0x85 defb %10001000 defb 0 -char_AE ; 0x86 +char_AE: ; 0x86 defb %00011100 defb %00110000 defb %01010000 @@ -1017,7 +1020,7 @@ char_AE ; 0x86 defb %10011100 defb 0 -char_C_cedilla ; 0x87 +char_C_cedilla: ; 0x87 defb %01110000 defb %10001000 defb %10000000 @@ -1027,7 +1030,7 @@ char_C_cedilla ; 0x87 defb %01110000 defb %01100000 -char_E_grave ; 0x88 +char_E_grave: ; 0x88 defb %01000000 defb %00100000 defb %11111000 @@ -1037,7 +1040,7 @@ char_E_grave ; 0x88 defb %11111000 defb 0 -char_E_acute ; 0x89 +char_E_acute: ; 0x89 defb %00100000 defb %01000000 defb %11111000 @@ -1047,7 +1050,7 @@ char_E_acute ; 0x89 defb %11111000 defb 0 -char_E_circumflex ; 0x8A +char_E_circumflex: ; 0x8A defb %00100000 defb %01010000 defb %11111000 @@ -1057,7 +1060,7 @@ char_E_circumflex ; 0x8A defb %11111000 defb 0 -char_E_umlaut ; 0x8B +char_E_umlaut: ; 0x8B defb %01010000 defb %00000000 defb %11111000 @@ -1067,7 +1070,7 @@ char_E_umlaut ; 0x8B defb %11111000 defb 0 -char_I_grave ; 0x8C +char_I_grave: ; 0x8C defb %01000000 defb %00100000 defb %01110000 @@ -1077,7 +1080,7 @@ char_I_grave ; 0x8C defb %01110000 defb 0 -char_I_acute ; 0x8D +char_I_acute: ; 0x8D defb %00100000 defb %01000000 defb %01110000 @@ -1087,7 +1090,7 @@ char_I_acute ; 0x8D defb %01110000 defb 0 -char_I_circumflex ; 0x8E +char_I_circumflex: ; 0x8E defb %00100000 defb %01010000 defb %01110000 @@ -1097,7 +1100,7 @@ char_I_circumflex ; 0x8E defb %01110000 defb 0 -char_I_umlaut ; 0x8F +char_I_umlaut: ; 0x8F defb %01010000 defb %00000000 defb %01110000 @@ -1107,7 +1110,7 @@ char_I_umlaut ; 0x8F defb %01110000 defb 0 -char_D_barrada ; 0x90 +char_D_barrada: ; 0x90 defb %11100000 defb %10010000 defb %10001000 @@ -1117,7 +1120,7 @@ char_D_barrada ; 0x90 defb %11100000 defb 0 -char_ENE ; 0x91 +char_ENE: ; 0x91 defb %00101000 defb %01010000 defb %10001000 @@ -1127,7 +1130,7 @@ char_ENE ; 0x91 defb %10001000 defb 0 -char_O_grave ; 0x92 +char_O_grave: ; 0x92 defb %01000000 defb %00100000 defb %01110000 @@ -1137,7 +1140,7 @@ char_O_grave ; 0x92 defb %01110000 defb 0 -char_O_acute ; 0x93 +char_O_acute: ; 0x93 defb %00100000 defb %01000000 defb %01110000 @@ -1147,7 +1150,7 @@ char_O_acute ; 0x93 defb %01110000 defb 0 -char_O_circumflex ; 0x94 +char_O_circumflex: ; 0x94 defb %00100000 defb %01010000 defb %01110000 @@ -1157,7 +1160,7 @@ char_O_circumflex ; 0x94 defb %01110000 defb 0 -char_O_tilde ; 0x95 +char_O_tilde: ; 0x95 defb %01010000 defb %10100000 defb %01110000 @@ -1167,7 +1170,7 @@ char_O_tilde ; 0x95 defb %01110000 defb 0 -char_O_umlaut ; 0x96 +char_O_umlaut: ; 0x96 defb %01010000 defb %00000000 defb %01110000 @@ -1177,7 +1180,7 @@ char_O_umlaut ; 0x96 defb %01110000 defb 0 -char_times ; 0x97 +char_times: ; 0x97 defb 0 defb 0 defb %10001000 @@ -1187,7 +1190,7 @@ char_times ; 0x97 defb %10001000 defb 0 -char_O_slash ; 0x98 +char_O_slash: ; 0x98 defb %01110000 defb %10001000 defb %10011000 @@ -1197,7 +1200,7 @@ char_O_slash ; 0x98 defb %01110000 defb 0 -char_U_grave ; 0x99 +char_U_grave: ; 0x99 defb %01000000 defb %00100000 defb %10001000 @@ -1207,7 +1210,7 @@ char_U_grave ; 0x99 defb %01110000 defb 0 -char_U_acute ; 0x9A +char_U_acute: ; 0x9A defb %00100000 defb %01000000 defb %10001000 @@ -1217,7 +1220,7 @@ char_U_acute ; 0x9A defb %01110000 defb 0 -char_U_circumflex ; 0x9B +char_U_circumflex: ; 0x9B defb %00100000 defb %01010000 defb %10001000 @@ -1227,7 +1230,7 @@ char_U_circumflex ; 0x9B defb %01110000 defb 0 -char_U_umlaut ; 0x9C +char_U_umlaut: ; 0x9C defb %01010000 defb %00000000 defb %10001000 @@ -1237,7 +1240,7 @@ char_U_umlaut ; 0x9C defb %01110000 defb 0 -char_Y_acute ; 0x9D +char_Y_acute: ; 0x9D defb %00010000 defb %00100000 defb %10001000 @@ -1247,7 +1250,7 @@ char_Y_acute ; 0x9D defb %00100000 defb 0 -char_THORN ; 0x9E +char_THORN: ; 0x9E defb %10000000 defb %11110000 defb %10001000 @@ -1257,7 +1260,7 @@ char_THORN ; 0x9E defb %10000000 defb 0 -char_ESZETT ; 0x9F +char_ESZETT: ; 0x9F defb %11110000 defb %10001000 defb %10001000 @@ -1267,7 +1270,7 @@ char_ESZETT ; 0x9F defb %10110000 defb %10000000 -char_a_grave ; 0xA0 +char_a_grave: ; 0xA0 defb %01000000 defb %00100000 defb %01110000 @@ -1277,7 +1280,7 @@ char_a_grave ; 0xA0 defb %01111000 defb 0 -char_a_acute ; 0xA1 +char_a_acute: ; 0xA1 defb %00100000 defb %01000000 defb %01110000 @@ -1287,7 +1290,7 @@ char_a_acute ; 0xA1 defb %01111000 defb 0 -char_a_circumflex ; 0xA2 +char_a_circumflex: ; 0xA2 defb %00100000 defb %01010000 defb %01110000 @@ -1297,7 +1300,7 @@ char_a_circumflex ; 0xA2 defb %01111000 defb 0 -char_a_tilde ; 0xA3 +char_a_tilde: ; 0xA3 defb %01010000 defb %10100000 defb %01110000 @@ -1307,7 +1310,7 @@ char_a_tilde ; 0xA3 defb %01111000 defb 0 -char_a_umlaut ; 0xA4 +char_a_umlaut: ; 0xA4 defb %01010000 defb %00000000 defb %01110000 @@ -1317,7 +1320,7 @@ char_a_umlaut ; 0xA4 defb %01111000 defb 0 -char_anillo ; 0xA5 +char_anillo: ; 0xA5 defb %01110000 defb %10001000 defb %01110000 @@ -1327,7 +1330,7 @@ char_anillo ; 0xA5 defb %01111000 defb 0 -char_ae ; 0xA6 +char_ae: ; 0xA6 defb 0 defb 0 defb %11110000 @@ -1337,7 +1340,7 @@ char_ae ; 0xA6 defb %01011000 defb 0 -char_c_cedilla ; 0xA7 +char_c_cedilla: ; 0xA7 defb 0 defb 0 defb %01111000 @@ -1347,7 +1350,7 @@ char_c_cedilla ; 0xA7 defb %01111000 defb %00100000 -char_e_grave ; 0xA8 +char_e_grave: ; 0xA8 defb %01000000 defb %00100000 defb %01110000 @@ -1357,7 +1360,7 @@ char_e_grave ; 0xA8 defb %01111000 defb 0 -char_e_acute ; 0xA9 +char_e_acute: ; 0xA9 defb %00100000 defb %01000000 defb %01110000 @@ -1367,7 +1370,7 @@ char_e_acute ; 0xA9 defb %01111000 defb 0 -char_e_circumflex ; 0xAA +char_e_circumflex: ; 0xAA defb %00100000 defb %01010000 defb %01110000 @@ -1377,7 +1380,7 @@ char_e_circumflex ; 0xAA defb %01111000 defb 0 -char_e_umlaut ; 0xAB +char_e_umlaut: ; 0xAB defb %01010000 defb %00000000 defb %01110000 @@ -1387,7 +1390,7 @@ char_e_umlaut ; 0xAB defb %01111000 defb 0 -char_i_grave ; 0xAC +char_i_grave: ; 0xAC defb %01000000 defb %00100000 defb %01100000 @@ -1397,7 +1400,7 @@ char_i_grave ; 0xAC defb %01110000 defb 0 -char_i_acute ; 0xAD +char_i_acute: ; 0xAD defb %00100000 defb %01000000 defb %01100000 @@ -1407,7 +1410,7 @@ char_i_acute ; 0xAD defb %01110000 defb 0 -char_i_circumflex ; 0xAE +char_i_circumflex: ; 0xAE defb %00100000 defb %01010000 defb %01100000 @@ -1417,7 +1420,7 @@ char_i_circumflex ; 0xAE defb %01110000 defb 0 -char_i_umlaut ; 0xAF +char_i_umlaut: ; 0xAF defb %01010000 defb %00000000 defb %01100000 @@ -1427,7 +1430,7 @@ char_i_umlaut ; 0xAF defb %01110000 defb 0 -char_o_d_barrada ; 0xB0 +char_o_d_barrada: ; 0xB0 defb %00000000 defb %11100000 defb %01110000 @@ -1437,7 +1440,7 @@ char_o_d_barrada ; 0xB0 defb %01110000 defb 0 -char_ene ; 0xB1 +char_ene: ; 0xB1 defb %01010000 defb %10100000 defb %11110000 @@ -1447,7 +1450,7 @@ char_ene ; 0xB1 defb %10001000 defb 0 -char_o_grave ; 0xB2 +char_o_grave: ; 0xB2 defb %01000000 defb %00100000 defb %01110000 @@ -1457,7 +1460,7 @@ char_o_grave ; 0xB2 defb %01110000 defb 0 -char_o_acute ; 0xB3 +char_o_acute: ; 0xB3 defb %00100000 defb %01000000 defb %01110000 @@ -1467,7 +1470,7 @@ char_o_acute ; 0xB3 defb %01110000 defb 0 -char_o_circumflex ; 0xB4 +char_o_circumflex: ; 0xB4 defb %00100000 defb %01010000 defb %01110000 @@ -1477,7 +1480,7 @@ char_o_circumflex ; 0xB4 defb %01110000 defb 0 -char_o_tilde ; 0xB5 +char_o_tilde: ; 0xB5 defb %01010000 defb %10100000 defb %01110000 @@ -1487,7 +1490,7 @@ char_o_tilde ; 0xB5 defb %01110000 defb 0 -char_o_umlaut ; 0xB6 +char_o_umlaut: ; 0xB6 defb %01010000 defb %00000000 defb %01110000 @@ -1497,7 +1500,7 @@ char_o_umlaut ; 0xB6 defb %01110000 defb 0 -char_divide ; 0xB7 +char_divide: ; 0xB7 defb 0 defb %00100000 defb 0 @@ -1507,7 +1510,7 @@ char_divide ; 0xB7 defb 0 defb 0 -char_o_slash ; 0xB8 +char_o_slash: ; 0xB8 defb 0 defb 0 defb %01110000 @@ -1517,7 +1520,7 @@ char_o_slash ; 0xB8 defb %01110000 defb 0 -char_u_grave ; 0xB9 +char_u_grave: ; 0xB9 defb %01000000 defb %00100000 defb %10001000 @@ -1527,7 +1530,7 @@ char_u_grave ; 0xB9 defb %01110000 defb 0 -char_u_acute ; 0xBA +char_u_acute: ; 0xBA defb %00010000 defb %00100000 defb %10001000 @@ -1537,7 +1540,7 @@ char_u_acute ; 0xBA defb %01110000 defb 0 -char_u_circumflex ; 0xBB +char_u_circumflex: ; 0xBB defb %00100000 defb %01010000 defb %00000000 @@ -1547,7 +1550,7 @@ char_u_circumflex ; 0xBB defb %01110000 defb 0 -char_u_umlaut ; 0xBC +char_u_umlaut: ; 0xBC defb %01010000 defb %00000000 defb %10001000 @@ -1557,7 +1560,7 @@ char_u_umlaut ; 0xBC defb %01110000 defb 0 -char_y_acute ; 0xBD +char_y_acute: ; 0xBD defb %00010000 defb %00100000 defb %10001000 @@ -1567,7 +1570,7 @@ char_y_acute ; 0xBD defb %01110000 defb 0 -char_thorn ; 0xBE +char_thorn: ; 0xBE defb %00000000 defb %10000000 defb %11110000 @@ -1577,7 +1580,7 @@ char_thorn ; 0xBE defb %10000000 defb 0 -char_y_umlaut ; 0xBF +char_y_umlaut: ; 0xBF defb %01010000 defb %00000000 defb %10001000 @@ -1588,7 +1591,11 @@ char_y_umlaut ; 0xBF defb 0 ; for 0xC2 characters, only a small subset is supported (by lookup table) -char_euro +.globl CHARSET_C2 +CHARSET_C2: +.globl CHARSET_C2_DIST +CHARSET_C2_DIST: equ (CHARSET_C2-CHARSET)/8 +char_euro: defb %01110000 defb %10001000 defb %10000000 @@ -1598,7 +1605,11 @@ char_euro defb %01110000 defb 0 -char_inverted_pling +.globl CHARSET_INVPLING +CHARSET_INVPLING: +.globl CHARSET_INVPLING_DIST +CHARSET_INVPLING_DIST: equ (CHARSET_INVPLING-CHARSET)/8 +char_inverted_pling: defb %00100000 defb 0 defb %00100000 @@ -1608,7 +1619,7 @@ char_inverted_pling defb %00100000 defb 0 -char_cent +char_cent: defb 0 defb %00100000 defb %01111000 @@ -1618,7 +1629,11 @@ char_cent defb %01111000 defb %00100000 -char_inverted_quest +.globl CHARSET_INVQUEST +CHARSET_INVQUEST: +.globl CHARSET_INVQUEST_DIST +CHARSET_INVQUEST_DIST: equ (CHARSET_INVQUEST-CHARSET) / 8 +char_inverted_quest: defb %00100000 defb 0 defb %00100000 diff --git a/rom/ui_lookup.asm b/syslib/ui_lookup.asm similarity index 96% rename from rom/ui_lookup.asm rename to syslib/ui_lookup.asm index d9a1c06..ac1223f 100644 --- a/rom/ui_lookup.asm +++ b/syslib/ui_lookup.asm @@ -22,8 +22,9 @@ ; This file contains a simple lookup table for the UI 42 column output ; routine. - -col_lookup +.section lookup +.globl col_lookup +col_lookup: defb 0,0,1,2,3,3,4,5,6,6,7,8,9,9,10,11,12,12,13,14,15,15 defb 16,17,18,18,19,20,21,21,22,23,24,24,25,26,27,27,28,29,30,30,31 diff --git a/rom/ui_menu.asm b/syslib/ui_menu.asm similarity index 87% rename from rom/ui_menu.asm rename to syslib/ui_menu.asm index dd6a7af..6400c9b 100644 --- a/rom/ui_menu.asm +++ b/syslib/ui_menu.asm @@ -19,17 +19,22 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "spectranet.inc" +.include "ctrlchars.inc" +.include "sysvars.inc" ; Simple menu system routines. +.text ;-------------------------------------------------------------------------- ; F_genmenu ; Generates a menu screen. ; Parameters: HL = pointer to menu structure, that should be a null terminated ; list of pointers to strings that define the choices. -F_genmenu +.globl F_genmenu +F_genmenu: ld b, 'A' ; first option is 'A' -.loop +.loop1: ld e, (hl) ; get pointer into DE inc hl ld d, (hl) @@ -50,39 +55,40 @@ F_genmenu ex de, hl ; get string pointer into hl call PRINT42 ; print the menu option ex de, hl ; move the menu pointer back - ld a, '\n' ; print a CR + ld a, NEWLINE ; print a CR call PUTCHAR42 inc b ; update option character - jr .loop + jr .loop1 ;------------------------------------------------------------------------- ; F_getmenuopt: ; Wait for the user to press a key, then call the appropriate routine. -F_getmenuopt +.globl F_getmenuopt +F_getmenuopt: ld (v_hlsave), hl ; save HL without disturbing stack -.getkey +.getkey2: call GETKEY ; wait for key to be pressed ld hl, (v_hlsave) sub 'a' ; ASCII a = 0 - jr c, .getkey ; key pressed was < 'a' -.loop + jr c, .getkey2 ; key pressed was < 'a' +.loop2: push af ld a, (hl) inc hl or (hl) ; Null terminator? - jr z, .outofrange + jr z, .outofrange2 inc hl ; hl points at call entry pop af and a ; A=0? - jr z, .callopt + jr z, .callopt2 dec a inc hl ; advance past string pointer inc hl - jr .loop -.outofrange + jr .loop2 +.outofrange2: pop af ; fix stack - jr .getkey ; try again -.callopt + jr .getkey2 ; try again +.callopt2: ld e, (hl) ; get call address into DE inc hl ld d, (hl) diff --git a/rom/ui_output.asm b/syslib/ui_output.asm similarity index 82% rename from rom/ui_output.asm rename to syslib/ui_output.asm index e9cf907..1e774d1 100644 --- a/rom/ui_output.asm +++ b/syslib/ui_output.asm @@ -19,6 +19,8 @@ ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ;THE SOFTWARE. +.include "sysvars.inc" +.include "ctrlchars.inc" ; User interface output routines ; This is mostly about putting characters on the screen, and clearing the @@ -31,26 +33,28 @@ ; The 'core' of the putchar routine, F_print calls this directly (handling ; the paging itself) ; The routine could probably do with improvement. -F_putc_5by8_impl +.text +.globl F_putc_5by8_impl +F_putc_5by8_impl: push hl push bc push de ld h, a ; save character ld a, (v_utf8) ; check UTF-8 state and a ; if nonzero, process it - jp nz, .map_utf8 + jp nz, .map_utf81 ld a, h ; restore character - cp '\n' ; carriage return? - jr z, .nextrow + cp NEWLINE ; carriage return? + jr z, .nextrow1 cp 0xC1 ; utf-8 character that we support - jp nc, .utf8 ; which is 0xC2 and higher + jp nc, .utf81 ; which is 0xC2 and higher ; find the address of the character in the bitmap table sub 32 ; space = offset 0 ld l, a -.utf8_continue ; we return here from the utf8 map subroutine +.utf8_continue1: ; we return here from the utf8 map subroutine ld h, 0 ; multiply by 8 to get the byte offset @@ -59,7 +63,7 @@ F_putc_5by8_impl add hl, hl ; add the offset - ld bc, char_space + ld bc, CHARSET add hl, bc ; Now find the address in the frame buffer to be written. @@ -71,123 +75,124 @@ F_putc_5by8_impl ld l, a ; hl = pointer to byte in lookup table ld a, (hl) ; a = lookup table value ld hl, (v_row) ; hl = framebuffer pointer for start of row - add l + add a,l ld l, a ; hl = frame buffer address ; de contains the address of the char bitmap ; hl contains address in the frame buffer -.paintchar +.paintchar1: ld a, b ; retrieve column and 3 ; find out how much we need to rotate - jr z, .norotate ; no need to rotate, character starts at MSB + jr z, .norotate1 ; no need to rotate, character starts at MSB rla ; multipy by 2 ld (v_pr_wkspc), a ; save A ld b, 8 ; byte copy count for outer loop -.fbwriterotated +.fbwriterotated1: push bc ; save outer loop count ld a, (v_pr_wkspc) ld b, a ; set up rotate loop count ld a, (de) ; get character bitmap ld c, a ; C contains rightmost fragment of bitmap xor a ; set a=0 to accept lefmost fragment of bitmap -.rotloop +.rotloop1: rl c rla ; suck out leftmost bit from the carry flag - djnz .rotloop -.writerotated + djnz .rotloop1 +.writerotated1: or (hl) ; merge with existing character ld (hl), a ld a, c cp 0 - jr z, .writerotated.skip ; nothing to do + jr z, .writerotated1_skip1 ; nothing to do inc l ; next char cell or (hl) ld (hl), a dec l ; restore l -.writerotated.skip +.writerotated1_skip1: inc h ; next line inc de ; next line of character bitmap pop bc ; retrieve outer loop count - djnz .fbwriterotated -.nextchar + djnz .fbwriterotated1 +.nextchar1: ld a, (v_column) inc a cp 42 - jr nz, .nextchar.done -.nextrow + jr nz, .nextchar1_done1 +.nextrow1: ld a, (v_rowcount) ; check the row counter cp 23 ; 24th line? - jr nz, .noscroll + jr nz, .noscroll1 call F_jumpscroll_impl ld a, 16 ld (v_rowcount), a ld hl, 0x5000 ; address of first row of bottom 1/3rd - jr .nextchar.saverow ; save row addr and complete -.noscroll + jr .nextchar1_saverow1 ; save row addr and complete +.noscroll1: inc a ld (v_rowcount), a ld hl, (v_row) ; advance framebuffer pointer to next character row ld a, l - add 32 - jr c, .nextthird + add a, 32 + jr c, .nextthird1 ld l, a - jr .nextchar.saverow -.nextthird + jr .nextchar1_saverow1 +.nextthird1: ld l, 0 ld a, h - add 8 + add a, 8 ld h, a -.nextchar.saverow +.nextchar1_saverow1: ld (v_row), hl xor a ; a = 0 -.nextchar.done +.nextchar1_done1: ld (v_column), a -.leave +.leave1: pop de pop bc pop hl ret -.norotate +.norotate1: ld b, 8 -.norotate.loop +.norotate1_loop1: ld a, (de) ; move bitmap into the frame buffer ld (hl), a inc de ; next line of bitmap inc h ; next line of frame buffer - djnz .norotate.loop - jr .nextchar + djnz .norotate1_loop1 + jr .nextchar1 ; Support for a subset of utf-8 - a few of the 0xC2 characters ; (€, ¡ and ¿) and all of the 0xC3 characters (mostly accented ; chars and the Spanish ñ character) -.utf8 +.utf81: cp 0xC3 ; 0xC3 chars need no translation - jr z, .leave + jr z, .leave1 ld (v_utf8), a ; else set the UTF8 variable to the byte passed - jr .leave + jr .leave1 -.map_utf8 +.map_utf81: xor a ; reset UTF8 state ld (v_utf8), a ld a, h ; get char cp 0x80 ; euro - ld l, (char_euro-char_space)/8 - jp z, .utf8_continue + ld l, CHARSET_C2_DIST + jp z, .utf8_continue1 cp 0xA1 ; ¡ - ld l, (char_inverted_pling-char_space)/8 - jp z, .utf8_continue + ld l, CHARSET_INVPLING_DIST + jp z, .utf8_continue1 cp 0xA2 ; cent inc l - jp z, .utf8_continue - ld l, (char_inverted_quest-char_space)/8 - jp .utf8_continue + jp z, .utf8_continue1 + ld l, CHARSET_INVQUEST_DIST + jp .utf8_continue1 ;-------------------------------------------------------------------------- ; F_jumpscroll: ; a simple 'jump scroll' which scrolls the screen by 1/3rd. Simpler ; than scrolling one line. -F_jumpscroll_impl +.globl F_jumpscroll_impl +F_jumpscroll_impl: push hl push de push bc @@ -209,7 +214,8 @@ F_jumpscroll_impl ; F_erasechar ; Removes the character at the current 5by8 character position. ; No parameters. -F_erasechar_impl +.globl F_erasechar_impl +F_erasechar_impl: ; Find the address in the frame buffer. ld hl, col_lookup @@ -219,11 +225,11 @@ F_erasechar_impl ld l, a ; hl = pointer to byte in lookup table ld a, (hl) ; a = lookup table value ld hl, (v_row) ; hl = framebuffer pointer for start of row - add l + add a, l ld l, a ; hl = frame buffer address ld a, b ; retrieve column and 3 ; find out how much rotation is needed - jr z, .norotate ; no need to do any at all + jr z, .norotate3 ; no need to do any at all rla ; multiply by 2 ld b, a ; set loop count @@ -232,15 +238,15 @@ F_erasechar_impl ; now create two masks - one for the left byte, and one for the ; right byte. ld c, 0 ; c will contain left mask -.maskloop +.maskloop3: rla rl c - djnz .maskloop -.rotated + djnz .maskloop3 +.rotated3: cpl ; turn it into the proper mask value ld (v_pr_wkspc), a ; save right byte mask ld b, 8 ; 8 bytes high -.rotated_loop +.rotated_loop3: inc l ; right hand byte and (hl) ; make new value ld (hl), a ; write it back @@ -251,23 +257,24 @@ F_erasechar_impl ld (hl), a ; write it back inc h ; next line in frame buffer ld a, (v_pr_wkspc) ; retrieve right byte mask - djnz .rotated_loop + djnz .rotated_loop3 ret ; done -.norotate +.norotate3: ld b, 8 ; 8 bytes high -.norotate_loop +.norotate_loop3: ld a, 0x03 ; mask out left 6 bits and (hl) ; mask out character cell at current position ld (hl), a ; write back to frame buffer inc h - djnz .norotate_loop + djnz .norotate_loop3 ret ; done ;-------------------------------------------------------------------------- ; F_backspace: Perform a backspace (move current character position 1 ; back and delete the right most character). -F_backspace_impl +.globl F_backspace_impl +F_backspace_impl: ld a, (v_column) and a ; Are we at column 0? ret z ; nothing more to do (possible TODO - go back a line) @@ -277,7 +284,8 @@ F_backspace_impl ;-------------------------------------------------------------------------- ; F_clear: Clears the screen to spectranet UI colours. -F_clear_impl +.globl F_clear_impl +F_clear_impl: ld a, 1 out (254), a ; border ld hl, 16384 diff --git a/utils/Makefile b/utils/Makefile new file mode 100644 index 0000000..2dd632a --- /dev/null +++ b/utils/Makefile @@ -0,0 +1,10 @@ +CC = gcc +B2TOBJS = bin2tzx.o +B2TOUT = bin2tzx +RM = rm + +bin2tzx: $(B2TOBJS) + $(CC) -o $(B2TOUT) $(B2TOBJS) + +clean: + $(RM) -f $(B2TOUT) $(B2TOBJS) diff --git a/utils/bin2tzx.c b/utils/bin2tzx.c index 18c15c4..e138031 100644 --- a/utils/bin2tzx.c +++ b/utils/bin2tzx.c @@ -11,17 +11,29 @@ int main(int argc, char **argv) { FILE *infile, *outfile; unsigned short length; + unsigned int start=0x8000; struct stat fileinfo; unsigned char header[20]; unsigned char tzxhdr[6]; unsigned char checksum; unsigned char *buf; - if(argc < 2) + if(argc < 3 || argc > 4) { - printf("Usage: %s \n", argv[0]); + fprintf(stderr, "Usage: %s [start-addr]\n", argv[0]); + fprintf(stderr, "Default start address is 32768\n"); + printf("argc=%d\n",argc); exit(255); } + if(argc == 4) + { + start=strtol(argv[3], NULL, 0); + if(start > 65535) + { + fprintf(stderr,"Start address too large\n"); + exit(255); + } + } if(stat(argv[1], &fileinfo) < 0) { @@ -55,10 +67,10 @@ int main(int argc, char **argv) /* little-endian size */ header[12]=length % 256; header[13]=length / 256; - header[14]=0; /* LSB of 0x8000 */ - header[15]=0x80; /* MSB of 0x8000 */ - header[16]=0; /* and again */ - header[17]=0x80; + header[14]=start & (0xFF); + header[15]=(start >> 8) & (0xFF); + header[16]=header[14]; /* and again */ + header[17]=header[15]; header[18]=getChecksum(header, 18); diff --git a/utils/flashwrite.asm b/utils/flashwrite.asm deleted file mode 100644 index 1a9cf7d..0000000 --- a/utils/flashwrite.asm +++ /dev/null @@ -1,76 +0,0 @@ -; Simple flash writer for the Am29F010 (and probably any 1 megabit flash -; with 16kbyte sectors) -; Pass the page in A -; On error, carry flag set. -F_FlashEraseSectorZero - ld a, 0xAA ; unlock code 1 - ld (0x555), a ; unlock addr 1 - ld a, 0x55 ; unlock code 2 - ld (0x2AA), a ; unlock addr 2 - ld a, 0x80 ; erase cmd 1 - ld (0x555), a ; erase cmd addr 1 - ld a, 0xAA ; erase cmd 2 - ld (0x555), a ; erase cmd addr 2 - ld a, 0x55 ; erase cmd 3 - ld (0x2AA), a ; erase cmd addr 3 - ld a, 0x30 ; erase cmd 4 - ld (0x0000), a ; erase sector address - - ld hl, 0 -.wait - bit 7, (hl) ; test DQ7 - should be 1 when complete - jr nz, .complete - bit 5, (hl) ; test DQ5 - should be 1 to continue - jr z, .wait - bit 7, (hl) ; test DQ7 again - jr z, .borked - -.complete - or 0 ; clear carry flag - ret - -.borked - scf ; carry flag = error - ret - -; F_FlashWriteByte -; Write the byte in A to the address pointed at by DE. -; On return, carry flag set = error -F_FlashWriteByte - push bc - ld c, a ; save A - - ld a, #AA ; unlock 1 - ld (0x555), a ; unlock address 1 - ld a, 0x55 ; unlock 2 - ld (0x2AA), a ; unlock address 2 - ld a, 0xA0 ; Program - ld (0x555), a ; Program address - ld a, c ; retrieve A - ld (de), a ; program it - -.wait - ld a, (de) ; read programmed address - ld b, a ; save status - xor c - bit 7, a ; If bit 7 = 0 then bit 7 = data - jr z, .byteComplete - - bit 5, b ; test DQ5 - jr z, .wait - - ld a, (de) ; read programmed address - xor c - bit 7, a ; Does DQ7 = programmed data? 0 if true - jr nz, .borked - -.byteComplete - pop bc - or 0 ; clear carry flag - ret - -.borked - pop bc - scf ; error = set carry flag - ret - diff --git a/utils/fsconfig.asm b/utils/fsconfig.asm deleted file mode 100644 index 2d5b70f..0000000 --- a/utils/fsconfig.asm +++ /dev/null @@ -1,12 +0,0 @@ - org 0x8000 - - include "../rom/spectranet.asm" - - call PAGEIN - - -J_exit - jp PAGEOUT - - include "../rom/flashwrite.asm" - diff --git a/z88dk/Makefile b/z88dk/Makefile new file mode 100644 index 0000000..0fe1edb --- /dev/null +++ b/z88dk/Makefile @@ -0,0 +1,16 @@ +SUBDIRS = libspectranet socklib libhttp + +.PHONY: subdirs $(SUBDIRS) + +.PHONY: clean + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) -C $@ + +clean: + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean; \ + done + diff --git a/libhttp/Makefile b/z88dk/libhttp/Makefile similarity index 64% rename from libhttp/Makefile rename to z88dk/libhttp/Makefile index 9f75361..6e67983 100644 --- a/libhttp/Makefile +++ b/z88dk/libhttp/Makefile @@ -1,17 +1,11 @@ # Makefile for the simple HTTP library. -CC = zcc LIBNAME = libhttp -RM = rm -f -LIBLINKER = z80asm -ASSEMBLER = z80asm COBJS = addFormData.o freeFormData.o parseURI.o parseproto.o \ allocURI.o freeURI.o base64enc.o request.o readData.o \ postsize.o getheader.o freeheaders.o readHeaders.o htrecv.o CFLAGS = -I./include -O2 -preserve -vn -make-lib all: $(COBJS) - $(LIBLINKER) -d -ns -nm -Mo -x$(LIBNAME) $(COBJS) - -clean: - $(RM) $(COBJS) $(TESTOBJS) $(TESTOUT) $(LIBNAME) + $(LIBLINKER) $(LIBLDFLAGS) -x$(LIBNAME) $(COBJS) +include ../make.inc diff --git a/libhttp/addFormData.c b/z88dk/libhttp/addFormData.c similarity index 100% rename from libhttp/addFormData.c rename to z88dk/libhttp/addFormData.c diff --git a/libhttp/allocURI.c b/z88dk/libhttp/allocURI.c similarity index 100% rename from libhttp/allocURI.c rename to z88dk/libhttp/allocURI.c diff --git a/libhttp/base64enc.c b/z88dk/libhttp/base64enc.c similarity index 100% rename from libhttp/base64enc.c rename to z88dk/libhttp/base64enc.c diff --git a/libhttp/freeFormData.c b/z88dk/libhttp/freeFormData.c similarity index 100% rename from libhttp/freeFormData.c rename to z88dk/libhttp/freeFormData.c diff --git a/libhttp/freeURI.c b/z88dk/libhttp/freeURI.c similarity index 100% rename from libhttp/freeURI.c rename to z88dk/libhttp/freeURI.c diff --git a/libhttp/freeheaders.c b/z88dk/libhttp/freeheaders.c similarity index 100% rename from libhttp/freeheaders.c rename to z88dk/libhttp/freeheaders.c diff --git a/libhttp/getheader.c b/z88dk/libhttp/getheader.c similarity index 100% rename from libhttp/getheader.c rename to z88dk/libhttp/getheader.c diff --git a/libhttp/htrecv.c b/z88dk/libhttp/htrecv.c similarity index 100% rename from libhttp/htrecv.c rename to z88dk/libhttp/htrecv.c diff --git a/libhttp/include/http.h b/z88dk/libhttp/include/http.h similarity index 100% rename from libhttp/include/http.h rename to z88dk/libhttp/include/http.h diff --git a/libhttp/parseURI.c b/z88dk/libhttp/parseURI.c similarity index 100% rename from libhttp/parseURI.c rename to z88dk/libhttp/parseURI.c diff --git a/libhttp/parseproto.c b/z88dk/libhttp/parseproto.c similarity index 100% rename from libhttp/parseproto.c rename to z88dk/libhttp/parseproto.c diff --git a/libhttp/postsize.c b/z88dk/libhttp/postsize.c similarity index 100% rename from libhttp/postsize.c rename to z88dk/libhttp/postsize.c diff --git a/libhttp/readData.c b/z88dk/libhttp/readData.c similarity index 100% rename from libhttp/readData.c rename to z88dk/libhttp/readData.c diff --git a/libhttp/readHeaders.c b/z88dk/libhttp/readHeaders.c similarity index 100% rename from libhttp/readHeaders.c rename to z88dk/libhttp/readHeaders.c diff --git a/libhttp/request.c b/z88dk/libhttp/request.c similarity index 100% rename from libhttp/request.c rename to z88dk/libhttp/request.c diff --git a/libspectranet/Makefile b/z88dk/libspectranet/Makefile similarity index 85% rename from libspectranet/Makefile rename to z88dk/libspectranet/Makefile index 42484c5..e0d322a 100644 --- a/libspectranet/Makefile +++ b/z88dk/libspectranet/Makefile @@ -1,14 +1,10 @@ # Makefile to build the Spectranet C library. -ASSEMBLER = z80asm SRCGEN = ./makesources.pl PLIBNAME = libspectranet NPLIBNAME = libspectranet_np -ASMFLAGS = -d -ns -nm -Mo PASMFILES = libspectranet.lst NPASMFILES = libspectranet_np.lst -RM = rm -f -CC = zcc TESTOUT = testlibsn.bin BASOUT = testbas.bin CFLAGS = +zx -vn -I./include -O2 -preserve @@ -16,6 +12,7 @@ COBJS = testlibsn.o BASOBJS = testbasext.o CLIBS = -lndos -llibspectranet +all: plib nplib plib: $(PASMFILES) $(SRCGEN) @@ -31,6 +28,4 @@ test: $(COBJS) basext: $(BASOBJS) $(CC) $(CFLAGS) -o $(BASOUT) $(BASOBJS) $(CLIBS) -clean: - $(RM) $(LIBNAME).lib *.o *_p.asm *_np.asm - +include ../make.inc diff --git a/libspectranet/addbasicext.asm b/z88dk/libspectranet/addbasicext.asm similarity index 100% rename from libspectranet/addbasicext.asm rename to z88dk/libspectranet/addbasicext.asm diff --git a/libspectranet/deconfig.asm b/z88dk/libspectranet/deconfig.asm similarity index 100% rename from libspectranet/deconfig.asm rename to z88dk/libspectranet/deconfig.asm diff --git a/libspectranet/exit_success.asm b/z88dk/libspectranet/exit_success.asm similarity index 100% rename from libspectranet/exit_success.asm rename to z88dk/libspectranet/exit_success.asm diff --git a/libspectranet/expect2num.asm b/z88dk/libspectranet/expect2num.asm similarity index 100% rename from libspectranet/expect2num.asm rename to z88dk/libspectranet/expect2num.asm diff --git a/libspectranet/expectnum.asm b/z88dk/libspectranet/expectnum.asm similarity index 100% rename from libspectranet/expectnum.asm rename to z88dk/libspectranet/expectnum.asm diff --git a/libspectranet/expectstringexp.asm b/z88dk/libspectranet/expectstringexp.asm similarity index 100% rename from libspectranet/expectstringexp.asm rename to z88dk/libspectranet/expectstringexp.asm diff --git a/libspectranet/find_int1.asm b/z88dk/libspectranet/find_int1.asm similarity index 100% rename from libspectranet/find_int1.asm rename to z88dk/libspectranet/find_int1.asm diff --git a/libspectranet/find_int2.asm b/z88dk/libspectranet/find_int2.asm similarity index 100% rename from libspectranet/find_int2.asm rename to z88dk/libspectranet/find_int2.asm diff --git a/libspectranet/get_ifconfig_gw.asm b/z88dk/libspectranet/get_ifconfig_gw.asm similarity index 100% rename from libspectranet/get_ifconfig_gw.asm rename to z88dk/libspectranet/get_ifconfig_gw.asm diff --git a/libspectranet/get_ifconfig_inet.asm b/z88dk/libspectranet/get_ifconfig_inet.asm similarity index 100% rename from libspectranet/get_ifconfig_inet.asm rename to z88dk/libspectranet/get_ifconfig_inet.asm diff --git a/libspectranet/get_ifconfig_netmask.asm b/z88dk/libspectranet/get_ifconfig_netmask.asm similarity index 100% rename from libspectranet/get_ifconfig_netmask.asm rename to z88dk/libspectranet/get_ifconfig_netmask.asm diff --git a/libspectranet/gethwaddr.asm b/z88dk/libspectranet/gethwaddr.asm similarity index 100% rename from libspectranet/gethwaddr.asm rename to z88dk/libspectranet/gethwaddr.asm diff --git a/libspectranet/ifconfig_gw.asm b/z88dk/libspectranet/ifconfig_gw.asm similarity index 100% rename from libspectranet/ifconfig_gw.asm rename to z88dk/libspectranet/ifconfig_gw.asm diff --git a/libspectranet/ifconfig_inet.asm b/z88dk/libspectranet/ifconfig_inet.asm similarity index 100% rename from libspectranet/ifconfig_inet.asm rename to z88dk/libspectranet/ifconfig_inet.asm diff --git a/libspectranet/ifconfig_netmask.asm b/z88dk/libspectranet/ifconfig_netmask.asm similarity index 100% rename from libspectranet/ifconfig_netmask.asm rename to z88dk/libspectranet/ifconfig_netmask.asm diff --git a/libspectranet/include/basicext.h b/z88dk/libspectranet/include/basicext.h similarity index 100% rename from libspectranet/include/basicext.h rename to z88dk/libspectranet/include/basicext.h diff --git a/libspectranet/include/spectranet.h b/z88dk/libspectranet/include/spectranet.h similarity index 100% rename from libspectranet/include/spectranet.h rename to z88dk/libspectranet/include/spectranet.h diff --git a/libspectranet/ipstring2long.asm b/z88dk/libspectranet/ipstring2long.asm similarity index 100% rename from libspectranet/ipstring2long.asm rename to z88dk/libspectranet/ipstring2long.asm diff --git a/libspectranet/ipstring2long_callee.asm b/z88dk/libspectranet/ipstring2long_callee.asm similarity index 100% rename from libspectranet/ipstring2long_callee.asm rename to z88dk/libspectranet/ipstring2long_callee.asm diff --git a/libspectranet/libspectranet.lst b/z88dk/libspectranet/libspectranet.lst similarity index 100% rename from libspectranet/libspectranet.lst rename to z88dk/libspectranet/libspectranet.lst diff --git a/libspectranet/libspectranet_np.lst b/z88dk/libspectranet/libspectranet_np.lst similarity index 100% rename from libspectranet/libspectranet_np.lst rename to z88dk/libspectranet/libspectranet_np.lst diff --git a/libspectranet/long2ipstring.asm b/z88dk/libspectranet/long2ipstring.asm similarity index 100% rename from libspectranet/long2ipstring.asm rename to z88dk/libspectranet/long2ipstring.asm diff --git a/libspectranet/long2ipstring_callee.asm b/z88dk/libspectranet/long2ipstring_callee.asm similarity index 100% rename from libspectranet/long2ipstring_callee.asm rename to z88dk/libspectranet/long2ipstring_callee.asm diff --git a/libspectranet/mac2string.asm b/z88dk/libspectranet/mac2string.asm similarity index 100% rename from libspectranet/mac2string.asm rename to z88dk/libspectranet/mac2string.asm diff --git a/libspectranet/mac2string_callee.asm b/z88dk/libspectranet/mac2string_callee.asm similarity index 100% rename from libspectranet/mac2string_callee.asm rename to z88dk/libspectranet/mac2string_callee.asm diff --git a/libspectranet/makesources.pl b/z88dk/libspectranet/makesources.pl similarity index 100% rename from libspectranet/makesources.pl rename to z88dk/libspectranet/makesources.pl diff --git a/libspectranet/next_char.asm b/z88dk/libspectranet/next_char.asm similarity index 100% rename from libspectranet/next_char.asm rename to z88dk/libspectranet/next_char.asm diff --git a/libspectranet/pagein.asm b/z88dk/libspectranet/pagein.asm similarity index 100% rename from libspectranet/pagein.asm rename to z88dk/libspectranet/pagein.asm diff --git a/libspectranet/pageout.asm b/z88dk/libspectranet/pageout.asm similarity index 100% rename from libspectranet/pageout.asm rename to z88dk/libspectranet/pageout.asm diff --git a/libspectranet/sethwaddr.asm b/z88dk/libspectranet/sethwaddr.asm similarity index 100% rename from libspectranet/sethwaddr.asm rename to z88dk/libspectranet/sethwaddr.asm diff --git a/libspectranet/setpagea.asm b/z88dk/libspectranet/setpagea.asm similarity index 100% rename from libspectranet/setpagea.asm rename to z88dk/libspectranet/setpagea.asm diff --git a/libspectranet/setpageb.asm b/z88dk/libspectranet/setpageb.asm similarity index 100% rename from libspectranet/setpageb.asm rename to z88dk/libspectranet/setpageb.asm diff --git a/libspectranet/spectranet.asm b/z88dk/libspectranet/spectranet.asm similarity index 100% rename from libspectranet/spectranet.asm rename to z88dk/libspectranet/spectranet.asm diff --git a/libspectranet/statement_end.asm b/z88dk/libspectranet/statement_end.asm similarity index 100% rename from libspectranet/statement_end.asm rename to z88dk/libspectranet/statement_end.asm diff --git a/libspectranet/string_fetch.asm b/z88dk/libspectranet/string_fetch.asm similarity index 100% rename from libspectranet/string_fetch.asm rename to z88dk/libspectranet/string_fetch.asm diff --git a/libspectranet/string_fetch_callee.asm b/z88dk/libspectranet/string_fetch_callee.asm similarity index 100% rename from libspectranet/string_fetch_callee.asm rename to z88dk/libspectranet/string_fetch_callee.asm diff --git a/libspectranet/testbasext.c b/z88dk/libspectranet/testbasext.c similarity index 100% rename from libspectranet/testbasext.c rename to z88dk/libspectranet/testbasext.c diff --git a/libspectranet/testlibsn.c b/z88dk/libspectranet/testlibsn.c similarity index 100% rename from libspectranet/testlibsn.c rename to z88dk/libspectranet/testlibsn.c diff --git a/libspectranet/zxromdefs.asm b/z88dk/libspectranet/zxromdefs.asm similarity index 100% rename from libspectranet/zxromdefs.asm rename to z88dk/libspectranet/zxromdefs.asm diff --git a/z88dk/make.inc b/z88dk/make.inc new file mode 100644 index 0000000..255502e --- /dev/null +++ b/z88dk/make.inc @@ -0,0 +1,13 @@ +# make.inc file for z88dk libraries +CC = zcc +LIBLINKER = z80asm +ASSEMBLER = z80asm +RM = rm -f +LIBLDFLAGS = -d -ns -nm -Mo +ASMFLAGS = -d -ns -nm -Mo + +.PHONY: clean + +clean: + $(RM) *.o *.lib *.def *_p.asm *_np.asm + diff --git a/socklib/Makefile b/z88dk/socklib/Makefile similarity index 87% rename from socklib/Makefile rename to z88dk/socklib/Makefile index b98195e..70ea54c 100644 --- a/socklib/Makefile +++ b/z88dk/socklib/Makefile @@ -1,15 +1,10 @@ # Makefile to build the Spectranet C library. - -ASSEMBLER = z80asm SRCGEN = ./makesources.pl LIBNAME = libsocket -ASMFLAGS = -d -ns -nm -Mo PASMFILES = libsocket.lst NPASMFILES = libsocket_np.lst PLIBNAME = libsocket NPLIBNAME = libsocket_np -RM = rm -f -CC = zcc TESTOUT = testsocks.bin NPTESTOUT = testsocks_np.bin CFLAGS = +zx -vn -I./include -O2 -preserve @@ -18,6 +13,7 @@ NPCOBJS = np_testsocks.o testclient.o nonmuxserver.o muxserver.o testudpserv.o CLIBS = -lndos -llibsocket NPCLIBS = -lndos -llibsocket_np +all: plib nplib plib: $(PASMFILES) $(SRCGEN) @@ -33,6 +29,4 @@ test: $(COBJS) nptest: $(NPCOBJS) $(CC) $(CFLAGS) -o $(NPTESTOUT) $(NPCOBJS) $(NPCLIBS) -clean: - $(RM) $(LIBNAME).lib *.o *_p.asm *_np.asm - +include ../make.inc diff --git a/socklib/accept.asm b/z88dk/socklib/accept.asm similarity index 100% rename from socklib/accept.asm rename to z88dk/socklib/accept.asm diff --git a/socklib/accept_callee.asm b/z88dk/socklib/accept_callee.asm similarity index 100% rename from socklib/accept_callee.asm rename to z88dk/socklib/accept_callee.asm diff --git a/socklib/bind.asm b/z88dk/socklib/bind.asm similarity index 100% rename from socklib/bind.asm rename to z88dk/socklib/bind.asm diff --git a/socklib/bind_callee.asm b/z88dk/socklib/bind_callee.asm similarity index 100% rename from socklib/bind_callee.asm rename to z88dk/socklib/bind_callee.asm diff --git a/socklib/connect.asm b/z88dk/socklib/connect.asm similarity index 100% rename from socklib/connect.asm rename to z88dk/socklib/connect.asm diff --git a/socklib/connect_callee.asm b/z88dk/socklib/connect_callee.asm similarity index 100% rename from socklib/connect_callee.asm rename to z88dk/socklib/connect_callee.asm diff --git a/socklib/gethostbyname.asm b/z88dk/socklib/gethostbyname.asm similarity index 100% rename from socklib/gethostbyname.asm rename to z88dk/socklib/gethostbyname.asm diff --git a/socklib/include/netdb.h b/z88dk/socklib/include/netdb.h similarity index 100% rename from socklib/include/netdb.h rename to z88dk/socklib/include/netdb.h diff --git a/socklib/include/sockpoll.h b/z88dk/socklib/include/sockpoll.h similarity index 100% rename from socklib/include/sockpoll.h rename to z88dk/socklib/include/sockpoll.h diff --git a/socklib/include/sys/socket.h b/z88dk/socklib/include/sys/socket.h similarity index 100% rename from socklib/include/sys/socket.h rename to z88dk/socklib/include/sys/socket.h diff --git a/socklib/libsocket.lst b/z88dk/socklib/libsocket.lst similarity index 100% rename from socklib/libsocket.lst rename to z88dk/socklib/libsocket.lst diff --git a/socklib/libsocket_np.lst b/z88dk/socklib/libsocket_np.lst similarity index 100% rename from socklib/libsocket_np.lst rename to z88dk/socklib/libsocket_np.lst diff --git a/socklib/listen.asm b/z88dk/socklib/listen.asm similarity index 100% rename from socklib/listen.asm rename to z88dk/socklib/listen.asm diff --git a/socklib/listen_callee.asm b/z88dk/socklib/listen_callee.asm similarity index 100% rename from socklib/listen_callee.asm rename to z88dk/socklib/listen_callee.asm diff --git a/socklib/makesources.pl b/z88dk/socklib/makesources.pl similarity index 100% rename from socklib/makesources.pl rename to z88dk/socklib/makesources.pl diff --git a/socklib/muxserver.c b/z88dk/socklib/muxserver.c similarity index 100% rename from socklib/muxserver.c rename to z88dk/socklib/muxserver.c diff --git a/socklib/nonmuxserver.c b/z88dk/socklib/nonmuxserver.c similarity index 100% rename from socklib/nonmuxserver.c rename to z88dk/socklib/nonmuxserver.c diff --git a/socklib/np_testsocks.c b/z88dk/socklib/np_testsocks.c similarity index 100% rename from socklib/np_testsocks.c rename to z88dk/socklib/np_testsocks.c diff --git a/socklib/pollall.asm b/z88dk/socklib/pollall.asm similarity index 100% rename from socklib/pollall.asm rename to z88dk/socklib/pollall.asm diff --git a/socklib/pollfd.asm b/z88dk/socklib/pollfd.asm similarity index 100% rename from socklib/pollfd.asm rename to z88dk/socklib/pollfd.asm diff --git a/socklib/recv.asm b/z88dk/socklib/recv.asm similarity index 100% rename from socklib/recv.asm rename to z88dk/socklib/recv.asm diff --git a/socklib/recv_callee.asm b/z88dk/socklib/recv_callee.asm similarity index 100% rename from socklib/recv_callee.asm rename to z88dk/socklib/recv_callee.asm diff --git a/socklib/recvfrom_callee.asm b/z88dk/socklib/recvfrom_callee.asm similarity index 100% rename from socklib/recvfrom_callee.asm rename to z88dk/socklib/recvfrom_callee.asm diff --git a/socklib/send.asm b/z88dk/socklib/send.asm similarity index 100% rename from socklib/send.asm rename to z88dk/socklib/send.asm diff --git a/socklib/send_callee.asm b/z88dk/socklib/send_callee.asm similarity index 100% rename from socklib/send_callee.asm rename to z88dk/socklib/send_callee.asm diff --git a/socklib/sendto_callee.asm b/z88dk/socklib/sendto_callee.asm similarity index 100% rename from socklib/sendto_callee.asm rename to z88dk/socklib/sendto_callee.asm diff --git a/socklib/sockclose.asm b/z88dk/socklib/sockclose.asm similarity index 100% rename from socklib/sockclose.asm rename to z88dk/socklib/sockclose.asm diff --git a/socklib/socket.asm b/z88dk/socklib/socket.asm similarity index 100% rename from socklib/socket.asm rename to z88dk/socklib/socket.asm diff --git a/socklib/socket_callee.asm b/z88dk/socklib/socket_callee.asm similarity index 100% rename from socklib/socket_callee.asm rename to z88dk/socklib/socket_callee.asm diff --git a/socklib/spectranet.asm b/z88dk/socklib/spectranet.asm similarity index 100% rename from socklib/spectranet.asm rename to z88dk/socklib/spectranet.asm diff --git a/socklib/testclient.c b/z88dk/socklib/testclient.c similarity index 100% rename from socklib/testclient.c rename to z88dk/socklib/testclient.c diff --git a/socklib/testsocks.c b/z88dk/socklib/testsocks.c similarity index 100% rename from socklib/testsocks.c rename to z88dk/socklib/testsocks.c diff --git a/socklib/testudpserv.c b/z88dk/socklib/testudpserv.c similarity index 100% rename from socklib/testudpserv.c rename to z88dk/socklib/testudpserv.c