OK, been hacking all morning and think I understand the problem and have a solution which I present in case anyone else has the same problem or can see a flaw with it:

In the zones postage calculation there is a check to see if the customer's country is in a list where postage is not permitted:
if (strstr(MODULE_SHIPPING_ZONES_SKIPPED, $dest_country)) { ... don't offer postage ... }

In my shop the list was not initialised (and I can't see where to do that in the admin pages).
That meant it was comparing the country to the actual phrase MODULE_SHIPPING_ZONES_SKIPPED and matching on ES (in ZONES) and skipping shipping.

The MODULE_SHIPPING_ZONES_SKIPPED is a configuration constant so I added it to my configuration database table with an empty value for skipped countries, based on this line from the zones.php file:
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, c
onfiguration_description, configuration_group_id, sort_order, set_function, date_added) values ('Skip Countries, use a comm
a separated list of the two character ISO country codes', 'MODULE_SHIPPING_ZONES_SKIPPED', '', 'Disable for the following C
ountries:', '6', '0', 'zen_cfg_textarea(', now())");
and that seems to have done the trick. Maybe this is something I've messed up during the upgrade from my old shop 1.3.9?