У меня уже есть макрос для печати массива байтов (?text), поэтому далее я решил напечатать номер байта.
Когда вы печатаете байт (я еще не знаю, как работать с числами, для которых требуется более 8 бит), вы обнаруживаете, что он состоит из одной, двух или трех цифр, например. 223 — это «2», «2» и «3», поэтому сначала вам нужно преобразовать номер байта в какой-либо печатный формат.
Я подготовил макрос BYTE2STR для этой задачи. Я преобразую число, постепенно вычитая сотни, чтобы найти первую цифру, после этого я вычитаю десятки, чтобы найти вторую цифру, а остаток — это последняя третья цифра.
*=$0801 ; C64 program starts at this address ; "10 SYS (2064)" ;byte $0E, $08, $0A, $00, $9E, $20, $28, $32 ;byte $30, $36, $34, $29, $00, $00, $00 BYTE2STR number, result rts number byte 244 result byte 0,0,0 ; ---------------------------------- ; ; Convert byte into 3 bytes long ; string ; ; ---------------------------------- defm BYTE2STR ; In /1 = Byte (Memory) ; Out /2 = 3 bytes long string space (Memory) zeroChar = #$30 ; Constant for '0' character lda /1 ; Load byte into A ; --- First handle 100s ldx #0 ; Reset 100s counter cmp #100 ; Unsigned comparsion bcs @over100 ; If the C flag is 1 then A(unsigned) >=NUM ; (unsigned) and BCS will branch jmp @end100 ; Go to end of 100s computation @over100 ; Number is greater than 100 inx cmp #200 ; Check if it is greater than 200 bcs @over200 ; If the C flag is 1 then A(unsigned) >=NUM ; (unsigned) and BCS will branch sec sbc #100 ; Subtract 100 jmp @end100 ; Go to end of 100s computation @over200 ; Number is greater than 200 inx sec sbc #200 ; Subtract 200 jmp @end100 ; Go to end of 100s computation @end100 stx /2 ; Store 100s in memory ; --- Now handle 10s ldx #-1 ; Reset 10s counter @loop10 inx sec sbc #10 ; Subtract 10 bpl @loop10 ; Loop if result > 0 stx /2+1 ; Store 10s in memory clc adc #10 ; Add 10 (the A is negative) ; --- Now handle 1s clc adc zeroChar ; In A register is remainder sta /2+2 ; Store remainder in memory lda /2 ; Convert 100s character (add $30) clc adc zeroChar sta /2 lda /2+1 ; Convert 100s character (add $30) clc adc zeroChar sta /2+1 endm
Примечание. В проекте Git я разделил все маркировки в отдельный файл library.asm.
GitHub: https://github.com/RetroAsmDev/C64asm/tree/master/Byte2Str
Редактировать:
01.06.2018 - Ошибка в коде при использовании инструкции BPL:
- Флаг N (отрицательный), называемый иногда S (ign) в регистре состояния, устанавливается в значение бита 7 последней операции.
- Если мы интерпретируем в программе 8-битное значение как знаковое, положительные числа будут от 0 до 127 ($00-$7F), а отрицательные - от -1 до -128 ($80-$FF). Если интерпретировать в программе 8-битное значение как беззнаковое, положительными числами будут от 0 до 255 ($00-$FF). Проблема в том, что микропроцессор не знает, как мы интерпретируем эти значения в программе, например. $FF может быть либо 255, либо -128, поскольку программные инструкции работают с ним, как если бы это было -128.
- Старший бит (бит 7 для 8-битного числа) равен нулю, если число неотрицательное (от 0 до 127), и единице, если число отрицательное. Это означает, что, например. результат операции 255–100 = 155 ($9B, 10011011), даже интерпретируемый в коде как положительное число, устанавливает флаг N в регистре состояния, поскольку значение бита 7 равно 1.
- Это влияет на такие инструкции, как BPL, которые перескакивают в случае положительного результата... Поскольку инструкция CMP может сравнивать числа без знака, решением было использование одной пары инструкций CMP и BCS вместо SBC и BPL.