143 lines
2.7 KiB
ArmAsm
143 lines
2.7 KiB
ArmAsm
; Common routines and runtime
|
|
|
|
; Must be defined by target-specific runtime:
|
|
;
|
|
; init_runtime: ; target-specific inits
|
|
; std_print: ; default routine to print char A
|
|
; post_exit: ; called at end of std_exit
|
|
; report_byte: ; report A to user
|
|
|
|
.define RUNTIME_INCLUDED 1
|
|
|
|
.ifndef bss
|
|
; address of next normal variable
|
|
.define bss $D800
|
|
.endif
|
|
|
|
.ifndef dp
|
|
; address of next direct-page ($FFxx) variable
|
|
.define dp $FF80
|
|
.endif
|
|
|
|
; DMG/CGB hardware identifier
|
|
.define gb_id_cgb $10 ; mask for testing CGB bit
|
|
.define gb_id_devcart $04 ; mask for testing "on devcart" bit
|
|
|
|
.define gb_id bss
|
|
.redefine bss bss+1
|
|
|
|
; Stack is normally here
|
|
.define std_stack $DFFF
|
|
|
|
; Copies $1000 bytes from HL to $C000, then jumps to it.
|
|
; A is preserved for jumped-to code.
|
|
copy_to_wram_then_run:
|
|
ld b,a
|
|
|
|
ld de,$C000
|
|
ld c,$10
|
|
- ldi a,(hl)
|
|
ld (de),a
|
|
inc e
|
|
jr nz,-
|
|
inc d
|
|
dec c
|
|
jr nz,-
|
|
|
|
ld a,b
|
|
jp $C000
|
|
|
|
.ifndef CUSTOM_RESET
|
|
reset:
|
|
; Run code from $C000, as is done on devcart. This
|
|
; ensures minimal difference in how it behaves.
|
|
ld hl,$4000
|
|
jp copy_to_wram_then_run
|
|
|
|
.bank 1 slot 1
|
|
.org $0 ; otherwise wla pads with lots of zeroes
|
|
jp std_reset
|
|
.endif
|
|
|
|
; Common routines
|
|
.include "gb.inc"
|
|
.include "macros.inc"
|
|
.include "delay.s"
|
|
.include "crc.s"
|
|
.include "printing.s"
|
|
.include "numbers.s"
|
|
.include "testing.s"
|
|
|
|
; Sets up hardware and runs main
|
|
std_reset:
|
|
|
|
; Init hardware
|
|
di
|
|
ld sp,std_stack
|
|
|
|
; Save DMG/CGB id
|
|
ld (gb_id),a
|
|
|
|
; Init hardware
|
|
.ifndef BUILD_GBS
|
|
wreg TAC,$00
|
|
wreg IF,$00
|
|
wreg IE,$00
|
|
.endif
|
|
|
|
wreg NR52,0 ; sound off
|
|
wreg NR52,$80 ; sound on
|
|
wreg NR51,$FF ; mono
|
|
wreg NR50,$77 ; volume
|
|
|
|
; TODO: clear all memory?
|
|
|
|
ld hl,std_print
|
|
call init_printing
|
|
call init_testing
|
|
call init_runtime
|
|
call reset_crc ; in case init_runtime prints anything
|
|
|
|
delay_msec 250
|
|
|
|
; Run user code
|
|
call main
|
|
|
|
; Default is to successful exit
|
|
ld a,0
|
|
jp exit
|
|
|
|
|
|
; Exits code and reports value of A
|
|
exit:
|
|
ld sp,std_stack
|
|
push af
|
|
call +
|
|
pop af
|
|
jp post_exit
|
|
|
|
+ push af
|
|
call print_newline
|
|
call show_printing
|
|
pop af
|
|
|
|
; Report exit status
|
|
cp 1
|
|
|
|
; 0: ""
|
|
ret c
|
|
|
|
; 1: "Failed"
|
|
jr nz,+
|
|
print_str "Failed",newline
|
|
ret
|
|
|
|
; n: "Failed #n"
|
|
+ print_str "Failed #"
|
|
call print_dec
|
|
call print_newline
|
|
ret
|
|
|
|
; returnOrg puts this code AFTER user code.
|
|
.section "runtime" returnOrg
|