4X: create README.md specifically for 4X, add experimental config file support

This commit is contained in:
mgcaret 2017-04-25 20:10:02 -07:00
parent ce5f476f64
commit fdbb458ec6
5 changed files with 560 additions and 201 deletions

View File

@ -1,216 +1,342 @@
.psc02
.code
.include "iic.defs"
.org reset4x
stz power2 + rx_mslot ; action = normal boot
asl butn1 ; closed apple
bcs ckdiag
exitrst: jmp gorst4x ; return to RESET.X
.org reset4x
stz power2 + rx_mslot ; action = normal boot
asl butn1 ; closed apple
bcs ckdiag
exitrst: jmp gorst4x ; return to RESET.X
; check to see if both apples are down
ckdiag: bit butn0 ; open apple
bmi exitrst ; return to RESET.X
ckdiag: bit butn0 ; open apple
bmi exitrst ; return to RESET.X
; present menu because only closed apple is down
menu4x: jsr gobanner ; "Apple //c"
ldx #$00 ; menu start
jsr disp ; show it
jsr gtkey
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 confirm
bne menu4x ; go back to menu4x
ckkey2: sec
sbc #$b0 ; ascii->number
bmi menu4x ; < 0 not valid
cmp #$08
bpl menu4x ; > 7 not valid
sta power2 + rx_mslot ; for boot4x
stz softev + 1 ; deinit coldstart
stz pwerdup ; ditto
bra exitrst
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
menu4x: jsr gobanner ; "Apple //c"
ldx #$00 ; menu start
jsr disp ; show it
jsr gtkey
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 confirm
bne menu4x ; go back to menu4x
ckkey2: sec
sbc #$b0 ; ascii->number
bmi menu4x ; < 0 not valid
cmp #$08
bpl menu4x ; > 7 not valid
sta power2 + rx_mslot ; for boot4x
stz softev + 1 ; deinit coldstart
stz pwerdup ; ditto
bra exitrst
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 #$04
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
disp: stz $0 ; load some safe defaults
lda #$04
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
; 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 = *
.byte $05,$06,"0 Monitor"
.byte $05,$86,"1 Reboot"
.byte $06,$06,"2 Zero RAM Card and Reboot"
.byte $06,$86,"3 Diagnostics"
.byte $07,$06,"4 RAM Card Diagnostics"
.byte $07,$86,"5 Boot SmartPort"
.byte $04,$2e,"6 Boot Int. 5.25"
.byte $04,$ae,"7 Boot Ext. 5.25"
.byte $07,$5f,"By M.G."
msg2: .byte $07,$db,"ROM 4X 04/08/17"
.byte $05,$ae,$00 ; cursor pos in menu
msg3: .byte $05,$b0,"SURE? ",$00
.res boot4x - *, 0
.org boot4x
jsr gobanner ; "Apple //c"
jsr rdrecov ; try to recover ramdisk
lda power2 + rx_mslot ; get action saved by reset4x
beq boot4 ; if zero, continue boot
ldx #(msg2-msg1) ; short banner offset
jsr disp ; display it
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
;bra boot4
btc5: cmp #$05 ; boot smartport
beq boot5
btc6: cmp #$06 ; boot int drive
beq boot6
btc7: cmp #$07 ; boot ext drive
bne boot4 ; none of the above
; copy small routine to $800 to boot
; external 5.25
ldy #(bt4xend-bootext+1)
btc7lp: lda bootext,y
sta $800,y
dey
bpl btc7lp
lda #$08 ; copy done
bra bootsl
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: jmp gobt4x ; continue boot
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
.byte $05,$06,"0 Monitor"
.byte $05,$86,"1 Reboot"
.byte $06,$06,"2 Zero RAM Card and Reboot"
.byte $06,$86,"3 Diagnostics"
.byte $07,$06,"4 RAM Card Diagnostics"
.byte $07,$86,"5 Boot SmartPort"
.byte $04,$2e,"6 Boot Int. 5.25"
.byte $04,$ae,"7 Boot Ext. 5.25"
.byte $07,$5f,"By M.G."
msg2: .byte $07,$db,"ROM 4X 04/08/17"
.byte $05,$ae,$00 ; cursor pos in menu
msg3: .byte $05,$b0,"SURE? ",$00
.res boot4x - *, 0
.org boot4x
jsr gobanner ; "Apple //c"
jsr rdrecov ; try to recover ramdisk
lda power2 + rx_mslot ; get action saved by reset4x
beq :+
pha ; save it
bra selboot ; set, go do it
: lda numbanks,y ; (y should be OK here) ram card present?
beq boot6 ; nope, boot slot 6
jsr getcfg ; try to get config
bcs boot4 ; no config, normal boot
;stx $7d2
;sty $7d3
phx ; config present, move on
lda #'C' ; tell user
sta $7d1 ; on screen
selboot: ldx #(msg2-msg1) ; short banner offset
jsr disp ; display it
pla ; boot selection
sta $7d2
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
;bra boot4
btc5: cmp #$05 ; boot smartport
beq boot5
btc6: cmp #$06 ; boot int drive
beq boot6
btc7: cmp #$07 ; boot ext drive
bne boot4 ; none of the above
; copy small routine to $800 to boot
; external 5.25
ldy #(bt4xend-bootext+1)
btc7lp: lda bootext,y
sta $800,y
dey
bpl btc7lp
lda #$08 ; copy done
bra bootsl
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: jmp gobt4x ; continue boot
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
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
bootext: lda #$e0
ldy #$01 ; unit #
ldx #$60 ; slot #
jmp $c60b ; jump into Disk II code
bt4xend = *
; --------------------------------------------------
; config getter
; values and locs
;chktype = $5a ; 'CFG'
chktype = $06 ; 'BIN' - easy to set auxtype with bsave
entbuf = $0280
; zp locs, safe to use under our circumstances
blkptrl = $06
blkptrh = blkptrl + 1
entryl = $08
nentries = $09
.proc getcfg
jsr rdinit
lda #$02 ; first block of volume directory
sta blkptrl
stz blkptrh
jsr setblk
lda #$03 ; want this to EOR out to $00
ldy #$04 ; check 4 bytes
: eor data,x ; check previous blk ptr for zero
dey
bne :-
cmp #$00 ; see if A is 0
bne nocfg ; not vol dir key block, end of mission
lda #$04 ; where we expect to find volume dir header
sta addrl,x ; set data ptr
lda data,x ; volume directory header first byte
and #$f0 ; mask off length
cmp #$f0 ; storage type is $f?
bne nocfg ; nope, eom
lda #$23 ; offset of directory entry length in block
sta addrl,x
lda data,x ; grab entry length
sta entryl ; save it
ldy data,x ; entries per block
sty nentries ; save it for later
bra nxtbl1 ; skip setting slinky block and nentries, already there
nxtblk: jsr setblk
beq nocfg ; just set block 0, eom
ldy nentries ; restore # entries per block+1 into y
nxtbl1: jsr gnxtblk ; set next block pointer, leave data ptr at offset $04
nxtent: dey ; next entry, assumes y has # of entries remaining to check
bmi nxtblk ; next block if we dont have any more (hope we don't have more than $7F of them)
jsr rentry ; read directory entry
; now check storage type and name length
lda entbuf
and #$f0
beq nxtent ; if storage type = $0
and #$c0 ; mask out values $1-$3 (normal files)
bne nxtent ; if any other bits set
lda entbuf+$10 ; get type
cmp #chktype ; and check
bne nxtent ; no match, try next entry
lda entbuf ; get storage type and length
and #$0f ; mask in length
cmp #(fname_-fname) ; check length
bne nxtent
phy ; save num entries
tay ; a still has length
mtchlp: lda entbuf,y ; get file name char
cmp fname-1,y ; compare to what we are looking for
bne nomtch ; if no match
dey
bne mtchlp ; check next char
; we have a match
ply ; discard saved num entries
ldx entbuf+$1f ; low byte of aux type
ldy entbuf+$20 ; high byte of aux type
clc
rts
nomtch: ply ; restore saved num entries
bra nxtent
; no config found
nocfg: sec
rts
fname: .byte "BOOTX"
fname_ = *
.endproc
; get next block pointer into blkptrl and blkptrh
.proc gnxtblk
lda #$02 ; assumes we are in first half of block
sta addrl,x ; set byte offset
lda data,x ; next block low byte
sta blkptrl
lda data,x ; next block high byte
sta blkptrh
rts
.endproc
; set slinky address to block pointer, address = blk num * 2 * $100
.proc setblk
stz addrl,x ; zero low byte of slinky address
lda blkptrl ; low byte of block pointer
; sta $7e0
asl ; shift left, high bit to c
sta addrm,x ; put into middle byte of slinky address
lda blkptrh ; get high byte of block pointer
; sta $7e1
rol ; rotate left, c into bit 0
sta addrh,x ; set high byte of slinky address
ora addrm,x ; set z flag if we just set block 0
rts
.endproc
; read a ProDOS directory entry from slinky
.proc rentry
phy ; preserve y
ldy #$00
: lda data,x
sta entbuf,y
iny
cpy entryl
bne :-
ply
rts
.endproc

233
rom4x/README.md Normal file
View File

@ -0,0 +1,233 @@
# ROM 4X by MG
ROM 4X is a collection of enhancements to the Apple //c version 4. See the top level [README.md](../README.md) for more general information on ROM 4X and ROM 5X.
It adds the following features to the Apple //c and IIc Plus firmware:
- Identifies and reinstates a *bootable* (it must have something that looks like a boot block!) RAM disk from battery-backed expansion memory (see below), such as the [RAM Express II+](http://a2heaven.com/webshop/index.php?rt=product/product&product_id=144) from A2Heaven.
- Provides a menu of various tools upon pressing Ctrl+Closed-Apple+Reset (or holding Closed-Apple when powering up), that let you:
- Enter the monitor unconditionally.
- Reboot the machine (enter standard boot sequence).
- Zero the RAM card, in case it is corrupted.
- Execute the machine and RAM card diagnostics.
- Tell the machine to boot the SmartPort, the internal floppy drive, or an external floppy drive.
- *New as of 04/25/2017*: By saving a file on the RAM card, control the way the system boots by default.
- The system drops to BASIC if no bootable device is found (this is the default behavior in the IIc Plus).
# User Guide
## Installation
### Real System
Assuming you already have it burned onto a chip (I use SST27SF512s flash chips which hold 64K and Atmel 27C256, which hold 32K, and program with a TL866), generally the instructions [here](http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Computers/Apple%20II/Apple%20IIc/Manuals/Apple%20IIc%20v4%20ROM%20Upgrade%20Installation.pdf) are relevant. You won't need to cut any traces or solder a jumper unless, you are installing this ROM in an original //c. I don't recommend installing it on a non-memory expansion //c unless you have expansion memory that looks like the 'slinky' memory of the later models. ROM 4X/5X doesn't know about RAMWorks-style expansions.
Cards known to work with ROM 4X include the Apple Memory Expansion Card (but no battery!), and the A2Heaven [RAM Express II](http://a2heaven.com/webshop/index.php?rt=product/product&product_id=146) for the original //c, and the [RAM Express II+](http://a2heaven.com/webshop/index.php?rt=product/product&product_id=144) for the memory-expandable //c and IIc Plus.
### Emulator
#### //c
Copy the ROM into the appropriate location for your emulator. At the time of writing the only emulator I am aware of that can emulate the //c with memory expansion is [Catakig](http://catakig.sourceforge.net/) for MacOS. It's a bit older of an emulator but it runs fine on newer MacOSes.
MAME's Apple //c emulation may work, but I have not tried it.
## Operation
### Menu
Power on your machine. Everything should look and work *almost* like it did before. If there is a bootable device somewhere, the machine will boot it. If there is not (and this is one of the noticable changes), you will get dropped to BASIC without the need to press ctrl+reset. If things don't go well, revisit your installation.
If you don't have an initialized RAM disk, format the card RAM disk with something like Copy II Plus. Put ProDOS and BASIC.SYSTEM on it. Power off the machine, and power it on after a few minutes. You should boot off of the RAM disk. You might notice an "R" flash on the screen for an instant before ProDOS loads.
Now, press Control+Closed-Apple+Reset, holding down Closed-Apple after releasing reset. You should see the following menu appear (on a //c, IIc Plus menu is more compact to save firmware space):
```
0 Monitor
1 Reboot
2 Zero RAM Card and Reboot
3 Diagnostics
4 RAM Card Diagnostics
5 Boot SmartPort
6 Boot Int. 5.25
7 Boot Ext. 5.25
```
Picking any of the menu options besides 0 results in the menu being cleared, but the bottom line 'ROM 4X mm/dd/yy' immediately reappears to confirm that the new code is taking action.
What each option does is detailed below. Note that the various device boot options will try that device and any remaining devices in the boot order, which for the Apple //c is RAM card, 5.25 drive, and finally SmartPort.
#### 0 Monitor
This drops you unconditionally into the monitor.
#### 1 Reboot
This carries out the normal boot sequence, which is to try the RAM disk first, then the internal 5.25 floppy drive, then the first connected smartport device. Some of the other options let you skip over one or more of this ordering.
#### 2 Zero RAM Card and Reboot
This zeros out the RAM card memory and the screen holes. This is a nuclear option if the RAM disk is corrupt and the system fails to boot. After selecting 2 the word "SURE?" appears on the screen. At this point you must type `Y` or `y` to continue with the zeroing, or any other key to cancel.
If there is no card RAM, you are immediately rebooted. Otherwise an 'A' will appear in the upper left corner of the screen and will follow the alphabet as each 64K of the card is cleared. After it completes the letter will disappear and the machine will try booting.
#### 3 Diagnostics
This jumps to the //c internal diagnostics that are also run when you press control+both-apples+reset.
#### 4 RAM Card Diagnostics
This runs the RAM card diagnostics. When the diagnostics are finished either by user cancel or error, you are dropped into the monitor.
Since the test may damage data on the card, you are asked to confirm as per option 2 above.
#### 5 Boot SmartPort
This attempts to boot the first smartport device, such as a UniDisk 3.5.
#### 6 Boot Internal 5.25
This skips the RAM disk and starts booting with the internal 5.25 drive.
#### 7 Boot External 5.25
This is like option 6, but using an external 5.25 drive. The only OS I am aware of that supports booting this way is ProDOS.
This destructively copies a short routine to $800, which under most circumstances is also immediately overwritten by the boot sector, so should not be a problem..
### Configuration File
**EXPERIMENTAL**
If the RAM card is ProDOS-formatted, you can save a binary file in the volume directory called `BOOTX`. ROM 4X will find this file and use the Aux Type field (the load address) to set a default of the menu options above when no option has been selected using the menu. For example, `BSAVE /RAM4/BOOTX,A6,L0` will cause ROM 4X to skip booting the RAM card and go straight to booting the internal floppy drive (menu item 6). The contents of `BOOTX` are irrelevant, only the Aux Type is used. You cannot set it to jump into the monitor because that action happens before the boot code takes over.
You will know the configuration file is being used because the ROM 4X line will appear on the bottom of the screen and a flashing 'C' will appear in the lower-left corner.
**WARNING**: You *can* set the `BOOTX` file to clear the RAM card or run the RAM card diagnostics. This will happen exactly once and your RAM disk will be gone. *Caveat emptor*.
# Build/Develop Guide
## Build
To build the new firmware, you must start with a copy of the repository, and obtain a copy of the Apple //c version 4 ROM. The patches to the firmware work with the ROM dump that has sha256sum:
```
8ad5e6c4ed15d09b62183965b6c04762610d4b26510afc1896bdb4ecc55da883
```
It may work with other ROM dumps, it will *not* work with any other ROM versions, including ROM 3 and earlier. You must build ROM 4X using a ROM 4 dump.
Place the ROM dump in the directory with the other files and name it `iic_rom4.bin`.
Now you will need a 65C02 cross assembler. The current codebase is developed using ca65 from the [cc65](http://www.cc65.org/) project. (Note: The code was developed originally using [xa](http://www.floodgap.com/retrotech/xa/)).
Finally you will need [Ruby](https://www.ruby-lang.org/en/) and [Rake](https://github.com/ruby/rake).
Once you have it all together change to the directory with the source files and original ROM image and type `rake`.
If all goes well, you will have a shiny new `iic_rom4x.bin` or `iic+_rom5x.bin`.
If you intend to build an image for a 512-kbit chip such as the SST27SF512, do `rake sf512`.
## Develop
### First Thing's First
First and foremost, it is most helpful to have an emulator. The only one that I have found that can be used for (almost) thorough testing is [Catakig](http://catakig.sourceforge.net/) for MacOS. It can emulate the //c and the Expansion Card (though not battery-backed).
If you plan to test on a real machine, be aware that the ROM socket is not rated for a large number of insertions and you *will* break something after a while. You may consider putting a machine-pin DIP socket or a ZIF socket into the CPU socket position. This can be done by desoldering the original socket if you have the skills, or by plugging the new socket into the existing CPU socket. If you do do the latter you should consider the new socket permanent as the socket pins are thicker than a ROM chip's and removing it may leave the socket in such a state as to not be able to make good contact with a subsequent chip.
As for me, I just use the emulator and then I am very careful with changing the ROM when I want to test on the real hardware. For heavy development/testing I insert a low-profile solder-tail ZIF socket into the existing chip socket..
### Apple //c Technical Reference and other Documentation
You need this.
The Apple //c Technical Reference Manual that is available on the internet has the firmware listing for ROM 3. ROM 4 fixes a few bugs that were in ROM 3, including with the memory card driver. The changes are minor and affect some of the offsets of routines in the RAM card support, but it is easy to figure them out.
[This](http://www.1000bit.it/support/manuali/apple/technotes/memx/tn.memx.1.html) tech note is also helpful as it documents the screen holes and some of the card behavior including under what conditions it reformats. Though the power2 byte is *not* used by the Apple //c code -- it is commented out in the firmware listings in the Technical Reference. ROM 4X uses it for the menu function.
[This](http://www.1000bit.it/support/manuali/apple/technotes/aiic/tn.aiic.5.html) technical note is a little less helpful for this project.
### Magic File Names
The main source files are named after a pattern, `B#_####_something.s` where the first # represents the bank number (0 = main, 1 = aux), and #### is the location in the bank to patch the code into. E.G. the `B1_E000_rom4.bin`'s object code is loaded into bank 1 at E000. Generally the origin address of the code in the file matches the #### portion of the file name.
The Rakefile uses this information to patch the original ROM 4 and produce the ROM 4X version.
### Defs
One file, `iic.defs` is included by all of the other source files. This has entry points, origins, and various RAM locations defined in it for use by the other source code.
### Test Scenarios
#### Basic Functional Tests
1. Boot ProDOS from power off. Run SlotScan 1.62 and confirm that the slots are identified as expected, see below.
2. With no bootable ProDOS RAMdisk, boot the system from power off or ctrl-oa-reset.
1. With the drop-to-basic patch:
- Expected: The system says "No bootable device" and drops to BASIC.
2. Without to drop-to-basic patch:
- Expected: The system boots the same as an unmodified ROM 4.
3. With a bootable ProDOS RAMdisk containing ProDOS, boot the system from power off or ctrl-oa-reset.
- Expected: The system boots from RAM disk, an inverse or flashing R may appear on the left of line 24 of the display.
4. Power on the system with the ca key pressed or use ctrl-ca-reset.
- Expected: The menu is displayed.
5. RAM disk recovery:
1. Battery-backed RAM present with bootable RAM disk: Power off the machine and leave it for 1 hr. Power on.
- Expected: The system boots from RAM disk.
2. Non-battery-backed RAM present with bootable RAM disk: Erase main RAM from 0300 up (e.g. in monitor: `300:00` then `301<300.BFFEM`) and press ctrl-reset.
- Expected: The system boots from RAM disk.
Expected SlotScan output:
```
SlotScan Version 1.62 Copyright 1989-1994 by Robert S. Claney
--------------------------------------------------------------------------------
Apple Computer Type: //c, ROM Ver 4 (Newer Mem. Exp.)
Processor type: 65c02
Total RAM: 128K
-----Scanning for peripherals-----
Port 1: Serial Port (#1)
Port 2: Serial Port (#1)
Port 3: 80-Column Port (#8)
Port 4: RamCard SmartPort: 1 device found
Manufacturer #0 (Unknown)
Device 1: "RAMCARD", Size: 2048 Blocks (1024K, 1 Meg)
Type: Mem. expansion Version: 0.102
Addl. info: (None)
Port 5: SmartPort: 0 devices found
Port 6: Disk ][ Port
Device Size: 280 Blocks (140K)
Port 7: Mouse Port (#0)
Done. Press any key to continue, or Control-P to get a printout
```
#### Menu Item Functional Tests
All cases: When any menu option is selected, the "ROM 4X MM/DD/YY" message is displayed on the bottom of the screen.
0. Monitor
- Expected: We are dropped into the monitor immediately.
1. Reboot
- Expected: System boots as normal.
2. Zero RAM Card and Reboot
- Expected: Reboot if no card RAM present. Otherwise, counter appears in upper left corner and card RAM is cleared.
3. Diagnostics
- Expected: System enters built-in diagnostics as if ctrl-oa-ca-reset was pressed.
4. RAM Card Diagnostics
- Expected: System enters RAM card diagnostics if card RAM present, then/or (no mem) drops to monitor when exited by failure or user escape key.
5. Boot SmartPort
- Expected: The system boots from a SmartPort device, skipping the RAM card and 5.25 floppy drives.
6. Boot Internal 5.25
- Expected: The system boots from the internal 5.25 drive, skipping the RAM card. The system may proceed to the SmartPort if no disk is found.
7. Boot External 5.25
- Expected: The system boots from the external 5.25 drive, skipping the RAM card. The system may proceed to the SmartPort if no disk is found.
### Ideas for Future
- Replace Apple Slinky code with RamFactor code. (Difficulty: Hard)

View File

@ -47,7 +47,7 @@ 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
nbtfail = $e400 ; new boot fail
banner = $fb60 ; 'Apple //c'
testsize = $d99f ; test ramdisk size (rom 3 = $d995)
monitor = $ff59 ; monitor

View File

@ -1,7 +1,7 @@
.code
.psc02
.include "iic+.defs"
.org boot5x ; 234 bytes available, code assembles to 222
.org boot5x ; 234 bytes available, code assembles to 220
jsr titl5x ; "Apple IIc +"
jsr rdrecov ; try to recover ramdisk
lda power2 + rx_mslot ; get action saved by reset5x