PCEAS_Startup_File

From ArchaicPixels: HuC and PCEAS Documentation

Jump to: navigation, search
;
; STARTUP.INC - MagicKit startup code equates and macros
;
; ----
; this block defines names for joypad
; direction and button bits
JOY_I = $01
JOY_II = $02
JOY_SEL = $04
JOY_RUN = $08
JOY_UP = $10
JOY_RIGHT = $20
JOY_DOWN = $40
JOY_LEFT = $80
JOY_TYPE6 = $50
JOY_III = $01
JOY_IV = $02
JOY_V = $04
JOY_VI = $08
JOY_BITI = $0
JOY_BITII = $1
JOY_BITSEL = $2
JOY_BITRUN = $3
JOY_BITUP = $4
JOY_BITRT = $5
JOY_BITDN = $6
JOY_BITLT = $7
JOY_BITIII = $0
JOY_BITIV = $1
JOY_BITV = $2
JOY_BITVI = $3
; ----
; this block defines names for interrupt
; vectors
;
IRQ2 = 0
IRQ1 = 1
TIMER = 2
NMI = 3
VSYNC = 4
HSYNC = 5
SOFT_RESET = 6
; ----
; setvec(num, addr)
; ----
; num, vector number (see defines above)
; addr, address of the new routine
; ----
setvec
.macro
lda \1
ldx #LOW(\2)
ldy #HIGH(\2)
jsr set_intvec
.endm
; ----
; vec_on(num)
; ----
; num, vector to enable
; ----
vec_on
.macro
.if
(\1 = 5)
smb #6,<irq_m
.else
smb \1,<irq_m
.endif
.endm
; ----
; vec_off(num)
; ----
; num, vector to disable
; ----
vec_off
.macro
.if
(\1 = 5)
rmb #6,<irq_m
.else
rmb \1,<irq_m
.endif
.endm
; ----
; vsync([nb])
; ----
; nb, number of frames to be sync'ed on
; ----
vsync
.macro
.if
(\# = 0)
lda #1
.else
lda \1
.endif
jsr wait_vsync
.endm
;===================================================================
;
; STARTUP.ASM - MagicKit standard startup code
;
; first, set MOUSE to default on:
;
SUPPORT_MOUSE
.equ
1
.list
.ifdef
HUC
.include
"huc.inc"
; HUC
.include
"huc_opt.inc"
.endif
; HUC
.include
"standard.inc"
; HUCARD
; ----
; setup flexible boundaries for startup code
; and user program's "main".
;
START_BANK
.equ
0
LIB1_BANK
.equ
START_BANK
LIB2_BANK
.equ
START_BANK+1
.ifdef
HUC
FONT_BANK
.equ
START_BANK+1
.if
(CDROM)
CONST_BANK
.equ
START_BANK+2
DATA_BANK
.equ
START_BANK+3
.else
PSG_BANK
.equ
START_BANK+2
CONST_BANK
.equ
START_BANK+3
DATA_BANK
.equ
START_BANK+4
.endif
.else
; HuC (because of .proc/.endp) does not use MAIN_BANK
MAIN_BANK
.equ
START_BANK+2
.endif
; HUC
; ----
; if FONT_VADDR is not specified, then specify it
; (VRAM address to load font into)
;
.ifndef
FONT_VADDR
FONT_VADDR
.equ
$0800
.endif
; ----
; system variables
;
.zp
zp_ptr1:
.ds
2
.bss
.if
(CDROM)
; CDROM def's in system.inc
.include
"system.inc"
.else
; ie HuCard
.org
$2200
user_jmptbl:
; user interrupt vectors
irq2_jmp:
.ds
2
; IRQ2 (BRK instruction and external IRQ)
irq1_jmp:
.ds
2
; IRQ1 (VDC interrupt)
timer_jmp:
.ds
2
; TIMER
nmi_jmp:
.ds
2
; NMI (unused)
vsync_hook:
.ds
2
; VDC vertical sync routine
hsync_hook:
.ds
2
; VDC horizontal sync rountine
bg_x1:
.ds
2
bg_x2:
.ds
2
bg_y1:
.ds
2
bg_y2:
.ds
2
.org
$2227
joyena:
.ds
1
; soft reset enable (bit 0/pad 1, bit 1/pad2, etc.)
joy:
.ds
5
; 'current' pad values (pad #1-5)
joytrg:
.ds
5
; 'delta' pad values (new keys hit)
joyold:
.ds
5
; 'previous' pad values
.org
$2241
irq_cnt:
.ds
1
; VDC interrupt counter; increased 60 times per second
; reset to zero when vsync() function called
vdc_mwr:
.ds
1
vdc_dcr:
.ds
1
.endif
.org
$2244
scr_mode:
.ds
1
; screen mode and dimensions - set by <ex_scrmod>
scr_w:
.ds
1
scr_h:
.ds
1
.org
$2284
soft_reset:
.ds
2
; soft reset jump loc (run+select)
.if
 !(CDROM)
.include
"sound.inc"
.endif
.org
$2680
vsync_cnt:
.ds
1
; counter for 'wait_vsync' routine
joybuf:
.ds
5
; 'delta' pad values collector
joyhook:
.ds
2
; 'read_joypad' routine hook
joycallback:
.ds
6
; joypad enhanced callback support
disp_cr:
.ds
1
; display control (1 = on, 0 = off)
clock_hh
.ds
1
; system clock, hours since startup (0-255)
clock_mm
.ds
1
; system clock, minutes since startup (0-59)
clock_ss
.ds
1
; system clock, seconds since startup (0-59)
clock_tt
.ds
1
; system clock, ticks (1/60th sec) since startup (0-59)
joy6:
.ds
5
; second byte for 6-button joysticks
joytrg6:
.ds
5
joyold6:
.ds
5
joybuf6:
.ds
5
joytmp:
.ds
5
joytmp6:
.ds
5
.if
(CDROM)
ovl_running
.ds
1
; overlay # that is currently running
cd_super
.ds
1
; Major CDROM version #
irq_storea
.ds
1
; CDROM IRQ-specific handling stuff
irq_storeb
.ds
1
ram_vsync_hndl
.ds
25
ram_hsync_hndl
.ds
25
.endif
; (CDROM)
;±±±[ STARTUP CODE ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; Let's prepare this secondary libray bank first, for use later.
; The reason, as you will see, is because code for a given function
; which sits together in a file, may have things in zero-page,
; bss, LIB1_BANK (ie. START_BANK), and LIB2_BANK
.
;
; The assembler must know beforehand what address etc. to use as a basis
.
;
.data
.bank
LIB2_BANK,"Base Library 2/Font"
.org
$6000
.include
"font.inc"
.code
.bank
LIB2_BANK
.org
$A600
.data
.bank
CONST_BANK,"Constants"
.data
.bank
DATA_BANK,"User Program"
.org
$6000
;
; place overlay array here
; 50 entries, each containing
; 2 bytes for start sector,
; 2 bytes for # sectors
;
ovlarray:
.ds
200
.code
.bank
START_BANK,"Base Library 1"
; A little introduction to the boot sequence:
;
; A HuCard has its origin at bank 0, and is mapped at $E000
; It needs to grab the interrupt vectors at $FFF6 and implement
; implement handlers for them
;
; A CDROM will load at bank $80 ($68 for SCD), and the initial
; loader will be mapped at $4000. The current MagicKit sequence
; also maps $C000 to this same bank. However, the initial boot
; sequence will execute at $4070, proceeding to load additional
; code and data, and then jump to a post-boot section called
; 'init_go'. This is the point at which the loader explicitly
; relinquishes the $4000 segment. It should be noted that there
; are library subroutines loaded as part of this initial segment,
; and those routines are located in the $C000 range as well.
;
; Sectors are loaded, up to and including the first "DATA_BANK",
; where the overlay array is stored - so that the CDROM error
; overlay can be located and executed in the event of a CDROM
; system version mismatch (ie. playing SCD games on CDROM)
;
; A second entry point is defined for overlays that are not
; being booted (ie. they are loaded and executed from another
; overlay). This entry point is at $4000, after the segments
; have all found their natural loading spots (ie. segment $68
; for Super CDROMs). This entry point maps the necessary
; segments and resets the stack, without clearing memory or
; performing other setup chores, and then maps and executes
; _main() to run the module. The user has no choice regarding
; this function, although he can pass values through the global
; variables which main() can use to decide what to do next.
;
; An additional "Hook" area has now been defined at $4028,
; which is used at initial load time, in case a SCD overlay
; program is run on plain CDROM hardware, and the author
; wishes to override the default text error message by
; loading and executing a plain CDROM program instead
;
; ----
; interrupt vectors
.if
 !(CDROM)
.org
$FFF6
.dw
_irq2
.dw
_irq1
.dw
_timer
.dw
_nmi
.dw
_reset
.endif
; !(CDROM)
; ----
; develo startup code
.if
(DEVELO)
.org
$6000
sei
map _reset
jmp _reset
_restart:
cla
; map the CD-ROM system bank
tam #7
jmp $4000
; back to the Develo shell
.endif
; (DEVELO)
; ----
; reset
; ----
; things start here
; ----
; ----
; CDROM re-map library bank
;
;
; overlay entry point
;
; assume MMR0, MMR1, MMR6, MMR7 are set.
; set others & reset stack pointer
;
.if
(CDROM)
.org
$C000
; current overlay number that is running
; this is overwritten by the isolink prgram; the load
; statement must be the first in the block
;
ovlentry:
lda #1
sta ovl_running
lda #CONST_BANK+_bank_base
tam #2
lda #DATA_BANK+_bank_base
tam #3
lda #_call_bank
tam #4
stw #$4000,<__sp
ldx #$ff
txs
map _main
jsr _main
bra *
;
; CDROM error message alternate load entry point
;
.org
$4028
cderr_override:
.db
0
cderr_overlay_num:
.db
0
cdrom_err_load:
; since CDROM program will load into same area in RAM,
; this load routine must be executed from scratch RAM
; re-use the ram interrupt handler areas (not yet initialized)
tii
.load_cd_ovl,
ram_vsync_hndl, 64
jmp ram_vsync_hndl
.load_cd_ovl:
lda cderr_overlay_num
asl A
asl A
tay
lda #DATA_BANK+$80
tam #3
ldx ovlarray,Y++
lda ovlarray,Y++
stz <_cl
; sector (offset from base of track)
sta <_ch
stx <_dl
lda ovlarray,Y
sta <_al
; # sectors
lda #$80
sta <_bl
; bank #
lda #3
sta <_dh
; MPR #
jsr cd_read
cmp #0
bne
.error
lda #$80
tam #2
jmp _boot
.error:
jmp cd_boot
; Can't load - reboot CDROM system card
;
; Proper Boot-time entry point
;
.org
$4070
_boot:
stz $2680
; clear program RAM
tii $2680,$2681,$197F
;
; Note: All CDROM boot loaders will load into MMR $80 region
; regardless of whether they are CD or SCD.
; Here, we will move the information to occupy
; base memory at MMR $68 if appropriate
;
.if
(CDROM = SUPER_CD)
jsr ex_getver
; check if SCD program running
stx cd_super
; on SCD hardware
cpx #3
; don't copy to _bank_base if
bne
.nocopy
; memory doesn't exist there
lda #_bank_base+1
; copy bank 2 to proper location
tam #6
tii $6000,$C000,$2000
tam #3
; FONT_BANK now lives in SCD area ($69 exactly)
lda #_bank_base
; then copy bank 1
tam #6
tii $4000,$C000,$2000
; then load rest of program
.nocopy:
.endif
; (CDROM = SUPER_CD)
.else
; (ie
.
if HuCard...)
.org
$E010
_reset:
sei
; disable interrupts
csh
; select the 7
.16
MHz clock
cld
; clear the decimal flag
ldx #$FF
; initialize the stack pointer
txs
lda #$FF
; map the I/O bank in the first page
tam #0
lda #$F8
; and the RAM bank in the second page
tam #1
stz $2000
; clear all the RAM
tii $2000,$2001,$1FFF
.endif
; (CDROM)
; ----
; initialize the hardware
_init:
.if
(CDROM)
jsr ex_dspoff
jsr ex_rcroff
jsr ex_irqoff
jsr ad_reset
.else
stz timer_ctrl
; init timer
.endif
; (CDROM)
jsr init_psg
; init sound
jsr init_vdc
; init video
lda #$1F
; init joypad
sta joyena
; ----
; initialize interrupt vectors
.if
(CDROM)
jsr ex_dspon
jsr ex_rcron
jsr ex_irqon
.else
ldx #4
; user vector table
cly
.l2:
lda #LOW(_rti)
sta user_jmptbl,Y
iny
lda #HIGH(_rti)
sta user_jmptbl,Y
iny
dex
bne
.l2
stw #_reset,soft_reset
; soft reset
stw #_rts,vsync_hook
; user vsync routine
stw #_rts,hsync_hook
; user hsync routine
lda #$01
; enable interrupts
sta irq_disable
stz irq_status
cli
; ----
; enable display and VSYNC interrupt
vreg #5
lda #$C8
sta <vdc_crl
sta video_data_l
st2 #$00
lda #$01
sta disp_cr
.endif
; (CDROM)
; ----
; init TIA instruction in RAM (fast BLiTter to hardware)
lda #$E3
; TIA instruction opcode
sta _ram_hdwr_tia
lda #$60
; RTS instruction opcode
sta _ram_hdwr_tia_rts
; ----
; init random number generator
lda #1
jsr wait_vsync
; wait for one frame & randomize _rndseed
stw #$03E7,<_cx
; set random seed
stw _rndseed,<_dx
jsr srand
.if
(CDROM)
.if
(CDROM = SUPER_CD)
lda cd_super
; don't load the program if SCD
cmp #3
; program not running on SCD hrdware
beq loadprog
lda cderr_override
lbeq dontloadprog
jmp cdrom_err_load
.endif
; (SUPER_CD)
; ----
; load program
; ----
; CL/CH/DL = sector address
; DH = load mode - bank mode ($6000-$7FFF)
; BL = bank index
; AL = number of sectors
;
loadprog:
lda ovlentry+1
; current overlay (as written by ISOLINK)
cmp #1
; is it initial overlay ?
lbne _init_go
; if not initial overlay, somebody else already
; loaded us completely; do not try to load remainder
; (ie
.
executing CDROM error overlay)
stz <_cl
; initial boot doesn't load complete program;
stz <_ch
; prepare to load remainder
lda #10
; 10th sector (0-1 are boot;
; 2-9 are this library...)
sta <_dl
lda #3
; load mode (consecutive banks; use MPR 3)
sta <_dh
stw #(_bank_base+2),<_bx
; 2 banks are boot/base library
stw #(_nb_bank-2)*4,<_ax
jsr cd_read
cmp #$00
lbeq _init_go
; ----
jmp cd_boot
; reset
; This is the point in the CDROM loader where the code no longer
; executes in the $4000 segment, in favour of using the $C000
; segment (also used for the library subroutines)
.org
$C130
; These routines will be run from RAM @ $2000 so we
; need to count bytes to determine how much to xfer
; (The total is 24 bytes, but we copy 25)
.bank
LIB2_BANK
vsync_irq_ramhndlr:
php
; 1 byte
pha
; 1
tma #6
; 2
sta irq_storea
; 3
lda #BANK(_vsync_hndl)
; 2
tam #6
; 2
pla
; 1
pha
; 1
jsr _vsync_hndl
; 3
lda irq_storea
; 3
tam #6
; 2
pla
; 1
plp
; 1
rts
; 1 = 24 bytes
hsync_irq_ramhndlr:
php
; 1 byte
pha
; 1
tma #6
; 2
sta irq_storeb
; 3
lda #BANK(_hsync_hndl)
; 2
tam #6
; 2
pla
; 1
pha
; 1
jsr _hsync_hndl
; 3
lda irq_storeb
; 3
tam #6
; 2
pla
; 1
plp
; 1
rts
; 1 = 24 bytes
.bank
LIB1_BANK
_init_go:
.if
(CDROM = SUPER_CD)
dontloadprog:
.endif
.endif
; (CDROM)
; ----
; jump to main routine
; ----
; load font
.ifdef
HUC
stw #$4000,<__sp
; init stack ptr first
stw #FONT_VADDR,<_di
; Load Font @ VRAM addr
;
; this section of font loading was stolen
; from _load_default_font because the default
; FONT segment number is not yet guaranteed
; if the SCD is being run on a plain CDROM system
; so we need to trick the segment pointer
; with a reliable one
;
__ldw <_di
; stolen from _load_default_font
; because segment# default not reliable
jsr _set_font_addr
; set VRAM
.if
(CDROM)
stb #FONT_BANK+$80,<_bl
; guarantee FONT_BANK even if
; SCD on regular CDROM system
.else
stb #FONT_BANK+_bank_base,<_bl
.endif
stb #96,<_cl
stb _font_color+1,<_ah
lda _font_color
bne
.fntld
inc A
.fntld:
sta <_al
clx
lda font_table,X
sta <_si
inx
lda font_table,X
sta <_si+1
; Now, load the font
;
; Note for CDROM/Super CDROM:
;
; The 'REAL' mapping for the lib2_load_font function
; maybe doesn't exist yet (we are executing from bank $80,
; not from $68 if it's a Super CDROM)
;
; So we must map the version at bank ($80 + LIB2_BANK)
; before executing it
.
We remap the bank after completion,
; 'just in case'
.if
(CDROM)
tma #page(lib2_load_font)
pha
lda #LIB2_BANK+$80
tam #page(lib2_load_font)
jsr lib2_load_font
pla
tam #page(lib2_load_font)
.else
jsr load_font
.endif
;
; END stolen font-load
;
jsr _cls
stz color_reg
; set color #0 = 0/0/0 rgb
stz color_reg+1
stz color_data
stz color_data+1
lda #1
; set color #1 = 7/7/7 rgb
sta color_reg
stz color_reg+1
ldx #$ff
stx color_data
sta color_data+1
; ----
; Super CDROM error message
; ----
.if
(CDROM)
.if
(CDROM = SUPER_CD)
lda cd_super
cmp #3
lbeq
.ok
; SCD running on Super system
lda #FONT_BANK+$80
; guarantee FONT_BANK even if
; SCD on regular CDROM system
tam #PAGE(scdmsg1)
__ldwi scdmsg1
__phw 2,2
__ldwi $0180
call _put_string
.2
__ldwi scdmsg2
__phw 2,2
__ldwi $0200
call _put_string
.2
__ldwi scdmsg3
__phw 2,2
__ldwi $0383
call _put_string
.2
__ldwi scdmsg4
__phw 2,2
__ldwi $0403
call _put_string
.2
bra *
; otherwise loop on blank screen
.bank
LIB2_BANK
scdmsg1:
.db
"This game was written for the"
.db
0
scdmsg2:
.db
"PC Engine Super CDROM System"
.db
0
scdmsg3:
.db
"Please use a PC Engine"
.db
0
scdmsg4:
.db
"Super CDROM System card"
.db
0
.bank
LIB1_BANK
.ok:
.endif
; (CDROM = SUPER_CD)
.endif
; (CDROM)
.endif
; (HUC)
.ifdef
SUPPORT_MOUSE
jsr mousinit
; check existence of mouse
.endif
; SUPPORT_MOUSE
.if
(CDROM)
; Now, install the RAM-based version of the
; interrupt-handlers and activate them
tma #page(vsync_irq_ramhndlr)
pha
lda #bank(vsync_irq_ramhndlr)
tam #page(vsync_irq_ramhndlr)
tii vsync_irq_ramhndlr,ram_vsync_hndl,25
tii hsync_irq_ramhndlr,ram_hsync_hndl,25
pla
tam #page(vsync_irq_ramhndlr)
stw #ram_vsync_hndl,vsync_hook
; set VSYNC handler
smb #4,<irq_m
; enable new code
smb #5,<irq_m
; disable system card code
stw #ram_hsync_hndl,hsync_hook
; set HSYNC handler
smb #6,<irq_m
; enable new code
smb #7,<irq_m
; disable system card code
.endif
; (CDROM)
.ifdef
HUC
; ----
; Map the final stuff before executing main()
; ----
lda #CONST_BANK+_bank_base
; map string constants bank
tam #2
; (ie
.
$4000-$5FFF)
lda #_call_bank
; map call bank
tam #4
; (ie
.
$8000-$9FFF)
; ---
.if
(CDROM)
lda #1
; first overlay to run at boot time
sta ovl_running
; store for later use
.endif
; ---
stz clock_hh
; clear clock
stz clock_mm
stz clock_ss
stz clock_tt
map _main
jsr _main
; go!
bra *
.else
map main
jmp main
.endif
; HUC
; ----
; system
; ----
; give back control to the Develo system
; ----
.if
(DEVELO)
_system:
sei
csh
cld
ldx #$FF
; stack
txs
lda #$FF
; I/O bank
tam #0
lda #$F8
; RAM bank
tam #1
lda #$80
; Develo Bank
tam #2
tma #7
; startup code bank
tam #3
; ----
; re-initialize the machine
;
stz $2000
; clear RAM
tii $2000,$2001,$1FFF
stz timer_ctrl
; init timer
jsr init_psg
; init sound
jsr init_vdc
; init video
lda #$1F
; init joypad
sta joyena
lda #$07
; set interrupt mask
sta irq_disable
stz irq_status
; reset timer interrupt
lda #$80
; disable sound driver
sta <$20E7
st0 #5
; enable display and vsync interrupt
lda #$C8
sta <vdc_crl
sta video_data_l
jmp _restart
; restart
.endif
; (DEVELO)
;±±±[ INTERRUPT CODE ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
_rts:
rts
_rti:
rti
; ----
; irq2
; ----
; IRQ2 interrupt handler
; ----
.if
 !(CDROM)
_irq2:
bbs0 <irq_m,
.user
rti
.user:
jmp [irq2_jmp]
.endif
; !(CDROM)
; ----
; irq1
; ----
; VDC interrupt handler
; ----
.if
 !(CDROM)
_irq1:
bbs1 <irq_m,user_irq1
; jump to the user irq1 vector if bit set
; --
pha
; save registers
phx
phy
; --
lda video_reg
; get VDC status register
sta <vdc_sr
; save a copy
; ----
; vsync interrupt
;
.vsync:
bbr5 <vdc_sr,
.hsync
; --
inc irq_cnt
; increment IRQ counter
; --
st0 #5
; update display control (bg/sp)
lda <vdc_crl
sta video_data_l
; --
bbs5 <irq_m,
.l3
; --
jsr _vsync_hndl
; --
.l3:
bbr4 <irq_m,
.l4
jsr user_vsync
; call user vsync routine
.l4:
; ----
; hsync interrupt
;
.hsync:
bbr2 <vdc_sr,
.exit
bbs7 <irq_m,
.l5
; --
jsr _hsync_hndl
; --
.l5:
bbr6 <irq_m,
.exit
jsr user_hsync
; call user handler
; ----
; exit interrupt
;
.exit:
lda <vdc_reg
; restore VDC register index
sta video_reg
; --
ply
plx
pla
rti
; ----
; user routine hooks
;
user_irq1:
jmp [irq1_jmp]
user_hsync:
jmp [hsync_hook]
user_vsync:
jmp [vsync_hook]
.endif
; !(CDROM)
; ----
; _vsync_hndl
; ----
; Handle VSYNC interrupts
; ----
_vsync_hndl:
.if
 !(CDROM)
ldx disp_cr
; check display state (on/off)
bne
.l1
and #$3F
; disable display
st0 #5
; update display control (bg/sp)
sta video_data_l
bra
.l2
; --
.endif
.l1:
jsr rcr_init
; init display list
.l2:
st0 #7
; scrolling
stw bg_x1,video_data
st0 #8
stw bg_y1,video_data
; --
lda clock_tt
; keep track of time
inc A
cmp #60
bne
.lcltt
lda clock_ss
inc A
cmp #60
bne
.lclss
lda clock_mm
inc A
cmp #60
bne
.lclmm
inc clock_hh
cla
.lclmm:
sta clock_mm
cla
.lclss:
sta clock_ss
cla
.lcltt:
sta clock_tt
; --
.if
(CDROM)
jsr ex_colorcmd
inc rndseed
jsr randomize
lda <$e7
cmp #$01
bne
.skip_psg
jsr psg_driver
.skip_psg:
.endif
.ifdef
SUPPORT_MOUSE
lda msflag
; if mouse supported, and exists
beq
.l3
; then read mouse instead of pad
jsr mousread
bra
.out
.endif
; SUPPORT_MOUSE
.l3:
jsr read_joypad
; else read joypad
.out:
rts
; ----
; _hsync_hndl
; ----
; Handle HSYNC interrupts
; ----
; ----
; hsync scrolling handler
;
_hsync_hndl:
ldy s_idx
bpl
.r1
; --
lda <vdc_crl
and #$3F
sta <vdc_crl
stz s_idx
ldx s_list
lda s_top,X
jsr rcr5
rts
; --
.r1:
ldx s_list,Y
lda <vdc_crl
and #$3F
ora s_cr,X
sta <vdc_crl
; --
jsr rcr_set
; --
lda s_top,X
cmp #$FF
beq
.out
; --
st0 #7
lda s_xl,X
ldy s_xh,X
sta video_data_l
sty video_data_h
st0 #8
lda s_yl,X
ldy s_yh,X
sub #1
bcs
.r2
dey
.r2:
sta video_data_l
sty video_data_h
.out:
rts
; ----
; init display list
;
rcr_init:
maplibfunc build_disp_list
bcs
.r3
rts
; --
.r3:
smb #7,<vdc_crl
lda #$FF
sta s_idx
ldx s_list
ldy s_top,X
cpy #$FF
bne rcr5
; --
ldy s_xl,X
sty bg_x1
ldy s_xh,X
sty bg_x1+1
ldy s_yl,X
sty bg_y1
ldy s_yh,X
sty bg_y1+1
stz s_idx
bra rcr5
; ----
; program scanline interrupt
;
rcr_set:
iny
sty s_idx
lda s_list,Y
tay
lda s_top,Y
cmp scr_height
bhs rcr6
cmp s_bottom,X
blo rcr5
; --
lda s_bottom,X
rcr4: dec A
pha
lda #$F0
sta s_bottom,X
stz s_cr,X
dec s_idx
pla
; --
rcr5:
st0 #6
; set scanline counter
add #64
sta video_data_l
cla
adc #0
sta video_data_h
bra __rcr_on
;--
rcr6: lda s_bottom,X
cmp scr_height
blo rcr4
bra __rcr_off
; ----
; rcr_on
; ----
; enable scanline interrupt
; ----
rcr_on:
_rcr_on:
lda #5
sta <vdc_reg
__rcr_on:
st0 #5
lda <vdc_crl
ora #$04
sta <vdc_crl
sta video_data_l
rts
; ----
; rcr_off
; ----
; disable scanline interrupt
; ----
rcr_off:
_rcr_off:
lda #5
sta <vdc_reg
__rcr_off:
st0 #5
lda <vdc_crl
and #$FB
sta <vdc_crl
sta video_data_l
rts
; ----
; timer
; ----
; timer interrupt handler
; ----
.if
 !(CDROM)
_timer_user:
jmp [timer_jmp]
_timer:
bbs2 <irq_m,_timer_user
pha
phx
phy
sta irq_status
; acknowledge interrupt
lda <psg_irqflag
; is IRQ being serviced ?
bne
.exit
inc <psg_irqflag
; IRQ being serviced
cli
; but allow other interrupts to be processed
lda <psg_inhibit
; if sound off, don't bother
bne
.exit2
bsr psg_driver
; do all sound-related stuff
.exit2:
stz <psg_irqflag
; allow IRQ processing again
.exit:
ply
plx
pla
rti
psg_driver:
tma #page(psg_drive)
; map out the code segment
pha
lda #bank(psg_drive)
tam #page(psg_drive)
tma #4
; save data banks
pha
tma #3
pha
lda psg_bank1
; map PSG data banks
tam #3
lda psg_bank2
tam #4
jsr psg_drive
lda psg_tempo
bmi
.noreset
sta timer_cnt
ora #$80
sta psg_tempo
.noreset:
pla
; restore data banks
tam #3
pla
tam #4
pla
tam #page(psg_drive)
; restore code bank
rts
.endif
; !(CDROM)
; ----
; nmi
; ----
; NMI interrupt handler
; ----
.if
 !(CDROM)
_nmi:
bbs3 <irq_m,
.user
rti
.user:
jmp [nmi_jmp]
.endif
; !(CDROM)
;±±[ DATA ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; ----
; font
; ----
.ifdef
HUC
font_table:
.dw
font_1
.dw
font_2
.dw
font_1
.dw
font_1
.endif
; HUC
;±±[ LIBRARY ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; ----
; standard library
; ----
.include
"library
.asm"
.include
"scroll
.asm"
.include
"math
.asm"
.ifdef
HUC
.include
"huc
.asm"
.include
"huc_gfx
.asm"
.include
"huc_math
.asm"
.include
"huc_bram
.asm"
.include
"huc_misc
.asm"
.endif
; HUC
.ifdef
SUPPORT_MOUSE
.include
"mouse
.asm"
.endif
; SUPPORT_MOUSE
.if
(CDROM)
.include
"cdrom
.asm"
.else
.include
"sound
.asm"
.endif
; CDROM
; ----
; disp_on
; ----
; enable display
; ----
.ifdef
HUC
_disp_on:
ldx disp_cr
lda #1
sta disp_cr
cla
rts
.else
disp_on:
lda #1
sta disp_cr
rts
.endif
; HUC
; ----
; disp_off
; ----
; disable display
; ----
.ifdef
HUC
_disp_off:
ldx disp_cr
stz disp_cr
cla
rts
.else
disp_off:
stz disp_cr
rts
.endif
; HUC
; ----
; set_intvec
; ----
; set interrupt vector
; ----
; IN : A = vector number
; 0 IRQ2
; 1 IRQ1 (VDC)
; 2 TIMER
; 3 NMI
; 4 VSYNC
; 5 HSYNC
; 6 SOFT RESET (RUN + SELECT)
; X = vector address low byte
; Y = " " high byte
; ----
.if
 !(CDROM)
set_intvec:
php
sei
cmp #6
blo
.vector
bne
.exit
.reset:
stx soft_reset
sty soft_reset+1
bra
.exit
.vector:
pha
asl A
sax
sta user_jmptbl,X
inx
tya
sta user_jmptbl,X
pla
.exit:
plp
rts
.endif
; !(CDROM)
; ----
; wait_vsync
; ----
; wait the next vsync
; ----
; IN : A = number of frames to be sync'ed on
; ----
; OUT: A = number of elapsed frames since last call
; ----
wait_vsync:
bbr1 <irq_m,
.l1
cla
; return immediately if IRQ1 is redirected
.ifdef
HUC
clx
.endif
rts
.l1:
sei
; disable interrupts
cmp irq_cnt
; calculate how many frames to wait
beq
.l2
bhs
.l3
lda irq_cnt
.l2:
inc A
.l3:
sub irq_cnt
sta vsync_cnt
cli
; re-enable interrupts
.l4:
lda irq_cnt
; wait loop
.l5:
incw _rndseed
cmp irq_cnt
beq
.l5
dec vsync_cnt
bne
.l4
stz irq_cnt
; reset system interrupt counter
inc A
; return number of elapsed frames
.ifndef
HUC
rts
.else
; ----
; callback support
pha
lda joycallback
; callback valid?
bpl
.t3
bit #$01
bne
.t3
lda joycallback+1
; get events for all the
beq
.t3
; selected joypads
sta <_al
cly
cla
.t1:
lsr <_al
bcc
.t2
ora joybuf,Y
.t2:
iny
cpy #5
blo
.t1
and joycallback+2
; compare with requested state
beq
.t3
inc joycallback
; lock callback feature
tax
; call user routine
tma #5
pha
lda joycallback+3
tam #5
cla
jsr
.callback
pla
tam #5
dec joycallback
; unlock
; --
.t3:
plx
cla
rts
; ----
; user routine callback
;
.callback:
jmp [joycallback+4]
.endif
; ndef HUC
.include
"joypad.asm"
; read joypad values
;±±[ USER PROGRAM ]±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
; .nomlist
; .list
;...
; .endif
Personal tools