Я работаю над небольшой программой сборки Z80, одной из моих первых. Вот мой код сборки Z-80:
main:
LD SP, $FFFF ; start by setting stack to top of RAM
printChar1:
LD A, 'X' ; this works
CALL transmitCharFromA ; this works
LD HL, (generationMsg) ; this does not work
CALL txAsciiZMsg ; this does not work
endInNopLoop:
NOP
JR endInNopLoop
generationMsg: DEFB "Generation: ", CR, LF, 0 ; null-terminated string
Ожидаемый результат заключается в том, что впоследствии он выдаст «XGeneration:» с комбинацией CRLF.
Подпрограмма transmitCharFromA
прекрасно работает, и первым символом вывода действительно является «X». Вот эта рутина:
transmitCharFromA:
PUSH AF ; store char in A for later
consoleOutput:
IN A,($80) ; read ACIA status byte
BIT 1,A ; set Z flag if still transmitting character
JR Z,consoleOutput ; and loop until flag signals ready
POP AF ; get the character back from the stack
OUT ($81),A ; send it over RS232 to ACIA outpout address
RET
Как я уже говорил, это прекрасно работает. Поэтому я хотел бы продолжить на этом, разрешив вывод строки с нулевым символом в конце:
txAsciiZMsg:
LD A, (HL) ; A holds pointer to start of null-term string
OR A ; OR A with A to set Z flag if A holds null terminator
RET Z ; return if done
CALL transmitCharFromA ; otherwise transmit it using working routine
INC HL ; move pointer to next character
JR txAsciiZMsg ; and keep going
Это не работает, выводит кучу мусорных символов до остановки и (якобы) входа в цикл endInNopLoop
.
Может кто-нибудь подсказать, что я делаю неправильно в txAsciiZMsg
рутине, что это:
- Печать мусора
- Не печатается сообщение «Поколение:»
- По-видимому, не находит завершающий ноль символ 0x00
Я использую z88dk для сборки и сборки моей программы.
Я вижу в своем списке ассемблера, что оператор LD A, (HL)
собран правильно, показывая первый байт адреса сообщения в качестве операнда инструкции LD. Так что я зашел в тупик относительно того, что может пойти не так.
Кто-нибудь может указать на мою ошибку (ошибки)?