News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

MC START/BOOT PROGRAM WITHOUT reseting firmware jumpblock?

Started by ikonsgr, 13:47, 30 January 19

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ikonsgr

Hi everyone,

I'm in a process of developing a code for direct load and execution of programs using the Serial interface i've also developed. I'm using the classic method of patching the firmware routines for CAS IN OPEN, CAS IN DIRECT, CAS IN CLOSE, and redirect them to execute my code. Everything works perfect for loading/running BASIC programs or single binary programs.
BUT,unfortunately whenever a binary loader uses MC START PROGRAM or MC BOOT PROGRAM routines, program either crashes or tries to load next file from disk (giving a "File not found" message), obviously because these routines reset the firmware jumpblocks.
So,i was wondering,is there a way to somehow "emulate" these two routines inside my code,in order to avoid the firmware jumpblock reset? Or perhaps, there is another way to do it?...

Docent

Quote from: ikonsgr on 13:47, 30 January 19
Hi everyone,

I'm in a process of developing a code for direct load and execution of programs using the Serial interface i've also developed. I'm using the classic method of patching the firmware routines for CAS IN OPEN, CAS IN DIRECT, CAS IN CLOSE, and redirect them to execute my code. Everything works perfect for loading/running BASIC programs or single binary programs.
BUT,unfortunately whenever a binary loader uses MC START PROGRAM or MC BOOT PROGRAM routines, program either crashes or tries to load next file from disk (giving a "File not found" message), obviously because these routines reset the firmware jumpblocks.
So,i was wondering,is there a way to somehow "emulate" these two routines inside my code,in order to avoid the firmware jumpblock reset? Or perhaps, there is another way to do it?...
Both routines do jumpblock reinitialization, so your changes are no longer there.
You have two options:
1. use rom disassembly and copy both routines from rom into your program so you can have full control over it, or
2. patch both calls to point to your own routine, first storing original pointers in your code. In this routine:
a. remember provided start address
b. set your own start address to your boot routine
c. call saved original routines so the system will perform initializations and will jump into your code
d. restore your jumpblock patches
e. call original start address from step a


ikonsgr

I've checked these 2 routines, they both execute LOW jump calls 'RST 1' to OS rom. I tried to "isolate" the MC BOOT PROGRAM routine from the OS rom, and i used this online disassmbler:
https://onlinedisassembler.com/odaweb/
This is the assembly output code:
Spoiler: ShowHide

                           .data:00000000 31 00 c0                         ld sp,0xc000
                           .data:00000003 e5                               push hl
                           .data:00000004 cd e9 1f                         call 0x1fe9
                           .data:00000007 f3                               di
                           .data:00000008 01 ff f8                         ld bc,0xf8ff
                           .data:0000000b ed 49                            out (c),c
                           .data:0000000d cd 5c 00                         call 0x005c
                           .data:00000010 e1                               pop hl
                           .data:00000011 d5                               push de
                           .data:00000012 c5                               push bc
                           .data:00000013 e5                               push hl
                           .data:00000014 cd 98 1b                         call 0x1b98
                           .data:00000017 cd 84 10                         call 0x1084
                           .data:0000001a cd d0 0a                         call 0x0ad0
                           .data:0000001d cd 5f ba                         call 0xba5f
                           .data:00000020 e1                               pop hl
                           .data:00000021 cd 1e 00                         call 0x001e
                           .data:00000024 c1                               pop bc
                           .data:00000025 d1                               pop de
                           .data:00000026 38 07                            jr c,0x002f
                           .data:00000028 eb                               ex de,hl
                           .data:00000029 48                               ld c,b
                           .data:0000002a 11 f9 06                         ld de,0x06f9
                           .data:0000002d 18 03                            jr 0x0032
                           .data:0000002f 11 37 07                         ld de,0x0737
                           .data:00000032 f3                               di
                           .data:00000033 ed 56                            im 1
                           .data:00000035 d9                               exx
                           .data:00000036 01 00 df                         ld bc,0xdf00
                           .data:00000039 ed 49                            out (c),c
                           .data:0000003b 01 ff f8                         ld bc,0xf8ff
                           .data:0000003e ed 49                            out (c),c
                           .data:00000040 01 c0 7f                         ld bc,0x7fc0
                           .data:00000043 ed 49                            out (c),c
                           .data:00000045 01 7e fa                         ld bc,0xfa7e
                           .data:00000048 af                               xor a
                           .data:00000049 ed 79                            out (c),a
                           .data:0000004b 21 00 b1                         ld hl,0xb100
                           .data:0000004e 11 01 b1                         ld de,0xb101
                           .data:00000051 01 f9 07                         ld bc,0x07f9
                           .data:00000054 77                               ld (hl),a
                           .data:00000055 ed b0                            ldir
                           .data:00000057 01 89 7f                         ld bc,0x7f89
                           .data:0000005a ed 49                            out (c),c
                           .data:0000005c d9                               exx
                           .data:0000005d af                               xor a
                           .data:0000005e 08                               ex af,af'
                           .data:0000005f 31 00 c0                         ld sp,0xc000
                           .data:00000062 e5                               push hl
                           .data:00000063 c5                               push bc
                           .data:00000064 d5                               push de
                           .data:00000065 cd 44 00                         call 0x0044
                           .data:00000068 cd bd 08                         call 0x08bd
                           .data:0000006b cd 5c 1b                         call 0x1b5c
                           .data:0000006e cd e9 1f                         call 0x1fe9
                           .data:00000071 cd bf 0a                         call 0x0abf
                           .data:00000074 cd 74 10                         call 0x1074
                           .data:00000077 cd a8 15                         call 0x15a8
                           .data:0000007a cd bc 24                         call 0x24bc
                           .data:0000007d cd e0 07                         call 0x07e0
                           .data:00000080 fb                               ei
                           .data:00000081 e1                               pop hl
                           .data:00000082 cd 1e 00                         call 0x001e
                           .data:00000085 c1                               pop bc
                           .data:00000086 e1                               pop hl
                           .data:00000087 c3 77 00                         jp 0x0077
                           .data:0000008a 21 02 02                         ld hl,0x0202
                           .data:0000008d cd 70 11                         call 0x1170
                           .data:00000090 cd 23 07                         call 0x0723
                           .data:00000093 cd fc 06                         call 0x06fc
                           .data:00000096 21 88 06                         ld hl,0x0688
                           .data:00000099 18 74                            jr 0x010f
                           .data:0000009b 20 31                            jr nz,0x00ce
                           .data:0000009d 32 38 4b                         ld (0x4b38),a
                           .data:000000a0 20 4d                            jr nz,0x00ef
                           .data:000000a2 69                               ld l,c
                           .data:000000a3 63                               ld h,e
                           .data:000000a4 72                               ld (hl),d
                           .data:000000a5 6f                               ld l,a
                           .data:000000a6 63                               ld h,e
                           .data:000000a7 6f                               ld l,a
                           .data:000000a8 6d                               ld l,l
                           .data:000000a9 70                               ld (hl),b
                           .data:000000aa 75                               ld (hl),l
                           .data:000000ab 74                               ld (hl),h
                           .data:000000ac 65                               ld h,l
                           .data:000000ad 72                               ld (hl),d
                           .data:000000ae 20 20                            jr nz,0x00d0
                           .data:000000b0 28 76                            jr z,0x0128
                           .data:000000b2 33                               inc sp
                           .data:000000b3 29                               add hl,hl
                           .data:000000b4 1f                               rra
                           .data:000000b5 02                               ld (bc),a
                           .data:000000b6 04                               inc b
                           .data:000000b7 43                               ld b,e
                           .data:000000b8 6f                               ld l,a
                           .data:000000b9 70                               ld (hl),b
                           .data:000000ba 79                               ld a,c
                           .data:000000bb 72                               ld (hl),d
                           .data:000000bc 69                               ld l,c
                           .data:000000bd 67                               ld h,a
                           .data:000000be 68                               ld l,b
                           .data:000000bf 74                               ld (hl),h
                           .data:000000c0 1f                               rra
                           .data:000000c1 02                               ld (bc),a
                           .data:000000c2 04                               inc b
                           .data:000000c3 a4                               and h
                           .data:000000c4 31 39 38                         ld sp,0x3839
                           .data:000000c7 35                               dec (hl)
                           .data:000000c8 20 41                            jr nz,0x010b
                           .data:000000ca 6d                               ld l,l
                           .data:000000cb 73                               ld (hl),e
                           .data:000000cc 74                               ld (hl),h
                           .data:000000cd 72                               ld (hl),d
                           .data:000000ce 61                               ld h,c
                           .data:000000cf 64                               ld h,h
                           .data:000000d0 20 43                            jr nz,0x0115
                           .data:000000d2 6f                               ld l,a
                           .data:000000d3 6e                               ld l,(hl)
                           .data:000000d4 73                               ld (hl),e
                           .data:000000d5 75                               ld (hl),l
                           .data:000000d6 6d                               ld l,l
                           .data:000000d7 65                               ld h,l
                           .data:000000d8 72                               ld (hl),d
                           .data:000000d9 20 45                            jr nz,0x0120
                           .data:000000db 6c                               ld l,h
                           .data:000000dc 65                               ld h,l
                           .data:000000dd 63                               ld h,e
                           .data:000000de 74                               ld (hl),h
                           .data:000000df 72                               ld (hl),d
                           .data:000000e0 6f                               ld l,a
                           .data:000000e1 6e                               ld l,(hl)
                           .data:000000e2 69                               ld l,c
                           .data:000000e3 63                               ld h,e
                           .data:000000e4 73                               ld (hl),e
                           .data:000000e5 20 70                            jr nz,0x0157
                           .data:000000e7 6c                               ld l,h
                           .data:000000e8 63                               ld h,e
                           .data:000000e9 1f                               rra
                           .data:000000ea 0c                               inc c
                           .data:000000eb 05                               dec b
                           .data:000000ec 61                               ld h,c
                           .data:000000ed 6e                               ld l,(hl)
                           .data:000000ee 64                               ld h,h
                           .data:000000ef 20 4c                            jr nz,0x013d
                           .data:000000f1 6f                               ld l,a
                           .data:000000f2 63                               ld h,e
                           .data:000000f3 6f                               ld l,a
                           .data:000000f4 6d                               ld l,l
                           .data:000000f5 6f                               ld l,a
                           .data:000000f6 74                               ld (hl),h
                           .data:000000f7 69                               ld l,c
                           .data:000000f8 76                               halt
                           .data:000000f9 65                               ld h,l
                           .data:000000fa 20 53                            jr nz,0x014f
                           .data:000000fc 6f                               ld l,a
                           .data:000000fd 66                               ld h,(hl)
                           .data:000000fe 74                               ld (hl),h
                           .data:000000ff 77                               ld (hl),a
                           .data:00000100 61                               ld h,c
                           .data:00000101 72                               ld (hl),d
                           .data:00000102 65                               ld h,l
                           .data:00000103 20 4c                            jr nz,0x0151
                           .data:00000105 74                               ld (hl),h
                           .data:00000106 64                               ld h,h
                           .data:00000107 2e 1f                            ld l,0x1f
                           .data:00000109 01 07 00                         ld bc,0x0007
                           .data:0000010c 21 05 07                         ld hl,0x0705
                           .data:0000010f 7e                               ld a,(hl)
                           .data:00000110 23                               inc hl
                           .data:00000111 b7                               or a
                           .data:00000112 c8                               ret z
                           .data:00000113 cd fe 13                         call 0x13fe
                           .data:00000116 18 f7                            jr 0x010f
                           .data:00000118 2a 2a 2a                         ld hl,(0x2a2a)
                           .data:0000011b 20 50                            jr nz,0x016d
                           .data:0000011d 52                               ld d,d
                           .data:0000011e 4f                               ld c,a
                           .data:0000011f 47                               ld b,a
                           .data:00000120 52                               ld d,d
                           .data:00000121 41                               ld b,c
                           .data:00000122 4d                               ld c,l
                           .data:00000123 20 4c                            jr nz,0x0171
                           .data:00000125 4f                               ld c,a
                           .data:00000126 41                               ld b,c
                           .data:00000127 44                               ld b,h
                           .data:00000128 20 46                            jr nz,0x0170
                           .data:0000012a 41                               ld b,c
                           .data:0000012b 49                               ld c,c
                           .data:0000012c 4c                               ld c,h
                           .data:0000012d 45                               ld b,l
                           .data:0000012e 44                               ld b,h
                           .data:0000012f 20 2a                            jr nz,0x015b
                           .data:00000131 2a 2a 0d                         ld hl,(0x0d2a)
                           .data:00000134 0a                               ld a,(bc)
                           .data:00000135 00                               nop
                           .data:00000136 06 f5                            ld b,0xf5
                           .data:00000138 ed 78                            in a,(c)
                           .data:0000013a 2f                               cpl
                           .data:0000013b e6 0e                            and 0x0e
                           .data:0000013d 0f                               rrca
                           .data:0000013e 21 38 07                         ld hl,0x0738
                           .data:00000141 3c                               inc a
                           .data:00000142 47                               ld b,a
                           .data:00000143 7e                               ld a,(hl)
                           .data:00000144 23                               inc hl
                           .data:00000145 b7                               or a
                           .data:00000146 20 fb                            jr nz,0x0143
                           .data:00000148 10 f9                            djnz 0x0143
                           .data:0000014a c9                               ret


The problem is that, it includes more than a dozen of Calls all over the rom, so in order to get the MC boot program routine i would also include these, but i'm afraid it would be like adding the intire OS rom...  ::)

ALso,i've tried to "emulate" the routine:
Spoiler: ShowHide
PUSH HL ;;HL holds the address of the loading routine
DI
CALL &BD06 ;;KL EVENT DISABLE
CALL &BCC8 ;;KL CHOKE OFF
CALL &BC02 ;;SCREEN RESET
CALL &BB03 ;;KM RESET
CALL &BCA7 ;;SOUND RESET
CALL &BB51 ;;TXT RESET
LD SP,&BFFE ;;reset stack pointer...I hope :-)
POP HL
JP (HL)


According to firmware guide, MC BOOT PROGRAM needs the address of the loading routine at HL, so after i reserve the addr into stack,i call all the init routines and then jump to loading address again. Unfortunately this doesn't seem to work right, it seems like i'm missing some things that have to be done, or i i'm not doing something right....

I've also tried to execute the RST 1 calls to routines, inside my code, and then repatch the routines i need:

RST 1,&85ED
CALL JUMPBLOCKS
RET

But unfortunately this ,didn't work too. It seems that  the patched routines are reinitialized inside BOOT PROGRAM, before any loading is actually done, so when loader routine kicks in ,it tries to load the file using the firmware loading routines= crash...
Perhaps if anyone knows the inners of these two routines in more detail could give us some hint


HAL6128

Eventually this might help in conjunction with the Firmware:
LD HL, address; to start the program
JP &BD16 ; instead of RST Call > this is the entre for the MC Start Programm over RST#8
?
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

ikonsgr

Well, the problem with MC BOOT PROGRAM is that, when it's called, HL registers does NOT have the execution address of the file to be executed, but rather the address of the assembly loader routine, that will load the actual file needed...
And unfortunately replacing MC BOOT PROGRAM with a simple jump to the loader routine address, doesn't seem to work right (although, in theory it should work, at least if anything else was initialized properly...)


Docent

Quote from: ikonsgr on 22:50, 30 January 19
Well, the problem with MC BOOT PROGRAM is that, when it's called, HL registers does NOT have the execution address of the file to be executed, but rather the address of the assembly loader routine, that will load the actual file needed...
And unfortunately replacing MC BOOT PROGRAM with a simple jump to the loader routine address, doesn't seem to work right (although, in theory it should work, at least if anything else was initialized properly...)
Use the second approach from my message above: patch both vectors, remembering their addresses first,  store hl, call original vectors with hl pointing to your routine. In your routine patch vectors again and jump into address of previously stored hl

ikonsgr

Very good trick, indeed, i use this code for the MCBOOTPROGRAM:

LD (&A924),HL  (temporary saving of loader address)
LD HL,&AA56  (this is the addr just after the RST 1 instruction)
RST 1,&85ED  (this is the initial instruction for MCBOOTPROGRAM)
CALL JUMPBLOCKS (this is &AA56)
LD HL,(&A924) (reload the correct loading address)
JP (HL)


But unfortunately still doesn't seem to work right.  After some study of the situation, i conclude that the loader routine itself  (the one called by MCBOOTPROGRAM), probably mess up with the address where my code is installed ,&A9B0-ABAF , these are 512 bytes normally used as loading buffer, usually contain the last sector loaded. Is this area often used by game loaders too?
Is there any other place you can suggest to put my code? Perhaps the 128 bytes  @ &A7E4 (normally used for buffering records sent/load from disc), although i would need a total of at least 250 bytes for all the modified loading routines and the jumpblocks.


Docent

Quote from: ikonsgr on 15:25, 06 February 19
Very good trick, indeed, i use this code for the MCBOOTPROGRAM:

LD (&A924),HL  (temporary saving of loader address)
LD HL,&AA56  (this is the addr just after the RST 1 instruction)
RST 1,&85ED  (this is the initial instruction for MCBOOTPROGRAM)
CALL JUMPBLOCKS (this is &AA56)
LD HL,(&A924) (reload the correct loading address)
JP (HL)


But unfortunately still doesn't seem to work right.  After some study of the situation, i conclude that the loader routine itself  (the one called by MCBOOTPROGRAM), probably mess up with the address where my code is installed ,&A9B0-ABAF , these are 512 bytes normally used as loading buffer, usually contain the last sector loaded. Is this area often used by game loaders too?
Is there any other place you can suggest to put my code? Perhaps the 128 bytes  @ &A7E4 (normally used for buffering records sent/load from disc), although i would need a total of at least 250 bytes for all the modified loading routines and the jumpblocks.
Use of the load buffer to store themselves is not the best idea for game loaders :)
They usually use temporary areas like screen or stack.
As for free areas (not counting smaller or various disk or basic buffers), you have:
- 80 bytes at &ABB0 (up to &abff)
- 58 bytes at &b0c7 (up to &b0ff)
- 64 bytes at &be00 (up to &be3f)
- 768 bytes at &be80 (up to &bfff), but the stack is setup to grow down from &bfff, so you can probably use max 100-200 bytes from this area or you risk overwriting your data.

I'd try to go with &be80 and see if it works.

ikonsgr

I've tried to move to &be80 but it didn't work either.
After initial loading my code (using a small Basic program that initally loads my code to RAM), i've found out that even a soft reset doesn't erase it, and so, giving a single CALL instruction that replaces the jumpblocks (these are reseted to their original state after reset) is all you need to do to be able to load again directly from serial port!
The problem is that for some mysterious reason, whenever i try to run a binary loader file, it corrupts my code, in whatever place i tried to put it!
The good news is that i finally manage to load correctly some games using a somewhat "indirect" way. Instead of giving directly run"gamename", i give:

Memory loadaddr-1
load"gamename"
call execaddr

I've already tried it with Eagle's nest, 1942, terramex and some others, and all loaded succesfully using this method! Also,i manage to run Cauldron 2 directly (e.g. using run"cauldron.bas") which uses  a small BASIC program that loads 3-4 separate files in different memory areas.
So it seems that if i use BASIC commands or the loader uses a BASIC program, everything works ok, but if a binary loader is used, it f@cks up my code!   :)
So, the question is, why this thing happens?  Is there any other Firmware routines  that a loader might call and potentailly destroy my code placed in some reserved area like &A9B0? Or is there some other code inside binary loaders that could also destroy my code?  ::)
Note also that i've also tried to "disable" KL ROM WALK,KL INIT BACK and MC JUMP RESTORE,  by giving a simple RET at their jumpblock addresses (in case some of these might damage cod or the modified jumpblocks too), but with no luck....

ikonsgr

FINALLY, for the 1st time i've managed to run some games with binary loaders!   :D
I used this code for MC BOOTPROGRAM and MC STARTPROGRAM:

;;MCBOOT PROGRAM
LD A,&E9
LD (&ABB2),A
LD (&ABB3),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&ABB3)
CALL &ABB2
JP (HL)

;;MC START PROGRAM
LD (&ABB0),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
LD HL,(&ABB0)
JP (HL)


The "trick" i used was,instead of direct jumping to (HL) address of the loading routine, i CALL the routine, using a jump (hl)=&e9 @ &ABB2 e.g. CALL &ABB2. The loading routine is supposed to return the execution address of the loaded program  at (HL), so a simple JP (HL) after the CALL should  cause the execution of the program.
I've tried this, with 15-20 games so far, and the results are:
- All binary files seemed to load succesfully from PC (previously, after initial run"file , no extra binary file was loaded  from PC, my code seemed corrupted and  i usually end up with a reset...)
- ~ half of the games are loaded and run succesfully, but unfortunately many games ,although the binary files was loaded correctly, they still seem to crash on execution.

I was wondering is there a chance that many games use custom loading routines instead of the firmware CAS IN OPEN,CAS IN DIRECT, CAS IN CLOSE?
And if yes, how exactly they do that? Is there a way to "talk" with 765 Floppy controller bypassing the firmware routines?




Docent

Quote from: ikonsgr on 15:27, 07 February 19
FINALLY, for the 1st time i've managed to run some games with binary loaders!   :D
I used this code for MC BOOTPROGRAM and MC STARTPROGRAM:

;;MCBOOT PROGRAM
LD A,&E9
LD (&ABB2),A
LD (&ABB3),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&ABB3)
CALL &ABB2
JP (HL)

;;MC START PROGRAM
LD (&ABB0),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
LD HL,(&ABB0)
JP (HL)


The "trick" i used was,instead of direct jumping to (HL) address of the loading routine, i CALL the routine, using a jump (hl)=&e9 @ &ABB2 e.g. CALL &ABB2. The loading routine is supposed to return the execution address of the loaded program  at (HL), so a simple JP (HL) after the CALL should  cause the execution of the program.
It is not a trick - You have just correctly emulated MC BOOT PROGRAM :)
I assumed that you knew the difference between them so didn't go into details how they operate...
Quote
I've tried this, with 15-20 games so far, and the results are:
- All binary files seemed to load succesfully from PC (previously, after initial run"file , no extra binary file was loaded  from PC, my code seemed corrupted and  i usually end up with a reset...)
- ~ half of the games are loaded and run succesfully, but unfortunately many games ,although the binary files was loaded correctly, they still seem to crash on execution.

I was wondering is there a chance that many games use custom loading routines instead of the firmware CAS IN OPEN,CAS IN DIRECT, CAS IN CLOSE?
And if yes, how exactly they do that? Is there a way to "talk" with 765 Floppy controller bypassing the firmware routines?
There are couple of methods, one is for example directly calling routines from amsdos rom.
Custom loading routines were used mainly by original games - most tape games used that approach. Some disk games used custom load or start through |cpm command, but then you will not see any files on disk.

You can probably assume that if a game has visible files on the disk it should load via standard firmware calls.   Of course there are always exceptions - some multiload games (like those transferred from tape) can have their ingame loaders done via direct calling amsdos rom routines or using floppy controller.
So if you have files on a disk and the game loads and starts correctly without your patch, it should work with the patch. If it doesn't work, there are chances that your code is overwritten by a loader that copies itself into the same space or you have found one that do not use system to load data.


ikonsgr

Yes, some games might indeed overwrite my code, and i'm afraid these  can't be run directly with this method....
BUT, i noticed that several games, although they doesn't seem to run directly by giving: run"game loader name", they run if i "manually" give the basic commands:

memory loadaddress-1
load"game name loader"
call execution address


So, does anyone knows what exactly the basic command :run" ,does, in case of a binary file? Obviously first, loads the file using the CAS firmware routines, but then what? it calls the execution address? it calls the MCSTARTPROGRAM @&BD16? it calls the MCBOOTPROGRAM @&BD13? Or maybe something else?..  ::) 

Docent

Quote from: ikonsgr on 20:05, 07 February 19
Yes, some games might indeed overwrite my code, and i'm afraid these  can't be run directly with this method....
You can try to minimize the code size and put it into other free space, but I don't think you'll get 100% success ratio. You'll get better results if you put your code into rom.
Quote
So, does anyone knows what exactly the basic command :run" ,does, in case of a binary file? Obviously first, loads the file using the CAS firmware routines, but then what? it calls the execution address? it calls the MCSTARTPROGRAM @&BD16? it calls the MCBOOTPROGRAM @&BD13? Or maybe something else?..  ::)
run goes through MC BOOT PROGRAM with pointer to loading routine in rom that uses &bc83 (CAS IN DIRECT). After successful load it jumps to start address from loaded file.

ikonsgr

Quote from: Docent on 21:00, 07 February 19
You can try to minimize the code size and put it into other free space, but I don't think you'll get 100% success ratio.
I've already tried alternative places, even by splitting code in two pieces, but unfortunately this didn't work either...

Quote from: Docent on 21:00, 07 February 19
You'll get better results if you put your code into rom.
Unfortunately this is not an option,at least not with the USIfAC (Universal Serial Interface for Amstrad CPC)

Quote from: Docent on 21:00, 07 February 19
run goes through MC BOOT PROGRAM with pointer to loading routine in rom that uses &bc83 (CAS IN DIRECT). After successful load it jumps to start address from loaded file.
Hmmm, i remember when i first got involved with this project, i managed to run a couple of these games using the RUN" command, when i "took over" loading and execution myself: everything was done using only a modified CAS IN OPEN code, i just loaded the file to ram, and then jump to execution address! This "brute" approach worked only for some games, but funny thing is, the new code has execution problems with EXACTLY these games! (besides the games that crashed because they seemed to overwrite my code...)
Most probable this "loading routine in rom " you mention, doesn't cooperate well with my code...   ::)
If there was a way to distinguish if the loaded file comes from a RUN" command, maybe i could use an alternative code to  load&execute these files myself, instead of leaving MCBOOTPROGRAM to screw it up!    :)

Docent

Quote from: ikonsgr on 23:36, 07 February 19
I've already tried alternative places, even by splitting code in two pieces, but unfortunately this didn't work either...
Unfortunately this is not an option,at least not with the USIfAC (Universal Serial Interface for Amstrad CPC)
Hmmm, i remember when i first got involved with this project, i managed to run a couple of these games using the RUN" command, when i "took over" loading and execution myself: everything was done using only a modified CAS IN OPEN code, i just loaded the file to ram, and then jump to execution address! This "brute" approach worked only for some games, but funny thing is, the new code has execution problems with EXACTLY these games! (besides the games that crashed because they seemed to overwrite my code...)
Most probable this "loading routine in rom " you mention, doesn't cooperate well with my code...   ::)
If there was a way to distinguish if the loaded file comes from a RUN" command, maybe i could use an alternative code to  load&execute these files myself, instead of leaving MCBOOTPROGRAM to screw it up!    :)
Cant help you with this without seeing the code and an example game that did not work as you expected. If you want post it somewhere or send a pm with dsk and I can have a look

ikonsgr

Ok, since you ask for it, here is the hole code:


Spoiler: ShowHide
LIMIT &FFFF
ORG &A9B0
;;NOLIST
write"DIRECT.BIN"

LD D,B

LD A,1
LD BC,&FBD1
OUT (C),A
LD A,D
LD BC,&FBD0
OUT (C),A

.LOOP_NAME
LD A,(HL)
LD BC,&FBD0
OUT (C),A
INC HL
DEC D
JR NZ,LOOP_NAME

;;RECEIVE HEADER


;;RECEIVE HEADER
LD B,69
LD DE,&A755
LD HL,&A7E4
.LOAD_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_HEADER
LD A,&FB
IN A,(&D0)
LD (DE),A
LD (HL),A
INC DE
INC HL
DEC B
JR NZ,LOAD_HEADER

LD B,59
.LOAD_FULL_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_FULL_HEADER
LD A,&FB
IN A,(&D0)
LD (HL),A
INC HL
DEC B
JR NZ,LOAD_FULL_HEADER

CALL BYTE_CHECK ;;FILESIZE TO DE (TEMP)
LD A,&FB
IN A,(&D0)
LD E,A

CALL BYTE_CHECK
LD A,&FB
IN A,(&D0)
LD D,A

LD (&A920),DE ;;A920=FILESIZE
PUSH DE

EX DE,HL   ;; HL=SIZE OF FILE

;;EXIT CONDITIONS FOR CAS IN OPEN
SCF
LD A,2
DEC A
LD HL,&A7E4 ;;LD HL,&A755
LD DE,(&A76A)
POP BC
LD A,(&A767)
RET

;;CAS IN DIRECT
LD DE,(&A920)
LD (&A924),HL
.LOAD_BYTE
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_BYTE
LD A,&FB
IN A,(&D0)
LD (HL),A  ;;2
INC HL
DEC DE
LD A,D
OR E
JR Z,THE_END

JP LOAD_BYTE  ;;22us

.THE_END

LD HL,(&A76F)
SCF
LD A,2
DEC A
RET

;;MCBOOT PROGRAM
LD A,&E9 ;;&E9 JP (HL)
LD (&A922),A
LD (&A923),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&A923)
CALL &A922
;;CALL &ABB2
LD (&A923),HL
;;LD HL,(&A76F)
JP (HL)


;;MC START PROGRAM
LD (&A926),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
;;CALL ROUTINE
LD HL,(&A926)
JP (HL)


.BYTE_CHECK
LD A,&FB
IN A,(&D1)
DEC A
JR Z,BYTE_CHECK
RET


;;JUMPBLOCKS!
.JUMPBLOCKS

LD HL,&BC77  ;;JP &A9B0 CAS IN OPEN
LD A,&C3
LD (HL),A
INC HL
LD A,&B0
LD (HL),A
INC HL
LD A,&A9
LD (HL),A

LD HL,&BC83  ;;JP &BC83 CAS IN DIRECT
LD A,&C3
LD (HL),A
INC HL
LD A,&1A
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC7A  ;;JP CAS IN CLOSE
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BD16  ;;RUN PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&59
LD (HL),A
INC HL
LD A,&AA
LD (HL),A

LD HL,&BD13  ;;JP BOOT PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&3E
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC8C  ;;CAS OUT OPEN
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BCCB  ;;KL ROM WALK rst 1,&8326
LD A,&C9
LD (HL),A


LD HL,&BCCE  ;;KL ROM WALK
LD A,&C9
LD (HL),A

LD HL,&BD37  ;;JUMP RESTORE
LD A,&C9
LD (HL),A
RET



And here i have two small videos, showing the difference behavior of the game 1943, when i try to load it using run"1943:
https://www.dropbox.com/s/sgv6vauvprko4kw/DSCN1163.AVI?dl=0
And here is when i use the memory loadaddr-1:load"1943":call execaddr method:
https://www.dropbox.com/s/bbo59k28nsfhq6t/DSCN1164.AVI?dl=0

In both cases, binary game file seemed to transferred succesfully from pc, but execution works only with 2nd method!
I have exactly the same problem with Eagle's nest game too.
Anyway, the good news is that i have managed to run succesfully games that use the method of:
openout"d";memory addr 
Which ,if i understand it correctly, it's a metohd that allows to load a program in "forbiden" addresses, like below &170 or beyond &A06C (this was always a mystery to me, because i saw it in many game loaders,but after openout nothing was actually written to the "d" file...). It seems that many games use this loading method, and until now, the "openout" BASIC instruction, caused reset, obviously due to the modified loading routines i'm using.
And then, suddenly "hits me"! Openout is essentially the CAS OUT OPEN firmware routine, which... i hadn't modified it! By replacing the original jumpblock of the CAS OUT OPEN with only a SCF (=set carry flag, to "fool" amstrad thinks that file was opened succesfully) and RET instructions, ALL games which use the: openout"d" method, run succesfully!  :)
Even Target renegade which uses openout"d" method, pokes some code, and loads many files at various addresses, is loaded and runned in ~8seconds!  :D


ikonsgr

UPDATE: I've checked dozens of games and ~75% seemed to run ok. This is a list of games that tested and run ok:

-1942
-1943
-cauldron 2
-Ghost'n' Goblins
-Target Renegade
-Solomon's key
-Thanatos
-Gryzor
-Stalone Cobra
-Robocop
-Ikari Warriors
-Shark
-Slyspy
-Rick Dangerous 2
-Billy2
-BubbleBobble2
-Silkworm
-Shinobi
-Switchblade
-Stryder
-Predator 2
-CYBERNOID 1&2
-Tank
-Uridium
-Wonder Boy
-Slug
-Titus The fox To Marakesh and Back
-Terramex
-Prehistoric
-Into the eagle's nest
-Xenon
-Pac-Mania
-Ghouls'n' ghosts

And this is alist of games that don't work:

-BabyJo
-Flimbo's Quest
-savage
-Double dragon 2&3
-Super Cauldron
-Terminator 2
-Super Cars
-Super Edge Grinder
-Twin World
-Titus the fox (***Program Load Failed***)
-Strider 2 (start ok, but then gives a message about rewind tape etc and the crashes...)

Golden Axe & UN squadron although they load ok, when they  try to load the 1st level they freeze,so maybe the files are damaged or has some kind of copy protection (i'm also hearing the tape relay that clicks so maybe i need to disable some other tape routines too...).
Some of the above nonworking games are crashing or reset,most probable because they overwrite my code, but there are some that give a "***Program LOAD failed***" message, so maybe i will be able to find a way to run these too in the future.

Anyway, it seems that even as it is, a considerable number of games can be load and run directly from PC.  Also all BASIC files and single binary files can be loaded directly too.
I suppose the interesting part, would be if this method works on a CPC 464 too, as it would be a rather cheap and easy solution for fast loading games and programs! ;-)  Unfortunately i don't have any CPC 464 to verify it....  ::)


Docent

Quote from: ikonsgr on 14:08, 09 February 19
Ok, since you ask for it, here is the hole code:


Spoiler: ShowHide
LIMIT &FFFF
ORG &A9B0
;;NOLIST
write"DIRECT.BIN"

LD D,B

LD A,1
LD BC,&FBD1
OUT (C),A
LD A,D
LD BC,&FBD0
OUT (C),A

.LOOP_NAME
LD A,(HL)
LD BC,&FBD0
OUT (C),A
INC HL
DEC D
JR NZ,LOOP_NAME

;;RECEIVE HEADER


;;RECEIVE HEADER
LD B,69
LD DE,&A755
LD HL,&A7E4
.LOAD_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_HEADER
LD A,&FB
IN A,(&D0)
LD (DE),A
LD (HL),A
INC DE
INC HL
DEC B
JR NZ,LOAD_HEADER

LD B,59
.LOAD_FULL_HEADER
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_FULL_HEADER
LD A,&FB
IN A,(&D0)
LD (HL),A
INC HL
DEC B
JR NZ,LOAD_FULL_HEADER

CALL BYTE_CHECK ;;FILESIZE TO DE (TEMP)
LD A,&FB
IN A,(&D0)
LD E,A

CALL BYTE_CHECK
LD A,&FB
IN A,(&D0)
LD D,A

LD (&A920),DE ;;A920=FILESIZE
PUSH DE

EX DE,HL   ;; HL=SIZE OF FILE

;;EXIT CONDITIONS FOR CAS IN OPEN
SCF
LD A,2
DEC A
LD HL,&A7E4 ;;LD HL,&A755
LD DE,(&A76A)
POP BC
LD A,(&A767)
RET

;;CAS IN DIRECT
LD DE,(&A920)
LD (&A924),HL
.LOAD_BYTE
LD A,&FB
IN A,(&D1) 
DEC A
JR Z,LOAD_BYTE
LD A,&FB
IN A,(&D0)
LD (HL),A  ;;2
INC HL
DEC DE
LD A,D
OR E
JR Z,THE_END

JP LOAD_BYTE  ;;22us

.THE_END

LD HL,(&A76F)
SCF
LD A,2
DEC A
RET

;;MCBOOT PROGRAM
LD A,&E9 ;;&E9 JP (HL)
LD (&A922),A
LD (&A923),HL
LD HL,&AA4C
RST 1,&85ED
CALL JUMPBLOCKS
LD HL,(&A923)
CALL &A922
;;CALL &ABB2
LD (&A923),HL
;;LD HL,(&A76F)
JP (HL)


;;MC START PROGRAM
LD (&A926),HL
LD HL,&AA62
RST 1,&861C
CALL JUMPBLOCKS
;;CALL ROUTINE
LD HL,(&A926)
JP (HL)


.BYTE_CHECK
LD A,&FB
IN A,(&D1)
DEC A
JR Z,BYTE_CHECK
RET


;;JUMPBLOCKS!
.JUMPBLOCKS

LD HL,&BC77  ;;JP &A9B0 CAS IN OPEN
LD A,&C3
LD (HL),A
INC HL
LD A,&B0
LD (HL),A
INC HL
LD A,&A9
LD (HL),A

LD HL,&BC83  ;;JP &BC83 CAS IN DIRECT
LD A,&C3
LD (HL),A
INC HL
LD A,&1A
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC7A  ;;JP CAS IN CLOSE
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BD16  ;;RUN PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&59
LD (HL),A
INC HL
LD A,&AA
LD (HL),A

LD HL,&BD13  ;;JP BOOT PROGRAM
LD A,&C3
LD (HL),A
INC HL
LD A,&3E
LD (HL),A
INC HL
LD A,&AA
LD (HL),A


LD HL,&BC8C  ;;CAS OUT OPEN
LD A,&37
LD (HL),A
INC HL
LD A,&C9
LD (HL),A


LD HL,&BCCB  ;;KL ROM WALK rst 1,&8326
LD A,&C9
LD (HL),A


LD HL,&BCCE  ;;KL ROM WALK
LD A,&C9
LD (HL),A

LD HL,&BD37  ;;JUMP RESTORE
LD A,&C9
LD (HL),A
RET


Anyway, the good news is that i have managed to run succesfully games that use the method of:
openout"d";memory addr 
Which ,if i understand it correctly, it's a metohd that allows to load a program in "forbiden" addresses, like below &170 or beyond &A06C (this was always a mystery to me, because i saw it in many game loaders,but after openout nothing was actually written to the "d" file...). It seems that many games use this loading method, and until now, the "openout" BASIC instruction, caused reset, obviously due to the modified loading routines i'm using.
openout is a sort of trick that allows you to load binaries from basic into very low addresses but the address cannot be lower that &170 ie below the address basic programs are stored.
Quote
And then, suddenly "hits me"! Openout is essentially the CAS OUT OPEN firmware routine, which... i hadn't modified it! By replacing the original jumpblock of the CAS OUT OPEN with only a SCF (=set carry flag, to "fool" amstrad thinks that file was opened succesfully) and RET instructions, ALL games which use the: openout"d" method, run succesfully!  :)
It runs, but it is just a hack and some programs that save files will not work. I think that openout overwrites your code in the disk buffer or some other problem happens.
Quote
Even Target renegade which uses openout"d" method, pokes some code, and loads many files at various addresses, is loaded and runned in ~8seconds!  :D

I have some free time today so I rewrote your code - now it is smaller, is easier to reassemble to another address and does more :)
- patches try to be more similar in functionality to routines in rom
- you should probably remove patching of cas open out as it shouldnt be modified this way
- header equ is the address of the header buffer - you can modify it to other suitable address
- try the #be80 org address - maybe it will work better

LIMIT &FFFF
header equ #ab80
ORG &A9B0
;org #be80
;;NOLIST
write"DIRECT.BIN"

start:
call patch_jumpblocks
ret

; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_data:
; hl - address
; de - count
call byte_check
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data
load_completed
ret

send_data:
; hl - address
; d - count
ld a, 1
ld bc, #FBD1
out (c), a
ld a, d
ld bc, #FBD0
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ret

; patched routines

cas_in_open:
; send file name
ld d, b
call send_data
; receive file header
ld hl, header
ld de, 128
call load_data
; receive filesize
ld hl, filesize
ld de, 2
call load_data
; setup return values
ld bc, (filesize)
ld hl, header
ld de, (header+#15)
ld a,  (header+#12)
scf
ret

cas_in_direct:
ld de,(filesize)
call load_data
ld hl,(header+26)
xor a
scf
ret

mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1,0
mc_boot_continue:
call patch_jumpblocks
mc_boot_start_addr:
ld hl, 0
call jumphl
jr c, mc_start_program
rst 0
jumphl:
jp (hl)

mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1,0
mc_start_continue:
call patch_jumpblocks
mc_start_start_addr:
ld hl, 0
call jumphl
rst 0

kl_init_back:
kl_init_back_patch:
rst 1,0
jr continue

kl_rom_walk:
kl_rom_walk_patch:
rst 1,0
jr continue

mc_jump_restore:
mc_jump_restore_patch:
rst 1,0
continue:
push hl
call patch_jumpblocks
pop hl
ret

cas_in_close:
cas_out_open:
scf
ret

patch_jumpblocks:
ld a, #c3 ; jump opcode

;patch cas in open

ld (#bc77), a
ld hl, cas_in_open
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch cas out open

ld (#bc8c), a
ld hl, cas_out_open
ld (#bc8d), hl

; patch mc boot program

ld hl, (#bd14)
ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl

; patch mc start program

ld hl, (#bd17)
ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl

; patch jump restore

ld hl, (#bd38)
ld (mc_jump_restore_patch+1), hl
ld (#bd37), a
ld hl, mc_jump_restore
ld (#bd38), hl

; patch kl rom walk

ld hl, (#bccc)
ld (kl_rom_walk_patch+1), hl
ld (#bccb), a
ld hl, kl_rom_walk
ld (#bccc), hl

; patch kl init back

ld hl, (#bccf)
ld (kl_init_back_patch+1), hl
ld (#bcce), a
ld hl, kl_init_back
ld (#bccf), hl
ret
filesize:
dw 0


Couldn't check if it actually runs, but feel free to find this out :)))


Docent

Quote from: ikonsgr on 18:58, 09 February 19
-Titus the fox (***Program Load Failed***)
-Strider 2 (start ok, but then gives a message about rewind tape etc and the crashes...)

Golden Axe & UN squadron although they load ok, when they  try to load the 1st level they freeze,so maybe the files are damaged or has some kind of copy protection (i'm also hearing the tape relay that clicks so maybe i need to disable some other tape routines too...).
Some of the above nonworking games are crashing or reset,most probable because they overwrite my code, but there are some that give a "***Program LOAD failed***" message, so maybe i will be able to find a way to run these too in the future.
"***Program LOAD failed***" is a message from MC BOOT PROGRAM when called loader returns wit carry clear. The version I modified and posted should work correctly with these titles.
Check out these games with the loader I posted - it should increase the success ratio :)
QuoteAnyway, it seems that even as it is, a considerable number of games can be load and run directly from PC.  Also all BASIC files and single binary files can be loaded directly too.
I suppose the interesting part, would be if this method works on a CPC 464 too, as it would be a rather cheap and easy solution for fast loading games and programs! ;-)  Unfortunately i don't have any CPC 464 to verify it....  ::)
It should work on cpc464, but you'll still need to load the program from tape :)

ikonsgr

Thank you very much for your interest and time Docent! I'll try your code and let you know of the results.
Btw, there is no need to have the code on tape or disk, i use  a very small  basic program  (5-6 lines in all,takes ~1 minute to write it) , that transfers the code  directly from PC to amstrad in 2 seconds,by just pressing a button on the pc program i developed, it's similar to the "cold start" function i already had! 
So, the only thing you actually need to have on tape or disk, is only this small basic program!  ;)



ikonsgr

Ok,i just have the first results.
Running the code as it is, was giving me "broken in" errors on loading Basic files, so after a  quick check ,i saw that you hadn't set zero flag for "cas in direct" and "cas in open" exit conditions (except setting carry flag, you also need to set zero flag too).  So after adding LD A,2 and DEC A (i haven't find any more elegant way to set zero flag  ::)), in exit conditions  of those two routines, and setting header to &A755, basic programs and  games that use BASIC loaders, were load and execute fine!
But, unfortunately  any game with binary loader didn't seem to work at all. I've tried 4-5 games (of those that executed fine using my code), and all crash or reset after initial loading . So, most probable something is wrong with the MCBOOT PROGRAM, MC START routines or the patches of them.
Btw, this is the small program i'm using to transfer the code to amstrad:

10 OUT &FBD1,0:OUT &FBD1,1
20 FOR I=0 TO 287 (this changes according to code size)
30 WHILE INP(&FBD1)=1:WEND   
40 POKE &A9B0+I,INP(&FBD0)   
50 NEXT i
100 CALL &A9B0 (enable jump block patches)

As you can see, it's so small that you can even write it "on the fly" without saving at all!
Also, in many game loading cases, code is not damaged and remains even after reset, so it can be used for loading next game by just giving the last call to enable jumpblock patches!  ;)

ikonsgr

Docent, having a look at your code, i noticed that instead of jump to HL after the return of loading routine in MC BOOT PROGRAM , you instead, jump to  MC START program routine.
I apply this modification to my code,and guess what, all the games that needed the method of :"memory loadaddr-1:load"":call &execaddr" (like terramex, eagle's nest, xenon) now they run normally using the run" command!
I have also manage to run 2-3 more games of the non working list, so what remains, is most probable games that overwrite my code, although some big games like UN SQUADRON and Golden AXE are initially loaded succesfully, but when they try to load the level file, they seem to stop. I'm also hearing the tape relay clicking,so maybe these were tape versions that converted to discs and thus having problems with my modified loading routines.
In any case, out of the 45 games tested, 33 were able to run succesfully, so now we are up to a hit ratio of ~75%!

Docent

Quote from: ikonsgr on 18:49, 10 February 19
Docent, having a look at your code, i noticed that instead of jump to HL after the return of loading routine in MC BOOT PROGRAM , you instead, jump to  MC START program routine.
I apply this modification to my code,and guess what, all the games that needed the method of :"memory loadaddr-1:load"":call &execaddr" (like terramex, eagle's nest, xenon) now they run normally using the run" command!
I have also manage to run 2-3 more games of the non working list, so what remains, is most probable games that overwrite my code, although some big games like UN SQUADRON and Golden AXE are initially loaded succesfully, but when they try to load the level file, they seem to stop. I'm also hearing the tape relay clicking,so maybe these were tape versions that converted to discs and thus having problems with my modified loading routines.
In any case, out of the 45 games tested, 33 were able to run succesfully, so now we are up to a hit ratio of ~75%!

Hi,
I had a look at my code and fixed a couple of bugs:
- I fixed return flags - now all routines return correct error codes/flags just like firmware functions
- removed cas out open patch - it is not needed, see explanation below
- added more tests for various conditions - stream opened, patches applied etc
- the cas in open patch did not have a test against missing file and didn't return proper error code - added one, it assumes that pc side will return zero file length if a filename isincorrect of missing

The reason why some of programs crashed (especially those with openout in the loader) is that you put the code into disk buffer area, which is used and initialized depending on operations. One of such operations is "openout" basic command. It initializes this buffer, overwriting the code inside the buffer. This is the reason why you needed the patch for cas out open. Btw: also other operations like "cat" will destroy the code in the buffer.
I moved all the patch code to #be80, patching routines to #ab80 and buffer to #a9b0 and added needed relocation. Now the cas out open patch is not needed anymore.

The code still requires testing as I don't have the hardware to test - please check this version out! It should run with most games now.


LIMIT &FFFF
header equ #a9b0
org #be80
; nolist
;write"DIRECT.BIN"

start:
ld hl, patch_end
ld de, patch_jumpblocks
ld bc, patch_jumpblocks_end-patch_jumpblocks
ldir
jp apply_patches

; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_data:
; hl - address
; de - count
call byte_check
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data
load_completed
ret

send_data:
; hl - address
; d - count
ld a, 1
ld bc, #FBD1
out (c), a
ld a, d
ld bc, #FBD0
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ret

; patched routines
; cas in open
cas_in_open:
; check if stream has been already opened
ld a, (stream_opened)
or a
jr nz, cas_in_open_error
; send file name
ld d, b
call send_data
; receive file header
ld hl, header
ld de, 128
call load_data
; receive filesize
ld hl, filesize
ld de, 2
call load_data
; check if filesize is 0 - if so, file doesnt exists
ld bc, (filesize)
ld a, b
or c
jr nz, file_exists
xor a
jr cas_error_return
file_exists:
; set return flags
xor a
inc a
scf
; mark stream as opened
ld (stream_opened), a
; setup return values
ld hl, header
ld de, (header+#15)
ld a,  (header+#12)
ret

; cas in close
cas_in_close:
; check if stream has been opened
ld a, (stream_opened)
or a
jr z, cas_error_return
; reset stream opened flag
xor a
ld (stream_opened), a
scf
ret

; cas in direct
cas_in_direct:
ld a, (stream_opened)
or a
jr z, cas_in_direct_error_return
ld de,(filesize)
call load_data
ld hl,(header+26)
; set return flags
xor a
inc a
scf
ret

cas_in_open_error:
xor a
cas_in_direct_error_return:
; setup zero flag
inc a
cas_error_return:
; error - stream was not opened
ld a, #e
ccf
ret

mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1,0
mc_boot_continue:
call apply_patches
mc_boot_start_addr:
ld hl, 0
push hl
call jumphl
pop hl
jr c, mc_start_program
rst 0
jumphl:
jp (hl)

mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1,0
mc_start_continue:
call apply_patches
mc_start_start_addr:
ld hl, 0
call jumphl
rst 0

kl_init_back:
kl_init_back_patch:
rst 1,0
jr apply_patches

kl_rom_walk:
kl_rom_walk_patch:
rst 1,0
jr apply_patches

mc_jump_restore:
mc_jump_restore_patch:
rst 1,0

apply_patches:
xor a
ld (patches_applied), a
jp patch_jumpblocks

stream_opened:
db 0
filesize:
dw 0
patch_end:

org #ab80

patch_jumpblocks:
ld a, (patches_applied)
or a
ret nz
ld a, #c3 ; jump opcode
push hl
;patch cas in open

ld (#bc77), a
ld hl, cas_in_open
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch mc boot program

ld hl, (#bd14)
ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl

; patch mc start program

ld hl, (#bd17)
ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl

; patch jump restore

ld hl, (#bd38)
ld (mc_jump_restore_patch+1), hl
ld (#bd37), a
ld hl, mc_jump_restore
ld (#bd38), hl

; patch kl rom walk

ld hl, (#bccc)
ld (kl_rom_walk_patch+1), hl
ld (#bccb), a
ld hl, kl_rom_walk
ld (#bccc), hl

; patch kl init back

ld hl, (#bccf)
ld (kl_init_back_patch+1), hl
ld (#bcce), a
ld hl, kl_init_back
ld (#bccf), hl

pop hl
ld a, 1
ld (patches_applied), a
ret
patches_applied:
db 0
patch_jumpblocks_end

Docent

Quote from: ikonsgr on 12:34, 10 February 19
Ok,i just have the first results.
Running the code as it is, was giving me "broken in" errors on loading Basic files, so after a  quick check ,i saw that you hadn't set zero flag for "cas in direct" and "cas in open" exit conditions (except setting carry flag, you also need to set zero flag too).  So after adding LD A,2 and DEC A (i haven't find any more elegant way to set zero flag  ::)), in exit conditions  of those two routines, and setting header to &A755, basic programs and  games that use BASIC loaders, were load and execute fine!
Yeah, I missed that - I fixed it in the latest code. I used a different code to set carry and clear zero

xor a
inc a
scf

Quote
But, unfortunately  any game with binary loader didn't seem to work at all. I've tried 4-5 games (of those that executed fine using my code), and all crash or reset after initial loading . So, most probable something is wrong with the MCBOOT PROGRAM, MC START routines or the patches of them.
Btw, this is the small program i'm using to transfer the code to amstrad:

10 OUT &FBD1,0:OUT &FBD1,1
20 FOR I=0 TO 287 (this changes according to code size)
30 WHILE INP(&FBD1)=1:WEND   
40 POKE &A9B0+I,INP(&FBD0)   
50 NEXT i
100 CALL &A9B0 (enable jump block patches)

As you can see, it's so small that you can even write it "on the fly" without saving at all!
Also, in many game loading cases, code is not damaged and remains even after reset, so it can be used for loading next game by just giving the last call to enable jumpblock patches!  ;)
Nice! unfortunately I don't have the hardware to connect to my cpc and test...
Btw: you could modify this to first receive file length as two bytes, then the start/loading address (2 bytes) and load them as variables for loop and start address for poke and a call. Then you'll not need to modify the basic code anymore :)

ikonsgr

Thanks again docent,i really appreciate your help on this!
Now a couple of thinks i also found out:

- KL ROM WALK (and probably KL ROM INIT and JUMP RESTORE too) destroy, not only the jumpblock patches, but also the actual code itself, so it's better to "disable" it by just returning back the call, after all it makes no difference in a stock Amstrad without any extra Roms.

- The method you are using for setting the addresses to the RST 1, instructions, doesn't seem to work right. I've managed to actually make it work only when i "hard coded" the address like in my code, for example RST 1,&85ED, after all these addresses are always "fixed" and unchanged so there is no need to use aliases for them.

- In MC BOOT PROGRAM patched routine ,i had to add an LD C,&FF (=disable roms and address to RAM) instruction ,just before calling the MC START PROGRAM, otherwise i got reset in some games.

- The first 69 bytes of header must be placed at &A755, otherwise programs doesn't seem to be loaded correctly.But since header is 128 bytes long, (and some games might use some of the extra unused header bytes to load data) ,i modify the header receive code in order to place the hole 128 bytes on &A7E4 and the 69 bytes at &A755.

So, using your code which is much more flexible, elegant and smaller, i apply the above modifications and  manage to get exactly the same results with my code!
And here is the modded code of yours that seemed to worked ok:

LIMIT &FFFF
header equ #a755
header_full equ #a7e4
ORG &A9B0
;org #be80
;;NOLIST
write"DIRECT.BIN"

start:
call patch_jumpblocks
ret

; data trasfer
byte_check:
ld a,#FB
in a,(#D1)
dec a
jr z, byte_check
ret

load_header:
; hl - address
; de - count
call byte_check
ld a ,#FB
in a,(#D0)
ld (hl), a
ld (bc), a
inc hl
inc bc
dec de
ld a,d
or e
jr z, load_completed2
jr load_header
load_completed2
ret

load_data:
; hl - address
; de - count
       .check_BYTE
        LD A,&FB
        iN A,(&D1) 
        DEC A
        JR Z,check_BYTE
ld a ,#FB
in a,(#D0)
ld (hl), a
inc hl
dec de
ld a,d
or e
jr z, load_completed
jr load_data
load_completed
ret

send_data:
; hl - address
; d - count
ld a, 1
ld bc, #FBD1
out (c), a
ld a, d
ld bc, #FBD0
out (c), a

send_data_loop:
ld a,(hl)
out (c), a
inc hl
dec d
jr nz, send_data_loop
ret

; patched routines

cas_in_open:
; send file name
ld d, b
call send_data
; receive file header
ld hl, header_full
        ld      bc, header
ld de, 69
call load_header
        ld de, 59
call load_data
; receive filesize
ld hl, filesize
ld de, 2
call load_data
; setup return values
        LD A,2
        DEC A
ld bc, (filesize)
ld hl, header_full
ld de, (header+#15)
ld a,  (header+#12)
scf
ret

cas_in_direct:
ld de,(filesize)
call load_data
ld hl,(header+26)
        LD A,2
        DEC A
scf
ret

mc_boot_program:
ld (mc_boot_start_addr+1), hl
ld hl, mc_boot_continue
mc_boot_patch:
rst 1,&85ED
mc_boot_continue:
call patch_jumpblocks
mc_boot_start_addr:
ld hl, 0
call jumphl
        LD C, &FF
jr c, mc_start_program
rst 0


mc_start_program:
ld (mc_start_start_addr+1), hl
ld hl, mc_start_continue
mc_start_patch:
rst 1,&861C
mc_start_continue:
call patch_jumpblocks
mc_start_start_addr:
ld hl, 0
call jumphl
rst 0

;kl_init_back:
;kl_init_back_patch:
; rst 1,&8330
; jr continue

;kl_rom_walk:
;kl_rom_walk_patch:
; rst 1,&8326
; jr continue

;mc_jump_restore:
;mc_jump_restore_patch:
; rst 1,&BD88
;continue:
; push hl
; call patch_jumpblocks
; pop hl
; ret

cas_in_close:
        scf
ret
cas_out_open:
scf
ret

patch_jumpblocks:
ld a, #c3 ; jump opcode

;patch cas in open

ld (#bc77), a
ld hl, cas_in_open
ld (#bc78), hl

; patch cas in direct

ld (#bc83), a
ld hl, cas_in_direct
ld (#bc84), hl

; patch cas in close

ld (#bc7a), a
ld hl, cas_in_close
ld (#bc7b), hl

; patch cas out open

ld (#bc8c), a
ld hl, cas_out_open
ld (#bc8d), hl

; patch mc boot program

; ld hl, (#bd14)
; ld (mc_boot_patch+1), hl
ld (#bd13), a
ld hl, mc_boot_program
ld (#bd14), hl

; patch mc start program

; ld hl, (#bd17)
; ld (mc_start_patch+1), hl
ld (#bd16), a
ld hl, mc_start_program
ld (#bd17), hl

LD HL,&BCCB  ;;KL ROM WALK rst 1,&8326
LD A,&C9
LD (HL),A


LD HL,&BCCE  ;;KL ROM WALK
LD A,&C9
LD (HL),A

LD HL,&BD37  ;;JUMP RESTORE
LD A,&C9
LD (HL),A

; patch jump restore

; ld hl, (#bd38)
; ld (mc_jump_restore_patch+1), hl
; ld (#bd37), a
; ld hl, mc_jump_restore
; ld (#bd38), hl

; patch kl rom walk

; ld hl, (#bccc)
; ld (kl_rom_walk_patch+1), hl
; ld (#bccb), a
; ld hl, kl_rom_walk
; ld (#bccc), hl

; patch kl init back

; ld hl, (#bccf)
; ld (kl_init_back_patch+1), hl
; ld (#bcce), a
; ld hl, kl_init_back
; ld (#bccf), hl
ret
jumphl:
jp (hl)

filesize:
dw 0


Now, about placing the code at the base of the stack &BE80, i'm afraid it will have much less chances to remain untouched than with the 512bytes of sector buffer. I've already tried to place my code @ &BE80 before, and i end up with crashes very often! It seems that stack region is much more used by games and programs than the sector buffer.
And since the code we are having is rather large, in the range of 200-300 bytes, i doubt it would survive many games... As for you concerns about the need to modify the CAS OUT OPEN routine in order to avoid erasing of code placed at sector buffer, i believe that the vast majority of amstrad games (~99% or more) are actually "Read only", they don't offer  any saving options , so most probable it will not matter after all....  :)

Powered by SMFPacks Menu Editor Mod