Changeset 7c25c3e in avrstuff
- Timestamp:
- Nov 28, 2012, 10:59:11 PM (11 years ago)
- Branches:
- main
- Children:
- 0853bac
- Parents:
- 1d60f7b
- Location:
- CPC stuff/gordon/manager
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
CPC stuff/gordon/manager/Makefile
r1d60f7b r7c25c3e 9 9 # TODO use a target variable for the address, and get it from VASM/VLINK somehow 10 10 $(NAME).BIN:: gordon.o 11 $(NAME).BIN: START = 0x 200011 $(NAME).BIN: START = 0x1800 12 12 13 13 include cpc.mk -
CPC stuff/gordon/manager/cpc.mk
r1d60f7b r7c25c3e 35 35 36 36 # Assemble the sources 37 %.o: %.z80 37 %.o: %.z80 Makefile 38 38 $(call BECHO,"Assembling $<...") 39 39 vasmz80_oldstyle -Fvobj -o $@ $< -
CPC stuff/gordon/manager/gordon.z80
r1d60f7b r7c25c3e 3 3 ; This program is distributed under the terms of the MIT licence 4 4 5 ; Start here. 5 GLOBAL _start 6 7 ; Friendly firmware functions 8 getc EQU 0xBB06 9 putc EQU 0xBB5A 10 screenmem EQU 0xBC08 11 12 13 ; FIXME the plan is to have the same file behave both as a ROM and as an 14 ; executable, so it can bootstrap itself into the megaflash. So we should start 15 ; with a standard ROM header. RSXs to expose are : 16 ; |BURN,"file",n (load file to &4000, then copy it to ROM n) 17 ; |HIDE,n (write a FF as first byte in ROM to hide it from firmware) 18 ; |HIDE (hides all ROMs) 19 ; |SHOW,n (restore ROM n to visible state 20 ; |SHOW (shows all ROMs) 21 ; |KILL,n (erases ROM n) 22 23 ; This is the entry point when running as a standalone file 24 _start 25 ; Ask the user to allow us to write to the flash memory 26 LD HL,MSG_WRITE_START 27 CALL puts 28 CALL getc 29 ; From there on, writing is enabled. This is ok as long as we don't 30 ; connect a writable ROM ! When we do, we have to make sure NOTHING 31 ; is read written from 8000-FFFF because the MegaFlash hardware 32 ; doesn't decode A14 and will answer for the whole 32k range. This 33 ; means, no use of firmware jumpblocks, and the stack needs to be 34 ; moved elsewhere 35 6 36 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 37 ; Move the stack away from the $8000-$FFFF area, since any write there 38 ; will be intercepted by the Megaflash (it does not decode A14). 39 LD (stack),SP 40 LD SP,0x7FFF 41 42 ; Save the interrupt vector and replace it with EI/RET 43 LD HL,(0x38) 44 LD (inthandle),HL 45 LD HL,0xC9FB 46 LD (0x38),HL 47 48 ; TODO get the ROM number to burn somehow ? 49 ; (we can get it as a CALL parameter) 50 51 CALL ERASE 52 CALL WRITE 53 54 ; Disconnect the Megaflash 55 LD BC,0xDFFF 56 OUT (C),C 57 58 ; Restore the firmware in working order now that we are done 59 LD SP,(stack) 60 LD HL,(inthandle) 61 LD (0x38),HL 62 EI 63 64 ; Tell firmware to draw the screen at &4000 (so we don't erase the 65 ; ROM with the next message...) 66 LD A,0x40 67 CALL screenmem 68 69 LD HL,MSG_WRITE_END 70 CALL puts 71 ; Wait for key 72 CALL 0xBB06 73 74 ; Put screen back at normal address 75 LD A,0xC0 76 CALL screenmem 77 78 ; TODO cleanly get out (and handle both calls by RUN and CALL) 79 JR $ 80 81 ; Erase a 16K ROM. Input: 82 ; A - ROM number to erase (TODO) 83 ; Assumes we are in write mode, interrupts disabled. 31 84 ERASE 32 PUSH BC 85 LD B,4 86 eraseloop 87 PUSH BC 33 88 34 89 LD A, 0x80 ; ERASE … … 51 106 52 107 LD H,A 53 108 LD L,0 109 110 ; Sector erase command 54 111 LD E, 0x30 55 112 LD (HL), E 56 113 57 ; This will delay long enough - we need at least 2 5ms114 ; This will delay long enough - we need at least 20ms 58 115 EI 59 116 HALT … … 61 118 HALT 62 119 HALT 120 HALT 121 HALT 122 HALT 63 123 DI 64 124 65 DJNZ ERASE 66 125 DJNZ eraseloop 126 127 RET 128 129 130 ; Write a 16K ROM 131 ; IN: A - ROM number to write (TODO) 132 ; &2000 - Data to copy (TODO let the caller put that in IX maybe ?) 133 ; Assumes we are in write-enabled mode (TODO) 134 WRITE 67 135 ; Ok, now that we erased the 4 sectors we needed, we can write data to them 68 136 LD HL, 0xC000 69 LD IX, 0x 4000137 LD IX, 0x2000 70 138 PROGRAM 71 LD A, 0xA0 ; BYTE PROGRAM ; 2 10 72 PUSH HL ; 3 13 73 CALL send_command ; 5 18 139 PUSH HL 140 141 LD A, 0xA0 ; BYTE PROGRAM 142 CALL send_command 143 144 POP HL 74 145 75 146 LD B,0xDF … … 77 148 OUT (C),C 78 149 79 POP HL80 81 150 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 151 LD (HL),A ; Write occurs here. Need to wait 20 NOPs before next 152 ; operation on ROM. Our code is slow enough already ! 153 154 INC IX 155 INC HL 156 157 ; As INC HL doesn't update the flags, check if we overflowed yet 88 158 LD A,H 89 159 OR L 90 160 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 ! 161 JR NZ, PROGRAM 162 99 163 RET 100 164 … … 113 177 114 178 ; Select ROM 1 again and write the command to address 0xEAAA 115 INC C179 DEC C 116 180 OUT (C),C 117 181 EX DE,HL … … 137 201 138 202 ; Select ROM 2 and write 0x55 to address 0xEAAA 139 DEC C203 INC C 140 204 OUT (C),C 141 205 EX DE,HL … … 145 209 146 210 147 ; Print value of A, as 2 hex digits 148 printhex 211 ; Write message pointed by HL to screen 212 puts 213 LD A,(HL) 214 INC HL 215 CALL &BB5A 216 OR A 217 JR NZ,puts 218 RET 219 220 ; ----------------------------------------------------------------------------- 221 ; Messages 222 MSG_WRITE_START string "Turn write switch ON and press a key...\r\n" 223 MSG_WRITE_END string "Turn write switch OFF and press a key...\r\n" 224 225 ; ----------------------------------------------------------------------------- 226 SECTION .uninit,"urw" 227 228 stack DEFW 1 229 inthandle DEFW 1 230 231 end 232 233 ; Very basic command prompt/monitor stuff for testing 234 ; Print prompt 235 LD A,'?' 236 CALL 0xBB5A 237 ; Wait for key 238 CALL 0xBB06 239 ; Parse commands 240 CP A,'d' 241 JP Z,DUMP 242 CP A,'e' 243 JP Z,ERASE 244 CP A,'w' 245 JP Z,WRITE 246 247 ; Unhandled command 248 LD A,'X' 249 CALL 0xBB5A 250 251 ; Start over 252 JR _start 253 254 255 ; Dump some bytes from beginning of ROM 5 256 DUMP 257 DI 258 259 ; Map the ROM in (stay in mode 1 and get system rom out) 260 LD BC, 0x7F85 261 OUT (C),C 262 263 LD BC,0xDF05 264 OUT (C),C 265 266 ; Copy the ROM to RAM 267 LD DE, 0x4000 268 LD BC, 0x4000 269 LD HL, 0xC000 270 LDIR 271 272 EI 273 274 ; Dump the RAM (we're safe if the system maps another ROM this way) 275 LD HL,0x4000 276 plop 277 LD A,(HL) 278 INC HL 279 CALL PRNHEX2 280 DJNZ plop 281 282 ; Wait for next command 283 JP _start 284 285 286 PRNHEX2 ;affiche la valeur de A sur 2 chiffres 287 ; en hexad{cimal 149 288 PUSH AF 150 289 RRA … … 163 302 ;on a le code ascii du chiffre @ afficher 164 303 JP 0xBB5A ;call-ret 165 ; 304 305 306 PRNHEX2 ;affiche la valeur de A sur 2 chiffres 307 ; en hexad{cimal 308 PUSH AF 309 RRA 310 RRA 311 RRA 312 RRA ;divise A par 8 313 CALL PRNHEX1 ;affiche le premier morceau 314 POP AF ;r{cup la valeur originale pour la suit 315 PRNHEX1 ;affiche la valeur de A sur 1 chiffre 316 ;affiche A sur 1 chiffre en Hexa 317 AND 0xF ;ne prend que les unit{s 318 OR A 319 DAA ;convertit en d{cimal 320 ADD A,0xF0 ;ajoute 240 321 ADC A,0x40 ;ajoute 64+le carry (si >15) 322 ;on a le code ascii du chiffre @ afficher 323 JP 0xBB5A ;call-ret 324 325 -
CPC stuff/gordon/manager/link.ld
r1d60f7b r7c25c3e 1 1 SECTIONS { 2 2 .text: { *(.text) } 3 . = MAX(.,0x3FFC); 4 .romcalls: { *(.romcalls) } 3 .uninit: { *(.uninit) } 5 4 }
Note:
See TracChangeset
for help on using the changeset viewer.