mirror of
https://github.com/simonowen/apple1emu.git
synced 2024-12-26 23:29:15 +00:00
631 lines
21 KiB
NASM
631 lines
21 KiB
NASM
; Apple 1 emulator for SAM Coupe, by Simon Owen
|
|
;
|
|
; Version 1.1 (24/8/2008)
|
|
;
|
|
; WWW: http://simonowen.com/sam/apple1emu/
|
|
|
|
base: equ &a000 ; Spare-ish Apple 1 space
|
|
|
|
status: equ &f9 ; Status and extended keyboard port
|
|
lmpr: equ &fa ; Low Memory Page Register
|
|
hmpr: equ &fb ; High Memory Page Register
|
|
vmpr: equ &fc ; Video Memory Page Register
|
|
keyboard: equ &fe ; Keyboard port
|
|
border: equ &fe ; Border port
|
|
|
|
rom0_off: equ %00100000 ; LMPR bit to disable ROM0
|
|
rom1_on: equ %01000000 ; LMPR bit to enable ROM1
|
|
vmpr_mode2: equ %00100000 ; Mode 2 select for VMPR
|
|
|
|
low_page: equ 3 ; LMPR during emulation
|
|
screen_page: equ 5 ; SAM display
|
|
file_page: equ 6 ; File import text page
|
|
|
|
bord_invalid: equ 2 ; Invalid instruction (red)
|
|
|
|
m6502_nmi: equ &fffa ; nmi vector address
|
|
m6502_reset: equ &fffc ; reset vector address
|
|
m6502_int: equ &fffe ; int vector address (also for BRK)
|
|
|
|
getkey: equ &1cab ; SAM ROM key reading (NZ=got key in A, A=0 for no key)
|
|
|
|
|
|
; Apple 1 keyboard and display I/O locations
|
|
|
|
kbd_data: equ &d010 ; keyboard data
|
|
kbd_ctrl: equ &d011 ; keyboard control
|
|
dsp_data: equ &d012 ; display data
|
|
dsp_ctrl: equ &d013 ; display control
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
org base
|
|
dump $
|
|
autoexec
|
|
|
|
start: di
|
|
|
|
ld a,low_page+rom0_off
|
|
out (lmpr),a
|
|
ld a,vmpr_mode2+screen_page
|
|
out (vmpr),a
|
|
ld sp,stack_top
|
|
|
|
call set_sam_attrs ; set the mode 2 attrs so the screen is visible
|
|
call setup_im2 ; enable IM 2
|
|
|
|
reset_loop: ld hl,0
|
|
ld (dsp_data),hl ; display ready
|
|
ld (kbd_data),hl ; no key available
|
|
|
|
ld hl,(m6502_reset) ; start from reset vector
|
|
ld (reg_pc),hl
|
|
ld a,&04 ; interrupts disabled
|
|
ld (reg_p),a
|
|
|
|
ei
|
|
call load_state
|
|
call execute ; GO!
|
|
call save_state
|
|
jr reset_loop
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
; Utility functions
|
|
|
|
; Fill SAM mode 2 display attributes to make the screen visible
|
|
set_sam_attrs: ld a,screen_page+rom0_off
|
|
out (lmpr),a
|
|
|
|
ld hl,&2000
|
|
ld bc,&1844 ; 24 blocks of bright green on black
|
|
clear_lp: ld (hl),c
|
|
inc l
|
|
jr nz,clear_lp
|
|
inc h
|
|
djnz clear_lp
|
|
|
|
ld a,low_page+rom0_off
|
|
out (lmpr),a
|
|
ret
|
|
|
|
; Scroll the screen up 1 row and clear the bottom line
|
|
scroll_screen: ld hl,0
|
|
ld d,h
|
|
ld e,l
|
|
inc h
|
|
ld bc,&1700
|
|
scroll_lp: FOR 32, ldi ; 32 * LDI
|
|
jp pe,scroll_lp
|
|
dec h
|
|
scroll_clr: ld (hl),0
|
|
inc l
|
|
jp nz,scroll_clr
|
|
ret
|
|
|
|
; Advance the cursor 1 character, wrapping and scrolling if necessary
|
|
advance_chr: ld hl,(cursor_xy)
|
|
cp &5f
|
|
jr z,back_chr
|
|
cp &0a
|
|
jr z,advance_line
|
|
cp &0d
|
|
jr z,advance_line
|
|
ld a,l
|
|
add a,6
|
|
ld l,a
|
|
cp &f0
|
|
jr c,no_wrap
|
|
advance_line: ld l,0
|
|
inc h
|
|
ld a,h
|
|
cp &18
|
|
jr nz,no_wrap
|
|
dec h
|
|
exx
|
|
call scroll_screen
|
|
exx
|
|
no_wrap: ld (cursor_xy),hl
|
|
ret
|
|
back_chr: ld a,l
|
|
sub 6
|
|
ld l,a
|
|
jr nc,no_wrap
|
|
ld l,39*6
|
|
ld a,h
|
|
sub 1
|
|
adc a,0
|
|
ld h,a
|
|
jr no_wrap
|
|
|
|
; Map display character from SAM to Apple 1
|
|
map_chr: cp &20
|
|
jr c,invalid_chr
|
|
and %10111111
|
|
xor %01100000
|
|
ret
|
|
invalid_chr: xor a
|
|
ret
|
|
|
|
; Display character in A at current cursor position
|
|
display_chr: add a,a ; * 2
|
|
add a,a ; * 4
|
|
ld l,a
|
|
ld h,0
|
|
add hl,hl ; * 8
|
|
ld de,font_data
|
|
add hl,de
|
|
ld d,mask_data/256
|
|
exx
|
|
ld hl,(cursor_xy)
|
|
ld a,l
|
|
and %00000111
|
|
srl l
|
|
srl l
|
|
srl l
|
|
inc l
|
|
exx
|
|
ld e,a
|
|
exx
|
|
ld de,&0020
|
|
ld b,8
|
|
draw_lp: exx
|
|
ld c,(hl)
|
|
inc l
|
|
xor a
|
|
cp e
|
|
jr z,no_rot
|
|
ld b,e
|
|
rot_lp: srl c
|
|
rra
|
|
djnz rot_lp
|
|
no_rot: ld b,a
|
|
ld a,(de)
|
|
inc e
|
|
exx
|
|
and (hl)
|
|
inc l
|
|
exx
|
|
or c
|
|
ex af,af'
|
|
ld a,(de)
|
|
dec e
|
|
exx
|
|
and (hl)
|
|
exx
|
|
or b
|
|
exx
|
|
ld (hl),a
|
|
dec l
|
|
ex af,af'
|
|
ld (hl),a
|
|
add hl,de
|
|
djnz draw_lp
|
|
ret
|
|
|
|
; LSB=pixel position (0-240), MSB=display row (0-23)
|
|
cursor_xy: defw 0
|
|
|
|
; Map key symbols from SAM to Apple 1
|
|
map_key: cp &0c
|
|
jr z,del_key
|
|
cp &fc
|
|
jr z,tab_key
|
|
cp &80
|
|
jr nc,ignore_key
|
|
cp &61 ; 'a'
|
|
ret c
|
|
cp &7b ; 'z'+1
|
|
ret nc
|
|
and %11011111
|
|
ret
|
|
del_key: ld a,&5f ; Delete -> _
|
|
ret
|
|
tab_key: ld a,&09 ; standard tab
|
|
ret
|
|
invalid_key: ld a,&20 ; space for invalid
|
|
ret
|
|
ignore_key: xor a ; ignore
|
|
ret
|
|
|
|
; Get a type-in key from the imported file
|
|
get_filekey: ld a,file_page+rom0_off
|
|
out (lmpr),a
|
|
|
|
ld hl,(filepos)
|
|
ld a,h
|
|
or l
|
|
or (hl)
|
|
jr z,file_done ; jump if no file
|
|
|
|
file_skip: ld a,(hl) ; fetch next file character
|
|
inc hl
|
|
and a
|
|
jr z,clear_file2 ; clear file at end
|
|
cp &0d ; CR?
|
|
jr z,file_skip ; ignore CR in file
|
|
cp &0a ; LF?
|
|
jr nz,file_done
|
|
ld a,&0d ; convert LF to CR
|
|
file_done: ld (filepos),hl
|
|
ex af,af'
|
|
ld a,screen_page+rom0_off
|
|
out (lmpr),a
|
|
ex af,af'
|
|
and a
|
|
ret
|
|
filepos: defw 0
|
|
|
|
; Clear the file area to disable type-in
|
|
clear_file: ld a,file_page+rom0_off
|
|
out (lmpr),a
|
|
clear_file2: ld hl,0
|
|
ld c,l
|
|
clr_file_lp: ld (hl),c
|
|
inc l
|
|
jr nz,clr_file_lp
|
|
inc h
|
|
bit 7,h
|
|
jr nz,clr_file_lp
|
|
ld h,l
|
|
xor a ; no file character
|
|
jr file_done
|
|
|
|
update_io:
|
|
ld a,&f7
|
|
in a,(status)
|
|
and %00100000
|
|
jr nz,not_esc ; jump if Esc not pressed
|
|
|
|
call clear_file ; Esc cancels type-in mode
|
|
|
|
ld a,&fe
|
|
in a,(keyboard)
|
|
rra
|
|
jr c,not_reset ; unshifted gives chr
|
|
|
|
ld a,&c9 ; RET opcode
|
|
ld (main_loop),a ; return to reset on next instruction
|
|
not_reset:
|
|
jr c,got_key ; unshifted gives chr
|
|
|
|
still_esc: ld a,&f7
|
|
in a,(status)
|
|
and %00100000
|
|
jr z,still_esc ; wait until Esc released
|
|
|
|
ld a,&1b ; Esc character
|
|
jr got_key
|
|
not_esc:
|
|
ld a,&7f
|
|
in a,(keyboard)
|
|
bit 1,a
|
|
jr nz,not_sym
|
|
|
|
ld a,&f7
|
|
in a,(keyboard)
|
|
rra
|
|
ld c,&ff ; line interrupt disable
|
|
jr nc,got_line
|
|
rra
|
|
ld c,88 ; centre of display (312/2-68=88)
|
|
jr c,not_sym
|
|
got_line: ld a,c
|
|
out (status),a ; set or disable line interrupt
|
|
not_sym:
|
|
ld hl,kbd_ctrl
|
|
bit 7,(hl) ; key available?
|
|
jr nz,no_key ; no need to read more yet
|
|
|
|
call get_filekey ; got a type-in key from file?
|
|
jr nz,got_key ; jump if we have
|
|
|
|
skip_key: ld a,&1f+rom1_on
|
|
out (lmpr),a
|
|
call getkey
|
|
ex af,af'
|
|
ld a,screen_page+rom0_off
|
|
out (lmpr),a
|
|
ex af,af'
|
|
jr z,no_key
|
|
call map_key
|
|
and a
|
|
jr z,skip_key
|
|
got_key:
|
|
ld hl,kbd_data
|
|
ld (hl),a
|
|
set 7,(hl) ; bit 7 always set
|
|
inc l
|
|
set 7,(hl) ; key available
|
|
no_key:
|
|
ld hl,dsp_data
|
|
bit 7,(hl) ; display char available?
|
|
jr z,no_char
|
|
res 7,(hl) ; display ready
|
|
ld a,(hl) ; fetch character to display
|
|
and a
|
|
jr z,done_draw
|
|
cp &7f
|
|
jr z,done_draw
|
|
push af
|
|
ld a,&00 ; space
|
|
call display_chr ; erase cursor
|
|
pop af
|
|
cp &5f ; backspace? (underscore)
|
|
jr z,done_draw2 ; if so, no need to process further
|
|
|
|
push af
|
|
call map_chr ; map output from SAM->Apple 1
|
|
call display_chr ; show it
|
|
pop af
|
|
done_draw2: call advance_chr ; advance the cursor position
|
|
ld a,&3f ; cursor block
|
|
call display_chr ; show cursor
|
|
done_draw:
|
|
no_char:
|
|
ret
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
; Interrupt handling
|
|
|
|
setup_im2: ld hl,im2_table
|
|
ld a,im2_jp/256
|
|
im2_fill: ld (hl),a
|
|
inc l
|
|
jr nz,im2_fill
|
|
inc h
|
|
ld (hl),a ; complete the final entry
|
|
ld a,im2_table/256
|
|
ld i,a
|
|
im 2 ; set interrupt mode 2
|
|
ret
|
|
|
|
im2_handler: push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
ex af,af'
|
|
exx
|
|
push af
|
|
push bc
|
|
push de
|
|
push hl
|
|
push ix
|
|
push iy
|
|
|
|
in a,(lmpr)
|
|
push af
|
|
ld a,screen_page+rom0_off
|
|
out (lmpr),a
|
|
|
|
call update_io
|
|
|
|
pop af
|
|
out (lmpr),a
|
|
|
|
pop iy
|
|
pop ix
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
exx
|
|
ex af,af'
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
pop af
|
|
ei
|
|
reti
|
|
|
|
|
|
; IM 2 table must be aligned to 256-byte boundary
|
|
defs -$\256
|
|
im2_table: defs 257
|
|
|
|
; IM 2 vector must have LSB==MSB
|
|
defs $/256-1
|
|
stack_top: ; stack fits nicely in the slack space
|
|
im2_jp: jp im2_handler
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
; 65C02 emulation
|
|
|
|
execute: ld a,&1a ; LD A,(DE)
|
|
ld (ix),a
|
|
jp (ix)
|
|
|
|
|
|
i_undoc_3: inc de ; 3-byte NOP
|
|
i_undoc_2: inc de ; 2-byte NOP
|
|
i_undoc_1:
|
|
; ld a,bord_invalid
|
|
; out (border),a
|
|
jp (ix)
|
|
|
|
|
|
read_write_loop:
|
|
write_loop: ld a,h
|
|
cp &d0 ; I/O area?
|
|
jr z,write_trap
|
|
|
|
zwrite_loop:
|
|
main_loop: ld a,(de) ; 7/7/15 - fetch opcode
|
|
inc de ; 6/7/11 - PC++
|
|
ld l,a ; 4/6/6 - LSB is opcode
|
|
ld h,msb_table/256 ; 7/7/15 - look-up table
|
|
ld h,(hl) ; 7/8/16 - opcode MSB
|
|
jp (hl) ; 4/5/9 - execute!
|
|
; = 35T (official) / 40T (off-screen) / 72T (on-screen)
|
|
|
|
write_trap: ld a,l
|
|
cp &12 ; display char?
|
|
jr z,chr_write
|
|
jp (ix)
|
|
chr_write: set 7,(hl) ; display busy
|
|
jp (ix)
|
|
|
|
read_loop: ld a,h
|
|
cp &d0
|
|
jr z,read_trap
|
|
|
|
ld a,(de) ; fetch opcode
|
|
inc de ; PC++
|
|
ld l,a ; LSB is opcode
|
|
ld h,msb_table/256 ; look-up table
|
|
ld h,(hl) ; opcode MSB
|
|
jp (hl) ; execute!
|
|
|
|
read_trap: ld a,l
|
|
cp &10 ; key read?
|
|
jr z,key_read
|
|
jp (ix)
|
|
key_read: inc l
|
|
res 7,(hl) ; key not available
|
|
jp (ix)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
load_state: ld a,(reg_a)
|
|
ld b,a ; set A
|
|
ld a,(reg_x)
|
|
ld iyh,a ; set X to IYh
|
|
ld a,(reg_y)
|
|
ld iyl,a ; set Y to IYl
|
|
exx
|
|
ld a,(reg_s)
|
|
ld l,a ; set S
|
|
ld h,&01 ; MSB for stack pointer
|
|
ld a,(reg_p)
|
|
ld c,a ; keep safe
|
|
and %00001100 ; keep D and I
|
|
or %00110000 ; force T and B
|
|
ld d,a ; set P
|
|
ld a,c
|
|
and %01000000 ; keep V
|
|
ld e,a ; set V
|
|
ld a,c
|
|
rra ; carry from C
|
|
ex af,af' ; set carry
|
|
ld a,c
|
|
and %10000010 ; keep N Z
|
|
xor %00000010 ; zero for Z
|
|
exx
|
|
ld c,a ; set N Z
|
|
ld de,(reg_pc) ; set PC
|
|
ld ix,main_loop ; decode loop
|
|
ret
|
|
|
|
save_state: ld a,b ; get A
|
|
ld (reg_a),a
|
|
ld a,iyh ; get X from IYh
|
|
ld (reg_x),a
|
|
ld a,iyl ; get Y from IYl
|
|
ld (reg_y),a
|
|
ex af,af' ; carry
|
|
inc c
|
|
dec c ; set N Z
|
|
push af ; save flags
|
|
ex af,af' ; protect carry
|
|
exx
|
|
pop bc
|
|
ld a,c
|
|
and %10000001 ; keep Z80 N and C
|
|
bit 6,c ; check Z80 Z
|
|
jr z,save_nz
|
|
or %00000010 ; set Z
|
|
save_nz: or e ; merge V
|
|
or d ; merge T B D I
|
|
ld (reg_p),a
|
|
ld a,l ; get S
|
|
ld (reg_s),a
|
|
exx
|
|
ld (reg_pc),de
|
|
ret
|
|
|
|
|
|
; During running we keep the 65xx registers in Z80 registers
|
|
; These are used only to hold the state before/after running
|
|
reg_a: defb 0
|
|
reg_p: defb 0
|
|
reg_x: defb 0
|
|
reg_y: defb 0
|
|
reg_s: defb 0
|
|
reg_pc: defw 0
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
defs -$\256
|
|
|
|
msb_table: defb op_00>>8, op_01>>8, op_02>>8, op_03>>8, op_04>>8, op_05>>8, op_06>>8, op_07>>8
|
|
defb op_08>>8, op_09>>8, op_0a>>8, op_0b>>8, op_0c>>8, op_0d>>8, op_0e>>8, op_0f>>8
|
|
defb op_10>>8, op_11>>8, op_12>>8, op_13>>8, op_14>>8, op_15>>8, op_16>>8, op_17>>8
|
|
defb op_18>>8, op_19>>8, op_1a>>8, op_1b>>8, op_1c>>8, op_1d>>8, op_1e>>8, op_1f>>8
|
|
defb op_20>>8, op_21>>8, op_22>>8, op_23>>8, op_24>>8, op_25>>8, op_26>>8, op_27>>8
|
|
defb op_28>>8, op_29>>8, op_2a>>8, op_2b>>8, op_2c>>8, op_2d>>8, op_2e>>8, op_2f>>8
|
|
defb op_30>>8, op_31>>8, op_32>>8, op_33>>8, op_34>>8, op_35>>8, op_36>>8, op_37>>8
|
|
defb op_38>>8, op_39>>8, op_3a>>8, op_3b>>8, op_3c>>8, op_3d>>8, op_3e>>8, op_3f>>8
|
|
defb op_40>>8, op_41>>8, op_42>>8, op_43>>8, op_44>>8, op_45>>8, op_46>>8, op_47>>8
|
|
defb op_48>>8, op_49>>8, op_4a>>8, op_4b>>8, op_4c>>8, op_4d>>8, op_4e>>8, op_4f>>8
|
|
defb op_50>>8, op_51>>8, op_52>>8, op_53>>8, op_54>>8, op_55>>8, op_56>>8, op_57>>8
|
|
defb op_58>>8, op_59>>8, op_5a>>8, op_5b>>8, op_5c>>8, op_5d>>8, op_5e>>8, op_5f>>8
|
|
defb op_60>>8, op_61>>8, op_62>>8, op_63>>8, op_64>>8, op_65>>8, op_66>>8, op_67>>8
|
|
defb op_68>>8, op_69>>8, op_6a>>8, op_6b>>8, op_6c>>8, op_6d>>8, op_6e>>8, op_6f>>8
|
|
defb op_70>>8, op_71>>8, op_72>>8, op_73>>8, op_74>>8, op_75>>8, op_76>>8, op_77>>8
|
|
defb op_78>>8, op_79>>8, op_7a>>8, op_7b>>8, op_7c>>8, op_7d>>8, op_7e>>8, op_7f>>8
|
|
defb op_80>>8, op_81>>8, op_82>>8, op_83>>8, op_84>>8, op_85>>8, op_86>>8, op_87>>8
|
|
defb op_88>>8, op_89>>8, op_8a>>8, op_8b>>8, op_8c>>8, op_8d>>8, op_8e>>8, op_8f>>8
|
|
defb op_90>>8, op_91>>8, op_92>>8, op_93>>8, op_94>>8, op_95>>8, op_96>>8, op_97>>8
|
|
defb op_98>>8, op_99>>8, op_9a>>8, op_9b>>8, op_9c>>8, op_9d>>8, op_9e>>8, op_9f>>8
|
|
defb op_a0>>8, op_a1>>8, op_a2>>8, op_a3>>8, op_a4>>8, op_a5>>8, op_a6>>8, op_a7>>8
|
|
defb op_a8>>8, op_a9>>8, op_aa>>8, op_ab>>8, op_ac>>8, op_ad>>8, op_ae>>8, op_af>>8
|
|
defb op_b0>>8, op_b1>>8, op_b2>>8, op_b3>>8, op_b4>>8, op_b5>>8, op_b6>>8, op_b7>>8
|
|
defb op_b8>>8, op_b9>>8, op_ba>>8, op_bb>>8, op_bc>>8, op_bd>>8, op_be>>8, op_bf>>8
|
|
defb op_c0>>8, op_c1>>8, op_c2>>8, op_c3>>8, op_c4>>8, op_c5>>8, op_c6>>8, op_c7>>8
|
|
defb op_c8>>8, op_c9>>8, op_ca>>8, op_cb>>8, op_cc>>8, op_cd>>8, op_ce>>8, op_cf>>8
|
|
defb op_d0>>8, op_d1>>8, op_d2>>8, op_d3>>8, op_d4>>8, op_d5>>8, op_d6>>8, op_d7>>8
|
|
defb op_d8>>8, op_d9>>8, op_da>>8, op_db>>8, op_dc>>8, op_dd>>8, op_de>>8, op_df>>8
|
|
defb op_e0>>8, op_e1>>8, op_e2>>8, op_e3>>8, op_e4>>8, op_e5>>8, op_e6>>8, op_e7>>8
|
|
defb op_e8>>8, op_e9>>8, op_ea>>8, op_eb>>8, op_ec>>8, op_ed>>8, op_ee>>8, op_ef>>8
|
|
defb op_f0>>8, op_f1>>8, op_f2>>8, op_f3>>8, op_f4>>8, op_f5>>8, op_f6>>8, op_f7>>8
|
|
defb op_f8>>8, op_f9>>8, op_fa>>8, op_fb>>8, op_fc>>8, op_fd>>8, op_fe>>8, op_ff>>8
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
defs -$\256 ; align to 256-byte boundary
|
|
|
|
font_data:
|
|
MDAT "font.bin"
|
|
|
|
mask_data: defb %00000011,%11111111
|
|
defb %11000000,%11111111
|
|
defb %11110000,%00111111
|
|
defb %11111100,%00001111
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
end: equ $
|
|
length: equ end-start
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
; Instruction implementations
|
|
INC "opimpl.inc"
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
; Ken Wessen's custom BASIC+Krusader+Monitor ROM (&e000-&ffff)
|
|
; BRK handler points to mini-monitor in this version
|
|
dump &e000
|
|
MDAT "65C02.rom.bin"
|
|
|
|
; Original Monitor ROM (&ff00-&ffff)
|
|
; If uncommented, this will replace the monitor ROM section from above
|
|
dump &ff00
|
|
MDAT "apple1.rom"
|