ord(stringy[a])
However this returns the byte (not char) at the given position. But copy does the same, copy accesses the string by bytes.
so as soon as any accented, umlaut, or other such char occurs in you string, that will break. Because by default Lazarus uses UTF8, and chars can use between 1 and 4 bytes.
Then again for UTF8 chars there is no ascii-code (and no function like ord).
in LCLProc there are a few string handling functions like UTF8Length.