Assuming no hardware changes to the 6502 memory access, why would a system routine to output characters necessarily be slower than one that you code that accesses hardware directly?
On top of that, you’d need to define an ABI to specify what to write where.
That means using registers, which aren’t plentiful (I love understatements) on a 6502, the stack (slightly less “not plentiful”, but pushing a single byte takes 3 cycles, if you happen to have it in a register, and popping it back 4 cycles) or memory (that’s what https://en.wikipedia.org/wiki/SWEET16 sort-of did for a software ABI, and could be made to work _if_ you added extra hardware. For example, on a Z80 you could have had a graphics buffer addressable by I/O ports (write row number to one port, column number to another, then write character to a third port)