Last active
July 24, 2023 20:40
-
-
Save htv04/54f1724887a937304ffd670d4fb37f0f to your computer and use it in GitHub Desktop.
SGDK Startup Code for VASM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; SGDK Startup Code for VASM v1.0 | |
| ; By HTV04 | |
| ; Translated from SEGA Startup Code for the Sozobon C Compiler | |
| ; Written by Paul W. Lee | |
| ; Modified by Charles Coty | |
| ; Modified by Stephane Dallongeville | |
| ; MIT License | |
| ; | |
| ; Copyright (c) 2019 Stephane Dallongeville | |
| ; Copyright (c) 2023 HTV04 | |
| ; | |
| ; Permission is hereby granted, free of charge, to any person obtaining a copy | |
| ; of this software and associated documentation files (the "Software"), to deal | |
| ; in the Software without restriction, including without limitation the rights | |
| ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| ; copies of the Software, and to permit persons to whom the Software is | |
| ; furnished to do so, subject to the following conditions: | |
| ; | |
| ; The above copyright notice and this permission notice shall be included in all | |
| ; copies or substantial portions of the Software. | |
| ; | |
| ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| ; SOFTWARE. | |
| USER_STACK_LENGTH = 512 | |
| UTSK_REGS_LEN = 15*4 | |
| TSK_PEND_FOREVER = -1 | |
| section .text.keepboot | |
| org $00000000 | |
| _Start_Of_Rom: | |
| _Vectors_68K: | |
| dc.l __stack ; Stack address | |
| dc.l _Entry_Point ; Program start address | |
| dc.l _Bus_Error | |
| dc.l _Address_Error | |
| dc.l _Illegal_Instruction | |
| dc.l _Zero_Divide | |
| dc.l _Chk_Instruction | |
| dc.l _Trapv_Instruction | |
| dc.l _Privilege_Violation | |
| dc.l _Trace | |
| dc.l _Line_1010_Emulation | |
| dc.l _Line_1111_Emulation | |
| dc.l _Error_Exception,_Error_Exception,_Error_Exception,_Error_Exception | |
| dc.l _Error_Exception,_Error_Exception,_Error_Exception,_Error_Exception | |
| dc.l _Error_Exception,_Error_Exception,_Error_Exception,_Error_Exception | |
| dc.l _Error_Exception | |
| dc.l _INT | |
| dc.l _EXTINT | |
| dc.l _INT | |
| dc.l hintCaller | |
| dc.l _INT | |
| dc.l _VINT | |
| dc.l _INT | |
| dc.l _trap_0 ; Resume supervisor task | |
| dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT | |
| dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT | |
| dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT | |
| dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT | |
| rom_header:: | |
| incbin "out/rom_head.bin",0,$100 | |
| _Entry_Point: | |
| move #$2700,sr | |
| tst.l $a10008 | |
| bne.s SkipJoyDetect | |
| tst.w $a1000c | |
| SkipJoyDetect: | |
| bne.s SkipSetup | |
| lea Table,a5 | |
| movem.w (a5)+,d5-d7 | |
| movem.l (a5)+,a0-a4 | |
| ; Check Version Number | |
| move.b -$10ff(a1),d0 | |
| andi.b #$0f,d0 | |
| beq.s WrongVersion | |
| ; Sega Security Code (SEGA) | |
| move.l #$53454741,$2f00(a1) | |
| WrongVersion: | |
| ; Read from the control port to cancel any pending read/write command | |
| move.w (a4),d0 | |
| ; Configure a USER_STACK_LENGTH bytes user stack at bottom, and system stack on top of it | |
| move sp,usp | |
| sub #USER_STACK_LENGTH,sp | |
| move.w d7,(a1) | |
| move.w d7,(a2) | |
| ; Jump to initialisation process now... | |
| jmp _start_entry | |
| SkipSetup: | |
| jmp _reset_entry | |
| Table: | |
| dc.w $8000,$3fff,$0100 | |
| dc.l $A00000,$A11100,$A11200,$C00000,$C00004 | |
| ; Interrupt functions | |
| registersDump: | |
| move.l d0,registerState+0 | |
| move.l d1,registerState+4 | |
| move.l d2,registerState+8 | |
| move.l d3,registerState+12 | |
| move.l d4,registerState+16 | |
| move.l d5,registerState+20 | |
| move.l d6,registerState+24 | |
| move.l d7,registerState+28 | |
| move.l a0,registerState+32 | |
| move.l a1,registerState+36 | |
| move.l a2,registerState+40 | |
| move.l a3,registerState+44 | |
| move.l a4,registerState+48 | |
| move.l a5,registerState+52 | |
| move.l a6,registerState+56 | |
| move.l a7,registerState+60 | |
| rts | |
| busAddressErrorDump: | |
| move.w 4(sp),ext1State | |
| move.l 6(sp),addrState | |
| move.w 10(sp),ext2State | |
| move.w 12(sp),srState | |
| move.l 14(sp),pcState | |
| jmp registersDump | |
| exception4WDump: | |
| move.w 4(sp),srState | |
| move.l 6(sp),pcState | |
| move.w 10(sp),ext1State | |
| jmp registersDump | |
| exceptionDump: | |
| move.w 4(sp),srState | |
| move.l 6(sp),pcState | |
| jmp registersDump | |
| _Bus_Error: | |
| jsr busAddressErrorDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l busErrorCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Address_Error: | |
| jsr busAddressErrorDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l addressErrorCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Illegal_Instruction: | |
| jsr exception4WDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l illegalInstCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Zero_Divide: | |
| jsr exceptionDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l zeroDivideCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Chk_Instruction: | |
| jsr exception4WDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l chkInstCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Trapv_Instruction: | |
| jsr exception4WDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l trapvInstCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Privilege_Violation: | |
| jsr exceptionDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l privilegeViolationCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Trace: | |
| jsr exceptionDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l traceCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Line_1010_Emulation: | |
| _Line_1111_Emulation: | |
| jsr exceptionDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l line1x1xCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _Error_Exception: | |
| jsr exceptionDump | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l errorExceptionCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _INT: | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l intCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _EXTINT: | |
| movem.l d0-d1/a0-a1,-(sp) | |
| move.l eintCB,a0 | |
| jsr (a0) | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte | |
| _VINT: | |
| btst #5,(sp) ; Skip context switch if not in user task | |
| bne.s no_user_task | |
| tst.w task_lock | |
| bne.s lock | |
| move.w #0,-(sp) ; TSK_superPend() will return 0 | |
| bra.s unlock ; If lock == 0, supervisor task is not locked | |
| lock: | |
| bcs.s no_user_task ; If lock < 0, super is locked with infinite wait | |
| subq.w #1,task_lock ; Locked with wait, subtract 1 to the frame count | |
| bne.s no_user_task ; And do not unlock if we did not reach 0 | |
| move.w #1,-(sp) ; TSK_superPend() will return 1 | |
| unlock: | |
| ; Save bg task registers (excepting a7, that is stored in usp) | |
| move.l a0,task_regs | |
| lea (task_regs+UTSK_REGS_LEN),a0 | |
| movem.l d0-d7/a1-a6,-(a0) | |
| move.w (sp)+,d0 ; Load return value previously pushed to stack | |
| move.w (sp)+,task_sr ; Pop user task sr and pc, and save them, | |
| move.l (sp)+,task_pc ; so they can be restored later. | |
| movem.l (sp)+,d2-d7/a2-a6 ; Restore non clobberable registers | |
| no_user_task: | |
| ; At this point, we always have in the stack the SR and PC of the task | |
| ; we want to jump after processing the interrupt, that might be the | |
| ; point where we came from (if there is no context switch) or the | |
| ; supervisor task (if we unlocked it). | |
| movem.l d0-d1/a0-a1,-(sp) | |
| ori.w #$0001,intTrace ; in V-Int | |
| addq.l #1,vtimer ; increment frame counter (more a vint counter) | |
| btst #3,VBlankProcess+1 ; PROCESS_XGM_TASK ? (use VBlankProcess+1 as btst is a byte operation) | |
| beq.s no_xgm_task | |
| jsr XGM_doVBlankProcess ; do XGM vblank task | |
| no_xgm_task: | |
| btst #1,VBlankProcess+1 ; PROCESS_BITMAP_TASK ? (use VBlankProcess+1 as btst is a byte operation) | |
| beq.s no_bmp_task | |
| jsr BMP_doVBlankProcess ; do BMP vblank task | |
| no_bmp_task: | |
| move.l vintCB,a0 ; load user callback | |
| jsr (a0) ; call user callback | |
| andi.w #$FFFE,intTrace ; out V-Int | |
| movem.l (sp)+,d0-d1/a0-a1 | |
| rte |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment