Skip to content

Commit 97e979b

Browse files
Rangi42ISSOtm
andauthored
Release hardware.inc version 4.11 (#54)
* Add `rSYS` alias for `rKEY0` * Add separate bit number and flag constants for each audio channel * Refactored the `rev_Check_hardware_inc` macro * Add comments in rev_Check_hardware_inc Co-authored-by: Eldred Habert <[email protected]> * Update date --------- Co-authored-by: Eldred Habert <[email protected]>
1 parent f2d8ebb commit 97e979b

File tree

2 files changed

+120
-56
lines changed

2 files changed

+120
-56
lines changed

HISTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,7 @@
8484
- Deprecate memory region and cartridge header constants
8585
- Changed formatting and reorganized sections
8686
- Moved revision history to separate HISTORY.md file
87+
- **Rev 4.11.0** - 2025-05-22 *(Rangi42)*
88+
- Added `rSYS` alias for `rKEY0`
89+
- Added separate bit number and flag constants for each audio channel
90+
- Refactored the `rev_Check_hardware_inc` macro

hardware.inc

Lines changed: 116 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,24 @@ endc
2222
; Define the include guard and the current hardware.inc version
2323
; (do this after the RGBDS version check since the `def` syntax depends on it)
2424
def HARDWARE_INC equ 1
25-
def HARDWARE_INC_VERSION equs "4.10.0"
25+
def HARDWARE_INC_VERSION equs "4.11.0"
2626

2727
; Usage: rev_Check_hardware_inc <min_ver>
2828
; Examples:
2929
; rev_Check_hardware_inc 1.2.3
3030
; rev_Check_hardware_inc 1.2 (equivalent to 1.2.0)
3131
; rev_Check_hardware_inc 1 (equivalent to 1.0.0)
3232
MACRO rev_Check_hardware_inc
33-
def hw_inc_cur_ver\@ equs strrpl("{HARDWARE_INC_VERSION}", ".", ",")
34-
def hw_inc_min_ver\@ equs strrpl("\1", ".", ",")
35-
def hw_inc_def_check\@ equs """MACRO hw_inc_check\@
36-
if \\1 != \\4 || (\\2 < \\5 || (\\2 == \\5 && \\3 < \\6))
37-
fail "Version \\1.\\2.\\3 of 'hardware.inc' is incompatible with requested version \\4.\\5.\\6"
33+
if _NARG == 1 ; Actual invocation by the user
34+
def hw_inc_cur_ver\@ equs strrpl("{HARDWARE_INC_VERSION}", ".", ",")
35+
def hw_inc_min_ver\@ equs strrpl("\1", ".", ",")
36+
rev_Check_hardware_inc {hw_inc_cur_ver\@}, {hw_inc_min_ver\@}, 0, 0
37+
purge hw_inc_cur_ver\@, hw_inc_min_ver\@
38+
else ; Recursive invocation
39+
if \1 != \4 || (\2 < \5 || (\2 == \5 && \3 < \6))
40+
fail "Version \1.\2.\3 of 'hardware.inc' is incompatible with requested version \4.\5.\6"
3841
endc
39-
\nENDM"""
40-
hw_inc_def_check\@
41-
hw_inc_check\@ {hw_inc_cur_ver\@}, {hw_inc_min_ver\@}, 0, 0
42-
purge hw_inc_cur_ver\@, hw_inc_min_ver\@, hw_inc_def_check\@, hw_inc_check\@
42+
endc
4343
ENDM
4444

4545

@@ -194,31 +194,27 @@ def AUD1SWEEP_SHIFT equ %00000_111 ; how much the period increases/decreases per
194194
; Audio channel 1 length timer and duty cycle
195195
def rAUD1LEN equ $FF11
196196

197-
; These values are also applicable to AUD2LEN
198-
def AUDLENF_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w]
199-
def AUDLEN_DUTY_12_5 equ %00_000000 ; 12.5%
200-
def AUDLEN_DUTY_25 equ %01_000000 ; 25%
201-
def AUDLEN_DUTY_50 equ %10_000000 ; 50%
202-
def AUDLEN_DUTY_75 equ %11_000000 ; 75%
197+
def AUD1LENF_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w]
198+
def AUD1LEN_DUTY_12_5 equ %00_000000 ; 12.5%
199+
def AUD1LEN_DUTY_25 equ %01_000000 ; 25%
200+
def AUD1LEN_DUTY_50 equ %10_000000 ; 50%
201+
def AUD1LEN_DUTY_75 equ %11_000000 ; 75%
203202

204-
; This value is also applicable to AUD2LEN and AUD4LEN
205-
def AUDLENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo]
203+
def AUD1LENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo]
206204

207205
; -- AUD1ENV / NR12 ($FF12) ---------------------------------------------------
208206
; Audio channel 1 volume and envelope
209207
def rAUD1ENV equ $FF12
210208

211-
; Values are also applicable to AUD2ENV and AUD4ENV
209+
def AUD1ENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w]
212210

213-
def AUDENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w]
211+
def AUD1ENVB_DIR equ 3 ; direction of volume envelope [r/w]
212+
def AUD1ENVF_DIR equ 1 << AUD1ENVB_DIR
213+
def AUD1ENV_DOWN equ 0 << AUD1ENVB_DIR
214+
def AUD1ENV_UP equ 1 << AUD1ENVB_DIR
214215

215-
def AUDENVB_DIR equ 3 ; direction of volume envelope [r/w]
216-
def AUDENVF_DIR equ 1 << AUDENVB_DIR
217-
def AUDENV_DOWN equ 0 << AUDENVB_DIR
218-
def AUDENV_UP equ 1 << AUDENVB_DIR
219-
220-
def AUDENVF_PACE equ %00000_111 ; how long between envelope iterations
221-
; (in 64 Hz ticks, ~15.6 ms apart) [r/w]
216+
def AUD1ENVF_PACE equ %00000_111 ; how long between envelope iterations
217+
; (in 64 Hz ticks, ~15.6 ms apart) [r/w]
222218

223219
; -- AUD1LOW / NR13 ($FF13) ---------------------------------------------------
224220
; Audio channel 1 period (low 8 bits) [r/w]
@@ -228,29 +224,41 @@ def rAUD1LOW equ $FF13
228224
; Audio channel 1 period (high 3 bits) and control
229225
def rAUD1HIGH equ $FF14
230226

231-
; Values are also applicable to AUD2HIGH and AUD3HIGH
232-
233-
def AUDHIGHB_RESTART equ 7 ; 1 = restart the channel [wo]
234-
def AUDHIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w]
235-
def AUDHIGH_RESTART equ 1 << AUDHIGHB_RESTART
236-
def AUDHIGH_LENGTH_OFF equ 0 << AUDHIGHB_LEN_ENABLE
237-
def AUDHIGH_LENGTH_ON equ 1 << AUDHIGHB_LEN_ENABLE
227+
def AUD1HIGHB_RESTART equ 7 ; 1 = restart the channel [wo]
228+
def AUD1HIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w]
229+
def AUD1HIGH_RESTART equ 1 << AUD1HIGHB_RESTART
230+
def AUD1HIGH_LENGTH_OFF equ 0 << AUD1HIGHB_LEN_ENABLE
231+
def AUD1HIGH_LENGTH_ON equ 1 << AUD1HIGHB_LEN_ENABLE
238232

239-
def AUDHIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w]
233+
def AUD1HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w]
240234

241235
; -- $FF15 is unused ----------------------------------------------------------
242236

243237
; -- AUD2LEN / NR21 ($FF16) ---------------------------------------------------
244238
; Audio channel 2 length timer and duty cycle
245239
def rAUD2LEN equ $FF16
246240

247-
; Values are reused from AUD1LEN
241+
def AUD2LENF_DUTY equ %11_000000 ; ratio of time spent high vs. time spent low [r/w]
242+
def AUD2LEN_DUTY_12_5 equ %00_000000 ; 12.5%
243+
def AUD2LEN_DUTY_25 equ %01_000000 ; 25%
244+
def AUD2LEN_DUTY_50 equ %10_000000 ; 50%
245+
def AUD2LEN_DUTY_75 equ %11_000000 ; 75%
246+
247+
def AUD2LENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo]
248248

249249
; -- AUD2ENV / NR22 ($FF17) ---------------------------------------------------
250250
; Audio channel 2 volume and envelope
251251
def rAUD2ENV equ $FF17
252252

253-
; Values are reused from AUD1ENV
253+
def AUD2ENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w]
254+
255+
def AUD2ENVB_DIR equ 3 ; direction of volume envelope [r/w]
256+
def AUD2ENVF_DIR equ 1 << AUD2ENVB_DIR
257+
def AUD2ENV_DOWN equ 0 << AUD2ENVB_DIR
258+
def AUD2ENV_UP equ 1 << AUD2ENVB_DIR
259+
260+
def AUD2ENVF_PACE equ %00000_111 ; how long between envelope iterations
261+
; (in 64 Hz ticks, ~15.6 ms apart) [r/w]
254262

255263
; -- AUD2LOW / NR23 ($FF18) ---------------------------------------------------
256264
; Audio channel 2 period (low 8 bits) [r/w]
@@ -260,7 +268,13 @@ def rAUD2LOW equ $FF18
260268
; Audio channel 2 period (high 3 bits) and control
261269
def rAUD2HIGH equ $FF19
262270

263-
; Values are reused from AUD1HIGH
271+
def AUD2HIGHB_RESTART equ 7 ; 1 = restart the channel [wo]
272+
def AUD2HIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w]
273+
def AUD2HIGH_RESTART equ 1 << AUD2HIGHB_RESTART
274+
def AUD2HIGH_LENGTH_OFF equ 0 << AUD2HIGHB_LEN_ENABLE
275+
def AUD2HIGH_LENGTH_ON equ 1 << AUD2HIGHB_LEN_ENABLE
276+
277+
def AUD2HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w]
264278

265279
; -- AUD3ENA / NR30 ($FF1A) ---------------------------------------------------
266280
; Audio channel 3 enable
@@ -292,21 +306,35 @@ def rAUD3LOW equ $FF1D
292306
; Audio channel 3 period (high 3 bits) and control
293307
def rAUD3HIGH equ $FF1E
294308

295-
; Values are reused from AUD1HIGH
309+
def AUD3HIGHB_RESTART equ 7 ; 1 = restart the channel [wo]
310+
def AUD3HIGHB_LEN_ENABLE equ 6 ; 1 = reset the channel after the length timer expires [r/w]
311+
def AUD3HIGH_RESTART equ 1 << AUD3HIGHB_RESTART
312+
def AUD3HIGH_LENGTH_OFF equ 0 << AUD3HIGHB_LEN_ENABLE
313+
def AUD3HIGH_LENGTH_ON equ 1 << AUD3HIGHB_LEN_ENABLE
314+
315+
def AUD3HIGHF_PERIOD_HIGH equ %00000_111 ; upper 3 bits of the channel's period [r/w]
296316

297317
; -- $FF1F is unused ----------------------------------------------------------
298318

299319
; -- AUD4LEN / NR41 ($FF20) ---------------------------------------------------
300-
; Audio channel 4 length timer [wo]
320+
; Audio channel 4 length timer
301321
def rAUD4LEN equ $FF20
302322

303-
; AUDLENF_TIMER value is reused from AUD1LEN
323+
def AUD4LENF_TIMER equ %00_111111 ; initial length timer (0-63) [wo]
304324

305325
; -- AUD4ENV / NR42 ($FF21) ---------------------------------------------------
306326
; Audio channel 4 volume and envelope
307327
def rAUD4ENV equ $FF21
308328

309-
; Values are reused from AUD1ENV
329+
def AUD4ENVF_INIT_VOL equ %1111_0000 ; initial volume [r/w]
330+
331+
def AUD4ENVB_DIR equ 3 ; direction of volume envelope [r/w]
332+
def AUD4ENVF_DIR equ 1 << AUD4ENVB_DIR
333+
def AUD4ENV_DOWN equ 0 << AUD4ENVB_DIR
334+
def AUD4ENV_UP equ 1 << AUD4ENVB_DIR
335+
336+
def AUD4ENVF_PACE equ %00000_111 ; how long between envelope iterations
337+
; (in 64 Hz ticks, ~15.6 ms apart) [r/w]
310338

311339
; -- AUD4POLY / NR43 ($FF22) --------------------------------------------------
312340
; Audio channel 4 period and randomness
@@ -430,8 +458,8 @@ def LCDCB_PRION equ 0 ; (CGB only) whether OBJ priority bits are enabled [r/w]
430458
def LCDCF_WINOFF equ 0 << LCDCB_WINON
431459
def LCDCF_WINON equ 1 << LCDCB_WINON
432460
def LCDCF_BLKS equ 1 << LCDCB_BLKS
433-
def LCDCF_BLK21 equ 0 << LCDCB_BLKS
434-
def LCDCF_BLK01 equ 1 << LCDCB_BLKS
461+
def LCDCF_BLK21 equ 0 << LCDCB_BLKS
462+
def LCDCF_BLK01 equ 1 << LCDCB_BLKS
435463
def LCDCF_BG9800 equ 0 << LCDCB_BG9C00
436464
def LCDCF_BG9C00 equ 1 << LCDCB_BG9C00
437465
def LCDCF_OBJ8 equ 0 << LCDCB_OBJ16
@@ -512,20 +540,20 @@ def rWX equ $FF4B
512540

513541
def WX_OFS equ 7 ; subtract this to get the actual Window Y coordinate
514542

515-
; -- KEY0 ($FF4C) -------------------------------------------------------------
543+
; -- SYS / KEY0 ($FF4C) -------------------------------------------------------------
516544
; (CGB boot ROM only) CPU mode select
517-
def rKEY0 equ $FF4C
545+
def rSYS equ $FF4C
518546

519-
; KEY0 is known as the "CPU mode register" in Fig. 11 of this patent:
547+
; This is known as the "CPU mode register" in Fig. 11 of this patent:
520548
; https://patents.google.com/patent/US6322447B1/en?oq=US6322447bi
521549
; "OBJ priority mode designating register" in the same patent
522550
; Credit to @mattcurrie for this finding!
523551

524-
def KEY0F_MODE equ %0000_11_00 ; current system mode [r/w]
525-
def KEY0F_CGB equ %0000_00_00 ; CGB mode
526-
def KEY0F_DMG equ %0000_01_00 ; DMG compatibility mode
527-
def KEY0F_PGB1 equ %0000_10_00 ; LCD is driven externally, CPU is stopped
528-
def KEY0F_PGB2 equ %0000_11_00 ; LCD is driven externally, CPU is running
552+
def SYSF_MODE equ %0000_11_00 ; current system mode [r/w]
553+
def SYSF_CGB equ %0000_00_00 ; CGB mode
554+
def SYSF_DMG equ %0000_01_00 ; DMG compatibility mode
555+
def SYSF_PGB1 equ %0000_10_00 ; LCD is driven externally, CPU is stopped
556+
def SYSF_PGB2 equ %0000_11_00 ; LCD is driven externally, CPU is running
529557

530558
; -- SPD / KEY1 ($FF4D) -------------------------------------------------------
531559
; (CGB only) Double-speed mode control
@@ -867,6 +895,13 @@ def rNR50 equ rAUDVOL
867895
def rNR51 equ rAUDTERM
868896
def rNR52 equ rAUDENA
869897

898+
def rKEY0 equ rSYS
899+
def KEY0F_MODE equ SYSF_MODE
900+
def KEY0F_CGB equ SYSF_CGB
901+
def KEY0F_DMG equ SYSF_DMG
902+
def KEY0F_PGB1 equ SYSF_PGB1
903+
def KEY0F_PGB2 equ SYSF_PGB2
904+
870905
def rKEY1 equ rSPD
871906
def KEY1F_DBLSPEED equ SPDF_DBLSPEED
872907
def KEY1F_PREPARE equ SPDF_PREPARE
@@ -912,10 +947,6 @@ def _OAMRAM equ $FE00 ; $FE00-$FE9F (prefer `STARTOF(OAM)`)
912947
def _IO equ $FF00 ; $FF00-$FF7F, $FFFF (prefer `ldh [c]` to `ld [_IO+c]`)
913948
def _HRAM equ $FF80 ; $FF80-$FFFE (prefer `STARTOF(HRAM)`)
914949

915-
def _VRAM8000 equ _VRAM
916-
def _VRAM8800 equ _VRAM + $800
917-
def _VRAM9000 equ _VRAM + $1000
918-
919950

920951
;******************************************************************************
921952
; (deprecated) Cartridge header
@@ -1009,6 +1040,31 @@ def CART_DEST_NON_JAPANESE equ $01 ; prefer `rgbfix -j/--non-japanese`
10091040

10101041
; These values are deprecated; please avoid using them.
10111042

1043+
def AUDLENF_DUTY equ AUD1LENF_DUTY
1044+
def AUDLEN_DUTY_12_5 equ AUD1LEN_DUTY_12_5
1045+
def AUDLEN_DUTY_25 equ AUD1LEN_DUTY_25
1046+
def AUDLEN_DUTY_50 equ AUD1LEN_DUTY_50
1047+
def AUDLEN_DUTY_75 equ AUD1LEN_DUTY_75
1048+
1049+
def AUDLENF_TIMER equ AUD1LENF_TIMER
1050+
1051+
def AUDENVF_INIT_VOL equ AUD1ENVF_INIT_VOL
1052+
1053+
def AUDENVB_DIR equ AUD1ENVB_DIR
1054+
def AUDENVF_DIR equ AUD1ENVF_DIR
1055+
def AUDENV_DOWN equ AUD1ENV_DOWN
1056+
def AUDENV_UP equ AUD1ENV_UP
1057+
1058+
def AUDENVF_PACE equ AUD1ENVF_PACE
1059+
1060+
def AUDHIGHB_RESTART equ AUD1HIGHB_RESTART
1061+
def AUDHIGHB_LEN_ENABLE equ AUD1HIGHB_LEN_ENABLE
1062+
def AUDHIGH_RESTART equ AUD1HIGH_RESTART
1063+
def AUDHIGH_LENGTH_OFF equ AUD1HIGH_LENGTH_OFF
1064+
def AUDHIGH_LENGTH_ON equ AUD1HIGH_LENGTH_ON
1065+
1066+
def AUDHIGHF_PERIOD_HIGH equ AUD1HIGHF_PERIOD_HIGH
1067+
10121068
def LCDCB_BG8000 equ LCDCB_BLKS
10131069
def LCDCF_BG8800 equ LCDCF_BLK21
10141070
def LCDCF_BG8000 equ LCDCF_BLK01
@@ -1019,4 +1075,8 @@ def IEF_LCDC equ IEF_STAT
10191075

10201076
def sizeof_OAM_ATTRS equ OBJ_B
10211077

1078+
def _VRAM8000 equ _VRAM
1079+
def _VRAM8800 equ _VRAM + $800
1080+
def _VRAM9000 equ _VRAM + $1000
1081+
10221082
endc ; HARDWARE_INC

0 commit comments

Comments
 (0)