Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - snail.sms

Reply to topic
Author Message
Eric
  • Guest
Reply with quote
snail.sms
Post Posted: Fri Jul 23, 1999 5:27 am
I was able to get my SMS music test program running on the emulator Massage. The music is timed using VBlanks. In fact, most of the code is in the interrupt handler.

In order to be more "SMS-like" I changed the song from "Mary Had a Little Lamb" (which even I thought was kind of lame) to the song from "Maze" or "Snail" (the game built into SMS units.) I have reproduced the code below. Maybe Zoop will start a section of S8-Dev for storing sample source code files...


; Eric R. Quinn
; July 21, 1999
; snail.asm

; This program plays the theme from "Maze: The Snail Game" on SMS hardware.
; It has been tested on the emulator MASSAGE.
; Feel free to use this code as you wish. It is provided "As-is"
; Submitted to S8-Dev on July 22, 1999

#define EQU .equ

; Key offsets
;
START EQU $0000
INTERRUPT_HANDLER_OFFSET EQU $0038
MAIN EQU $1000
DATA_SEGMENT EQU $4000
HEADER_OFFSET EQU $7FF0
LAST_PAGE_OFFSET EQU $8000

; Useful definitions
;
VDP_ADDRESS_PORT EQU $BF
PSG_PORT EQU $7F

VDP_REG_WRITE EQU $80
VDP_REG_1 EQU $01
VDPREG1_VSYNC_FLAG EQU $20
VDPREG1_DISP_ENABLE_FLAG EQU $40
SOUND_VOLUME_WRITE EQU $90
SOUND_CHANNEL_0 EQU $00
SOUND_VOLUME_LOUDEST EQU $00
SOUND_VOLUME_OFF EQU $0F
SOUND_FREQUENCY_WRITE_LO EQU $80
SOUND_FREQUENCY_WRITE_HI EQU $00

; Frequency table
;
CONCERT_G3_LO EQU $0E
CONCERT_G3_HI EQU $13
CONCERT_GS3_LO EQU $0E
CONCERT_GS3_HI EQU $12
CONCERT_AF3_LO EQU CONCERT_GS3_LO
CONCERT_AF3_HI EQU CONCERT_GS3_HI
CONCERT_A4_LO EQU $0C
CONCERT_A4_HI EQU $11
CONCERT_AS4_LO EQU $0C
CONCERT_AS4_HI EQU $01
CONCERT_BF4_LO EQU CONCERT_AS4_LO
CONCERT_BF4_HI EQU CONCERT_AS4_HI
CONCERT_B4_LO EQU $0D
CONCERT_B4_HI EQU $0F
CONCERT_C4_LO EQU $0F
CONCERT_C4_HI EQU $0E
CONCERT_CS4_LO EQU $01
CONCERT_CS4_HI EQU $0E
CONCERT_DF4_LO EQU CONCERT_CS4_LO
CONCERT_DF4_HI EQU CONCERT_CS4_HI
CONCERT_D4_LO EQU $05
CONCERT_D4_HI EQU $0D
CONCERT_DS4_LO EQU $09
CONCERT_DS4_HI EQU $0C
CONCERT_EF4_LO EQU CONCERT_DS4_LO
CONCERT_EF4_HI EQU CONCERT_DS4_HI
CONCERT_E4_LO EQU $0E
CONCERT_E4_HI EQU $0B
CONCERT_F4_LO EQU $03
CONCERT_F4_HI EQU $0B
CONCERT_FS4_LO EQU $09
CONCERT_FS4_HI EQU $0A
CONCERT_GF4_LO EQU CONCERT_FS4_LO
CONCERT_GF4_HI EQU CONCERT_FS4_HI
CONCERT_G4_LO EQU $0F
CONCERT_G4_HI EQU $09
CONCERT_GS4_LO EQU $07
CONCERT_GS4_HI EQU $09
CONCERT_AF4_LO EQU CONCERT_GS4_LO
CONCERT_AF4_HI EQU CONCERT_GS4_HI
CONCERT_A5_LO EQU $0E
CONCERT_A5_HI EQU $08
CONCERT_AS5_LO EQU $06
CONCERT_AS5_HI EQU $08
CONCERT_BF5_LO EQU CONCERT_AS5_LO
CONCERT_BF5_HI EQU CONCERT_AS5_HI
CONCERT_B5_LO EQU $0F
CONCERT_B5_HI EQU $07
CONCERT_C5_LO EQU $07
CONCERT_C5_HI EQU $07

; Music note durations
DURATION_1S EQU 60
DURATION_05S EQU 30
DURATION_025S EQU 15
DURATION_INTRO EQU 15
DURATION_BETWEEN_NOTES EQU 1


.ORG START
; This code contains standard SMS initialization routines.
DI ; Disable Interrupts
IM 1 ; Interrupt Mode 1
LD SP, $D000 ; Initialize stack pointer
LD HL, $FFFD
LD (HL), $00 ; Map ROM page 0
INC HL
LD (HL), $01 ; Map ROM page 1
INC HL
LD (HL), $00 ; Map ROM page 0
JP MAIN

.ORG INTERRUPT_HANDLER_OFFSET
DEC C ; Decrement duration counter
JR Z, NEXT_NOTE ; If counter is 0, then play next note
LD A, C
CP DURATION_BETWEEN_NOTES ; Play short silence between notes.
JR NZ, I_HANDLER_DONE

; Silence sound channel 0 for inter-note break.
LD A, SOUND_VOLUME_WRITE
OR SOUND_CHANNEL_0
OR SOUND_VOLUME_OFF
OUT (PSG_PORT), A
JR I_HANDLER_DONE

NEXT_NOTE:
; Turn sound channel 0 back on.
LD A, SOUND_VOLUME_WRITE
OR SOUND_CHANNEL_0
OR SOUND_VOLUME_LOUDEST
OUT (PSG_PORT), A

; Load low frequency bits
LD A, (HL)
OR SOUND_FREQUENCY_WRITE_LO
OR SOUND_CHANNEL_0
OUT (PSG_PORT), A

; Point to next byte in music data table.
; Register D contains the count of bytes accessed in music
; data table. This count is used to determine when end
; of music data is reached so song can be repeated.
INC HL
INC D

; Load high frequency bits
LD A, (HL)
OR SOUND_FREQUENCY_WRITE_HI
OR SOUND_CHANNEL_0
OUT (PSG_PORT), A

; Load duration counter.
INC HL
INC D
LD C, (HL)
INC HL
INC D

; Check if at we're at the end of the music data table.
LD A, D
CP (END_MUSIC_DATA_TABLE-MUSIC_DATA_TABLE+3)
JR NZ, I_HANDLER_DONE

; If we are set HL to point back to beginning.
; Clear D
; Set C to allow a short break between songs.
LD HL, MUSIC_DATA_TABLE
LD D, $00
LD C, DURATION_INTRO

; Silence sound channel 0.
LD A, SOUND_VOLUME_WRITE
OR SOUND_CHANNEL_0
OR SOUND_VOLUME_OFF
OUT (PSG_PORT), A

I_HANDLER_DONE:
EI
RETI

.ORG MAIN
; Turn on VBlank interrupt
XOR A
LD A, VDPREG1_VSYNC_FLAG
OUT (VDP_ADDRESS_PORT), A
LD A, VDP_REG_WRITE
OR VDP_REG_1
OUT (VDP_ADDRESS_PORT), A

; Set up sound channel 0 volume.
LD A, SOUND_VOLUME_WRITE
OR SOUND_CHANNEL_0
OR SOUND_VOLUME_LOUDEST
OUT (PSG_PORT), A

; Set up music pointer and counters.
; HL register is pointer, BC is duration counter.
LD D, $00
LD HL, MUSIC_DATA_TABLE
LD C, $01
EI

; Start loop
MAIN_LOOP:

JR MAIN_LOOP
HALT

.ORG DATA_SEGMENT

; This data table contains the information necessary to play the
; theme from "Maze: The Snail Game" The data is in the form of bytes
; arranged as ordered pairs of (frequency, duration). Duration is
; measured in VBlanks. Consequently, a value of 60 for duration implies
; a note lasting one second on NTSC machines.

MUSIC_DATA_TABLE:

.DB CONCERT_C4_LO
.DB CONCERT_C4_HI
.DB DURATION_025S

.DB CONCERT_G4_LO
.DB CONCERT_G4_HI
.DB DURATION_025S

.DB CONCERT_E4_LO
.DB CONCERT_E4_HI
.DB DURATION_025S

.DB CONCERT_G4_LO
.DB CONCERT_G4_HI
.DB DURATION_025S

.DB CONCERT_F4_LO
.DB CONCERT_F4_HI
.DB DURATION_025S

.DB CONCERT_D4_LO
.DB CONCERT_D4_HI
.DB DURATION_025S

.DB CONCERT_E4_LO
.DB CONCERT_E4_HI
.DB DURATION_025S

.DB CONCERT_D4_LO
.DB CONCERT_D4_HI
.DB DURATION_025S

.DB CONCERT_C4_LO
.DB CONCERT_C4_HI
.DB DURATION_025S

.DB CONCERT_D4_LO
.DB CONCERT_D4_HI
.DB DURATION_025S

.DB CONCERT_E4_LO
.DB CONCERT_E4_HI
.DB DURATION_025S

.DB CONCERT_D4_LO
.DB CONCERT_D4_HI
.DB DURATION_025S

.DB CONCERT_G3_LO
.DB CONCERT_G3_HI
.DB DURATION_025S

.DB CONCERT_A4_LO
.DB CONCERT_A4_HI
.DB DURATION_025S

.DB CONCERT_G3_LO
.DB CONCERT_G3_HI
.DB DURATION_025S

.DB CONCERT_G3_LO
.DB CONCERT_G3_HI
.DB DURATION_025S

.DB CONCERT_C4_LO
.DB CONCERT_C4_HI
.DB DURATION_025S

.DB CONCERT_G4_LO
.DB CONCERT_G4_HI
.DB DURATION_025S

.DB CONCERT_E4_LO
.DB CONCERT_E4_HI
.DB DURATION_025S

.DB CONCERT_G4_LO
.DB CONCERT_G4_HI
.DB DURATION_025S

.DB CONCERT_F4_LO
.DB CONCERT_F4_HI
.DB DURATION_025S

.DB CONCERT_D4_LO
.DB CONCERT_D4_HI
.DB DURATION_025S

.DB CONCERT_E4_LO
.DB CONCERT_E4_HI
.DB DURATION_025S

.DB CONCERT_D4_LO
.DB CONCERT_D4_HI
.DB DURATION_025S

.DB CONCERT_E4_LO
.DB CONCERT_E4_HI
.DB DURATION_025S

.DB CONCERT_D4_LO
.DB CONCERT_D4_HI
.DB DURATION_025S

.DB CONCERT_C4_LO
.DB CONCERT_C4_HI
.DB DURATION_025S

.DB CONCERT_B4_LO
.DB CONCERT_B4_HI
.DB DURATION_025S

.DB CONCERT_C4_LO
.DB CONCERT_C4_HI
.DB DURATION_025S

.DB CONCERT_C4_LO
.DB CONCERT_C4_HI
.DB DURATION_025S

.DB CONCERT_C4_LO
.DB CONCERT_C4_HI
.DB DURATION_025S

END_MUSIC_DATA_TABLE:

.ORG HEADER_OFFSET
.DB "TMR MESA" ; Tradmark
.DW 9919h ; Year
.DW 0000h ; Checksum not correct
.DW 0000h ; Part Num not correct
.DW 2107h ; Day / Month

.ORG LAST_PAGE_OFFSET
.END


 
Eric
  • Guest
Reply with quote
Post Posted: Fri Jul 23, 1999 5:30 am
The source code formatting is messed up in my message posting. Sorry.
 
Chris
  • Guest
Reply with quote
Better Source View
Post Posted: Fri Jul 23, 1999 4:20 pm
Don't worrry Eric. I didn't touch a thing down there. All I'm doing is adding the HTML code feature.


Quote
>

> ; Eric R. Quinn
> ; July 21, 1999
> ; snail.asm

> ; This program plays the theme from "Maze: The Snail Game" on SMS hardware.
> ; It has been tested on the emulator MASSAGE.
> ; Feel free to use this code as you wish. It is provided "As-is"
> ; Submitted to S8-Dev on July 22, 1999

> #define EQU .equ

> ; Key offsets
> ;
> START EQU $0000
> INTERRUPT_HANDLER_OFFSET EQU $0038
> MAIN EQU $1000
> DATA_SEGMENT EQU $4000
> HEADER_OFFSET EQU $7FF0
> LAST_PAGE_OFFSET EQU $8000

> ; Useful definitions
> ;
> VDP_ADDRESS_PORT EQU $BF
> PSG_PORT EQU $7F

> VDP_REG_WRITE EQU $80
> VDP_REG_1 EQU $01
> VDPREG1_VSYNC_FLAG EQU $20
> VDPREG1_DISP_ENABLE_FLAG EQU $40
> SOUND_VOLUME_WRITE EQU $90
> SOUND_CHANNEL_0 EQU $00
> SOUND_VOLUME_LOUDEST EQU $00
> SOUND_VOLUME_OFF EQU $0F
> SOUND_FREQUENCY_WRITE_LO EQU $80
> SOUND_FREQUENCY_WRITE_HI EQU $00

> ; Frequency table
> ;
> CONCERT_G3_LO EQU $0E
> CONCERT_G3_HI EQU $13
> CONCERT_GS3_LO EQU $0E
> CONCERT_GS3_HI EQU $12
> CONCERT_AF3_LO EQU CONCERT_GS3_LO
> CONCERT_AF3_HI EQU CONCERT_GS3_HI
> CONCERT_A4_LO EQU $0C
> CONCERT_A4_HI EQU $11
> CONCERT_AS4_LO EQU $0C
> CONCERT_AS4_HI EQU $01
> CONCERT_BF4_LO EQU CONCERT_AS4_LO
> CONCERT_BF4_HI EQU CONCERT_AS4_HI
> CONCERT_B4_LO EQU $0D
> CONCERT_B4_HI EQU $0F
> CONCERT_C4_LO EQU $0F
> CONCERT_C4_HI EQU $0E
> CONCERT_CS4_LO EQU $01
> CONCERT_CS4_HI EQU $0E
> CONCERT_DF4_LO EQU CONCERT_CS4_LO
> CONCERT_DF4_HI EQU CONCERT_CS4_HI
> CONCERT_D4_LO EQU $05
> CONCERT_D4_HI EQU $0D
> CONCERT_DS4_LO EQU $09
> CONCERT_DS4_HI EQU $0C
> CONCERT_EF4_LO EQU CONCERT_DS4_LO
> CONCERT_EF4_HI EQU CONCERT_DS4_HI
> CONCERT_E4_LO EQU $0E
> CONCERT_E4_HI EQU $0B
> CONCERT_F4_LO EQU $03
> CONCERT_F4_HI EQU $0B
> CONCERT_FS4_LO EQU $09
> CONCERT_FS4_HI EQU $0A
> CONCERT_GF4_LO EQU CONCERT_FS4_LO
> CONCERT_GF4_HI EQU CONCERT_FS4_HI
> CONCERT_G4_LO EQU $0F
> CONCERT_G4_HI EQU $09
> CONCERT_GS4_LO EQU $07
> CONCERT_GS4_HI EQU $09
> CONCERT_AF4_LO EQU CONCERT_GS4_LO
> CONCERT_AF4_HI EQU CONCERT_GS4_HI
> CONCERT_A5_LO EQU $0E
> CONCERT_A5_HI EQU $08
> CONCERT_AS5_LO EQU $06
> CONCERT_AS5_HI EQU $08
> CONCERT_BF5_LO EQU CONCERT_AS5_LO
> CONCERT_BF5_HI EQU CONCERT_AS5_HI
> CONCERT_B5_LO EQU $0F
> CONCERT_B5_HI EQU $07
> CONCERT_C5_LO EQU $07
> CONCERT_C5_HI EQU $07

> ; Music note durations
> DURATION_1S EQU 60
> DURATION_05S EQU 30
> DURATION_025S EQU 15
> DURATION_INTRO EQU 15
> DURATION_BETWEEN_NOTES EQU 1

>
> .ORG START
> ; This code contains standard SMS initialization routines.
> DI ; Disable Interrupts
> IM 1 ; Interrupt Mode 1
> LD SP, $D000 ; Initialize stack pointer
> LD HL, $FFFD
> LD (HL), $00 ; Map ROM page 0
> INC HL
> LD (HL), $01 ; Map ROM page 1
> INC HL
> LD (HL), $00 ; Map ROM page 0
> JP MAIN

> .ORG INTERRUPT_HANDLER_OFFSET
> DEC C ; Decrement duration counter
> JR Z, NEXT_NOTE ; If counter is 0, then play next note
> LD A, C
> CP DURATION_BETWEEN_NOTES ; Play short silence between notes.
> JR NZ, I_HANDLER_DONE

> ; Silence sound channel 0 for inter-note break.
> LD A, SOUND_VOLUME_WRITE
> OR SOUND_CHANNEL_0
> OR SOUND_VOLUME_OFF
> OUT (PSG_PORT), A
> JR I_HANDLER_DONE

> NEXT_NOTE:
> ; Turn sound channel 0 back on.
> LD A, SOUND_VOLUME_WRITE
> OR SOUND_CHANNEL_0
> OR SOUND_VOLUME_LOUDEST
> OUT (PSG_PORT), A

> ; Load low frequency bits
> LD A, (HL)
> OR SOUND_FREQUENCY_WRITE_LO
> OR SOUND_CHANNEL_0
> OUT (PSG_PORT), A

> ; Point to next byte in music data table.
> ; Register D contains the count of bytes accessed in music
> ; data table. This count is used to determine when end
> ; of music data is reached so song can be repeated.
> INC HL
> INC D

> ; Load high frequency bits
> LD A, (HL)
> OR SOUND_FREQUENCY_WRITE_HI
> OR SOUND_CHANNEL_0
> OUT (PSG_PORT), A

> ; Load duration counter.
> INC HL
> INC D
> LD C, (HL)
> INC HL
> INC D

> ; Check if at we're at the end of the music data table.
> LD A, D
> CP (END_MUSIC_DATA_TABLE-MUSIC_DATA_TABLE+3)
> JR NZ, I_HANDLER_DONE

> ; If we are set HL to point back to beginning.
> ; Clear D
> ; Set C to allow a short break between songs.
> LD HL, MUSIC_DATA_TABLE
> LD D, $00
> LD C, DURATION_INTRO

> ; Silence sound channel 0.
> LD A, SOUND_VOLUME_WRITE
> OR SOUND_CHANNEL_0
> OR SOUND_VOLUME_OFF
> OUT (PSG_PORT), A

> I_HANDLER_DONE:
> EI
> RETI

> .ORG MAIN
> ; Turn on VBlank interrupt
> XOR A
> LD A, VDPREG1_VSYNC_FLAG
> OUT (VDP_ADDRESS_PORT), A
> LD A, VDP_REG_WRITE
> OR VDP_REG_1
> OUT (VDP_ADDRESS_PORT), A
>
> ; Set up sound channel 0 volume.
> LD A, SOUND_VOLUME_WRITE
> OR SOUND_CHANNEL_0
> OR SOUND_VOLUME_LOUDEST
> OUT (PSG_PORT), A

> ; Set up music pointer and counters.
> ; HL register is pointer, BC is duration counter.
> LD D, $00
> LD HL, MUSIC_DATA_TABLE
> LD C, $01
> EI

> ; Start loop
> MAIN_LOOP:

> JR MAIN_LOOP
> HALT

> .ORG DATA_SEGMENT

> ; This data table contains the information necessary to play the
> ; theme from "Maze: The Snail Game" The data is in the form of bytes
> ; arranged as ordered pairs of (frequency, duration). Duration is
> ; measured in VBlanks. Consequently, a value of 60 for duration implies
> ; a note lasting one second on NTSC machines.

> MUSIC_DATA_TABLE:

> .DB CONCERT_C4_LO
> .DB CONCERT_C4_HI
> .DB DURATION_025S

> .DB CONCERT_G4_LO
> .DB CONCERT_G4_HI
> .DB DURATION_025S

> .DB CONCERT_E4_LO
> .DB CONCERT_E4_HI
> .DB DURATION_025S

> .DB CONCERT_G4_LO
> .DB CONCERT_G4_HI
> .DB DURATION_025S

> .DB CONCERT_F4_LO
> .DB CONCERT_F4_HI
> .DB DURATION_025S

> .DB CONCERT_D4_LO
> .DB CONCERT_D4_HI
> .DB DURATION_025S

> .DB CONCERT_E4_LO
> .DB CONCERT_E4_HI
> .DB DURATION_025S

> .DB CONCERT_D4_LO
> .DB CONCERT_D4_HI
> .DB DURATION_025S

> .DB CONCERT_C4_LO
> .DB CONCERT_C4_HI
> .DB DURATION_025S

> .DB CONCERT_D4_LO
> .DB CONCERT_D4_HI
> .DB DURATION_025S

> .DB CONCERT_E4_LO
> .DB CONCERT_E4_HI
> .DB DURATION_025S

> .DB CONCERT_D4_LO
> .DB CONCERT_D4_HI
> .DB DURATION_025S

> .DB CONCERT_G3_LO
> .DB CONCERT_G3_HI
> .DB DURATION_025S

> .DB CONCERT_A4_LO
> .DB CONCERT_A4_HI
> .DB DURATION_025S

> .DB CONCERT_G3_LO
> .DB CONCERT_G3_HI
> .DB DURATION_025S

> .DB CONCERT_G3_LO
> .DB CONCERT_G3_HI
> .DB DURATION_025S

> .DB CONCERT_C4_LO
> .DB CONCERT_C4_HI
> .DB DURATION_025S

> .DB CONCERT_G4_LO
> .DB CONCERT_G4_HI
> .DB DURATION_025S

> .DB CONCERT_E4_LO
> .DB CONCERT_E4_HI
> .DB DURATION_025S

> .DB CONCERT_G4_LO
> .DB CONCERT_G4_HI
> .DB DURATION_025S

> .DB CONCERT_F4_LO
> .DB CONCERT_F4_HI
> .DB DURATION_025S

> .DB CONCERT_D4_LO
> .DB CONCERT_D4_HI
> .DB DURATION_025S

> .DB CONCERT_E4_LO
> .DB CONCERT_E4_HI
> .DB DURATION_025S

> .DB CONCERT_D4_LO
> .DB CONCERT_D4_HI
> .DB DURATION_025S

> .DB CONCERT_E4_LO
> .DB CONCERT_E4_HI
> .DB DURATION_025S

> .DB CONCERT_D4_LO
> .DB CONCERT_D4_HI
> .DB DURATION_025S

> .DB CONCERT_C4_LO
> .DB CONCERT_C4_HI
> .DB DURATION_025S

> .DB CONCERT_B4_LO
> .DB CONCERT_B4_HI
> .DB DURATION_025S

> .DB CONCERT_C4_LO
> .DB CONCERT_C4_HI
> .DB DURATION_025S

> .DB CONCERT_C4_LO
> .DB CONCERT_C4_HI
> .DB DURATION_025S

> .DB CONCERT_C4_LO
> .DB CONCERT_C4_HI
> .DB DURATION_025S

> END_MUSIC_DATA_TABLE:

> .ORG HEADER_OFFSET
> .DB "TMR MESA" ; Tradmark
> .DW 9919h ; Year
> .DW 0000h ; Checksum not correct
> .DW 0000h ; Part Num not correct
> .DW 2107h ; Day / Month

> .ORG LAST_PAGE_OFFSET
> .END

>




Sorry about the >s but I don't want to accidently erase anything.
 
Chris
  • Guest
Reply with quote
Damn it!
Post Posted: Fri Jul 23, 1999 4:22 pm
Nevermind, it did the same shit. Sorry.

Chris :o|
 
Chris
  • Guest
Reply with quote
Beautiful
Post Posted: Fri Jul 23, 1999 5:26 pm
Man, why didn't you tell me that you knew Assembler? Did you know I've been studying that stuff for the
past 4 months? A while back I wrote my little sound demo via brute force. I wrote a program in C that
would call a bunch of C functions and predefined macros in order to dump sound bytes to a file and
dump around 16k to the file. It worked but not on all emulators. Brsms was the only one who could
play the sound. Meka, MGX, and all others couldn't do it.

I don't even know where to begin. It's like I know a whole lot about the instructions for the Z80 and
the 80x86s but I don't know how to write out an assembler source. It's not like C where you can
just type in a few lines and get it to print "Hello, World!". But everything is starting to piece
together in my head. .ORG means a function or subroutine, right?

.ORG

And if you say. ORG $8048 and you put a bunch of .DB statements in the sub then those bytes
will be written to that area of memory? You wrote:

.ORG HEADER_OFFSET
.DB "TMR MESA" ; Tradmark
.DW 9919h ; Year
.DW 0000h ; Checksum not correct
.DW 0000h ; Part Num not correct
.DW 2107h ; Day / Month

So those 8 bytes will be written to or more like stored at $7FF0? Oh, I think I see something
else too. When you say .DB, that means DATA thats of byte value and when you say .DW
that means DATA of word value? Please tell me that's correct.

Also, why did you declare your stack like that? Is that the only way to do it in Z80? I know
in X86 assembler you just type

.STACK 200h (256k memory)

but I guess it's different on different systems and assemblers. But even though I like assembler
and all this is nuts! I seriously doubt SMS programmers back in the day wrote out all of their
games in pure assembler. They had to have built some music editors, graphics editors, and
some kind of high language. I'm thinking more than likely that they built some kind of SMS
C compiler. Could you imagine how easy this would be in C? I could see it now...


#include
#include
#define MAX 00

void main()
{
SetVblankChecks(); /*Function in VDP.h*/
SetVolume(MAX, _m1); /*Function in sound.h*/
PlayMusic();
}

void PlayMusic()
{
Sound(_c2, _m1); /*Function in sound.h*/
Csound(_m1); /*Function in sound.h (means clear sound)*/
Sound(_d2, _m1);
Csound(_m1);
Sound(_e2, _m1);
Csound(_m1);
Sound(_f2, _m1);
Csound(_m1);
Sound(_g2, _m1);
Csound(_m1);
Sound(_a2, _m1);
Csound(_m1);
Sound(_b2, _m1);
Csound(_m1);
Sound(_c3, _m1);
Csound(_m1);
}

So when you call the function SetVblankChecks sound will only update during Vblank. When
SetVblankChecks hasn't been called sound will update as fast as the Z80 can process. I don't
know if that's totally correct but it's a start.

Chris :o)
 
Nyef
  • Guest
Reply with quote
Re: Beautiful
Post Posted: Fri Jul 23, 1999 7:14 pm
Quote
> Man, why didn't you tell me that you knew Assembler? Did you know I've been studying that stuff for the
> past 4 months? A while back I wrote my little sound demo via brute force. I wrote a program in C that
> would call a bunch of C functions and predefined macros in order to dump sound bytes to a file and
> dump around 16k to the file. It worked but not on all emulators. Brsms was the only one who could
> play the sound. Meka, MGX, and all others couldn't do it.

I would say that at least 5 posters to this board know ASM. It's not that hard to learn, either. :-)

Quote
> I don't even know where to begin. It's like I know a whole lot about the instructions for the Z80 and
> the 80x86s but I don't know how to write out an assembler source. It's not like C where you can
> just type in a few lines and get it to print "Hello, World!". But everything is starting to piece
> together in my head. .ORG means a function or subroutine, right?

'Not like C where you can just type in a few lines and get it to print "Hello, World!"'? I beg to differ.
Depending on the environment in question it can be (Win9x comes to mind, actually). :-)

There are some x86 ASM tutorials at http://freehosting2.at.webjump.com/ic/iczelion-webjump/ if you
want to go that way. Or you could hang around here and see if anyone posts more z80 ASM.

Quote
> .ORG

No, ORG is short for "origin", it is used to place data/code at a certain location.

Quote
> And if you say. ORG $8048 and you put a bunch of .DB statements in the sub then those bytes
> will be written to that area of memory? You wrote:

> .ORG HEADER_OFFSET
> .DB "TMR MESA" ; Tradmark
> .DW 9919h ; Year
> .DW 0000h ; Checksum not correct
> .DW 0000h ; Part Num not correct
> .DW 2107h ; Day / Month

> So those 8 bytes will be written to or more like stored at $7FF0? Oh, I think I see something
> else too. When you say .DB, that means DATA thats of byte value and when you say .DW
> that means DATA of word value? Please tell me that's correct.

Essentially correct. DB actually stands for "define byte", and DW is "define word", but that's just semantics.

Quote
> Also, why did you declare your stack like that? Is that the only way to do it in Z80? I know
> in X86 assembler you just type

> .STACK 200h (256k memory)

Umm... you need to point the stack pointer to it, don't you? (or did the EXE format load SS:SP
for you? I forget...)

Quote
> but I guess it's different on different systems and assemblers. But even though I like assembler
> and all this is nuts! I seriously doubt SMS programmers back in the day wrote out all of their
> games in pure assembler. They had to have built some music editors, graphics editors, and
> some kind of high language. I'm thinking more than likely that they built some kind of SMS
> C compiler. Could you imagine how easy this would be in C? I could see it now...

Music editors, graphics editors, may have been written in C, but the games were written in ASM.
Gauranteed. Back in the day, people wrote assemblers, linkers, operating systems, and applications
all in ASM. Heck, there's even a linker for Win32 systems written in ASM (I'd ditch it in favor of a better
one but it has one feature I really like so I'd have to write my own).

[ Example code deleted ]

Quote
> So when you call the function SetVblankChecks sound will only update during Vblank. When
> SetVblankChecks hasn't been called sound will update as fast as the Z80 can process. I don't
> know if that's totally correct but it's a start.

*sigh*. The _real_ reasons that people use C are rapid development and portability. We are
working with a specific target in mind here, so we can ignore portability. The next issue is a
decision to go with more control (ASM) or faster development (C). Most people go with ASM,
because they like the control, and because for programs this small development tends to be
fairly rapid anyway.

Quote
> Chris :o)

--Nyef
 
  • Joined: 24 Jun 1999
  • Posts: 1732
  • Location: Paris, France
Reply with quote
Re: Beautiful
Post Posted: Fri Jul 23, 1999 7:57 pm
Quote
> games in pure assembler. They had to have built some music editors, graphics editors, and
> some kind of high language. I'm thinking more than likely that they built some kind of SMS
> C compiler. Could you imagine how easy this would be in C? I could see it now...

Hahahaha. Nice said for someone for always praise about making programs fast.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 1999
  • Posts: 1732
  • Location: Paris, France
Reply with quote
Bugs
Post Posted: Fri Jul 23, 1999 8:10 pm
It is only working at the right speed with Massage.
Try writing 255 to VDP Register 10.
Or try disabling HBL interrupts. I see them enabled with Meka information box.
  View user's profile Send private message Visit poster's website
Eric
  • Guest
Reply with quote
Re: Bugs
Post Posted: Fri Jul 23, 1999 8:28 pm
Quote
> It is only working at the right speed with Massage.
> Try writing 255 to VDP Register 10.
> Or try disabling HBL interrupts. I see them enabled with Meka information box.

Thank you.

I know the code, as it stands, doesn't work with BrSMS (and I assume Meka as well.) I posted it in the hopes that someone out there could help debug it.

I will try the changes you suggest. However, I do not believe the code I wrote enables HBlanks. Does Meka enable HBlanks by default?

Eric
 
Eric
  • Guest
Reply with quote
Re: Beautiful
Post Posted: Fri Jul 23, 1999 8:59 pm
Quote
> Man, why didn't you tell me that you knew Assembler? Did you know I've been studying that stuff for the
> past 4 months? A while back I wrote my little sound demo via brute force. I wrote a program in C that
> would call a bunch of C functions and predefined macros in order to dump sound bytes to a file and
> dump around 16k to the file. It worked but not on all emulators. Brsms was the only one who could
> play the sound. Meka, MGX, and all others couldn't do it.

I know x86 assembly language and I'm learning Z80 assembly language. I also know C/C++.

My first Z80 emulator was written in 16-bit x86 assembly language.

Could you explain a little more about this program you wrote (maybe you should e-mail me.)

Quote
> I don't even know where to begin. It's like I know a whole lot about the instructions for the Z80 and
> the 80x86s but I don't know how to write out an assembler source. It's not like C where you can
> just type in a few lines and get it to print "Hello, World!". But everything is starting to piece
> together in my head. .ORG means a function or subroutine, right?

> .ORG

As Nyef explained, .ORG means "ORIGIN". It's used to tell the assembler exactly where to start assembling the raw object bytes. The Z80 uses linearly addressed memory, so the .ORG directive is used quite frequently to force data into certain areas of memory. In x86 assembly language it's not used as much. The x86 memory scheme is segmented, and .ORG defines offsets from beginning of segments, not absolute addresses.The operating system decides where in memory the segments are loaded. You can't really use .ORG to define absolute memory addresses on the x86, everything is based off of segment offsets.

In my code I use .ORG to define the beginning of "blocks" of code. For example, the interrupt handler must be at 0x0038, so I use an .ORG statement to force assembly at that address. The final .ORG statement is used to tell the assembler that the file must be a multiple of 16Kbytes in length.

Quote
> And if you say. ORG $8048 and you put a bunch of .DB statements in the sub then those bytes
> will be written to that area of memory? You wrote:

> .ORG HEADER_OFFSET
> .DB "TMR MESA" ; Tradmark
> .DW 9919h ; Year
> .DW 0000h ; Checksum not correct
> .DW 0000h ; Part Num not correct
> .DW 2107h ; Day / Month

> So those 8 bytes will be written to or more like stored at $7FF0? Oh, I think I see something
> else too. When you say .DB, that means DATA thats of byte value and when you say .DW
> that means DATA of word value? Please tell me that's correct.

Again, this is explained in Nyef's response. You are basically correct.

Quote
> Also, why did you declare your stack like that? Is that the only way to do it in Z80? I know
> in X86 assembler you just type

> .STACK 200h (256k memory)

x86 memory is segmented. The directive above defines a segment for stack memory. I believe you still need to initialize SS and SP explicitly (this may depend on the operating system your code is written for.)

For the Z80, the stack is wherever the SP points. On the SMS, the only memory area that is RAM is 0xC000 through 0xDFFF. So, all I have to do is set SP to point somewhere in this area. That's it, the stack is set up. If you ever write a program that uses procedures (CALLS/RETS) or interrtupts, you need to set up the stack. My program uses interrupts, so I had to initialize SP.


Eric
 
  • Joined: 24 Jun 1999
  • Posts: 1732
  • Location: Paris, France
Reply with quote
Re: Bugs
Post Posted: Fri Jul 23, 1999 9:07 pm
Quote
> I know the code, as it stands, doesn't work with BrSMS (and I assume Meka as well.) I posted it in the hopes that someone out there could help debug it.
> I will try the changes you suggest. However, I do not believe the code I wrote enables HBlanks. Does Meka enable HBlanks by default?

Default VDP registers values are:

0x36, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00

So yes.
These are the same values as set by the BIOS.
  View user's profile Send private message Visit poster's website
Chris
  • Guest
Reply with quote
Control; I like that word :o)
Post Posted: Fri Jul 23, 1999 9:27 pm
You took the words right out of my mouth, or should I say mind and keyboard, I guess. Anyway, that's
why I want to learn ASM because it gives you total control over your system. It's amazing the shit er
stuff you can do in ASM and the programs are light years faster than any other language by itself.
I tell people all the time, C and Basic are slow. There's no way around it. Then they tell me,
"Oh. C and Basic aren't slow. It just depends on how you code it." No, it depends on whether
the routines you are using were written assembler. At my local programming place my friend
downloaded this program giving an example for the battle of the fastest. It was programs of
a rotating skull. One version written in Basic, another in C, another in Basic mixed with ASM,
another in C mixed wtih ASM, and just one pure ASM; a total of 5 EXE files. The program
would make the skull picture rotate and zoom in and out, similar to the effects of the SNES'
Mode 7. The Basic version was just pathetic. It took my PC a total of 2 seconds or more to
draw all the pixels and render it to the screen with each frame of animation. The Basic
version mixed with ASM was suprisingly quick, giving a nice skill rotation animation on
my screen. The plain C version kinda ran close to the speed of the Basic mixed with
ASM version but a bit faster. Now the C mixed with ASM was blindly fast alone...
But in the end, the mighty and small pure ASM version proved faster and thus supreme
among the competition. I almosed urinated in my pants. It was so fast, that all
I could see was a grey blur, almost like a circle that flashed bigger and smaller.
Oh, I forgot to mention that if you hit space bar instead of Esc when the program ended,
it would give you an FPS average. The C mixed with ASM version was only 7 or
9 frames lower but the pure ASM version was quicker.

I really like ASM a lot but it's so cryptic and it's not as readable as C or Basic.

Chris :o)
 
ziggy880
  • Guest
Reply with quote
Re: Control; I like that word :o)
Post Posted: Sat Jul 24, 1999 2:18 am
Actually most compilers today do optimize better then most coders.
The truth is I do feel people should learn asm "for the platform they are working on primarily"
and I even prefer using it for older system development since most systems dont have c compilers and
those that do arent normally the best in the world "no insult intended"
and Id really like to know how asm is so cryptic its fucking baby steps to
an overall goal nothing about it is cryptic. I really find that most the coders
I admire think asm. They may program in pascal c c++ fortran basic but they know what
there code does and above all else thats whats important. print "hello, world" sounds
easy but you could just type hello,world into a text editor and then just save it if you
really want easy and dont care how the hell you really did it.
 
Chris
  • Guest
Reply with quote
Hehe, Acutally...
Post Posted: Sat Jul 24, 1999 5:22 am
Quote
> I'd really like to know how asm is so cryptic its fucking baby steps to
> an overall goal nothing about it is cryptic.

It's just cryptic for me because I'm a newbie to ASM. I'm used to Basic. Even C can become cryptic
at times when it comes to pointers, refereneces, and classes. But the more I use it, the more
I understand it and the easier it becomes to progarm under that environment. A couple of
minutes ago I wrote my first Windows program (more like copying what was out of the book
and modifying it to the way I like it). It simply loads a form that prints a blue rectangle box
around the letters "Hello, World". It's fun because I learned how to change the color of
the rectangle box, how to change the text string to whatever I want, how to change the
Form caption string to whatever I want, it's pretty cool. A lot of what I wrote I understood
but I just need to memorize the little functions, classes, and data types declared in
Windows.h. Oh, and I wrote the program under Visual C++ 1.0. Why? It came with the
CD contained in this book. I still have a copy of Visual C++ 5.0 and I have the Direct
X development libraries but I figured I'd better take my baby steps before I run and bump
my head into a wall or something, you know what I mean?

But back to the point. ASM is cryptic! You mean to tell me that copying your VGA segment
of memory into the AX register, using the bitwise operators and shifting to calculate the position
of the pixel you want to change, sending some hex number to the DX register (color) and
causing an interrupt just to print a pixel onto your screen, you call that baby steps!? You find
that's not cryptic, one bit? I'm sorry but ASM is cryptic! Why? It's difficult to learn and there's
so much crap that you've gotta memorize. There's so much shit that I already know in my
head but I can't express or explain that to you progie veterans. Give me a break. I think
it's cryptic. Mabye in a couple of months things will get easier but for now: it's cryptic.

Chris :o)
 
Reply to topic



Back to the top of this page

Back to SMS Power!