19Fermer21
chickendudeLe 25/02/2013 à 13:35
Maintenant je bosse sur l'exécution des programmes dans RAM. Ça résulte assez compliqué :/ J'ai écrit une routine qui copie le program à $9D95, mais ça ne te permet utiliser que la motie de la RAM (sinon on aura pas espace suffisant pour le _InsertMem). Voice le "simple way" :
simpleWay:
;get program size
	ld e,(hl)
	inc hl
	ld d,(hl)				;de = program size, first two bytes in data
	dec de
	dec de					;-2 because of AsmPrgm token
;check if it starts with AsmPrgm token
	inc hl					;$BB
	ld a,(hl)
	cp $BB					;if first byte isn't $BB, not an assembly program
	 jr nz,zshell_hook_return_z	;parse as basic
	inc hl					;$6D AsmPrgm token (2 bytes)
	ld a,(hl)
	cp $6D
	 jr nz,zshell_hook_return_z	;if program is not an assembly program, quit
;create space at $9D95 to load the program
	inc hl					;first byte of program data
	push hl					;hl = first byte of prog data
	push de					;de = prog size (-AsmPrgm token)
		ex de,hl			;hl = prog size
		ld de,progstart		;$9D95
		bcall(_InsertMem)	;insert 'hl' bytes to $9D95
	pop bc					;bc = size of program
	pop hl					;hl = first byte of program data
	push bc					;save size of program
		add hl,bc			;we've inserted 'bc' bytes ;)
		ldir				;de = progstart
		call progstart		;run the program
;now delete that memory
	pop de					;de = number of bytes to delete
	ld hl,progstart			;hl = where to delete them from
	bcall($4357)			;_DelMem
	ret
Bientôt j'aurai fini le "hard way", au moins la première partie smile

EDIT : Ok, ça marche !
progstartLocation = saferam1	;current address in progstart
progAddress = saferam1+2		;current address of program in RAM

;the program is in RAM, so let's copy it to $9D95!
;hl = pointer to start of data
;de = VAT info (not important)
;a = 0 (in RAM) (also unimportant)
zshell_hook_execute_prgm_ram:
;get program size
	ld e,(hl)
	inc hl
	ld d,(hl)				;de = program size, first two bytes in data
	dec de
	dec de					;-2 because of AsmPrgm token
;check if it starts with AsmPrgm token
	inc hl					;$BB
	ld a,(hl)
	cp $BB					;if first byte isn't $BB, not an assembly program
	 jr nz,zshell_hook_return_z	;parse as basic
	inc hl					;$6D AsmPrgm token (2 bytes)
	ld a,(hl)
	cp $6D
	 jr nz,zshell_hook_return_z	;if program is not an assembly program, quit
	inc hl					;first byte of program data
load_program_to_progstart:
;hl = first byte of program data
;de = program size
	ld bc,progstart
	ld (progstartLocation),bc
	ld (progAddress),hl
	ex de,hl				;hl = size
load_loop:
;check if there are <768 bytes left to copy
	ld bc,768
	or a
	sbc hl,bc				;subtract 768 from the program size
	 jr nc,$+8				;if no carry, there are still more than 768 bytes to copy
		add hl,bc
		ld c,l
		ld b,h
		ld hl,$0000
	push hl					;how many bytes left to copy
	ld hl,(progAddress)
;copy the program to the gbuf
		push bc				;hl = program data start
			ld de,gbuf		;bc = # bytes to copy
			ldir			;copy bc bytes
		pop de				;# bytes copied
		ld (progAddress),hl	;save new program data pointer
;delete BC bytes from the program
		or a				;hl = start of prog data + 768
		sbc hl,de			;
		push de				;de = # of bytes copied
			bcall(_DelMem)	;hl = where to delete from, de = # bytes
		pop hl				;hl = # bytes deleted
;insert HL bytes to $9D95
		ld de,(progstartLocation)	;$9D95
		push hl				;hl = # bytes deleted
			bcall(_InsertMem)	;insert 'hl' bytes to $9D95
		pop bc				;bc = bytes deleted
		ld hl,(progstartLocation)		;ex de,hl ???
		add hl,bc
		ld (progstartLocation),hl
;copy gbuf to $9D95
		ld hl,gbuf			;de = location where memory was inserted ($9D95+XXX)
		ldir				;copy # of bytes deleted from gbuf to progstart
	pop hl					;how many bytes are left to copy
	ld a,l
	or h
	 jr nz,load_loop

	call progstart			;run the program
;now rewrite the data back into the program
;...not done yet...
	ret


x7e3

Pour le moment tu ne peux l'exécuter qu'une fois parce que je ne copie pas le programme de nouveau (donc la seconde fois le programme sera vide :P). Mais je crois que je peut tout simplement invertir progstartLocation et progAddress...