-
Notifications
You must be signed in to change notification settings - Fork 0
/
Eaton.hs
49 lines (40 loc) · 1.26 KB
/
Eaton.hs
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
-- | Eaton specific stuff.
module Eaton
( esb
, bootloader
, jumpToBoot
) where
import Data.Bits
import Data.Digest.CRC32
import Data.Word
import PPC
import Utils
-- | Create an image in Eaton's ESB format.
esb :: [Word8] -> [Word8]
esb image = [0xE5, 0x5B, 0xBE, 0xE5, 5, 0, 0, 0] ++ le (fromIntegral $ crc32 block) ++ block
where
block :: [Word8]
block = [1, 0, 0, 0, 3, 0, 0, 0, 128, 0, 0, 0] ++ le (length image) ++ image
-- | Insert appropriate fields for Eaton's bootloader. Programs must start at address 0x8001c.
bootloader :: [Word8] -> [Word8]
bootloader program' = be (0 - sum block) ++ block
where
program = program' ++ case (length program' + 4) `mod` 8 of
0 -> []
n -> replicate (8 - n) 0
sa = 3
block :: [Word8]
block = be (length program + 0x8001c)
++ assemble (ba 0x8001c)
++ [0xea, 0x55, 0xaa, 0x01]
++ [0x90, 0x12, 0x00, 0x00]
++ [0, 0, 0, 0]
++ [130, sa] ++ [0xff, 0xff]
++ program
sum :: [Word8] -> Int
sum (a : b : c : d : rest) = foldl1 (.|.) [ shiftL (fromIntegral a) n | (a, n) <- zip [a, b, c, d] [24, 16, 8, 0] ] + sum rest
sum [] = 0
sum _ = error "words not on 32-bit boundry"
-- | Jump back to the bootloader from the application.
jumpToBoot :: PPC
jumpToBoot = ba 0x8