• ProDOS boot block?

    From Steve Nickolas@21:1/5 to All on Mon Dec 20 17:12:25 2021
    My head exploded when trying to parse the ProDOS boot block.

    I'm trying to see whether it's possible to remove the Apple /// stuff and
    add some 6502-8086 diglot stuff, given that I have an 8086 boot block that
    does more or less the same thing, and that I could stuff into the second
    block.

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From I am Rob@21:1/5 to All on Fri Dec 24 16:17:04 2021
    My head exploded when trying to parse the ProDOS boot block.

    And thus the reason no-one has replied. We are not willing to follow in your footsteps.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Nickolas@21:1/5 to I am Rob on Fri Dec 24 20:03:33 2021
    On Fri, 24 Dec 2021, I am Rob wrote:

    My head exploded when trying to parse the ProDOS boot block.

    And thus the reason no-one has replied. We are not willing to follow in your footsteps.


    We all know I'm a lunatic ;p

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From qkumba@21:1/5 to All on Sat Dec 25 15:04:31 2021
    ProBoot (part of Total Replay) parses the ProDOS file-system to find the named .SYS file to load and run.
    It has no Apple III support, only Apple II and compatible. The source is in the repo on GitHub. Maybe it's useful to you somehow.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Nickolas@21:1/5 to Kent Dickey on Sat Dec 25 19:00:18 2021
    On Sat, 25 Dec 2021, Kent Dickey wrote:

    In article <alpine.DEB.2.21.2112201707330.6571@sd-119843.dedibox.fr>,
    Steve Nickolas <usotsuki@buric.co> wrote:
    My head exploded when trying to parse the ProDOS boot block.

    I'm trying to see whether it's possible to remove the Apple /// stuff and
    add some 6502-8086 diglot stuff, given that I have an 8086 boot block that >> does more or less the same thing, and that I could stuff into the second
    block.

    -uso.

    I don't understand what you are asking. Are you trying to make a boot block that will work on 8086 and an Apple II? If so, you'll need to work out opcodes to start the block with that make sense for both architectures.
    I don't understand why you'd want to do this and what you think this will achieve. For the Apple II part, the first byte needs to be $01 and will
    not be executed. If you want it can be any value from $01 to $0f, but
    higher values will result in wasted time (it will read more sectors into memory which will in general not be useful).

    That indeed was the trick.

    As for the ProDOS boot block, it's basic operation is to find the PRODOS
    file in the volume directory, and boot from a 5.25" Disk II or a "Smartport" device (really, the ProDOS entry point). It looks at the boot slot
    $CnFF to get the ProDOS entry point (generally $07, so the entry point is $Cn07), and then makes READBLOCK calls to find PRODOS. For Disk II, it creates a fake driver (so the rest of the code can think in terms of blocks), which then does the needed head moves (slower than needed, but short code) and re-uses the $Cn5C entry point to read the sector data. It's clever,
    but not too complex.

    You mention Apple ///, but again I don't know what you mean. There's
    special code to handle $CnFF being >= $F9, and maybe that's for Apple ///, but I didn't trace through that code to figure out what it was doing.
    My understanding is an Apple /// will boot from Block 1 (and Block 1 is usually all 0's on volumes created on an Apple II).

    Kent

    I actually wrote this code:

    http://6.buric.co/p86head.a86.txt

    This is pretty close to what I understand the 6502 code does in principle,
    but written from scratch in 8086 ASM (NASM dialect) - and I have written a "hello world" test, though my head exploded trying to go further and
    actually write a kernel.

    I'm currently trying to write a small Apple ][ emulator in order to test
    the code further, but I am very unfluent in 8086 being mainly a C
    programmer.

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kent Dickey@21:1/5 to usotsuki@buric.co on Sat Dec 25 17:30:36 2021
    In article <alpine.DEB.2.21.2112201707330.6571@sd-119843.dedibox.fr>,
    Steve Nickolas <usotsuki@buric.co> wrote:
    My head exploded when trying to parse the ProDOS boot block.

    I'm trying to see whether it's possible to remove the Apple /// stuff and
    add some 6502-8086 diglot stuff, given that I have an 8086 boot block that >does more or less the same thing, and that I could stuff into the second >block.

    -uso.

    I don't understand what you are asking. Are you trying to make a boot block that will work on 8086 and an Apple II? If so, you'll need to work out
    opcodes to start the block with that make sense for both architectures.
    I don't understand why you'd want to do this and what you think this will achieve. For the Apple II part, the first byte needs to be $01 and will
    not be executed. If you want it can be any value from $01 to $0f, but
    higher values will result in wasted time (it will read more sectors into
    memory which will in general not be useful).

    As for the ProDOS boot block, it's basic operation is to find the PRODOS
    file in the volume directory, and boot from a 5.25" Disk II or a "Smartport" device (really, the ProDOS entry point). It looks at the boot slot
    $CnFF to get the ProDOS entry point (generally $07, so the entry point is $Cn07), and then makes READBLOCK calls to find PRODOS. For Disk II, it
    creates a fake driver (so the rest of the code can think in terms of blocks), which then does the needed head moves (slower than needed, but short code)
    and re-uses the $Cn5C entry point to read the sector data. It's clever,
    but not too complex.

    You mention Apple ///, but again I don't know what you mean. There's
    special code to handle $CnFF being >= $F9, and maybe that's for Apple ///,
    but I didn't trace through that code to figure out what it was doing.
    My understanding is an Apple /// will boot from Block 1 (and Block 1 is
    usually all 0's on volumes created on an Apple II).

    Kent

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From I am Rob@21:1/5 to All on Sat Dec 25 17:14:08 2021
    I'm currently trying to write a small Apple ][ emulator in order to test
    the code further, but I am very unfluent in 8086 being mainly a C
    programmer.

    Someone got the most part of an 8080 simulator working on a 6502 over here:

    http://forum.6502.org/viewtopic.php?f=2&t=6541

    See if the code listed can give you any ideas.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From qkumba@21:1/5 to All on Mon Dec 27 10:34:09 2021
    For the Apple II part, the first byte needs to be $01

    It can be zero. The PROM loops while the value in $3D is < $800.
    Then to make 6502/8086 compatible, the sequence can be
    00 CD EB xx

    which on 8086 is
    00 CD ADD CH,CL
    EB xx JMP SHORT [to x86-specific code]
    and on 6502
    00 ;1 sector read
    CD EB xx CMP $xxEB
    [6502 continues]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From qkumba@21:1/5 to All on Mon Dec 27 18:16:54 2021
    If you need to load two sectors, that's fine, too:
    02 CD ADD CL,CH

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From qkumba@21:1/5 to All on Mon Dec 27 18:17:09 2021
    If you need to load two sectors, that's fine, too:
    02 CD ADD CL,CH

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Nickolas@21:1/5 to qkumba on Tue Dec 28 00:06:50 2021
    On Mon, 27 Dec 2021, qkumba wrote:

    For the Apple II part, the first byte needs to be $01

    It can be zero. The PROM loops while the value in $3D is < $800.
    Then to make 6502/8086 compatible, the sequence can be
    00 CD EB xx

    which on 8086 is
    00 CD ADD CH,CL
    EB xx JMP SHORT [to x86-specific code]
    and on 6502
    00 ;1 sector read
    CD EB xx CMP $xxEB
    [6502 continues]

    Hm. So if I can plug in some x86 code that moves code out of the way to
    load the second block in place of the first at 0000:7C00, i.e.,

    retry: mov ax, 0x0201 ; read (AH) 1 (AL) sector
    mov cx, 0x0002 ; track 0 sector 2
    mov dh, 0x00 ; head 0 (DL unchanged from entry)
    xor bx, bx
    mov es, bx ; ES=$0000
    mov bx, 0x7C00
    int 0x13
    jc retry
    jmp 0x0000:0x7C00

    (just banged out in a hurry)

    it might be possible to make a diglot 6502-8086 bootloader. But I'd have
    to strip out the /// stuff to have enough free space for that. And it
    would probably require some better 8086 code than what I just wrote. But
    it's a start.

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Nickolas@21:1/5 to All on Tue Dec 28 03:11:55 2021
    Currently the most efficient x86-side code I can come up with is this:

    B8 01 02 B9 02 00 30 F6 31 DB 8E C3 BB 00 7C 26
    C7 06 FE 7B CD 13 EA 00 7C 00 00

    That's pretty much the same code I described before, except that once the registers are set I place an "int 13h" at 0000:7BFE and jump hard to it.
    (This 8086 code could probably be done even more efficiently.)

    Since I haven't yet RE'd the entire ProDOS bootloader - only as far as
    $096C, and that only basically - I'm not really sure what code might be
    safe to maneuver around without breaking things, other than the stuff that
    I was able to identify as being part of the SOS chainloader.

    Still, this seems to suggest that a 6502-8086 diglot bootloader is indeed possible. (It would only really be feasible on a 1.44 MB floppy though
    which is quite rare on the Apple ][ line!)

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From qkumba@21:1/5 to All on Tue Dec 28 09:28:06 2021
    You'd be running already from 0000:7C00 if you're on a PC. Your read will overwrite your existing code.
    Since all of the registers will have been set already for the first load, you could just
    mov ax, 0x201
    inc cx
    pushf
    push es
    push bx
    jmp far es:[0x004c]
    and forget about retry.
    Otherwise, yes it's possible to have a polyglot bootsector, even on a 5.25".
    As for the ProDOS loader, block 1 is "reserved" (=unused). You could put the original sector there. Then you wouldn't need to fit the actual loader in the boot sector.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Nickolas@21:1/5 to qkumba on Tue Dec 28 20:19:58 2021
    On Tue, 28 Dec 2021, qkumba wrote:

    You'd be running already from 0000:7C00 if you're on a PC. Your read
    will overwrite your existing code.

    Yeah, knew that.

    Since all of the registers will have been set already for the first
    load, you could just
    mov ax, 0x201
    inc cx
    pushf
    push es
    push bx
    jmp far es:[0x004c]
    and forget about retry.

    Hm. I was trying to think about how to emulate an INT by jumping (much
    like the very common on the Apple ][ method of "return to subroutine",
    which the ProDOS bootloader actually does use). I guess that's what I was looking for.

    0100- B8 01 02 MOV AX, 0201
    0103- 41 INC CX
    0104- 9C PUSHF
    0105- 06 PUSH ES
    0106- 53 PUSH BX
    0107- EA 4C 00 00 00 JMP 0000:004C

    12 bytes, eh? That's far more efficient than I'd come up with. xD

    Otherwise, yes it's possible to have a polyglot bootsector, even on a
    5.25".

    Of course most Apple ][ media wouldn't work on a PC and vice-versa - the
    1.44 MB floppy being the exception.

    As for the ProDOS loader, block 1 is "reserved" (=unused). You could
    put the original sector there. Then you wouldn't need to fit the actual loader in the boot sector.

    Yeah, that's what I was hoping to be able to do: literally the Apple ///
    trick, with a PC replacing the ///.

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From qkumba@21:1/5 to All on Wed Dec 29 10:11:51 2021
    0100- B8 01 02 MOV AX, 0201
    0103- 41 INC CX
    0104- 9C PUSHF
    0105- 06 PUSH ES
    0106- 53 PUSH BX
    0107- EA 4C 00 00 00 JMP 0000:004C

    12 bytes, eh? That's far more efficient than I'd come up with. xD

    The instruction at 0107 should read

    0107- 26 FF 26 4C 00 JMP FAR ES:[004C]

    It has to be indirect to use the vector.
    If you're willing to bet that DS is also zero, then you can drop the first 26.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Nickolas@21:1/5 to qkumba on Wed Dec 29 13:27:59 2021
    On Wed, 29 Dec 2021, qkumba wrote:

    0100- B8 01 02 MOV AX, 0201
    0103- 41 INC CX
    0104- 9C PUSHF
    0105- 06 PUSH ES
    0106- 53 PUSH BX
    0107- EA 4C 00 00 00 JMP 0000:004C

    12 bytes, eh? That's far more efficient than I'd come up with. xD

    The instruction at 0107 should read

    0107- 26 FF 26 4C 00 JMP FAR ES:[004C]

    It has to be indirect to use the vector.
    If you're willing to bet that DS is also zero, then you can drop the first 26.


    Didn't know you could use a segment override with JMP. o.o

    The 8086 is a lot more complicated than the 6502.

    (I'm also trying to write a 6502 core in 8086 asm but given that I don't
    even have a fully working 6502 core in C, it's probably a fool's errand.)

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)