Кaк-то уже писал свой транслятор с ассемблера, в котором опкод - i8080, а мнемоника - x86.
И знаете что? Отлаживать свои программы стало легче!
Так как я их стал писать в MSVC внутри «_asm {…}», а потом копировал и транслировал в код ВМ80:
  • mov al,[bx] === mov a,m
  • xchg bx,[sp] === xthl
  • jmp bx === pchl
  • add bx,dx === dad de


Кстати, вот накидал тут кода:

Используется всё: RST 0…7

Код:
prompt  equ	0F86Ch
puta	equ	0F815h
puts    equ	0F818h

THE_PSW	EQU	07FFEH
THE_HL	EQU	07FFCH

JRNZ	EQU	0C7H
JRZ	EQU	0CFH
JRNC	EQU	0D7H
JRC	EQU	0DFH

        org 0
;    Эта крошечная утилита с оригинальным трюком
; использования RST-команд.
; Возможность выбора точки старта программы посредством
; директивы <G0>..<G38>-МОНИТОРа.
; Возможность вызова нужной подпрограммы при помощи
; функции <USR(0..56)>-БЕЙСИКа.
; Вызов дополнительного API из любой части остального
; приложения посредством <RST 0>..<RST 7>
	ORG	00000H
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
; Здесь располагается обработчик программных прерываний и системных вызовов.
; Через "МОНИТОР" из-вне имеется 57 точек входа директивой G0-G38 для запуска
; программы в различных режимах.
; Внутри программы эти вызовы дублируют API "МОНИТОРа" и дополняют его.
	ORG	00038H
	SHLD	THE_HL	; Сохраняем HL-пару
	PUSH	PSW	; Затем, посредством
	POP	H	; регистровой пары HL
	SHLD	THE_PSW	; сохраняем и PSW
	LXI	H,08A00H; Проверяем указатель стека:
	DAD	SP	; Предустановил ли его МОНИТОР?
	POP	H
	JC	START	; Значит это "холодный старт"
	MOV	A,H
	ADD	A	; Проверим, прикладной ли вызов?
	JNZ	THE_APP	; Приложение вызывает наш API
	JC	MON_RST	; Значит один из FF МОНИТОРа
	MVI	A,TAPIS	; Table of APIs
	ADD	L	; Иначе - это USR-вызов
	MOV	A,M
	INX	H
	MOV	H,M
	XTHL
	LHLD	THE_PSW
	PUSH	H
	POP	PSW
	LHLD	THE_HL
	RET
THE_APP:MOV	A,M	; Вызов из приложения
	XRI	080H	; Если укладывается в KOI-7
	JM	PRINT	; Просто печатаем сообщение
	INX	H
	PUSH	H	; Сейчас проверим следующий байт
	SUI	012H	; Одна из стандартных 18 точек
	JC	THE_MON	; МОНИТОРа?
	ADD	A
	MVI	H,THE_API >> 8
	MOV	L,A
	MOV	A,M
	INX	H
	MOV	H,M
	MOV	L,A
	XTHL
	RET
THE_MON:CMA
	MOV	L,A
	ADD	A
	ADD	L
	MOV	L,A
	MVI	H,0F8H
THE_RET:PUSH	H
	LHLD	THE_PSW
	PUSH	H
	POP	PSW
	LHLD	THE_HL
	RET
PRINT:	PUSH	H
	PUSH	B
	CALL	PUTS
	POP	B
	INX	H
	JMP	THE_RET
TAPIS:	DW	PROMPT
	DW	  0,0,0,0,0,0,0
	DW	0,0,0,0,0,0,0,0
	DW	0,0,0,0,0,0,0,0
	DW	0,0,0,0,0,0,0,0
	DW	0,0,0,0,0,0,0,0
	DW	0,0,0,0,0,0,0,0
	DW	0,0,0,0,0,0,0
START:	LXI	SP,075FFH
	MOV	C,L
	DB	0FFH,1FH,'START:',0
	MOV	A,C
	DB	0FFH,08AH
	DB	0FFH,092H
Фокус в том, что при запуске через «G0…G38» указатель стека SP установлен в служебную область МОНИТОРа и программно легко это определить.
А вот при «CALL 00000h…00038h» указатель стека уже в области пользователя и получается, что и «RST 0» тоже работает как особая подпрограмма.

На ZX-Spectrum этот трюк не сработает, так как при СБРОСе SP никак не изменяется.
Но вот кодом «FF» я заполнял все 256 ячеек (исключения - 00038h и 00098h, где нужно вставить «JR»), а сам код начинался с 00100h.
[свернуть]