1 | ; FLASH GORDON driver
|
---|
2 | ; Copyright 2012, Adrien Destugues <pulkomandy@gmail.com>
|
---|
3 | ; This program is distributed under the terms of the MIT licence
|
---|
4 |
|
---|
5 | ; Start here.
|
---|
6 | DI
|
---|
7 |
|
---|
8 | LD HL, 0xC9FB
|
---|
9 | LD (0x38), HL
|
---|
10 |
|
---|
11 | ; Move the screen to $8000 or $0000 so we can display things to the user, while
|
---|
12 | ; C000 will write to the ROM and 4000 will hold the data to write... That could
|
---|
13 | ; get a bit messy so maybe we will need to use the screen at 4000 as a buffer
|
---|
14 | ; for the ROM data as well. Or just use a bank for that ?
|
---|
15 | ; TODO
|
---|
16 |
|
---|
17 | ; Map the ROM in
|
---|
18 | LD BC, 0x7F85
|
---|
19 | OUT (C),C
|
---|
20 |
|
---|
21 | ; ask the user to enable writing
|
---|
22 | ; TODO
|
---|
23 |
|
---|
24 | ; Turns out with the MegaFlash design, we can't both read and write. When the
|
---|
25 | ; memory is in write mode, reading is disabled. This means we can't identify
|
---|
26 | ; the chip, or use the data polling features. And we have to go for the
|
---|
27 | ; worst-case timing given in the datasheet :(
|
---|
28 |
|
---|
29 | ; ... anyway, start with erasing the sectors we need.
|
---|
30 | LD B, 4
|
---|
31 | ERASE
|
---|
32 | PUSH BC
|
---|
33 |
|
---|
34 | LD A, 0x80 ; ERASE
|
---|
35 | CALL send_command
|
---|
36 |
|
---|
37 | CALL prepare_command
|
---|
38 |
|
---|
39 | LD B,0xDF
|
---|
40 | LD C,5 ; ROM number to write (FIXME get it as a RSX param)
|
---|
41 | OUT (C),C
|
---|
42 |
|
---|
43 | ; Compute address near start of sector
|
---|
44 | POP BC
|
---|
45 | LD A,B
|
---|
46 | DEC A
|
---|
47 | SLA A
|
---|
48 | SLA A
|
---|
49 |
|
---|
50 | ADD 0xC0
|
---|
51 |
|
---|
52 | LD H,A
|
---|
53 |
|
---|
54 | LD E, 0x30
|
---|
55 | LD (HL), E
|
---|
56 |
|
---|
57 | ; This will delay long enough - we need at least 25ms
|
---|
58 | EI
|
---|
59 | HALT
|
---|
60 | HALT
|
---|
61 | HALT
|
---|
62 | HALT
|
---|
63 | DI
|
---|
64 |
|
---|
65 | DJNZ ERASE
|
---|
66 |
|
---|
67 | ; Ok, now that we erased the 4 sectors we needed, we can write data to them
|
---|
68 | LD HL, 0xC000
|
---|
69 | LD IX, 0x4000
|
---|
70 | PROGRAM
|
---|
71 | LD A, 0xA0 ; BYTE PROGRAM ; 2 10
|
---|
72 | PUSH HL ; 3 13
|
---|
73 | CALL send_command ; 5 18
|
---|
74 |
|
---|
75 | LD B,0xDF
|
---|
76 | LD C,5 ; ROM number to write (FIXME get it as a RSX param)
|
---|
77 | OUT (C),C
|
---|
78 |
|
---|
79 | POP HL
|
---|
80 |
|
---|
81 | LD A,(IX + 0)
|
---|
82 | LD (HL),A ; Write occurs here. Need to wait 20 NOPs before next
|
---|
83 | ; operation on ROM. Our code is slow enough already !
|
---|
84 |
|
---|
85 | INC IX ; 3 5
|
---|
86 | INC HL ; 2 2
|
---|
87 |
|
---|
88 | LD A,H
|
---|
89 | OR L
|
---|
90 |
|
---|
91 | JR NZ, PROGRAM ; 3 8
|
---|
92 |
|
---|
93 | JR $
|
---|
94 |
|
---|
95 | ; Now reuse and adapt the code from OUL guys !
|
---|
96 | ; TODO
|
---|
97 |
|
---|
98 | ; That's all folks !
|
---|
99 | RET
|
---|
100 |
|
---|
101 | ; Helper routines -----------------------------------------------------
|
---|
102 |
|
---|
103 | ; Send a command to the ROM. The available commands are :
|
---|
104 | ;ERASE equ 0x80
|
---|
105 | IDENTIFY equ 0x90
|
---|
106 | BYTEPROG equ 0xA0
|
---|
107 | RESET equ 0xF0
|
---|
108 |
|
---|
109 | ; Input: Commend to send in A register
|
---|
110 | send_command:
|
---|
111 | ; That code is shared with sector erase which has some tricks
|
---|
112 | call prepare_command
|
---|
113 |
|
---|
114 | ; Select ROM 1 again and write the command to address 0xEAAA
|
---|
115 | INC C
|
---|
116 | OUT (C),C
|
---|
117 | EX DE,HL
|
---|
118 | LD (HL), A
|
---|
119 |
|
---|
120 | ; Select ROM 0xFF, which basically prevents future accesses to get to the
|
---|
121 | ; Flash chip.
|
---|
122 | DEC C
|
---|
123 | DEC C
|
---|
124 | OUT (C),C
|
---|
125 |
|
---|
126 | RET
|
---|
127 |
|
---|
128 | prepare_command:
|
---|
129 | ; Select ROM 1
|
---|
130 | LD BC,0xDF01
|
---|
131 | LD HL,0xD555
|
---|
132 | LD DE,0xEAAA
|
---|
133 |
|
---|
134 | ; Select ROM 1 and write 0xAA to address 0xD555
|
---|
135 | OUT (C),C
|
---|
136 | LD (HL),E
|
---|
137 |
|
---|
138 | ; Select ROM 2 and write 0x55 to address 0xEAAA
|
---|
139 | DEC C
|
---|
140 | OUT (C),C
|
---|
141 | EX DE,HL
|
---|
142 | LD (HL), E
|
---|
143 |
|
---|
144 | RET
|
---|
145 |
|
---|
146 |
|
---|
147 | ; Print value of A, as 2 hex digits
|
---|
148 | printhex
|
---|
149 | PUSH AF
|
---|
150 | RRA
|
---|
151 | RRA
|
---|
152 | RRA
|
---|
153 | RRA ;divise A par 8
|
---|
154 | CALL PRNHEX1 ;affiche le premier morceau
|
---|
155 | POP AF ;r{cup la valeur originale pour la suit
|
---|
156 | PRNHEX1 ;affiche la valeur de A sur 1 chiffre
|
---|
157 | ;affiche A sur 1 chiffre en Hexa
|
---|
158 | AND 0xF ;ne prend que les unit{s
|
---|
159 | OR A
|
---|
160 | DAA ;convertit en d{cimal
|
---|
161 | ADD A,0xF0 ;ajoute 240
|
---|
162 | ADC A,0x40 ;ajoute 64+le carry (si >15)
|
---|
163 | ;on a le code ascii du chiffre @ afficher
|
---|
164 | JP 0xBB5A ;call-ret
|
---|
165 | ;
|
---|