Ho trovato come risolverlo, quindi spero che questo possa essere utile a qualcuno.
Innanzitutto, SQL_Latin1_General_CP1_CI_AS è uno strano mix di CP-1252 e UTF-8. I caratteri di base sono CP-1252, quindi ecco perché tutto ciò che dovevo fare era UTF-8 e tutto funzionava. I caratteri asiatici e altri UTF-8 sono codificati su 2 byte e il driver php pdo_mssql sembra odiare i caratteri di lunghezza variabile, quindi sembra fare un CAST su varchar (invece di nvarchar) e quindi tutti i caratteri da 2 byte diventano punti interrogativi (' ?').
L'ho risolto eseguendo il cast su binary e quindi ricostruisco il testo con php:
SELECT CAST(MY_COLUMN AS VARBINARY(MAX)) FROM MY_TABLE;
In 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);