From: Alan P. <ala...@gm...> - 2024-03-16 21:32:14
|
Replying to my own post in case anyone is listening. There are two questions that need answered to get disciple working on 128K: 1) Does the Disciple ROM get paged in when PC hits 0001 ? If so, this undoubtedly runs code that won't work when on 128K and ROM0 (128 editor) is in, and ends up calling a 48K ROM NEW routine. 2) Does the Disciple ROM get paged in on RESET ? Answers 1) I can conclusively say YES, the Disciple ROM gets paged in when PC hits 0001 - EXCEPT when machine is RESET. I've proven this two ways - (1) Recheck the PAL decoding - this is correct and there is no way it won't get paged in when address bus hits 0001 and (2) on a REAL 128K machine by running machine code which pages in EDITOR ROM and then JP to location 0. With Disciple not attached the machine initialises as expected back to the menu system. With the Disciple attached the machine crashes. With Disciple inhibited machine goes back to menu system as expected. This proves beyond a shadow of a doubt that the Disciple is paged in when PC=0001 2) The Disciple gets PAGED OUT on a RESET. The PAL equations prove this, and I've updated the doc with this correction. In RESET the Disciple never sees or reacts to PC=00001 as I'm guessing the reset line stays LOW longer than it takes the PC to advance past 0001, keeping the Disciple OUT via PAL logic. This is obviously a race condition and I've no reason to believe this would be different on a 48K machine. I also noticed FUSE puts the Disiple ROM at 0x2000 and RAM at 0x0000 which is incorrect - in normal operation ROM should be at 0x0000, and if the Disciple Boot Flip Flop flips them, then it means System needs reloaded, Described here by RAMSOFT: 3.1 DISCiPLE PORT 7Bh AND MEMORY ADDRESSES ========================================== Port 7Bh (123 decimal) is available only on the DISCiPLE and has a flip flop attached to it. It can be used to swap the RAM/ROM addresses in this way: Access ROM RAM Purpose IN 0x0000 0x2000 reset ff OUT 0x2000 0x0000 set ff This feature is used by GDOS to know if it necessary to load the system file from disk on boot or after two consecutive resets without any DOS command between them; UNIDOS ignores this feature, so any swap attempt will result in a system crash. In GDOS there is a variable located in RAM at offset 0x1DE4 that is set to 0x44 ('D') after a BASIC syntax check (i.e. after a RST 08h with a code lower than 1Bh) and after a bootstrap: this variable indicates that the DOS services have been called almost once. Whenever the user resets the computer, the flip flop attached to port 7Bh is reset, so the ROM will be placed at 0x0000. When the first interrupt occurs, the keyboard scanning routine is called at 0x028E and the DISCiPLE memory is automatically paged in. At offset 0x028E in the DISCiPLE's ROM there's a routine that checks if the variable we said above holds 0x44: if it's the case, then the same routine puts 00h in there to say that DOS services haven't been called since last reset; otherwise the routine sets the variable to 0x53 ('S') and copies the first 2335 (0x091F) bytes of ROM in the RAM: in this case the system file has to be loaded again. When all is finished, the memories will be swapped again (i.e. the flip flop will be set) by OUTing to port 7Bh, the DISCiPLE paged out by OUTing to port BBh and the keyscan routine is finally executed. INning from port 7Bh has the same meaning of a system reset for the DOS, so after reading 2 times from port 7Bh without typing a DOS command between them the system file needs to be reloaded. NOTE that since all this is based on the keyscan routine in the Spectrum's ROM, nothing will happen by INning from port 7Bh if the call is not performed (i.e. if interrupts are disabled in IM 1 or we're not in IM 1 or keyboard is scanned in a custom way); however the last operation with port 7Bh must be an OUT before the routine in the ROM is executed if you want to keep the system safe by resetting once. So to get this working under emulation in 128K mode, we need to do things: 1) Not page the disciple in when it hits location 0001 (easiest not to do it in any circumstances) 2) Change the ROM to be located at 0x0000 and observe the function of the flip flop as described above. I’ve updated the Disciple pals document and it should be available here shortly : https://spectrumcomputing.co.uk/entry/1000117/Hardware/DISCiPLE_Interface Anyone out there who can make this happen in FUSE ? > On 5 Mar 2024, at 23:01, Alan Pearson <ala...@gm...> wrote: > > Hi All, > > > I'm the guy wrote 'The Disciple PALs finally unveiled' and I found this thread discussing the issue on WoS by accident while trying to figure out why the disciple isn't working on FUSE in 128K mode. > https://worldofspectrum.org/forums/discussion/42567/the-disciple-clone-doable/p1 > What an interesting thread , and i was shocked to see my doc referenced. > I haven’t been able to create an account on WoS to reply there, it seems the admin may have gone on holiday or something…. so I came here. > > First, the document: > 1) This was a direct reverse engineer of working PAL chips, put on a logic analyser by Rudy Biesma, then turned into the equations manually by myself then jedec files created. > 2) All the findings & equations seem to correspond to known info about the disciple (manual, Ramsoft guide and Rudy's disassembly) > 3) The proof however was in real world testing - I repaired a broken disciple by programming the PAL chips with the jedec files created and it works perfectly on a 128k +2 (grey). > 4) There is a typo... N1 should be M1 throughout the doc, but I think you guys worked that out already > > Now, from my reading of the WoS thread and the Rudy disassembly, it seems there is no way the disciple should work on a 128K (at least no way it should initialise)... but it does. > The code path just doesn't make sense on a 128K machine at reset time. > > Let's change tact - the PlusD uses EXACTLY the same initialisation code, lands in the same place in the ROM when it unpages itself at reset (location #52) and makes no attempt (on reset at least) to figure out if it's a 1128K or 48K or 128k spectrum or which spectrum rom is in. > How does the plusD then work under FUSE ? It's very weird. > It's worth saying that the PlusD does have routines specific to 128K paging/unpaging but they are only used when the COPY command finishes and the machine resets after completion. > The PlusD TO_NEW routine essentially jumps to location #C7 on a 128k (reset routine in the editor ROM) or #11B7 in 48K. > Relevant routines below, but as I said they are NOT called when the system resets. > > From Rudy's +D disassembly : > > THE 'UNPAGE 128 ROM' SUBROUTINE > This routine pages out the +D system and returns to the 128K ROM at address #0049. That > address contains a RET instruction so the effect is a jump to BC with the 128K ROM paged > in. > > 0046 UNPAGE_BC PUSH BC Stack return address. > 0047 UNPAGE_0 OUT (231),A Page out +D system. > 0049 RET ? This statement is not reached from > above. > 004A DEFB #00,#00,#00,#00,#00 Unused locations. > > THE 'NEW' PATCH > When the file copy command is finished the +D jumps to the 'NEW' routine. With System 2a > a selection is made for 48K or 128K 'NEW' > > 3137 TO_NEW BIT 4,(IY+1) Jump if not in 128K mode HL contains > 313B JP Z,#004F,UNPAGE_HL #11B7, the address of 48K 'NEW'. > 313E CALL #5B00,SWAP Call the paging subroutine of the 128. > 3141 DI > 3142 LD BC,#00C7 Address of 128 'NEW' routine. > 3145 JP #0046,UNPAGE_BC > > > > Regarding the PALs, I suspect the equations are right, and the fact the code exists in both the +d and Disciple to initialise them suggests that it should be used, so I don't think this is a problem of paging in the interfaces at the wrong time. That said, I can't see how it all should work on a 128, but it does. So this can't be a disciple specific problem, can we trace the +D codepath in FUSE in 128K mode?? I'm not sure how to do this myself. > > > It would be great to see Disciple working in 128K models... there are difference between the interfaces that I've run into in converting a program to load from disc (specifically the interface 1 hook code #32, which does a RET on the disciple, but on the PlusD allows any ROM addresss to be called via DE register) > > I know this is a horrible kludge, but can we not monitor location #52 on both inrwefaces and if we have a 128K ROM paged in, simply jump to #00C7 after the OUT instruction ? > > > > Any thoughts ? > > Alan |