From 3ffe25098b3d18a68c001e223cbdecf043e44c86 Mon Sep 17 00:00:00 2001 From: jonnosan Date: Fri, 10 Apr 2009 01:19:42 +0000 Subject: [PATCH] simplified NB65 - this is now release candidate for 1.0 of the API definition (although not necessarily the implementation) git-svn-id: http://svn.code.sf.net/p/netboot65/code@92 93682198-c243-4bdb-bd91-e943c89aac3b --- client/cfg/rrbin.cfg | 4 +-- client/clients/rrnetboot.s | 26 +++----------- client/inc/commonprint.i | 29 ++++++++++----- client/inc/nb65_constants.i | 43 +++++++++++----------- client/ip65/function_dispatcher.s | 52 +++++++-------------------- client/test/test_cart_api.s | 26 ++------------ doc/nb65_api_technical_reference.doc | Bin 0 -> 99328 bytes 7 files changed, 65 insertions(+), 115 deletions(-) create mode 100644 doc/nb65_api_technical_reference.doc diff --git a/client/cfg/rrbin.cfg b/client/cfg/rrbin.cfg index 9e2c894..2712386 100644 --- a/client/cfg/rrbin.cfg +++ b/client/cfg/rrbin.cfg @@ -4,8 +4,8 @@ MEMORY { ZP: start = $02, size = $1A, type = rw, define = yes; IP65ZP: start = $5f, size = $10, type = rw, define = yes; - HEADER: start = $8000, size = $16, file = %O; - ROM: start = $8016, size = $1F00, define = yes, file = %O; + HEADER: start = $8000, size = $18, file = %O; + ROM: start = $8018, size = $1F00, define = yes, file = %O; RAM: start = $C080, size = $0f80, define = yes; diff --git a/client/clients/rrnetboot.s b/client/clients/rrnetboot.s index 5a342db..f66c1f5 100644 --- a/client/clients/rrnetboot.s +++ b/client/clients/rrnetboot.s @@ -38,7 +38,6 @@ .import print_hex .import print_ip_config - .import dhcp_msg .import ok_msg .import failed_msg .import init_msg @@ -72,6 +71,8 @@ nb65_param_buffer: .res $20 .word $FE47 ;warm start vector .byte $C3,$C2,$CD,$38,$30 ; "CBM80" .byte $4E,$42,$36,$35 ; "NB65" - API signature +.byte $01 ;NB65_API_VERSION +.byte $02 ;NB65_BANKSWITCH_SUPPORT jmp nb65_dispatcher ; NB65_DISPATCH_VECTOR : entry point for NB65 functions jmp ip65_process ;NB65_PERIODIC_PROCESSING_VECTOR : routine to be periodically called to check for arrival of ethernet packects jmp timer_vbl_handler ;NB65_VBL_VECTOR : routine to be called during each vertical blank interrupt @@ -133,13 +134,10 @@ init: @tftp_boot: - ldy #NB65_GET_DRIVER_NAME - jsr NB65_DISPATCH_VECTOR - jsr print ldax #init_msg jsr print - ldy #NB65_INIT_IP + ldy #NB65_INITIALIZE jsr NB65_DISPATCH_VECTOR bcc :+ @@ -150,20 +148,6 @@ init: print_ok - ldax #dhcp_msg - jsr print - ldax #init_msg - jsr print - - ldy #NB65_INIT_DHCP - jsr NB65_DISPATCH_VECTOR - bcc :+ - print_failed - jsr print_errorcode - jmp bad_boot -: - print_ok - jsr print_ip_config ldax #press_a_key_to_continue @@ -226,8 +210,8 @@ init: @file_downloaded_ok: - ;remove the IP timer code from IRQ chain - ldy #NB65_UNHOOK_VBL_IRQ + ;get ready to bank out + ldy #NB65_DEACTIVATE jsr NB65_DISPATCH_VECTOR ;check whether the file we just downloaded was a BASIC prg diff --git a/client/inc/commonprint.i b/client/inc/commonprint.i index 9dc40cd..b5ec7c6 100644 --- a/client/inc/commonprint.i +++ b/client/inc/commonprint.i @@ -7,7 +7,9 @@ .export failed_msg .export init_msg .export print - .export print_decimal + .export print_decimal +.import cs_driver_name + .zeropage pptr: .res 2 .bss @@ -49,8 +51,14 @@ temp_bcd: .res 2 .import print_cr .import cs_driver_name print_ip_config: - + ldax #interface_type + jsr print + + ldax #cs_driver_name + jsr print + jsr print_cr + ldax #mac_address_msg jsr print jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear @@ -245,29 +253,32 @@ print_hex: hexdigits: .byte "0123456789ABCDEF" +interface_type: +.byte "INTERFACE : ",0 + mac_address_msg: - .byte "MAC ADDRESS: ", 0 +.byte "MAC ADDRESS : ", 0 ip_address_msg: - .byte "IP ADDRESS: ", 0 +.byte "IP ADDRESS : ", 0 netmask_msg: - .byte "NETMASK: ", 0 +.byte "NETMASK : ", 0 gateway_msg: - .byte "GATEWAY: ", 0 +.byte "GATEWAY : ", 0 dns_server_msg: - .byte "DNS SERVER: ", 0 +.byte "DNS SERVER : ", 0 dhcp_server_msg: - .byte "DHCP SERVER:", 0 +.byte "DHCP SERVER : ", 0 dhcp_msg: .byte "DHCP",0 init_msg: - .byte " INIT ",0 + .byte "INIT ",0 failed_msg: .byte "FAILED", 0 diff --git a/client/inc/nb65_constants.i b/client/inc/nb65_constants.i index 5b51f46..8f26bce 100644 --- a/client/inc/nb65_constants.i +++ b/client/inc/nb65_constants.i @@ -1,12 +1,14 @@ -.ifndef NB65_API_VERSION +.ifndef NB65_API_VERSION_NUMBER -NB65_API_VERSION=$0001 +NB65_API_VERSION_NUMBER=$01 NB65_CART_SIGNATURE = $8009 -NB65_DISPATCH_VECTOR = $800d -NB65_PERIODIC_PROCESSING_VECTOR = $8010 -NB65_VBL_VECTOR = $8013 +NB65_API_VERSION = $800d +NB65_BANKSWITCH_SUPPORT = $800e +NB65_DISPATCH_VECTOR = $800f +NB65_PERIODIC_PROCESSING_VECTOR = $8012 +NB65_VBL_VECTOR = $8015 NB65_RAM_STUB_SIGNATURE = $C000 NB65_RAM_STUB_ACTIVATE = $C004 @@ -19,20 +21,17 @@ NB65_RAM_STUB_ACTIVATE = $C004 ; some functions return results in AX directly, others will update the parameter buffer they were called with. ; any register not specified in outputs will have an undefined value on exit -NB65_GET_DRIVER_NAME =$01 ;no inputs, outputs AX=pointer to asciiz driver name -NB65_GET_IP_CONFIG =$02 ;AX=pointer to buffer where IP configuration structure written, outputs AX=points to same buffer, which has now been written to -NB65_SET_IP_CONFIG =$03 ;AX=pointer to buffer where IP configuration structure written, outputs AX=points to same buffer, which has now been written to -NB65_INIT_IP =$04 ;no inputs or outputs - also sets IRQ chain to call NB65_VBL_VECTOR at @ 60hz -NB65_INIT_DHCP =$05 ;no inputs or outputs (NB65_INIT_IP should be called first -NB65_TFTP_DIRECTORY_LISTING =$06 ;inputs: AX points to a TFTP parameter structure, outputs: none -NB65_TFTP_DOWNLOAD =$07 ;inputs: AX points to a TFTP parameter structure, outputs: TFTP param structure updated with +NB65_INITIALIZE =$01 ;no inputs or outputs - initializes IP stack, also sets IRQ chain to call NB65_VBL_VECTOR at @ 60hz +NB65_GET_IP_CONFIG =$02 ;no inputs, outputs AX=pointer to IP configuration structure +NB65_TFTP_DIRECTORY_LISTING =$03 ;inputs: AX points to a TFTP parameter structure, outputs: none +NB65_TFTP_DOWNLOAD =$04 ;inputs: AX points to a TFTP parameter structure, outputs: TFTP param structure updated with ;NB65_TFTP_POINTER updated to reflect actual load address (if load address $0000 originally passed in) -NB65_DNS_RESOLVE_HOSTNAME =$08 ;inputs: AX points to a DNS parameter structure, outputs: DNS param structure updated with +NB65_DNS_RESOLVE =$05 ;inputs: AX points to a DNS parameter structure, outputs: DNS param structure updated with ;NB65_DNS_HOSTNAME_IP updated with IP address corresponding to hostname. -NB65_UDP_ADD_LISTENER =$09 ;inputs: AX points to a UDP listener parameter structure, outputs: none -NB65_GET_INPUT_PACKET_INFO =$0A ;inputs: AX points to a UDP packet parameter structure, outputs: UDP packet structure filled in -NB65_SEND_UDP_PACKET =$0B ;inputs: AX points to a UDP packet parameter structure, outputs: none packet is sent -NB65_UNHOOK_VBL_IRQ =$0C ;inputs: none, outputs: none (removes call to NB65_VBL_VECTOR on IRQ chain) +NB65_UDP_ADD_LISTENER =$06 ;inputs: AX points to a UDP listener parameter structure, outputs: none +NB65_GET_INPUT_PACKET_INFO =$07 ;inputs: AX points to a UDP packet parameter structure, outputs: UDP packet structure filled in +NB65_SEND_UDP_PACKET =$08 ;inputs: AX points to a UDP packet parameter structure, outputs: none packet is sent +NB65_DEACTIVATE =$09 ;inputs: none, outputs: none (removes call to NB65_VBL_VECTOR on IRQ chain) NB65_PRINT_ASCIIZ =$80 ;inputs: AX= pointer to null terminated string to be printed to screen, outputs: none NB65_PRINT_HEX =$81 ;inputs: A = byte digit to be displayed on screen as (zero padded) hex digit, outputs: none @@ -43,20 +42,21 @@ NB65_PRINT_IP_CONFIG =$83 ;no inputs, no outputs, prints to screen curr NB65_GET_LAST_ERROR =$FF ;no inputs, outputs A = error code (from last function that set the global error value, not necessarily the ;last function that was called) -;offsets in NB65 configuration structure +;offsets in IP configuration structure (used by NB65_GET_IP_CONFIG) NB65_CFG_MAC = $00 ;6 byte MAC address NB65_CFG_IP = $06 ;4 byte local IP address (will be overwritten by DHCP) NB65_CFG_NETMASK = $0A ;4 byte local netmask (will be overwritten by DHCP) NB65_CFG_GATEWAY = $0D ;4 byte local gateway (will be overwritten by DHCP) NB65_CFG_DNS_SERVER = $12 ;4 byte IP address of DNS server (will be overwritten by DHCP) NB65_CFG_DHCP_SERVER = $16 ;4 byte IP address of DHCP server (will only be set by DHCP initialisation) +NB65_DRIVER_NAME = $1A ;2 byte pointer to name of driver -;offsets in TFTP parameter structure +;offsets in TFTP parameter structure (used by NB65_TFTP_DIRECTORY_LISTING & NB65_TFTP_DOWNLOAD) NB65_TFTP_IP = $00 ;4 byte IP address of TFTP server NB65_TFTP_FILENAME = $04 ;2 byte pointer to asciiz filename (or filemask in case of NB65_TFTP_DIRECTORY_LISTING) -NB65_TFTP_POINTER = $06 ;2 byte pointer to memory location data to be stored in OR address of tftp callback +NB65_TFTP_POINTER = $06 ;2 byte pointer to memory location data to be stored in -;offsets in TFTP parameter structure +;offsets in DNS parameter structure (used by NB65_DNS_RESOLVE) NB65_DNS_HOSTNAME = $00 ;2 byte pointer to asciiz hostname to resolve (can also be a dotted quad string) NB65_DNS_HOSTNAME_IP= $00 ;4 byte IP address (filled in on succesful resolution of hostname) @@ -77,6 +77,7 @@ NB65_ERROR_TIMEOUT_ON_RECEIVE = $81 NB65_ERROR_TRANSMIT_FAILED = $82 NB65_ERROR_TRANSMISSION_REJECTED_BY_PEER = $83 NB65_ERROR_INPUT_TOO_LARGE = $84 +NB65_ERROR_DEVICE_FAILURE = $85 NB65_ERROR_OPTION_NOT_SUPPORTED = $FE NB65_ERROR_FUNCTION_NOT_SUPPORTED = $FF diff --git a/client/ip65/function_dispatcher.s b/client/ip65/function_dispatcher.s index 56b0398..4b359ee 100644 --- a/client/ip65/function_dispatcher.s +++ b/client/ip65/function_dispatcher.s @@ -10,7 +10,6 @@ .import ip65_init .import dhcp_init -.import cs_driver_name .import cfg_get_configuration_ptr .import tftp_load_address .importzp tftp_filename @@ -91,38 +90,8 @@ nb65_dispatcher: stax nb65_params - cpy #NB65_GET_DRIVER_NAME - bne :+ - ldax #cs_driver_name - clc - rts -: - cpy #NB65_GET_IP_CONFIG - bne :+ - stax copy_dest - ldax #cfg_mac - stax copy_src - ldax #NB65_CFG_DHCP_SERVER+4 ;bytes to copy - jsr copymem - clc - ldax nb65_params - rts -: - - cpy #NB65_SET_IP_CONFIG - bne :+ - stax copy_src - ldax #cfg_mac - stax copy_dest - ldax #NB65_CFG_DHCP_SERVER+4 ;bytes to copy - jsr copymem - clc - ldax nb65_params - rts -: - - cpy #NB65_INIT_IP + cpy #NB65_INITIALIZE bne :+ lda irq_handler_installed_flag bne irq_handler_installed @@ -135,14 +104,19 @@ nb65_dispatcher: cli sta irq_handler_installed_flag irq_handler_installed: - jmp ip65_init -: - - cpy #NB65_INIT_DHCP - bne :+ + jsr ip65_init jmp dhcp_init : + cpy #NB65_GET_IP_CONFIG + bne :+ + ldax #cfg_mac + clc + rts +: + + + cpy #NB65_TFTP_DIRECTORY_LISTING bne :+ jsr set_tftp_params @@ -171,7 +145,7 @@ irq_handler_installed: jmp @after_tftp_call : - cpy #NB65_DNS_RESOLVE_HOSTNAME + cpy #NB65_DNS_RESOLVE bne :+ ldy #NB65_DNS_HOSTNAME+1 lda (nb65_params),y @@ -297,7 +271,7 @@ irq_handler_installed: jmp udp_send : - cpy #NB65_UNHOOK_VBL_IRQ + cpy #NB65_DEACTIVATE bne :+ ldax jmp_old_irq+1 sei ;don't want any interrupts while we fiddle with the vector diff --git a/client/test/test_cart_api.s b/client/test/test_cart_api.s index 8a629bd..807d849 100644 --- a/client/test/test_cart_api.s +++ b/client/test/test_cart_api.s @@ -94,14 +94,10 @@ init: jsr NB65_RAM_STUB_ACTIVATE ;we need to turn on NB65 cartridge @found_nb65_signature: - call #NB65_GET_DRIVER_NAME - - - call #NB65_PRINT_ASCIIZ print #initializing - ldy #NB65_INIT_IP + ldy #NB65_INITIALIZE jsr NB65_DISPATCH_VECTOR bcc :+ print #failed @@ -112,19 +108,6 @@ init: print #ok print_cr - print #dhcp - print #initializing - - call #NB65_INIT_DHCP - - bcc :+ - print #failed - jsr print_errorcode - jmp bad_boot -: - - print #ok - print_cr call #NB65_PRINT_IP_CONFIG ;DNS resolution test @@ -139,7 +122,7 @@ init: cout #' ' ldax #nb65_param_buffer - call #NB65_DNS_RESOLVE_HOSTNAME + call #NB65_DNS_RESOLVE bcc :+ print #dns_lookup_failed_msg print_cr @@ -289,10 +272,7 @@ reply_sent: initializing: - .byte " INITIALIZING ",0 - -dhcp: -.byte "DHCP",0 + .byte "INITIALIZING ",0 port: .byte "PORT: $",0 diff --git a/doc/nb65_api_technical_reference.doc b/doc/nb65_api_technical_reference.doc new file mode 100644 index 0000000000000000000000000000000000000000..57eb0c6ca69e4e3e4433af6c441bb6ba8879bea0 GIT binary patch literal 99328 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

+?jyvn2KL9jCgG6 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 bC