/// @file /// A lightweight library for printing on the C64. /// /// Printing with this library is done by calling print_ function for each element // Commodore 64 PRG executable file .file [name="linkedlist-kc.prg", type="prg", segments="Program"] .segmentdef Program [segments="Basic, Code, Data"] .segmentdef Basic [start=$0801] .segmentdef Code [start=$80d] .segmentdef Data [startAfter="Code"] .segment Basic :BasicUpstart(__start) .const OFFSET_STRUCT_NODE_VALUE = 2 .label print_screen = $400 .label last_time = $e .label print_line_cursor = $a .label Ticks = 4 .label Ticks_1 = $c .label print_char_cursor = 8 .label free_ = 6 .label root = 2 .segment Code __start: { // unsigned int last_time lda #<0 sta.z last_time sta.z last_time+1 jsr main rts } main: { .label __5 = 6 .label i = $a // start() jsr start ldx #0 lda #print_screen sta.z print_char_cursor+1 __b1: lda #<0 sta.z root sta.z root+1 sta.z free_ sta.z free_+1 sta.z i sta.z i+1 __b2: // prepend(i) jsr prepend // for(unsigned int i : 0..2999) inc.z i bne !+ inc.z i+1 !: lda.z i+1 cmp #>$bb8 bne __b2 lda.z i cmp #<$bb8 bne __b2 // sum() jsr sum // print_char((byte)sum()) lda.z __5 jsr print_char // for(unsigned char c : 0..4) inx cpx #5 bne __b1 // end() jsr end // } rts } start: { .label LAST_TIME = last_time // asm jsr $ffde sta LAST_TIME stx LAST_TIME+1 // } rts } // void prepend(__zp($a) unsigned int x) prepend: { .label new = 4 .label x = $a // alloc() jsr alloc // new = alloc() // new->next = root ldy #0 lda.z root sta (new),y iny lda.z root+1 sta (new),y // new->value = x ldy #OFFSET_STRUCT_NODE_VALUE lda.z x sta (new),y iny lda.z x+1 sta (new),y // root = new lda.z new sta.z root lda.z new+1 sta.z root+1 // } rts } sum: { .label current = 2 .label s = 6 .label return = 6 // current = root lda #<0 sta.z s sta.z s+1 __b1: // while (current) lda.z current+1 cmp #>0 bne __b2 lda.z current cmp #<0 bne __b2 // } rts __b2: // s += current->value ldy #OFFSET_STRUCT_NODE_VALUE clc lda.z s adc (current),y sta.z s iny lda.z s+1 adc (current),y sta.z s+1 // current = current->next ldy #0 lda (current),y pha iny lda (current),y sta.z current+1 pla sta.z current jmp __b1 } // Print a single char // void print_char(__register(A) char ch) print_char: { // *(print_char_cursor++) = ch ldy #0 sta (print_char_cursor),y // *(print_char_cursor++) = ch; inc.z print_char_cursor bne !+ inc.z print_char_cursor+1 !: // } rts } end: { // Ticks = last_time lda.z last_time sta.z Ticks lda.z last_time+1 sta.z Ticks+1 // start() jsr start // last_time -= Ticks lda.z last_time sec sbc.z Ticks sta.z last_time lda.z last_time+1 sbc.z Ticks+1 sta.z last_time+1 // Ticks = last_time lda.z last_time sta.z Ticks_1 lda.z last_time+1 sta.z Ticks_1+1 // print_uint(Ticks) jsr print_uint // print_ln() jsr print_ln // } rts } alloc: { .label __1 = 4 .label return = 4 // heap + free_ lda.z free_ asl sta.z __1 lda.z free_+1 rol sta.z __1+1 asl.z __1 rol.z __1+1 lda.z return clc adc #heap sta.z return+1 // free_++; inc.z free_ bne !+ inc.z free_+1 !: // } rts } // Print a unsigned int as HEX // void print_uint(__zp($c) unsigned int w) print_uint: { .label w = $c // print_uchar(BYTE1(w)) ldx.z w+1 jsr print_uchar // print_uchar(BYTE0(w)) ldx.z w jsr print_uchar // } rts } // Print a newline print_ln: { lda #print_screen sta.z print_line_cursor+1 __b1: // print_line_cursor + 0x28 lda #$28 clc adc.z print_line_cursor sta.z print_line_cursor bcc !+ inc.z print_line_cursor+1 !: // while (print_line_cursor>4 txa lsr lsr lsr lsr // print_char(print_hextab[b>>4]) tay lda print_hextab,y // Table of hexadecimal digits jsr print_char // b&0xf lda #$f axs #0 // print_char(print_hextab[b&0xf]) lda print_hextab,x jsr print_char // } rts } .segment Data print_hextab: .text "0123456789abcdef" heap: .fill 4*$fa0, 0