diff --git a/client/examples/Makefile b/client/examples/Makefile new file mode 100644 index 0000000..4f807af --- /dev/null +++ b/client/examples/Makefile @@ -0,0 +1,34 @@ +CC=cl65 +AS=ca65 +LD=ld65 +CFLAGS=-Oirs -t $(TARGET) +AFLAGS= + + +IP65TCPLIB=../ip65/ip65_tcp.lib + +C64PROGLIB=../drivers/c64prog.lib + +INCFILES=\ + ../inc/common.i\ + ../inc/commonprint.i\ + ../inc/net.i\ + +all: \ + comatomx.prg \ + +%.o: %.s sine_data.i + $(AS) $(AFLAGS) $< + +sine_data.i: make_sine_data.rb + ruby make_sine_data.rb + +%.prg: %.o $(IP65LIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg + $(LD) -m $*.map -vm -C ../cfg/c64prg.cfg -o $*.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB) + +clean: + rm -f *.o *.pg2 *.prg + rm -f ip65test.dsk + +distclean: clean + rm -f *~ diff --git a/client/examples/comatomx.s b/client/examples/comatomx.s new file mode 100644 index 0000000..5fae3c0 --- /dev/null +++ b/client/examples/comatomx.s @@ -0,0 +1,721 @@ + +.include "../inc/common.i" +.include "../inc/commonprint.i" +.include "../inc/net.i" +.ifndef NB65_API_VERSION_NUMBER + .define EQU = + .include "../inc/nb65_constants.i" +.endif + + +.import get_key +.import copymem +.importzp copy_src +.importzp copy_dest + +temp_buff=copy_dest + +.import url_download +.import url_download_buffer +.import url_download_buffer_length +.import parser_init +.import parser_skip_next + + +SCREEN_RAM = $0400 +COLOUR_RAM = $d800 +VIC_CTRL_A = $d011 +VIC_RASTER_REG = $d012 +VIC_CTRL_B = $d016 +VIC_MEMORY_CTRL=$d018 +VIC_IRQ_FLAG = $d019 + + +IRQ_VECTOR=$fffe + + +BORDER_COLOR = $d020 +BACKGROUND_COLOR_0 = $d021 +SCROLL_DELAY=4 +CHARS_PER_LINE = 40 +SCROLL_LINE=12 +SCROLL_RAM = SCREEN_RAM+(SCROLL_LINE*CHARS_PER_LINE) + +TOP_BORDER_SCAN_LINES = 50 + + +BLACK = 0 +WHITE = 1 +RED = 2 +CYAN = 3 +PURPLE = 4 +GREEN = 5 +BLUE = 6 +YELLOW = 7 +ORANGE = 8 +BROWN = 9 +LIGHT_RED = 10 +DARK_GRAY = 11 +GRAY = 12 +LIGHT_GREEN = 13 +LIGHT_BLUE = 14 +LIGHT_GRAY = 15 + +.macro start_irq + pha + txa + pha + tya + pha + +.endmacro + + +.macro end_irq + pla + tay + pla + tax + pla +.endmacro + +.macro wait_next_raster + lda VIC_RASTER_REG +@loop: + cmp VIC_RASTER_REG + beq @loop +.endmacro + +.bss +current_input_ptr_ptr: .res 2 +param_offset: .res 1 + +scroll_state: .res 1 + +download_buffer: +download_buffer_length=7600 + .res download_buffer_length + +scroll_buffer_0: + .res 2000 + +scroll_buffer_1: + .res 2000 + +string_offset: .res 1 + +.segment "STARTUP" ;this is what gets put at the start of the file on the C64 + +.word basicstub ; load address + +basicstub: + .word @nextline + .word 2003 + .byte $9e + .byte <(((init / 1000) .mod 10) + $30) + .byte <(((init / 100 ) .mod 10) + $30) + .byte <(((init / 10 ) .mod 10) + $30) + .byte <(((init ) .mod 10) + $30) + .byte 0 +@nextline: + .word 0 + +init: + + jsr ip65_init + jsr dhcp_init + + jsr setup_static_scroll_text + + lda #0 + jsr clear_screen + lda #DARK_GRAY + sta BORDER_COLOR + lda #YELLOW + sta BACKGROUND_COLOR_0 + + + lda #<(charset_font >>10)+$10 + sta VIC_MEMORY_CTRL + + + sei ;disable maskable IRQs + + lda #$7f + sta $dc0d ;disable timer interrupts which can be generated by the two CIA chips + sta $dd0d ;the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better + ;stop it. + + lda $dc0d ;by reading this two registers we negate any pending CIA irqs. + lda $dd0d ;if we don't do this, a pending CIA irq might occur after we finish setting up our irq. + ;we don't want that to happen. + + lda #$01 ;this is how to tell the VICII to generate a raster interrupt + sta $d01a + + lda #$00 ;this is how to tell at which rasterline we want the irq to be triggered + sta VIC_RASTER_REG + + + ;copy KERNAL to the RAM underneath, in case any ip65 routines need it + + ldax #$e000 + stax copy_src + stax copy_dest + ldax #$1FFF + + jsr copymem + + + + lda #$35 ;we turn off the BASIC and KERNAL rom here, so we can overwrite the IRQ vector at $fffe + sta $01 ;the cpu now sees RAM everywhere except at $d000-$e000, where still the registers of + ;SID/VICII/etc are visible + + jsr setup_sprites + + jsr set_next_irq_jump + cli ;enable maskable interrupts again + + + lda #0 + sta scroll_state +;position for the first text + + ldax #scroll_buffer_0 + stax current_input_ptr_ptr + jsr reset_input_buffer + +;now download the feed +@download_feed: + + ldax #download_buffer + stax url_download_buffer + ldax #download_buffer_length + stax url_download_buffer_length + ldax #feed_url + jsr url_download + + + lda #1 + sta scroll_state + + ldax #scroll_buffer_1 + stax current_output_ptr + jsr emit_titles + + ldax #scroll_buffer_1 + stax current_input_ptr_ptr ;will get picked up once we have finished going through the message once + +@endless_loop: + jsr ip65_process + jmp @endless_loop + +reset_input_buffer: + ldax current_input_ptr_ptr + stax current_input_ptr + rts + + +setup_sprites: + ;turn on all 8 sprites + lda #$FF + sta $d015 + + ldx #$07 +@setup_sprite: + ;position each sprite + txa + asl + tay + lda sprite_x_pos,x + sta $d000,y ;sprite 0 X pos (LSB) + lda 0 + sta $d001,y ;sprite 0 Y pos + + ;colour sprite 0 + lda #BLUE + sta $d027,x ;sprite 0 color + + ;select bitmap for sprite + sec + lda sprite_text,x + sbc #'A' + clc + adc #<(sprite_font/64) + sta SCREEN_RAM+$03f8,x + dex + bpl @setup_sprite + + lda sprite_x_msb + sta $d010 + + ;turn on multicolor mode for all 8 sprites + lda #$FF + sta $d01c + + lda #DARK_GRAY + sta $d025 ;sprite multicolor register 0 + lda #LIGHT_GRAY + sta $d026 ;sprite multicolor register 1 + + rts + + +clear_screen: + + ldx #$00 + lda #$20 + +: + sta SCREEN_RAM,x + sta SCREEN_RAM+$100,x + sta SCREEN_RAM+$200,x + sta SCREEN_RAM+$300,x + sta COLOUR_RAM,x + sta COLOUR_RAM+$100,x + sta COLOUR_RAM+$200,x + sta COLOUR_RAM+$300,x + + dex + bne :- + rts + +set_next_irq_jump: + inc jump_counter + + lda jump_counter + asl + asl +load_next_raster_entry: + tax + lda raster_jump_table,x ;bit 9 of raster to trigger on + + cmp #$ff + bne not_last_entry + lda #0 + sta jump_counter + jmp load_next_raster_entry +not_last_entry: + ora #$18 ;turn on bits 3 & 4 + sta VIC_CTRL_A + lda raster_jump_table+1,x ;bits 0..7 of raster to trigger on + sta VIC_RASTER_REG + lda raster_jump_table+2,x ;LSB of IRQ handler + sta IRQ_VECTOR + lda raster_jump_table+3,x ;LSB of IRQ handler + sta IRQ_VECTOR+1 + rts + +exit_from_irq: + jsr set_next_irq_jump + lda #$ff ;this is the orthodox and safe way of clearing the interrupt condition of the VICII. + sta VIC_IRQ_FLAG;if you don't do this the interrupt condition will be present all the time and you end + ;up having the CPU running the interrupt code all the time, as when it exists the + ;interrupt, the interrupt request from the VICII will be there again regardless of the + ;rasterline counter. + + end_irq + rti + + + +scroll_text_irq: + start_irq + lda scroll_timer + bne done_scrolling_message + lda #SCROLL_DELAY + sta scroll_timer + ldx #1 + ldy #0 +scroll_1_char: + lda SCROLL_RAM,x + sta SCROLL_RAM,y + lda SCROLL_RAM+40,x + sta SCROLL_RAM+40,y + + inx + iny + cpx #CHARS_PER_LINE + bne scroll_1_char + + + jsr get_a + cmp #0 + beq last_char_in_message + sta SCROLL_RAM+CHARS_PER_LINE-1 + clc + adc #$80 + sta SCROLL_RAM+CHARS_PER_LINE+40-1 + + jmp done_scrolling_message + + +last_char_in_message: + jsr reset_input_buffer + +done_scrolling_message: + dec scroll_timer + + jmp exit_from_irq + + +scroll_timer: .byte 1 +scroll_counter: .byte 0 + + +pixel_scroll_irq: + start_irq + wait_next_raster +; set X scroll offset + lda scroll_timer + clc + asl + clc + and #$07 + sta VIC_CTRL_B + + jmp exit_from_irq + +move_sprites_irq: + start_irq + wait_next_raster + ldy sprite_ticker + inc sprite_ticker + + ldx #$0e ;7*2 +@position_sprite: + lda sprite_y_pos,y + sta $d001,x ;sprite 0 Y pos + + ;change colour when the sprite goes off screen +; cmp #$ff ;are we off the screen? +; bne @not_off_screen +; txa +; pha +; lsr +; tax +; inc $d027,x ;sprite color +; pla +; tax +;@not_off_screen: + + txa + beq @y_set + dex + dex +@mod_y: + iny + iny + iny + dex + dex + bpl @mod_y +@y_set: + + tax + dex + dex + bpl @position_sprite + + jmp exit_from_irq + + +setup_static_scroll_text: + ldax #scroll_buffer_0 + stax current_output_ptr + ldax #scroll_template + stax current_input_ptr +@next_byte: + jsr get_a + cmp #'%' + beq @operator + pha + jsr emit_a + pla + bne @next_byte + rts + +@operator: + jsr get_a + cmp #'i' + bne @not_ip + lda #NB65_CFG_IP + jmp @loaded_offset +@not_ip: + cmp #'g' + bne @not_gateway + lda #NB65_CFG_GATEWAY + jmp @loaded_offset +@not_gateway: + cmp #'d' + bne @not_dns + lda #NB65_CFG_DNS_SERVER + jmp @loaded_offset +@not_dns: + cmp #'f' + bne @not_feed_url + ldy #0 +@copy_feed_url_loop: + lda feed_url,y + beq @next_byte + jsr emit_a + iny + bne @copy_feed_url_loop +@not_feed_url: + jmp @next_byte + +@loaded_offset: + sta param_offset + jsr cfg_get_configuration_ptr ;ax=base config, carry flag clear + adc param_offset + bcc :+ + inx +: + jsr emit_dotted_quad + + + jmp @next_byte + +;emit the 4 bytes pointed at by AX as dotted decimals +emit_dotted_quad: + sta pptr + stx pptr + 1 + ldy #0 + lda (pptr),y + jsr emit_decimal + lda #'.' + jsr emit_a + + ldy #1 + lda (pptr),y + jsr emit_decimal + lda #'.' + jsr emit_a + + ldy #2 + lda (pptr),y + jsr emit_decimal + lda #'.' + jsr emit_a + + ldy #3 + lda (pptr),y + jsr emit_decimal + + rts + +emit_decimal: ;emit byte in A as a decimal number + pha + sta temp_bin ;save + sed ; Switch to decimal mode + lda #0 ; Ensure the result is clear + sta temp_bcd + sta temp_bcd+1 + ldx #8 ; The number of source bits + : + asl temp_bin+0 ; Shift out one bit + lda temp_bcd+0 ; And add into result + adc temp_bcd+0 + sta temp_bcd+0 + lda temp_bcd+1 ; propagating any carry + adc temp_bcd+1 + sta temp_bcd+1 + dex ; And repeat for next bit + bne :- + + cld ;back to binary + + pla ;get back the original passed in number + bmi @emit_hundreds ; if N is set, the number is >=128 so emit all 3 digits + cmp #10 + bmi @emit_units + cmp #100 + bmi @emit_tens +@emit_hundreds: + lda temp_bcd+1 ;get the most significant digit + and #$0f + clc + adc #'0' + jsr emit_a + +@emit_tens: + lda temp_bcd + lsr + lsr + lsr + lsr + clc + adc #'0' + jsr emit_a +@emit_units: + lda temp_bcd + and #$0f + clc + adc #'0' + jsr emit_a + + rts + +top_sprite_color_irq: + start_irq + wait_next_raster + dec $d025 ;sprite multicolor register 0 + dec $d026 ;sprite multicolor register 1 + + jmp exit_from_irq + +bottom_sprite_color_irq: + start_irq + wait_next_raster + inc $d025 ;sprite multicolor register 0 + inc $d026 ;sprite multicolor register 1 + jmp exit_from_irq + +emit_titles: + ldax #download_buffer + jsr parser_init +@next_title: + ldax #title + jsr parser_skip_next + bcs @done + + jsr emit_tag_contents + lda #' ' + jsr emit_a + lda #'/' + jsr emit_a + lda #' ' + jsr emit_a + jmp @next_title +@done: + rts + +emit_tag_contents: + stax temp_buff + lda #0 + sta string_offset +@next_byte: + jsr @get_next_byte + cmp #0 + beq @done + cmp #'<' + beq @done + cmp #'&' + beq @entity + jsr emit_a + beq @done + jmp @next_byte +@entity: + jsr @get_next_byte + cmp #'a' + bne @not_amper + lda #'&' + jsr emit_a +@not_amper: + cmp #'g' + bne @not_gt + lda #'>' + jsr emit_a +@not_gt: + cmp #'l' + bne @not_lt + lda #'<' + jsr emit_a +@not_lt: + +@loop_till_semi_colon: + jsr @get_next_byte + cmp #0 + beq @done + cmp #';' + bne @loop_till_semi_colon + jmp @next_byte +@get_next_byte: + ldy string_offset + lda (temp_buff),y + inc string_offset +@done: + rts + + + +.data + +sprite_ticker: .byte 0 + +emit_a: +current_output_ptr=emit_a+1 + sta $ffff + inc current_output_ptr + bne :+ + inc current_output_ptr+1 +: + rts + +get_a: +current_input_ptr=get_a+1 + lda $ffff + inc current_input_ptr + bne :+ + inc current_input_ptr+1 +: + rts + + +raster_jump_table: + ;format: + ;offset meaning + ; $00 BIT 9 OF RASTER TO TRIGGER ON ($00 if bit 8 =0 , $80 if bit 8 =1) + ; $01 BITS 0..7 OF RASTER TO TRIGGER ON + ; $02 LSB OF ROUTINE TO JUMP TO + ; $03 MSB OF ROUTINE TO JUMP TO + ;table needs to end with a single byte $ff + ;table needs to be sorted by scanlines + .byte $0,$01 + .word scroll_text_irq + .byte $0,$1b +; .word top_sprite_color_irq +; .byte $0,$20 + .word pixel_scroll_irq + .byte $0,$80 +; .word bottom_sprite_color_irq +; .byte $0,255 + .word move_sprites_irq + + .byte $ff ;end of list + +jump_counter: .byte 0 + + +sprite_x_pos: +.byte $38,$58,$78,$98,$B8,$D8,$F8,$18 + +sprite_x_msb: +.byte $80 + +sprite_y_pos: +.include "sine_data.i" +.include "sine_data.i" + +scroll_template: + +sprite_text: +.byte "COMATOMX" + +.byte " configured via dhcp - ip: %i / gateway: %g / dns server %d / polling %f /" +.byte " ",0 + + +feed_url: +.byte "http://search.twitter.com/search.atom?q=kipper",0 +.byte "http://static.cricinfo.com/rss/livescores.xml",0 + +title: +.byte "",0 + +.segment "VIC_DATA" +charset_font: + .incbin "font16x8.bin" +sprite_font: + .incbin "spud_letters.spr" diff --git a/client/examples/font16x8.bin b/client/examples/font16x8.bin new file mode 100644 index 0000000..380d7ed Binary files /dev/null and b/client/examples/font16x8.bin differ diff --git a/client/examples/make_sine_data.rb b/client/examples/make_sine_data.rb new file mode 100644 index 0000000..467381f --- /dev/null +++ b/client/examples/make_sine_data.rb @@ -0,0 +1,17 @@ +f=File.open("sine_data.i","w") + +TABLE_ENTRIES=0x80 +AMPLITUDE=205 +OFFSET=50 + +TABLE_ENTRIES.times do |i| + value=OFFSET+Math.sin(Math::PI*i.to_f/TABLE_ENTRIES.to_f)*AMPLITUDE + if i%0x08==0 + f<<"\n.byte " + else + f<<", " + end + f<<"$%02x" % value +end + +f.close \ No newline at end of file diff --git a/client/examples/sine_data.i b/client/examples/sine_data.i new file mode 100644 index 0000000..3c7933f --- /dev/null +++ b/client/examples/sine_data.i @@ -0,0 +1,17 @@ + +.byte $32, $37, $3c, $41, $46, $4b, $50, $55 +.byte $59, $5e, $63, $68, $6d, $72, $77, $7b +.byte $80, $85, $89, $8e, $92, $97, $9b, $9f +.byte $a3, $a8, $ac, $b0, $b4, $b7, $bb, $bf +.byte $c2, $c6, $c9, $cd, $d0, $d3, $d6, $d9 +.byte $dc, $df, $e1, $e4, $e6, $e9, $eb, $ed +.byte $ef, $f1, $f3, $f4, $f6, $f7, $f8, $fa +.byte $fb, $fb, $fc, $fd, $fe, $fe, $fe, $fe +.byte $ff, $fe, $fe, $fe, $fe, $fd, $fc, $fb +.byte $fb, $fa, $f8, $f7, $f6, $f4, $f3, $f1 +.byte $ef, $ed, $eb, $e9, $e6, $e4, $e1, $df +.byte $dc, $d9, $d6, $d3, $d0, $cd, $c9, $c6 +.byte $c2, $bf, $bb, $b7, $b4, $b0, $ac, $a8 +.byte $a3, $9f, $9b, $97, $92, $8e, $89, $85 +.byte $80, $7b, $77, $72, $6d, $68, $63, $5e +.byte $59, $55, $50, $4b, $46, $41, $3c, $37 \ No newline at end of file diff --git a/client/examples/spud_letters.spr b/client/examples/spud_letters.spr new file mode 100644 index 0000000..38a50ad Binary files /dev/null and b/client/examples/spud_letters.spr differ diff --git a/client/ip65/url.s b/client/ip65/url.s index d960108..78d53ca 100644 --- a/client/ip65/url.s +++ b/client/ip65/url.s @@ -408,7 +408,7 @@ not_end_of_file: get: .byte "GET " get_length=4 http_preamble: - .byte " HTTP/1.1",$0d,$0a + .byte " HTTP/1.0",$0d,$0a .byte "User-Agent: IP65/" .include "../inc/version.i" .byte $0d,$0a