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
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
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...