For self-modifying code, you need functional RAM. If the purpose of your monitor is to help diagnose RAM issues, that's a nonstarter. I wrote (too many years ago) a monitor that fit in a 2708 EPROM that used no RAM at all--return addresses were passed in a register, but the monitor was not position-independent for that reason.
Although not exactly a monitor, I did have a liking for the (I think) Processor Tech assembler/editor in ROM.
How did you deal with read and write of I/O ports ( I'm assuming a 8080 here )?