I'm trying to add a level loader to Boulder Dash, so that BDCK (https://www.cpcwiki.eu/forum/games/bdck-yet-another-boulder-dash-editor)levels can be re-loaded from the game.
The game overwrites AMSDOS. AFAIK it does not use mc_start_program.
Is it possible to re-enable AMSDOS again? I have studied various threads with this topic, but none covered an overwritten AMSDOS.
In particular my level loader overwrites the original code at: #16AF
You can safely enable Amsdos again, but keep in mind that some memory will be overwritten, starting at &a700 normally. You should backup what's there if BD needs it, so you can restore after loading your levels. I don't remember the exacts calls right now, but I am sure you can find it online or maybe a fellow from here will provide it :)
Why does your loader have to be at &16af, though?
Quote from: BSC on 16:14, 27 November 22Why does your loader have to be at &16af, though?
Thanks, I'll try! &16af is the default level decrunching routine. In case anyone will have a look at it ;D
Quote from: pmeier on 14:20, 27 November 22Is it possible to re-enable AMSDOS again? I have studied various threads with this topic, but none covered an overwritten AMSDOS.
The following code will reinitialise the AMSDOS ROM:
initialise_amsdos:
ld hl,(&be7d) ;Get address where current drive number is stored
inc hl ;Move forward 2 bytes to the address where the drive
inc hl ;number of the most recently loaded file is stored
ld a,(hl) ;Get drive number (A = 0, B = 1)
push af ;Store drive number on the stack
ld de,&40
ld hl,&b0ff ;Highest usable byte of memory
ld c,7 ;AMSDOS ROM is located in slot 7
call &bcce ;Initialise the selected ROM
pop af ;Get drive number
ld hl,(&be7d) ;Get new address where drive number is stored
ld (hl),a ;Set drive number
ret
This, of course, relies on the firmware still being in use. If it isn't, then I can provide additional code to reinitialise the firmware as well (although it gets a bit more complicated as you have to modify the code slightly depending on the model of CPC being used).
Quote from: Nich on 20:36, 27 November 22This, of course, relies on the firmware still being in use. If it isn't, then I can provide additional code to reinitialise the firmware as well (although it gets a bit more complicated as you have to modify the code slightly depending on the model of CPC being used).
Indeed the firmware was overwritten, too. I'd love to see your solution.
Nevertheless, your initialise_amsdos routine is very helpful. I'll keep it safe.
Hello.
Maybe this could help : https://z80live.amstrad.info/edit/kFRsABo4Ys3pfYYcT
Best.
Tronic/GPA.
@tronic This looks promising! Thank you! It does restore firmware in my artificial tests, but unfortunately within the game it crashes... I guess I'm going to play with this example for some hours...
Quote from: pmeier on 09:03, 28 November 22Indeed the firmware was overwritten, too. I'd love to see your solution.
Nevertheless, your initialise_amsdos routine is very helpful. I'll keep it safe.
I know
@tronic has posted a link to some code, but here is the code I use (which is quite similar):
;This initialisation routine must not be located in the lower ROM area
;i.e. 0-&3FFF)
himem equ &b0ff ;Highest usable byte of memory when initialising
;AMSDOS
initialise_amsdos:
ld bc,&7f88 ;Set the screen to Mode 0 and enable the lower ROM;
out (c),c ;change BC to &7F89 for Mode 1, &7F8A for Mode 2
exx
xor a
ex af,af'
call &0044 ;Initialise the firmware
initialise_firmware_call:
call &08bd ;Change address to &0888 for CPC464 machines and &08BB
;for CPC664 machines
call &bb00
call &b909 ;Disable the lower ROM
ld a,&c9 ;&C9 = RET instruction
ld (&bb5a),a ;Disable printing of text to the screen
;Initialise all ROMs, including AMSDOS
ld de,&40
ld hl,himem ;Highest usable byte of memory
ld c,7 ;AMSDOS ROM is located in slot 7
call &bcce ;Initialise the selected ROM
ld a,&ff
ld (&be78),a ;Disable disc error message prompts
;Set the drive number to use when loading files
set_drive_number:
ld a,0 ;0 = drive A, 1 = drive B
ld (himem-&04ff),a ;Set the drive number
ret
And to find out what address you need to use to initialise the firmware, and to set the drive to use (A or B), use this code:
ld hl,(&bd38) ;Get the address in the lower ROM that CALL &BD37
;(which initialises the firmware) jumps to
res 7,h ;Set bit 7 of H to zero
ld (initialise_firmware_call+1),hl ;Store the address in the
;initialisation routine
ld hl,(&be7d) ;Get address where current drive number is stored
inc hl ;Move forward 2 bytes to the address where the drive
inc hl ;number of the most recently loaded file is stored
ld a,(hl) ;Get drive number (A = 0, B = 1)
ld (set_drive_number+1),a ;Store it in the initialisation routine
@Nich /
@tronic Thank you. Both solutions do the job!