mirror of
https://github.com/mgcaret/rom4x.git
synced 2024-12-21 11:29:55 +00:00
ROM5X preliminary code
This commit is contained in:
parent
cda85678ee
commit
adeb5e6b04
25
notes/mig_notes.txt
Normal file
25
notes/mig_notes.txt
Normal file
@ -0,0 +1,25 @@
|
||||
MIG space references in ROM:
|
||||
CE00-CE1F - MIG RAM window
|
||||
CE20 - Increment page
|
||||
CE3D-CE3E - ?
|
||||
CE40 - write in E4D9,E503,E612,EF02
|
||||
read in 8E9C,E9A3,E9EB,EA15,EA2D,EA40,EE87,
|
||||
always around slot 6 I/O accesses.
|
||||
CE60 - read in routine at E4C7,E8C5,E974,EA6B,EE95
|
||||
write in routine at E4F2,E612,E652,EF02,EFC6,F54C
|
||||
always around slot 6 I/O accesses.
|
||||
CEA0 - Reset page 0
|
||||
CECD - ? from data
|
||||
CED5 - ? from data
|
||||
CF9A - ? from bank switch @C746 prob calling main bannk
|
||||
CFCF - ? from data
|
||||
CFFF - leftover from non //c ROM
|
||||
|
||||
MIG page usage:
|
||||
Page 0 - 3.5 ROM - routines at CA12, E51D
|
||||
CE11 - slot I/O offset of ? (ldy CE11, lda C000,y in routine at CA12)
|
||||
Page 1 - used by routines at CA71,E54F,E534
|
||||
Page 2 - Appears used only by accelerator code
|
||||
Page 3 - used by routines at CA4B, CA71, E1E1, EB8B, ECCF
|
||||
Page 4+ - used all over the place
|
||||
|
27
notes/rom5_zeros.txt
Normal file
27
notes/rom5_zeros.txt
Normal file
@ -0,0 +1,27 @@
|
||||
Inventory of zeros of 5 bytes or more in the IIc Plus ROM
|
||||
|
||||
Main Bank
|
||||
C1FB - 5 bytes
|
||||
C4EE - 12 bytes
|
||||
C5F3 - 5 bytes
|
||||
C6FB - 5 bytes
|
||||
C9A1 - 9 bytes
|
||||
CFF9 - 7 bytes
|
||||
Alt Bank
|
||||
C572 - 8 bytes
|
||||
C7FB - 8 bytes
|
||||
C7FC - 7 bytes
|
||||
CE00 - 512 bytes not usable (MIG space)
|
||||
D134 - 76 bytes
|
||||
D516 - 234 bytes
|
||||
D6CE - 306 bytes
|
||||
DB63 - 157 bytes
|
||||
DE00 - 512 bytes maybe not usable (second mig space?), none of the firmware
|
||||
touches it.
|
||||
F72D - 16 bytes not usable (some kind of data table)
|
||||
F7ED - 19 bytes
|
||||
FB3C - 196 bytes
|
||||
FC3C - 12 bytes
|
||||
FCC9 - 55 bytes
|
||||
FE96 - 352 bytes, but reserve 65816 vectors
|
||||
|
8
rom5x/B0_CFF9_switch_cmd.s
Normal file
8
rom5x/B0_CFF9_switch_cmd.s
Normal file
@ -0,0 +1,8 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = $cff9 ; 7 bytes available here
|
||||
lda #$a9 ; lda opcode
|
||||
nop ; jmp/jsr $cffa does lda #$ea
|
||||
jmp $fbdf ; jump to bell1 hijack
|
||||
; total 6 bytes.
|
||||
|
7
rom5x/B0_FAB4_patch_pwrup.s
Normal file
7
rom5x/B0_FAB4_patch_pwrup.s
Normal file
@ -0,0 +1,7 @@
|
||||
; patch PWRUP to call boot5x
|
||||
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = $fab4
|
||||
nop
|
||||
jmp gobt5x
|
7
rom5x/B0_FAC8_patch_reset.s
Normal file
7
rom5x/B0_FAC8_patch_reset.s
Normal file
@ -0,0 +1,7 @@
|
||||
; patch RESET.X to call reset5x
|
||||
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = $fac8
|
||||
jmp gorst5x
|
||||
|
4
rom5x/B0_FBDF_bell1_hijack.s
Normal file
4
rom5x/B0_FBDF_bell1_hijack.s
Normal file
@ -0,0 +1,4 @@
|
||||
.text
|
||||
* = $fbdf
|
||||
sta $c028
|
||||
|
@ -1,5 +0,0 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = $fcde
|
||||
sta rombank
|
||||
|
@ -1,39 +0,0 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = rom5x
|
||||
asl butn1 ; check option key
|
||||
bcc rd5x ; not pressed, see if RD recoverable
|
||||
lda #"O" ; flashing "O"
|
||||
sta $7d0 ; tell user
|
||||
exit5x lda #>(r5xrtn-1)
|
||||
pha
|
||||
lda #<(r5xrtn-1)
|
||||
pha
|
||||
ldy #$00 ; in case someone assumes this later
|
||||
jmp swrts2
|
||||
rd5x jsr rdinit ; init ram card and registers
|
||||
lda pwrup,y ; get power up flag
|
||||
cmp #pwrbyte ; already initialized?
|
||||
beq exit5x ; exit if so
|
||||
jsr testsize ; does not wreck x or y
|
||||
lda numbanks,y ; get discovered # banks
|
||||
beq exit5x ; no memory
|
||||
stz addrl,x ; set slinky address 0
|
||||
stz addrm,x
|
||||
stz addrh,x
|
||||
lda data,x ; get first byte
|
||||
cmp #$01 ; boot block?
|
||||
bne exit5x ; nope
|
||||
lda data,x ; next byte
|
||||
beq exit5x ; not bootable if 0
|
||||
cmp #$ff ; other likely byte for fresh RAM
|
||||
beq exit5x ; not bootable if $ff
|
||||
lda #pwrbyte ; sta pwrup,y
|
||||
lda #"R" ; tell user
|
||||
sta $7d0 ; on screen
|
||||
bra exit5x
|
||||
rdinit bit rx_mslot*$100 ; activate registers
|
||||
ldy #rx_mslot ; slot offset
|
||||
ldy #rx_devno ; register offset
|
||||
rts
|
||||
|
112
rom5x/B1_D516_boot5x.s
Normal file
112
rom5x/B1_D516_boot5x.s
Normal file
@ -0,0 +1,112 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = boot5x ; 234 bytes available, code assembles to 231 when
|
||||
; next line uncommented
|
||||
; jsr ntitle ; TODO "Apple IIc +"
|
||||
jsr rdrecov ; try to recover ramdisk
|
||||
lda power2 + rx_mslot ; get action saved by reset5x
|
||||
beq boot4 ; if zero, continue boot
|
||||
jsr bann5x ; display ROM 5X footer
|
||||
lda power2 + rx_mslot ; boot selection
|
||||
btc2 cmp #$02 ; clear ramcard
|
||||
bne btc3
|
||||
jsr rdclear ; do clear
|
||||
bra boot4
|
||||
btc3 cmp #$03 ; Diags
|
||||
bne btc4
|
||||
jmp $c7c4
|
||||
btc4 cmp #$04 ; RX diags
|
||||
bne btc5
|
||||
ldx #$ff
|
||||
txs ; reset stack
|
||||
jsr rdinit ; get x and y loaded
|
||||
stx sl_devno ; diags need this
|
||||
jsr testsize ; compute card size
|
||||
lda #>(monitor-1) ; load "return" address
|
||||
pha ; into stack so that we
|
||||
lda #<(monitor-1) ; exit card test into
|
||||
pha ; the monitor
|
||||
lda numbanks,y ; get the card size in banks
|
||||
bne dordiag ; do diag if memory present
|
||||
jmp swrts2 ; otherwise jump to monitor
|
||||
dordiag jmp $db3a ; diags
|
||||
btc5 cmp #$05 ; boot smartport
|
||||
beq boot5
|
||||
; fall through if none of the above
|
||||
boot4 lda #rx_mslot ; boot slot 4
|
||||
bra bootsl
|
||||
boot5 lda #$c5 ; boot slot 5
|
||||
bra bootsl
|
||||
boot6 lda #$c6 ; boot slot 6
|
||||
bootsl ldx #$00 ; low byte of slot
|
||||
bootadr stx $0 ; store address
|
||||
sta $1 ; return to bank 0 does jmp (0)
|
||||
endbt4x lda #>(bt5xrtn-1)
|
||||
pha
|
||||
lda #<(bt5xrtn-1)
|
||||
pha
|
||||
lda $1
|
||||
jmp swrts2
|
||||
rdrecov jsr rdinit ; init ramcard
|
||||
lda pwrup,y ; get power up flag
|
||||
cmp #pwrbyte ; already initialized?
|
||||
beq recovdn ; exit if initialized
|
||||
jsr testsize ; does not wreck x or y
|
||||
lda numbanks,y ; get discovered # banks
|
||||
beq recovdn ; no mem
|
||||
stz addrl,x ; set slinky address 0
|
||||
stz addrm,x
|
||||
stz addrh,x
|
||||
lda data,x ; start check for bootable ramdisk
|
||||
cmp #$01
|
||||
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
|
||||
sta $7d0 ; on screen
|
||||
recovdn rts
|
||||
; zero ram card space
|
||||
rdclear jsr rdinit ; init ramcard
|
||||
jsr testsize ; get size
|
||||
lda numbanks,y ; # of 64Ks to write
|
||||
beq clrdone ; no memory
|
||||
lda #$c0 ; 'A' - 1
|
||||
sta $400 ; upper left corner
|
||||
stz addrl,x ; slinky address 0
|
||||
stz addrm,x
|
||||
stz addrh,x
|
||||
clbnklp inc $400 ; poor mans progress meter
|
||||
ldy #$00
|
||||
cl64klp ldx #$00 ; loop for all pages in bank
|
||||
cl256lp txa ; loop for all bytes in page
|
||||
ldx #rx_devno
|
||||
stz data,x ; write a zero to card
|
||||
tax
|
||||
dex
|
||||
bne cl256lp ; 256 byte loop
|
||||
dey
|
||||
bne cl64klp ; 64K loop
|
||||
ldx #rx_mslot
|
||||
dec numbanks,x
|
||||
bne clbnklp ; if more banks
|
||||
clrdone ldx #rx_mslot
|
||||
stz pwrup,x ; zero powerup byte
|
||||
lda #$a0 ; ' '
|
||||
sta $400 ; clear progress
|
||||
rts
|
||||
rdinit bit rx_mslot*$100 ; activate registers
|
||||
ldy #rx_mslot ; slot offset
|
||||
ldx #rx_devno ; register offset
|
||||
rts
|
||||
; next is snippet of code to boot external 5.25
|
||||
bootext lda #$e0
|
||||
ldy #$01
|
||||
ldx #$60
|
||||
jmp $c60b
|
||||
bt4xend = *
|
||||
|
||||
|
90
rom5x/B1_D6CE_rom5x_misc.s
Normal file
90
rom5x/B1_D6CE_rom5x_misc.s
Normal file
@ -0,0 +1,90 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = misc5x ; max 306 bytes
|
||||
bra domenu
|
||||
bra dobann
|
||||
bra gtkey
|
||||
bra confirm
|
||||
dobann jsr ntitle
|
||||
ldx #(msg2-msg1) ; msg display entry point
|
||||
jmp disp
|
||||
domenu jsr ntitle ; "Apple ||c +"
|
||||
ldx #$00 ; menu start
|
||||
jsr disp ; show it
|
||||
rts
|
||||
gtkey lda #$60
|
||||
sta ($0),y ; cursor
|
||||
sta kbdstrb ; clr keyboard
|
||||
kbdin lda kbd ; get key
|
||||
bpl kbdin
|
||||
sta kbdstrb ; clear keyboard
|
||||
sta ($0),y ; put it on screen
|
||||
rts
|
||||
; display message, input x = message start relative to msg1
|
||||
disp stz $0 ; load some safe defaults
|
||||
lda #$40
|
||||
sta $1
|
||||
ldy #$0 ; needs to be zero
|
||||
disp0 lda msg1,x ; get message byte
|
||||
bne disp1 ; proceed if nonzero
|
||||
rts ; exit if 0
|
||||
disp1 inx ; next byte either way
|
||||
cmp #$20 ; ' '
|
||||
bcc disp2 ; start of ptr if < 20
|
||||
eor #$80 ; invert high bit
|
||||
sta ($0),y ; write to mem
|
||||
inc $0 ; inc address low byte
|
||||
bra disp0 ; back to the beginning
|
||||
disp2 sta $1 ; write address high
|
||||
lda msg1,x ; get it
|
||||
sta $0 ; write address low
|
||||
inx ; set next msg byte
|
||||
bra disp0 ; back to the beginning
|
||||
confirm pha
|
||||
ldx #(msg3-msg1) ; ask confirm
|
||||
jsr disp
|
||||
jsr gtkey
|
||||
plx
|
||||
ora #$20 ; to lower
|
||||
cmp #$f9 ; "y"
|
||||
php
|
||||
txa
|
||||
plp
|
||||
rts
|
||||
; display "Apple IIc +" in a convoluted manner
|
||||
; ultimately, the rts instruction here "rts" to swrts2
|
||||
; which switches banks and "rts" to the title/banner firmware call
|
||||
; which then "rts" to swrts (same addr as swrts2, but main bank)
|
||||
; which then actually rts to our caller
|
||||
ntitle lda #>(swrts2-1) ; put return addr of swrts2 on stack
|
||||
pha
|
||||
lda #<(swrts2-1)
|
||||
pha
|
||||
lda #>(banner-1)
|
||||
pha
|
||||
lda #<(banner-1)
|
||||
pha
|
||||
lda #>(swrts2-1)
|
||||
pha
|
||||
lda #<(swrts2-1)
|
||||
pha
|
||||
rts ; jump to swrts2
|
||||
; msg format
|
||||
; A byte < $20 indicates high byte of address.
|
||||
; Next byte must be low byte of address. Anything
|
||||
; else are characters to display and will have their
|
||||
; upper bit inverted before being written to the screen.
|
||||
msg1 = *
|
||||
.db $05,$06,"0 Monitor"
|
||||
.db $05,$86,"1 Reboot"
|
||||
.db $06,$06,"2 Zero RAM Card"
|
||||
.db $06,$86,"3 Sys Diags"
|
||||
.db $07,$06,"4 RAM Card Diags"
|
||||
.db $07,$86,"5 Boot 3.5/SmartPort"
|
||||
.db $04,$2e,"6 Boot 5.25"
|
||||
; .db $04,$ae,"7 Accelerator"
|
||||
.db $07,$5f,"By M.G."
|
||||
msg2 .db $07,$db,"ROM 5X 02/08/17"
|
||||
.db $05,$ae,$00 ; cursor pos in menu
|
||||
msg3 .db $05,$b0,"SURE? ",$00
|
||||
|
42
rom5x/B1_DB63_reset5x.s
Normal file
42
rom5x/B1_DB63_reset5x.s
Normal file
@ -0,0 +1,42 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = reset5x ; max 157 bytes
|
||||
stz power2 + rx_mslot ; action = normal reset
|
||||
lda #>(rst5xrtn-1) ; common case
|
||||
pha
|
||||
lda #<(rst5xrtn-1)
|
||||
pha ; note that this stays on stack
|
||||
asl butn1 ; closed apple
|
||||
bcs ckdiag
|
||||
exitrst jmp swrts2
|
||||
; check to see if both apples are down
|
||||
ckdiag bit butn0 ; open apple
|
||||
bmi exitrst ; return to RESET.X
|
||||
; present menu because only closed apple is down
|
||||
menu jsr menu5x ; display menu
|
||||
jsr gkey5x
|
||||
cmp #$b0 ; "0"
|
||||
bne ckkey1
|
||||
ldx #$ff ; reset stack
|
||||
txs
|
||||
lda #>(monitor-1) ; monitor entry on stack
|
||||
pha
|
||||
lda #<(monitor-1)
|
||||
pha
|
||||
jmp swrts2 ; rts to enter monitor
|
||||
ckkey1 cmp #$b2 ; "2"
|
||||
beq doconf
|
||||
cmp #$b4 ; "4"
|
||||
bne ckkey2
|
||||
doconf jsr conf5x
|
||||
bne menu ; go back to menu4x
|
||||
ckkey2 sec
|
||||
sbc #$b0 ; ascii->number
|
||||
bmi menu ; < 0 not valid
|
||||
cmp #$08 ; we will use 7 for accelerator later
|
||||
bpl menu ; > 7 not valid
|
||||
sta power2 + rx_mslot ; for boot5x
|
||||
stz softev + 1 ; deinit coldstart
|
||||
stz pwerdup ; ditto
|
||||
bra exitrst
|
||||
|
17
rom5x/B1_FBE2_rom5x_dispatch.s
Normal file
17
rom5x/B1_FBE2_rom5x_dispatch.s
Normal file
@ -0,0 +1,17 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = $fbe2 ; ~29 bytes free here
|
||||
cmp #$a9 ; reset patch
|
||||
bne chk2
|
||||
jmp reset5x
|
||||
chk2: cmp #$ea ; boot patch
|
||||
bne dowait
|
||||
jmp boot5x
|
||||
dowait: jsr $fcb5 ; do delay if anything else
|
||||
lda #>($fbe2-1)
|
||||
pha
|
||||
lda #<($fbe2-1)
|
||||
pha
|
||||
lda #$00 ; in case someone assumes this
|
||||
jmp swrts2
|
||||
; 28 bytes, will have to move if we get bigger
|
@ -1,6 +0,0 @@
|
||||
#include "iic+.defs"
|
||||
.text
|
||||
* = $fce1
|
||||
sta set80col ; instruction we patched over
|
||||
jmp rom5x
|
||||
|
@ -1,18 +1,26 @@
|
||||
# ROM 5X by MG
|
||||
|
||||
## DO NOT EVEN TRY THIS YET :-)
|
||||
## PRELIMINARY, DO NOT EVEN TRY THIS YET :-)
|
||||
|
||||
**Warning:** This has not been tested on an emulator or a real Apple IIc Plus.
|
||||
|
||||
This is a patch for the Apple IIc Plus firmware that tries to recover a battery-backed
|
||||
RAM disk upon cold start. Because of the limited space in the Apple IIc ROM. it does not
|
||||
have the complete feature set of ROM 4X for the (non-Plus) //c.
|
||||
This is ROM4X revised to the Apple IIc Plus ROM version 5.
|
||||
|
||||
Upon cold start, the patch checks for a potentially bootable RAM disk and restores the
|
||||
appropriate screen holes to prevent it from being destroyed and to enable boot. If a
|
||||
RAMdisk is recovered, a flashing "R" will appear in the lower left corner of the screen.
|
||||
There are almost no free bytes in the main bank of the IIc Plus firmware, so
|
||||
I had to get creative to get into the alternate bank, where I then had to split
|
||||
the code up across multiple smaller free spaces. Ironically this makes the
|
||||
code larger as well.
|
||||
|
||||
For those interested, I hijack the monitor BEEP1 routine. The beep routine has
|
||||
an LDA #$40 and then calls WAIT with this value for a .1 second delay,
|
||||
presumably so that multiple beeps are distinct from each other.
|
||||
|
||||
I patch the JSR WAIT to be STA $C028, which switches to the other bank.
|
||||
The code in the other bank checks the accumulator and for two values calls
|
||||
either reset5x or boot5x, and for any other value executes the WAIT (assuming
|
||||
that we got there from BEEP1).
|
||||
|
||||
Then, in only 6 bytes I can create two entry points that load the value into
|
||||
A that we need for the reset or boot routines, and then jump to the above patch.
|
||||
|
||||
To prevent the check and recovery, power on the machine with the Option key held down.
|
||||
A flashing "O" will appear in the lower left corner of the screen and the system will
|
||||
boot without checking for or recovering any RAM disk.
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
; hardware
|
||||
set80col = $c001
|
||||
;set80col = $c001
|
||||
rombank = $c028
|
||||
butn0 = $c061
|
||||
butn1 = $c062
|
||||
kbd = $c000
|
||||
kbdstrb = $c010
|
||||
addrl = $bff8
|
||||
addrm = $bff9
|
||||
addrh = $bffa
|
||||
@ -20,8 +22,13 @@ sl_scrn7 = $778 - $c0
|
||||
sl_scrn8 = $7f8 - $c0
|
||||
numbanks = sl_scrn1
|
||||
pwrup = sl_scrn7
|
||||
power2 = sl_scrn8
|
||||
sl_devno = $778
|
||||
|
||||
; locations
|
||||
softev = $3f2
|
||||
pwerdup = $3f4
|
||||
|
||||
; values
|
||||
pwrbyte = $a5
|
||||
rx_slot = $4
|
||||
@ -29,8 +36,35 @@ rx_mslot = rx_slot + $c0
|
||||
rx_devno = rx_slot * $10 + $88
|
||||
|
||||
; entry points
|
||||
r5xrtn = $fce1
|
||||
rom5x = $cf00
|
||||
gorst5x = $cff9
|
||||
gobt5x = $cffa
|
||||
rst5xrtn = $facb
|
||||
bt5xrtn = $fb19
|
||||
reset5x = $db63
|
||||
boot5x = $d516
|
||||
testsize = $d99f
|
||||
swrts2 = $c784
|
||||
monitor = $ff59
|
||||
misc5x = $d6ce
|
||||
menu5x = misc5x
|
||||
bann5x = menu5x+2
|
||||
gkey5x = bann5x+2
|
||||
conf5x = gkey5x+2
|
||||
banner = $fb60
|
||||
|
||||
; macros
|
||||
#define psa(addr) \
|
||||
lda #>(addr-1) \
|
||||
pha \
|
||||
lda #<(addr-1) \
|
||||
pha \
|
||||
jsr swrts2
|
||||
|
||||
#define rtj(addr) \
|
||||
psa(addr) \
|
||||
rts
|
||||
|
||||
#define rtl(addr) \
|
||||
psa(addr) \
|
||||
jmp swrts2
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user