Eu encontrei como resolvê-lo, então espero que isso seja útil para alguém.
Primeiro, SQL_Latin1_General_CP1_CI_AS é uma estranha mistura de CP-1252 e UTF-8. Os caracteres básicos são CP-1252, então é por isso que tudo que eu tinha que fazer era UTF-8 e tudo funcionou. Os caracteres asiáticos e outros UTF-8 são codificados em 2 bytes e o driver php pdo_mssql parece odiar caracteres de comprimento variável, então parece fazer um CAST para varchar (em vez de nvarchar) e, em seguida, todos os caracteres de 2 bytes se tornam pontos de interrogação (' ?').
Eu consertei lançando para binário e depois reconstruí o texto com php:
SELECT CAST(MY_COLUMN AS VARBINARY(MAX)) FROM MY_TABLE;
Em php:
//Binary to hexadecimal
$hex = bin2hex($bin);
//And then from hex to string
$str = "";
for ($i=0;$i<strlen($hex) -1;$i+=2)
{
$str .= chr(hexdec($hex[$i].$hex[$i+1]));
}
//And then from UCS-2LE/SQL_Latin1_General_CP1_CI_AS (that's the column format in the DB) to UTF-8
$str = iconv('UCS-2LE', 'UTF-8', $str);