1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
;
; Karri Kaksonen, 2011
;
; This bootloader creates a signed binary so that the Lynx will accept it.
;
.include "lynx.inc"
.include "extzp.inc"
.import __BANK0BLOCKSIZE__
.export __BOOTLDR__: absolute = 1
; ------------------------------------------------------------------------
; Bootloader
.segment "BOOTLDR"
;**********************************
; Here is the bootloader in plaintext
; The idea is to make the smalles possible encrypted loader as decryption
; is very slow. The minimum size is 49 bytes plus a zero byte.
;**********************************
; EXE = $fb68
;
; .org $0200
;
; ; 1. force Mikey to be in memory
; stz MAPCTL
;
; ; 3. set ComLynx to open collector
; lda #4 ; a = 00000100
; sta SERCTL ; set the ComLynx to open collector
;
; ; 4. make sure the ROM is powered on
; lda #8 ; a = 00001000
; sta IODAT ; set the ROM power to on
;
; ; 5. read in secondary exe + 8 bytes from the cart and store it in $f000
; ldx #0 ; x = 0
; ldy #$97 ; y = secondary loader size (151 bytes)
;rloop1: lda RCART0 ; read a byte from the cart
; sta EXE,X ; EXE[X] = a
; inx ; x++
; dey ; y--
; bne rloop1 ; loops until y wraps
;
; ; 6. jump to secondary loader
; jmp EXE ; run the secondary loader
;
; .reloc
;**********************************
; After compilation, encryption and obfuscation it turns into this.
;**********************************
.byte $ff, $81, $ca, $33, $be, $80, $a2, $c4
.byte $6d, $98, $fe, $8d, $bc, $66, $c0, $7a
.byte $09, $50, $23, $28, $18, $c8, $06, $70
.byte $58, $4f, $1b, $e1, $c7, $90, $08, $cd
.byte $1a, $6e, $5a, $45, $32, $d7, $6d, $c6
.byte $8a, $e5, $d8, $5c, $a0, $e8, $4f, $7a
.byte $5f, $73, $8d, $22
;**********************************
; Now we have the secondary loader
;**********************************
.org $fb68
; 1. Read in the 1st File-entry (main exe) in FileEntry
ldx #$00
ldy #8
rloop: lda RCART0 ; read a byte from the cart
sta _FileEntry,X ; EXE[X] = a
inx
dey
bne rloop
; 2. Set the block hardware to the main exe start
lda _FileStartBlock
sta _FileCurrBlock
jsr seclynxblock
; 3. Skip over the block offset
lda _FileBlockOffset+1
eor #$FF
tay
lda _FileBlockOffset
eor #$FF
tax
jsr seclynxskip0
; 4. Read in the main exe to RAM
lda _FileDestAddr
ldx _FileDestAddr+1
sta _FileDestPtr
stx _FileDestPtr+1
lda _FileFileLen+1
eor #$FF
tay
lda _FileFileLen
eor #$FF
tax
jsr seclynxread0
; 5. Jump to start of the main exe code
jmp (_FileDestAddr)
;**********************************
; Skip bytes on bank 0
; X:Y count (EOR $FFFF)
;**********************************
seclynxskip0:
inx
bne @0
iny
beq exit
@0: jsr secreadbyte0
bra seclynxskip0
;**********************************
; Read bytes from bank 0
; X:Y count (EOR $ffff)
;**********************************
seclynxread0:
inx
bne @1
iny
beq exit
@1: jsr secreadbyte0
sta (_FileDestPtr)
inc _FileDestPtr
bne seclynxread0
inc _FileDestPtr+1
bra seclynxread0
;**********************************
; Read one byte from cartridge
;**********************************
secreadbyte0:
lda RCART0
inc _FileBlockByte
bne exit
inc _FileBlockByte+1
bne exit
;**********************************
; Select a block
;**********************************
seclynxblock:
pha
phx
phy
lda __iodat
and #$fc
tay
ora #2
tax
lda _FileCurrBlock
inc _FileCurrBlock
sec
bra @2
@0: bcc @1
stx IODAT
clc
@1: inx
stx SYSCTL1
dex
@2: stx SYSCTL1
rol
sty IODAT
bne @0
lda __iodat
sta IODAT
stz _FileBlockByte
lda #<($100-(>__BANK0BLOCKSIZE__))
sta _FileBlockByte+1
ply
plx
pla
exit: rts
.reloc
|