mirror of
https://github.com/mgcaret/romex.git
synced 2024-11-23 01:36:30 +00:00
initial
This commit is contained in:
commit
73b2b6f918
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
*.o65
|
||||
*.lbl
|
||||
*.bin
|
||||
*.bin.cd
|
||||
*.bin.ef
|
||||
*.swp
|
||||
*.zip
|
||||
*.o
|
||||
*.lst
|
||||
*.b
|
||||
*.po
|
||||
copyrom.sh
|
||||
make_rom.sh
|
||||
rom.sha256
|
||||
**/.DS_Store
|
||||
t
|
70
common/iiee.defs
Normal file
70
common/iiee.defs
Normal file
@ -0,0 +1,70 @@
|
||||
; macros
|
||||
|
||||
; use at beginning of patch, set maxsize=0 for no max size check
|
||||
.macro rompatch addr,maxsize,desc
|
||||
patchstart = addr
|
||||
.org patchstart
|
||||
patchmsize = maxsize
|
||||
.define patchdesc desc
|
||||
.if patchmsize > 0
|
||||
.out .sprintf(" ROM patch %s bgn %x, max size %d", patchdesc, patchstart, patchmsize)
|
||||
.else
|
||||
.out .sprintf(" ROM patch %s bgn %x, max size unconstrained", patchdesc, patchstart)
|
||||
.endif
|
||||
.endmacro
|
||||
|
||||
; use at end of patch, displays info about the patch
|
||||
; and checks for over-size patch
|
||||
.macro endpatch
|
||||
.if patchmsize > 0
|
||||
.out .sprintf(" ROM patch %s end %x; size: %d of %d, %d left", patchdesc, *-1, *-patchstart, patchmsize, patchmsize-*+patchstart)
|
||||
.assert * <= (patchstart+patchmsize), error, .sprintf(" ROM patch %s code too big", patchdesc)
|
||||
.else
|
||||
.out .sprintf(" ROM patch %s end %x; size: %d", patchdesc, *-1, *-patchstart)
|
||||
.endif
|
||||
.endmacro
|
||||
|
||||
; hardware
|
||||
;set80col = $c001
|
||||
setslotcxrom = $c006
|
||||
setintcxrom = $c007
|
||||
setaltchar = $c00f
|
||||
butn0 = $c061
|
||||
butn1 = $c062
|
||||
kbd = $c000
|
||||
kbdstrb = $c010
|
||||
romin = $c081
|
||||
|
||||
|
||||
; ZP locations
|
||||
ch = $24 ; cursor horizontal pos
|
||||
cv = $25
|
||||
|
||||
; locations
|
||||
softev = $3f2
|
||||
pwerdup = $3f4
|
||||
ampervec = $3f5
|
||||
|
||||
; values
|
||||
pwrbyte = $a5
|
||||
menucol = 10 ; column for menu entries
|
||||
|
||||
; entries
|
||||
init = $fb2f ; init text screen
|
||||
tabv = $fb5b ; vtab to a-reg
|
||||
vtab = $fc22 ; vtab to cv
|
||||
sloop = $faba ; slot scan loop
|
||||
title = $fb60 ; clear screen, display "Apple //e"
|
||||
bell1 = $fbdd ; beep
|
||||
wait = $fca8 ; waste time
|
||||
rdkey = $fd0c ; read keyboard
|
||||
cout = $fded ; character out
|
||||
setkbd = $fe89 ; set keyboard as input
|
||||
setvid = $fe93 ; set text screen as output
|
||||
rdchar = $fd35 ; rdchar, used for delete key patch
|
||||
prhex = $fde3 ; x,y preserved
|
||||
prbyte = $fdda ; x,y preserved
|
||||
monitor = $ff59 ; monitor
|
||||
intcxrts = $f8cb ; switch in internal cx ROM and rts
|
||||
slotcxrts = $fec5 ; switch in slot cx ROM and rts
|
||||
|
50
common/pickboot.s
Normal file
50
common/pickboot.s
Normal file
@ -0,0 +1,50 @@
|
||||
.pc02
|
||||
.if ::no_tape
|
||||
checkatalk = $d8b7 ; actually checkatalk2...
|
||||
atwait = $d8b9
|
||||
rts ; so STORE returns
|
||||
.else
|
||||
; pressoa defined elsewhere
|
||||
.endif
|
||||
; we get here from patch at $fab6 (no tape) or $d8f0 (no diags)
|
||||
.proc pickboot
|
||||
stx $00 ; is a zero
|
||||
sta $01 ; is $c8
|
||||
lda $02 ;
|
||||
eor $03
|
||||
cmp #pwrbyte
|
||||
bne goboot
|
||||
dosel: lda $02
|
||||
cmp #$b1
|
||||
bcc goboot ; check value right, but illegal value
|
||||
cmp #$b8
|
||||
bcs goboot
|
||||
eor #$70 ; $b0 -> $c0
|
||||
inc a
|
||||
sta $01
|
||||
.if ::no_tape
|
||||
; if we are assembling over STORE/RECALL
|
||||
bit $60 ; assembles an RTS at RECALL
|
||||
.assert *-1=$f3bc,error,.sprintf("RECALL aligment problem, *=%x",*-1)
|
||||
.endif
|
||||
sta $02 ; so that next try has default behavior
|
||||
jsr checkatalk ; note ::no_tape version calls checkatalk2 here
|
||||
bcc goboot ; nope, just boot the slot
|
||||
sta setaltchar ; turn on mousetext
|
||||
jsr atwait ; Wait for open apple
|
||||
goboot:
|
||||
.if !::no_tape
|
||||
; set up RTS trick
|
||||
lda #>(sloop-1)
|
||||
pha
|
||||
lda #<(sloop-1)
|
||||
pha
|
||||
.endif
|
||||
ldx $00
|
||||
lda $01
|
||||
.if ::no_tape
|
||||
jmp sloop
|
||||
.else
|
||||
jmp slotcxrts ; return to slot ROM and execute RTS trick
|
||||
.endif
|
||||
.endproc
|
132
common/romx_main.s
Normal file
132
common/romx_main.s
Normal file
@ -0,0 +1,132 @@
|
||||
.pc02
|
||||
|
||||
.if no_tape
|
||||
checkblk = $d8b1
|
||||
checkatalk = $d8b3
|
||||
getslotbyte = $d8b5
|
||||
checkatalk2 = $d8b7 ; not used here
|
||||
atwait = $d8b9
|
||||
.else
|
||||
; above must be defined by including file
|
||||
.endif
|
||||
|
||||
.proc pressoa
|
||||
ldx #msg7-msg0 ; Press open apple
|
||||
jmp Disp
|
||||
.endproc
|
||||
.proc resete0x
|
||||
.if ::no_tape
|
||||
; if we are over tape code, we still have diags so allow access
|
||||
bit butn0 ; open apple also pressed?
|
||||
bpl :+ ; nope, just ca/option
|
||||
jmp $c600 ; do diags
|
||||
.endif
|
||||
: jsr title
|
||||
ldx #msg0-msg0 ; basic parts of menu
|
||||
jsr Disp
|
||||
; display slots now
|
||||
stz $00 ; zero low byte of slot ptr
|
||||
ldx #$07
|
||||
: phx
|
||||
jsr dslot
|
||||
dec cv
|
||||
jsr vtab ; wrecks y
|
||||
lda #menucol
|
||||
sta ch
|
||||
plx
|
||||
dex
|
||||
bne :-
|
||||
jsr rdkey
|
||||
cmp #$b0 ; is 0 or less?
|
||||
bcc :-- ; less than, re-draw
|
||||
bne :+ ; not zero, skip
|
||||
jmp monitor ; do not pass go, do not collect $200
|
||||
: cmp #$b8 ; 8 or higher
|
||||
bcs :--- ; yep, re-draw
|
||||
sta $02 ; put in $02
|
||||
eor #pwrbyte ; make check byte
|
||||
sta $03 ; put in $03
|
||||
lda #$80 ; flag to open-apple+reset
|
||||
jmp $c2c6 ; back to resetx
|
||||
.endproc
|
||||
; entered with slot # in x, and scanslots having been called
|
||||
.proc dslot
|
||||
txa
|
||||
jsr prhex
|
||||
lda #$a0 ; space
|
||||
jsr cout
|
||||
txa
|
||||
ora #$c0 ; to ref
|
||||
sta $01 ; high nibble of ptr
|
||||
jsr checkatalk
|
||||
bcc :+ ; skip if not
|
||||
ldx #msg2-msg0
|
||||
jsr Disp ; print it
|
||||
: jsr checkblk ; is block device
|
||||
bcs block
|
||||
ldy #$0b ; check for Pascal 1.1 FW protocol
|
||||
jsr getslotbyte ; get byte (cxrom is on!)
|
||||
dec a
|
||||
beq pascal
|
||||
exit: rts
|
||||
pascal: ldx #msg5-msg0
|
||||
jsr Disp
|
||||
ldy #$0c ; Pascal card ID
|
||||
jsr getslotbyte
|
||||
jmp prbyte
|
||||
block: beq smart
|
||||
ldy #$ff ; last byte of firmware
|
||||
jsr getslotbyte
|
||||
beq disk ; $00 = 16-sector
|
||||
inc a ; is $FF?
|
||||
beq disk ; yes 13-sector
|
||||
ldx #msg3-msg0 ; generic block device
|
||||
.byte $2c ; BIT Absolute opcode
|
||||
disk: ldx #msg4-msg0
|
||||
.byte $2c
|
||||
smart: ldx #msg6-msg0
|
||||
; fall-through
|
||||
.endproc
|
||||
.proc Disp
|
||||
lda msg0,x
|
||||
bne :+
|
||||
rts
|
||||
: inx ; set up for next message byte
|
||||
cmp #$18 ; last line + 1
|
||||
bcc repos
|
||||
eor #$80
|
||||
jsr cout ; not supposed to change any regs
|
||||
bra Disp
|
||||
repos: jsr tabv ; destroys a and y, but not x
|
||||
lda msg0,x ; get horizontal
|
||||
sta ch ; and write
|
||||
inx ; next message byte
|
||||
bra Disp
|
||||
.endproc
|
||||
.if no_tape
|
||||
msg0: .byte 3,menucol,"0 Mon"
|
||||
.else
|
||||
msg0: .byte 3,menucol,"0 Monitor"
|
||||
.endif
|
||||
.byte 5,menucol,"Slots:"
|
||||
.byte 22,16,"By M.G."
|
||||
msg1: .byte 23,13,"ROM eX 02-19A",13,menucol,$00
|
||||
.if no_tape
|
||||
msg2: .byte "ATalk ",$00
|
||||
.else
|
||||
msg2: .byte "AppleTalk ",$00
|
||||
.endif
|
||||
msg3: .byte "Block",$00
|
||||
msg4: .byte "Disk II",$00
|
||||
.if no_tape
|
||||
msg5: .byte "Pas $",$00
|
||||
.else
|
||||
msg5: .byte "Pascal $",$00
|
||||
.endif
|
||||
.if no_tape
|
||||
msg6: .byte "Smart",$00
|
||||
.else
|
||||
msg6: .byte "SmartPort",$00
|
||||
.endif
|
||||
msg7: .byte 3,16,"Press ",$C1,$00
|
||||
|
109
common/slotscan.s
Normal file
109
common/slotscan.s
Normal file
@ -0,0 +1,109 @@
|
||||
; If building the version that removes the tape code,
|
||||
; this lands outside of $Cxxx space, so we can directly query the slots
|
||||
; If we are removing the diags, then this lands in $Cxxx space and must
|
||||
; call the getslotbyte routine that lives outside of $Cxxx space.
|
||||
; to facilitate this, a couple of AppleSoft tape I/O routines are relocated
|
||||
; to $Cxxx space.
|
||||
.pc02
|
||||
.if ::no_tape
|
||||
rts ; so SAVE returns
|
||||
bra checkblk ; $d8b1
|
||||
bra checkatalk ; $d8b3
|
||||
bra getslotbyte ; $d8b5
|
||||
bra checkatalk2 ; $d8b7, without cxrom stuff
|
||||
; fall-through $d8b9 to atwait
|
||||
.endif
|
||||
|
||||
; WS card requires open apple to be held to boot appletalk after the
|
||||
; firmware diagnostics have passed. Display wait msg and
|
||||
.proc atwait
|
||||
jsr title
|
||||
.if ::no_tape
|
||||
jsr $c502 ; display message
|
||||
.else
|
||||
jsr $c606 ; display messsage
|
||||
.endif
|
||||
: bit butn0
|
||||
bpl :-
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.if ::no_tape
|
||||
; enter assuming cxrom is on ($00) points to card slot ROM
|
||||
; y contains byte index into card firmware
|
||||
.proc getslotbyte
|
||||
sta setslotcxrom
|
||||
lda ($00),y
|
||||
bra cxexit
|
||||
.endproc
|
||||
.else
|
||||
getslotbyte = $d8f3
|
||||
.endif
|
||||
|
||||
; enter assuming cxrom is on, ($00) points to card slot ROM
|
||||
; and y is usable
|
||||
; exits with carry set if block device in slot, and z flag set if smartport
|
||||
; carry clear otherwise
|
||||
.proc checkblk
|
||||
.if ::no_tape
|
||||
sta setslotcxrom
|
||||
.endif
|
||||
ldy #$05
|
||||
:
|
||||
.if ::no_tape
|
||||
lda ($00),y
|
||||
.else
|
||||
jsr getslotbyte
|
||||
.endif
|
||||
cmp $fb01,y ; Disk ID bytes
|
||||
beq :+
|
||||
clc
|
||||
bcc cxexit
|
||||
: dey ; note carry is set
|
||||
dey
|
||||
bpl :-- ; until done or all bytes match
|
||||
ldy #$07 ; carry still set here
|
||||
.if ::no_tape
|
||||
lda ($00),y ; get smartport
|
||||
.else
|
||||
jsr getslotbyte
|
||||
.endif
|
||||
cxexit:
|
||||
.if ::no_tape
|
||||
jmp $f8cb ; has sta setintcxrom then rts
|
||||
.else
|
||||
rts
|
||||
.endif
|
||||
.endproc
|
||||
cxexit = checkblk::cxexit
|
||||
|
||||
; enter assuming that cxrom is on, ($00) points to card slot ROM
|
||||
; and y is usable
|
||||
.proc checkatalk
|
||||
.if ::no_tape
|
||||
sta setslotcxrom
|
||||
jsr checkatalk2
|
||||
bra cxexit
|
||||
.endproc
|
||||
|
||||
; enter assuming ($00) points to card slot ROM
|
||||
; and y is usable
|
||||
.proc checkatalk2
|
||||
.endif
|
||||
ldy #$F9 ; check $CnF9-$CnFC
|
||||
at_chk:
|
||||
.if ::no_tape
|
||||
lda ($00),y
|
||||
.else
|
||||
jsr getslotbyte
|
||||
.endif
|
||||
cmp atid-$F9,y
|
||||
clc ; anticipate failure
|
||||
bne done
|
||||
iny
|
||||
cpy #$FD
|
||||
bcc at_chk
|
||||
done: rts
|
||||
atid: .byte "ATLK"
|
||||
.endproc
|
||||
|
39
no_diags/B0_C600_romx_main.s
Normal file
39
no_diags/B0_C600_romx_main.s
Normal file
@ -0,0 +1,39 @@
|
||||
.include "iiee.defs"
|
||||
|
||||
rompatch $c600,512,"romx_main"
|
||||
.pc02
|
||||
; if we get here, we know that the closed apple/option key was held down
|
||||
; and CX ROM is already active
|
||||
bra resete0x ; $C600
|
||||
bra tapestuff ; $C602
|
||||
bra pickboot ; $C604
|
||||
bra pressoa ; $C606
|
||||
; Replacement tape routines
|
||||
.proc tapestuff
|
||||
bcc progio
|
||||
; fall-through
|
||||
.endproc
|
||||
.proc vartio
|
||||
lda #$50 ; LINNUM
|
||||
ldy #$00
|
||||
sta $3C ; A1L
|
||||
sty $3D ; A1H
|
||||
lda #$52 ; TMPPT (lock byte)
|
||||
sty $D6 ; LOCK
|
||||
seta2: sta $3E ; A2L
|
||||
sty $3F ; A2H
|
||||
jmp slotcxrts
|
||||
.endproc
|
||||
.proc progio
|
||||
lda $67 ; TXTTAB
|
||||
ldy $68
|
||||
sta $3C ; A1L
|
||||
sta $3D ; A1H
|
||||
lda $69 ; VARTAB
|
||||
ldy $6A
|
||||
bra vartio::seta2
|
||||
.endproc
|
||||
.include "../common/pickboot.s"
|
||||
.include "../common/romx_main.s"
|
||||
.include "../common/slotscan.s"
|
||||
endpatch
|
36
no_diags/B0_D8F0_patch_vartio.s
Normal file
36
no_diags/B0_D8F0_patch_vartio.s
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
.pc02
|
||||
.include "iiee.defs"
|
||||
rompatch $d8f0,34,"patch_vartio" ; patches over Applesoft VARTIO
|
||||
.proc vartio
|
||||
sec
|
||||
bra gocx
|
||||
.endproc
|
||||
; enter assuming cxrom is on ($00) points to card slot ROM
|
||||
; y contains byte index into card firmware
|
||||
.proc getslotbyte
|
||||
sta setslotcxrom
|
||||
lda ($00),y
|
||||
jmp intcxrts
|
||||
.endproc
|
||||
.proc gopickboot
|
||||
sta setintcxrom
|
||||
jmp $c604
|
||||
.endproc
|
||||
.assert *=$d901,error,.sprintf("PROGIO aligment problem, *=%x",*)
|
||||
.proc progio
|
||||
clc
|
||||
; fall-through
|
||||
.endproc
|
||||
.proc gocx
|
||||
sta setintcxrom
|
||||
jmp $c602 ; go to vartio/progio replacement
|
||||
.endproc
|
||||
.proc fixdelkey
|
||||
jsr rdchar
|
||||
cmp #$ff
|
||||
bne :+
|
||||
lda #$88
|
||||
: rts
|
||||
.endproc
|
||||
endpatch
|
7
no_diags/B0_FAB6_patch_pwrup.s
Normal file
7
no_diags/B0_FAB6_patch_pwrup.s
Normal file
@ -0,0 +1,7 @@
|
||||
; patch PWRUP to go to romx boot code
|
||||
.code
|
||||
.include "iiee.defs"
|
||||
rompatch $fab6,4,"patch_pwrup"
|
||||
jmp $d8fb
|
||||
nop
|
||||
endpatch
|
6
no_diags/B0_FD75_patch_getln1.s
Normal file
6
no_diags/B0_FD75_patch_getln1.s
Normal file
@ -0,0 +1,6 @@
|
||||
; patch GETLN1 to call delete key handler
|
||||
.code
|
||||
.include "iiee.defs"
|
||||
rompatch $fd75,3,"patch_getln1"
|
||||
jsr $d908
|
||||
endpatch
|
165
no_diags/Rakefile
Normal file
165
no_diags/Rakefile
Normal file
@ -0,0 +1,165 @@
|
||||
rom_url = 'http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Computers/Apple%20II/Apple%20IIe/ROM%20Images/Apple%20IIe%20Enhanced%20ROM%20Pages%20C0-FF%20-%20342-0349-B%20-%201985.bin'
|
||||
source_rom = '../iiee_rom.bin'
|
||||
source_rom_sha256 = 'aab38a03ca8deabbb2f868733148c2efd6f655a59cd9c5d058ef3e0b7aa86a1a'
|
||||
dest_rom = 'iiee_romx_no_diags.bin'
|
||||
distzip = 'iiee_romx_no_diags.zip'
|
||||
rom_base = 0xc000
|
||||
acmd = 'java -jar ~/bin/AppleCommander-1.3.5-ac.jar'
|
||||
|
||||
source_files = Rake::FileList.new('*.s')
|
||||
|
||||
desc "Default: clean and build it"
|
||||
task :default => [:clean, :assemble, :build_rom] do
|
||||
sh "ls -l #{dest_rom}"
|
||||
end
|
||||
|
||||
task :zip => [:clean, :assemble, :build_zip] do
|
||||
sh "ls -l #{dest_rom}"
|
||||
end
|
||||
|
||||
desc "Clean object files"
|
||||
task :clean do
|
||||
sh "rm -f #{dest_rom}"
|
||||
sh "rm -f #{dest_rom}.cd"
|
||||
sh "rm -f #{dest_rom}.ef"
|
||||
sh "rm -f sf512_#{dest_rom}"
|
||||
sh "rm -f *.o"
|
||||
sh "rm -f *.lst"
|
||||
sh "rm -f *.b"
|
||||
sh "rm -f rom.sha256"
|
||||
sh "rm -f make_rom.sh"
|
||||
sh "rm -f #{distzip}"
|
||||
end
|
||||
|
||||
desc 'Obtain ROM'
|
||||
rule source_rom do
|
||||
require 'open-uri'
|
||||
|
||||
puts "Downloading ROM..."
|
||||
|
||||
File.open(source_rom, "wb") do |romfile|
|
||||
open(rom_url) do |wwwfile|
|
||||
romfile.write(wwwfile.read)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Verify ROM Checksum"
|
||||
task :checksum_rom => source_rom do
|
||||
require 'digest'
|
||||
|
||||
sha256 = Digest::SHA256.file source_rom
|
||||
fail "ROM checksum failed" unless sha256.hexdigest == source_rom_sha256
|
||||
puts "Source ROM appears correct!"
|
||||
end
|
||||
|
||||
desc "Assemble all source files"
|
||||
task :assemble => source_files.ext('.b')
|
||||
|
||||
rule ".o" => ".s" do |t|
|
||||
sh "ca65 -l #{t.name}.lst #{t.source}"
|
||||
end
|
||||
|
||||
rule ".b" => ".o" do |t|
|
||||
sh "ld65 -t none -o #{t.name} #{t.source}"
|
||||
end
|
||||
|
||||
desc "Build ROM"
|
||||
task :build_rom => [:assemble, :checksum_rom] do
|
||||
puts "Building ROM image..."
|
||||
obj_files = Rake::FileList.new('*.b')
|
||||
rom = File.read(source_rom)
|
||||
obj_files.each do |t|
|
||||
if t =~ /B(\h)_(\h{4})/
|
||||
bnum = $1.to_i(16)
|
||||
badd = $2.to_i(16)
|
||||
addr = bnum * 16384 + badd - rom_base
|
||||
fc = File.read(t)
|
||||
fl = fc.bytes.count
|
||||
puts "Loading #{t} into bank #{bnum} @ $#{badd.to_s(16)}, file addr $#{addr.to_s(16)}, len $#{fl.to_s(16)} (#{fl})"
|
||||
nzc = 0
|
||||
fc.each_byte do |b|
|
||||
nzc += 1 if rom.getbyte(addr) != 0 && rom.getbyte(addr) != b
|
||||
rom.setbyte(addr, b)
|
||||
addr += 1
|
||||
end
|
||||
puts "\tNote: patched over #{nzc} nonzero bytes!" if nzc > 0
|
||||
else
|
||||
puts "I dont know where to load #{t}"
|
||||
end
|
||||
end
|
||||
File.write(dest_rom, rom)
|
||||
puts "ROM image done: #{dest_rom}"
|
||||
end
|
||||
|
||||
# IIe version copies 4 times because rom is half size
|
||||
desc "Build SST27SF512 Image"
|
||||
task :sf512 => [:build_rom] do
|
||||
sh "cat #{dest_rom} #{dest_rom} #{dest_rom} #{dest_rom} > sf512_#{dest_rom}"
|
||||
end
|
||||
|
||||
desc "Split image into two images"
|
||||
task :split => [:build_rom] do
|
||||
sh "split -b 8192 #{dest_rom}"
|
||||
sh "mv -f xaa #{dest_rom}.cd"
|
||||
sh "mv -f xab #{dest_rom}.ef"
|
||||
end
|
||||
|
||||
desc "Build disributable ZIP"
|
||||
task :build_zip => [:build_rom] do
|
||||
require 'digest'
|
||||
require 'date'
|
||||
|
||||
sha256 = Digest::SHA256.file dest_rom
|
||||
shafile = <<EOF
|
||||
#{source_rom_sha256} #{source_rom}
|
||||
#{sha256.hexdigest} #{dest_rom}
|
||||
EOF
|
||||
|
||||
dd_cmds = []
|
||||
|
||||
puts "Building distributable ZIP..."
|
||||
obj_files = Rake::FileList.new('*.b')
|
||||
obj_files.each do |t|
|
||||
if t =~ /B(\h)_(\h{4})/
|
||||
bnum = $1.to_i(16)
|
||||
badd = $2.to_i(16)
|
||||
addr = bnum * 16384 + badd - rom_base
|
||||
dd_cmds << "dd if=#{t} of=#{dest_rom} bs=1 seek=#{addr} conv=notrunc"
|
||||
sh "zip #{distzip} #{t}"
|
||||
end
|
||||
end
|
||||
|
||||
puts "Creating maker script..."
|
||||
|
||||
script = <<EOF
|
||||
#!/bin/bash
|
||||
set -e
|
||||
BDATE="#{DateTime.now.to_s}"
|
||||
ROM_URL="#{rom_url}"
|
||||
echo ${BDATE}
|
||||
if [ -e `which curl` ]; then
|
||||
curl -s "${ROM_URL}" > #{source_rom}
|
||||
elif [ -e `which wget` ]; then
|
||||
wget -O #{source_rom} "${ROM_URL}"
|
||||
else
|
||||
echo "Can't download source ROM image!"
|
||||
fi
|
||||
cp #{source_rom} #{dest_rom}
|
||||
#{dd_cmds.join("\n")}
|
||||
if [ -e `which shasum` ]; then
|
||||
shasum -a 256 -c rom.sha256
|
||||
elif [ -e "sha256sum" ]; then
|
||||
sha256sum -c rom.sha256
|
||||
else
|
||||
echo "Please check the .bin files against rom.sha256"
|
||||
fi
|
||||
echo "#{dest_rom} created!"
|
||||
EOF
|
||||
|
||||
File.write('rom.sha256', shafile)
|
||||
File.write('make_rom.sh', script)
|
||||
|
||||
sh "zip #{distzip} rom.sha256 make_rom.sh"
|
||||
end
|
||||
|
4
no_diags/iiee.defs
Normal file
4
no_diags/iiee.defs
Normal file
@ -0,0 +1,4 @@
|
||||
.include "../common/iiee.defs"
|
||||
|
||||
no_tape = 0
|
||||
|
6
no_tape/B0_C2C0_patch_resetx.s
Normal file
6
no_tape/B0_C2C0_patch_resetx.s
Normal file
@ -0,0 +1,6 @@
|
||||
.pc02
|
||||
.include "iiee.defs"
|
||||
; correlate these with the text patch
|
||||
rompatch $c2c0,3,"resetx"
|
||||
jmp $c500 ; intercept diags hook
|
||||
endpatch
|
7
no_tape/B0_C500_romx_main.s
Normal file
7
no_tape/B0_C500_romx_main.s
Normal file
@ -0,0 +1,7 @@
|
||||
.include "iiee.defs"
|
||||
.pc02
|
||||
|
||||
rompatch $c500,256,"romx_main"
|
||||
bra resete0x
|
||||
.include "../common/romx_main.s"
|
||||
endpatch
|
2
no_tape/B0_D034_kill_shload.s
Normal file
2
no_tape/B0_D034_kill_shload.s
Normal file
@ -0,0 +1,2 @@
|
||||
.include "iiee.defs"
|
||||
.addr ampervec-1
|
2
no_tape/B0_D04E_kill_recall.s
Normal file
2
no_tape/B0_D04E_kill_recall.s
Normal file
@ -0,0 +1,2 @@
|
||||
.include "iiee.defs"
|
||||
.addr ampervec-1
|
2
no_tape/B0_D050_kill_store.s
Normal file
2
no_tape/B0_D050_kill_store.s
Normal file
@ -0,0 +1,2 @@
|
||||
.include "iiee.defs"
|
||||
.addr ampervec-1
|
2
no_tape/B0_D06C_kill_load.s
Normal file
2
no_tape/B0_D06C_kill_load.s
Normal file
@ -0,0 +1,2 @@
|
||||
.include "iiee.defs"
|
||||
.addr ampervec-1
|
2
no_tape/B0_D06E_kill_save.s
Normal file
2
no_tape/B0_D06E_kill_save.s
Normal file
@ -0,0 +1,2 @@
|
||||
.include "iiee.defs"
|
||||
.addr ampervec-1
|
5
no_tape/B0_D8B0_slotscan.s
Normal file
5
no_tape/B0_D8B0_slotscan.s
Normal file
@ -0,0 +1,5 @@
|
||||
.pc02
|
||||
.include "iiee.defs"
|
||||
rompatch $d8b0,98,"slotscan" ; patches over Applesoft SAVE, LOAD,and VARTIO
|
||||
.include "../common/slotscan.s"
|
||||
endpatch
|
6
no_tape/B0_F39F_pickboot.s
Normal file
6
no_tape/B0_F39F_pickboot.s
Normal file
@ -0,0 +1,6 @@
|
||||
.pc02
|
||||
.include "iiee.defs"
|
||||
; correlate these with the text patch
|
||||
rompatch $f39f,57,"pickboot" ; patches over AppleSoft STORE and RECALL
|
||||
.include "../common/pickboot.s"
|
||||
endpatch
|
7
no_tape/B0_F77B_no_shload_jmp.s
Normal file
7
no_tape/B0_F77B_no_shload_jmp.s
Normal file
@ -0,0 +1,7 @@
|
||||
; Patch out JSR $C500 in AppleSoft SHLOAD code and
|
||||
; always return failure
|
||||
.include "iiee.defs"
|
||||
nop
|
||||
nop
|
||||
sec
|
||||
|
2
no_tape/B0_F7E4_fix_getarypt.s
Normal file
2
no_tape/B0_F7E4_fix_getarypt.s
Normal file
@ -0,0 +1,2 @@
|
||||
.include "iiee.defs"
|
||||
rts
|
7
no_tape/B0_FAB6_patch_pwrup.s
Normal file
7
no_tape/B0_FAB6_patch_pwrup.s
Normal file
@ -0,0 +1,7 @@
|
||||
; patch PWRUP to go to romx boot code
|
||||
.code
|
||||
.include "iiee.defs"
|
||||
.org $fab6
|
||||
jmp $f3a0
|
||||
nop
|
||||
|
5
no_tape/B0_FCCC_no_mon_headr.s
Normal file
5
no_tape/B0_FCCC_no_mon_headr.s
Normal file
@ -0,0 +1,5 @@
|
||||
; Patch out JSR $C567 in monitor tape HEADR code
|
||||
.include "iiee.defs"
|
||||
nop
|
||||
lda #$00
|
||||
|
6
no_tape/B0_FD75_patch_getln1.s
Normal file
6
no_tape/B0_FD75_patch_getln1.s
Normal file
@ -0,0 +1,6 @@
|
||||
; patch GETLN1 to call delete key handler
|
||||
.code
|
||||
.include "iiee.defs"
|
||||
.org $fd75
|
||||
jsr $feff
|
||||
|
9
no_tape/B0_FECD_mon_write.s
Normal file
9
no_tape/B0_FECD_mon_write.s
Normal file
@ -0,0 +1,9 @@
|
||||
; Patch monitor WRITE code
|
||||
.pc02
|
||||
.include "iiee.defs"
|
||||
rompatch $fecd,10,"mon_write"
|
||||
bra $ff2d ; print ERR
|
||||
sta romin ; at $fecf
|
||||
jmp $f3a0 ; to boot selection hanndler
|
||||
endpatch
|
||||
|
12
no_tape/B0_FEFD_mon_read.s
Normal file
12
no_tape/B0_FEFD_mon_read.s
Normal file
@ -0,0 +1,12 @@
|
||||
; Patch monitor READ code
|
||||
.pc02
|
||||
.include "iiee.defs"
|
||||
rompatch $fefd,13,"mon_read"
|
||||
bra $ff2d ; print ERR
|
||||
; delete key patch
|
||||
jsr $fd35 ; RDCHAR
|
||||
cmp #$ff
|
||||
bne :+
|
||||
lda #$88
|
||||
: rts
|
||||
endpatch
|
165
no_tape/Rakefile
Normal file
165
no_tape/Rakefile
Normal file
@ -0,0 +1,165 @@
|
||||
rom_url = 'http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Computers/Apple%20II/Apple%20IIe/ROM%20Images/Apple%20IIe%20Enhanced%20ROM%20Pages%20C0-FF%20-%20342-0349-B%20-%201985.bin'
|
||||
source_rom = '../iiee_rom.bin'
|
||||
source_rom_sha256 = 'aab38a03ca8deabbb2f868733148c2efd6f655a59cd9c5d058ef3e0b7aa86a1a'
|
||||
dest_rom = 'iiee_romx_no_tape.bin'
|
||||
distzip = 'iiee_romx_no_tape.zip'
|
||||
rom_base = 0xc000
|
||||
acmd = 'java -jar ~/bin/AppleCommander-1.3.5-ac.jar'
|
||||
|
||||
source_files = Rake::FileList.new('*.s')
|
||||
|
||||
desc "Default: clean and build it"
|
||||
task :default => [:clean, :assemble, :build_rom] do
|
||||
sh "ls -l #{dest_rom}"
|
||||
end
|
||||
|
||||
task :zip => [:clean, :assemble, :build_zip] do
|
||||
sh "ls -l #{dest_rom}"
|
||||
end
|
||||
|
||||
desc "Clean object files"
|
||||
task :clean do
|
||||
sh "rm -f #{dest_rom}"
|
||||
sh "rm -f #{dest_rom}.cd"
|
||||
sh "rm -f #{dest_rom}.ef"
|
||||
sh "rm -f sf512_#{dest_rom}"
|
||||
sh "rm -f *.o"
|
||||
sh "rm -f *.lst"
|
||||
sh "rm -f *.b"
|
||||
sh "rm -f rom.sha256"
|
||||
sh "rm -f make_rom.sh"
|
||||
sh "rm -f #{distzip}"
|
||||
end
|
||||
|
||||
desc 'Obtain ROM'
|
||||
rule source_rom do
|
||||
require 'open-uri'
|
||||
|
||||
puts "Downloading ROM..."
|
||||
|
||||
File.open(source_rom, "wb") do |romfile|
|
||||
open(rom_url) do |wwwfile|
|
||||
romfile.write(wwwfile.read)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Verify ROM Checksum"
|
||||
task :checksum_rom => source_rom do
|
||||
require 'digest'
|
||||
|
||||
sha256 = Digest::SHA256.file source_rom
|
||||
fail "ROM checksum failed" unless sha256.hexdigest == source_rom_sha256
|
||||
puts "Source ROM appears correct!"
|
||||
end
|
||||
|
||||
desc "Assemble all source files"
|
||||
task :assemble => source_files.ext('.b')
|
||||
|
||||
rule ".o" => ".s" do |t|
|
||||
sh "ca65 -l #{t.name}.lst #{t.source}"
|
||||
end
|
||||
|
||||
rule ".b" => ".o" do |t|
|
||||
sh "ld65 -t none -o #{t.name} #{t.source}"
|
||||
end
|
||||
|
||||
desc "Build ROM"
|
||||
task :build_rom => [:assemble, :checksum_rom] do
|
||||
puts "Building ROM image..."
|
||||
obj_files = Rake::FileList.new('*.b')
|
||||
rom = File.read(source_rom)
|
||||
obj_files.each do |t|
|
||||
if t =~ /B(\h)_(\h{4})/
|
||||
bnum = $1.to_i(16)
|
||||
badd = $2.to_i(16)
|
||||
addr = bnum * 16384 + badd - rom_base
|
||||
fc = File.read(t)
|
||||
fl = fc.bytes.count
|
||||
puts "Loading #{t} into bank #{bnum} @ $#{badd.to_s(16)}, file addr $#{addr.to_s(16)}, len $#{fl.to_s(16)} (#{fl})"
|
||||
nzc = 0
|
||||
fc.each_byte do |b|
|
||||
nzc += 1 if rom.getbyte(addr) != 0 && rom.getbyte(addr) != b
|
||||
rom.setbyte(addr, b)
|
||||
addr += 1
|
||||
end
|
||||
puts "\tNote: patched over #{nzc} nonzero bytes!" if nzc > 0
|
||||
else
|
||||
puts "I dont know where to load #{t}"
|
||||
end
|
||||
end
|
||||
File.write(dest_rom, rom)
|
||||
puts "ROM image done: #{dest_rom}"
|
||||
end
|
||||
|
||||
# IIe version copies 4 times because rom is half size
|
||||
desc "Build SST27SF512 Image"
|
||||
task :sf512 => [:build_rom] do
|
||||
sh "cat #{dest_rom} #{dest_rom} #{dest_rom} #{dest_rom} > sf512_#{dest_rom}"
|
||||
end
|
||||
|
||||
desc "Split image into two images"
|
||||
task :split => [:build_rom] do
|
||||
sh "split -b 8192 #{dest_rom}"
|
||||
sh "mv -f xaa #{dest_rom}.cd"
|
||||
sh "mv -f xab #{dest_rom}.ef"
|
||||
end
|
||||
|
||||
desc "Build disributable ZIP"
|
||||
task :build_zip => [:build_rom] do
|
||||
require 'digest'
|
||||
require 'date'
|
||||
|
||||
sha256 = Digest::SHA256.file dest_rom
|
||||
shafile = <<EOF
|
||||
#{source_rom_sha256} #{source_rom}
|
||||
#{sha256.hexdigest} #{dest_rom}
|
||||
EOF
|
||||
|
||||
dd_cmds = []
|
||||
|
||||
puts "Building distributable ZIP..."
|
||||
obj_files = Rake::FileList.new('*.b')
|
||||
obj_files.each do |t|
|
||||
if t =~ /B(\h)_(\h{4})/
|
||||
bnum = $1.to_i(16)
|
||||
badd = $2.to_i(16)
|
||||
addr = bnum * 16384 + badd - rom_base
|
||||
dd_cmds << "dd if=#{t} of=#{dest_rom} bs=1 seek=#{addr} conv=notrunc"
|
||||
sh "zip #{distzip} #{t}"
|
||||
end
|
||||
end
|
||||
|
||||
puts "Creating maker script..."
|
||||
|
||||
script = <<EOF
|
||||
#!/bin/bash
|
||||
set -e
|
||||
BDATE="#{DateTime.now.to_s}"
|
||||
ROM_URL="#{rom_url}"
|
||||
echo ${BDATE}
|
||||
if [ -e `which curl` ]; then
|
||||
curl -s "${ROM_URL}" > #{source_rom}
|
||||
elif [ -e `which wget` ]; then
|
||||
wget -O #{source_rom} "${ROM_URL}"
|
||||
else
|
||||
echo "Can't download source ROM image!"
|
||||
fi
|
||||
cp #{source_rom} #{dest_rom}
|
||||
#{dd_cmds.join("\n")}
|
||||
if [ -e `which shasum` ]; then
|
||||
shasum -a 256 -c rom.sha256
|
||||
elif [ -e "sha256sum" ]; then
|
||||
sha256sum -c rom.sha256
|
||||
else
|
||||
echo "Please check the .bin files against rom.sha256"
|
||||
fi
|
||||
echo "#{dest_rom} created!"
|
||||
EOF
|
||||
|
||||
File.write('rom.sha256', shafile)
|
||||
File.write('make_rom.sh', script)
|
||||
|
||||
sh "zip #{distzip} rom.sha256 make_rom.sh"
|
||||
end
|
||||
|
4
no_tape/iiee.defs
Normal file
4
no_tape/iiee.defs
Normal file
@ -0,0 +1,4 @@
|
||||
.include "../common/iiee.defs"
|
||||
|
||||
no_tape = 1
|
||||
|
Loading…
Reference in New Issue
Block a user