[7dcccbc] | 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 |
|
---|
[413443e] | 8 | LD HL, 0xC9FB
|
---|
| 9 | LD (0x38), HL
|
---|
| 10 |
|
---|
[7dcccbc] | 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 ?
|
---|
[67031cd] | 15 | ; TODO
|
---|
[7dcccbc] | 16 |
|
---|
| 17 | ; Map the ROM in
|
---|
[67031cd] | 18 | LD BC, 0x7F85
|
---|
| 19 | OUT (C),C
|
---|
[7dcccbc] | 20 |
|
---|
| 21 | ; ask the user to enable writing
|
---|
[67031cd] | 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 :(
|
---|
[7dcccbc] | 28 |
|
---|
[67031cd] | 29 | ; ... anyway, start with erasing the sectors we need.
|
---|
| 30 | LD B, 4
|
---|
| 31 | ERASE
|
---|
| 32 | PUSH BC
|
---|
| 33 |
|
---|
| 34 | LD A, 0x80 ; ERASE
|
---|
[7dcccbc] | 35 | CALL send_command
|
---|
| 36 |
|
---|
[67031cd] | 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
|
---|
[413443e] | 58 | EI
|
---|
| 59 | HALT
|
---|
| 60 | HALT
|
---|
| 61 | HALT
|
---|
| 62 | HALT
|
---|
| 63 | DI
|
---|
[67031cd] | 64 |
|
---|
| 65 | DJNZ ERASE
|
---|
| 66 |
|
---|
| 67 | ; Ok, now that we erased the 4 sectors we needed, we can write data to them
|
---|
[7dcccbc] | 68 | LD HL, 0xC000
|
---|
[67031cd] | 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
|
---|
[7dcccbc] | 78 |
|
---|
[67031cd] | 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
|
---|
[413443e] | 86 | INC HL ; 2 2
|
---|
| 87 |
|
---|
| 88 | LD A,H
|
---|
| 89 | OR L
|
---|
| 90 |
|
---|
| 91 | JR NZ, PROGRAM ; 3 8
|
---|
[7dcccbc] | 92 |
|
---|
| 93 | JR $
|
---|
| 94 |
|
---|
[67031cd] | 95 | ; Now reuse and adapt the code from OUL guys !
|
---|
| 96 | ; TODO
|
---|
[7dcccbc] | 97 |
|
---|
| 98 | ; That's all folks !
|
---|
| 99 | RET
|
---|
| 100 |
|
---|
| 101 | ; Helper routines -----------------------------------------------------
|
---|
| 102 |
|
---|
| 103 | ; Send a command to the ROM. The available commands are :
|
---|
[67031cd] | 104 | ;ERASE equ 0x80
|
---|
[7dcccbc] | 105 | IDENTIFY equ 0x90
|
---|
| 106 | BYTEPROG equ 0xA0
|
---|
| 107 | RESET equ 0xF0
|
---|
| 108 |
|
---|
| 109 | ; Input: Commend to send in A register
|
---|
| 110 | send_command:
|
---|
[67031cd] | 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
|
---|
[413443e] | 115 | INC C
|
---|
[67031cd] | 116 | OUT (C),C
|
---|
| 117 | EX DE,HL
|
---|
| 118 | LD (HL), A
|
---|
| 119 |
|
---|
[413443e] | 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 |
|
---|
[67031cd] | 126 | RET
|
---|
| 127 |
|
---|
| 128 | prepare_command:
|
---|
[7dcccbc] | 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
|
---|
[413443e] | 139 | DEC C
|
---|
[7dcccbc] | 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 | ;
|
---|