diff --git a/libsrc/lynx/Makefile b/libsrc/lynx/Makefile index 9d6c4960c..d6801be30 100644 --- a/libsrc/lynx/Makefile +++ b/libsrc/lynx/Makefile @@ -64,7 +64,8 @@ OBJS = bllhdr.o \ oserror.o \ read.o \ sysuname.o \ - toascii.o + toascii.o \ + uploader.o #-------------------------------------------------------------------------- # Drivers diff --git a/libsrc/lynx/uploader.s b/libsrc/lynx/uploader.s new file mode 100644 index 000000000..da72fd5b9 --- /dev/null +++ b/libsrc/lynx/uploader.s @@ -0,0 +1,79 @@ + .include "lynx.inc" + .include "extzp.inc" + .interruptor _UpLoaderIRQ + .export __UPLOADER__: absolute = 1 + +load_len=_FileDestAddr +load_ptr=_FileFileLen +load_ptr2=_FileCurrBlock + +.segment "UPCODE" + +ComLynxReadAndExec: + ldy #4 +loop0: + jsr read_byte + sta load_len-1,y + dey + bne loop0 ; get destination and length + tax ; lowbyte of length + + lda load_ptr + sta load_ptr2 + lda load_ptr+1 + sta load_ptr2+1 + +loop1: + inx + bne cont1 + inc load_len+1 + bne cont1 + jmp (load_ptr) + +cont1: + jsr read_byte + sta (load_ptr2),y + sta PALETTE ; feedback ;-) + iny + bne loop1 + inc load_ptr2+1 + bra loop1 + +read_byte: + bit SERCTL + bvc read_byte + lda SERDAT + rts + +_UpLoaderIRQ: + lda INTSET + and #$10 + bne @L0 + clc + rts +@L0: + lda SERDAT ; wait for the start sequence + bit flag ; already seen $81 ? + bpl again ; >= 0 => no + cmp #$50 ; "P" ? + bne again ; not correct, so clear flag + sei + jmp ComLynxReadAndExec + +again: + stz flag + cmp #$81 + bne exit + sta flag +; +; last action : clear interrupt +; +exit: + clc + rts + +.segment "UPDATA" + +flag: + .byte 0 + diff --git a/src/ld65/cfg/lynx-uploader.cfg b/src/ld65/cfg/lynx-uploader.cfg new file mode 100644 index 000000000..96f43db4e --- /dev/null +++ b/src/ld65/cfg/lynx-uploader.cfg @@ -0,0 +1,48 @@ +SYMBOLS { + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __STARTOFDIRECTORY__: type = weak, value = $00DF; # start just after loader + __BLOCKSIZE__: type = weak, value = 1024; # cart block size + __EXEHDR__: type = import; + __BOOTLDR__: type = import; + __DEFDIR__: type = import; + __UPLOADER__: type = import; +} +MEMORY { + ZP: file = "", define = yes, start = $0000, size = $0100; + HEADER: file = %O, start = $0000, size = $0040; + BOOT: file = %O, start = $0200, size = __STARTOFDIRECTORY__; + DIR: file = %O, start = $0000, size = 8; + RAM: file = %O, define = yes, start = $0200, size = $BD38 - __STACKSIZE__; + UPLDR: file = %O, define = yes, start = $BFDC, size = $005C; +} +SEGMENTS { + EXEHDR: load = HEADER, type = ro; + BOOTLDR: load = BOOT, type = ro; + DIRECTORY:load = DIR, type = ro; + STARTUP: load = RAM, type = ro, define = yes; + LOWCODE: load = RAM, type = ro, optional = yes; + INIT: load = RAM, type = ro, define = yes, optional = yes; + CODE: load = RAM, type = ro, define = yes; + RODATA: load = RAM, type = ro, define = yes; + DATA: load = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss, define = yes; + UPCODE: load = UPLDR, type = ro, define = yes; + UPDATA: load = UPLDR, type = rw, define = yes; + ZEROPAGE: load = ZP, type = zp; + EXTZP: load = ZP, type = zp, optional = yes; + APPZP: load = ZP, type = zp, optional = yes; +} +FEATURES { + CONDES: segment = INIT, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = RODATA, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; + CONDES: segment = RODATA, + type = interruptor, + label = __INTERRUPTOR_TABLE__, + count = __INTERRUPTOR_COUNT__; +}