.alias putchar $FFD2 ; print [null-terminated string start address] .macro print txa ; backup = x pha ldx #0 ; x = 0 _loop: lda _1, x ; while (_1[x] != 0) { beq _done jsr putchar ; putchar(_1[x]) inx ; ++x bne _loop ; if (x == 0) break } This allows max 255 character to be read _done: pla ; x = backup tax .macend .macro printchar lda #_1 jsr putchar .macend ; print value (byte) at address as a number .macro printm lda _1 jsr printa .macend printy: tya ; a = y jmp printa ; print register x as a number printx: txa ; a = x ; print register a as a number printa: .scope cmp #10 ; if (a < 10) bcc _1digit cmp #100 ; if (a < 100) bcc _2digit _3digit: pha `div 100 clc adc #'0 jsr putchar pla `mod 100 _2digit: pha `div 10 clc adc #'0 jsr putchar pla `mod 10 _1digit: clc adc #'0 jsr putchar rts .scend ; a = a % _1 .macro mod ; 10 cycles (2+2+2+2+2) raw cmp #_1 ; if (a < _1) return bcc _end sec ; carry = 1 _loop: sbc #_1 ; do a -= _1 + !carry beq _end ; if (a == 0) break cmp #_1 ; while (a >= _1) bcs _loop _end: .macend buffer: .byte 0 ; a = a % MemoryAddress .macro modm cmp _1 ; if (a < _1) return bcc _end sec ; carry = 1 _loop: sbc _1 ; do a -= _1 + !carry beq _end ; if (a == 0) break cmp _1 ; while (a >= _1) bcs _loop _end: .macend ; a = a % y .macro mody sty buffer `modm buffer .macend ; a = a / _1 .macro div ora #0 ; The CMP (and friends) instruction changes the carry and zero flag, ; which can cause the flags (and therefore the branch instructions) ; to get "desynced" with the actual accumulator value. ; With this instruction, we force a "refresh" of the flags. ; It took me half an hour to figure this out... beq _return ; if (a == 0) return 0 cmp #_1 ; if (a < _1) return 0 bcc _zero stx buffer ; buffer = x ldx #0 ; x = 0 sec ; carry = 1 _loop: sbc #_1 ; a -= _1 + !carry inx ; ++x beq _end ; if (a == 0) break cmp #_1 ; while (a >= _1) bcs _loop _end: txa ; a = x ldx buffer ; x = buffer jmp _return _zero: lda #0 _return: .macend .macro lowercase ldx #23 stx 53272 .macend