diff --git a/aboutcredits.md b/aboutcredits.md index 06f6fae..6f23130 100644 --- a/aboutcredits.md +++ b/aboutcredits.md @@ -6,10 +6,10 @@ GTE.TXT by doomed@c64.org / psx.rules.org
SPU.TXT by doomed@c64.org / psx.rules.org
CDINFO.TXT by doomed with big thanks to Barubary, who rewrote a large part
SYSTEM.TXT by doomed with thanx to Herozero for breakpoint info
-PS_ENG.TXT PlayStation PAD/Memory Interface Protocol by HFB03536
+PS\_ENG.TXT PlayStation PAD/Memory Interface Protocol by HFB03536
IDT79R3041 Hardware User's Manual by Integrated Device Technology, Inc.
IDTR3051, R3052 RISController User's Manual by Integrated Device Technology
-PSX.* by Joshua Walker (additional details in various distorted file formats)
+PSX.\* by Joshua Walker (additional details in various distorted file formats)
LIBMIRAGE by Rok; info/source code for various cdrom-image formats
psxdev.ru; cdrom sub-cpu decapping
diff --git a/cdromdrive.md b/cdromdrive.md index 3f1a17c..a51833c 100644 --- a/cdromdrive.md +++ b/cdromdrive.md @@ -360,9 +360,9 @@ E = Error 80h appears on some commands (02h..09h, 0Bh..0Dh, 10h..16h, 1Ah, 1Bh?, and 1Dh) when the disk is missing, or when the drive unit is disconnected from the mainboard.
-#### sub_function numbers (for command 19h) -Test commands are invoked with command number 19h, followed by a sub_function -number as first parameter byte. The Kernel seems to be using only sub_function +#### sub\_function numbers (for command 19h) +Test commands are invoked with command number 19h, followed by a sub\_function +number as first parameter byte. The Kernel seems to be using only sub\_function 20h (to detect the CDROM Controller version).
``` sub params response ;Effect @@ -412,9 +412,9 @@ number as first parameter byte. The Kernel seems to be using only sub_function 76h *** a,b,c,d INT3(stat) ;Decoder Prepare Transfer to/from SRAM 77h..FFh - INT5(11h,10h) ;N/A ``` -* sub_functions 06h..08h, 30h..31h, and 4xh are supported only in vC0 and vC1.
-** sub_function 51h is supported only in BIOS version vC2 and up.
-*** sub_functions 22h..25h, 71h..76h supported only in BIOS version vC1 and up.
+\* sub\_functions 06h..08h, 30h..31h, and 4xh are supported only in vC0 and vC1.
+\*\* sub\_function 51h is supported only in BIOS version vC2 and up.
+\*\*\* sub\_functions 22h..25h, 71h..76h supported only in BIOS version vC1 and up.
#### Unsupported GetQ,VCD,SecretUnlock (command 1Dh,1Fh,5xh) INT5 will be returned if the command is unsupported. That, WITHOUT removing the @@ -830,7 +830,7 @@ boundaries (eg. if track=N Index=0 starts at 12:34:56, and Track=N Index=1 starts at 12:36:56, then GetTD(N) will return 12:36, ie. the sector number is truncated, and the Index=0 region is skipped).
-#### GetQ - Command 1Dh,adr,point --\> INT3(stat) --\> INT2(10bytesSubQ,peak_lo) +#### GetQ - Command 1Dh,adr,point --\> INT3(stat) --\> INT2(10bytesSubQ,peak\_lo) ``` Caution: Supported only in BIOS version vC1 and up. Not supported in vC0. Caution: When unsupported, Parameter Fifo isn't cleared after the command. @@ -1120,8 +1120,8 @@ match). Typically, the values are "01h,01h" for Licensed PSX Data CDs, or "00h,00h" for disk missing, unlicensed data CDs, Audio CDs.
The counters are reset to zero, and SCEx receive mode is active for a few seconds after booting a new disk (on power up, on closing the drive door, on -sending a Reset command, and on sub_function 04h). The disk is unlocked if the -"success" counter is nonzero, the only exception is sub_function 04h which does +sending a Reset command, and on sub\_function 04h). The disk is unlocked if the +"success" counter is nonzero, the only exception is sub\_function 04h which does update the counters, but does not lock/unlock the disk.
@@ -1314,14 +1314,14 @@ That two bytes are 0Ch,08h after Read commands.
changes to [1F1h] which may occur after read command (eg. may be 20h) ``` -#### 19h,76h,len_lo,len_hi,addr_lo,addr_hi --\> INT3(stat) ;Prepare SRAM Transfer +#### 19h,76h,len\_lo,len\_hi,addr\_lo,addr\_hi --\> INT3(stat) ;Prepare SRAM Transfer Prepare Transfer to/from 32K SRAM.
After INT3, data can be read (same way as sector data after INT1).
## CDROM - Test Commands - Read HC05 SUB-CPU RAM and I/O Ports -#### 19h,60h,addr_lo,addr_hi --\> INT3(data) ;Read one byte from Drive RAM or I/O +#### 19h,60h,addr\_lo,addr\_hi --\> INT3(data) ;Read one byte from Drive RAM or I/O Reads one byte from the controller's RAM or I/O area, see the memory map below for more info. Among others, the command allows to read Subchannel Q data, eg. at [200h..209h], including ADR=2/UPC/EAN and ADR=3/ISRC values (which are @@ -1792,7 +1792,7 @@ error).
Read (double speed) 0036cd2h 00322dfh..003ab2bh ``` The INT1 rate needs to be precise for CD-DA and CD-XA Audio streaming, exact -clock cycle values should be: SystemClock*930h/4/44100Hz for Single Speed (and +clock cycle values should be: SystemClock\*930h/4/44100Hz for Single Speed (and half as much for Double Speed) (the "Average" values are AVERAGE values, not exact values).
@@ -2487,7 +2487,7 @@ Character Set values (for ID1=8Fh, ID2=00h, DATA[0]=charset):
09h (or 0909h for 16bit charset) may be used to indicate the same as previous track. It shall not used for the first track."
-#### adjust_crc_16_ccitt(addr_len) ;for CD-TEXT and Subchannel Q +#### adjust\_crc\_16\_ccitt(addr\_len) ;for CD-TEXT and Subchannel Q ``` lsb=00h, msb=00h ;-initial value (zero for both CD-TEXT and Sub-Q) for i=0 to len-1 ;-len (10h for CD-TEXT, 0Ah for Sub-Q) @@ -2541,7 +2541,7 @@ track. It shall not used for the first track."
92Ch 4 EDC (checksum accross [010h..92Bh]) (or 00000000h if no EDC) ``` -#### encode_sector +#### encode\_sector ``` sector[000h]=00h,FFh,FFh,FFh,FFh,FFh,FFh,FFh,FFh,FFh,FFh,00h sector[00ch]=bcd(adr/75/60) ;0..7x @@ -2570,7 +2570,7 @@ track. It shall not used for the first track."
adjust_edc(sector+10h,914h+8) ;edc is optional for form2 ``` -#### calc_parity(sector,offs,len,j0,step1,step2) +#### calc\_parity(sector,offs,len,j0,step1,step2) ``` src=00ch, dst=81ch+offs, srcmax=dst for i=0 to len-1 @@ -2583,10 +2583,10 @@ track. It shall not used for the first track."
sector[dst+2*len+1]=y AND 0FFh, [dst+1]=y SHR 8 dst=dst+2, src=base+step2 ``` -calc_p_parity(sector) = calc_parity(sector,0,43,19,2*43,2)
-calc_q_parity(sector) = calc_parity(sector,43*4,26,0,2*44,2*43)
+calc\_p\_parity(sector) = calc\_parity(sector,0,43,19,2\*43,2)
+calc\_q\_parity(sector) = calc\_parity(sector,43\*4,26,0,2\*44,2\*43)
-#### adjust_edc(addr,len) +#### adjust\_edc(addr,len) ``` x=00000000h for i=0 to len-1 @@ -2594,7 +2594,7 @@ calc_q_parity(sector) = calc_parity(sector,43*4,26,0,2*44,2*43)
word[addr+len]=x ;append EDC value (little endian) ``` -#### init_tables +#### init\_tables ``` for i=0 to FFh x=i, for j=0 to 7, x=x shr 1, if carry then x=x xor D8018001h @@ -2700,7 +2700,7 @@ various ways to arrange multiple files or channels, for example,
eight different files with one 1/8 audio channel each etc. ``` -(*) If the Audio and Video data belongs together then both should use the SAME +(\*) If the Audio and Video data belongs together then both should use the SAME channel.
Note: Above interleave values are assuming that PSX Game Disks are always running at double speed (that's fastest for normal data files, and ADPCM files @@ -2796,7 +2796,7 @@ or, for 8bit ADPCM format:
24-31 Byte for 4th Block/Mono, or 2nd Block/Right (-80h..+7Fh) ``` -#### decode_sector(src) +#### decode\_sector(src) ``` src=src+12+4+8 ;skip sync,header,subheader for i=0 to 11h @@ -2814,7 +2814,7 @@ or, for 8bit ADPCM format:
src=src+14h+4 ;skip padding,edc ``` -#### decode_28_nibbles(src,blk,nibble,dst,old,older) +#### decode\_28\_nibbles(src,blk,nibble,dst,old,older) ``` shift = 12 - (src[4+blk*2+nibble] AND 0Fh) filter = (src[4+blk*2+nibble] AND 30h) SHR 4 @@ -2840,7 +2840,7 @@ supports five filters (0..4).
The incoming old/older values are usually that from the previous part, or garbage (in case of decoding errors in the previous part), or whatever (in case there was no previous part) (ie. maybe zero on power-up?) (and maybe there's -also a way to reset the values to zero at the begin of a new file, or *maybe* +also a way to reset the values to zero at the begin of a new file, or \*maybe\* it's silently done automatically when issuing seek commands?).
#### 25-point Zigzag Interpolation @@ -3110,8 +3110,8 @@ Playstation disks usually have only two Volume Descriptors,
## CDROM ISO File and Directory Descriptors The location of the Root Directory is described by a 34-byte Directory Record being located in Primary Volume Descriptor entries 09Ch..0BDh. The data therein -is: Block Number (usually 22 on PSX disks), LEN_FI=01h, Name=00h, and, -LEN_SU=00h (due to the 34-byte limit).
+is: Block Number (usually 22 on PSX disks), LEN\_FI=01h, Name=00h, and, +LEN\_SU=00h (due to the 34-byte limit).
#### Format of a Directory Record ``` @@ -3129,8 +3129,8 @@ LEN_SU=00h (due to the 34-byte limit).
xxh 0..1 Padding Field (00h) (only if LEN_FI is even) xxh LEN_SU System Use (LEN_SU bytes) (see below for CD-XA disks) ``` -LEN_SU can be calculated as "LEN_DR-(33+LEN_FI+Padding)". For CD-XA disks (as -used in the PSX), LEN_SU is 14 bytes:
+LEN\_SU can be calculated as "LEN\_DR-(33+LEN\_FI+Padding)". For CD-XA disks (as +used in the PSX), LEN\_SU is 14 bytes:
``` 00h 2 Owner ID Group (whatever, usually 0000h, big endian) 02h 2 Owner ID User (whatever, usually 0000h, big endian) @@ -3185,7 +3185,7 @@ size and location of the tables is stored in Volume Descriptor entries ``` The first entry (directory number 0001h) is the root directory, the root doesn't have a name, nor a parent (the name field contains a 00h byte, rather -than ASCII text, LEN_DI is 01h, and parent is 0001h, making the root it's own +than ASCII text, LEN\_DI is 01h, and parent is 0001h, making the root it's own parent; ignoring the fact that incest is forbidden in many countries).
The next entries (directory number 0002h and up) (if any) are sub-directories within the root (sorted in alphabetical order, and all having parent=0001h). @@ -3340,8 +3340,8 @@ AUTOEXEC.BAT files for MSDOS. A typical SYSTEM.CNF would look like so:
STACK = 801FFF00 ;HEX (=memtop-256) ``` The first line specifies the executable to load, from the "cdrom:" drive, "\" -root directory, filename "abcd_123.45" (case-insensitive, the real name in the -disk directory would be uppercase, ie. "ABCD_123.45"), and, finally ";1" is the +root directory, filename "abcd\_123.45" (case-insensitive, the real name in the +disk directory would be uppercase, ie. "ABCD\_123.45"), and, finally ";1" is the file's version number (a rather strange ISO-filesystem specific feature) (the version number should be usually/always 1). Additionally, "arg" may contain an optional 128-byte command line argument string, which is copied to address @@ -3350,17 +3350,17 @@ don't use that feature).
Each line in the file should be terminated by 0Dh,0Ah characters... not sure if it's also working with only 0Dh, or only 0Ah...?
-A note on the "ABCD_123.45" file:
+A note on the "ABCD\_123.45" file:
This is a normal executable (exactly as for the .EXE files, described below), however, the filename/extension is taken from the game code (the "ABCD-12345" text that is printed on the CD cover), but, with the minus replaced by an underscore, and due to the 8-letter filename limit, the last two characters are stored in the extension region.
-That "XXXX_NNN.NN" naming convention seems to apply for all official licensed +That "XXXX\_NNN.NN" naming convention seems to apply for all official licensed PSX games, not sure if it's possible to specify something like "FILENAME.EXE" as boot-file.
-#### XXXX_NNN.NN (Boot-Executable) (filename specified in SYSTEM.CNF) +#### XXXX\_NNN.NN (Boot-Executable) (filename specified in SYSTEM.CNF) #### FILENAME.EXE (General-Purpose Executable) PSX executables are having an 800h-byte header, followed by the code/data.
``` @@ -3465,7 +3465,7 @@ color of the disks, and works also with normal silver disks.
#### Disk-Swap-Trick Once when the PSX has recognized a disk with the "SCEx" signal, it'll be -satisfied until a new disk is inserted, which is sensed by the SHELL_OPEN +satisfied until a new disk is inserted, which is sensed by the SHELL\_OPEN switch. When having that switch blocked, it is possible to insert a CDR without the PSX noticing that the disk was changed.
Additionally, the trick requires some boot software that stops the drive motor @@ -3598,7 +3598,7 @@ protection, ie. games that refuse to run if they detect a modchip. The detection relies on the fact that the SCEx signal is normally received only when booting the disk, whilst older modchips were sending that signal permanently. Stealth modchips are sending the signal only on power-up (and when -inserting a new disk, which can be sensed via SHELL_OPEN signal).
+inserting a new disk, which can be sensed via SHELL\_OPEN signal).
Modchip detection reportedly works like so (not too sure if all commands are required, some seem to be rather offtopic):
``` @@ -3897,7 +3897,7 @@ usually TOC info for Track 1 and up.
The .CCD file doesn't define the "PreGapSize" (the number of missing sectors at begin of first track). It seems to be simply constant " PreGapSize=150". Unless one is supposed to calculate it as -"PreGapSize=((PMin*60+PSec)*75+PFrame)-PLBA".
+"PreGapSize=((PMin\*60+PSec)\*75+PFrame)-PLBA".
The SectorSize seems to be also constant, "SectorSize=930h".
#### Non-BCD Caution @@ -4274,7 +4274,7 @@ the tracks could use separate filename blocks; with different filenames).
``` 00h 6 Filename, terminated by zero (usually "*.mdf",00h) ``` -Contains the filename of the of the sector data (usually "*.mdf", indicating to +Contains the filename of the of the sector data (usually "\*.mdf", indicating to use the same name as for the .mds file, but with .mdf extension).
#### Missing @@ -4624,7 +4624,7 @@ checksums.
M3S files are containing Subchannel Q data for all sectors on Minute=03 (the region where PSX libcrypt data is located) (there is no support for storing the (unused) libcrypt backup copy on Minute=09). The .M3S filesize is 72000 bytes -(60 seconds * 75 sectors * 16 bytes). The 16 bytes per sector are:
+(60 seconds \* 75 sectors \* 16 bytes). The 16 bytes per sector are:
``` Q0..Q9 Subchannel Q data (normally position data) Q10..Q11 Subchannel Q checksum diff --git a/cdrominternalinfoonpsxcdromcontroller.md b/cdrominternalinfoonpsxcdromcontroller.md index fd84b47..fe25987 100644 --- a/cdrominternalinfoonpsxcdromcontroller.md +++ b/cdrominternalinfoonpsxcdromcontroller.md @@ -48,7 +48,7 @@ Later version is CXD1817R (Servo/Signal/Decoder Combo).
Even later PSX mainboards have it integrated in the Sound Chip: CXD2938Q (SPU+CDROM) with some changed bits and New SCEx transfer:
[CDROM Internal Commands CX(0x..Ex) - CXD2938Q Servo/Signal/SPU Combo](cdrominternalinfoonpsxcdromcontroller.md#cdrom-internal-commands-cx0xex---cxd2938q-servosignalspu-combo)
-Finally, PM-41(2) boards are using a CXD2941R chip (SPU+CDROM+SPU_RAM), unknown +Finally, PM-41(2) boards are using a CXD2941R chip (SPU+CDROM+SPU\_RAM), unknown if/how far the CDROM part of that chip differs from CXD2938Q.
Some general notes:
[CDROM Internal Commands CX(xx) - Notes](cdrominternalinfoonpsxcdromcontroller.md#cdrom-internal-commands-cxxx---notes)
@@ -1746,7 +1746,7 @@ XXX
$EX OV64 OV64 - $7X-9X,DX,FX Z 0 - ``` -*1 $38 outputs AGOK during AGT and AGF command settings, and XAVEBSY during +\*1 $38 outputs AGOK during AGT and AGF command settings, and XAVEBSY during AVRG measurement.
SSTP is output in all other cases.
@@ -2030,7 +2030,7 @@ commands:
- CX(Xxxxxx) CX(Xxxxxx) SerialSense, CX(Xxxx) with extra 8bit junk ``` Note: for vC2, some CX(38xxxx) values may differ depending on -"set_mid_lsb_to_140Eh".
+"set\_mid\_lsb\_to\_140Eh".
For vC2, CX(Dx) and CX(Ex) should be officially zero-padded to CX(Dx00) and CX(Ex00), but the vC2 BIOS doesn't do that, it still uses short 8bit form.
For vC2, CX(Dx) and CX(Ex) should be apparently zero-padded to CX(Dx0000) and diff --git a/cdromvideocdsvcd.md b/cdromvideocdsvcd.md index 8853afe..d72e54b 100644 --- a/cdromvideocdsvcd.md +++ b/cdromvideocdsvcd.md @@ -87,7 +87,7 @@ InfoStatusFlags at [02Bh] describes certain characteristics of the disc:
Note: Bit5/6 are used only if the next disc has the same Album ID (eg. the feature allows to skip copyright messages if the same message was already shown on another disc).
-First_segment_addr: The location of the first sector of the Segment Play Item +First\_segment\_addr: The location of the first sector of the Segment Play Item Area [that is... the first ITEMnnnn.DAT file?], in the form mm:ss:00. Must be 00:00:00 if PSD size is zero. If PSD size is nonzero, but no segments used: Usually set to 00:02:00.
@@ -106,7 +106,7 @@ Version;
0x02 --- VCD2.0 0x01 --- SVCD, should be same as version in INFO.SVD ``` -Sys_prof_tag;
+Sys\_prof\_tag;
``` 0x01 if VCD1.1 0x00 else @@ -239,14 +239,14 @@ one picture frame, or eventually with a few frames for short animations, including audio in some cases). Still images are said to be allowed to use twice the resolution of MPEG videos.
-#### EXT\PSD_X.VCD or EXT\PSD_X.SVD (extended version of PSD.VCD) -#### EXT\LOT_X.VCD or EXT\LOT_X.SVD (extended version of LOT.VCD) +#### EXT\PSD\_X.VCD or EXT\PSD\_X.SVD (extended version of PSD.VCD) +#### EXT\LOT\_X.VCD or EXT\LOT\_X.SVD (extended version of LOT.VCD) The "extended" files are often identical to the normal PSD/LOT files. The difference is that, if disc uses SelectionLists, then PSD should use the normal -descriptor (18h), and PSD_X should use the extended descriptor (1Ah), the +descriptor (18h), and PSD\_X should use the extended descriptor (1Ah), the latter one seems to be intended to allow to highlight the current menu selection (particulary useful when using +/- buttons instead of Numeric Keypad -input). Note: Nethertheless, Muppets from Space uses descriptor 18h in PSD_X.
+input). Note: Nethertheless, Muppets from Space uses descriptor 18h in PSD\_X.
Unknown if SVCDs do really have "extended" files, too (theoretically the VCD extension should be a default feature for SVCDs).
@@ -254,7 +254,7 @@ extension should be a default feature for SVCDs).
Although PBC was intended as "nice extra feature", many VCDs are containing faulty PSD files. In general, VCD players should either leave PBC unsupported (or provide an option for disabling it).
-Red Dragon from 2003 uses extended selection lists, but crops PSD_X.VCD to the +Red Dragon from 2003 uses extended selection lists, but crops PSD\_X.VCD to the same filesize as PSD.VCD.
Muppets from Space from 1999 assigns weird functions to Prev/Next buttons (Next wraps from Last Track to First Track, but Prev doesn't wrap from First to Last; @@ -285,7 +285,7 @@ If that's correct, then the files would overlap with PSD.SVD (when PSD.SVD is bigger than one sector), that would be weird, but possible (ie. the "PsdOffset" in PSD.SVD would need to "skip" the region used by those two files).
-#### EXT\SCANDATA.DAT (12+3*N bytes for VCD 2.0) (or 16+3*N+2*X+3*Y+3*Z for SVCD) +#### EXT\SCANDATA.DAT (12+3\*N bytes for VCD 2.0) (or 16+3\*N+2\*X+3\*Y+3\*Z for SVCD) This file fulfills much the same purpose of the SEARCH.DAT file except that this file is mandatory only if the System Profile Tag of the INFO.SVD file is 0x01 (HQ-VCD) and also that it contains sector addresses also for each video @@ -316,7 +316,7 @@ Segment Play Items in addition to the regular MPEG tracks.
xxxh 3*Z msf_t scandata_table[Z] ;MM:SS:FF ``` -#### SVCD\SEARCH.DAT (13+3*N bytes) +#### SVCD\SEARCH.DAT (13+3\*N bytes) This file defines where the scan points are. It covers all mpeg tracks together. A scan point at time T is the nearest I-picture in the MPEG stream to the given time T. Scan points are given at every half-second for the entire @@ -333,7 +333,7 @@ Note: This SVCD file is about same as the old EXT\SCANDATA.DAT file on VCDs (with one extra entry for Time Interval). Whilst, SVCDs are storing some different stuff in EXT\SCANDATA.DAT (despite of the identical filename).
-#### SVCD\TRACKS.SVD (11+4*N bytes) (or rarely:11+5*N bytes) +#### SVCD\TRACKS.SVD (11+4\*N bytes) (or rarely:11+5\*N bytes) The TRACKS.SVD file contains a series of structures, one for each track, which indicates the track's playing time (in sectors, not actually real time) and contents.
@@ -409,8 +409,8 @@ the picture frames (ie. in the MPEG macroblocks, rather than using the Closed Caption feature).
These CAPTnn.DAT files are intended for Closed Captions (eg. subtitles in different languages and/or for deaf people).
-Alternately, the "user_data_cc" flag in INFO.VCD?/INFO.SVD can indicate to -store Closed Captions in MPEG User Data (with START_CODE=000001B2h=User Data) +Alternately, the "user\_data\_cc" flag in INFO.VCD?/INFO.SVD can indicate to +store Closed Captions in MPEG User Data (with START\_CODE=000001B2h=User Data) instead of in EXT\CAPTnn.DAT. Either way, the format of those Closed Captions is unknown.
Moreover, Content can be flagged to have Overlay Graphics/Text (OGT), whatever @@ -434,17 +434,17 @@ of that files is unknown.
Reportedly there are Midi VCDs (MVCDs) for karaoke, maybe those discs have "KARINFO.xxx" files(?)
-#### PICTURES\*.* (whatever) +#### PICTURES\\*.\* (whatever) Unknown purpose. The PICTURES folder has been spotted on one VCD (Wallace and Gromit), but the folder was just empty.
-#### CDI\*.* (some kind of GUI/driver for Philips CDI Players) +#### CDI\\*.\* (some kind of GUI/driver for Philips CDI Players) The CDI folder is some relict for Philips CDI Players, it isn't used by normal VCD players, however, the CDI folder & files are included on most or all VCDs.
The path/name for the CDI executable is stored at offset 23Eh in the ISO -Primary Volume Descriptor (usually "CDI/CDI_APPL.VCD;1" or "CDI/CDI_VCD.APP;1") -(or accidentally "CDI_CDI_VCD.APP;1" on homebrew Nero discs).
+Primary Volume Descriptor (usually "CDI/CDI\_APPL.VCD;1" or "CDI/CDI\_VCD.APP;1") +(or accidentally "CDI\_CDI\_VCD.APP;1" on homebrew Nero discs).
The files in the CDI folder are usually just some standard files (without any customizations), however, there are some different revisions of these files:
``` @@ -463,20 +463,20 @@ customizations), however, there are some different revisions of these files:
-CDI_IMAG.RTF is seen as 1510028 byte file under windows (that is, with a +CDI\_IMAG.RTF is seen as 1510028 byte file under windows (that is, with a windows RIFF header, and with data area containing the whole 930h bytes from each sector; this includes the MM:SS:FF values from the sector header, so the RTF file may look slightly different depending on which sectors it has been stored on, although the files are usually exactly same apart from those MM:SS:FF values). Note: The RTF file is cropped to 1324220 bytes (instead of 1510028) on the homebrew DemoVCD (apart from that, the file is same as normal).
-CDI_ALL.RTF and CDI_BUM.RTF cannot be read/copied under Windows 7 (which is +CDI\_ALL.RTF and CDI\_BUM.RTF cannot be read/copied under Windows 7 (which is weirdly reporting them to use an "invalid MS-DOS function"; some people also -reported having CDI_IMAG.RTF files with similar problems). The reason is +reported having CDI\_IMAG.RTF files with similar problems). The reason is unknown, maybe windows doesn't fully support the CD filesystem, or some VCDs are violating the filesystem specs, or whatever... maybe windows is mis-identifying certain RTF files as Rich Text Format files and tries to @@ -521,7 +521,7 @@ determine the position/bitrate, so the Pack is kinda useless).
1bit Marker (1) ;/ ``` -#### MPEG-1 Multiplex System Header (12+N*3 bytes)(optionally)(at start of stream) +#### MPEG-1 Multiplex System Header (12+N\*3 bytes)(optionally)(at start of stream) The System Header is usally found after the first Pack at the begin of the stream.
``` @@ -539,7 +539,7 @@ stream.
5bit Video Bound (max number of video streams in this ISO stream) ;/ 8bit Reserved (FFh) ;-1byte ``` -Followed by N*3 bytes for the streams (each with first bit=set):
+Followed by N\*3 bytes for the streams (each with first bit=set):
``` 8bit Stream ID (C0h..DFh=Audio, E0h..EFh=Video) ;\ 2bit Fixed (11b) ; 3byte @@ -626,7 +626,7 @@ packets preceeded (and interrupted) by Multiplex headers. Ie. before processing the Video packets, one must first extract the video snippets from the Multiplex stream (see previous chapter).
-#### MPEG-1 Video Sequence Header (12, 76, or 140 bytes, ie. 12+N*64) +#### MPEG-1 Video Sequence Header (12, 76, or 140 bytes, ie. 12+N\*64) ``` 32bit SEQUENCE_HEADER_CODE (000001B3h) ;-4byte 12bit Width in pixels (1..4095) ;\3byte @@ -899,7 +899,7 @@ used by the .CDZ cdrom-image format.
## Inflate - Core Functions -#### tinf_uncompress(dst,src) +#### tinf\_uncompress(dst,src) ``` tinf_init() ;init constants (needed to be done only once) tinf_align_src_to_byte_boundary() @@ -915,7 +915,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_inflate_uncompressed_block() +#### tinf\_inflate\_uncompressed\_block() ``` tinf_align_src_to_byte_boundary() len=LittleEndian16bit[src+0] ;get len @@ -925,7 +925,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_inflate_compressed_block() +#### tinf\_inflate\_compressed\_block() ``` repeat sym1=tinf_decode_symbol(tinf_len_tree) @@ -940,7 +940,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_decode_symbol(tree) +#### tinf\_decode\_symbol(tree) ``` sum=0, cur=0, len=0 repeat ;get more bits while code value is above sum @@ -952,21 +952,21 @@ used by the .CDZ cdrom-image format.
return tree.trans[sum+cur] ``` -#### tinf_read_bits(num) ;get N bits from source stream +#### tinf\_read\_bits(num) ;get N bits from source stream ``` val=0 for i=0 to num-1, val=val+(tinf_getbit() shl i), next i return val ``` -#### tinf_getbit() ;get one bit from source stream +#### tinf\_getbit() ;get one bit from source stream ``` bit=tag AND 01h, tag=tag/2 if tag=00h then tag=[src], src=src+1, bit=tag AND 01h, tag=tag/2+80h return bit ``` -#### tinf_align_src_to_byte_boundary() +#### tinf\_align\_src\_to\_byte\_boundary() ``` tag=01h ;empty/end-bit (discard any bits, align src to byte-boundary) ret @@ -975,7 +975,7 @@ used by the .CDZ cdrom-image format.
## Inflate - Initialization & Tree Creation -#### tinf_init() +#### tinf\_init() ``` tinf_build_bits_base(length_bits, length_base, 4, 3) length_bits[28]=0, length_base[28]=258 @@ -983,7 +983,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_build_bits_base(bits,base,delta,base_val) +#### tinf\_build\_bits\_base(bits,base,delta,base\_val) ``` for i=0 to 29 bits[i]=min(0,i-delta)/delta @@ -992,7 +992,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_build_fixed_trees() +#### tinf\_build\_fixed\_trees() ``` for i=0 to 6, tinf_len_tree.table[i]=0, next i ;[0..6]=0 ;len tree... tinf_len_tree.table[7,8,9]=24,152,112 ;[7..9]=24,152,112 @@ -1006,7 +1006,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_decode_dynamic_trees() +#### tinf\_decode\_dynamic\_trees() ``` hlit = tinf_read_bits(5)+257 ;get 5 bits HLIT (257-286) hdist = tinf_read_bits(5)+1 ;get 5 bits HDIST (1-32) @@ -1027,7 +1027,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_build_tree(tree, first, num) +#### tinf\_build\_tree(tree, first, num) ``` for i=0 to 15, tree.table[i]=0, next i ;clear code length count table ;scan symbol lengths, and sum code length counts... @@ -1041,7 +1041,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_data +#### tinf\_data ``` clcidx[0..18] = 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 ;constants ``` @@ -1070,7 +1070,7 @@ used by the .CDZ cdrom-image format.
## Inflate - Headers and Checksums -#### tinf_gzip_uncompress(void *dest, *destLen, *source, sourceLen) +#### tinf\_gzip\_uncompress(void \*dest, \*destLen, \*source, sourceLen) ``` src_start=src, dst_start=dst ;memorize start addresses if (src[0]<>1fh or src[1]<>8Bh) then ERROR ;check id bytes @@ -1092,7 +1092,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_zlib_uncompress(dst, destLen, src, sourceLen) +#### tinf\_zlib\_uncompress(dst, destLen, src, sourceLen) ``` src_start=src, dst_start=dst ;memorize start addresses hdr=BigEndian16bit[src], src=src+2 ;get header @@ -1108,7 +1108,7 @@ used by the .CDZ cdrom-image format.
ret ``` -#### tinf_adler32(src, length) +#### tinf\_adler32(src, length) ``` s1=1, s2=0 while (length>0) diff --git a/cheatdevices.md b/cheatdevices.md index c81dbf2..e0a4c42 100644 --- a/cheatdevices.md +++ b/cheatdevices.md @@ -27,7 +27,7 @@ DB25 connector can be directly connected to a PC parallel port.
[Cheat Devices - FLASH/EEPROMs](cheatdevices.md#cheat-devices---flasheeproms)
http://gamehacking.org/faqs/hackv500c.html - cheat code formats
-http://doc.kodewerx.org/hacking_psx.html - cheat code formats
+http://doc.kodewerx.org/hacking\_psx.html - cheat code formats
http://xianaix.net/museum.htm - around 64 bios versions
http://www.murraymoffatt.com/playstation-xplorer.html - xplorer bioses
@@ -624,7 +624,7 @@ The filedata is split into fragments, Len should be max 2000h per fragment.
``` Memcard ReadFile does transfer N fragments of Len=2000h (depending on filesize). The GetWhatever function transfers one fragment with Len=80h, -followed by N*6 fragments with Len=40Ah.
+followed by N\*6 fragments with Len=40Ah.
#### RxTurbo for Memcard (bu) GetDirectory/GetFileHeader functions ``` @@ -857,7 +857,7 @@ on/off" flag (bit3: 0=on, 1=off; whatever that means, it does probably require WHATEVER actions to enable codes that are "off"; maybe via the Ftaaaaaa dddd code).
-#### break_type (cccc) (aka MSBs of cop0r7 DCIC register) +#### break\_type (cccc) (aka MSBs of cop0r7 DCIC register) ``` E180 (instruction gotton by CPU but not yet implemented) (uh, gotton what?) EE80 (data to be read or written) ;<--looks okay @@ -868,7 +868,7 @@ code).
The CPU supports one data breakpoint and one instruction breakpoint (though unknown if the Xplorer does support to use both simultaneously, or if it does allow only one of them to be used).
-If the break_type/address/mask to match up with CPU's memory access actions... +If the break\_type/address/mask to match up with CPU's memory access actions... then "something" does probably happen (maybe executing a sub-function that consists of the d0,d1,d2,etc-bytes, if so, maybe at a fixed/unknown memory address, or maybe at some random address; which would require relocatable @@ -881,7 +881,7 @@ The "Slide" code shall be used only with even addresses, unknown if other ## Cheat Devices - Xplorer Cheat Code and ROM-Image Decryption -#### decrypt_xplorer_cheat_code: +#### decrypt\_xplorer\_cheat\_code: ``` key = x[0] and 07h ;'''''''' AABBCCDD EEFF ''''''''; x[0] = x[0] xor key ; / / / \ \ \ ; @@ -916,7 +916,7 @@ The "Slide" code shall be used only with even addresses, unknown if other endif ``` -#### decrypt_xplorer_fcd_rom_image: +#### decrypt\_xplorer\_fcd\_rom\_image: ``` for i=0 to romsize-1 x=45h diff --git a/controllersandmemorycards.md b/controllersandmemorycards.md index 8c31469..e2e3cb2 100644 --- a/controllersandmemorycards.md +++ b/controllersandmemorycards.md @@ -33,33 +33,33 @@ ## Controller and Memory Card I/O Ports -#### 1F801040h JOY_TX_DATA (W) +#### 1F801040h JOY\_TX\_DATA (W) ``` 0-7 Data to be sent 8-31 Not used ``` Writing to this register starts the transfer (if, or as soon as TXEN=1 and -JOY_STAT.2=Ready), the written value is sent to the controller or memory card, -and, simultaneously, a byte is received (and stored in RX FIFO if JOY_CTRL.1 or -JOY_CTRL.2 is set).
-The "TXEN=1" condition is a bit more complex: Writing to SIO_TX_DATA latches +JOY\_STAT.2=Ready), the written value is sent to the controller or memory card, +and, simultaneously, a byte is received (and stored in RX FIFO if JOY\_CTRL.1 or +JOY\_CTRL.2 is set).
+The "TXEN=1" condition is a bit more complex: Writing to SIO\_TX\_DATA latches the current TXEN value, and the transfer DOES start if the current TXEN value OR the latched TXEN value is set (ie. if TXEN gets cleared after writing to -SIO_TX_DATA, then the transfer may STILL start if the old latched TXEN value +SIO\_TX\_DATA, then the transfer may STILL start if the old latched TXEN value was set).
-#### 1F801040h JOY_RX_DATA (R) +#### 1F801040h JOY\_RX\_DATA (R) ``` 0-7 Received Data (1st RX FIFO entry) (oldest entry) 8-15 Preview (2nd RX FIFO entry) 16-23 Preview (3rd RX FIFO entry) 24-31 Preview (4th RX FIFO entry) (5th..8th cannot be previewed) ``` -A data byte can be read when JOY_STAT.1=1. Data should be read only via 8bit +A data byte can be read when JOY\_STAT.1=1. Data should be read only via 8bit memory access (the 16bit/32bit "preview" feature is rather unusable, and usually there shouldn't be more than 1 byte in the FIFO anyways).
-#### 1F801044h JOY_STAT (R) +#### 1F801044h JOY\_STAT (R) ``` 0 TX Ready Flag 1 (1=Ready/Started) 1 RX FIFO Not Empty (0=Empty, 1=Not Empty) @@ -75,7 +75,7 @@ usually there shouldn't be more than 1 byte in the FIFO anyways).
11-31 Baudrate Timer (21bit timer, decrementing at 33MHz) ``` -#### 1F801048h JOY_MODE (R/W) (usually 000Dh, ie. 8bit, no parity, MUL1) +#### 1F801048h JOY\_MODE (R/W) (usually 000Dh, ie. 8bit, no parity, MUL1) ``` 0-1 Baudrate Reload Factor (1=MUL1, 2=MUL16, 3=MUL64) (or 0=MUL1, too) 2-3 Character Length (0=5bits, 1=6bits, 2=7bits, 3=8bits) @@ -86,7 +86,7 @@ usually there shouldn't be more than 1 byte in the FIFO anyways).
9-15 Unknown (always zero) ``` -#### 1F80104Ah JOY_CTRL (R/W) (usually 1003h,3003h,0000h) +#### 1F80104Ah JOY\_CTRL (R/W) (usually 1003h,3003h,0000h) ``` 0 TX Enable (TXEN) (0=Disable, 1=Enable) 1 /JOYn Output (0=High, 1=Low/Select) (/JOYn as defined in Bit13) @@ -109,7 +109,7 @@ Dualshock and Mouse require at least some small delay, and older Analog Joypads require a huge delay (around 500 clock cycles for SCPH-1150), official kernel waits more than 2000 cycles (which is much more than needed).
-#### 1F80104Eh JOY_BAUD (R/W) (usually 0088h, ie. circa 250kHz, when Factor=MUL1) +#### 1F80104Eh JOY\_BAUD (R/W) (usually 0088h, ie. circa 250kHz, when Factor=MUL1) ``` 0-15 Baudrate Reload value for decrementing Baudrate Timer ``` @@ -136,16 +136,16 @@ an /ACK, or if there's no peripheral connected at all).
Actually, /IRQ7 means "more-data-request", accordingly, it does NOT get triggered after receiving the LAST byte. ``` -I_STAT.7 is edge triggered (that means it can be acknowledge before or after -acknowledging JOY_STAT.9). However, JOY_STAT.9 is NOT edge triggered (that +I\_STAT.7 is edge triggered (that means it can be acknowledge before or after +acknowledging JOY\_STAT.9). However, JOY\_STAT.9 is NOT edge triggered (that means it CANNOT be acknowledged while the external /IRQ input is still low; ie. -one must first wait until JOY_STAT.7=0, and then set JOY_CTRL.4=1) (this is +one must first wait until JOY\_STAT.7=0, and then set JOY\_CTRL.4=1) (this is apparently a hardware glitch; note: the LOW duration is circa 100 clock cycles).
#### /IRQ10 (/IRQ) Controller - Lightpen Interrupt Pin8 on Controller Port. Routed directly to the Interrupt Controller (at -1F80107xh). There are no status/enable bits in the JOY_registers (at +1F80107xh). There are no status/enable bits in the JOY\_registers (at 1F80104xh).
#### RX FIFO / TX FIFO Notes @@ -191,7 +191,7 @@ Controllers can be probably accessed via InitPad and StartPad functions,
[BIOS Joypad Functions](kernelbios.md#bios-joypad-functions)
Memory cards can be accessed by the filesystem (with device names "bu00:" (slot1) and "bu10:" (slot2) or so). Before using that device names, it seems to -be required to call InitCard, StartCard, and _bu_init (?).
+be required to call InitCard, StartCard, and \_bu\_init (?).
#### Connectors The PlayStation has four connectors (two controllers, two memory cards),
@@ -261,15 +261,15 @@ usually 00h) to receive the response bytes.
X = none, - = Hi-Z
-* 0x81 is memory-card, 0x01 is standard-pad at top command.
-* serial data transfer is LSB-First format.
-* data is down edged output, PSX is read at up edge in shift clock.
-* PSX expects No-connection if not returned Acknowledge less than 100 usec.
-* clock pulse is 250KHz.
-* no need Acknowledge at last data.
-* Acknowledge signal width is more than 2 usec.
-* time is 16msec between SEL from previous SEL.
-* SEL- for memory card in PAD access.
+\* 0x81 is memory-card, 0x01 is standard-pad at top command.
+\* serial data transfer is LSB-First format.
+\* data is down edged output, PSX is read at up edge in shift clock.
+\* PSX expects No-connection if not returned Acknowledge less than 100 usec.
+\* clock pulse is 250KHz.
+\* no need Acknowledge at last data.
+\* Acknowledge signal width is more than 2 usec.
+\* time is 16msec between SEL from previous SEL.
+\* SEL- for memory card in PAD access.
@@ -1065,7 +1065,7 @@ screen; ie. on the game's GP1(06h) and GP1(07h) settings.
Vertical coordinates are counted in scanlines (ie. equal to pixels). Horizontal coordinates are counted in 8MHz units (which would equal a resolution of 385 pixels; which can be, for example, converted to 320 pixel resolution as -X=X*320/385).
+X=X\*320/385).
#### Misinformation (from bugged homebrew source code) ``` @@ -1184,7 +1184,7 @@ different if IRQs are disabled (eg. while another IRQ is processed).
However, IRQ10 does also get triggered in the next some scanlines, so the first IRQ10 is used only as a notification that the CPU should watch out for further IRQ10's. Ie. the IRQ10 handler should disable all DMAs, acknowledge IRQ10, and -then enter a waitloop that waits for the IRQ10 bit in I_STAT to become set +then enter a waitloop that waits for the IRQ10 bit in I\_STAT to become set again (or abort if a timeout occurs) and then read the timers, reportedly like so:
``` @@ -1824,7 +1824,7 @@ port).
#### TTY Debug Terminal If present, the external DUART can be used for external keyboard input, at the -BIOS side, this is supported as "std_in".
+BIOS side, this is supported as "std\_in".
@@ -2056,7 +2056,7 @@ Sony), followed by up to 8 characters,
``` (which may identify the file if the game uses multiple files; this part often contains a random string which seems to be allowed to contain any chars in -range of 20h..7Fh, of course it shouldn't contain "?" and "*" wildcards).
+range of 20h..7Fh, of course it shouldn't contain "?" and "\*" wildcards).
#### Broken Sector List (Block 0, Frame 16..35) ``` diff --git a/conversion/psx-spx-pass1.awk b/conversion/psx-spx-pass1.awk index 19529e7..f72396d 100644 --- a/conversion/psx-spx-pass1.awk +++ b/conversion/psx-spx-pass1.awk @@ -6,7 +6,7 @@ function trim(s) { return rtrim(ltrim(s)); } # Escape slashes and amps in a string for building links function linkescape(s) { gsub(/\//, "\\/", s); - gsub(/\&/, "\\\\&", s); + gsub(/&/, "\\\\&", s); return s; } @@ -68,6 +68,9 @@ WAIT_FOR_START { next; } # outside of
 blocks, we want to escape these for the md format.
         gsub(/</, "\\<");
         gsub(/>/, "\\>");
+        gsub(/*/, "\\*");
+        gsub(/_/, "\\_");
+        gsub(/~/, "\\~");
     }
     gsub(/&/, "\\&");
 
diff --git a/cpuspecifications.md b/cpuspecifications.md
index bd1ed4d..0033283 100644
--- a/cpuspecifications.md
+++ b/cpuspecifications.md
@@ -52,7 +52,7 @@ for most CPUs) - Full means that SP points to the first ALLOCATED word on the
 stack, so the allocated memory is at SP+0 and above, free memory at SP-1 and
 below, Wasted means that when calling a sub-function with N parameters, then
 the caller must pre-allocate N works on stack, and the sub-function may freely
-use and destroy these words; at [SP+0..N*4-1].
+use and destroy these words; at [SP+0..N\*4-1].
For example, "push ra,r16,r17" would be implemented as:
``` @@ -294,7 +294,7 @@ The mul/div opcodes are starting the multiply/divide operation, starting takes only a single clock cycle, however, trying to read the result from the hi/lo registers while the mul/div operation is busy will halt the CPU until the mul/div has completed. For multiply, the execution time depends on rs (ie. -"small*large" can be much faster than "large*small").
+"small\*large" can be much faster than "large\*small").
``` __umul_execution_time_____________________________________________________ Fast (6 cycles) rs = 00000000h..000007FFh diff --git a/dmachannels.md b/dmachannels.md index bfe29a5..8a68a2d 100644 --- a/dmachannels.md +++ b/dmachannels.md @@ -15,7 +15,7 @@ These ports control DMA at the CPU-side. In most cases, you'll additionally need to initialize an address (and transfer direction, transfer enabled, etc.) at the remote-side (eg. at the GPU-side for DMA2).
-#### 1F801080h+N*10h - D#_MADR - DMA base address (Channel 0..6) (R/W) +#### 1F801080h+N\*10h - D#\_MADR - DMA base address (Channel 0..6) (R/W) ``` 0-23 Memory Address where the DMA will start reading from/writing to 24-31 Not used (always zero) @@ -30,7 +30,7 @@ hold the end-address in SyncMode=1, or the 00FFFFFFh end-code in SyncMode=2)
-#### 1F801084h+N*10h - D#_BCR - DMA Block Control (Channel 0..6) (R/W) +#### 1F801084h+N\*10h - D#\_BCR - DMA Block Control (Channel 0..6) (R/W) For SyncMode=0 (ie. for OTC and CDROM):
``` 0-15 BC Number of words (0001h..FFFFh) (or 0=10000h words) @@ -50,10 +50,10 @@ set the blocksize larger than the buffer of the corresponding unit can hold. (GPU and SPU both have a 16-word buffer). A larger blocksize means faster transfer.
SyncMode=1 decrements BA to zero, SyncMode=0 with chopping enabled decrements -BC to zero (aside from that two cases, D#_BCR isn't changed during/after +BC to zero (aside from that two cases, D#\_BCR isn't changed during/after transfer).
-#### 1F801088h+N*10h - D#_CHCR - DMA Channel Control (Channel 0..6) (R/W) +#### 1F801088h+N\*10h - D#\_CHCR - DMA Channel Control (Channel 0..6) (R/W) ``` 0 Transfer Direction (0=To Main RAM, 1=From Main RAM) 1 Memory Address Step (0=Forward;+4, 1=Backward;-4) @@ -82,7 +82,7 @@ force the first block to be transferred instantly without DRQ, which isn't desired).
The Start/Busy bit is automatically cleared upon COMPLETION of the transfer, this bit must be always set for all SyncModes when starting a transfer.
-For DMA6/OTC there are some restrictions, D6_CHCR has only three +For DMA6/OTC there are some restrictions, D6\_CHCR has only three read/write-able bits: Bit24,28,30. All other bits are read-only: Bit1 is always 1 (step=backward), and the other bits are always 0.
diff --git a/expansionportpio.md b/expansionportpio.md index 97a1e70..59820cd 100644 --- a/expansionportpio.md +++ b/expansionportpio.md @@ -298,8 +298,8 @@ Additionally, the OP0 and OP1 outputs are controlled via MR2A.5 and MR2B.5.
BGR Test switches between Baud Rate Set1/Set2 and Set3/Set4.
1X/16X Test switches between whatever...?
-#### 1F80202Eh/Read - CT_START - DUART Start Counter Command (Read=Strobe) -#### 1F80202Fh/Read - CT_STOP - DUART Stop Counter Command (Read=Strobe) +#### 1F80202Eh/Read - CT\_START - DUART Start Counter Command (Read=Strobe) +#### 1F80202Fh/Read - CT\_STOP - DUART Stop Counter Command (Read=Strobe) ``` 7-0 Not used (just issue a dummy-read to strobe start/stop command) ``` @@ -333,7 +333,7 @@ Note: The Motorola 68681 should be the same as the Philips/Signetics 2681.
Unknown if the Interrupt signal is connected to the PSX... there seems to be no spare IRQ for it, though it \ share an IRQ with whatever other hardware...?
-The BIOS seems to use only one of the two channels; for the std_io functions:
+The BIOS seems to use only one of the two channels; for the std\_io functions:
[BIOS TTY Console (std_io)](kernelbios.md#bios-tty-console-stdio)
Aside from the external DUART, the PSX additionally contains an internal UART,
[Serial Port (SIO)](serialportsio.md)
diff --git a/geometrytransformationenginegte.md b/geometrytransformationenginegte.md index efac7fc..7a423f7 100644 --- a/geometrytransformationenginegte.md +++ b/geometrytransformationenginegte.md @@ -414,7 +414,7 @@ set.
MAC0=(((H*20000h/SZ3)+1)/2)*IR2+OFY, SY2=MAC0/10000h ;ScrY FIFO -400h..+3FFh MAC0=(((H*20000h/SZ3)+1)/2)*DQA+DQB, IR0=MAC0/1000h ;Depth cueing 0..+1000h ``` -If the result of the "(((H*20000h/SZ3)+1)/2)" division is greater than 1FFFFh, +If the result of the "(((H\*20000h/SZ3)+1)/2)" division is greater than 1FFFFh, then the division result is saturated to +1FFFFh, and the divide overflow bit in the FLAG register gets set; that happens if the vertex is exceeding the "near clip plane", ie. if it is very close to the camera (SZ3\<=H/2), exactly @@ -475,12 +475,12 @@ Multiplies a vector with either the rotation matrix, the light matrix or the color matrix and then adds the translation vector or background color vector.
The GTE also allows selection of the far color vector (FC), but this vector is not added correctly by the hardware: The return values are reduced to the last -portion of the formula, ie. MAC1=(Mx13*Vx3) SAR (sf*12), and similar for MAC2 +portion of the formula, ie. MAC1=(Mx13\*Vx3) SAR (sf\*12), and similar for MAC2 and MAC3, nethertheless, some bits in the FLAG register seem to be adjusted as if the full operation would have been executed. Setting Mx=3 selects a garbage matrix (with elements -60h, +60h, IR0, RT13, RT13, RT13, RT22, RT22, RT22).
-#### COP2 0A00428h+sf*80000h - 5 Cycles - SQR(sf) - Square vector +#### COP2 0A00428h+sf\*80000h - 5 Cycles - SQR(sf) - Square vector ``` [MAC1,MAC2,MAC3] = [IR1*IR1,IR2*IR2,IR3*IR3] SHR (sf*12) [IR1,IR2,IR3] = [MAC1,MAC2,MAC3] ;IR1,IR2,IR3 saturated to max 7FFFh @@ -488,7 +488,7 @@ matrix (with elements -60h, +60h, IR0, RT13, RT13, RT13, RT22, RT22, RT22).
Calculates the square of a vector. The result is, of course, always positive, so the "lm" flag for negative saturation has no effect.
-#### COP2 170000Ch+sf*80000h - 6 Cycles - OP(sf,lm) - Outer product of 2 vectors +#### COP2 170000Ch+sf\*80000h - 6 Cycles - OP(sf,lm) - Outer product of 2 vectors ``` [MAC1,MAC2,MAC3] = [IR3*D2-IR2*D3, IR1*D3-IR3*D1, IR2*D1-IR1*D2] SAR (sf*12) [IR1,IR2,IR3] = [MAC1,MAC2,MAC3] ;copy result @@ -563,7 +563,7 @@ Fifo entries are modified.
Note: Although the SHL in GPL is theoretically undone by the SAR, 44bit overflows can occur internally when sf=1.
-#### Details on "MAC+(FC-MAC)*IR0" +#### Details on "MAC+(FC-MAC)\*IR0" ``` [IR1,IR2,IR3] = (([RFC,GFC,BFC] SHL 12) - [MAC1,MAC2,MAC3]) SAR (sf*12) [MAC1,MAC2,MAC3] = (([IR1,IR2,IR3] * IR0) + [MAC1,MAC2,MAC3]) @@ -572,7 +572,7 @@ Note: Above "[IR1,IR2,IR3]=(FC-MAC)" is saturated to -8000h..+7FFFh (ie. as if lm=0), anyways, further writes to [IR1,IR2,IR3] (within the same command) are saturated as usually (ie. depening on lm setting).
-#### Details on "(LLM*V0) SAR (sf*12)" and "(BK*1000h + LCM*IR) SAR (sf*12)" +#### Details on "(LLM\*V0) SAR (sf\*12)" and "(BK\*1000h + LCM\*IR) SAR (sf\*12)" Works like MVMVA command (see there), but with fixed Tx/Vx/Mx parameters, the sf/lm bits can be changed and do affect the results (although normally both bits should be set for use with color matrices).
@@ -621,7 +621,7 @@ mechanism (based on Unsigned Newton-Raphson (UNR) algorithm):
n = min(1FFFFh, (((n*d) + 8000h) SHR 16)) ;n=0..1FFFFh else n = 1FFFFh, FLAG.Bit17=1, FLAG.Bit31=1 ;n=1FFFFh plus overflow flag ``` -the GTE's unr_table[000h..100h] consists of following values:
+the GTE's unr\_table[000h..100h] consists of following values:
``` FFh,FDh,FBh,F9h,F7h,F5h,F3h,F1h,EFh,EEh,ECh,EAh,E8h,E6h,E4h,E3h ;\ E1h,DFh,DDh,DCh,DAh,D8h,D6h,D5h,D3h,D1h,D0h,CEh,CDh,CBh,C9h,C8h ; 00h..3Fh @@ -641,9 +641,9 @@ the GTE's unr_table[000h..100h] consists of following values:
07h,07h,06h,06h,05h,05h,04h,04h,03h,03h,02h,02h,01h,01h,00h,00h ;/ 00h ;<-- one extra table entry (for "(d-7FC0h)/80h"=100h) ;-100h ``` -Above can be generated as "unr_table[i]=min(0,(40000h/(i+100h)+1)/2-101h)".
+Above can be generated as "unr\_table[i]=min(0,(40000h/(i+100h)+1)/2-101h)".
Some special cases: NNNNh/0001h uses a big multiplier (d=20000h), in practice, -this can occur only for 0000h/0001h and 0001h/0001h (due to the H\ The min(1FFFFh) limit is needed for cases like FE3Fh/7F20h, F015h/780Bh, etc. (these do produce UNR result 20000h, and are saturated to 1FFFFh, but without diff --git a/graphicsprocessingunitgpu.md b/graphicsprocessingunitgpu.md index abb0b3b..90b51b9 100644 --- a/graphicsprocessingunitgpu.md +++ b/graphicsprocessingunitgpu.md @@ -645,7 +645,7 @@ edge, which can be utilised by setting the start of the screen earlier and the end later. The size of the pixels is NOT changed with these settings, the GPU simply sends more data to the screen. Some monitors/TVs have a smaller display area and the extended size might not be visible on those sets. "(Mine is -capable of about 330 pixels horizontal, and 272 vertical in 320*240 mode)"
+capable of about 330 pixels horizontal, and 272 vertical in 320\*240 mode)"
#### GP1(05h) - Start of Display area (in VRAM) ``` @@ -655,7 +655,7 @@ capable of about 330 pixels horizontal, and 272 vertical in 320*240 mode)"
``` Upper/left Display source address in VRAM. The size and target position on screen is set via Display Range registers; target=X1,Y2; -size=(X2-X1/cycles_per_pix), (Y2-Y1).
+size=(X2-X1/cycles\_per\_pix), (Y2-Y1).
#### GP1(06h) - Horizontal Display range (on Screen) ``` @@ -664,8 +664,8 @@ size=(X2-X1/cycles_per_pix), (Y2-Y1).
``` Specifies the horizontal range within which the display area is displayed. For resolutions other than 320 pixels it may be necessary to fine adjust the value -to obtain an exact match (eg. X2=X1+pixels*cycles_per_pix).
-The number of displayed pixels per line is "(((X2-X1)/cycles_per_pix)+2) AND +to obtain an exact match (eg. X2=X1+pixels\*cycles\_per\_pix).
+The number of displayed pixels per line is "(((X2-X1)/cycles\_per\_pix)+2) AND NOT 3" (ie. the hardware is rounding the width up/down to a multiple of 4 pixels).
Most games are using a width equal to the horizontal resolution (ie. 256, 320, diff --git a/interrupts.md b/interrupts.md index fe14d2b..65f43af 100644 --- a/interrupts.md +++ b/interrupts.md @@ -1,9 +1,9 @@ # Interrupts -#### 1F801070h I_STAT - Interrupt status register (R=Status, W=Acknowledge) -#### 1F801074h I_MASK - Interrupt mask register (R/W) -Status: Read I_STAT (0=No IRQ, 1=IRQ)
-Acknowledge: Write I_STAT (0=Clear Bit, 1=No change)
-Mask: Read/Write I_MASK (0=Disabled, 1=Enabled)
+#### 1F801070h I\_STAT - Interrupt status register (R=Status, W=Acknowledge) +#### 1F801074h I\_MASK - Interrupt mask register (R/W) +Status: Read I\_STAT (0=No IRQ, 1=IRQ)
+Acknowledge: Write I\_STAT (0=Clear Bit, 1=No change)
+Mask: Read/Write I\_MASK (0=Disabled, 1=Enabled)
``` 0 IRQ0 VBLANK (PAL=50Hz, NTSC=60Hz) 1 IRQ1 GPU Can be requested via GP0(1Fh) command (rarely used) @@ -24,26 +24,26 @@ Mask: Read/Write I_MASK (0=Disabled, 1=Enabled)
[EXP2 DTL-H2000 I/O Ports](expansionportpio.md#exp2-dtl-h2000-io-ports)
#### Interrupt Request / Execution -The interrupt request bits in I_STAT are edge-triggered, ie. the get set ONLY +The interrupt request bits in I\_STAT are edge-triggered, ie. the get set ONLY if the corresponding interrupt source changes from "false to true".
-If one or more interrupts are requested and enabled, ie. if "(I_STAT AND -I_MASK)=nonzero", then cop0r13.bit10 gets set, and when cop0r12.bit10 and +If one or more interrupts are requested and enabled, ie. if "(I\_STAT AND +I\_MASK)=nonzero", then cop0r13.bit10 gets set, and when cop0r12.bit10 and cop0r12.bit0 are set, too, then the interrupt gets executed.
#### Interrupt Acknowledge -To acknowledge an interrupt, write a "0" to the corresponding bit in I_STAT. +To acknowledge an interrupt, write a "0" to the corresponding bit in I\_STAT. Most interrupts (except IRQ0,4,5,6) must be additionally acknowledged at the -I/O port that has caused them (eg. JOY_CTRL.bit4).
-Observe that the I_STAT bits are edge-triggered (they get set only on +I/O port that has caused them (eg. JOY\_CTRL.bit4).
+Observe that the I\_STAT bits are edge-triggered (they get set only on High-to-Low, or False-to-True edges). The correct acknowledge order is:
``` First, acknowledge I_STAT (eg. I_STAT.bit7=0) Then, acknowledge corresponding I/O port (eg. JOY_CTRL.bit4=1) ``` When doing it vice-versa, the hardware may miss further IRQs (eg. when first -setting JOY_CTRL.4=1, then a new IRQ may occur in JOY_STAT.4 within a single -clock cycle, thereafter, setting I_STAT.7=0 would successfully reset I_STAT.7, -but, since JOY_STAT.4 is already set, there'll be no further edge, so I_STAT.7 +setting JOY\_CTRL.4=1, then a new IRQ may occur in JOY\_STAT.4 within a single +clock cycle, thereafter, setting I\_STAT.7=0 would successfully reset I\_STAT.7, +but, since JOY\_STAT.4 is already set, there'll be no further edge, so I\_STAT.7 won't be ever set in future).
#### COP0 Interrupt Handling @@ -55,7 +55,7 @@ opcode) is used to prepare the return from interrupts. For more info, see
#### PSX specific COP0 Notes COP0 has six hardware interrupt bits, of which, the PSX uses only cop0r13.bit10 (the other ones, cop0r13.bit11-15 are always zero). cop0r13.bit10 is NOT a -latch, ie. it gets automatically cleared as soon as "(I_STAT AND I_MASK)=zero", +latch, ie. it gets automatically cleared as soon as "(I\_STAT AND I\_MASK)=zero", so there's no need to do an acknowledge at the cop0 side. COP0 additionally has two software interrupt bits, cop0r13.bit8-9, which do exist in the PSX, too, these bits are read/write-able latches which can be set/cleared manually to diff --git a/kernelbios.md b/kernelbios.md index bd36dd9..73c4d14 100644 --- a/kernelbios.md +++ b/kernelbios.md @@ -131,8 +131,8 @@ total size (in bytes) of the corresponding control blocks.
00000148h - Unused/reserved 00000150h DCB Device Control Blocks (addr=fixed, size=0Ah*50h) ``` -File handles (fd=00h..0Fh) can be simply converted as fcb=[140h]+fd*2Ch.
-Event handles (event=F10000xxh) as evcb=[120h]+(event AND FFFFh)*1Ch.
+File handles (fd=00h..0Fh) can be simply converted as fcb=[140h]+fd\*2Ch.
+Event handles (event=F10000xxh) as evcb=[120h]+(event AND FFFFh)\*1Ch.
#### Garbage Area at Address 00000000h The first some bytes of memory address 00000000h aren't actually used by the @@ -163,7 +163,7 @@ Argument(s) are passed in R4,R5,R6,R7,[SP+10h],[SP+14h],etc.
Caution: When calling a sub-function with N parameters, the caller MUST always allocate N words on the stack, and, although the first four parameters are passed in registers rather than on stack, the sub-function is allowed to -use/destroy these words at [SP+0..N*4-1].
+use/destroy these words at [SP+0..N\*4-1].
BIOS Functions (and custom callback functions) are allowed to destroy registers R1-R15, R24-R25, R31 (RA), and HI/LO. Registers R16-R23, R29 (SP), and R30 (FP) must be left unchanged (if the function uses that registers, then it must @@ -513,7 +513,7 @@ The 20bit immediate in the "syscall imm" opcode is unused (should be zero).
#### BREAK-Functions (Break opcode with function number in opcode's immediate) BRK opcodes may be used within devkits, however, the standard BIOS simply calls -DeliverEvent(F0000010h,1000h) and SystemError_A_40h upon any BRK opcodes (as +DeliverEvent(F0000010h,1000h) and SystemError\_A\_40h upon any BRK opcodes (as well as on any other unresolved exceptions).
``` BRK(1C00h) Division by zero (commonly checked/invoked by software) @@ -554,7 +554,7 @@ Opens a file on the target device for io. Accessmode is set like this:
bit16-31 Number of memory card blocks for a new file on the memory card ``` The PSX can have a maximum of 16 files open at any time, of which, 2 handles -are always reserved for std_io, so only 14 handles are available for actual +are always reserved for std\_io, so only 14 handles are available for actual files. Some functions (chdir, testdevice, FileDelete, FileUndelete, FormatDevice, firstfile, FileRename) are temporarily allocating 1 filehandle (FileRename tries to use 2 filehandles, but, it does accidently use only 1 @@ -621,10 +621,10 @@ stored in RAM, so chdir is causing useless SLOW read/seek delays).
#### B(42h) - firstfile(filename,direntry) - Find first file to match the name Returns r2=direntry (or r2=0 if no matching files).
Searches for the first file to match the specified filename; the filename may -contain "?" and "*" wildcards. "*" means to ignore ALL following characters; -accordingly one cannot specify any further characters after the "*" (eg. -"DATA*" would work, but "*.DAT" won't work). "?" is meant to ignore a single -character cell. Note: The "?" wildcards (but not "*") can be used also in all +contain "?" and "\*" wildcards. "\*" means to ignore ALL following characters; +accordingly one cannot specify any further characters after the "\*" (eg. +"DATA\*" would work, but "\*.DAT" won't work). "?" is meant to ignore a single +character cell. Note: The "?" wildcards (but not "\*") can be used also in all other file functions; causing the function to use the first matching name (eg. FileDelete "????" would erase the first matching file, not all matching files).
Start the name with the device you want to address. (ie. pcdrv:) Different @@ -659,7 +659,7 @@ operations.
Returns r2=direntry (or r2=0 if no more matching files).
Uses the settings of a previous firstfile/nextfile command.
-#### B(44h) - FileRename(old_filename, new_filename) +#### B(44h) - FileRename(old\_filename, new\_filename) Returns 1=okay, or 0=failed.
#### B(45h) - FileDelete(filename) - Delete a file on target device @@ -778,18 +778,18 @@ BUG: Part3 accidently treats the first 4 characters of the exename as memory address (causing an invalid memory address exception on address 6F726463h, for "cdrom:filename.exe").
-#### A(9Ch) - SetConf(num_EvCB, num_TCB, stacktop) +#### A(9Ch) - SetConf(num\_EvCB, num\_TCB, stacktop) Changes the number of EvCBs and TCBs, and the stacktop. That values are usually initialized from the settings in the SYSTEM.CNF file, so using this function usually shouldn't ever be required.
The function deallocates all old ExCBs, EvCBs, TCBs (so all Exception handlers, Events, and Threads (except the current one) are lost, and all other memory -that may have been allocated via alloc_kernel_memory(size) is deallocated, too. +that may have been allocated via alloc\_kernel\_memory(size) is deallocated, too. It does then allocate the new control blocks, and enqueue the default handlers. Despite of the changed stacktop, the current stack pointer is kept intact, and the function returns to the caller.
-#### A(9Dh) - GetConf(num_EvCB_dst, num_TCB_dst, stacktop_dst) +#### A(9Dh) - GetConf(num\_EvCB\_dst, num\_TCB\_dst, stacktop\_dst) Returns the number of EvCBs, TCBs, and the initial stacktop. There's no return value in the R2 register, instead, the three 32bit return values are stored at the specified "dst" addresses.
@@ -822,7 +822,7 @@ to:
init_card B(4Ah) and by intro/boot code ``` -for load_file/load_exec, IRQ2 (cdrom) and IRQ3 (dma) need to be enabled, so the +for load\_file/load\_exec, IRQ2 (cdrom) and IRQ3 (dma) need to be enabled, so the "disable all IRQs" workaround cannot be used for that functions, however, one can/should disable as many IRQs as possible, ie. everything except IRQ2/IRQ3, and all DMA interrupts except DMA3 (cdrom).
@@ -942,7 +942,7 @@ Memory Cards aka Backup Units (bu) are basically accessed via normal file functions, with device names "bu00:" (Slot 1) and "bu10:" (Slot 2),
[BIOS File Functions](kernelbios.md#bios-file-functions)
Before using the file functions for memory cards, first call -InitCard(pad_enable), then StartCard(), and then _bu_init().
+InitCard(pad\_enable), then StartCard(), and then \_bu\_init().
#### File Header, Filesize, and Sector Alignment The first 100h..200h bytes (2..4 sectors) of the file must contain the title @@ -987,7 +987,7 @@ immediately after invoking the access (which does then continue on interrupt level, and does return an event when finished).
The file "FileRead" and "FileWrite" functions act asynchronous when accessmode bit15 is set when opening the file. Additionally, the A(ACh) -_card_async_load_directory(port) function can be used to tell the BIOS to load +\_card\_async\_load\_directory(port) function can be used to tell the BIOS to load the directory entries and broken sector list to its internal RAM buffers (eg. during the games title screen, so the BIOS doesn't need to load that data once when the game enters its memory card menu). All other functions like FileDelete @@ -1007,7 +1007,7 @@ cards (via Multitap adaptors). Device/port names "bu01:", "bu02:", "bu03:" allow to access extra memory carts in slot1 (and "bu11:", "bu12:", "bu13:" in slot2). Namely, those names will send values 82h, 83h, 84h to the memory card slot (instead of the normal 81h value).
-However, the BIOS directory_buffer and broken_sector_list do support only two +However, the BIOS directory\_buffer and broken\_sector\_list do support only two memory cards (one in slot1 and one in slot2). So, trying to access more memory cards may cause great data corruption (though there might be a way to get the BIOS to reload those buffers before accessing a different memory card).
@@ -1016,52 +1016,52 @@ accessing only two memory cards. Trying to use the BIOS to access up to eight memory cards would be very-extremly-very slow, which would be more annoying than useful.
-#### B(4Ah) - InitCard(pad_enable) ;uses/destroys k0/k1 !!! +#### B(4Ah) - InitCard(pad\_enable) ;uses/destroys k0/k1 !!! #### B(4Bh) - StartCard() #### B(4Ch) - StopCard() -#### A(55h) or A(70h) - _bu_init() +#### A(55h) or A(70h) - \_bu\_init() ``` --- Below are some lower level memory card functions --- ``` -#### A(ABh) - _card_info(port) -#### B(4Dh) - _card_info_subfunc(port) ;subfunction for "_card_info" -Can be used to check if the most recent call to write_card_sector has completed +#### A(ABh) - \_card\_info(port) +#### B(4Dh) - \_card\_info\_subfunc(port) ;subfunction for "\_card\_info" +Can be used to check if the most recent call to write\_card\_sector has completed okay. Issues an incomplete dummy read command (similar to B(4Fh) - -read_card_sector). The read command is aborted once when receiving the status +read\_card\_sector). The read command is aborted once when receiving the status byte from the memory card (the actual data transfer is skipped).
-#### A(AFh) - card_write_test(port) ;not supported by old CEX-1000 version +#### A(AFh) - card\_write\_test(port) ;not supported by old CEX-1000 version Resets the card changed flag. For some strange reason, this flag isn't automatically reset after reading the flag, instead, the flag is reset upon sector writes. To do that, this function issues a dummy write to sector 3Fh.
-#### B(50h) - allow_new_card() +#### B(50h) - allow\_new\_card() Normally any memory card read/write functions fail if the BIOS senses the card change flag to be set. Calling this function tells the BIOS to ignore the card change flag on the next read/write operation (the function is internally used -when loading the "MC" ID from sector 0, and when calling the card_write_test +when loading the "MC" ID from sector 0, and when calling the card\_write\_test function to acknowledge the card change flag).
-#### B(4Eh) - write_card_sector(port,sector,src) -#### B(4Fh) - read_card_sector(port,sector,dst) +#### B(4Eh) - write\_card\_sector(port,sector,src) +#### B(4Fh) - read\_card\_sector(port,sector,dst) Invokes asynchronous reading/writing of a single sector. The function returns 1=okay, or 0=failed (on invalid sector numbers). The actual I/O is done on IRQ level, completion of the I/O command transmission can be checked, among others, -via get/wait_card_status(slot) functions (with slot=port/10h).
+via get/wait\_card\_status(slot) functions (with slot=port/10h).
In case of the write function, completion of the \ does NOT mean that the actual \ has completed, instead, write errors are indicated upon completion of the \ read/write transmission -(or, if there are no further sectors to be accessed; one can use _card_info to +(or, if there are no further sectors to be accessed; one can use \_card\_info to verify completion of the last written sector).
The sector number should be in range of 0..3FFh, for some strange reason, probably a BUG, the function also accepts sector 400h. The specified sector number is directly accessed (it is NOT parsed through the broken sector replacement list).
-#### B(5Ch) - get_card_status(slot) -#### B(5Dh) - wait_card_status(slot) +#### B(5Ch) - get\_card\_status(slot) +#### B(5Dh) - wait\_card\_status(slot) Returns the status of the most recent I/O command, possible values are:
``` 01h=ready @@ -1071,29 +1071,29 @@ Returns the status of the most recent I/O command, possible values are:
11h=failed/timeout (eg. when no cartridge inserted) 21h=failed/general error ``` -get_card_status returns immediately, wait_card_status waits until a non-busy +get\_card\_status returns immediately, wait\_card\_status waits until a non-busy state occurs.
-#### A(A7h) - bu_callback_okay() -#### A(A8h) - bu_callback_err_write() -#### A(A9h) - bu_callback_err_busy() -#### A(AAh) - bu_callback_err_eject() -#### A(AEh) - bu_callback_err_prev_write() +#### A(A7h) - bu\_callback\_okay() +#### A(A8h) - bu\_callback\_err\_write() +#### A(A9h) - bu\_callback\_err\_busy() +#### A(AAh) - bu\_callback\_err\_eject() +#### A(AEh) - bu\_callback\_err\_prev\_write() These five callback functions are internally used by the BIOS, notifying other BIOS functions about (un-)successful completion of memory card I/O commands.
-#### B(58h) - get_bu_callback_port() -This is a subfunction for the five bu_callback_xxx functions (indicating +#### B(58h) - get\_bu\_callback\_port() +This is a subfunction for the five bu\_callback\_xxx functions (indicating whether the callback occured for a slot1 or slot2 access).
-#### A(ACh) - _card_async_load_directory(port) +#### A(ACh) - \_card\_async\_load\_directory(port) Invokes asynchronous reading of the memory card directory. The function isn't too useful because the BIOS tends to read the directory automatically in various places in synchronous mode, so there isn't too much chance to replace the automatic synchronous reading by asynchronous reading.
-#### A(ADh) - set_card_auto_format(flag) -Can be used to enable/disable auto format (0=off, 1=on). The _bu_init function +#### A(ADh) - set\_card\_auto\_format(flag) +Can be used to enable/disable auto format (0=off, 1=on). The \_bu\_init function initializes auto format as disabled. If auto format is enabled, then the BIOS does automatically format memory cards if it has failed to read the "MC" ID bytes on sector 0. Although potentially useful, activating this feature is @@ -1102,8 +1102,8 @@ due to improperly inserted cards with dirty contacts, so it'd be better to prompt the user whether or not to format the card, rather than doing that automatically).
-#### C(1Ah) - set_card_find_mode(mode) -#### C(1Dh) - get_card_find_mode() +#### C(1Ah) - set\_card\_find\_mode(mode) +#### C(1Dh) - get\_card\_find\_mode() Allows to get/set the card find mode (0=normal, 1=find deleted files), the mode setting affects only the firstfile/nextfile functions. All other file functions are used fixed mode settings (always mode=0 for FileOpen, FileRename, @@ -1330,7 +1330,7 @@ This function is usually called by the kernel, undelivers all events that are enabled/ready, and that have mode=2000h, and that have the specified class and spec values. Undeliver means that the events are marked as enabled/busy.
-#### C(04h) get_free_EvCB_slot() +#### C(04h) get\_free\_EvCB\_slot() A subfunction for OpenEvent.
#### Event Classes @@ -1482,7 +1482,7 @@ notifications from the BIOS).
## BIOS Thread Functions -#### B(0Eh) OpenThread(reg_PC,reg_SP_FP,reg_GP) +#### B(0Eh) OpenThread(reg\_PC,reg\_SP\_FP,reg\_GP) Searches a free TCB, marks it as used, and stores the inital program counter (PC), global pointer (GP aka R28), stack pointer (SP aka R29), and frame pointer (FP aka R30) (using the same value for SP and FP). All other registers @@ -1530,7 +1530,7 @@ back to that thread. Mind that other registers (I/O Ports or GTE registers aren't stored automatically, so, when needed, they need to be pushed/popped by software before/after ChangeThread).
-#### C(05h) get_free_TCB_slot() +#### C(05h) get\_free\_TCB\_slot() Subfunction for OpenThread, returns the number of the first free TCB (usually in range 0..3) or FFFFFFFFh if there's no free TCB.
@@ -1558,33 +1558,33 @@ the two handlers).
So, although Vblank IRQs are most important for games, the PSX BIOS doesn't actually allow to use them for purposes other than joypad access. A possible workaround is to examine the status byte in one of the joypad buffers (ie. the -InitPad(buf1,22h,buf2,22h) buffers). Eg. a wait_for_vblank function could look +InitPad(buf1,22h,buf2,22h) buffers). Eg. a wait\_for\_vblank function could look like so: set buf1[0]=55h, then wait until buf1[0]=00h or buf1[0]=FFh.
-#### B(02h) init_timer(t,reload,flags) -When t=0..2, resets the old timer mode by setting [1F801104h+t*16]=0000h, -applies the reload value by [1F801108h+t*16]=reload, computes the new mode:
+#### B(02h) init\_timer(t,reload,flags) +When t=0..2, resets the old timer mode by setting [1F801104h+t\*16]=0000h, +applies the reload value by [1F801108h+t\*16]=reload, computes the new mode:
``` if flags.bit4=0 then mode=0048h else mode=0049h if flags.bit0=0 then mode=mode OR 100h if flags.bit12=1 then mode=mode OR 10h ``` -and applies it by setting [1F801104h+t*16]=mode, and returns 1. Does nothing +and applies it by setting [1F801104h+t\*16]=mode, and returns 1. Does nothing and returns zero for t\>2.
-#### B(03h) get_timer(t) -Reads the current timer value: Returns halfword[1F801100h+t*16] for t=0..2. +#### B(03h) get\_timer(t) +Reads the current timer value: Returns halfword[1F801100h+t\*16] for t=0..2. Does nothing and returns zero for t\>2.
-#### B(04h) enable_timer_irq(t) -#### B(05h) disable_timer_irq(t) +#### B(04h) enable\_timer\_irq(t) +#### B(05h) disable\_timer\_irq(t) Enables/disables timer or vblank interrupt enable bits in [1F801074h], bit4,5,6 for t=0,1,2, or bit0 for t=3, or random/garbage bits for t\>3. The enable function returns 1 for t=0..2, and 0 for t=3. The disable function returns always 1.
-#### B(06h) restart_timer(t) -Sets the current timer value to zero: Sets [1F801100h+t*16]=0000h and returns 1 +#### B(06h) restart\_timer(t) +Sets the current timer value to zero: Sets [1F801100h+t\*16]=0000h and returns 1 for t=0..2. Does nothing and returns zero for t\>2.
#### C(0Ah) - ChangeClearRCnt(t,flag) ;root counter (aka timer) @@ -1609,8 +1609,8 @@ pads (such like for controlling rumble motors).
Memorizes the desired buf1/buf2 addresses, zerofills the buffers by using the siz1/siz2 buffer size values (which should be 22h bytes each). And does some initialization on the PadCardIrq element (but doesn't enqueue it, that must be -done by a following call to StartPad), and does set the "pad_enable_flag", that -flag can be also set/cleared via InitCard(pad_enable), where it selects if the +done by a following call to StartPad), and does set the "pad\_enable\_flag", that +flag can be also set/cleared via InitCard(pad\_enable), where it selects if the Pads are kept handled together with Memory Cards. buf1/buf2 are having the following format:
``` @@ -1622,7 +1622,7 @@ Note: InitPad does initially zerofill the buffers, so, until the first IRQ is processed, the initial status is 00h=okay, with buttons=0000h (all buttons pressed), to fix that situation, change the two status bytes to FFh after calling InitPad (or alternately, reject ID1=00h).
-Once when the PadCardIrq is enqueued via StartPad, and while "pad_enable_flag" +Once when the PadCardIrq is enqueued via StartPad, and while "pad\_enable\_flag" is set, the data for (both) Pad1 and Pad2 is read on Vblank interrupts, and stored in the buffers, the IRQ handler stores up to 22h bytes in the buffer (regardless of the siz1/siz2 values) (eg. a Multitap adaptor uses all 22h @@ -1636,7 +1636,7 @@ additionally initialize some flags.
Dequeues the PadCardIrq handler. Note that this handler is also used for memory cards, so it'll "stop" cards, too.
-#### B(15h) - OutdatedPadInitAndStart(type, button_dest, unused, unused) +#### B(15h) - OutdatedPadInitAndStart(type, button\_dest, unused, unused) This is an extremely bizarre and restrictive function - don't use! The function fails unless type is 20000000h or 20000001h (the type value has no other function). The function uses "buf1/buf2" addresses that are located somewhere @@ -1645,7 +1645,7 @@ internal buffers is to use the ugly "OutdatedPadGetButtons()" function. For some strange reason it FFh-fills buf1/buf2, and does then call InitPad(buf1,22h,buf2,22) (which does immediately 00h-fill the previously FFh-filled buffers), and does then call StartPad().
-Finally, it does memorize the "button_dest" address (see +Finally, it does memorize the "button\_dest" address (see OutdatedPadGetButtons() for details on that value). The two unused parameters have no function, however, they are internally written back to the stack locations reserved for parameter 2 and 3, ie. at [SP+08h] and [SP+0Ch] on the @@ -1654,13 +1654,13 @@ allocated on stack. Return value is 2 (or 0 if type was disliked).
#### B(16h) - OutdatedPadGetButtons() This is a very ugly function, using the internal "buf1/buf2" values from -"OutdatedPadInitAndStart" and the "button_dest" value that was passed to that +"OutdatedPadInitAndStart" and the "button\_dest" value that was passed to that function.
-If "button_dest" is non-zero, then this function is automatically called by the -PadCardIrq handler, and stores it's return value at [button_dest] (where it may -be read by the main program). If "button_dest" is zero, then it isn't called +If "button\_dest" is non-zero, then this function is automatically called by the +PadCardIrq handler, and stores it's return value at [button\_dest] (where it may +be read by the main program). If "button\_dest" is zero, then it isn't called automatically, and it \ be called manually (with return value in R2), -however, it does additionally write the return value to [button_dest], ie. to +however, it does additionally write the return value to [button\_dest], ie. to [00000000h] in this case, destroying that memory location.
The return value itself is useless garbage: The lower 16bit contain the pad1 buttons, the upper 16bit the pad2 buttons, of which, both values have reversed @@ -1678,23 +1678,23 @@ other ID values, or disconnected joypads, cause the halfword to be set to FFFFh #### A(48h) - SendGP1Command(gp1cmd) Writes [1F801814h]=gp1cmd. There's no return value (r2 is left unchanged).
-#### A(49h) - GPU_cw(gp0cmd) ;send GP0 command word -Calls gpu_sync(), and does then write [1F801810h]=gp0cmd. Returns the return -value from the gpu_sync() call.
+#### A(49h) - GPU\_cw(gp0cmd) ;send GP0 command word +Calls gpu\_sync(), and does then write [1F801810h]=gp0cmd. Returns the return +value from the gpu\_sync() call.
-#### A(4Ah) - GPU_cwp(src,num) ;send GP0 command word and parameter words -Calls gpu_sync(), and does then copy "num" words from [src and up] to +#### A(4Ah) - GPU\_cwp(src,num) ;send GP0 command word and parameter words +Calls gpu\_sync(), and does then copy "num" words from [src and up] to [1F801810h], src should usually point to a command word, followed by num-1 parameter words. Transfer is done by software (without DMA). Always returns 0.
-#### A(4Bh) - send_gpu_linked_list(src) -Transfer an OT via DMA. Calls gpu_sync(), and does then write +#### A(4Bh) - send\_gpu\_linked\_list(src) +Transfer an OT via DMA. Calls gpu\_sync(), and does then write [1F801814h]=4000002h, [1F8010F4h]=0, [1F8010F0h]=[1F8010F0h] OR 800h, [1F8010A0h]=src, [1F8010A4h]=0, [1F8010A8h]=1000401h. The function does additionally output a bunch of TTY status messages via printf. The function doesn't wait until the DMA is completed. There's no return value.
-#### A(4Ch) - gpu_abort_dma() +#### A(4Ch) - gpu\_abort\_dma() Writes [1F8010A8h]=401h, [1F801814h]=4000000h, [1F801814h]=2000000h, [1F801814h]=1000000h. Ie. stops GPU DMA, and issues GP1(4), GP1(2), GP1(1). Returns 1F801814h, ie. the I/O address.
@@ -1702,30 +1702,30 @@ Returns 1F801814h, ie. the I/O address.
#### A(4Dh) - GetGPUStatus() Reads [1F801814h] and returns that value.
-#### A(46h) - GPU_dw(Xdst,Ydst,Xsiz,Ysiz,src) -Waits until GPUSTAT.Bit26 is set (unlike gpu_sync, which waits for Bit28), and +#### A(46h) - GPU\_dw(Xdst,Ydst,Xsiz,Ysiz,src) +Waits until GPUSTAT.Bit26 is set (unlike gpu\_sync, which waits for Bit28), and does then [1F801810h]=A0000000h, [1F801810h]=YdstXdst, [1F801810h]=YsizXsiz, and finally transfers "N" words from [src and up] to [1F801810h], where "N" is -"Xsiz*Ysiz/2". The data is transferred by software (without DMA) (by code +"Xsiz\*Ysiz/2". The data is transferred by software (without DMA) (by code executed in the uncached BIOS region with high waitstates, so the data transfer is very SLOW).
-Caution: If "Xsiz*Ysiz" is odd, then the last halfword is NOT transferred, so +Caution: If "Xsiz\*Ysiz" is odd, then the last halfword is NOT transferred, so the GPU stays waiting for the last data value.
-Returns [SP+04h]=Ydst, [SP+08h]=Xsiz, [SP+0Ch]=Ysiz, [SP+10h]=src+N*4, and -R2=src=N*4.
+Returns [SP+04h]=Ydst, [SP+08h]=Xsiz, [SP+0Ch]=Ysiz, [SP+10h]=src+N\*4, and +R2=src=N\*4.
-#### A(47h) - gpu_send_dma(Xdst,Ydst,Xsiz,Ysiz,src) -Calls gpu_sync(), writes [1F801810h]=A0000000h, [1F801814h]=4000002h, -[1F8010F0h]=[1F8010F0h] OR 800h, [1F8010A0h]=src, [1F8010A4h]=N*10000h+10h -(where N="Xsiz*Ysiz/32"), [1F8010A8h]=1000201h.
-Caution: If "Xsiz*Ysiz" is not a multiple of 32, then the last halfword(s) are +#### A(47h) - gpu\_send\_dma(Xdst,Ydst,Xsiz,Ysiz,src) +Calls gpu\_sync(), writes [1F801810h]=A0000000h, [1F801814h]=4000002h, +[1F8010F0h]=[1F8010F0h] OR 800h, [1F8010A0h]=src, [1F8010A4h]=N\*10000h+10h +(where N="Xsiz\*Ysiz/32"), [1F8010A8h]=1000201h.
+Caution: If "Xsiz\*Ysiz" is not a multiple of 32, then the last halfword(s) are NOT transferred, so the GPU stays waiting for that values.
Returns R2=1F801810h, and [SP+04h]=Ydst, [SP+08h]=Xsiz, [SP+0Ch]=Ysiz.
-#### A(4Eh) - gpu_sync() +#### A(4Eh) - gpu\_sync() If DMA is off (when GPUSTAT.Bit29-30 are zero): Waits until GPUSTAT.Bit28=1 (or until timeout).
-If DMA is on: Waits until D2_CHCR.Bit24=0 (or until timeout), and does then +If DMA is on: Waits until D2\_CHCR.Bit24=0 (or until timeout), and does then wait until GPUSTAT.Bit28=1 (without timeout, ie. may hang forever), and does then turn off DMA via GP1(04h).
Returns 0 (or -1 in case of timeout, however, the timeout values are very big, @@ -1752,17 +1752,17 @@ handle it may destroy memory at [buf-4], or trigger a memory exception (for example, when buf=0).
#### A(37h) - calloc(sizx, sizy) ;SLOW! -Allocates xsiz*ysiz bytes by calling malloc(xsiz*ysiz), and, unlike malloc, it +Allocates xsiz\*ysiz bytes by calling malloc(xsiz\*ysiz), and, unlike malloc, it does additionally zerofill the memory via SLOW "bzero" function. Returns the address of the memory block (or zero if failed).
-#### A(38h) - realloc(old_buf, new_size) ;SLOW! -If "old_buf" is zero, executes malloc(new_size), and returns r2=new_buf (or -0=failed). Else, if "new_size" is zero, executes free(old_buf), and returns -r2=garbage. Else, executes malloc(new_size), bcopy(old_buf,new_buf,new_size), -and free(old_buf), and returns r2=new_buf (or 0=failed).
+#### A(38h) - realloc(old\_buf, new\_size) ;SLOW! +If "old\_buf" is zero, executes malloc(new\_size), and returns r2=new\_buf (or +0=failed). Else, if "new\_size" is zero, executes free(old\_buf), and returns +r2=garbage. Else, executes malloc(new\_size), bcopy(old\_buf,new\_buf,new\_size), +and free(old\_buf), and returns r2=new\_buf (or 0=failed).
Caution: The bcopy function is SLOW, and realloc does accidently copy -"new_size" bytes from old_buf, so, if the old_size was smaller than new_size +"new\_size" bytes from old\_buf, so, if the old\_size was smaller than new\_size then it'll copy whatever garbage data - in worst case, if it exceeds the top of the 2MB RAM region, it may crash with a locked memory exception, although that'd happen only if SetMemSize(2) was used to restrict RAM to 2MBs.
@@ -1777,11 +1777,11 @@ may use it to deallocate all old memory).
The heap is used only by malloc/realloc/calloc/free, and by the "qsort" function.
-#### B(00h) alloc_kernel_memory(size) -#### B(01h) free_kernel_memory(buf) +#### B(00h) alloc\_kernel\_memory(size) +#### B(01h) free\_kernel\_memory(buf) Same as malloc/free, but, instead of the heap, manages the 8kbyte control block memory at A000E000h..A000FFFFh. This region is used by the kernel to allocate -ExCBs (4x08h bytes), EvCBs (N*1Ch bytes), TCBs (N*0C0h bytes), and the process +ExCBs (4x08h bytes), EvCBs (N\*1Ch bytes), TCBs (N\*0C0h bytes), and the process control block (1x04h bytes). Unlike the heap, the BIOS does automatically initialize this memory region via SysInitMemory(addr,size), and does autimatically allocate the above data (where the number of EvCBs and TCBs is as @@ -1931,14 +1931,14 @@ Returns the index (relative to src) of that occurence. If there was no occurence, then it returns the length of src. That silly return values do not actually indicate if an occurence has been found or not (unless one checks for [src+index]=00h or so).
-***
+\*\*\*
"The strcspn() function shall compute the length (in bytes) of the maximum initial segment of the string pointed to by s1 which consists entirely of bytes not from the string pointed to by s2."
"The strspn() function shall compute the length (in bytes) of the maximum initial segment of the string pointed to by s1 which consists entirely of bytes from the string pointed to by s2."
-***
+\*\*\*
Hmmmm, that'd be vice-versa?
#### A(23h) - strtok(src, list) ;first call @@ -1994,7 +1994,7 @@ to uppercase/lowercase format accordingly. Works only for char 00h..7Fh (some characters in range 80h..FFh are left unchanged, others are randomly "adjusted" by adding/subtracting 20h, and by sign-expanding the result to 32bits).
-#### A(0Dh) - strtol(src, src_end, base) +#### A(0Dh) - strtol(src, src\_end, base) Converts a string to a number. The function skips any leading "blank" characters (that are, 09h..0Dh, and 20h) (ie. TAB, CR, LF, SPC, and some others) (some characters in range 80h..FFh are accidently treated as "blank", @@ -2014,34 +2014,34 @@ string "o55" will be treated as 55 octal) (the only workaround would be to add/remove leading "0" characters, ie. "b11" or "00b11" or "0o55" would work okay).
Finally, the function initializes result=0, and does then process the digits as -"result=result*base+digit" (without any overflow checks) unless/until it +"result=result\*base+digit" (without any overflow checks) unless/until it reaches an unknown digit (or when digit\>=base) (ie. the string may end with 00h, or with any other unexpected characters).
The function accepts both uppercase and lowercase characters (both as prefixes, and as numeric digits). The function returns R2=result, and -[src_end]=end_address (ie. usually the address of the ending 00h byte; or of +[src\_end]=end\_address (ie. usually the address of the ending 00h byte; or of any other unexpected end-byte). If src points to 00000000h, then the function -returns r2=0, and leaves [src_end] unchanged.
+returns r2=0, and leaves [src\_end] unchanged.
-#### A(0Ch) - strtoul(src, src_end, base) +#### A(0Ch) - strtoul(src, src\_end, base) Same as "strtol" except that it doesn't recognize the "-" sign prefix (ie. works only for unsigned numbers).
#### A(10h) - atoi(src) #### A(11h) - atol(src) ;exactly same as "atoi" (but slightly slower) Same as "strtol", except that it doesn't return the string end address in -[src_end], and except that it defaults to base=10, but still supports prefixes, +[src\_end], and except that it defaults to base=10, but still supports prefixes, allowing to use base2,8,16. CAUTION: For some super bizarre reason, this function treats "0" (a leading ZERO digit) as OCTAL prefix (unlike strtol, which uses the "o" letter as octal prefix) (the "0x" and "0b" prefixes are working as usually).
-#### A(12h) - atob(src, num_dst) -Calls "strtol(str,src_end,10)", and does then exchange the two return values -(ie. sets R2=[src_end], and [num_dst]=value_32bit).
+#### A(12h) - atob(src, num\_dst) +Calls "strtol(str,src\_end,10)", and does then exchange the two return values +(ie. sets R2=[src\_end], and [num\_dst]=value\_32bit).
#### A(0Bh) - atof(src) ;USES (ABSENT) COP1 FPU !!! -#### A(32h) - strtod(src, src_end) ;USES (ABSENT) COP1 FPU !!! +#### A(32h) - strtod(src, src\_end) ;USES (ABSENT) COP1 FPU !!! These functions are intended to convert strings to floating point numbers, however, the functions are accidently compiled for MIPS processors with COP1 floating point unit (which is not installed in the PSX, nor does the BIOS @@ -2058,7 +2058,7 @@ values.
## BIOS Misc Functions #### A(2Fh) - rand() -Advances the random generator as "x=x*41C64E6Dh+3039h" (aka plus 12345 +Advances the random generator as "x=x\*41C64E6Dh+3039h" (aka plus 12345 decimal), and returns a 15bit random value "R2=(x/10000h) AND 7FFFh".
#### A(30h) - srand(seed) @@ -2122,9 +2122,9 @@ be, if it'd be in the array). Both functions return the address of the element #### C(19h) - ioabort(txt1,txt2) Displays the two strings on the TTY (in some cases the BIOS does accidently pass garbage instead of the 2nd string though). And does then execute -ioabort_raw(1), see there for more details.
+ioabort\_raw(1), see there for more details.
-#### A(B2h) - ioabort_raw(param) ;not supported by old CEX-1000 version +#### A(B2h) - ioabort\_raw(param) ;not supported by old CEX-1000 version Executes "RestoreState(ioabortbuffer,param)". Internally used to recover from failed I/O operations, param should be nonzero to notify the SaveState caller that the abort has occurred.
@@ -2153,7 +2153,7 @@ code at RA, ie. usually to the caller of the original SaveState call) (since SaveState returns 0, "param" should be usually 1, or another non-zero value to inidicate that RestoreState has occurred). See SaveState for further details.
-#### A(53h) - set_ioabort_handler(src) ;PS2 only ;PSX: SystemError +#### A(53h) - set\_ioabort\_handler(src) ;PS2 only ;PSX: SystemError Normally the ioabort handler is changed only internally during booting, with this new function, games can install their own ioabort handler. src is pointer to a 30h-byte "savestate" structure, which will be copied to the actual ioabort @@ -2215,7 +2215,7 @@ to SystemErrorUnresolvedException().
## BIOS Internal Boot Functions -#### A(45h) - init_a0_b0_c0_vectors +#### A(45h) - init\_a0\_b0\_c0\_vectors Copies the three default four-opcode handlers for the A(NNh),B(NNh),C(NNh) functions to A00000A0h..A00000CFh.
@@ -2349,7 +2349,7 @@ Attributes Bits (standard MSDOS-style):
V1 0 = success, error code if V0 is negative ``` -#### BRK(105h) - PCRead(filehandle, length, memory_destination_address) +#### BRK(105h) - PCRead(filehandle, length, memory\_destination\_address) ``` out: V0 0 = success, -1 = failure V1 number of read bytes or error code if V0 is negative. @@ -2360,13 +2360,13 @@ filelength obtain the filelength by PClSeek (A2=0, A3=2, V1 will return the length of the file, don't forget to reset the file pointer to the start before calling PCread!)
-#### BRK(106h) - PCWrite(filehandle, length, memory_source_address) +#### BRK(106h) - PCWrite(filehandle, length, memory\_source\_address) ``` out: V0 0 = success, -1 = failure V1 number of written bytes or error code if V0 is negative. ``` -#### BRK(107h) - PClSeek(filehandle, file_offset, seekmode) - Change Filepos +#### BRK(107h) - PClSeek(filehandle, file\_offset, seekmode) - Change Filepos seekmode may be from 0=Begin of file, 1=Current fpos, or 2=End of file.
``` out: V0 0 = success, -1 = failure @@ -2375,14 +2375,14 @@ seekmode may be from 0=Begin of file, 1=Current fpos, or 2=End of file.
-## BIOS TTY Console (std_io) +## BIOS TTY Console (std\_io) #### A(3Fh) - Printf(txt,param1,param2,etc.) - Print string to console ``` in: A0 Pointer to 0 terminated string A1,A2,A3,[SP+10h..] Argument(s) ``` Prints the specified string to the TTY console. Printf does internally use -"std_out_putchar" to output the separate characters (and expands char 09h and +"std\_out\_putchar" to output the separate characters (and expands char 09h and 0Ah accordingly).
The string can contain C-style escape codes (prefixed by "%" each):
``` @@ -2415,7 +2415,7 @@ doesn't work at all (accidently sign-expands 16bit to 32bit, and then displays that signed 32bit value as giant unsigned value). Printf supports only octal, decimal, and hex (but not binary).
-#### A(3Eh) or B(3Fh) std_out_puts(src) - Write string to TTY +#### A(3Eh) or B(3Fh) std\_out\_puts(src) - Write string to TTY ``` in: R4=address of string (terminated by 00h) ``` @@ -2424,32 +2424,32 @@ in a special way: If R4 points to a 00h character then nothing is output (as one would expect it), but, if R4 is 00000000h then "\" is output (only that six letters; without appending any CR or LF).
-#### A(3Dh) or B(3Eh) std_in_gets(dst) - Read string from TTY (keyboard input) +#### A(3Dh) or B(3Eh) std\_in\_gets(dst) - Read string from TTY (keyboard input) ``` in: r4=dst (pointer to a 128-byte buffer) - out: r2=dst (same is incoming r4) ``` -Internally uses "std_in_getchar" to receive the separate characters (which are +Internally uses "std\_in\_getchar" to receive the separate characters (which are thus masked by 7Fh). The received characters are stored in the buffer, and are -additionally sent back as echo to the TTY via std_out_putc.
+additionally sent back as echo to the TTY via std\_out\_putc.
The following characters are handled in a special way: 09h (TAB) is replaced by a single SPC. 08h or 7FH (BS or DEL) are removing the last character from the buffer (unless it is empty) and send 08h,20h,08h (BS,SPC,BS) to the TTY. 0Dh or 0Ah (CR or LF) do terminate the input (append 00h to the buffer, send 0Ah to -the TTY, which is expanded to 0Dh,0Ah by the std_out_putc function, and do then -return from the std_in_gets function).
+the TTY, which is expanded to 0Dh,0Ah by the std\_out\_putc function, and do then +return from the std\_in\_gets function).
The sequence 16h,NNh forces NNh to be stored in the buffer (even if NNh is a special character like 00h..1Fh or 7Fh). If the buffer is full (circa max 125 chars, plus one extra byte for the ending 00h), or if an unknown control code in range of 00h..1Fh is received without the 16h prefix, then 07h (BELL) is sent to the TTY.
-#### A(3Bh) or B(3Ch) std_in_getchar() - Read character from TTY +#### A(3Bh) or B(3Ch) std\_in\_getchar() - Read character from TTY Reads one character from the TTY console, by internally redirecting to "FileRead(0,tempbuf,1)". The returned character is ANDed by 7Fh (so, to read a fully intact 8bit character, "FileRead(0,tempbuf,1)" must be used instead of this function).
-#### A(3Ch) or B(3Dh) std_out_putchar(char) - Write character to TTY +#### A(3Ch) or B(3Dh) std\_out\_putchar(char) - Write character to TTY Writes the character to the TTY console, by internally redirecting to "FileWrite(1,tempbuf,1)". Char 09h (TAB) is expanded to one or more SPC characters, until reaching the next tabulation boundary (every 8 characters). @@ -2458,22 +2458,22 @@ should be handled at the remote terminal side) are 08h (BS, backspace, move cursor one position to the left), and 07h (BELL, produce a short beep sound).
#### C(13h) FlushStdInOutPut() -Closes and re-opens the std_in (fd=0) and std_out (fd=1) file handles.
+Closes and re-opens the std\_in (fd=0) and std\_out (fd=1) file handles.
#### C(1Bh) KernelRedirect(ttyflag) ;PS2: ttyflag=1 causes SystemError Removes, re-mounts, and flushes the TTY device, the parameter selects whether to mount the real DUART-TTY device (r4=1), or a Dummy-TTY device (r4=0), the -latter one sends any std_out to nowhere. Values other than r4=0 or r4=1 do +latter one sends any std\_out to nowhere. Values other than r4=0 or r4=1 do remove the device, but do not re-mount it (which might result in problems).
Caution: Trying to use r4=1 on a PSX that does not has the DUART hardware installed causes the BIOS to hang (so one should first detect the DUART hardware, eg. by writing two different bytes to Port 1F802020h.1st/2nd access, and the read and verify that two bytes).
-#### Activating std_io -The std_io functions can be enabled via C(1Bh) KernelRedirect(ttyflag), the +#### Activating std\_io +The std\_io functions can be enabled via C(1Bh) KernelRedirect(ttyflag), the BIOS is unable to detect the presence of the TTY hardware, by default the BIOS -bootcode disables std_io by setting the initial KernelRedirect value at +bootcode disables std\_io by setting the initial KernelRedirect value at [A000B9B0h] to zero, this is hardcoded shortly after the POST(E) output:
``` call output_post_r4 ;\output POST(E) @@ -2507,19 +2507,19 @@ handles (fd=0 and fd=1) would cause such functions to work unstable.
## BIOS Character Sets -#### B(51h) Krom2RawAdd(shiftjis_code) +#### B(51h) Krom2RawAdd(shiftjis\_code) ``` In: r4 = 16bit Shift-JIS character code Out: r2 = address in BIOS ROM of the desired character (or -1 = error) ``` r4 should be 8140h..84BEh (charset 2), or 889Fh..9872h (charset 3).
-#### B(53h) Krom2Offset(shiftjis_code) +#### B(53h) Krom2Offset(shiftjis\_code) ``` In: r4 = 16bit Shift-JIS character code Out: r2 = offset within charset (without charset base address) ``` -This is a subfunction for B(51h) Krom2RawAdd(shiftjis_code).
+This is a subfunction for B(51h) Krom2RawAdd(shiftjis\_code).
#### Character Sets in ROM (112Kbytes) The character sets are located at BFC64000h and up, intermixed with some other @@ -2543,7 +2543,7 @@ char(8FA6E0h..8FABF7h).
Version (and Copyright) string is NOT included in SCPH1000 version (that BIOS includes further japanese 8x15 pix chars in that region).
For charset 2 and 3 it may be recommended to use the B(51h) -Krom2RawAdd(shiftjis_code) to obtain the character addresses. Not sure if that +Krom2RawAdd(shiftjis\_code) to obtain the character addresses. Not sure if that BIOS function (or another BIOS function) allows to retrieve charset 1, 4, 5, and 6 addresses?
@@ -2745,7 +2745,7 @@ care), so the nocash PSX bios (or other homebrewn BIOSes) can detect and reproduce them. Or alternately, don't use the BIOS, and access I/O ports directly, which is much better and faster anyways.
-#### patch_missing_cop0r13_in_exception_handler: +#### patch\_missing\_cop0r13\_in\_exception\_handler: In newer Kernel version, the exception handler reads cop0r13/cause to r2, examines the Excode value in r2, and if the exception was caused by an interrupt, and if the next opcode (at EPC) is a GTE/COP2 command, then it does @@ -2792,7 +2792,7 @@ Racer at 80047B14h:
175BFFFC jne k0,k1,@@copy_lop ; 40026800 mov r2,cop0r13 AC43FFFC +mov [r2-4h],r3 ;/ 00000000 nop ``` -Alternately, slightly different code used in metal_gear_solid at 80095CC0h, and +Alternately, slightly different code used in metal\_gear\_solid at 80095CC0h, and in alone1 at 800A3ECCh:
``` 24090056 mov r9,56h ;\ @@ -2864,7 +2864,7 @@ Alternately, a bugged/nonfunctional homebrew variant (used by Hitmen's @@verify_mismatch: ``` -#### early_card_irq_patch: +#### early\_card\_irq\_patch: Because of a hardware glitch the card IRQ cannot be acknowledged while the external IRQ signal is still LOW, making it neccessary to insert a delay that waits until the signal gets HIGH before acknowledging the IRQ.
@@ -2938,13 +2938,13 @@ Alternately, elo2 uses slightly different code at 8003961Ch:
AC22xxxx +mov [r1+xxxxh],r2 ;/ ;03E00008 ret ... ;00000000 +nop ``` -Note: The above @@wait_lop's should be more preferably done with timeouts (else +Note: The above @@wait\_lop's should be more preferably done with timeouts (else they may hang endless if a Sony Mouse is newly connected; the mouse does have /ACK stuck LOW on power-up).
-#### patch_uninstall_early_card_irq_handler: -Used to uninstall the "early_card_irq_vector" (the BIOS installs that vector -from inside of B(4Ah) InitCard(pad_enable), and, without patches, the BIOS +#### patch\_uninstall\_early\_card\_irq\_handler: +Used to uninstall the "early\_card\_irq\_vector" (the BIOS installs that vector +from inside of B(4Ah) InitCard(pad\_enable), and, without patches, the BIOS doesn't allow to uninstall it thereafter).
Used in Breath of Fire III (SLES-01304) at 8017E790, and also in Ace Combat 2 (SLUS-00404) at 801D23F4:
@@ -2984,11 +2984,11 @@ Alternately, more inefficient, used in Blaster Master-Blasting Again 1549FFFB jne r10,r9,@@copy_lop ; @@new_data_end: 24420004 +add r2,4h ;dst ;/ ``` -Note: the above code is same as "patch_install_lightgun_irq_handler", except +Note: the above code is same as "patch\_install\_lightgun\_irq\_handler", except that it writes to r2+70h, instead of r2+80h.
-#### patch_card_specific_delay: -Same purpose as the "early_card_irq_patch" (but for the command/status bytes +#### patch\_card\_specific\_delay: +Same purpose as the "early\_card\_irq\_patch" (but for the command/status bytes rather than for the data bytes). The patch looks buggy since it inserts the delay AFTER the acknowledge, but it DOES work (the BIOS accidently acknowledges the IRQ twice; and the delay occurs PRIOR to 2nd acknowledge).
@@ -3037,8 +3037,8 @@ Evil 2 at 800910E4h:
AC4809C4 +mov [r2+9C4h],r8 ; ``` -#### patch_card_info_step4: -The "card_info" function sends an incomplete read command to the card; in order +#### patch\_card\_info\_step4: +The "card\_info" function sends an incomplete read command to the card; in order to receive status information. After receiving the last byte, the function does accidently send a further byte to the card, so the card responds by another byte (and another IRQ7), which is not processed nor acknowledged by the BIOS. @@ -3057,10 +3057,10 @@ Used in alone1 at 800AE214h:
AC600000 +mov [r3],0 ;=nop ;/ ``` -#### patch_pad_error_handling_and_get_pad_enable_functions: +#### patch\_pad\_error\_handling\_and\_get\_pad\_enable\_functions: If a transmission error occurs (or if there's no controller connected), then the Pad handler handler does usually issue a strange chip select signal to the -OTHER controller slot, and does then execute the bizarre_pad_delay function. +OTHER controller slot, and does then execute the bizarre\_pad\_delay function. The patch below overwrites that behaviour by NOPs. Purpose of the original (and patched) behaviour is unknown.
Used by Perfect Assassin at 800519D4h:
@@ -3119,7 +3119,7 @@ Pandemonium II (at 80083C94h and at 8010B77Ch):
24420004 +add r2,4h ;/ ``` -#### patch_optional_pad_output: +#### patch\_optional\_pad\_output: The normal BIOS functions are only allowing to READ from the controllers, but not to SEND data to them (which would be required to control Rumble motors, and to auto-activate Analog mode without needing the user to press the Analog @@ -3177,7 +3177,7 @@ Alternately, more inefficient (with NOPs), used in Lemmings at 80036618h:
00000000 +nop ;/ ``` -#### patch_no_pad_card_auto_ack: +#### patch\_no\_pad\_card\_auto\_ack: This patch suppresses automatic IRQ0 (vblank) acknowleding in the Pad/Card IRQ handler, that, even if auto-ack is enabled. Obviously, one could as well disable auto-ack via B(5Bh) ChangeClearPad(int), so this patch is total @@ -3220,7 +3220,7 @@ actually support the same IRQ to be processed by two different IRQ handlers, eg. the custom handler may acknowledge the IRQ even when the Pad/Card handler didn't process it, so pad input may become bumpy.
-#### patch_install_lightgun_irq_handler: +#### patch\_install\_lightgun\_irq\_handler: Used in Sporting Clays at 80027D68h (when Konami Lightgun connected):
``` 240A00B0 mov r10,0B0h ;\ @@ -3265,11 +3265,11 @@ coordinate (timer0) to a variable in RAM, thus getting the timer0 value unpredictable timing offsets that could be caused by cache hits/misses during later IRQ handling (and may also eliminate a rather irrelevant 1-cycle inaccuracy depending on whether EPC was pointing to a GTE opcode, and also -eliminates constant cycle offsets depending on whether early_card_irq_handler +eliminates constant cycle offsets depending on whether early\_card\_irq\_handler was installed and enabled, and might eliminate timing differences for different BIOS versions).
-#### set_conf_without_realloc: +#### set\_conf\_without\_realloc: Used in Spec Ops Airborne Commando at 80070AE8h, and also in the homebrew game Roll Boss Rush at 80010B68h and 8001B85Ch. Purpose is unknown (maybe to override improperly defined .EXE headers).
diff --git a/macroblockdecodermdec.md b/macroblockdecodermdec.md index 8810547..11fd4ac 100644 --- a/macroblockdecodermdec.md +++ b/macroblockdecodermdec.md @@ -120,7 +120,7 @@ These commands act identical as MDEC(0).
## MDEC Decompression -#### decode_colored_macroblock ;MDEC(1) command (at 15bpp or 24bpp depth) +#### decode\_colored\_macroblock ;MDEC(1) command (at 15bpp or 24bpp depth) ``` rl_decode_block(Crblk,src,iq_uv) ;Cr (low resolution) rl_decode_block(Cbblk,src,iq_uv) ;Cb (low resolution) @@ -130,12 +130,12 @@ These commands act identical as MDEC(0).
rl_decode_block(Yblk,src,iq_y), yuv_to_rgb(8,8) ;Y4 (and lower-right Cr,Cb) ``` -#### decode_monochrome_macroblock ;MDEC(1) command (at 4bpp or 8bpp depth) +#### decode\_monochrome\_macroblock ;MDEC(1) command (at 4bpp or 8bpp depth) ``` rl_decode_block(Yblk,src,iq_y), y_to_mono ;Y ``` -#### rl_decode_block(blk,src,qt) +#### rl\_decode\_block(blk,src,qt) ``` for i=0 to 63, blk[i]=0, next i ;initially zerofill all entries (for skip) @@skip: @@ -157,7 +157,7 @@ These commands act identical as MDEC(0).
return (with "src" address advanced) ``` -#### fast_idct_core(blk) ;fast "idct_core" version +#### fast\_idct\_core(blk) ;fast "idct\_core" version Fast code with only 80 multiplications, works only if the scaletable from MDEC(3) command contains standard values (which is the case for all known PSX games).
@@ -189,9 +189,9 @@ games).
next pass ``` -#### real_idct_core(blk) ;low level "idct_core" version +#### real\_idct\_core(blk) ;low level "idct\_core" version Low level code with 1024 multiplications, using the scaletable from the MDEC(3) -command. Computes dst=src*scaletable (using normal matrix maths, but with "src" +command. Computes dst=src\*scaletable (using normal matrix maths, but with "src" being diagonally mirrored, ie. the matrices are processed column by column, instead of row by column), repeated with src/dst exchanged.
``` @@ -215,9 +215,9 @@ working roughly like that, still the results aren't perfect.
Maybe the real hardware is doing further roundings in other places, possibly stripping some fractional bits before summing up "sum", possibly stripping different amounts of bits in the two "pass" cycles, and possibly keeping a -final fraction passed on to the y_to_mono stage.
+final fraction passed on to the y\_to\_mono stage.
-#### yuv_to_rgb(xx,yy) +#### yuv\_to\_rgb(xx,yy) ``` for y=0 to 7 for x=0 to 7 @@ -232,10 +232,10 @@ final fraction passed on to the y_to_mono stage.
next x next y ``` -Note: The exact fixed point resolution for "yuv_to_rgb" is unknown. And, -there's probably also some 9bit limit (similar as in "y_to_mono").
+Note: The exact fixed point resolution for "yuv\_to\_rgb" is unknown. And, +there's probably also some 9bit limit (similar as in "y\_to\_mono").
-#### y_to_mono +#### y\_to\_mono ``` for i=0 to 63 Y=[Yblk+i] @@ -246,7 +246,7 @@ there's probably also some 9bit limit (similar as in "y_to_mono").
next i ``` -#### set_iqtab ;MDEC(2) command +#### set\_iqtab ;MDEC(2) command ``` iqtab_core(iq_y,src), src=src+64 ;luminance quant table if command_word.bit0=1 @@ -254,15 +254,15 @@ there's probably also some 9bit limit (similar as in "y_to_mono").
endif ``` -#### iqtab_core(iq,src) ;src = 64 unsigned paramter bytes +#### iqtab\_core(iq,src) ;src = 64 unsigned paramter bytes ``` for i=0 to 63, iq[i]=src[i], next i ``` -Note: For "fast_idct_core" one could precalc "iq[i]=src[i]*scalezag[i]", but +Note: For "fast\_idct\_core" one could precalc "iq[i]=src[i]\*scalezag[i]", but that would conflict with the RLE saturation/rounding steps (though those steps aren't actually required, so a very-fast decoder could omit them).
-#### scalefactor[0..7] = cos((0..7)*90'/8) ;for [1..7]: multiplied by sqrt(2) +#### scalefactor[0..7] = cos((0..7)\*90'/8) ;for [1..7]: multiplied by sqrt(2) ``` 1.000000000, 1.387039845, 1.306562965, 1.175875602, 1.000000000, 0.785694958, 0.541196100, 0.275899379 @@ -280,7 +280,7 @@ aren't actually required, so a very-fast decoder could omit them).
35,36,48,49,57,58,62,63 ``` -#### scalezag[0..63] (precalulated factors, for "fast_idct_core") +#### scalezag[0..63] (precalulated factors, for "fast\_idct\_core") ``` for y=0 to 7 for x=0 to 7 @@ -294,7 +294,7 @@ aren't actually required, so a very-fast decoder could omit them).
for i=0 to 63, zagzig[zigzag[i]]=i, next i ``` -#### set_scale_table: ;MDEC(3) command +#### set\_scale\_table: ;MDEC(3) command This command defines the IDCT scale matrix, which should be usually/always:
``` 5A82 5A82 5A82 5A82 5A82 5A82 5A82 5A82 diff --git a/memorycontrol.md b/memorycontrol.md index dde3003..7b1ee96 100644 --- a/memorycontrol.md +++ b/memorycontrol.md @@ -47,7 +47,7 @@ the internal I/O ports, and crash the PSX. The Size bits seem to be ignored for SPU/CDROM. The SPU timings seem to be applied for both the 200h-byte SPU region at 1F801C00h and for the 200h-byte unknown region at 1F801E00h.
-#### 1F801020h - COM_DELAY / COMMON_DELAY (00031125h or 0000132Ch or 00001325h) +#### 1F801020h - COM\_DELAY / COMMON\_DELAY (00031125h or 0000132Ch or 00001325h) ``` 0-3 COM0 - Offset A ;used for SPU/EXP2 (and for adjusted CDROM timings) 4-7 COM1 - No effect? ;used for EXP2 @@ -76,7 +76,7 @@ values or so).
And the purpose... probably allows to define the length of the chipselect signals, and of gaps between that signals...?
-#### 1F801060h - RAM_SIZE (R/W) (usually 00000B88h) (or 00000888h) +#### 1F801060h - RAM\_SIZE (R/W) (usually 00000B88h) (or 00000888h) ``` 0-2 Unknown (no effect) 3 Crashes when zero (except PU-7 and EARLY-PU-8, which set bit3=0) @@ -105,7 +105,7 @@ seems to be always Locked.
The HighZ regions are FFh-filled, that even when grounding data lines on the system bus (ie. it is NOT a mirror of the PIO expansion region).
Locked means that the CPU generates an exception when accessing that area.
-Note: Wipeout uses a BIOS function that changes RAM_SIZE to 00000888h (ie. with +Note: Wipeout uses a BIOS function that changes RAM\_SIZE to 00000888h (ie. with corrected size of 2MB, and with the unknown Bit8 cleared). Gundam Battle Assault 2 does actually use the "8MB" space (with stacktop in mirrored RAM at 807FFFxxh).
diff --git a/pinouts.md b/pinouts.md index e1103e5..930f94c 100644 --- a/pinouts.md +++ b/pinouts.md @@ -733,7 +733,7 @@ while power is on, better measure them at the CPU side.
Pin 1..36 = MIPS-CPU bus. Pin 45..87 = SPU-RAM bus (A0,A10-A15,/WE1,OE1=NC). Pin 91..99 = Digital serial audio in/out (A=CDROM, B=EXP, O=OUT).
-#### IC732 - SONY CXD2941R (SPU+CDROM+SPU_RAM) (on PM-41(2) boards) +#### IC732 - SONY CXD2941R (SPU+CDROM+SPU\_RAM) (on PM-41(2) boards) ``` 1-DA16 23-FILO 45-LOCK 67-FSTO 89-SCSY 111-XCS 133-HD9 155-VSS5 2-DA15 24-FILI 46-SSTP 68-COUT 90-SCLK 112-XRD 134-HD8 156-HA1 @@ -824,7 +824,7 @@ SPU.Pin42 via capacitor to SPU.Pin41, and via resistor?/diode? to IC723.10
SPU206 (*) circa 2.27MHz SPU70 (*) whatever clock (with SHORT low pulses) ``` -(*) these frequencies are twice as fast in double speed mode.
+(\*) these frequencies are twice as fast in double speed mode.
#### CXD2938Q CDROM signals ``` @@ -970,7 +970,7 @@ and even later boards have it integrated in the SPU.
``` Datasheet exists. The CXD2545Q combines the functionality of CXA1782BR+CXD2510Q from older boards (later boards have it integrated in the SPU). XTAI/XTAO input -is 16.9344MHz (44.1kHz*180h), with XTSL=GND. Clock outputs are +is 16.9344MHz (44.1kHz\*180h), with XTSL=GND. Clock outputs are FSTO=16.9344MHz/3, FSOF=16.9344MHz/4, C16M=16.9344MHz/1.
#### IC101 - SONY CXD2515Q - Signal Processor + Servo Amp (used on DTL-H2010) diff --git a/pocketstation.md b/pocketstation.md index 993e15d..a4ef455 100644 --- a/pocketstation.md +++ b/pocketstation.md @@ -153,7 +153,7 @@ BIOS and FLASH can be read only in 16bit and 32bit units (not 8bit).
Upon reset, BIOS ROM is mirrored to address 00000000h (instead of RAM).
For most I/O ports, it is unknown if they are (R), (W), or (R/W)...?
I/O ports are usually accessed at 32bit width, occassionally some ports are -(alternately) accessed at 16bit width. A special case are the F_SN registers +(alternately) accessed at 16bit width. A special case are the F\_SN registers which seem to be required to be accessed at 16bit (not 32bit).
#### Memory Access Time @@ -171,7 +171,7 @@ Memory Access Time for Data Read/Write:
For data access, it doesn't matter if the access is 8bit/16bit/32bit (unlike as for opcode fetch, where 16bit/thumb can be faster than 32bit/arm). There seems to be no timing differences for sequential/non-sequential access.
-Additional memory waitstates can be added via F_WAIT2 (and F_WAIT1 maybe).
+Additional memory waitstates can be added via F\_WAIT2 (and F\_WAIT1 maybe).
#### Invalid/Unused Memory Locations ``` @@ -221,8 +221,8 @@ Additional memory waitstates can be added via F_WAIT2 (and F_WAIT1 maybe).
0B800002h-0BFFFFFEh RTC area, odd addresses (with A1=1) mirror to 0B80000Ah ``` -#### garbage_byte (for unsupported 8bit reads) -The "garbage_byte" depends on the LSBs of the read address, prefetched opcodes, +#### garbage\_byte (for unsupported 8bit reads) +The "garbage\_byte" depends on the LSBs of the read address, prefetched opcodes, and recent data fetches:
``` garbage_word = (prefetch OR (ramdata AND FFFFFFD0h)) @@ -250,7 +250,7 @@ There might be some more/unknown things that affect the garbage (eg. opcode fetches from RAM instead of FLASH, partial 8bit/16bit data reads from RAM, or reads from I/O areas, current CPU clock speed, or unpredictable things like temperature).
-Note: The garbage_byte is "used" by the pocketstation "Rockman" series games.
+Note: The garbage\_byte is "used" by the pocketstation "Rockman" series games.
@@ -333,7 +333,7 @@ can be freely read/written in 8bit, 16bit, and 32bit units.
#### Waitstates Unknown if and how many waitstates are applied to the different memory regions. -The F_WAIT1 and F_WAIT2 registers seem to be somehow waitstate related. FLASH +The F\_WAIT1 and F\_WAIT2 registers seem to be somehow waitstate related. FLASH memory does probably have a 16bit bus, so 32bit data/opcode fetches might be slower then 16bit reads...? Similar delays might happen for other memory and I/O regions...?
@@ -341,7 +341,7 @@ I/O regions...?
## Pocketstation IO Video and Audio -#### 0D000000h - LCD_MODE - LCD control word (R/W) +#### 0D000000h - LCD\_MODE - LCD control word (R/W) ``` 0-2 Draw mode; seems to turn off bits of the screen; 0: All 32 rows on ;\ @@ -363,17 +363,17 @@ I/O regions...?
7 Rotate display by 180 degrees (0=For Handheld Mode, 1=For Docked Mode) 8-31 Unknown (should be zero) ``` -Software should usually set LCD_MODE.7 equal to INT_INPUT.Bit11 (docking flag). +Software should usually set LCD\_MODE.7 equal to INT\_INPUT.Bit11 (docking flag). In handheld mode, the button-side is facing towards the player, whilst in Docked mode (when the Pocketstation is inserted into the PSX controller port), the button-side is facing towards the PSX, so the screen coordinates become vice-versa, which can be "undone" by the Rotation flag.
-#### 0D000004h - LCD_CAL - LCD Calibration (maybe contrast or so?) -Upon the reset, the kernel sets LCD_CAL = F_CAL AND 0000003Fh. Aside from that, -it doesn't use LCD_CAL.
+#### 0D000004h - LCD\_CAL - LCD Calibration (maybe contrast or so?) +Upon the reset, the kernel sets LCD\_CAL = F\_CAL AND 0000003Fh. Aside from that, +it doesn't use LCD\_CAL.
-#### 0D000100h..D00017Fh - LCD_VRAM - 32x32 pixels, 1bit color depth (R/W) +#### 0D000100h..D00017Fh - LCD\_VRAM - 32x32 pixels, 1bit color depth (R/W) This region consists of 32 words (32bit values),
``` [D000100h]=Top, through [D00017Ch]=Bottom-most scanline @@ -383,19 +383,19 @@ The separate scanlines consist of 32bit each,
Bit0=Left, through Bit31=Right-most Pixel (0=White, 1=Black) ``` That [D000100h].Bit0=Upper-left arrangement applies if the Rotate bit in -LCD_MODE.7 is set up in the conventional way, if it is set the opposite way, +LCD\_MODE.7 is set up in the conventional way, if it is set the opposite way, then it becomes [D00017Ch].Bit31=Upper-left.
-The LCD_VRAM area is reportedly mirrored to whatever locations?
+The LCD\_VRAM area is reportedly mirrored to whatever locations?
-#### 0D800010h - DAC_CTRL - Audio Control (R/W) +#### 0D800010h - DAC\_CTRL - Audio Control (R/W) ``` 0 Audio Enable enable (0=Off, 1=On) 1-31 Unknown, usually zero ``` -Note: Aside from the bit in DAC_CTRL, audio must be also enabled/disabled via -IOP_STOP/IOP_START bit5. Unknown if/which different purposes that bits have.
+Note: Aside from the bit in DAC\_CTRL, audio must be also enabled/disabled via +IOP\_STOP/IOP\_START bit5. Unknown if/which different purposes that bits have.
-#### 0D800014h - DAC_DATA - Audio D/A Converter +#### 0D800014h - DAC\_DATA - Audio D/A Converter Unknown how many bits are passed to the D/A converter, probably bit8-15, ie. 8 bits...?
``` @@ -404,7 +404,7 @@ bits...?
16-31 Probably unused, usually sign-expanded from bit15 ``` The Pocketstation doesn't have any square wave or noise generator (nor a sound -DMA channel). So the output levels must be written to DAC_DATA by software, +DMA channel). So the output levels must be written to DAC\_DATA by software, this is usually done via Timer1/IRQ-8 (to reduce CPU load caused by high audio frequencies, it may be much more recommended to use Timer2/FIQ-13, because the FIQ handler doesn't need to push r8-r12).
@@ -417,7 +417,7 @@ probably increased anyways when the speaker is enabled).
## Pocketstation IO Interrupts and Buttons -#### 0A000004h - INT_INPUT - Raw Interrupt Signal Levels (R) +#### 0A000004h - INT\_INPUT - Raw Interrupt Signal Levels (R) ``` Bit Type Meaning 0 IRQ Button Fire (0=Released, 1=Pressed) @@ -442,30 +442,30 @@ usually used to wakeup). Also, bit9-11 are often read from this register.
The direction keys seem to be separate buttons, ie. unlike as on a joystick or DPAD, Left/Right (and Up/Down) can be simultaneously pressed...?
-#### 0A000008h - INT_MASK_SET - Set Interrupt Mask (W) -#### 0A00000Ch - INT_MASK_CLR - Clear Interrupt Mask (W) -#### 0A000008h - INT_MASK_READ - Read Interrupt Mask (R) +#### 0A000008h - INT\_MASK\_SET - Set Interrupt Mask (W) +#### 0A00000Ch - INT\_MASK\_CLR - Clear Interrupt Mask (W) +#### 0A000008h - INT\_MASK\_READ - Read Interrupt Mask (R) ``` INT_MASK_SET Enable Interrupt Flags (0=No change, 1=Enable) (W) INT_MASK_CLR Disable Interrupt Flags (0=No change, 1=Disable) (W) INT_MASK_READ Current Interrupt Enable Flags (0=Disabled, 1=Enabled) (R) ``` -The locations of the separate bits are same as in INT_INPUT (see there).
+The locations of the separate bits are same as in INT\_INPUT (see there).
-#### 0A000000h - INT_LATCH - Interrupt Request Flags (R) -#### 0A000010h - INT_ACK - Acknowledge Interrupts (W) +#### 0A000000h - INT\_LATCH - Interrupt Request Flags (R) +#### 0A000010h - INT\_ACK - Acknowledge Interrupts (W) ``` INT_LATCH Latched Interrupt Requests (0=None, 1=Interrupt Request) (R) INT_ACK Clear Interrupt Requests (0=No change, 1=Acknowledge) (W) ``` -The locations of the separate bits are same as in INT_INPUT (see there).
+The locations of the separate bits are same as in INT\_INPUT (see there).
The interrupts seem to be edge-triggered (?), ie. when the corresponding bits -in INT_INPUT change from 0-to-1. Unknown if the request bits get set when the -corresponding interrupt is disabled in INT_MASK...?
+in INT\_INPUT change from 0-to-1. Unknown if the request bits get set when the +corresponding interrupt is disabled in INT\_MASK...?
ATTENTION: The GUI doesn't acknowledge Fire Button interrupts on wakeup... so, -it seems as if button interrupts are NOT latched... ie. the button "INT_LATCH" -bits seem to be just an unlatched mirror of the "INT_INPUT" bits... that might +it seems as if button interrupts are NOT latched... ie. the button "INT\_LATCH" +bits seem to be just an unlatched mirror of the "INT\_INPUT" bits... that might also apply for some other interrupt...?
However, after wakeup, the gui does DISABLE the Fire Button interrupt, MAYBE that does automatically acknowledge it... in that case it might be latched...?
@@ -485,38 +485,38 @@ them... is that really true?
INT_INPUT.9 RTC IRQ (usually 1Hz) (or 4096Hz when RTC paused) ``` -#### 0A800000h - T0_RELOAD - Timer 0 Reload Value -#### 0A800010h - T1_RELOAD - Timer 1 Reload Value -#### 0A800020h - T2_RELOAD - Timer 2 Reload Value +#### 0A800000h - T0\_RELOAD - Timer 0 Reload Value +#### 0A800010h - T1\_RELOAD - Timer 1 Reload Value +#### 0A800020h - T2\_RELOAD - Timer 2 Reload Value ``` 0-15 Reload Value (when timer becomes less than zero) ``` Writes to this register are ignored if the timer isn't stopped?
-#### 0A800004h - T0_COUNT - Timer 0 Current value -#### 0A800014h - T1_COUNT - Timer 1 Current value -#### 0A800024h - T2_COUNT - Timer 2 Current value +#### 0A800004h - T0\_COUNT - Timer 0 Current value +#### 0A800014h - T1\_COUNT - Timer 1 Current value +#### 0A800024h - T2\_COUNT - Timer 2 Current value ``` 0-15 Current value (decrementing) ``` Timer interrupts: The timers will automatically raise interrupts if they're enabled, there's no need to set a bit anywhere for IRQs (but you need to enable -the respect interrupts in INT_MASK).
+the respect interrupts in INT\_MASK).
-#### 0A800008h - T0_MODE - Timer 0 Control -#### 0A800018h - T1_MODE - Timer 1 Control -#### 0A800028h - T2_MODE - Timer 2 Control +#### 0A800008h - T0\_MODE - Timer 0 Control +#### 0A800018h - T1\_MODE - Timer 1 Control +#### 0A800028h - T2\_MODE - Timer 2 Control ``` 0-1 Timer Divider (0=Div2, 1=Div32, 2=Div512, 3=Div2 too) 2 Timer Enable (0=Stop, 1=Decrement) 3-15 Unknown (should be zero) ``` -Timers are clocked by the System Clock (usually 4MHz, when CLK_MODE=7), divided +Timers are clocked by the System Clock (usually 4MHz, when CLK\_MODE=7), divided by the above divider setting. Note that the System Clock changes when changing -the CPU speed via CLK_MODE, so Timer Divider and/or Timer Reload must be +the CPU speed via CLK\_MODE, so Timer Divider and/or Timer Reload must be adjusted accordingly.
-#### 0B800000h - RTC_MODE - RTC control word +#### 0B800000h - RTC\_MODE - RTC control word ``` 0 Pause RTC (0=Run/1Hz, 1=Pause/4096Hz) 1-3 Select value to be modified via RTC_ADJUST @@ -533,35 +533,35 @@ The selection bits can be:
06h = Year ;/ 07h = Unknown ;-usually used when RTC isn't paused ``` -When paused, the RTC IRQ bit in INT_INPUT.9 runs at 4096Hz (instead 1Hz).
+When paused, the RTC IRQ bit in INT\_INPUT.9 runs at 4096Hz (instead 1Hz).
-#### 0B800004h - RTC_ADJUST - Modify value (write only) +#### 0B800004h - RTC\_ADJUST - Modify value (write only) Writing a value here seems to increment the current selected parameter (by the RTC control). What is perhaps (?) clear is that you have to wait for the RTC interrupt signal to go low before writing to this.
-#### 0B800008h - RTC_TIME - Real-Time Clock Time (read only) (R) +#### 0B800008h - RTC\_TIME - Real-Time Clock Time (read only) (R) ``` 0-7 Seconds (00h..59h, BCD) 8-15 Minutes (00h..59h, BCD) 16-23 Hours (00h..23h, BCD) 24-31 Day of week (1=Sunday, ..., 7=Saturday) ``` -Reading RTC_TIME seems to be somewhat unstable: the BIOS uses a read/retry +Reading RTC\_TIME seems to be somewhat unstable: the BIOS uses a read/retry loop, until it has read twice the same value (although it does read the whole 32bit at once by a LDR opcode, the data is maybe passed through a 8bit or 16bit bus; so the LSBs might be a few clock cycles older than the MSBs...?).
-#### 0B80000Ch - RTC_DATE - Real-Time Clock Date (read only) (R) +#### 0B80000Ch - RTC\_DATE - Real-Time Clock Date (read only) (R) ``` 0-7 Day (01h..31h, BCD) 8-11 Month (01h..12h, BCD) 16-23 Year (00h..99h, BCD) 24-31 Unknown? (this is NOT used as century) ``` -Reading RTC_DATE seems to require the same read/retry method as RTC_TIME (see +Reading RTC\_DATE seems to require the same read/retry method as RTC\_TIME (see there). Note: The century is stored in battery-backed RAM (in the reserved -kernel RAM region) rather than in the RTC_DATE register. The whole date, +kernel RAM region) rather than in the RTC\_DATE register. The whole date, including century, can be read via SWI 0Dh, GetBcdDate().
@@ -573,7 +573,7 @@ IR is used in Final Fantasy 8's Chocobo World (press Left/Right in the Map screen to go to the IR menu), and in Metal Gear Solid Integral (Press Up in the main screen), and in PDA Remote 1 & 2 (one-directional TV remote control).
-#### 0C800000h - IRDA_MODE - Controlling the protocol - send/recv, etc. (R/W) +#### 0C800000h - IRDA\_MODE - Controlling the protocol - send/recv, etc. (R/W) ``` 0 Transfer Direction (0=Receive, 1=Transmit) 1 Disable IRDA (0=Enable, 1=Disable) @@ -582,7 +582,7 @@ main screen), and in PDA Remote 1 & 2 (one-directional TV remote control).
4-31 Unknown (should be zero) ``` -#### 0C800004h - IRDA_DATA - Infrared TX Data +#### 0C800004h - IRDA\_DATA - Infrared TX Data ``` 0 Transmit Data in Send Direction (0=LED Off, 1=LED On) 1-31 Unknown (should be zero) @@ -590,10 +590,10 @@ main screen), and in PDA Remote 1 & 2 (one-directional TV remote control).
Bits are usually encoded as long or short ON pulses, separated by short OFF pulses. Where long is usually twice as long as short.
-#### 0C80000Ch - IRDA_MISC +#### 0C80000Ch - IRDA\_MISC Unknown? Reportedly reserved.
-#### INT_INPUT.12 - IRQ - Infrared RX Interrupt +#### INT\_INPUT.12 - IRQ - Infrared RX Interrupt Seems to get triggered on raising or falling (?) edges of incoming data. The interrupt handler seems to read the current counter value from one of the timers (usually Timer 2, with reload=FFFFh) to determine the length of the @@ -611,12 +611,12 @@ pulse:
``` that might be maybe done automatically by the hardware...?
-Reportedly, Bit4 of Port 0D80000Ch (IOP_DATA) is also somewhat IR related...?
+Reportedly, Bit4 of Port 0D80000Ch (IOP\_DATA) is also somewhat IR related...?
## Pocketstation IO Memory-Control -#### 06000000h - F_CTRL +#### 06000000h - F\_CTRL ``` 0-31 Unknown ``` @@ -631,20 +631,20 @@ The GUI does additionally read from this register (and gets itself trapped in a bizarre endless loop if bit0 was zero). Unknown if it's possible to re-enable ROM at location 00000000h by writing any other values to this register?
-#### 06000004h F_STAT +#### 06000004h F\_STAT ``` 0-31 Unknown ``` -The kernel issues a dummy read from this address (before setting F_CTRL to +The kernel issues a dummy read from this address (before setting F\_CTRL to 00000001h).
-#### 06000008h F_BANK_FLG ;FLASH virtual bank mapping enable flags (16 bits)(R/W) +#### 06000008h F\_BANK\_FLG ;FLASH virtual bank mapping enable flags (16 bits)(R/W) ``` 0-15 Enable physical banks 0..15 in virtual region (0=Disable, 1=Enable) 16-31 Unknown (should be zero) ``` -#### 06000100h F_BANK_VAL ;FLASH virtual bank mapping addresses (16 words)(R/W) +#### 06000100h F\_BANK\_VAL ;FLASH virtual bank mapping addresses (16 words)(R/W) This region contains 16 words, the first word at 06000100h for physical bank 0, the last word at 0600013Ch for physical bank 15. Each word is:
``` @@ -652,9 +652,9 @@ the last word at 0600013Ch for physical bank 15. Each word is:
4-31 Should be 0 ``` Unused physical banks are usually mapped to 0Fh (and are additionally disabled -in the F_BANK_FLG register).
+in the F\_BANK\_FLG register).
-#### 0600000Ch F_WAIT1 ;waitstates...? +#### 0600000Ch F\_WAIT1 ;waitstates...? ``` 0..3 Unknown/not tested 4 hangs hardware? but that bit is used in some cases! @@ -667,10 +667,10 @@ RAM or BIOS ROM). Normally it is set to the following values:
F_WAIT1=00000010h when CPU Speed = 08h..0Fh ``` Note: The kernels Docking/Undocking IRQ-11 handler does additionally do this: -"F_WAIT1=max(08h,(CLK_MODE AND 0Fh))" (that is a bug, what it actually wants to -do is to READ the current F_WAIT.Bit4 setting).
+"F\_WAIT1=max(08h,(CLK\_MODE AND 0Fh))" (that is a bug, what it actually wants to +do is to READ the current F\_WAIT.Bit4 setting).
-#### 06000010h F_WAIT2 ;waitstates, and FLASH-Write-Control-and-Status...? +#### 06000010h F\_WAIT2 ;waitstates, and FLASH-Write-Control-and-Status...? ``` 0 no effect? but that bit is used in some cases! maybe write-enable? 1 hangs hardware? @@ -683,7 +683,7 @@ do is to READ the current F_WAIT.Bit4 setting).
8..31 Unknown/not tested ``` Unknown, seems to control some kind of memory waitstates, maybe for another -memory region than F_WAIT1, or maybe F_WAIT2 is for writing, and F_WAIT1 for +memory region than F\_WAIT1, or maybe F\_WAIT2 is for writing, and F\_WAIT1 for reading or so. Normally it is set to the following values:
``` F_WAIT2=00000000h when CPU Speed = 00h..07h ;\same as F_WAIT1 @@ -700,8 +700,8 @@ Before completion, those SWIs do additionally,
and then set F_WAIT2=00000000h ``` -#### 08002A54h - F_KEY1 - Flash Unlock Address 1 (W) -#### 080055AAh - F_KEY2 - Flash Unlock Address 2 (W) +#### 08002A54h - F\_KEY1 - Flash Unlock Address 1 (W) +#### 080055AAh - F\_KEY2 - Flash Unlock Address 2 (W) Unlocks FLASH memory for writing. The complete flowchart for writing sector data (or header values) is:
``` @@ -727,27 +727,27 @@ During the write operation one can (probably?) not read data (nor opcodes) from FLASH memory, so the above code must be executed either in RAM, or in BIOS ROM (see SWI 03h, SWI 0Fh, SWI 10h).
-#### 06000300h - F_SN_LO - Serial Number LSBs -#### 06000302h - F_SN_HI - Serial Number MSBs -#### 06000308h - F_CAL - Calibration value for LCD +#### 06000300h - F\_SN\_LO - Serial Number LSBs +#### 06000302h - F\_SN\_HI - Serial Number MSBs +#### 06000308h - F\_CAL - Calibration value for LCD ``` 0-15 Data ``` This seems to be an additional "header" region of the FLASH memory -(additionally to the 128K of data). The F_SN registers contain a serial number +(additionally to the 128K of data). The F\_SN registers contain a serial number or so (purpose unknown, maybe intended as some kind of an "IP" address for more complex infrared network applications), the two LO/HI registers must be read by -separate 16bit LDRH opcodes (not by a single 32bit LDR opcode). The F_CAL -register contains a 6bit calibration value for LCD_CAL (contrast or so?).
+separate 16bit LDRH opcodes (not by a single 32bit LDR opcode). The F\_CAL +register contains a 6bit calibration value for LCD\_CAL (contrast or so?).
Although only the above 3 halfwords are used by the BIOS, the "header" is unlike to be 6 bytes in size, probably there are whatever number of additional "header" locations at 06000300h and up...?
-Note: Metal Gear Solid Integral uses F_SN as some kind of copy protection (the -game refuses to run and displays "No copy" if F_SN is different as when the +Note: Metal Gear Solid Integral uses F\_SN as some kind of copy protection (the +game refuses to run and displays "No copy" if F\_SN is different as when the pocketstation file was initially created).
-#### F_BANK_VAL and F_BANK_FLG Notes -Observe that the physical_bank number (p) is used as array index, and that the +#### F\_BANK\_VAL and F\_BANK\_FLG Notes +Observe that the physical\_bank number (p) is used as array index, and that the virtual bank number (v) is stored in that location, ie. table[p]=v, which is unlike as one may have expected it (eg. on a 80386 CPU it'd be vice-versa: table[v]=p).
@@ -759,7 +759,7 @@ ANDed together).
## Pocketstation IO Communication Ports -#### 0C000000h - COM_MODE - Com Mode +#### 0C000000h - COM\_MODE - Com Mode ``` 0 Data Output Enable (0=None/HighZ, 1=Output Data Bits) 1 /ACK Output Level (0=None/HighZ, 1=Output LOW) @@ -767,13 +767,13 @@ ANDed together).
3-31 Unknown (should be zero) ``` -#### 0C000008h - COM_DATA - Com RX/TX Data +#### 0C000008h - COM\_DATA - Com RX/TX Data ``` 0-7 Data (Write: to be transmitted to PSX, Read: been received from PSX) 8-31 Unknown ``` -#### 0C000004h - COM_STAT1 - Com Status Register 1 (Bit1=Error) +#### 0C000004h - COM\_STAT1 - Com Status Register 1 (Bit1=Error) ``` 0 Unknown 1 Error flag or so (0=Okay, 1=Error) @@ -785,16 +785,16 @@ is unknown. Aside from checking the error flag, the kernel does issue a dummy read at the end of each transfer, maybe to acknowledge something, maybe the hardware simply resets the error bit after reading (although the kernel doesn't handle the bit like so when receiving the 1st command byte).
-Aside from the above error flag, one should check if INT_INPUT.11 becomes zero +Aside from the above error flag, one should check if INT\_INPUT.11 becomes zero during transfer (which indicates undocking).
-#### 0C000014h - COM_STAT2 - Com Status Register 2 (Bit0=Ready) +#### 0C000014h - COM\_STAT2 - Com Status Register 2 (Bit0=Ready) ``` 0 Ready flag (0=Busy, 1=Ready) (when 8bits have been transferred) 1-31 Unknown ``` -#### 0C000010h - COM_CTRL1 - Com Control Register 1 +#### 0C000010h - COM\_CTRL1 - Com Control Register 1 ``` 0 Unknown (should be set AT BEGIN OF A NEW command...?) 1 Unknown (0=Disable something, 1=Enable something) @@ -810,7 +810,7 @@ When doing the enable thing, Bit1 should be set to 0-then-1...? Bit0 might enable the data shift register... and bit1 might be a master enable and master acknowledge for the COM interrupt... or something else?
-#### 0C000018h - COM_CTRL2 - Com Control Register 2 +#### 0C000018h - COM\_CTRL2 - Com Control Register 2 ``` 0 Unknown (should be set, probably starts or acknowledges something) 1 Unknown (should be set when expecting a NEW command...?) @@ -823,24 +823,24 @@ Used values are:
``` Maybe that two bits acknowledge the ready/error bits?
-#### INT_INPUT.6 FIQ (!) COM for the COM_registers? (via /SEL Pin?) +#### INT\_INPUT.6 FIQ (!) COM for the COM\_registers? (via /SEL Pin?) ``` (via FIQ vector, not IRQ vector) ``` -#### INT_INPUT.11 IRQ Docked ("IOP") (0=Undocked, 1=Docked to PSX) +#### INT\_INPUT.11 IRQ Docked ("IOP") (0=Undocked, 1=Docked to PSX) Probably senses the voltage on the cartridge slots VCC Pin. Becomes zero when Undocked (and probably also when the PSX is switched off).
The Kernel uses IRQ-11 for BOTH sensing docking and undocking, ie. as if the IRQ would be triggered on both 0-to-1 and 1-to-0 transistions... though maybe that feature just relies on switch-bounce. For the same reason (switch bounce), -the IRQ-11 handler performs a delay before it checks the new INT_INPUT.11 +the IRQ-11 handler performs a delay before it checks the new INT\_INPUT.11 setting (ie. the delay skips the unstable switch bound period, and allows the signal to stabilize).
-#### IOP_START/IOP_STOP.Bit1 +#### IOP\_START/IOP\_STOP.Bit1 The BIOS adjusts this bit somehow in relation to communication. Unknown -when/why/how it must be used. For details on IOP_START/IOP_STOP see Power +when/why/how it must be used. For details on IOP\_START/IOP\_STOP see Power Control chapter.
#### Opcode E6000010h (The Undefined Instruction) - Write chr(r0) to TTY @@ -862,7 +862,7 @@ ie. which do neither trap data aborts, nor do mirror to existing ports...?
## Pocketstation IO Power Control -#### 0B000000h - CLK_MODE - Clock control (CPU and Timer Speed) (R/W) +#### 0B000000h - CLK\_MODE - Clock control (CPU and Timer Speed) (R/W) ``` 0-3 Clock Ratio (01h..08h, see below) (usually 7 = 3.99MHz) (R/W) 4 Clock Change State (0=Busy, 1=Ready) (Read-only) @@ -882,11 +882,11 @@ the CPU clock, or less, depending on the Timer Divider). Possible values are:
-#### 0B000004h - CLK_STOP - Clock stop (Sleep Mode) +#### 0B000004h - CLK\_STOP - Clock stop (Sleep Mode) Stops the CPU until an interrupt occurs. The pocketstation doesn't have a power-switch nor standby button, the closest thing to switch "power off" is to enter sleep mode. Software should do that when the user hasn't pressed buttons @@ -897,9 +897,9 @@ it's using the PSX power supply instead of the battery).
1-15 ? ``` Wakeup is usually done by IRQ-0 (Fire Button) and IRQ-11 (Docking). If alarm is -enabled, then the GUI also enables IRQ-9 (RTC), and compares RTC_TIME against +enabled, then the GUI also enables IRQ-9 (RTC), and compares RTC\_TIME against the alarm setting each time when it wakes up.
-Before writing to CLK_STOP, one should do:
+Before writing to CLK\_STOP, one should do:
``` DAC_CTRL=0 ;\disable sound IOP_STOP=20h ;/ @@ -908,12 +908,12 @@ Before writing to CLK_STOP, one should do:
BATT_CTRL=BATT_CTRL AND FFFFFFFCh ;-do whatever INT_MASK_SET=801h ;-enable Docking/Fire wakeup interrupts ``` -The GUI uses CLK_STOP only for Standby purposes (not for waiting for its 30Hz +The GUI uses CLK\_STOP only for Standby purposes (not for waiting for its 30Hz "frame rate" timer 0 interrupt; maybe that isn't possible, ie. probably -CLK_STOP does completely disable the system clock, and thus does stop +CLK\_STOP does completely disable the system clock, and thus does stop Timer0-2...?)
-#### 0D800000h - IOP_CTRL - Configures whatever...? (R/W) +#### 0D800000h - IOP\_CTRL - Configures whatever...? (R/W) ``` 0-3 Probably Direction for IOP_DATA bit0..3 (0=Input, 1=Output) 4-31 Unknown/Unused (seems to be always zero) @@ -921,11 +921,11 @@ Timer0-2...?)
Unknown. Set to 0000000Fh by BIOS upon reset. Aside from that, the BIOS does never use that register.
-#### 0D800004h - IOP_STAT (R) - Read Current bits? -- No, seems to be always 0 -#### 0D800004h - IOP_STOP (W) - Set IOP_DATA Bits -#### 0D800008h - IOP_START (W) - Clear IOP_DATA Bits +#### 0D800004h - IOP\_STAT (R) - Read Current bits? -- No, seems to be always 0 +#### 0D800004h - IOP\_STOP (W) - Set IOP\_DATA Bits +#### 0D800008h - IOP\_START (W) - Clear IOP\_DATA Bits These two ports are probably accessing a single register, writing "1" bits to -IOP_STOP sets bits in that register, and writing "1" bits to IOP_START clears +IOP\_STOP sets bits in that register, and writing "1" bits to IOP\_START clears bits... or vice-versa...? Writing "0" bits to either port seems to leave that bits unchanged. The meaning of most bits is still unknown:
``` @@ -939,15 +939,15 @@ bits unchanged. The meaning of most bits is still unknown:
7-31 Unknown, never STARTED nor STOPPED by BIOS ``` Aside from Bit1, it's probably not neccessary to change the unknown bits...?
-Sound is usually disabled by setting IOP_STOP=00000020h. IOP_STAT is rarely +Sound is usually disabled by setting IOP\_STOP=00000020h. IOP\_STAT is rarely used. Although, one piece of code in the BIOS disables sound by setting -IOP_STOP=IOP_STAT OR 00000020h, that is probably nonsense, probably intended to +IOP\_STOP=IOP\_STAT OR 00000020h, that is probably nonsense, probably intended to keep bits stopped if they are already stopped (which would happen anyways), however, the strange code implies that reading from 0D800004h returns the current status of the register, and that the bits in that register seem to be 0=Started, and 1=Stopped...?
-#### 0D80000Ch - IOP_DATA (R) +#### 0D80000Ch - IOP\_DATA (R) ``` 0 ? 1 Red LED (0=On, 1=Off) @@ -961,12 +961,12 @@ Connection...? This register is read by Rewrite ID, and by Harvest Moon. Maybe bit4 doesn't mean \ IR connection exist, but rather \ the received IR data level...?
-#### 0D800020h - BATT_CTRL - Battery Monitor Control? +#### 0D800020h - BATT\_CTRL - Battery Monitor Control? Unknown. Somehow battery saving related. Upon reset, and upon leaving sleep -mode, the BIOS does set BATT_CTRL=00000000h. Before entering sleep mode, it -does set BATT_CTRL=BATT_CTRL AND FFFFFFFCh, whereas, assuming that BATT_CTRL +mode, the BIOS does set BATT\_CTRL=00000000h. Before entering sleep mode, it +does set BATT\_CTRL=BATT\_CTRL AND FFFFFFFCh, whereas, assuming that BATT\_CTRL was 00000000h, ANDing it with FFFFFFFCh would simply leave it unchanged... -unless the hardware (or maybe a game) sets some bits in BATT_CTRL to nonzero +unless the hardware (or maybe a game) sets some bits in BATT\_CTRL to nonzero values...?
#### Battery Low Interrupt @@ -1055,8 +1055,8 @@ The kernel IRQ handler does (after the IRQ callback) process IRQ-11 (IOP) (which does mainly handle docking/undocking), and IRQ-9 (RTC) (which increments the century if the year wrapped from 99h to 00h).
And the kernel FIQ handler does (before the FIQ callback) process IRQ-6 (COM) -(which does, if ComFlags.Bit9 is set, handle bu_cmd's) (both IRQs and FIQs are -disabled, and the main program is stopped until the bu_cmd finishes, or until a +(which does, if ComFlags.Bit9 is set, handle bu\_cmd's) (both IRQs and FIQs are +disabled, and the main program is stopped until the bu\_cmd finishes, or until a joypad command is identified irrelevant, among others that means that sound/timer IRQs aren't processed during that time, so audio output may become distorted when docked).
@@ -1077,16 +1077,16 @@ SWI2 can be useful to execute code in privileged mode (eg. to initialize FIQ registers r8..r12 for a FIQ based sound engine) (which usually isn't possible because the main program runs in non-privileged user mode).
-#### SWI 04h - SetCpuSpeed(speed) out: old_speed +#### SWI 04h - SetCpuSpeed(speed) out: old\_speed Changes the CPU speed. The BIOS uses it with values in range 01h..07h. Unknown if value 00h can be also used? The function also handles values bigger than 07h, of which, some pieces of BIOS code look as if 08h would be the maximum value...?
-Before setting the new speed, the function sets F_WAIT1 and F_WAIT2 to +Before setting the new speed, the function sets F\_WAIT1 and F\_WAIT2 to 00000000h (or to 00000010h if speed.bit3=1). After changing the speed (by -writing the parameter to CLK_MODE) it does wait until the new speed is applied -(by waiting for CLK_MODE.bit4 to become zero). The function returns the old -value of CLK_MODE, anded with 0Fh.
+writing the parameter to CLK\_MODE) it does wait until the new speed is applied +(by waiting for CLK\_MODE.bit4 to become zero). The function returns the old +value of CLK\_MODE, anded with 0Fh.
@@ -1101,16 +1101,16 @@ Can be used to enable/disable communication. When starting an executable, communication is initially disabled, so it'd be a good idea to enable them (otherwise the PSX cannot communicate with the Pocketstation while the game is running).
-When flag=0, disables communication: Intializes the COM_registers, disables +When flag=0, disables communication: Intializes the COM\_registers, disables IRQ-6 (COM), and clears ComFlags.9. When flag=1, enables communication: -Intializes the COM_registers, enables IRQ-6 (COM), sets ComFlags.9 (when -docked), or clears Sys.Flags.9 (when undocked), and sets FAST cpu_speed=7 (only -when docked). The function returns garbage (r0=retadr to swi_handler).
+Intializes the COM\_registers, enables IRQ-6 (COM), sets ComFlags.9 (when +docked), or clears Sys.Flags.9 (when undocked), and sets FAST cpu\_speed=7 (only +when docked). The function returns garbage (r0=retadr to swi\_handler).
#### SWI 06h - GetPtrToComFlags() Returns a pointer to the ComFlags word in RAM, which contains several communication related flags (which are either modified upon docking/undocking, -or upon receiving certain bu_cmd's). The ComFlags word consists of the +or upon receiving certain bu\_cmd's). The ComFlags word consists of the following bits:
``` 0-3 Whatever (set/cleared when docked/undocked, and modified by bu_cmd's) @@ -1146,7 +1146,7 @@ cartridge slot. The function returns the incoming flags value ANDed with 70000h.
#### SWI 0Bh - ClearComFlagsBit10() -Resets ComFlags.Bit10, ie. enables bu_cmd_57h (write_sector) to write to the +Resets ComFlags.Bit10, ie. enables bu\_cmd\_57h (write\_sector) to write to the Broken Sector region in FLASH memory (sector 16..55). SWI 0Bh returns the current ComFlags value (the new value, with bit10=0).
Aside from calling SWI 0Bh, ComFlags.10 is also automatically cleared upon @@ -1170,7 +1170,7 @@ does set/clear ComFlags.9 when docked/undocked.
#### SWI 17h - GetPtrToFunc3addr() Returns a pointer to a halfword in RAM which contains the FUNC3 address (for -bu_cmd_5bh and bu_cmd_5ch). The address is only 16bit, originated at 02000000h +bu\_cmd\_5bh and bu\_cmd\_5ch). The address is only 16bit, originated at 02000000h in FLASH (ie. it can be only in the first 64K of the file), bit0 can be set for THUMB code. The default address is zero, which behaves bugged: It accidently sets [00000004h]=00000000h, ie. replaces the Undefined Instruction exception @@ -1192,17 +1192,17 @@ SetCallbacks(index,proc), and BU Command 5Dh for details.
## Pocketstation SWI Execute Functions -#### SWI 08h - PrepareExecute(flag,dir_index,param) -dir_index should be 0=GUI, or 1..15=First block of game. When calling +#### SWI 08h - PrepareExecute(flag,dir\_index,param) +dir\_index should be 0=GUI, or 1..15=First block of game. When calling DoExecute, param is passed to the entrypoint of the game or GUI in r0 register (see notes on GUI \ values belows). For games, param may be interpreted in whatever way.
-When flag=0, the function simply returns the old dir_index value. When flag=1, -the new dir_index and param values are stored in Kernel RAM (for being used by -DoExecute); the values are stored only if dir_index=0 (GUI), or if dir_index +When flag=0, the function simply returns the old dir\_index value. When flag=1, +the new dir\_index and param values are stored in Kernel RAM (for being used by +DoExecute); the values are stored only if dir\_index=0 (GUI), or if dir\_index belongs to a file with "SC" and "MCX0" or "MCX1" IDs in it's title sector. If -dir_index was accepted, then the new dir_index value is returned, otherwise the -old dir_index is returned.
+dir\_index was accepted, then the new dir\_index value is returned, otherwise the +old dir\_index is returned.
#### GUI \ values - for PrepareExecute(1,0,param) PrepareExecute(1,0,param) prepares to execute the GUI (rather than a file). @@ -1223,18 +1223,18 @@ The command numbers can be:
Command xxh --> Erase RTC time/date (same as Command 0xh) ``` For Command 2xh and 3xh, the lower 4bit of the command (x) must be a valid -dir_index of the 1st block of a pocketstation executable, otherwise the BIOS +dir\_index of the 1st block of a pocketstation executable, otherwise the BIOS erases the RTC time/date. Bit8 is just a "funny" nag feature, allowing the user to change the alarm setting, but with the changes being ignored (bit8 can be actually useful in BU Command 59h, after FUNC2 was used for changing alarm).
-#### SWI 09h - DoExecute(), or DoExecute(snapshot_saving_flag) for MCX1 -Allows to return control to the GUI (when dir_index=0), or to start an -executable (when dir_index=1..15). Prior to calling DoExecute, parameters -should be set via PrepareExecute(1,dir_index,param), when not doing that, +#### SWI 09h - DoExecute(), or DoExecute(snapshot\_saving\_flag) for MCX1 +Allows to return control to the GUI (when dir\_index=0), or to start an +executable (when dir\_index=1..15). Prior to calling DoExecute, parameters +should be set via PrepareExecute(1,dir\_index,param), when not doing that, DoExecute would simply restart the current executable (which may be a desired effect in some cases).
-The "snapshot_saving_flag" can be ommited for normal (MCX0) files, that +The "snapshot\_saving\_flag" can be ommited for normal (MCX0) files, that parameter is used only for special (MCX1) files (see Snapshot Notes for details).
Caution: DoExecute fails (and returns r0=unchanged) when ComFlags.9=1 (which @@ -1244,19 +1244,19 @@ calling SetComOnOff(0), or it can be updated according to the current docking-state by calling SetComOnOff(1) or SenseAutoCom().
#### SWI 16h - GetDirIndex() -Returns the dir_index for the currently executed file. If that value is zero, +Returns the dir\_index for the currently executed file. If that value is zero, ie. if there is no file executed, ie. if the function is called by the GUI, -then it does instead return the "alternate" dir_index (as set via SWI 15h).
+then it does instead return the "alternate" dir\_index (as set via SWI 15h).
-#### SWI 15h - MakeAlternateDirIndex(flag,dir_index) out: alt_dir_index (new/old) -Applies the specified dir_index as "alternate" dir_index (for being retrieved -via SWI 16h for whatever purpose). The dir_index is applied only when flag=1, -and only if dir_index is 0=none, or if it is equal to the dir_index of the +#### SWI 15h - MakeAlternateDirIndex(flag,dir\_index) out: alt\_dir\_index (new/old) +Applies the specified dir\_index as "alternate" dir\_index (for being retrieved +via SWI 16h for whatever purpose). The dir\_index is applied only when flag=1, +and only if dir\_index is 0=none, or if it is equal to the dir\_index of the currently executed file (ie. attempts to make other files being the "alternate" -one are rejected). If successful, the new dir_index is returned, otherwise the -old dir_index is returned (eg. if flag=0, or if the index was rejected).
+one are rejected). If successful, the new dir\_index is returned, otherwise the +old dir\_index is returned (eg. if flag=0, or if the index was rejected).
-#### SWI 12h - TestSnapshot(dir_index) +#### SWI 12h - TestSnapshot(dir\_index) Tests if the specified file contains a load-able snapshot, ie. if it does have the "SC" and "MCX1" IDs in the title sector, and the 01h,00h,"SE" ID in the snapshot header. If so, it returns r0=1, and otherwise returns r0=0.
@@ -1266,9 +1266,9 @@ Snapshots are somewhat automatically loaded/saved when calling DoExecute:
If the old file (the currently executed file) contains "SC" AND "MCX1" IDs in the title sector, then the User Mode CPU registers and User RAM at 200h..7FFh are automatically saved in the files snapshot region in FLASH memory, with the -snapshot_saving_flag being applied as bit0 of the 0xh,00h,"SE" ID of the +snapshot\_saving\_flag being applied as bit0 of the 0xh,00h,"SE" ID of the snapshot header).
-If the new file (specified in dir_index) contains load-able snapshot data (ie. +If the new file (specified in dir\_index) contains load-able snapshot data (ie. if it has "SC" and "MCX1" IDs in title sector, and 01h,00h,"SE" ID in the snapshot region), then the BIOS starts the saved snapshot data (instead of restarting the executable at its entrypoint). Not too sure if that feature is @@ -1283,7 +1283,7 @@ to underflow after loading one or two snapshots...?
#### SWI 0Ch - SetBcdDateTime(date,time) Sets the time and date, the parameters are having the same format as SWI 0Dh and SWI 0Eh return values (see there). The SWI 0Ch return value contains only -garbage (r0=RTC_DATE/10000h).
+garbage (r0=RTC\_DATE/10000h).
#### SWI 0Dh - GetBcdDate() ``` @@ -1291,7 +1291,7 @@ garbage (r0=RTC_DATE/10000h).
8-11 Month (01h..12h, BCD) 16-31 Year (0000h..9999h, BCD) ``` -Returns the current date, the lower 24bit are read from RTC_DATE, the century +Returns the current date, the lower 24bit are read from RTC\_DATE, the century in upper 8bit is read from Kernel RAM.
#### SWI 0Eh - GetBcdTime() @@ -1301,11 +1301,11 @@ in upper 8bit is read from Kernel RAM.
16-23 Hours (00h..23h, BCD) 24-31 Day of week (1=Sunday, ..., 7=Saturday) ``` -Returns the current time and day of week, read from RTC_TIME.
+Returns the current time and day of week, read from RTC\_TIME.
#### SWI 13h - GetPtrToAlarmSetting() Returns a pointer to a 64bit value in Kernel RAM, the upper word (Bit32-63) -isn't actually used by the BIOS, except that, the bu_cmd FUNC3 does transfer +isn't actually used by the BIOS, except that, the bu\_cmd FUNC3 does transfer the whole 64bits. The meaning of the separate bits is:
``` 0-7 Alarm Minute (00h..59h, BCD) @@ -1349,19 +1349,19 @@ Returns 0=okay, or 1=failed.
#### SWI 03h - FlashWriteVirtual(sector,src) The sector number (0..3FFh) is a virtual sector number (originated at -02000000h), the function uses the F_BANK_VAL settings to translate it to a +02000000h), the function uses the F\_BANK\_VAL settings to translate it to a physical sector number, and does then write the 80h-bytes at src to that location (via the FlashWritePhysical function). Returns 0=okay, or 1=failed (if the write failed, or if the sector number exceeded the filesize aka the virtually mapped memory region).
#### SWI 0Ah - FlashReadSerial() -Returns the 32bit value from the two 16bit F_SN registers (see F_SN for +Returns the 32bit value from the two 16bit F\_SN registers (see F\_SN for details).
-#### SWI 0Fh - FlashWriteSerial(serial_number) ;old BIOS only! -Changes the 32bit F_SN value in the "header" region of the FLASH memory. The -function also rewrites the F_CAL value (but it simply rewrites the old value, +#### SWI 0Fh - FlashWriteSerial(serial\_number) ;old BIOS only! +Changes the 32bit F\_SN value in the "header" region of the FLASH memory. The +function also rewrites the F\_CAL value (but it simply rewrites the old value, so it's left unchanged). The function isn't used by the BIOS, no idea if it is used by any games. No return value (always returns r0=0).
This function is supported by the old "061" version BIOS only (the function is @@ -1369,7 +1369,7 @@ padded with jump opcodes which hang the CPU in endless loops on newer "110" version).
#### SWI 18h - FlashReadWhateverByte(sector) -Returns [8000000h+sector*80h+7Eh] AND 00FFh. Purpose is totally unknown... the +Returns [8000000h+sector\*80h+7Eh] AND 00FFh. Purpose is totally unknown... the actual FLASH memory doesn't contain any relevant information at that locations (eg. the in the directory sectors, that byte is unused, usually zero)... and, reading some kind of status or manufacturer information would first require to @@ -1480,9 +1480,9 @@ aware of that situation. If the file is broken into a Pocketstation Executable region and a PSX Gameposition region, then it may modify the Gameposition stuff even while the Executable is running. If the PSX want to overwrite the executable then it must first ensure that it isn't executed (eg. by retrieving -the dir_index of the currently executed file via BU Command 5Ah, and comparing +the dir\_index of the currently executed file via BU Command 5Ah, and comparing it against the first block number in the files FCB at the PSX side; for file -handle "fd", the first block is found at "[104h]+fd*2Ch+24h" in PSX memory).
+handle "fd", the first block is found at "[104h]+fd\*2Ch+24h" in PSX memory).
#### Write Error Code FEh (write-protected Broken Sector region, sector 16..55) The write-protection is enabled by ComFlags.bit10 (which can be set/cleared via @@ -1517,7 +1517,7 @@ Might be somehow related to FUNC 03h...?
(0) 01h Send dummy/zero, receive another value (01h) ``` -#### BU Command 59h (Prepare File Execution with Dir_index, and Parameter) +#### BU Command 59h (Prepare File Execution with Dir\_index, and Parameter) ``` Send Reply Comment 81h N/A Memory Card Access @@ -1530,29 +1530,29 @@ Might be somehow related to FUNC 03h...?
PAR (0) Send exec_parameter.16-23, receive dummy/zero PAR (0) Send exec_parameter.24-31, receive dummy/zero ``` -The new dir_index can be the following:
+The new dir\_index can be the following:
``` 0000h..000Fh --> Request to Start GUI or File (with above parameter bits) 0010h..FFFDh --> Not used, acts same as FFFFh (see below) FFFEh --> Request to Destroy RTC and Start GUI (with parameter 00000000h) FFFFh --> Do nothing (transfer all bytes, but don't store the new values) ``` -Upon dir_index=0000h (Start GUI) or 0001..000Fh (start file), a request flag in +Upon dir\_index=0000h (Start GUI) or 0001..000Fh (start file), a request flag in ComFlags.11 is set, the GUI does handle that request, but the Kernel doesn't handle it (so it must be handled in the game; ie. check ComFlags.11 in your mainloop, and call DoExecute when that bit is set, there's no need to call PrepareExecute, since that was already done by the BU Command).
-Caution: When dir_index=0000h, then \ should be a value that does +Caution: When dir\_index=0000h, then \ should be a value that does NOT erase the RTC time/date (eg. 10h or 20h) (most other values do erase the RTC, see SWI 08h for details).
-Upon dir_index=FFFEh, a similar request flag is set in ComFlags.30, and, the +Upon dir\_index=FFFEh, a similar request flag is set in ComFlags.30, and, the Kernel (not the GUI) does handle that request in its FIQ handler (however, the request is: To reset the RTC time/date and to start the GUI with uninitialized irq/svc stack pointers, so this unpleasant and bugged feature shouldn't ever be -used). Finally, dir_index=FFFFh allows to read the current dir_index value +used). Finally, dir\_index=FFFFh allows to read the current dir\_index value (which could be also read via BU Command 5Ah).
-#### BU Command 5Ah (Get Dir_index, ComFlags, F_SN, Date, and Time) +#### BU Command 5Ah (Get Dir\_index, ComFlags, F\_SN, Date, and Time) ``` Send Reply Comment 81h N/A Memory Card Access @@ -1661,7 +1661,7 @@ execution is like so:
If value.8-15 = 00h, then ComFlags.bit10=1, else ComFlags.bit10=0. If download_callback<>0 then call download_callback with r0=value.0-23. ``` -In the GUI, the bu_cmd_5dh_hook/callback handles parameter bits as so (and +In the GUI, the bu\_cmd\_5dh\_hook/callback handles parameter bits as so (and games should probably handle that bits in the same fashion, too):
``` bit0-7 download duration (in whatever units... 30Hz, RTC, seconds...?) @@ -1705,7 +1705,7 @@ what you are doing). In the read direction it can read almost anything: RAM, BIOS ROM, I/O Ports, Physical and Virtual FLASH memory. Of which, trying to read unmapped Virtual FLASH does probably (?) cause a Data Abort exception (and crash the Pocketstation), so that region may be read only if a file is loaded -(check that dir_index isn't zero, via BU Command 5Ah, and, take care not to +(check that dir\_index isn't zero, via BU Command 5Ah, and, take care not to exceed the filesize of that file).
BUG: When sending more than 2 data bytes in the PSX-to-Pocketstation direction, then ADDR must be word-aligned (the BIOS tries to handle odd destination @@ -1730,7 +1730,7 @@ when it gets started, that copy isn't affected by FUNC2, so the GUI believes that the old alarm setting does still apply (and writes that old values back to Kernel RAM when leaving the GUI). The only workaround is:
Test if the GUI is running, if so, restart it via Command 59h (with -dir_index=0, and param=0120h or similar, ie. with param.bit8 set), then execute +dir\_index=0, and param=0120h or similar, ie. with param.bit8 set), then execute FUNC2, then restart the GUI again (this time with param.bit8 zero).
#### FUNC 03h - Custom Function 3 (aka FUNC3) @@ -1913,7 +1913,7 @@ Each icon frame is 32x32 pixels with 1bit color depth (32 words, =128 bytes),
+do occupy N\*80h bytes.
#### Executable Mono Icon List The number of entries in the Executable Mono Icon List is specified in hdr[56h] @@ -2141,8 +2141,8 @@ that it needs to install special transmission handlers):
strne r1,[r0,4] ;func3_buf_len=0 ;/ bx lr ;-for PRE data: return r0=func3_info ``` -Usage: Call "init_tty" at the executable's entrypoint (with incoming R0 passed -on). Call "tty_wrchr" to output ASCII characters.
+Usage: Call "init\_tty" at the executable's entrypoint (with incoming R0 passed +on). Call "tty\_wrchr" to output ASCII characters.
Note: The TTY messages are supported only in no$gba debug version (not no$gba gaming version).
diff --git a/serialportsio.md b/serialportsio.md index fb3df3f..0451da0 100644 --- a/serialportsio.md +++ b/serialportsio.md @@ -1,29 +1,29 @@ # Serial Port (SIO) -#### 1F801050h SIO_TX_DATA (W) +#### 1F801050h SIO\_TX\_DATA (W) ``` 0-7 Data to be sent 8-31 Not used ``` Writing to this register starts transmit (if, or as soon as, TXEN=1 and CTS=on -and SIO_STAT.2=Ready). Writing to this register while SIO_STAT.0=Busy causes +and SIO\_STAT.2=Ready). Writing to this register while SIO\_STAT.0=Busy causes the old value to be overwritten.
-The "TXEN=1" condition is a bit more complex: Writing to SIO_TX_DATA latches +The "TXEN=1" condition is a bit more complex: Writing to SIO\_TX\_DATA latches the current TXEN value, and the transfer DOES start if the current TXEN value OR the latched TXEN value is set (ie. if TXEN gets cleared after writing to -SIO_TX_DATA, then the transfer may STILL start if the old latched TXEN value +SIO\_TX\_DATA, then the transfer may STILL start if the old latched TXEN value was set; this appears for SIO transfers in Wipeout 2097).
-#### 1F801050h SIO_RX_DATA (R) +#### 1F801050h SIO\_RX\_DATA (R) ``` 0-7 Received Data (1st RX FIFO entry) (oldest entry) 8-15 Preview (2nd RX FIFO entry) 16-23 Preview (3rd RX FIFO entry) 24-31 Preview (4th RX FIFO entry) (5th..8th cannot be previewed) ``` -A data byte can be read when SIO_STAT.1=1. Data should be read only via 8bit +A data byte can be read when SIO\_STAT.1=1. Data should be read only via 8bit memory access (the 16bit/32bit "preview" feature is rather unusable).
-#### 1F801054h SIO_STAT (R) +#### 1F801054h SIO\_STAT (R) ``` 0 TX Ready Flag 1 (1=Ready/Started) (depends on CTS) (TX requires CTS) 1 RX FIFO Not Empty (0=Empty, 1=Not Empty) @@ -42,7 +42,7 @@ memory access (the 16bit/32bit "preview" feature is rather unusable).
Note: Bit0 gets cleared after sending the Startbit, Bit2 gets cleared after sending all bits up to including the Stopbit.
-#### 1F801058h SIO_MODE (R/W) (eg. 004Eh --\> 8N1 with Factor=MUL16) +#### 1F801058h SIO\_MODE (R/W) (eg. 004Eh --\> 8N1 with Factor=MUL16) ``` 0-1 Baudrate Reload Factor (1=MUL1, 2=MUL16, 3=MUL64) (or 0=STOP) 2-3 Character Length (0=5bits, 1=6bits, 2=7bits, 3=8bits) @@ -52,7 +52,7 @@ sending all bits up to including the Stopbit.
8-15 Not used (always zero) ``` -#### 1F80105Ah SIO_CTRL (R/W) +#### 1F80105Ah SIO\_CTRL (R/W) ``` 0 TX Enable (TXEN) (0=Disable, 1=Enable, when CTS=On) 1 DTR Output Level (0=Off, 1=On) @@ -69,37 +69,37 @@ sending all bits up to including the Stopbit.
13-15 Not used (always zero) ``` -#### 1F80105Ch SIO_MISC (R/W) +#### 1F80105Ch SIO\_MISC (R/W) This is an internal register, which usually shouldn't be accessed by software. Messing with it has rather strange effects: After writing a value "X" to this register, reading returns "X ROR 8" eventually "ANDed with 1F1Fh and ORed with -C0C0h or 8080h" (depending on the character length in SIO_MODE).
+C0C0h or 8080h" (depending on the character length in SIO\_MODE).
-#### 1F80105Eh SIO_BAUD (R/W) (eg. 00DCh --\> 9600 bauds; when Factor=MUL16) +#### 1F80105Eh SIO\_BAUD (R/W) (eg. 00DCh --\> 9600 bauds; when Factor=MUL16) ``` 0-15 Baudrate Reload value for decrementing Baudrate Timer ``` -The Baudrate is calculated (based on SIO_BAUD, and on Factor in SIO_MODE):
+The Baudrate is calculated (based on SIO\_BAUD, and on Factor in SIO\_MODE):
``` BitsPerSecond = (44100Hz*300h) / MIN(((Reload*Factor) AND NOT 1),Factor) ``` -#### SIO_TX_DATA Notes +#### SIO\_TX\_DATA Notes The hardware can hold (almost) 2 bytes in the TX direction (one being currently transferred, and, once when the start bit was sent, another byte can be stored -in SIO_TX_DATA). When writing to SIO_TX_DATA, both SIO_STAT.0 and SIO_STAT.2 -become zero. As soon as the transfer starts, SIO_STAT.0 becomes set (indicating -that one can write a new byte to SIO_TX_DATA; although the transmission is +in SIO\_TX\_DATA). When writing to SIO\_TX\_DATA, both SIO\_STAT.0 and SIO\_STAT.2 +become zero. As soon as the transfer starts, SIO\_STAT.0 becomes set (indicating +that one can write a new byte to SIO\_TX\_DATA; although the transmission is still busy). As soon as the transfer of the most recently written byte ends, -SIO_STAT.2 becomes set.
+SIO\_STAT.2 becomes set.
-#### SIO_RX_DATA Notes +#### SIO\_RX\_DATA Notes The hardware can hold 8 bytes in the RX direction (when receiving further byte(s) while the RX FIFO is full, then the last FIFO entry will by overwritten -by the new byte, and SIO_STAT.4 gets set; the hardware does NOT automatically +by the new byte, and SIO\_STAT.4 gets set; the hardware does NOT automatically disable RTS when the FIFO becomes full).
-Data can be read from SIO_RX_DATA when SIO_STAT.1 is set, that flag gets -automatically cleared after reading from SIO_RX_DATA (unless there are still +Data can be read from SIO\_RX\_DATA when SIO\_STAT.1 is set, that flag gets +automatically cleared after reading from SIO\_RX\_DATA (unless there are still further bytes in the RX FIFO). Note: The hardware does always store incoming data in RX FIFO (even when Parity or Stop bits are invalid).
Note: A 16bit read allows to read two FIFO entries at once; nethertheless, it @@ -113,19 +113,19 @@ FIFO empty flag gets set, but nethertheless, the last byte can be read two more times, but doing further reads returns 00h).
#### Interrupt Acknowledge Notes -First reset I_STAT.8, then set SIO.CTRL.4 (when doing it vice-versa, the +First reset I\_STAT.8, then set SIO.CTRL.4 (when doing it vice-versa, the hardware may miss a new IRQ which may occur immediately after setting -SIO.CTRL.4) (and I_STAT.8 is edge triggered, so that bit can be reset even -while SIO_STAT.9 is still set).
-When acknowledging via SIO_CTRL.4 with the enabled condition(s) in -SIO_CTRL.10-12 still being true (eg. the RX FIFO is still not empty): the IRQ +SIO.CTRL.4) (and I\_STAT.8 is edge triggered, so that bit can be reset even +while SIO\_STAT.9 is still set).
+When acknowledging via SIO\_CTRL.4 with the enabled condition(s) in +SIO\_CTRL.10-12 still being true (eg. the RX FIFO is still not empty): the IRQ does trigger again (almost) immediately (it goes off only for a very short -moment; barely enough to allow I_STAT.8 to sense a edge).
+moment; barely enough to allow I\_STAT.8 to sense a edge).
-#### SIO_BAUD Notes -Timer reload occurs when writing to SIO_BAUD, and, automatically when the +#### SIO\_BAUD Notes +Timer reload occurs when writing to SIO\_BAUD, and, automatically when the Baudrate Timer reaches zero. There should be two 16bit SIO timers (for TX and -RX), the upper 15bit of one of that timers can be read from SIO_STAT (not sure +RX), the upper 15bit of one of that timers can be read from SIO\_STAT (not sure which one, and no idea if there's a way to read the other timer, too).
Or... maybe there is only ONE timer, and RX/TX are separated only by separate "timer ellapsed" counters, in that case the MUL1 factor won't work properly, @@ -146,7 +146,7 @@ SIO uses I/O Addresses 1F801050h..1F80105Fh, which seem to be organized similar to the Controller/Memory Card registers at 1F801040h..1F80104Fh, though not identical, and with an additional register at 1F80105Ch, which has no corresponding port at 1F80104Ch.
-SIO_BAUD is \ same as for JOY_BAUD, but, \ +SIO\_BAUD is \ same as for JOY\_BAUD, but, \ they are a bit different:
``` JOY_BAUD is multiplied by Factor, and does then ellapse "2" times per bit. @@ -167,7 +167,7 @@ serial ports, connected to the expansion port,
#### SIO Games The serial port is used (for 2-player link) by Wipeout 2097 (that game -accidently assumes BAUDs based on 64*1024*1025 Hz rather than on 600h*44100 +accidently assumes BAUDs based on 64\*1024\*1025 Hz rather than on 600h\*44100 Hz).
Ridge Racer Revolution is also said to support 2P link.
Keitai Eddy seems to allow to connect a mobile phone to the SIO port (the games diff --git a/soundprocessingunitspu.md b/soundprocessingunitspu.md index 7dfa817..c3550af 100644 --- a/soundprocessingunitspu.md +++ b/soundprocessingunitspu.md @@ -79,7 +79,7 @@ The SPU is connected to a 16bit databus. 8bit/16bit/32bit reads and 16bit/32bit writes are implemented. However, 8bit writes are NOT implemented: 8bit writes to ODD addresses are simply ignored (without causing any exceptions), 8bit writes to EVEN addresses are executed as 16bit writes (eg. "movp r1,12345678h, -movb [spu_port],r1" will write 5678h instead of 78h).
+movb [spu\_port],r1" will write 5678h instead of 78h).
@@ -89,7 +89,7 @@ totally unsupported; leaving apart that one can write uncompressed 16bit PCM samples to the Reverb Buffer, which can be then output at 22050Hz, as long as they aren't overwritten by the hardware).
-#### 1F801C06h+N*10h - Voice 0..23 ADPCM Start Address (R/W) +#### 1F801C06h+N\*10h - Voice 0..23 ADPCM Start Address (R/W) This register holds the sample start address (not the current address, ie. the register doesn't increment during playback).
``` @@ -98,7 +98,7 @@ register doesn't increment during playback).
Writing to this register has no effect on the currently playing voice.
The start address is copied to the current address upon Key On.
-#### 1F801C0Eh+N*10h - Voice 0..23 ADPCM Repeat Address (R/W) +#### 1F801C0Eh+N\*10h - Voice 0..23 ADPCM Repeat Address (R/W) If the hardware finds an ADPCM header with Loop-Start-Bit, then it copies the current address to the repeat addresss register.
If the hardware finds an ADPCM header with Loop-Stop-Bit, then it copies the @@ -162,7 +162,7 @@ two sample rates, and, XA doesn't support looping.
## SPU ADPCM Pitch -#### 1F801C04h+N*10h - Voice 0..23 ADPCM Sample Rate (R/W) (VxPitch) +#### 1F801C04h+N\*10h - Voice 0..23 ADPCM Sample Rate (R/W) (VxPitch) ``` 0-15 Sample rate (0=stop, 4000h=fastest, 4001h..FFFFh=usually same as 4000h) ``` @@ -328,7 +328,7 @@ overflow, which has been a hardware glitch on the SNES).
## SPU Volume and ADSR Generator -#### 1F801C08h+N*10h - Voice 0..23 Attack/Decay/Sustain/Release (ADSR) (32bit) +#### 1F801C08h+N\*10h - Voice 0..23 Attack/Decay/Sustain/Release (ADSR) (32bit) ``` ____lower 16bit (at 1F801C08h+N*10h)___________________________________ 15 Attack Mode (0=Linear, 1=Exponential) @@ -357,8 +357,8 @@ and switches from Sustain to Release when the software sets the Key OFF flag.
``` 15 Must be zero (0=Volume Mode) @@ -408,7 +408,7 @@ ability to convert stereo CD output to mono, or to swap left/right channels).
-#### 1F801C0Ch+N*10h - Voice 0..23 Current ADSR volume (R/W) +#### 1F801C0Ch+N\*10h - Voice 0..23 Current ADSR volume (R/W) ``` 15-0 Current ADSR Volume (0..+7FFFh) (or -8000h..+7FFFh on manual write) ``` @@ -420,13 +420,13 @@ overwrite the setting (from another internal register) whenever applying a new Step?!
#### 1F801DB8h - Current Main Volume Left/Right -#### 1F801E00h+voice*04h - Voice 0..23 Current Volume Left/Right +#### 1F801E00h+voice\*04h - Voice 0..23 Current Volume Left/Right ``` 0-15 Current Volume Left (-8000h..+7FFFh) 16-31 Current Volume Right (-8000h..+7FFFh) ``` These are internal registers, normally not used by software (the Volume -settings are usually set via Ports 1F801D80h and 1F801C00h+N*10h).
+settings are usually set via Ports 1F801D80h and 1F801C00h+N\*10h).
#### Note Negative volumes are phase inverted, otherwise same as positive.
@@ -834,7 +834,7 @@ vIIR works only in range -7FFFh..+7FFFh. When set to -8000h, the multiplication by -8000h is still done correctly, but, the final result (the value written to memory) gets negated (this is a pretty strange feature, it is NOT a simple overflow bug, it does affect the "+[mLSAME-2]" addition; although that part -normally shouldn't be affected by the "*vIIR" multiplication). Similar effects +normally shouldn't be affected by the "\*vIIR" multiplication). Similar effects might (?) occur on some other volume registers when they are set to -8000h.
#### Speed of Sound diff --git a/timers.md b/timers.md index 2aa1640..04227ee 100644 --- a/timers.md +++ b/timers.md @@ -1,5 +1,5 @@ # Timers -#### 1F801100h+N*10h - Timer 0..2 Current Counter Value (R/W) +#### 1F801100h+N\*10h - Timer 0..2 Current Counter Value (R/W) ``` 0-15 Current Counter value (incrementing) 16-31 Garbage @@ -9,7 +9,7 @@ it to any value). It gets forcefully reset to 0000h on any write to the Counter Mode register, and on counter overflow (either when exceeding FFFFh, or when exceeding the selected target value).
-#### 1F801104h+N*10h - Timer 0..2 Counter Mode (R/W) +#### 1F801104h+N\*10h - Timer 0..2 Counter Mode (R/W) ``` 0 Synchronization Enable (0=Free Run, 1=Synchronize via Bit1-2) 1-2 Synchronization Mode (0-3, see lists below) @@ -48,7 +48,7 @@ the Mode register, and becomes inverted on each IRQ (in one-shot mode, it remains zero after the IRQ) (in repeat mode it inverts Bit10 on each IRQ, so IRQ4/5/6 are triggered only each 2nd time, ie. when Bit10 changes from 1 to 0).
-#### 1F801108h+N*10h - Timer 0..2 Counter Target Value (R/W) +#### 1F801108h+N\*10h - Timer 0..2 Counter Target Value (R/W) ``` 0-15 Counter Target value 16-31 Garbage diff --git a/unpredictablethings.md b/unpredictablethings.md index 8723fd2..3dffcec 100644 --- a/unpredictablethings.md +++ b/unpredictablethings.md @@ -42,9 +42,9 @@ Whereas,
(i16) write full 16bits (ignored if address isn't halfword-aligned) CROP write only lower 16bit (and leave upper 16bit unchanged) ``` -It's somewhat "legit" to use 16bit writes on 16bit registers like RAM_SIZE, -I_STAT, I_MASK, and Timer 0-2.
-Non-4-byte aligned 8bit/16bit writes to RAM_SIZE do crash (probably because the +It's somewhat "legit" to use 16bit writes on 16bit registers like RAM\_SIZE, +I\_STAT, I\_MASK, and Timer 0-2.
+Non-4-byte aligned 8bit/16bit writes to RAM\_SIZE do crash (probably because the "(w32)" effect is left-shifting the value, so lower 8bit become zero).
Results on unaligned I/O port writes (via SWL/SWR opcodes) are unknown.
@@ -103,7 +103,7 @@ assembler not to destroy that register behind your back.
The PSX Kernel uses "Full-Decrementing-Wasted-Stack", where "Wasted" means that when calling a sub-function with N parameters, then the caller must pre-allocate N works on stack, and the sub-function may freely use and destroy -these words; at [SP+0..N*4-1].
+these words; at [SP+0..N\*4-1].
#### Locked Locations in Memory and I/O Area ``` @@ -130,7 +130,7 @@ locked regions are same as for first 512MB of KUSEG.
``` 1F80108Ch+N*10h - D#_CHCR Mirrors - (N=0..6, for DMA channel 0..6) ``` -Read/writeable mirrors of DMA Control registers at 1F801088h+N*10h.
+Read/writeable mirrors of DMA Control registers at 1F801088h+N\*10h.
#### Garbage Locations in I/O Area ```