SecondBasic is a basic cross-compiler forked from BasiEgaXorz (both targeting Sega Megadrive), which can "Menu:Run:Compile to ASM", and "Menu:View:ASM Output"
so,
Code: Select all
For i&=131072 To 163839
Poke i&,Rnd(255)
Next
Code: Select all
include 'Z:\mnt\sda3\opt\wine\development\secondbasic\work\basic.lib'
jsr ___XGM_INIT_DRIVER
move.l #131072, d0
move.l d0, (__LONG_I)
__SBFORSTART_0:
move.l (__LONG_I), d0
move.l d0, d6
movem.l d0/d1/d4, -(a7)
move.l d2, -(a7)
move.l #255, d0
move.l (a7)+, d2
jsr GenRandom
move.w d0, d2
movem.l (a7)+, d0/d1/d4
moveq #0, d0
move.w d2, d0
move.l d6, a0
move.b d0, (a0)
__SBCONTFOR_0:
move.l #163839, d0
cmp.l (__LONG_I), d0
beq __SBFOREND_0
move.l #1, d0
add.l d0, (__LONG_I)
jmp __SBFORSTART_0
__SBFOREND_0:
jmp __sbsforever
___XGM_INIT_DRIVER:
move.l #64,d0
move.l d0,(__LONG_pcmid)
move.l #0, d0
move.w d0, (__INTEGER_xgmReady)
move.w #$100,($A11100) ; Send the Z80 a bus request.
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
MOVE.L #(Z80drv_end-Z80drv),d0
lea Z80drv,a0
MOVE.L #$A00000,a1
@loop:
MOVE.B (a0)+, (a1)+
dbra d0, @loop ; load driver
move.l #$A01C00,a0 ; point to Z80 sample id table (first entry = silent sample)
move.l #NULLpcm,d0 ; d0 = silent sample
lsr.l #8,d0
move.b d0,(a0)+ ; sample address
lsr.l #8,d0
move.b d0,(a0)+
move.b #$01,(a0)+ ; sample length
move.b #$00,(a0)
move.w #$000,($A11200) ; Start Z80 Reset
move.w #$000,($A11100) ; release the Z80 bus
move.l #$A00102,a0 ; point to status
@test_ready:
move.w #100,d0 ;
@wait:
dbra d0, @wait ; wait a bit
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200) ; End Z80 Reset
@z80_wait2:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait2 ; not yet, wait...
move.b (a0),d0
move.w #$000,($A11100) ; release the Z80 bus
btst #7,d0 ; not yet ready
beq @test_ready
move.l d0,d2
move.w (__INTEGER_VDP_CTRL),d2
btst.l #0,d2
sne d2
and.l #1,d2
moveq #0, d0
move.w d2,d0
tst.b d0
beq XGM_JUMP_7
move.l a5,(a5)+
move.l a3,(a5)+
move.l a5,a3
move.l #50,d0
move.l d0,(a5)+
jsr __SBSUB_xgm_setMusicTempo
jmp XGM_SKIP_7
XGM_JUMP_7:
move.l a5,(a5)+
move.l a3,(a5)+
move.l a5,a3
move.l #60,d0
move.l d0,(a5)+
jsr __SBSUB_xgm_setMusicTempo
XGM_SKIP_7:
move.l #0,d0
move.w d0,(__INTEGER_xgmTempoCnt)
move.l #1,d0
move.w d0,(__INTEGER_xgmReady)
moveq #0, d2
rts
__FUNC_xgm_vintProcess_PUSH:
moveq #0, d0
move.w (__INTEGER_xgmTempoCnt),d0
move.w d0,(__INTEGER_xgmcnt)
moveq #0, d0
move.w (__INTEGER_xgmTempoDef),d0
move.w d0,(__integer_xgmstp)
move.l #0, d0
move.w d0,(__integer_xgmnum)
__XGMWHILE_JUMP_0
addq.w #1,(__integer_xgmnum)
moveq #0, d0
move.w (__INTEGER_xgmcnt),d0
add.w (__integer_xgmstp),d0
move.w d0,(__INTEGER_xgmcnt)
__XGMWHILE_JUMP3_0:
moveq #0, d0
move.w (__INTEGER_xgmcnt),d0
move.l d0,d1
move.l #0,d0
cmp.w d1,d0
scc d0
and.l #1,d0
tst.b d0
bne __XGMWHILE_JUMP_0
__XGMWHILE_JUMP2_0:
moveq #0, d0
move.w (__INTEGER_xgmcnt),d0
sub.w (__INTEGER_xgmTempo),d0
move.w d0,(__INTEGER_xgmTempoCnt)
__XGMWHILE_JUMP_1
move.l #256,d0
move.w d0,(__INTEGER_Z80_HALT)
__XGMWHILE_JUMP_2
__XGMWHILE_JUMP3_2:
move.w (__INTEGER_Z80_HALT),d2
btst.l #8,d2
sne d2
and.l #1,d2
moveq #0, d0
move.w d2,d0
tst.b d0
bne __XGMWHILE_JUMP_2
__XGMWHILE_JUMP2_2:
movem.l d0/d1/d4,-(a7)
move.l d2,-(a7)
move.l #10486020,d0
add.l #14,d0
move.l (a7)+,d2
move.l d0,a0
clr.l d2
move.b (a0),d2
movem.l (a7)+,d0/d1/d4
moveq #0, d0
move.w d2,d0
move.l d0,d1
move.l #0,d0
cmp.w d1,d0
seq d0
and.l #1,d0
tst.b d0
beq XGMIF_JUMP_8
jmp __XGMWHILE_JUMP2_1
XGMIF_JUMP_8:
move.l #0,d0
move.w d0,(__INTEGER_Z80_HALT)
movem.l d0-d3,-(sp)
movem.l (sp)+,d0-d3
__XGMWHILE_JUMP3_1:
jmp __XGMWHILE_JUMP_1
__XGMWHILE_JUMP2_1:
move.l #10486020,d0
add.l #15,d0
move.l d0,d6
moveq #0, d0
move.w (__integer_xgmnum),d0
move.l d6,a0
move.b d0,(a0)
move.l #0,d0
move.w d0,(__INTEGER_Z80_HALT)
move.l -(a5),a3
move.l -(a5),a5
moveq #0,d2
clr.w (a5)
rts
__SBSUB_xgm_vintProcess:
move.w (__INTEGER_xgmcnt),-(a7)
clr.w (__INTEGER_xgmcnt)
move.w (__integer_xgmstp),-(a7)
clr.w (__integer_xgmstp)
move.w (__integer_xgmnum),-(a7)
clr.w (__integer_xgmnum)
jsr __FUNC_xgm_vintProcess_PUSH
move.w (a7)+,(__integer_xgmnum)
move.w (a7)+,(__integer_xgmstp)
move.w (a7)+,(__INTEGER_xgmcnt)
rts
__FUNC_xgm_setMusicTempo_PUSH:
moveq #0, d0
move.w (__integer_xgmvalue),d0
move.w d0,(__INTEGER_xgmTempo)
move.w (__INTEGER_VDP_CTRL),d2
btst.l #0,d2
sne d2
and.l #1,d2
moveq #0, d0
move.w d2,d0
tst.b d0
beq XGMIF_JUMP_9
move.l #50,d0
move.w d0,(__INTEGER_xgmTempoDef)
jmp XGMIF_SKIP_9
XGMIF_JUMP_9:
move.l #60,d0
move.w d0,(__INTEGER_xgmTempoDef)
XGMIF_SKIP_9:
move.l -(a5),a3
move.l -(a5),a5
moveq #0,d2
clr.w (a5)
rts
__SBSUB_xgm_setMusicTempo:
move.w (__integer_xgmvalue),-(a7)
clr.w (__integer_xgmvalue)
move.l a3,a2
lea 2(a2),a2
move.w (a2)+,(__integer_xgmvalue)
move.l a3,a5
jsr __FUNC_xgm_setMusicTempo_PUSH
move.w (a7)+,(__integer_xgmvalue)
rts
__SBFUNC_xgm_isPlayingMusic:
move.l a3,a5
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
move.b ($A00102),d0 ; get channel playing status
andi.l #$40,d0 ; keep play XGM bit only
move.w #$000,($A11100) ; release the Z80 bus
move.l d0,d2
move.l -(a5),a3
move.l -(a5),a5
clr.w (a5)
rts
__SBSUB_xgm_startPlayMusic:
move.l a3,a5
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
move.l a3,a0 ; a0 = reserved $FC array for sample id table
moveq #0,d0
@loop: ; prepare sample id table
move.w d0,d1
add.w d1,d1
add.w d1,d1
moveq #0,d2
move.w 0(a1,d1.w),d2 ; get sample addr in song bank table
rol.w #8,d2 ; revert endianess
cmp.w #$FFFF,d2 ; is null sample ?
bne @not_null
move.l NULLpcm,d2
jmp @addr_done
@not_null:
addq.w #1,d2 ; add offset
lsl.l #8,d2 ; pass to 24 bits
add.l a1,d2 ; transform to absolute address
@addr_done
lsr.l #8,d2 ; get high byte
move.b d2,0(a0,d1.w)
lsr.w #8,d2 ; get low byte
move.b d2,1(a0,d1.w)
move.w 2(a1,d1.w),2(a0,d1.w) ; copy sample length
addq.w #1,d0
cmp.w #$3F,d0
bne @loop
move.l #$A01C04,a2 ; destination of sample id table
lsl.w #2,d0 ; set size in bytes
subq.w #1,d0
@sampleIdLoop:
move.b (a0)+,(a2)+
dbra d0,@sampleIdLoop ; load sample id table
move.l a1,d0 ; d0 = song address
add.l #$100,d0 ; bypass sample id table
moveq #0,d2
move.w $FC(a1),d2 ; get sample data size
rol.w #8,d2 ; revert endianess
lsl.l #8,d2 ; pass to 24 bits
add.l d2,d0 ; bypass samples data
addq.l #4,d0 ; bypass music data size field
move.l #$A00104,a2 ; XGM base parameters address
move.b d0,0(a2) ; low byte
lsr.l #8,d0
move.b d0,1(a2) ; med low byte
lsr.l #8,d0
move.b d0,2(a2) ; med high byte
lsr.l #8,d0
move.b d0,3(a2) ; high byte
or.b #$40,($A00100) ; send play XGM command
move.w #$000,($A11100) ; release the Z80 bus
move.l d0,d2
move.l -(a5),a3
move.l -(a5),a5
clr.w (a5)
rts
__SBSUB_xgm_resumePlayMusic:
move.l a3,a5
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
or.b #$20,($A00100) ; send resume play command
move.w #$000,($A11100) ; release the Z80 bus
move.l d0,d2
move.l -(a5),a3
move.l -(a5),a5
clr.w (a5)
rts
__SBSUB_xgm_stopPlayMusic:
move.l a3,a5
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
or.b #$10,($A00100) ; send stop play command
move.w #$000,($A11100) ; release the Z80 bus
move.l d0,d2
move.l -(a5),a3
move.l -(a5),a5
clr.w (a5)
rts
__SBFUNC_xgm_isPlayingPCM:
move.l a3,a5
lea 2(a5),a5
move.w (a5)+,d2
move.l a3,a5
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
and.b ($A00102),d2 ; get channel playing status
moveq #0,d0
move.b d2,d0 ; store in d0
move.w #$000,($A11100) ; release the Z80 bus
move.l d0,d2
move.l -(a5),a3
move.l -(a5),a5
clr.w (a5)
rts
__SBSUB_xgm_playPCM:
move.l a3,a5
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
move.l (__LONG_pcmid),d0
lsl.l #2,d0
lea $A01C00,a0
adda.l d0,a0 ; a0 point on id table entry
move.l a1,d0 ; d0 = sample address
lsr.l #8,d0 ; get sample address (high byte)
move.b d0,(a0)+
lsr.w #8,d0 ; get sample address (low byte)
move.b d0,(a0)+
lsr.l #8,d1 ; get sample length (high byte)
move.b d1,(a0)+
lsr.w #8,d1 ; get sample length (low byte)
move.b d1,(a0)+
move.l d2,d0
and.l #3,d0 ; d0 = channel number
lea $A00100,a0
moveq #1,d1
lsl.l d0,d1 ; d1 = channel shift command
or.b d1,(a0) ; set PCM play command
lea $A00108,a0
add.l d0,d0
adda.l d0,a0 ; a0 point on channel info
move.l d2,d0
lsr.l #4,d0
and.l #$F,d0 ; d0 = priority
move.b d0,(a0)+ ; set priority
move.l (__LONG_pcmid),d0 ; d0 = PCM id
move.b d0,(a0) ; set PCM id
addq.l #1,d0
and.l #$FF,d0
or.l #$40,d0 ; id < 0x40 are reserved for music
move.l d0,(__LONG_pcmid) ; pass to next id
move.w #$000,($A11100) ; release the Z80 bus
move.l d0,d2
move.l -(a5),a3
move.l -(a5),a5
clr.w (a5)
rts
__SBSUB_xgm_stopPCM:
move.l a3,a5
lea 2(a5),a5
move.w (a5)+,d2
move.l a3,a5
move.w #$100,($A11100) ; Send the Z80 a bus request
move.w #$100,($A11200)
@z80_wait1:
move.w ($A11100),d0 ; read Z80 halted state
btst #8,d0 ; Z80 halted ?
bne @z80_wait1 ; not yet, wait..
move.l d2,d0
and.l #3,d0 ; d0 = channel number
lea $A00100,a0
moveq #1,d1
lsl.l d0,d1 ; d1 = channel shift command
or.b d1,(a0) ; set PCM play command
lea $A00108,a0
add.l d0,d0
adda.l d0,a0 ; a0 point on channel info
moveq #15,d0
move.b d0,(a0)+ ; set priority
moveq #0,d0
move.b d0,(a0) ; set PCM id
move.w #$000,($A11100) ; release the Z80 bus
move.l d0,d2
move.l -(a5),a3
move.l -(a5),a5
clr.w (a5)
rts
__FUNC_xgm_setBusProtection_PUSH:
move.l #256,d0
move.w d0,(__INTEGER_Z80_HALT)
__XGMWHILE_JUMP_3
__XGMWHILE_JUMP3_3:
move.w (__INTEGER_Z80_HALT),d2
btst.l #8,d2
sne d2
and.l #1,d2
moveq #0, d0
move.w d2,d0
tst.b d0
bne __XGMWHILE_JUMP_3
__XGMWHILE_JUMP2_3:
move.l #10486020,d0
add.l #13,d0
move.l d0,d6
moveq #0, d0
move.w (__integer_xgmvalue),d0
move.l d6,a0
move.b d0,(a0)
move.l #0,d0
move.w d0,(__INTEGER_Z80_HALT)
move.l -(a5),a3
move.l -(a5),a5
moveq #0,d2
clr.w (a5)
rts
__FUNC_xgm_setBusProtection:
move.w (__integer_xgmvalue),-(a7)
clr.w (__integer_xgmvalue)
move.l a3,a2
lea 2(a2),a2
move.w (a2)+,(__integer_xgmvalue)
move.l a3,a5
jsr __FUNC_xgm_setBusProtection_PUSH
move.w (a7)+,(__integer_xgmvalue)
rts
__FUNC_xgmElapsedTime_PUSH:
move.l #256,d0
move.w d0,(__INTEGER_Z80_HALT)
__XGMWHILE_JUMP_4
__XGMWHILE_JUMP3_4:
move.w (__INTEGER_Z80_HALT),d2
btst.l #8,d2
sne d2
and.l #1,d2
moveq #0, d0
move.w d2,d0
tst.b d0
bne __XGMWHILE_JUMP_4
__XGMWHILE_JUMP2_4:
movem.l d0/d1/d4,-(a7)
move.l d2,-(a7)
move.l #10486020,d0
add.l #144,d0
move.l (a7)+,d2
move.l d0,a0
clr.l d2
move.b (a0),d2
movem.l (a7)+,d0/d1/d4
moveq #0, d0
move.w d2,d0
move.l d0,(__LONG_xgmelapsed)
move.l (__LONG_xgmelapsed),d0
movem.l d0/d1/d4,-(a7)
movem.l d0/d1/d4,-(a7)
move.l d2,-(a7)
move.l #10486020,d0
add.l #145,d0
move.l (a7)+,d2
move.l d0,a0
clr.l d2
move.b (a0),d2
movem.l (a7)+,d0/d1/d4
moveq #0, d0
move.w d2,d0
lsl.l #8,d0
move.l d0,d2
movem.l (a7)+,d0/d1/d4
or.l d4, d0
move.l d0,d4
move.l d2,d0
or.l d4,d0
move.l d0,(__LONG_xgmelapsed)
move.l #16,d0
move.w d0,(__integer_xgmd)
move.l (__LONG_xgmelapsed),d0
movem.l d0/d1/d4,-(a7)
movem.l d0/d1/d4,-(a7)
move.l d2,-(a7)
move.l #10486020,d0
add.l #146,d0
move.l (a7)+,d2
move.l d0,a0
clr.l d2
move.b (a0),d2
movem.l (a7)+,d0/d1/d4
moveq #0, d0
move.w d2,d0
move.w (__integer_xgmd),d2
lsl.l d2,d0
move.l d0,d2
movem.l (a7)+,d0/d1/d4
or.l d4, d0
move.l d0,d4
move.l d2,d0
or.l d4,d0
move.l d0,(__LONG_xgmelapsed)
move.l #0,d0
move.w d0,(__INTEGER_Z80_HALT)
movem.l d0/d1/d4,-(a7)
move.l (__LONG_xgmelapsed),d0
move.l d0,d1
move.l #16777200,d0
move.l d0, d2
movem.l (a7)+, d0/d1/d4
move.l d0, d1
move.l d0,d2
cmp.l d1, d0
sls d0
move.w d2,d0
tst.b d0
beq XGMIF_JUMP_10
move.l #0,d0
move.l d0,(__LONG_xgmelapsed)
XGMIF_JUMP_10:
move.l -(a5),a3
move.l -(a5),a5
move.l (__LONG_xgmelapsed),d0
move.l d0,d2
clr.w (a5)
rts
__SBFUNC_xgmElapsedTime:
move.l (__LONG_xgmelapsed),-(a7)
clr.l (__LONG_xgmelapsed)
move.w (__integer_xgmd),-(a7)
clr.w (__integer_xgmd)
jsr __FUNC_xgmElapsedTime_PUSH
move.w (a7)+,(__integer_xgmd)
move.l (a7)+,(__LONG_xgmelapsed)
rts
even
__sbsforever:
bra __sbsforever
even
__SIGNCHECKPRTDATA:
dc.b '-', 0
include "Z:\mnt\sda3\opt\wine\development\secondbasic\work\sbsstr.s"
even
__DATASTART:
even
__INTEGER_XGMCNT equ $FF004C
__INTEGER_XGMSTP equ $FF004E
__INTEGER_XGMNUM equ $FF0050
__INTEGER_XGMVALUE equ $FF0052
__INTEGER_XGMD equ $FF0054
__INTEGER_XGMREADY equ $FF0056
__INTEGER_XGMTEMPO equ $FF0058
__INTEGER_XGMTEMPODEF equ $FF005A
__INTEGER_XGMTEMPOCNT equ $FF005C
__LONG_I equ $FF005E
__LONG_PCMID equ $FF0062
__LONG_XGMELAPSED equ $FF0066
__INTEGER_VDP_DATA equ $00C00000
__INTEGER_VDP_CTRL equ $00C00004
__INTEGER_Z80_HALT equ $00A11100
__INTEGER_Z80_RESET equ $00A11200
HEAPSTART equ $FF006A
__SBENDCODE:
end
anyway, if anyone want to share a working mdv/zip/etc. from it, and how the .asm would look like, be welcome!

SecondBasic: https://www.sbasic.net/ - it runs fine on Wine (otherwise i couldn't be posting the code above)