|
ForumsSega Master System / Mark III / Game GearSG-1000 / SC-3000 / SF-7000 / OMV |
Home - Forums - Games - Scans - Maps - Cheats - Credits Music - Videos - Development - Hacks - Translations - Homebrew |
Goto page 1, 2 Next |
Author | Message |
---|---|
|
My first SMS simple platform game test
Posted: Wed Nov 17, 2021 3:03 pm
|
Maybe it's nothing special, but my first attempt to write "something" on SMS :)
A simple demonstration of a platform game, you can jump, enemies are running - nothing else. Not tested on a real console, I'm curious if it will run: https://dl.dropboxusercontent.com/s/ktt4i0z0hzwun0s/plush_sms.sms At the same time, while learning the Z80 (WLA-DX), I wrote the GameBoy version: https://dl.dropboxusercontent.com/s/h4636pqe4sl4kx1/plush_gb.gb And the original version 6502 which I rewrote to the Z80: https://dl.dropboxusercontent.com/s/k46n7c3qliwnasn/plush_nes.nes Everything is going the right way at once and I hope we will be able to create something more specific on the SMS :) Regards. |
|
|
Posted: Wed Nov 17, 2021 4:22 pm |
you are writing VDP too fast that result in this. should be 29 t-states or more between sequential writes. |
|
|
Posted: Wed Nov 17, 2021 5:20 pm |
Thanks for the info, apparently my emulators didn't notice the problem (Gearsystem, MasterGear, Fusion).
I noticed that the problem is in the UpdateSAT function. What am I doing wrong? .ENUM $C000 SATBuf dsb 256 ; sat buffer .ENDE Forever: ; Infinite loop to stop program HALT CALL UpdateSAT JP Forever ;################################################################################ UpdateSAT: LD HL,$3F00 ; point to start of SAT in vram. CALL SetVDPAddress ; prepare vram to recieve data. LD B,255 ; amount of bytes to output. LD C,VDPData ; destination is vdp data port. LD HL,SATBuf ; source is start of sat buffer. OTIR ; output buffer to vdp. RET ;################################################################################ SetVDPAddress: ; vrampr PUSH AF LD A,L OUT (VDPControl),A LD A,H OR $40 OUT (VDPControl),A POP AF RET |
|
|
Posted: Wed Nov 17, 2021 8:16 pm |
Use Emulicious.
OTIR is too fast, use OUTI + JR loop. it is slow enough. |
|
|
Posted: Wed Nov 17, 2021 8:31 pm |
OTIR can't be run during VBL? | |
|
Posted: Wed Nov 17, 2021 8:45 pm |
If you share the full source code, it might be easier to help out. | |
|
Posted: Wed Nov 17, 2021 8:46 pm Last edited by siudym on Wed Nov 17, 2021 9:25 pm; edited 3 times in total |
Are there any sample sources showing correct SAT buffer sending?
EDIT: I moved "call UpdateSAT" from cpu (forever) loop to VBLANK and now it seems to work fine. https://dl.dropboxusercontent.com/s/ktt4i0z0hzwun0s/plush_sms.sms |
|
|
Posted: Wed Nov 17, 2021 9:23 pm |
You can otir or jump into an outi block to blast the data at max speed, if you are having problems it’s probably because the code is running after the active display has started up again. | |
|
Posted: Wed Nov 17, 2021 9:29 pm |
Thanks, it works:
UpdateSAT: LD HL,$3F00 CALL SetVDPAddress LD B,255 LD C,VDPData LD HL,SATBuf ; OTIR loop: OUTI JR NZ,loop RET *(Old UpdateSAT code also works with OTIR but moved to VBLANK.) |
|
|
Posted: Wed Nov 17, 2021 9:55 pm |
It seems like you draw on the Racer tutorial? Here, your UpdateSAT is called ldsat:
--------------------------------------------------------------
; LOAD SPRITE ATTRIBUTE TABLE ; Load data into sprite attribute table (SAT) from the buffer. ldsat ld hl,$3f00 ; point to start of SAT in vram. call vrampr ; prepare vram to recieve data. ld b,255 ; amount of bytes to output. ld c,$be ; destination is vdp data port. ld hl,satbuf ; source is start of sat buffer. otir ; output buffer to vdp. ret It is called almost as the first thing when a new vblank starts: mloop call wait
; Update vdp right when vblank begins! ld a,(scroll) ; 1-byte scroll reg. buffer in ram. ld b,9 ; target VDP register 9 (v-scroll). call setreg ; now vdp register = buffer, and the ; screen scrolls accordingly. call ldsat ; load sat buffer to vram. The cars ; and the (hi)-score sprites are ; updated on the screen. ... this way, it should finish in time :) Good luck with the project! |
|
|
Posted: Wed Nov 17, 2021 10:10 pm |
From this tutorial I only used the UpdateSAT code (ldsat). I analyzed many other sources. I have variables for sprites defined in the wram SAT Buffer: And any operations directly on these variables. .ENUM $C000 HERO_Y db ENEMY00_Y db ENEMY01_Y db ENEMY02_Y db ENEMY03_Y db ENEMY04_Y db ENEMY05_Y db ENEMY06_Y db ENEMY07_Y db (...) .ENDE .ENUM $C080 HERO_X db HERO_T db ENEMY00_X db ENEMY00_T db ENEMY01_X db ENEMY01_T db ENEMY02_X db ENEMY02_T db ENEMY03_X db ENEMY03_T db ENEMY04_X db ENEMY04_T db ENEMY05_X db ENEMY05_T db ENEMY06_X db ENEMY06_T db ENEMY07_X db ENEMY07_T db (...) .ENDE I don't know what the difference is between these two possibilities of synchronizing the CPU loop with VBLANK: ORG $0038 ; frame interrupt address. EX AF,AF' ; save accumulator in its shadow reg EXX IN A,$BF ; get vdp status / satisfy interrupt. LD (VDPStatus),A ; save vdp status in ram EXX EX AF,AF' ; restore accumulator. EI ; enable interrupts. RETI 1. Forever: HALT CALL UpdateSAT JP Forever 2. Forever: CALL WaitForFrameInterrupt CALL UpdateSAT JP Forever WaitForFrameInterrupt: ld a,(VDPStatus) bit 7,a jp z,WaitForFrameInterrupt res 7,a ld (VDPStatus),a ret They both work identically. ? |
|
|
Posted: Wed Nov 17, 2021 10:23 pm |
Yeah, I thought so too. But Calindro helped me realize that HALT will wait for any interrupt (including the pause button), not just vblank. It's in the conclusion of the Racer tutorial. In Calindro's words (in the Racer thread):
"I think I just identified your issue:
You're expecting VBLANK when the HALT instruction is left. But an NMI will also make the Z80 leave the HALT. While you're expecting VBLANK you're actually during active display. During that time you're writing your SAT using OTIR and that way kinda corrupt your sprite data which seems to quickly produce colliding sprites." So that is what made me transition to a focused "wait for vblank" routine :) |
|
|
Posted: Thu Nov 18, 2021 10:24 am |
it can |
|
|
Posted: Thu Nov 18, 2021 10:29 am |
into VBLANK interrupt ISR? then you will have troubles with drawing anything from main, because VDP is stateful, and there is no way to read that state for saving and restore. you can only disable/enable VDP access from VBLANK with some sort of mutexes. as for me, i suggest you to use a bit slower construction: loop: OUTI JR NZ,loop which is still fast enough for manipulating SAT, just call it from main where you need that. |
|
|
Posted: Thu Nov 18, 2021 11:34 am |
Thanks for the help.
I'm using Emulicious now (I've heard of it but never had Java installed and haven't used ...). I was interested in the 224 and 240p modes that SMS supports - my question is what are the limitations, etc., because most games work at 192 vertically? Since then, turning them on (bit4, bit3) in VDPControl does not change anything (or it will cause a problem and nothing will be displayed). I can ask for a quick info on this subject, because there are many topics while searching, but I didn't find the answer. |
|
|
Posted: Thu Nov 18, 2021 12:05 pm |
I think tilemap base address changes in these modes, and the 240 one only works on PAL machines with VDP2. | |
|
Posted: Thu Nov 18, 2021 12:41 pm |
The extended high modes were added later, so the first revision VDP doesn't support them - thus a game that uses those modes would be labelled as 'SMS II only', though it's slightly imprecise. |
|
|
Posted: Thu Nov 18, 2021 2:22 pm |
Ok, it's all clear.
In the past, I even heard that games from Codemasters often did not work on old SMS - I'm guessing, it's about higher resolution modes? |
|
|
Posted: Thu Nov 18, 2021 2:30 pm |
yes, it's!
Btw, I haven't been able to find a PAL SMS with the old VDP. |
|
|
Posted: Thu Nov 18, 2021 5:55 pm |
I don't understand this paragraph, maybe I misunderstand what you're trying to say. Can you elaborate? I always do all my vdp-related actions during the vblank interrupt routine and that has never caused any kind of problem at all. |
|
|
Posted: Thu Nov 18, 2021 10:55 pm |
If you tried to do something to VRAM from the non-interrupt code (without ei/di) then it might get interrupted and then change the VDP state (e.g. address, read/write mode). There are ways around this, of course. | |
|
Posted: Fri Nov 19, 2021 7:10 am |
Long periods when interrupts are disabled affect moment of ISR call, which can be easily moved out of vblank period too. |
|
|
Posted: Fri Nov 19, 2021 11:03 am |
That's obvious. I (mis)understood toxa like he tried to suggest that VDP access should always, or at least preferably, happen during active display and should be avoided during VBLANK, which is pretty much exactly the opposite of what I would recommend to a budding new developer. |
|
|
Posted: Sun Dec 26, 2021 5:36 pm |
I was interested in the older brother of the Sega Master System - the Sega SG-1000. A nice machine, similar to the MSX1 - the first two, simple demos:
https://dl.dropboxusercontent.com/s/4jxilxumeyvkbjy/sg1000demo.sg https://dl.dropboxusercontent.com/s/cyompte6mj3j1xm/msxdemo.rom https://dl.dropboxusercontent.com/s/h5n67zb70nsoa4d/sg1000bomberdemo.sg https://dl.dropboxusercontent.com/s/djvb13lhhfgpdns/msxbomberdemo.rom Does this console have any mappers? Are we limited to 32KB ROM? |
|
|
Posted: Sun Dec 26, 2021 8:27 pm |
Mappers are a feature of the cartridge, but no SG-1000 releases had ROM paging. You should probably assume the Master System standard mapper is supported by emulators. | |
|
Posted: Mon Dec 27, 2021 4:02 am |
Loretta's Portrait had to have a mapper if it was a 128KB game, I think.
I believe that was the final SG-1000 game, or did Sega brand it a Mark III game, I can't recall. |
|
|
Posted: Mon Dec 27, 2021 8:48 am |
It was packaged as a Mark III "Gold Cartridge" but apparently it is SG-1000 compatible (using only 1KB RAM and TMS9918a video modes). | |
|
Posted: Mon Dec 27, 2021 9:06 am |
I see some games are 48KB size ie $ 8000-BFFF space is also available? Because the documentation describes this address as "unused":
0x0000 ------------------------------------------------ ROM (read-only) 0x8000 ------------------------------------------------ Unused on SG-1000 0xA000 ------------------------------------------------ RAM (read/write) 0xC000 ------------------------------------------------ Mirror of RAM (read/write) 0xFFFF ------------------------------------------------ |
|
|
Posted: Mon Dec 27, 2021 10:39 am |
It’s not unused, it’s mapped from the cartridge to the CPU. Many SG-1000 games have variants where the ROM is split and some is mapped to start at 32KB. | |
|
Posted: Sun Jan 02, 2022 3:29 pm |
How can I turn off the screen (black screen) on SG-1000? When writing to VDP Register 1 the screen does not go black, but rendering freezes and the graphics are still visible:
LD A,%00100000 ; Turn screen off (6-EnableDisp,5-VBlank,1-DoubleSPR,0-ZoomedSPR OUT ($BF),A LD A,$81 OUT ($BF),A |
|
|
Posted: Sun Jan 02, 2022 6:22 pm |
For me it works by writing $A0 to register 1 |
|
|
Posted: Mon Jan 03, 2022 9:23 am |
I don't know where I go wrong, but it always freezes rendering for me, not turning off the screen (black).
For example, it works in the SMS code, but not in the SG-1000. |
|
|
Posted: Mon Jan 03, 2022 5:26 pm |
I would enclose the two OUT in a DI/EI pair to make sure nothing happens in between those two. | |
|
Posted: Mon Jan 03, 2022 6:05 pm |
Still the same, the screen freezes but is visible. | |
|
Posted: Mon Jan 03, 2022 6:46 pm |
'screen freezes' as in 'game freezes'?
because the screen freeze usually means the game is stuck in some infinite loop check you're not waiting for a disabled interrupt, you're probably setting the register #1 again to some other value and you get the screen on and the interrupt off instead of the other way around... |
|
|
Posted: Mon Jan 03, 2022 7:34 pm |
No. The mechanics of the game work (in the background), only the screen freezes as if it has stopped being rendered, but it does not go black. The same code in the SMS turns off the screen, on SG-1000 not.
So when it executes this code (disable rendering bit6 VDP Register 1) and the screen freezes instead of turning off (black). Rendering turns off, but the screen does not go black. There is no struck in any loop. That is why I am surprised why I do not want to turn off/black the SG-1000. LD A,%00000000 ; LD A,0 / LD A,%00100010 DI OUT ($BF),A LD A,$81 OUT ($BF),A EI For example: Pressing pad 1/2 will turn off rendering (same code above) : https://dl.dropboxusercontent.com/s/kd97uhm1tut5nu8/output.sg EDIT: It's clear now ... It's an emulator problem: Emulicious - Freeze Screen Fusion, Gearsystem - Ok (Black Screen) |
|
|
Posted: Tue Jan 04, 2022 12:08 pm |
oh I really thought you were getting that on hardware...
good you've found out the problem wasn't in the code :) |
|
|
Posted: Thu Jan 06, 2022 4:24 pm |
Does PSGLib also work with SG-1000? And what are the requirements for PSGLib memory, because SG-1000 has only 1KB WRAM. Or are there any sound library alternatives for the SG-1000? | |
|
Posted: Thu Jan 06, 2022 4:42 pm |
PSGlib works with SG-1000 too. It should require approximately 40 bytes of RAM. | |
|
Posted: Wed Jan 26, 2022 9:32 pm |
INIT code (for WLA-DX) for SG-1000 (MODE 1 / SCREEN 1) - I don't know if I'm doing everything correctly. There is not much information about the SG-1000 and I would like to be sure it initializes everything correctly:
Do I have to change the stack pointer to the end of $ C000? Because I noticed it is by default, at the end FFFF (RAM Mirror) - it works under the emulator, but will there be no problems on real hardware? .MEMORYMAP DEFAULTSLOT 0 SLOTSIZE $8000 SLOT 0 $0000 .ENDME .ROMBANKMAP BANKSTOTAL 1 BANKSIZE $8000 BANKS 1 .ENDRO ;------------------------- .ENUM $C000 ; variables .ENDE ;------------------------- .BANK 0 SLOT 0 .ORG 0 DI IM 1 JP MAIN ;------------------------- .ORG $0038 ; frame interrupt address. EX AF,AF' ; save accumulator in its shadow reg EXX IN A,$BF ; get vdp status / satisfy interrupt. LD (VDPStatus),A ; save vdp status in ram LD A,1 ; LD (VBlankFlag),A ; EXX EX AF,AF' ; restore accumulator. EI ; enable interrupts. RETI ; return from interrupt ;------------------------- .ORG $0066 ; pause button interrupt RETN ; disable pause button. ;------------------------- MAIN: LD C,$BF LD E,$80 LD A,%00000000 ; screen 1 OUT (C),A OUT (C),E ;------------------------- LD A,%01100010 ; Register 1 - b6=display,b5=vblank,bit1=doublespr,bit0=zoomedspr LD E,$81 OUT (C),A OUT (C),E ;------------------------- XOR A ; Register 2 Pattern Name Table Adres (Tile Map) LD A,%00000110 LD E,$82 OUT (C),A OUT (C),E ;------------------------- LD A,%10000000 ; Register 3 - Colour Table Adres LD E,$83 OUT (C),A OUT (C),E ;------------------------- LD A,%00000000 ; Register 4 - Pattern Generator Table Adres (Pattern Table) LD E,$84 OUT (C),A OUT (C),E ;------------------------- LD A,%00110110 ; Registers 5 (Sprite attribute) LD E,$85 OUT (C),A OUT (C),E ;------------------------- LD A,%00000111 ; Register 6 (Sprite pattern) LD E,$86 OUT (C),A OUT (C),E ;------------------------- LD A,15 ; Register 7 - Set colors LD E,$87 ; Bits 0 to 3 code for the transparent color. OUT (C),A ; Setting them to 0 mean a black color, else the color is taken in the palette. OUT (C),E EI HALT ;------------------------- Forever: HALT ; game loops JP Forever |
|
|
Posted: Thu Jan 27, 2022 10:14 am |
stack pointer is better set at $DFF0 as addresses $FFF0-$FFFF could be connected to hardware (mappers, 3D glasses etc) on a Master System.
since this is an SG-1000 program, you can probably set it at $C3FF and you should be fine on both systems also, you might want to ensure VDP is indeed ready before sending commands/data to it and, depending on how you handle your variables, you might want to zero the RAM too on a side note: you don't really need those two EXX in your ISR, as you're not touching any register that's not A or F. |
|
|
Posted: Thu Jan 27, 2022 12:19 pm |
Is it better to set the SP to C3FF or C400? (SG-1000)
DI LD SP,$C400 ; C400-1 IM 1 or DI LD SP,$C3FF IM 1 I have a problem with the WRAM cleaning function - I want to clear the memory of 1008 bytes (3F0), and looking at the WRAM preview in Emulicious, I have a smaller amount (2F0) cleared: https://i.postimg.cc/1XGt0Kg8/wram.png ClearWRAM: LD HL,$C000 LD BC,1008 ;I leave 16 bytes so the stack doesn't crash LD A,$00 ClearWRAM_Loop: LD (HL),A INC HL DEC C JR NZ,ClearWRAM_Loop DEC B JR NZ,ClearWRAM_Loop RET And do I also need to clean the WRAM Mirror on the SG-1000? I have a problem with the code, because everything works on emulators and real hardware doesn't work. |
|
|
Posted: Thu Jan 27, 2022 12:35 pm |
to clear RAM, you could write 00 to $C000 then LDIR 1024-1 times with source $C000 and dest $C001 - it's just less code
mirror RAM is the same RAM at a different address, so you don't need to zero that RAM twice as for SP, I would use $C3FF... I can't remember if using $C400 would overwrite first byte in RAM (maybe not but I wouldn't risk it for one byte...) what do you get on hardware? |
|
|
Posted: Thu Jan 27, 2022 1:24 pm |
The first run I did not have SP set at all = rom did not boot. Now, with Sp set up, it boot, but there are errors probably caused by uncleaned WRAM. I'll change Clear WRAM and it should work.
ClearWRAM: LD A,$00 LD ($C000),A LD HL,$C000 LD DE,$C001 LD BC,1024-16 ; with -1 not run LDIR RET It looks ok, it works, need to check on the Sg-1000. |
|
|
Posted: Thu Jan 27, 2022 3:47 pm |
XOR A ; faster and smaller than LD A,$00
LD HL,$C000 LD (HL),A ; faster and smaller than LD ($C000),A LD DE,$C001 LD BC,1024-16 ; with -1 not run LDIR RET |
|
|
Posted: Wed Feb 02, 2022 6:43 pm |
Going back to the maximum ROM size on the SG-1000 - do I have to pay attention to something important when I want to make a 48KB ROM? ($ 0000- $ BFFF). For example, in WLA-DX I create three 16KB slots and it will work properly ?:
SLOT 0 START $ 0000 SIZE $ 4000; ROM 0 SLOT 1 START $ 4000 SIZE $ 4000; ROM 1 SLOT 2 START $ 8000 SIZE $ 4000; ROM 2 And how is it in terms of hardware - will the cartridge connector support e.g. EPROM 27C512 (A15)? Or maybe it will be necessary to do some split into two ROMs, e.g. 27C256 + 27C128? (I have no idea what the catridge inside looks like when the game is 48KB) |
|
|
Posted: Thu Feb 03, 2022 6:02 pm |
you can even create a single 48 KiB bank, since there's no mapper you won't be paging anyway
the cartridge can use a 64 KiB ROM chip, the contents of the last 16 KiB won't ever be accessed |
|
|
Posted: Thu Feb 03, 2022 7:59 pm |
Ok it works. I thought it would be a problem if I set the bank / slot size to unequal.
.MEMORYMAP DEFAULTSLOT 0 SLOTSIZE $C000 SLOT 0 $0000 .ENDME .ROMBANKMAP BANKSTOTAL 1 BANKSIZE $C000 BANKS 1 .ENDRO |
|
|
Posted: Mon Feb 21, 2022 8:32 pm |
According to Enri, the 48KiB ROM cartridge used the 171-5180 board with two ROM chips, one 32KiB the other 16KiB. Still, this was (probably) done because chips in these sizes were readily available, and wasting 16KiBs on empty space would have increased costs unnecessarily. Interestingly, the only (official) game I could find that actually used the full 48KiB available to the SG-1000/SC-3000 was "Home Mahjongg" (G-1030). |
|
|
Posted: Mon Feb 21, 2022 9:12 pm |
(siudym: would be better to use zipped attachments rather than dropbox links, as the later will eventually disappear.) | |
Goto page 1, 2 Next |