Skip to content

Commit 48ca152

Browse files
committed
Savaged articles/txt files
1 parent c8e9f8e commit 48ca152

25 files changed

+2747
-2
lines changed

LICENSE

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
Copyright (c) 2015-2016 Antonio Vivace
1+
Copyright (c) 2015-2017 Antonio Vivace
22

33
DISCLAIMER
44
No commercial adaptation or implementation of this material is allowed
55
since the Game Boy platform is copyrighted by Nintendo and this is just
66
a collection of private hacking passionates that managed to write working
7-
code and hw mods to the original Nintendo paltform.
7+
code and hardware mods to the original Nintendo platform.
88
Nintendo never authorised or endorsed in anyway this type of work.
99

1010
GNU GENERAL PUBLIC LICENSE

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ An online converter, translates gameboy assembly into Pokémon R/B/Y items ([Sou
188188
- [GameBoy Color DMA-Transfers v0.0.1](http://gameboy.mongenel.com/dmg/gbc_dma_transfers.txt)
189189
- [STAT interrupt timings](http://gameboy.mongenel.com/dmg/istat98.txt)
190190

191+
#### Old articles
192+
[This](https://github.com/avivace/awesome-gbdev/tree/master/articles/savaged) folder is an historical archive of old articles, FAQs and in general text documents about the game boy development. Note that a lot of information may be wrong or obsolete - they are archived for historical reasons.
193+
191194
### C
192195
- [8-Bit Wonderland](http://belial.blarzwurst.de/gbpaper/paper.pdf) - Well-written introductory document about how the Game Boy works and how to start developing working code for it.
193196
- [Grooves Game Boy Programming](https://github.com/gbdk-salvage/grooves-game-boy-programming) - A complete set of lessons about implementing various game mechanics in a Game Boy game.

articles/savaged/2player.txt

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
Fast Two Player Code using RGBASM
2+
(or Fast OOP using RGBASM)
3+
Written by GeeBee
4+
With an addition by Otaku
5+
6+
As an example, let's say you have an assembly language two
7+
player game that you are working on where the majority of
8+
the code for player one might be identical for player two.
9+
There are basically two ways of handling this:
10+
11+
1) Pass a pointer to these routines that points to the
12+
"object" structure that you wish to process.
13+
14+
2) Repeat all of these code routines using slightly
15+
different function/variable names.
16+
17+
The advantage to using approach number 1 is that you can
18+
have two or more objects that share the same code routines.
19+
One disadvantage is the code will be slower than approach
20+
2 because you have to access the object structure through
21+
a pointer. Also this pointer can tie up valuable GB registers
22+
which can cause longer/slower code due to fewer available
23+
registers.
24+
25+
The advantage to using approach number 2 is that since your
26+
object data doesn't have to be accessed through a pointer the
27+
code can be much quicker which sometimes is very important
28+
on the limited GB/GBC platform. The disadvantages are that
29+
code must be repeated for each object (which can rapidly eat
30+
up ROM space for a large number of objects) and having several
31+
identical routines (with different function & variable names)
32+
is a big maintenance problem when the same changes need to be
33+
applied to each object.
34+
35+
36+
If you can get around the maintenance problems of approach
37+
number 2, this can be ideal in some cases where you need
38+
fast execution speed OR in cases where you have just finished
39+
coding a 1 player game and as an after-thought you decide to
40+
add 2 player support but you don't want to rewrite your code
41+
to use object pointers.
42+
43+
RGBASM is powerful enough that you can eliminate the majority
44+
of the maintenance problems in this case. Here's example code:
45+
(The macro operator '@' is incremented with each macro included
46+
in your source code so this code needs to be compiled stand-alone
47+
and then linked with other code or you must guarantee that no
48+
macros are included before this code. The macro FOO below is
49+
only used to increment '@' from 0 to 1 so that the first object
50+
ends with _1 instead of _0.)
51+
52+
53+
ObjectX_1: DB
54+
ObjectY_1: DB
55+
ObjectX_2: DB
56+
ObjectY_2: DB
57+
58+
FOO: MACRO
59+
db 0
60+
ENDM
61+
62+
; Set Object X,Y coordinates to H,L
63+
64+
OBJCODE: MACRO
65+
66+
SetObjectPos\@:
67+
ld a,h
68+
ld [ObjectX\@],a
69+
ld a,l
70+
ld [ObjectY\@],a
71+
ret
72+
73+
GetObjectPos\@:
74+
ld a,[ObjectX\@]
75+
ld h,a
76+
ld a,[ObjectY\@]
77+
ld l,a
78+
ret
79+
80+
ENDM
81+
82+
; Include code for object #1
83+
OBJCODE
84+
; Include code for object #2
85+
OBJCODE
86+
87+
; Set Object 1 coordinates to 0,0
88+
ld hl,0
89+
call SetObjectPos_1
90+
91+
; Set Object 2 coordinates to 0,0
92+
ld hl,0
93+
call SetObjectPos_2
94+
95+
; Return Object 1 coordinates in H,L
96+
call GetObjectPos_1
97+
98+
; Return Object 2 coordinates in H,L
99+
call GetObjectPos_2
100+
101+
--
102+
added by Otaku
103+
104+
Using SET to point to the start of your object
105+
structure, and then calculating offsets into the
106+
object structure is a neater way of doing this,
107+
without having to worry about an idle use of MACRO
108+
incrementing the @ counter.
109+
110+
So:
111+
Object1: DS 16
112+
Object2: DS 16
113+
114+
RSRESET
115+
X_POS RB 2
116+
Y_POS RB 2
117+
HEALTH RB 1
118+
119+
120+
; assume that x & y are passed in BC & DE
121+
; assume for this example that GB has the ability
122+
; to move registers directly to memory without using
123+
; the A register
124+
SetObjectPos: MACRO
125+
ObjectBase SET \1
126+
LD [ObjectBase+X_POS],C
127+
LD [ObjectBase+X_POS+1],B
128+
LD [ObjectBase+Y_POS],E
129+
LD [ObjectBase+Y_POS+1],D
130+
PURGE ObjectBase
131+
ENDM
132+
133+
SetObject1Pos:
134+
SetObjectPos Object1
135+
RET
136+
SetObject2Pos:
137+
SetObjectPos Object2
138+
RET
139+
140+
141+
142+

articles/savaged/2xsprites.txt

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Some ideas for why sprites would disappear in 2x Speed Mode
2+
Written by Jan-Lieuwe Koopmans
3+
4+
5+
6+
- You move your sprites using an ISR (interrupt service routine) and that
7+
particular interrupt is disabled by the cpu-speed switch routine (IE_REG
8+
being altered);
9+
10+
11+
- Bit 1 of the LCDC register is somehow set to zero;
12+
13+
14+
- The DMA copy of OAM workram to real OAM ram is not done anymore (that
15+
routine is in HiRam and is being called by the default VBL ISR).
16+
17+
18+
- Your sprite-tiles are not being copied to VRAM in a proper way.
19+
20+
21+
22+
You can check all these easily using No$Gmb (press F10 in debug mode to see
23+
register contents, check HiRam (starting at $FF80) using the debugger, check
24+
Video RAM using F5 in debug mode).
25+
26+
27+
28+

articles/savaged/JPtable.txt

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
by The ZenPsycho
2+
3+
;*****************************
4+
;* Jump table code *
5+
;*****************************
6+
;
7+
;******************************************************************
8+
;
9+
; on entry:
10+
; A = Address offset
11+
;
12+
; Registers used:
13+
; A, HL, DE
14+
;
15+
; on exit:
16+
; A destroyed
17+
; hl contains address from jump table
18+
;
19+
; place this routine at reset $08
20+
;
21+
; [example code]
22+
; (If A=0 then jp this)
23+
; (if A=1 then jp that)
24+
; (if A=2 then jp theother)
25+
;
26+
; RST $08 ;call function to jump to address from pointer table
27+
; DB this ;pointer table
28+
; DB that
29+
; DB theother
30+
;
31+
;
32+
;******************************************************************
33+
34+
35+
pop hl ;get address of first pointer from stack
36+
push de ;preserve DE
37+
add a,a ;multiply A by two
38+
ld e,a ;store A in E
39+
ld d,00 ;so that we can
40+
add hl,de ;add the offset to hl
41+
ldi a,(hl) ;and now
42+
ld h,(hl) ;get an address from the pointer table
43+
ld l,a ;
44+
pop de ;restore DE
45+
jp hl ;and jump to address from table
46+
47+
48+
49+
50+
51+
52+
53+
54+
;*****************************************************************
55+
56+
pop hl ;get address
57+
push bc ;preserve BC
58+
ld c,a ;get offset from A into BC
59+
ld b,00 ;
60+
ldi a,(hl) ;load from address into A and increment address
61+
push hl ;store address+1
62+
add hl,bc ;add offset to address+1
63+
ld c,a ;get data from address+1 into BC (B still=0)
64+
ld a,(hl) ;get data from address+1+offset
65+
pop hl ;restore address+1
66+
add hl,bc ;
67+
pop bc ;
68+
jp hl ;
69+
70+
;*****************************************************************

articles/savaged/LUtable.txt

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
;***************************************
2+
;* Lookup table function *
3+
;***************************************
4+
;
5+
; On entry:
6+
; A contains table index
7+
;
8+
; registers used:
9+
; A, HL, BC
10+
;
11+
; On exit:
12+
; A contains table entry
13+
; HL contains address of the end of the table
14+
; BC is preserved
15+
;
16+
; this function is placed at $0018
17+
;
18+
; [Example Code]
19+
; LD A, $04
20+
; CALL TABLE
21+
;
22+
; TABLE:
23+
; RST $18 ;call table look up function , push PC onto stack
24+
; DB $06 ;number of bytes in table
25+
; DB $06, $05, $04, $03, $02, $01 ;table data
26+
; ret
27+
;
28+
; after running this code the accumulator (A) contains $02
29+
;
30+
;************************************************************************
31+
32+
33+
POP HL ;Load address from stack
34+
PUSH BC ;preserve BC
35+
LD C,A ;Load index
36+
LD B,0 ;into BC
37+
LD A,[HLI] ;Load size of table into A
38+
PUSH HL ;preserve the address of the start of the table
39+
ADD HL,BC ;HL now points to table index
40+
LD C,A ;load size of table into BC
41+
LD A,[HL] ;A now contains Table entry at the specified index
42+
POP HL ;to the start address of the table,
43+
ADD HL,BC ;add the size of the table
44+
POP BC ;restore BC
45+
JP HL ;and jump to the instruction AFTER the table
46+

articles/savaged/ZenDMA.txt

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
Ok so you want sprites in your gameboy game/demo. You've got a DMA routine, you know how it works. What you don't know is what is the quickest, best way to copy it into HRAM at $FF80. That's where document comes in. I'm going to teach you how to use a routine that will allow you to easily copy data to ram. and this isn't only good for copying your DMA routine, you can use it to copy tile data and other bits of assorted code into ram, easily. the first thing you do is you put the following routine at $0028, like this:
2+
3+
4+
SECTION "COPY DATA",home[$0028]
5+
6+
POP HL
7+
PUSH BC
8+
LD A,[HLI]
9+
LD B,A
10+
LD A,[HLI]
11+
LD C,A
12+
copydataloop:
13+
LD A,[HLI]
14+
LD [DE],A
15+
INC DE
16+
DEC BC
17+
LD A,B
18+
OR C
19+
JR NZ, copydataloop
20+
POP BC
21+
JP [HL]
22+
23+
24+
The reason we put it at $0028 is because it's a reset code. which means you only need one byte to call the code that's there, as opposed to the 3 bytes you use in a normal call.
25+
I'll explain this code a little later, but for now I will show you how to use it. We'll create a new file called "DMA.INC". in this file you put this:
26+
27+
28+
DMACOPY:
29+
LD DE, $FF80 ;$FF80 is where we want to copy this data
30+
RST $28 ;Call the copy routine
31+
DB $00, $0D ;the amount of bytes we want to copy,
32+
;represented in a 16 bit unsigned integer.
33+
34+
35+
;And now the data. This is a DMA routine.
36+
;Hand assembled. It copies data from $C100
37+
38+
DB $F5, $3E, $C1, $EA, $46, $FF, $3E, $28, $3D, $20, $FD, $F1, $D9
39+
40+
RET
41+
42+
43+
now save this file, and include it in your main file. then when you want to copy the DMA routine to $FF80,
44+
45+
CALL DMACOPY
46+
47+
simple huh?
48+
ok now let's explore how the routine itself works.
49+
50+
51+
52+
POP HL ;when you call RST $28, it pushes the address of the
53+
;byte immediately following it, onto the stack.
54+
;this instruction stores that address into HL
55+
PUSH BC ;(preserve BC)
56+
LD A,[HLI] ;This copies the byte at that address into B
57+
LD B,A ;which is the MSB of the amount of bytes we want to
58+
LD A,[HLI] ;copy. Then this copies the LSB into C.
59+
LD C,A ;Now HL should point at the first byte of our data
60+
copydataloop:
61+
LD A,[HLI] ;Copy that byte into a
62+
LD [DE],A ;then copy a to the address contained in DE ($FF80)
63+
INC DE ;Increment the address in DE.
64+
DEC BC ;One byte down, BC to go
65+
LD A,B ;then OR B and C together
66+
OR C ;to find out if BC = 0
67+
JR NZ, copydataloop ;if it isn't, copy another byte
68+
POP BC ;(restore BC)
69+
JP [HL] ;Jump to the byte after the data, which is a RET
70+
71+
72+
73+
Pretty clever eh?
74+
75+
If you have any questions or comments, E-mail me at [email protected]
76+
77+
78+

0 commit comments

Comments
 (0)