--- /dev/null
+ .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
+
--- /dev/null
+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__;
+}