Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
user_program_interface [2016/05/23 15:39] ex_writer [User Program Interface] |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== User Program Interface ====== | ||
- | The User Program Interface (UPI) is a set of procedures and conventions used by a cartridge program to access the facilities provided by the Bally Arcade's [[system rom|operating system]]. | ||
- | For details on the UPI's usage, see [[UPI Conventions]]. | ||
- | |||
- | The basic rule for using the UPI is: With exception to the system [[glossary#d|DOPE vector]], no cartridge should ever address [[system ROM]] directly or expect a given cell to always equal a certain value. | ||
- | |||
- | The mechanism for calling a system routine is: | ||
- | <code z80> | ||
- | RST 56 | ||
- | DB (routine # + option) | ||
- | </code> | ||
- | The routine number is an even number specifying which subroutine to transfer to. Symbolic identifiers, which are equated to routine numbers, are provided in [[HVGLIB]]. | ||
- | |||
- | Option specifies how arguments are passed to the system routine. If option equals zero, the arguments are presumed to exist in CPU registers; if option equals 1, the arguments are taken to follow in line after the routine number/option byte. These arguments are loaded into the CPU registers automatically before the called routine is entered. The arguments required by each system routine are given in the routine's detail documentation. | ||
- | ===== SYSTEM and SYSSUK ===== | ||
- | |||
- | The SYSTEM macro generates the system routine call with option = 0: | ||
- | <code> | ||
- | SYSTEM (routine #) | ||
- | </code> | ||
- | Example: | ||
- | <code z80> | ||
- | SYSTEM FILL | ||
- | </code> | ||
- | |||
- | The SYSSUK macro generates the system routine call with option = 1: | ||
- | <code> | ||
- | SYSSUK (routine #) | ||
- | </code> | ||
- | |||
- | ===== The Interpreter ===== | ||
- | Frequently it is desirable to string several system routine calls together. If four or more calls follow in sequence, it is more efficient to use the interpreter, because it voids the overhead of the RST 56 instruction. | ||
- | |||
- | Special call indexes INTPC and EXIT are used to enter and exit interpretive mode, respectively. | ||
- | |||
- | Example: | ||
- | <code z80> | ||
- | SYSTEM INTPC ;BEGIN INTERPRETING | ||
- | DO FILL ;DO FILL ROUTINE | ||
- | DW NORMEM ;START AT TOP OF SCREEN | ||
- | DW 92*BYTEPL ;CONTINUE FOR 92 LINES | ||
- | DB 0 ;FILL WITH ZEROES | ||
- | DO CHRDIS ;DO CHARACTER DISPLAY ROUTINE | ||
- | DB 0 ;CHARACTER Y-COORDINATE | ||
- | DB 10 ;CHARACTER X-COORDINATE | ||
- | DB 8 ;OPTIONS-PLOP, 10-ON, 00-OFF | ||
- | DB 'A' ;CHARACTER TO DISPLAY | ||
- | EXIT ;EXIT INTERPRETER | ||
- | </code> | ||
- | |||
- | |||
- | |||
- | ===== System Routine Conventions ===== | ||
- | A system routine is coded like a conventional machine language subroutine, except that output parameters are not passed through registers but through the context block. | ||
- | |||
- | The context block is created by the RST 56 call. The user's register set (AF, BC, DE, HL, IX, IY) is pushed onto the stack. Register IY is set to point at this stack frame. Thus a copy of the input arguments exists in RAM, which the system routine may refer to as needed. These arguments are also present in the registers when the system routine is entered, so it is only necessary to refer to the context block when one has clobbered an input argument. | ||
- | |||
- | An output argument is returned to the caller by setting it in the context block. If a register was changed, but the associated cell in the context block was not, then the register will have its old value on return. Thus a system routine is free to use any of the registers it needs without worrying about saving and restoring. The user can also assume that no registers will change except those defined as returning an output argument. | ||
- | |||
- | ==== Context Block Format ==== | ||
- | |||
- | The following illustration describes the context block and equates provided in [[HVGLIB]] for each field. | ||
- | |||
- | {{cb_format.png}} | ||
- | |||
- | The UPI uses four tables in the control transfer process. The first two tables give the routine's starting address indexed via call number. The systems table is named SYSDPT. The user may extend this table by storing the address of their extended table into USERTB, USERTB+1. This address should point 128 bytes before the first entry. | ||
- | |||
- | The remaining two tables describe, if specified, the inline arguments a call expects. This table gives a one-byte bitstring, also indexed via call number. The systems name is MRARGT. The user's address is in UMARGT. UMARGT must point 64 bytes ahead. Arguments must follow the call in a specified order. | ||
- | |||
- | Note that the context contains additional information not shown. This information exists both above and below the context. User programs should never use this information or even assume that it exists. The user should only address this area by using IY. | ||
- | ==== Inline Argument Mask Table Entry ==== | ||
- | |||
- | If optioned (i.e., bit 0 of call index is set), the Macro Routine Argument Table (MRARGT) is indexed giving a mask which specifies how to transfer inline arguments into the context block. The mask is formatted as follows: | ||
- | |||
- | {{mask_table.png}} | ||
- | |||
- | Arguments must follow the call index in the following order (if an argument isn't specified, it is omitted.): | ||
- | |||
- | <code>(INDEX), IXL, IXH, E, D, C, B, A, L, H</code> | ||
- | |||
- | Registers that are not defined as containing output parameters will not change. | ||
- | |||
- | All UPI routines are [[glossary#r|reentrant]]. | ||
- | |||
- | ==== Custom System Routines ==== | ||
- | |||
- | The user is responsible for storing the addresses of these tables into dedicated system RAM cells. | ||
- | |||
- | The UPI has been extended to support user-provided system routines. If the interpreter encounters a negative call index, and 'suck inline' is optioned, the user's macro routine address table (USERMT) and argument table (UMARGT) are used. The User Macro Routine Argument Table (UMARGT) is indexed for a parameter mask. The address of this table is assumed to be in (UMARGT),(UMARGT+1). This pointer should point 64 bytes before the first real entry. | ||
- | |||
- | [**Note:** Section needs clarification. Does the source listing have the wrong labels listed??] | ||
- | |||
- | Example: | ||
- | <code z80> | ||
- | LD HL,USERMT-64 ; WHERE USERMT POINTS AT | ||
- | LD (UMARGT),HL | ||
- | </code> | ||
- | |||
- | [NM:2-7, source listing p. 20] | ||
- | |||
- | |||
- | ---- | ||
- | ===== UPI System Routines ===== | ||
- | |||
- | Undocumented routines are marked with an asterisk (*) | ||
- | |||
- | ^ Name ^ Description ^ | ||
- | | [[user program interface#exit|EXIT]] | Exit interpreter (with context) | | ||
- | | [[user program interface#intpc|INTPC]] | Begin interpreting | | ||
- | | [[user program interface#mcall|MCALL]] | "Macro Call" - Call an interpreter sequence as a subroutine | | ||
- | | [[user program interface#mjump|MJUMP]] | "Macro Jump" - Current interpretive PC is set to the contents of HL | | ||
- | | [[user program interface#mret|MRET]] | "Macro Return" from interpreter subroutine | | ||
- | | [[user program interface#rcall|RCALL]] | "Real Call" - Call any assembly language subroutine from the interpreter | | ||
- | | [[user program interface#suck|SUCK]]* | Suck inline arguments into context block | | ||
- | | [[user program interface#xintc|XINTC]] | Exits interpreter (same as EXIT) | | ||
- | |||
- | ===== UPI System Routine Descriptions ===== | ||
- | |||
- | ==== EXIT ==== | ||
- | |||
- | EXIT INTERPRETER | ||
- | |||
- | | Calling Sequence: | <code z80>EXIT</code> | | ||
- | | Arguments: | None | | ||
- | | Description: | This code causes the interpreter to exit. Execution of machine instructions proceeds at the following location. | | ||
- | | Restrictions: | This routine should only be called using the interpreter. A direct system call would produce unpredictable (and catastrophic) results. | | ||
- | |||
- | ==== INTPC ==== | ||
- | |||
- | BEGIN INTERPRETING | ||
- | |||
- | | Calling Sequence: | <code z80>SYSTEM INTPC</code> | | ||
- | | Arguments: | None | | ||
- | | Notes: | None | | ||
- | | Description: | See above for explanation of interpreter | | ||
- | |||
- | ==== MCALL ==== | ||
- | |||
- | CALL INTERPRETER SUBROUTINE | ||
- | |||
- | | Calling Sequence: | <code z80>SYSTEM MCALL</code> or <code z80>SYSSUK RCALL | ||
- | DW (routine address)</code>| | ||
- | | Arguments: | HL = address of subroutine | | ||
- | | Notes: | None | | ||
- | | Description: | MCALL calls an interpreter sequence as a subroutine. MCALL may be used from machine language as well as within an interpreted sequence. Calls may be nested infinitely, limited only by stack space (4 bytes per call).\\ \\ To exit the interpreted subroutine, use MRET. | | ||
- | | Restrictions: | None | | ||
- | |||
- | Example: | ||
- | <code z80> | ||
- | SYSSUK MCALL | ||
- | DW ZAPALL | ||
- | . | ||
- | . | ||
- | . | ||
- | ZAPALL: DO FILL+1 ;DO FILL | ||
- | DW NORMEM | ||
- | DW 0FFFH | ||
- | DB 0 | ||
- | DO MRET ;GO BACK TO CALLER</code> | ||
- | ==== MJUMP ==== | ||
- | |||
- | INTERPRETER JUMP | ||
- | |||
- | | Calling Sequence: | <code z80>DO MJUMP</code> or <code z80>DONT MJUMP | ||
- | DW (jump address)</code>| | ||
- | | Arguments: | HL = jump address | | ||
- | | Notes: | None | | ||
- | | Description: | The current interpretive program counter is set to the contents of HL. The next instruction is fetched from that address. | | ||
- | | Restrictions: | MJUMP must be called from the interpreter. The targets of all jumps must also be interpreted sequences. | | ||
- | |||
- | Example: | ||
- | <code z80> | ||
- | SYSTEM INTPC ;ENTER INTERPRETER | ||
- | . | ||
- | . | ||
- | . | ||
- | DO MJUMP ;JUMP TO | ||
- | DW END ;END OF INTERPRETER ROUTINE | ||
- | . | ||
- | . | ||
- | . | ||
- | END: DB XINTC ;EXIT INTERPRETER</code> | ||
- | ==== MRET ==== | ||
- | |||
- | RETURN FROM INTERPRETIVE SUBROUTINES | ||
- | |||
- | | Calling Sequence: | <code z80>DO MRET</code>| | ||
- | | Arguments: | None | | ||
- | | Notes: | None | | ||
- | | Description: | MRET causes execution to proceed at the instruction following the corresponding [[user program interface#mcall|MCALL]] instruction. | | ||
- | | Restrictions: | None | | ||
- | ==== RCALL ==== | ||
- | |||
- | CALL ASSEMBLY LANGUAGE SUBROUTINE | ||
- | |||
- | | Calling Sequence: | <code z80>DO RCALL</code> or <code z80>DONT RCALL | ||
- | DW (routine address)</code>| | ||
- | | Arguments: | HL = address of routine to call | | ||
- | | Notes: | None | | ||
- | | Description: | RCALL may be used to call any assembly language subroutine from the interpreter. When the subroutine returns, interpretation proceeds at the next instruction.\\ \\ When the assembly language routine receives control, HL will point at the routine's starting address; the other registers will contain their current values. Any changes made to the register set by the subroutine will not be passed along.\\ \\ To pass an output parameter, the subroutine must alter the context block, which is pointed at by IY. | | ||
- | | Restrictions: | Assembler routine must not destroy IY. | | ||
- | |||
- | Example: | ||
- | <code z80> | ||
- | SYSTEM INTPC | ||
- | . | ||
- | . | ||
- | . | ||
- | DO RCALL | ||
- | DW CLRAC | ||
- | . | ||
- | . | ||
- | . | ||
- | EXIT | ||
- | . | ||
- | . | ||
- | . | ||
- | CLRAC: XOR A | ||
- | RET</code> | ||
- | |||
- | ==== SUCK ==== | ||
- | |||
- | SUCK INLINE ARGUMENTS | ||
- | |||
- | | Calling Sequence: | <code z80>?? SUCK</code>| | ||
- | | Arguments: | B = Argument load mask | | ||
- | | Output: | HL = Updated Program Counter | | ||
- | | Notes: | Definition from source listing p. 21 | | ||
- | | Description: | This routine implements a macro load instruction. It is used by the interpreter as well. A one bit in the inline load mask means 'transfer the next inline byte'; A zero bit means 'advance context block pointer.' | | ||
- | | Restrictions: | None | | ||
- | |||
- | |||
- | ==== XINTC ==== | ||
- | |||
- | See [[user program interface#exit|EXIT]]. |