From c4b1070329f1734fa6ce71ce47266315cbbfa00f Mon Sep 17 00:00:00 2001 From: mgcaret Date: Thu, 12 Jan 2017 19:40:55 -0800 Subject: [PATCH] Simplify bootable ramdisk detection. Jump to AppleSoft if no boot device. I discovered that there are more than one ProDOS boot block in the wild, so I simplified the check for recoverable RAM disk to check card for $01 and then anything besides $00 and $FF since most uninitialized RAM tends to have one of those two values. This is slightly more rigid than the boot code checks for. I added a jump to AppleSoft if no bootable device is found. I changed the message a little bit, too. I also added notes about the feasibility of using the RamFactor firmware. --- notes/ramfactor.txt | 70 ++++++++++++++++++++++++++++++++++ rom4x/B0_C552_patch_bootfail.s | 18 +++++++++ rom4x/B1_E000_rom4x.s | 14 +++---- rom4x/B1_E300_new_bootfail.s | 19 +++++++++ rom4x/iic.defs | 8 ++++ 5 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 notes/ramfactor.txt create mode 100644 rom4x/B0_C552_patch_bootfail.s create mode 100644 rom4x/B1_E300_new_bootfail.s diff --git a/notes/ramfactor.txt b/notes/ramfactor.txt new file mode 100644 index 0000000..bda5892 --- /dev/null +++ b/notes/ramfactor.txt @@ -0,0 +1,70 @@ +A potential possibility is to replace Apple Slinky firmware with the RamFactor firmware. + +The ROM of the RamFactor is 8K in size, but that is not how much we'd need in the IIc. + +The layout of the ROM is two banks of 4K, selected by the low bit of $C08F+slot*$10. + +Each bank is laid out as follows, with the base at $C000 +$C000-$C0FF: Copyright message and fill, not visible in-system. +$C100-$C7FF: Slot firmware, $100 bytes for each slot, same code in both banks + This represents the same code assembled for each slot. + Only the slot the card is in is visible. +$C800-$CFFF: 2K of shared firmware space firmware, different for each bank. + +So as we see, without any modifications we need approximately 4K+256 bytes of space to +accomodate the RamFactor code. It is likely we will need to do some bank switching which +tends to add code, but also make some optimizations or drop features, which will remove +code. + +There is definitely enough space in the //c firmware for it. Especially if we can drop +the original slinky code, which uses $C400-$C4FF, $C752-$C762 (bank switch, both banks), +and $D800-$DB58 (eff. $DBFF). $C763-$C7FF is already used by ROM 4X. + +Features that might be droppable: More than 1MB memory support. + +Steps needed: + +Produce commented RF source that assembles to a binary match for the latest firmware (1.4). + +Port to Apple //c: + - The main issue is that we don't have the ability to run RF code at $C800. + - Bank switch code will need to be in the C400 space, but in the alt bank that + has the //c diagnostics, which will either need to be modified or we will have to + use less efficient bank switching (RTS trick). We can optimize the RTS trick in this + scenario by having an entry point table all on the same page. If we waste a few bytes + in the alt firmware bank we can do something like: +entry: ; expect x = function code + lda table_hibyte + pha + txa + asl + asl ; mult by 4 + pha ; "return addr" now a multiple of 4 in jump table + jmp swrts ; switch bank and go + - If the RF code calls any monitor routines we may need to supply them outright + or provide for a bank-switched call. + - We are likely going to need a "cross-bank JSR". + - Caller: Push callee address-1 on stack and JSR to xb_jsr + - xb_jsr: change banks, stack has: SP->caller callee + rework stack so that we have the following return entries + SP->callee swrts caller + sta $ ; into screen holes + stx $ + tsx ; SP->caller callee, x->caller callee + lda $103,x ; callee high + pha ; SP->callee[h] caller callee + lda $102,x ; callee low + pha ; SP->callee caller callee + lda $101,x ; caller high + sta $103,x ; SP->callee caller callee[l]+caller[h] + lda $100,x ; caller low + sta $102,x ; SP->callee caller caller + lda #swrts_hi-1 + sta $101,x + lda #swrts_lo-1 + sta $100,x ; SP->callee swrts caller + lda $ ; from screen holes + ldx $ + rts ; pops callee, callee rts pops swrts, swrts pops caller + ; above code is ~44 bytes + diff --git a/rom4x/B0_C552_patch_bootfail.s b/rom4x/B0_C552_patch_bootfail.s new file mode 100644 index 0000000..5b63898 --- /dev/null +++ b/rom4x/B0_C552_patch_bootfail.s @@ -0,0 +1,18 @@ +#include "iic.defs" + +.text +* = $c552 + jsr setnorm + jsr init + bra cbtfail + .dsb coma-*,$ea + bra coma ; Make sure coma routine exists + .db 0 ; rom4x present +cbtfail jsr setvid + jsr setkbd + lda #>(nbtfail-1) + pha + lda #<(nbtfail-1) + pha + jmp swrts2 + diff --git a/rom4x/B1_E000_rom4x.s b/rom4x/B1_E000_rom4x.s index 0df8bdb..f3b9734 100644 --- a/rom4x/B1_E000_rom4x.s +++ b/rom4x/B1_E000_rom4x.s @@ -161,15 +161,13 @@ rdrecov jsr rdinit ; init ramcard stz addrl,x ; set slinky address 0 stz addrm,x stz addrh,x - lda data,x ; start compare to ProDOS boot block + lda data,x ; start check for bootable ramdisk cmp #$01 - bne recovdn ; not ProDOS - lda data,x - cmp #$38 - bne recovdn ; not ProDOS - lda data,x - cmp #$b0 - bne recovdn ; not ProDOS + bne recovdn ; not bootable + lda data,x ; next byte should be nonzero and not $ff + beq recovdn ; not bootable + cmp #$ff + beq recovdn ; not bootable lda #pwrbyte sta pwrup,y ; set power byte lda "R" ; tell user diff --git a/rom4x/B1_E300_new_bootfail.s b/rom4x/B1_E300_new_bootfail.s new file mode 100644 index 0000000..a10bed2 --- /dev/null +++ b/rom4x/B1_E300_new_bootfail.s @@ -0,0 +1,19 @@ +#include "iic.defs" +.text +* = nbtfail + ldx #msglen +lp1 lda bootmsg,x + ora #$80 + sta $7d0+19-msglen/2,x + dex + bpl lp1 + lda #23 ; last line + sta cv + lda #>(basic-1) + pha + lda #<(basic-1) + pha + jmp swrts2 +bootmsg .db "No bootable device." +msglen = * - bootmsg - 1 + diff --git a/rom4x/iic.defs b/rom4x/iic.defs index e2f4c54..cb1ac88 100644 --- a/rom4x/iic.defs +++ b/rom4x/iic.defs @@ -30,6 +30,7 @@ sl_devno = $778 ; locations softev = $3f2 pwerdup = $3f4 +cv = $25 ; values pwrbyte = $a5 @@ -46,8 +47,15 @@ rst4xrtn = $facb ; where to return from reset4x bt4xrtn = $fb19 ; where to return from boot4x reset4x = $e000 ; reset routine boot4x = $e180 ; boot routine +nbtfail = $e300 ; new boot fail banner = $fb60 ; 'Apple //c' testsize = $d99f ; test ramdisk size (rom 3 = $d995) monitor = $ff59 ; monitor swrts2 = $c784 ; switch firmware and rts +basic = $e000 ; BASIC cold start entry point +coma = $c55d ; location of coma routine +setnorm = $fe84 ; normal video +init = $fb2f ; init screen +setvid = $fe93 ; init output +setkbd = $fe89 ; init input