The system card
The PC-Engine's system card offers a lot of functions to handle the CD-ROM and
other parts of the hardware. All of these functions are available through a jump-table
at $E000. To call a system function, just multiply it's number by 3 and add $E000.
This documentation has a list of all known functions and a short description.
I'm not able to cover ALL functions, because I've got to do some reverse-engineering
to get the information, or I've got to wait until one of the Develo-owners tell
me the information. Everything I say here refers to system-card 3.0.
The functions may destroy the registers, and some functions use the zeropage
to store information. Here are a few important addresses:
$20F3 |
Current VDC register selected |
$20F7 |
Value of VDC reg #5 (Control Register) |
$20F8 |
al |
$20F9 |
ah |
$20FA |
bl |
$20FB |
bh |
$20FC |
cl |
$20FD |
ch |
$20FE |
dl |
$20FF |
dh |
$2214/$2215 |
Used for EX SPRDMA, written to VDC reg #19 (Sprite Attribute table). |
$2227 |
joyena - disable/enable each of the 5 joypads |
$2228-$222C |
joy |
$222D-$2232 |
joytrg |
$2243 |
Value of VDC reg #15 (DMA-Control) |
CD-ROM related functions
CD_BOOT, Function #$00
Brings you to the CD-ROM start-up screen.
CD_RESET, Function #$01
CD_BASE, Function #$02
zeo :
- IN
- [bh] type of setting
- [$00]
- Use value in al:ah:bl in LBA mode as address
- [$40] (rather 6th bit set)
- Use value in al:ah:bl in MSF mode as address
- else
- Use address of beginning of track number al
- [ch] code beginning to set
if 0th bit
of ch is set (ch & 1 != 0 ), skip setting 1st code track address
if 1th bit of ch is set (ch & 2 != 0 ), skip setting 2nd code track
address
- OUT
CD_READ, Function #$03
zeo : blockload address is relative to the first sector of the code track
- IN
- [cl] blockadr >> 16 load start record no. of CD
- [ch] (blockadr >> 8) & 255
- [dl] blockadr & 255
- [dh] Destination data address type
- [$00] ?
- [$01] local
- [bx] address
- [al] number of blocks
- [$02-$06] MPR #
- [bl] Bank #
- [al] number of blocks
- [$FE] VRAM
- [$FF] VRAM
- [bx] address
- [al] number of blocks
- OUT
Load data from CD
CD_SEEK, Function #$04
CD_EXEC, Function #$05
- IN
- [cl] blockadr >> 16 load start record no. of CD
- [ch] (blockadr >> 8) & 255
- [dl] blockadr & 255
- [dh] Destination data address type
- [$01] local
- [bx] address
- [al] number of blocks
- OUT
Load code from CD, load s with $FF and jump to the address contained in bx.
CD_PLAY, Function #$06
- IN
- [bh] mode (only two upper bits used)
- [$?0] Play from # to #
- [al] start minutes (BCD)
- [ah] start seconds (BCD)
- [bl] start frames (BCD)
- [cl] stop minutes (BCD)
- [ch] stop seconds (BCD)
- [dl] stop frames (BCD)
- [$80] Play track #
- [al] track # (BCD)
- OUT
Play an audio track.
CD_SEARCH, Function #$07
CD_PAUSE, Function #$08
CD_STAT, Function #$09
CD_SUBQ, Function #$0A
- IN
- [bx] address of a buffer (zeo)
- OUT
- (zeo) certainly fill the buffer
- 0th byte -> 'PAUSED?' boolean
- following -> unknown
CD_DINFO, Function #$0B
- IN
- [bx] address of a 4 byte buffer
- [ah] track # (BCD)
- [al] Command
- [$00] return the number of tracks (zeo) (of course, ah value
is ignored)
- [0] number of first track (BCD)
- [1] number of last track (BCD)
- [$01] return the disk length (zeo) (here again, ah value is
ignored)
- [0] minutes (BCD)
- [1] seconds (BCD)
- [2] frames (BCD)
- [$02] return the track position as follows:
- [0] minutes (BCD)
- [1] seconds (BCD)
- [2] frames (BCD)
- [3] (unknown, maybe track ID number (zeo : content type ID)
)
- OUT
Get information about a given track.
CD_CONTNTS, Function #$0C
CD_SUBRQ, Function #$0D
Read the Q sub-channel
ZEO : Test the 4th bit of the byte at $1803, if set, set the carry flag
else
clear it and A = ($227E ) = ($1807).
CD_PCMRD, Function #$0E
- IN
- [reg A] (send to $1805 (zeo))
- OUT
- [reg X] (value from $1805)
- [reg Y] (value from $1806)
- [reg A] error status (in fact, 1st bit of $1803)
CD_FADE, Function #$0F
- IN
- [reg A] mode
- [$00] Cancel fade out
- [$08] PCM fade out (6.0 sec)
- [$0A] ADPCM fade out (6.0 sec)
- [$0C] PCM fade out (2.5 sec)
- [$0E] ADPCM fade out (2.5 sec)
- OUT
Begin or cancel linear PCM or ADPCM fade out
ADPCM related functions
AD_RESET, Function #$10
Reset the ADPCM controller.
AD_TRANS, Function #$11
Zeo:
- IN
- [bx]: Buffer address (destination)
- [dh]: Boolean (if false, don't set the buffer address else change the
buffer address to bx)
- [cl]: blockadr >> 16 load start record no. of CD
- [ch]: (blockadr >> 8) & 255
- [dl]: blockadr & 255
- [al]: number of block to read
- OUT
AD_READ, Function #$12
- IN
- CX: ADPCM buffer address
- DH: Destination data address type
- $00: Local
- $FF: VRAM
- $02-$06: MPR #
- BL: addr low bits
- BH: addr high bits
- AX: data size in bytes
- OUT
- reg A = error status
- $00: operation success
- other: error
Read data from ADPCM to memory Notes: When reading into VRAM, $2272 (VDTIN FLG)
becomes 1.
AD_WRITE, Function #$13
- IN
- CX: ADPCM buffer address
- DH: Destination data address type
- $00: Local
- $FF: VRAM
- $02-$06: MPR #
- BL: addr low bits low bits Bank # ($80-$87)
- BH: addr high bits high bits Not Used
- AX: data size in bytes
- OUT
- reg A = error status
- $00: operation success
- other: error
Write to ADPCM buffer from memory. Notes: When reading into VRAM, $2272 (VDTIN
FLG) becomes 1.
AD_PLAY, Function #$14
- IN
- BX: ADPCM buffer playback start address (START)
- AX: Size of data to playback in bytes (LENGTH)
- DH: Sampling rate (range: $00-$0E) (RATE) kHz = 32 / (16 - DH)
- DL: Mode
- [bit 0] Counter Mode
- 0: Set START, LENGTH, and RATE
- 1: Playback using previous START, LENGTH, and RATE
- [bit 7] Play Mode
- OUT
- [reg A] error status
- [$00] no error
- [other] error
Playback a section of data from ADPCM buffer. Notes: An error will occur if AD_PLAY
is called during playback of AD_PCM. Before executing, call AD_STOP to halt the
current playback followed by AD_STAT to confirm that playback has stopped.
AD_CPLAY, Function #$15
AD_STOP, Function #$16
Stop playback of ADPCM buffer data.
AD_STAT, Function #$17
- IN
- OUT
- [reg A] State of ADPCM controller
- [$00] ADPCM not busy (end or not playing)
- [other] ADPCM busy
- [reg X] ADPCM buffer and playback state
- [$00] Playback in progress and more than half of the buffer data is
remaining.
- [$01] Playback halted
- [$04] Playback in progress and less than half of the buffer data is
remaining.
Read the state of the ADPCM controller
Backup memory related functions
BM_FORMAT, Function #$18
- IN
- AX pointer to the string "!BM FORMAT!"
- OUT
- reg A: = error status
- $00: no error
- $01: string wrong
- other: error
This function is used to "format" the backup RAM. To avoid an accidental call
to this function, you have got to give a pointer to the string "!BM FORMAT!" in
ax. Otherwise it returns with A=1. When it's formatted, the BM_looks like this:
$8000 |
"HUBM" |
$8004 |
end-address of BM, $A000 if everything went OK |
$8006 |
value $8010 first free entry ? memory used ? |
$8010 |
value $0000 |
Note: All the functions dealing with BM return A=FF, when the string "HUBM" is
missing !
BM_FREE, Function #$19
- IN
- OUT
- CX: amount of free space in BM
Returns the free space in the BM.
BM_READ, Function #$1A
BM_WRITE, Function #$1B
BM_DELETE, Function #$1C
BM_FILES, Function #$1D
Misc. functions
EX_GETVER, Function #$1E
- IN
- OUT
- reg X: Major number
- reg Y: Minor number
This function returns the version number of the system card.
EX_SETVEC, Function #$1F
EX_GETFNT, Function #$20
EX_JOYSNS, Function #$21
Reads all 5 joystick values and checks, if "Run"+"Select" is pressed. The joystick
values are stored in $2228, $222D and $2232.
EX_JOYREP, Function #$22
This does directly point to a RTS instruction.
EX_SCRSIZ, Function #$23
EX_DOTMOD, Function #$24
EX_SCRMOD, Function #$25
EX_IMODE, Function #$26
- IN
- [reg A] value to inform the auto increment value
- [$00] auto increment by +1
- [$01] auto increment by +32
- [$02] auto increment by +64
- [$03] auto increment by +128
- OUT
This function change the value of the auto increment value (the value the pointer
in advanced after a Video RAM Read/Write). It updates $20F7 with #5.
EX_VMODE, Function #$27
EX_HMODE, Function #$28
EX_VSYNC, Function #$29
EX_RCRON, Function #$2A
This function sets bit 2 in VDC reg #5 and updates $20F3 and $20F7.
EX_RCROFF, Function #$2B
This function clears bit 2 in VDC reg #5 and updates $20F3 and $20F7.
EX_IRQON, Function #$2C
This function sets bit 3 in VDC reg #5 and updates $20F3 and $20F7.
EX_IRQOFF, Function #$2D
This function clears bit 3 in VDC reg #5 and updates $20F3 and $20F7.
EX_BGON, Function #$2E
This function sets bit 7 in $20F3. It does not update the VDC reg #5!
EX_BGOFF, Function #$2F
This function clears bit 7 in $20F3. It does not update the VFC reg #5!
EX_SPRON, Function #$30
This function sets bit 6 in $20F3. It does not update the VDC reg #5!
EX_SPROFF, Function #$31
This function clears bit 6 in $20F3. It does not update the VDC reg #5!
EX_DSPON, Function #$32
This function sets bit 6+7 in $20F3. It does not update the VDC reg #5!
EX_DSPOFF, Function #$33
This function clears bit 6+7 in $20F3. It does not update the VDC reg #5!
EX_DMAMOD, Function #$34
This functions sets VDC reg #15 and updates the value in $2243.
EX_SPRDMA, Function #$35
Copies the word form $2214/5 to VDC reg #19 (Sprite Attribute Table).
EX_SATCLR, Function #$36
EX_SPRPUT, Function #$37
EX_SETRCR, Function #$38
- IN
- reg A: low byte
- reg X: high byte
- OUT
This function sets the VDC reg #6 (Raster Counter Register).
EX_SETRED, Function #$39
- IN
- reg A: low byte
- reg X: high byte
- OUT
This function sets the VDC reg #1 (Memory Address Read).
EX_SETWRT, Function #$3A
- IN
- reg A: low byte
- reg X: high byte
- OUT
This function sets the VDC reg #0 (Memory Address Write).
EX_SETDMA, Function #$3B
EX_BINBCD, Function #$3C
EX_BCDBIN, Function #$3D
EX_RND, Function #$3E
Math functions
(When writing an emulator it may be interesting to trap these functions, and to
execute them native.)
MA_MUL8U, Function #$3F
MA_MUL8S, Function #$40
MA_MUL16U, Function #$41
MA_DIV16S, Function #$42
MA_DIV16U, Function #$43
MA_SQRT, Function #$44
MA_SIN, Function #$45
MA_COS, Function #$46
MA_ATNI, Function #$47
Additional functions
PSG BIOS, Function #$48
This is an incomplete list of the PSG-BIOS functions. This group of functions
is independent from the "main" list of functions. The function to call is indicated
by dh, and an additional parameter is in al. That's everything I know about these
functions.
(When writing an emulator it may be interesting to trap these functions, and
to output the data to a MIDI-device or MIDI-file. Should be cool with a wavetable
card.)
PSG_ON, Function #$0
PSG_OFF, Function #$1
PSG_INIT, Function #$2
PSG_BANK, Function #$3
PSG_TRACK, Function #$4
PSG_PLAY, Function #$0B
PSG_MSTAT, Function #$0C
PSG_ASTOP, Function #$10
PSG_FDOUT, Function #$13
GRP_BIOS, Function #$49
KEY_BIOS, Function #$4A
PSG_DRIVE, Function #$4B
EX_COLORC, Function #$4C
MA_MUL16S, Function #$4F (zeo)
MA_CBASIS, Function #$50 (zeo)
- IN
- AL : value to convert
- BL : new basis
- OUT
- CL : high digit of AL in the new basis
- DL : lowdigit of AL in the new basis
This function try to convert a value into a new basis. Whatever the values,
the following egality remains : AL = DL + CL * BL
If CL < BL, CL and DL are really the new representation of AL in basis BL.
For example, AL = 39 and BL = 16 will return CL = 2 and DL = 7, because hexadecimal
representation of 39 (decimal) is 27 (hexa)