The system ROM in an ORGANISER MKII occupies the memory map between $8000 and $FFFF. The ROM is divided into a number of functional areas:
This document is mainly concerned with describing the facilities provided by the operating system to application programmers. Both the OPL language and the applications (e.g. the diary) call the operating system via the standard operating system interface.
5.1 SYSTEM INTERFACE
5.1.1 CALLING SYSTEM SERVICES
The interface to the operating system is via the SWI hardware instruction followed by the vector number of the operating system service required, i.e.
SWI ; software interrupt .BYTE VECTOR_NUMBER ; required service vector HERE:
After execution of the SWI call, execution continues after the byte containing the vector number, at the label HERE in the example above.
Parameters to the service are passed in one or more of the A,B (or D), and X registers and for a small number of services in memory locations UTW_S0 and UTW_S1 which are zero page locations. Certain services also require information in the runtime buffer RTT_BF. The description of each service details the information required to be passed to it. In addition the results of a system service are returned in the machine registers A,B (or D) or X as required. The addresses of UTW_S0 and UTW_S1 are described in chapter 6.
5.1.2 REGISTER PRESERVATION
In general it should be assumed that all registers (A,B and X) are trashed by system services. If this is not the case then the system service description will explicitly state which registers are preserved.
5.1.3 ERROR HANDLING
All system services which indicate that they have error returns may set the carry flag on exit from the system service and return the error code in the B register. Note that system services such as KB$GETK, which do not return any errors, may not clear the carry flag.
5.1.4 THE OS MACRO
Throughout the operating system description examples will be provided which use a macro called OS which is as follows:
.MACRO OS XX .BYTE $3f,XX .ENDM
Using this macro to get a key, for example, will be coded as follows:
and calling a system service which can return an error such as AL$GRAB should be called as follows:
CLR A CLR B OS AL$GRAB BCC 1$ ; HANDLE THE ERROR WHOSE CODE IS IN THE B REGISTER. 1$: ; CALL SUCCESSFUL AND X HAS THE TAG OF THE CELL.
5.1.5 MEMORY USAGE
In the following description refer to chapter 6 for the addresses of the variables described.
The six words of memory storage labelled UTW_S0 to UTW_S5 are a set of scratch variables used by the operating system which any service may trash as required. Thus no values can be held in these words while making a call to an operating system service, although they may be used for storing intermediate values between calls to the operating system.
The seven words of memory storage labelled UTW_R0 to UTW_R6 are a set of fixed variables which are not trashed by the operating system service routines. The service routines actually use these variables but always push their contents on the stack before use and then recover them by popping them off the stack again. Application programs may use these variables as long as they maintain their integrity by pushing and popping.
As a code saving device there is a system service to push and pop these variables as follows:
OS BT$PPRG ; PSH UTW_R0 .BYTE 1 ; INSTRUCTION BYTE TO BT$PPRG ; CAN NOW USE UTW_R0 OS BT$PPRG ; POP UTW_R0 .BYT $81 ; INSTRUCTION BYTE TO BT$PPRG
The byte following the call to BT$PPRG instructs the service whether to push or pop the variables from the stack and which variables to push or pop. The format of the byte is as follows:
Thus if the byte value is $5 then UTW_R2 and UTW_R0 will be pushed.
When pushing, the higher address variables are pushed first and when popping, the lower address variables are popped first. Thus if UTW_R5 and UTW_R2 are pushed and UTW_R2 and UTW_R1 are popped then UTW_R1 will get the old value of UTW_R2 and UTW_R2 will get the old value of UTW_R5.
5.1.6 SYSTEM CONSTANTS AND MACROS
The following is a set of useful constants and macros used in the description of the system services and in the examples.
; ; MBSET MACRO ; =========== ; .MACRO MBSET MASK,ADDR OIM #MASK,ADDR .ENDM MBSET ; ; MBCLR MACRO ; =========== ; .MACRO MBCLR MASK,ADDR AIM #XFF-,ADDR .ENDM MBCLR ; ; MBTGL MACRO ; =========== ; .MACRO MBTGL MASK,ADDR EIM #MASK,ADDR .ENDM ; ; MBTST MACRO ; =========== ; .MACRO MBTST MASK,ADDR TIM #MASK,ADDR .ENDM ; ; CONSTANTS USED BY MPSH AND MPUL MACROS ; ====================================== ; $mtr0 equ 1 $mtr1 equ 2 $mtr2 equ 4 $mtr3 equ 8 $mtr4 equ 16 $mtr5 equ 32 $mtr6 equ 64 ; ; THE MPSH MACRO ; ============== ; .MACRO MPSH P0,P1,P2,P3,P4,P5,P6 $MSK EQU 0 .IF NB $MSK EQU $MSK ! $MT'P0 .IF NB $MSK EQU $MSK ! $MT'P1 .IF NB $MSK EQU $MSK ! $MT'P2 .IF NB $MSK EQU $MSK ! $MT'P3 .IF NB $MSK EQU $MSK ! $MT'P4 .IF NB $MSK EQU $MSK ! $MT'P5 .IF NB $MSK EQU $MSK ! $MT'P6 .ENDC .ENDC .ENDC .ENDC .ENDC .ENDC .ENDC OS BT$PPRG FCB $MSK .ENDM MPSH ; ; THE MPUL MACRO ; ============== ; .MACRO MPUL P0,P1,P2,P3,P4,P5,P6 $MSK EQU 0 .IF NB $MSK EQU $MSK ! $MT'P0 .IF NB $MSK EQU $MSK ! $MT'P1 .IF NB $MSK EQU $MSK ! $MT'P2 .IF NB $MSK EQU $MSK ! $MT'P3 .IF NB $MSK EQU $MSK ! $MT'P4 .IF NB $MSK EQU $MSK ! $MT'P5 .IF NB $MSK EQU $MSK ! $MT'P6 .ENDC .ENDC .ENDC .ENDC .ENDC .ENDC .ENDC OS BT$PPRG FCB X80 ! $MSK .ENDM MPUL ; ; ZERO PAGE PORTS ; =============== ; POB_DDR2 EQU $01 ; PORT 2 DATA DIRECTION REGISTER POB_PORT2 EQU $03 ; PORT 2 DATA REGISTER POB_TCSR1 EQU $08 ; TIMER CONTROL STATUS REGISTER 1 POW_FRC EQU $09 ; FREE RUNNING COUNTER POW_OCR1 EQU $0B ; OUTPUT COMPARE REGISTER 1 POB_TCSR2 EQU $0F ; TIMER 2 CONTROL/STATUS REGISTER POB_RMCR EQU $10 ; RATE MODE CONTROL REGISTER POB_TRCSR EQU $11 ; TX/RX CONTROL STATUS REGISTER POB_RDR EQU $12 ; RECEIVE DATA REGISTER POB_TDR EQU $13 ; TRANSMIT DATA REGISTER POB_RCR EQU $14 ; RAM/PORT 5 CONTROL REGISTER POB_PORT5 EQU $15 ; PORT 5 DATA REGISTER POB_DDR6 EQU $16 ; PORT 6 DATA DIRECTION REGISTER POB_PORT6 EQU $17 ; PORT 6 DATA REGISTER POB_TCSR3 EQU $1B ; TIMER 3 CONTROL/STATUS REGISTER POB_TCONR EQU $1C ; TIMER CONSTANT REGISTER ; ; SEMI-CUSTOM CHIP ADDRESSES ; ========================== ; SCA_LCDCONTROL EQU $0180 ; LCD CONTROL REGISTER SCA_LCDDATA EQU $0181 ; LCD DATA REGISTER SCA_SWITCHOFF EQU $01C0 ; SWITCH OFF SCA_PULSEENABLE EQU $0200 ; PULSE ENABLE SCA_PULSEDISABLE EQU $0240 ; PULSE DISABLE SCA_ALARMHIGH EQU $0280 ; BUZZER ON SCA_ALARMLOW EQU $02C0 ; BUZZER OFF SCA_COUNTERRESET EQU $0300 ; SET COUNTER TO 0 SCA_COUNTERCLOCK EQU $0340 ; CLOCK COUNTER ONCE SCA_NMIMPU EQU $0380 ; ENABLE NMI TO PROCESSOR SCA_NMICOUNTER EQU $03C0 ; ENABLE NMI TO COUNTER ; ; PORT 5 BITS ; =========== ; ONCLR EQU $80 ; ON/CLEAR LINE ACOUT EQU $02 ; ACOUT LINE LOWBATTERY EQU $01 ; LOW BATTERY LINE ; ; PORT 6 BITS ; =========== ; PACON EQU $80 ; PACK VCC ENABLE SIGNAL CS3 EQU $40 ; CHIP SELECT 3 SIGNAL CS2 EQU $20 ; CHIP SELECT 2 SIGNAL CS1 EQU $10 ; CHIP SELECT 1 SIGNAL OE EQU $08 ; OUTPUT ENABLE SIGNAL PGM EQU $04 ; PROGRAM SIGNAL MR EQU $02 ; MASTER RESET SIGNAL CLK EQU $01 ; CLOCK SIGNAL ; ; TCSR1 BITS ; ========== ; EOCI1 EQU $08 ; TIMER 1 INTERRUPT ENABLE ; ; KBB_STAT BITS ; ============= ; KY_SHFT EQU $80 ; SHIFT KY_NUMB EQU $40 ; NUMERIC LOCK KY_CPNM EQU $02 ; CAPS / NUMB FLAG KY_CAPS EQU $01 ; CAPS LOCK ; ; PACK CONTROL DELAYS ; =================== ; PACONDEL EQU 11520 ; FOR 50MS DELAY VPPONDEL EQU 2304 ; FOR 10MS DELAY VPPOFFDEL EQU 46080 ; FOR 200MS DELAY PK_OVERBLOW EQU 5 ; 5*X OVERBLOW ; ; MISCELLANEOUS CONSTANTS ; ======================= ; RAMBASE EQU $2000 ; MACHINE RAM BASE RAMFREE EQU BTT_RAMF ; FIRST FREE RAM BYTE MACHINE_STACK EQU $0100 ; SIZE OF MACHINE STACK MINEVL_STACK EQU $0100 ; MIN. SIZE OF EVALUATOR STACK ALLCELLS EQU 32 ; NUMBER OF ALLOCATOR CELLS PERMCELL EQU 0 ; PERMANENT CELL MENUCELL EQU 1 ; TOP LEVEL MENU CELL DIRYCELL EQU 2 ; DIARY CELL TEXTCELL EQU 3 ; LANGUAGE TEXT CELL SYMBCELL EQU 4 ; SYMBOL TABLE CELL GLOBCELL EQU 5 ; GLOBAL RECORD CELL OCODCELL EQU 6 ; QCODE OUTPUT CELL FSY1CELL EQU 7 ; FIELD NAME SYMBOL TABLE 1 FSY2CELL EQU 8 ; FIELD NAME SYMBOL TABLE 2 FSY3CELL EQU 9 ; FIELD NAME SYMBOL TABLE 3 FSY4CELL EQU 10 ; FIELD NAME SYMBOL TABLE 4 FBF1CELL EQU 11 ; FIELD BUFFER CELL 1 FBF2CELL EQU 12 ; FIELD BUFFER CELL 2 FBF3CELL EQU 13 ; FIELD BUFFER CELL 3 FBF4CELL EQU 14 ; FIELD BUFFER CELL 4 DATACELL EQU 15 ; DATABASE CELL PREALLOC EQU 16 ; NUMBER OF CELLS TO PREALLOCATE SWIDTH EQU $10 ; SCREEN WIDTH CURS_ON EQU $80 ; CURSOR ON FLAG CURS_OFF EQU $00 ; CURSOR OFF CURSOR_BLOCK EQU $00 ; CURSOR IN BLOCK FORM CURSOR_LINE EQU $01 ; CURSOR IN LINE FORM TIMEOUT EQU 300 ; AUTOMATIC TIMEOUT IN 5 MINS BSIZE EQU <256+64> ; RTT_BF BUFFER SIZE FSIZE EQU 32 ; RTT_FF BUFFER SIZE DELIM EQU 9 ; BUFFER DELIMITER KEY_TIME EQU $b3dd ; GIVES 50.000MS KEY POLLING KEY_DELAY EQU 14 ; DELAY BEFORE KEY REPEAT KEY_REPEAT EQU 0 ; RATE OF KEY REPEAT 0=FASTEST KEY_CLICK EQU 1 ; LENGTH OF KEY CLICK TYPEAHEAD EQU 16 ; 16 CHARACTER TYPE AHEAD HDELAY EQU 4 ; HORIZONTAL SCROLLING DELAY VDELAY EQU 10 ; VERTICAL SCROLLING DELAY REGSIZE EQU 32 ; NUMBER OF TABLE REGISTERS REGBASE EQU <256-REGSIZE> ; FIRST REGISTER NUMBER STACKSIZE EQU 32 ; TABLE STACK SIZE ; ; SYMBOLIC KEY CODE NAMES ; ======================== ; K_AC EQU 1 ; ON/CLEAR KEY K_MODE EQU 2 ; MODE KEY K_UP EQU 3 ; UP ARROW K_DOWN EQU 4 ; DOWN ARROW K_LEFT EQU 5 ; LEFT ARROW K_RGHT EQU 6 ; RIGHT ARROW K_DELR EQU 7 ; DELETE RIGHT KEY K_DEL EQU 8 ; DELETE KEY K_EXE EQU 13 ; EXECUTE KEY ; ; SCREEN DISPLAY CONTROL CODES ; ============================ ; D_BS EQU 8 ; BACK SPACE D_HT EQU 9 ; NEAREST POSITION MODULO 8 D_LF EQU 10 ; LINE FEED D_HM EQU 11 ; POSITION CURSOR TOP LEFT D_FF EQU 12 ; CLEAR ENTIRE DISPLAY D_CR EQU 13 ; GOTO START OF LINE D_CT EQU 14 ; CLEAR TOP LINE D_CB EQU 15 ; CLEAR BOTTOM LINE D_BL EQU 16 ; BELL D_RE EQU 17 ; REFRESH BOTH LINES D_TR EQU 18 ; REFRESH TOP LINE D_BR EQU 19 ; REFRESH BOTTOM LINE ; ; SLOT SYMBOLIC NAME ; ================== ; PAKA EQU 0 ; RAM DATA PACK PAKB EQU 1 ; FIRST PACK SLOT PAKC EQU 2 ; SECOND PACK SLOT PAKD EQU 3 ; TOP SLOT ; ; DATAPACK FIRST BYTE BITS ; ======================== ; EPROM EQU $02 ; SET IF EPROM PACK (NOT RAM PACK) PGCPK EQU $04 ; SET IF PACK WITH PAGE COUNTER RDWRT EQU $08 ; CLEAR IF PACK WRITE PROTECTED NOBOOT EQU $10 ; CLEAR IF PACK BOOTABLE COPYPK EQU $20 ; SET IF PACK COPYABLE NYIMPL EQU $40 ; SET FOR FUTURE EXPANSION MK1PAK EQU $80 ; SET IF MARK I PACK ; ; FILING SYSTEM ; ============= ; MAXFILE EQU 4 ; MAXIMUM NUMBER OF OPEN FILES BBODTYP EQU $80 ; BLOCK BODY RECORDS NAMETYP EQU $81 ; RECORD TYPE FOR FILE NAMES BDIATYP EQU $82 ; BLOCK NAME TYPE FOR DIARY BLANTYP EQU $83 ; BLOCK NAME TYPE FOR OPL FRECTYP EQU $91 ; FIRST FREE RECORD TYPE NAMELEN EQU 8 ; MAX LEN OF A FILE NAME TLRECT EQU ; RECORD TYPE FOR MAIN
5.1.7 ERROR NUMBERS
Included below are all the symbolic names of the error numbers returned by the operating system services.
These error numbers are always returned in the B register after an operating
system service has signalled an error by returning with the carry flag set.
ER_AL_NC EQU 255 ; NO MORE ALLOCATOR CELLS ER_AL_NR EQU 254 ; NO MORE ROOM ER_MT_EX EQU 253 ; EXPONENT OVERFLOW (OR UNDERFLOW) ER_MT_IS EQU 252 ; CONVERSION FROM STRING TO NUMERIC FAILED ER_MT_DI EQU 251 ; DIVIDE BY ZERO ER_MT_FL EQU 250 ; CONVERSION FROM NUMERIC TO STRING FAILED ER_IM_OV EQU 249 ; BCD STACK OVERFLOW ER_IM_UN EQU 248 ; BCD STACK UNDERFLOW ER_FN_BA EQU 247 ; BAD ARGUMENT IN FUNCTION CALL ER_PK_NP EQU 246 ; NO PACK IN SLOT ER_PK_DE EQU 245 ; DATAPACK ERROR (WRITE ERROR) ER_PK_RO EQU 244 ; ATTEMPTED WRITE TO READ ONLY PACK ER_PK_DV EQU 243 ; BAD DEVICE NAME ER_PK_CH EQU 242 ; PACK CHANGED ER_PK_NB EQU 241 ; PACK NOT BLANK ER_PK_IV EQU 240 ; UNKNOWN PACK TYPE ER_FL_PF EQU 239 ; PACK FULL ER_FL_EF EQU 238 ; END OF FILE ER_FL_BR EQU 237 ; BAD RECORD TYPE ER_FL_BN EQU 236 ; BAD FILE NAME ER_FL_EX EQU 235 ; FILE ALREADY EXISTS ER_FL_NX EQU 234 ; FILE DOES NOT EXIST ER_FL_DF EQU 233 ; DIRECTORY FULL ER_FL_CY EQU 232 ; PACK NOT COPYABLE ER_DV_CA EQU 231 ; INVALID DEVICE CALL ER_DV_NP EQU 230 ; DEVICE NOT PRESENT ER_DV_CS EQU 229 ; CHECKSUM ERROR ER_EX_SY EQU 228 ; SYNTAX ERROR ER_EX_MM EQU 227 ; MISMATCHED BRACKETS ER_EX_FA EQU 226 ; WRONG NUMBER OF FUNCTION ARGS ER_EX_AR EQU 225 ; SUBSCRIPT OR DIMENSION ERROR ER_EX_TV EQU 224 ; TYPE VIOLATION ER_LX_ID EQU 223 ; IDENTIFIER TOO LONG ER_LX_FV EQU 222 ; BAD FIELD VARIABLE NAME ER_LX_MQ EQU 221 ; UNMATCHED QUOTES IN STRING ER_LX_ST EQU 220 ; STRING TOO LONG ER_LX_US EQU 219 ; UNRECOGNISED SYMBOL ER_LX_NM EQU 218 ; NON-VALID NUMERIC FORMAT ER_TR_PC EQU 217 ; MISSING PROCEDURE DECLARATION ER_TR_DC EQU 216 ; ILLEGAL DECLARATION ER_TR_IN EQU 215 ; NON-INTEGER DIMENSION ER_TR_DD EQU 214 ; NAME ALREADY DECLARED ER_TR_ST EQU 213 ; STRUCTURE ERROR ER_TR_ND EQU 212 ; NESTING TOO DEEP ER_TR_NL EQU 211 ; LABEL REQUIRED ER_TR_CM EQU 210 ; MISSING COMMA ER_TR_BL EQU 209 ; BAD LOGICAL FILE NAME ER_TR_PA EQU 208 ; ARGUMENTS MAY NOT BE TARGET OF ASSIGN ER_TR_FL EQU 207 ; TOO MANY FIELDS ER_RT_BK EQU 206 ; BREAK KEY ER_RT_NP EQU 205 ; WRONG NUMBER OF PARAMETERS ER_RT_UE EQU 204 ; UNDEFINED EXTERNAL ER_RT_PN EQU 203 ; PROCEDURE NOT FOUND ER_RT_ME EQU 202 ; MENU ERROR ER_RT_NF EQU 201 ; FIELD NOT FOUND ER_PK_BR EQU 200 ; PACK BAD READ ERROR ER_RT_FO EQU 199 ; FILE ALREADY OPEN (OPEN/DELETE) ER_RT_RB EQU 198 ; RECORD TOO BIG ER_LG_BN EQU 197 ; BAD PROCEDURE NAME ER_RT_FC EQU 196 ; FILE NOT OPEN (CLOSE) ER_RT_IO EQU 195 ; INTEGER OVERFLOW ER_GN_BL EQU 194 ; BATTERY TOO LOW ER_GN_RF EQU 193 ; DEVICE READ FAIL ER_GN_WF EQU 192 ; DEVICE WRITE FAIL
5.1.8 VECTOR NUMBERS
Included below are all the operating system service names and numbers which may be used to set up an include file for machine code applications.
AL$FREE 000 AL$GRAB 001 AL$GROW 002 AL$REPL 003 AL$SHNK 004 AL$SIZE 005 AL$ZERO 006 BT$NMDN 007 BT$NMEN 008 BT$NOF 009 BT$NON 010 BT$PPRG 011 BT$SWOF 012 BZ$ALRM 013 BZ$BELL 014 BZ$TONE 015 DP$EMIT 016 DP$PRNT 017 DP$REST 018 DP$SAVE 019 DP$STAT 020 DP$VIEW 021 DP$WRDY 022 DV$BOOT 023 DV$CLER 024 DV$LKUP 025 DV$LOAD 026 DV$VECT 027 ED$EDIT 028 ED$EPOS 029 ED$VIEW 030 ER$LKUP 031 ER$MESS 032 FL$BACK 033 FL$BCAT 034 FL$BDEL 035 FL$BOPN 036 FL$BSAV 037 FL$CATL 038 FL$COPY 039 FL$CRET 040 FL$DELN 041 FL$ERAS 042 FL$FFND 043 FL$FIND 044 FL$FREC 045 FL$NEXT 046 FL$OPEN 047 FL$PARS 048 FL$READ 049 FL$RECT 050 FL$RENM 051 FL$RSET 052 FL$SETP 053 FL$SIZE 054 FL$WRIT 055 FN$ATAN 056 FN$COS 057 FN$EXP 058 FN$LN 059 FN$LOG 060 FN$POWR 061 FN$RND 062 FN$SIN 063 FN$SQRT 064 FN$TAN 065 IT$GVAL 066 IT$RADD 067 IT$STRT 068 IT$TADD 069 KB$BREK 070 KB$FLSH 071 KB$GETK 072 KB$INIT 073 KB$STAT 074 KB$TEST 075 KB$UGET 076 LG$NEWP 077 LG$RLED 078 LN$STRT 079 MN$DISP 080 MT$BTOF 081 MT$FADD 082 MT$FBDC 083 MT$FBEX 084 MT$FBGN 085 MT$FBIN 086 MT$FDIV 087 MT$FMUL 088 MT$FNGT 089 MT$FSUB 090 PK$PKOF 091 PK$QADD 092 PK$RBYT 093 PK$READ 094 PK$RWRD 095 PK$SADD 096 PK$SAVE 097 PK$SETP 098 PK$SKIP 099 RM$RUNP 100 TL$ADDI 101 TL$CPYX 102 TL$DELI 103 TL$XXMD 104 TM$DAYV 105 TM$TGET 106 TM$UPDT 107 TM$WAIT 108 UT$CPYB 109 UT$DDSP 110 UT$DISP 111 UT$ENTR 112 UT$FILL 113 UT$ICPB 114 UT$ISBF 115 UT$LEAV 116 UT$SDIV 117 UT$SMUL 118 UT$SPLT 119 UT$UDIV 120 UT$UMUL 121 UT$UTOB 122 UT$XCAT 123 UT$XTOB 124 UT$YSNO 125 UT$CDSP 126 ;AVAILABLE ON VERSION 2.5 AND ABOVE ONLY TL$RSTR 127 ;AVAILABLE ON VERSION 2.7 AND ABOVE ONLY
The following vectors are only available on LZ machines:
BT$TOFF 129 DP$MSET 130 DP$CSET 131 DP$CPRN 132 DP$UDG 133 MN$XDSP 134 MN$1DSP 135 MN$TITL 136 FN$SUM 137 FN$MEAN 138 FN$VAR 139 FN$STD 140 FN$MIN 141 FN$MAX 142 FL$WPAR 143 FL$WCAT 144 FL$WCPY 145 FL$WDEL 146 FL$WFND 147 UT$WILD 148 TM$NDYS 149 TM$WEEK 150 TM$DNAM 151 FL$GETX 152 FL$VALX 153 LN$XSTT 154 TL$ZZMD 155 XT$DIRM 156 FL$NCAT 157 AM$ENTR 158 NT$ENTR 159 CA$ENTR 160 XT$ENTR 161 XT$BAR 162 DP$PVEW 163 TI$ENTR 164 UT$SORT 165 WL$ENTR 166 DI$ENTR 167 XF$ENTR 168 ER$PRNT 169 TM$MNAM 170 LG$EDIT 171 FN$ASIN 172 FN$ACOS 173 XF$SORT 174 LG$ENTR 175 FL$FDEL 176 KB$CONK 177 UT$CMPB 178 TM$TSET 179
5.2 SYSTEM VERSIONS
There are serveral machine variants. Most of these were also produced as POS (meaning: point of sale) versions.
ROM RAM Display POS-Version CM 32K 8K 2x16 XP 32K 16K 2x16 POS-250 XP multilingual 64K 16K 2x16 LA 32K 32K 2x16 LA multilingual 64K 32K 2x16 32K 96K 2x16 POS-350 LZ 64K 32K 4x20 POS-432 LZ64(LP) 64K 64K 4x20 POS-464
Note that XP and LA were both labelled as XP.
Additionally there are XP and LA variants which were produced with just a numeric keyboard. Both are labelled as POS-200 machines, so that there exist two other machines known as the XP POS-200 and the LA POS-200.
The difference between the normal operating system and the POS variants is in the handling of the top level. The normal operating system enters the top level menu and then dispatches to the various services available, while the POS machines do the following:
Also, the POS-200 variants support the numeric-only keyboard automatically.
In order to allow the machine type to be determined as well as the software revision level of the ROM, there are 4 identification bytes. They occupy the following addresses:
$FFE7 - Language(s)-byte $FFE8 - Model-byte $FFE9 - Version number $FFCB - Model-byte-2 (introduced with model LZ)
ADDRESS: $FFE7 VALUES: $00 - English $01 - French $02 - German $80 - Eleven languages (English default) $81 - English, French, German (English default)
This was introduced in version 3.6 of the Organiser OS. Earlier versions are english only and this byte usually is $FF.
Bit 7 of this byte set, indicates that the machine is multi-lingual. The value of the remaining seven bits then gives either the language or selection of languages implemented. Further values may have been added as new language variants were introduced.
Applications should look at the RAM language byte BTB_LANG ($2186) to detect which language any machine is running in.
ADDRESS: $FFE8 VALUES: See below.
The base model type and the special model type are held together in the model byte. The base model type is held in the bottom 3 bits of this byte and the special model type is a single bit set in the remaining 5 bits. The base model type is for identifying the ROM/RAM configuration AND the Operating System.
NOTE: The ROM/RAM configuration alone does not determine the base model type.
Bits 0-2: BASE MODEL TYPE VALUE MODEL RAM SIZE ROM SIZE 0 CM 8K 32K 1 XP 16K 32K 2 LA 32K 32K 4 POS-350 96K 32K 5 LZ64(LP) 64K 64K 6 LZ 32K 64K 7 --- see MODEL-BYTE-2 --- Bit 3 indicates: see MODEL-BYTE-2 for special features Bits 4-7: indicate special models bit 4 set: POS-350,464 (??) bit 7 set: other POS (??)
Note that these two features are totally independant.
ADDRESS: $FFCB VALUES: Bits 0-2 reserved for future base model types Bit 3,4 reserved for extra features Bit 5 set in LZ/OS from OS Vers. 4.5 onward Bit 6 extended LCD Bit 7 LZ functionality
ADDRESS: $FFE9 VALUES: upper nibble: major version number lower nibble: minor version number
The LZ was initially released at version 4.2 with a lot of bugs but the version number is nevertheless stored correctly as $42 (66 decimal) in $FFE9.
$FFE8 = $00
The CM/OS is the base operating system from which all other operating system variants are derived. As such any software written to run on the CM/OS is guaranteed to run on all other operating system variants. In other words software is upwardly compatible between the operating systems.
$FFE8 = $01 XP machine. $FFE8 = $81 XP POS 200 machine.
As for the CM/OS but will support the following extra facilities:
$FFE8 = $02 LA machine. $FFE8 = $82 LA POS 200 machine.
As for the XP/OS with the exception that the memory allocator is completely different.
This is because the system variables are located at $2000 in the CM/OS and XP/OS as external RAM only starts at this address. However in the LA machines external RAM starts at address $400. In order to keep the operating systems compatible the system variables are still located at address $2000 in the LA machines.
The free RAM is therefor in two sections, between $400 and $2000 and above the system variables. In order to allow the operating system to use the extra 7K of RAM the memory allocator effectively joins these two discontinuous areas of RAM together.
$FFE8 = $0E LZ/OS - LZ machine. $FFE8 = $0D LP/OS - LZ64 (LP) machine. $FFE8 = $1D LP2/OS - POS-464 machine.
The operating system in the LZ is fully back-compatible with the standard Organiser II operating system but has many extensions. All system variables are at the same addresses as on the standard Organiser and all system services will work exactly as they did before. Some system services have been extended to use the 4-line screen and there are 51 new services together with new system variables.
5.3 POWER UP
The machine can be switched on in 3 different ways.
On power up the program counter is loaded from the system restart vector at address $FFFE in the operating system ROM. The system restart vector is set to address $8000 in all versions of the operating system, which is the base address of the operating system ROM. The restart code is then executed in the following sequence.
The next task performed by the operating system is to determine whether a warm or cold start is required. Essentially a cold start is when the machine is starting up for the first time after a power failure and as such all operating system variables must be initialized. A warm start is when the machine only needs to carry on from when it was powered down, as all RAM values are still valid.
The Hitachi HD6303X microprocessor has an internal flag to determine whether power to the internal RAM in the processor has failed at any stage. This flag is the top bit in PORT 5. If the flag is clear then power to the internal RAM has failed at some stage and so a cold start is required. If the flag is still set then the internal RAM is still intact and so a warm start is required. As the external RAM is on the same power rail as the processor the above flag also serves to describe the validity of the external RAM.
5.3.1 COLD START
On executing a cold start the machine performs the following procedures:
Multi-langual machines present the language menu after displaying the copyright message. One language must be selected (ON/CLEAR will do nothing) before the top-level menu is displayed in the language chosen. Devices are re-booted whenever a language is selected.
5.3.2 WARM START
On deciding that a warm start is required the operating system performs the following code:
LDS BTA_SAVSTACK LDX BTA_WRM JMP 0,X
The power off service BT$SWOF stores the stack pointer in BTA_SAVSTACK before switching off the machine to enable the machine to restart at the same place it was at when the machine was switched off. With the stack restored to the value that it had in BT$SWOF, an "RTS" will continue execution after the call to BT$SWOF. Next the vector for warm starting is used to jump to a warm start routine. The warm start routine may be replaced by another routine but the operating system warm start routine should be called as well. If it is not the operating system will not work correctly. See section 5.6 on replacing vectored routines.
The system warm start routine performs the following actions:
5.4 POWER DOWN
The machine can be switched off by calling the POWER DOWN service routine BT$SWOF. This routine is vectored through BTA_SOF as follows:
STS BTA_SAVSTACK LDX BTA_SOF JMP 0,X
The power down routine may be replaced by another routine but the operating system power down routine should be called as well. If it is not the operating system will not work correctly. See section 5.6 on replacing vectored routines.
The system power down service performs the following steps:
The LZ may be powered down for a specified time, if so, step 8 is performed as if an alarm was due at that time.
The operating system uses four of the ten hardware interrupts to perform various services. The remainder are just directed to a RTI instruction. However, all interrupts are vectored through RAM so that they may be intercepted or replaced in total. For the interrupts used by the operating system it is recommended that the interrupt only be intercepted and not be replaced if it is required that the operating system performs according to specification.
5.5.1 NON-MASKABLE INTERRUPTS
The semi-custom chip will deliver an NMI to the processor exactly once every second to provide an accurate system clock, provided the address SCA_NMIMPU has been accessed.
The NMIs to the processor can be disabled by accessing the address SCA_NMICOUNTER. Note that this is an unusual feature since NMIs, as their name implies, cannot normally be disabled.
The NMI service routine performs the following actions:
1. Clear the flag BTB_NMFL.
This is to allow code to detect that an NMI has occurred as follows:
INC BTB_NMFL 1$: SLP ; Go to sleep until an interrupt TST BTB_NMFL ; Test NMI flag BNE 1$ ; Still set - so wrong interrupt ; NMI interrupt occurred.
2. Test the BTB_IGNM (ignore NMI flag, set on warm starting)
3. Update the system time by one second.
4. Check whether the seconds count is exactly zero, i.e. a whole minute.
5. Check the auto switch off flag TMB_SWOF.
6. Return from the interrupt.
5.5.2 TIMER 1 COMPARE INTERRUPT
The timer 1 compare interrupt is used to scan the keyboard to allow keyboard buffering and to provide a timing service. This interrupt is referred to in the documentation as the KEYBOARD INTERRUPT (KI).
The interrupt is generated every time the free running counter matches the count in the timer 1 compare register. As the free running counter is being clocked by the system clock of 921600 HZ, extremely accurate timing can be performed using this interrupt.
The time between interrupts is controlled by the variable KBW_TDEL which is initialized on cold start to be $B3DD. This value makes the KI interrupt occur exactly every 50 milliseconds and is used extensively by the operating system for timing purposes. The value in KBW_TDEL can be changed, but all system timing will be destroyed as a result and the operating system may fail to perform correctly.
The KI service routine performs the following steps:
This flag is used to perform system timing for the operating system. If a delay of 150 milliseconds were required then the following code could be used to achieve that delay:
LDX #3 ; Three KI interrupts at 50 ms each STX DPW_REDY: 1$: SLP ; Wait for interrupt LDD DPW_REDY: ; See if decremented to zero yet BNE 1$ ; 150 ms now elapsed.
6. Poll the keyboard. See section 7.3.2 for more information.
5.5.3 SOFTWARE INTERRUPT
This interrupt is used to provide the interface between applications and the operating system. When a SWI instruction is executed the following code is executed:
LDX BTA_SWI JMP 0,X
The SWI service routine provided by the operating system is as follows:
PUL A STA A,BTB_4DONTUSE ;SAVE STATUS FLAG PUL B PUL A STD BTW_1DONTUSE ;SAVE THE D REGISTER PULX STX BTW_2DONTUSE ;SAVE THE X REGISTER PULX ;GET THE ADDRESS OF THE BYTE LDA B,0,X ;FOLLOWING THE SWI INSTRUCTION INX ;INCREMENT TO SKIP OVER THE BYTE PSHX ;PUSH BACK AS RETURN ADDRESS LDX BTA_VECT ;GET THE VECTOR TABLE ADDRESS ABX ;DOUBLE THE VECTOR NUMBER AND ABX ;ADD TO VECTOR TABLE LDX 0,X ;GET ADDRESS OF ROUTINE PSHX ;SAVE ON STACK FOR DUMMY RETURN LDX BTW_2DONTUSE ;RESTORE X REGISTER LDD BTW_1DONTUSE ;RESTORE D REGISTER PSH A ;SAVE A REGISTER LDA A,BTB_4DONTUSE ;GET STATUS FLAGS TAP ;RESTORE STATUS FLAGS PUL A ;RESTORE A REGISTER RTS ;JUMP TO REQUIRED ROUTINE
5.5.4 TRAP INTERRUPT
The operating system routine to handle the trap interrupt simply clears the LCD display and displays "TRAP" on the screen until the battery is removed and the machine is COLD started again. It is intended that this trap remain free for use with a debugger at some time in the future and as such should not be used.
In order to provide flexibility in the operating system all the hardware interrupts are vectored through RAM vectors so that they may be intercepted or even replaced. In addition a number of operating system services are provided through vectors as well so that they may be intercepted or replaced more easily than intercepting the SWI interrupt.
If the operating system is using an interrupt, it is strongly recommended that the interrupt is just intercepted and not replaced entirely. This can be done in the following way for example to intercept the NMI interrupt routine.
Initialization code. LDX BTA_NMI ; CURRENT SERVICE ROUTINE ADDRESS STX OLD_NMI ; SAVE THE ADDRESS SOMEWHERE LDX #NEW_NMI ; NEW NMI ROUTINE ADDRESS STX BTA_NMI ; RE-DIRECT THE OPERATING SYSTEM New NMI routine. NEW_NMI: ; PERFORM NEW NMI USER CODE LDX OLD_NMI ; OLD NMI ROUTINE ADDRESS JMP 0,X ; RUN THE OLD ROUTINE
5.6.1 HARDWARE VECTORS
The following is a list of hardware interrupts and their vectors in RAM. Those preceded by a * are not used by the operating system. The addresses for the vectors are given in the chapter on memory usage in section 22.214.171.124.
1. *IRQ2 - BTA_2IQ - Interrupt request 2.
2. *CMI - BTA_CMI - Timer 2 counter match interrupt.
3. TRAP - BTA_TRP - Trap exception interrupt.
4. *SIO - BTA_SIO - Serial input/output interrupt.
5. *TOI - BTA_TOI - Timer 1 overflow interrupt.
6. OCI - BTA_OCI - Timer output compare interrupt.
7. *ICI - BTA_ICI - Timer 1 input capture interrupt.
8. *IRQ1 - BTA_1IQ - Interrupt request 1 interrupt.
9. SWI - BTA_SWI - Software interrupt.
10. NMI - BTA_NMI - Non-maskable interrupt.
5.6.2 SOFTWARE VECTORS
The addresses for the vectors are given in the chapter on memory usage in section 126.96.36.199.
1. WARM - BTA_WRM - Warm start vector.
2. SWOF - BTA_SOF - Power down vector (switch off).
3. POLL - BTA_POLL - Keyboard poll routine vector.
4. TRAN - BTA_TRAN - Key translate routine vector.
5.7 RELEASE NOTES
What follows are notes for the different releases of CM and XP machines. All significant enhancements and known bugs are listed.
All the bugs noted are fixed for the following release.
5.7.1 VERSION 2.3 AND EARLIER
Not released in any quantity. Any machines with this operating system should be returned to Psion for update.
5.7.2 RELEASE 2.4
Released on 12th May 1986.
5.7.3 RELEASE 2.6
Released on 15 October 1986.
5.7.4 RELEASE 3.1
Released on 30 January 1987
5.8 SYSTEM SERVICES
VECTOR NUMBER: 007
INPUT PARAMETERS: None
OUTPUT VALUES: None
This system service routine switches off NMIs to the processor.
NOTE: As the NMI interrupt is used to provide the system clock the system time will be invalid. It is possible to switch off NMIs and still maintain a valid system time. See the system service BT$NOF.
If NMIs are switched off with this service then they should be switched back on with the BT$NMEN service.
VECTOR NUMBER: 008
INPUT PARAMETERS: None
OUTPUT VALUES: None
This system service routine switches on NMIs to the processor.
BT$NMEN should only be used to re-establish NMIs if they have been disabled with the BT$NMDN service.
VECTOR NUMBER: 009
INPUT PARAMETERS: None
OUTPUT VALUES: None
This system service routine switches off NMIs to the processor in such a way that the system time will be preserved.
The NMI interrupt is generated from the semi-custom chip every second to provide a very accurate system clock. When NMIs are switched off the processor, an internal counter in the semi-custom chip is connected to the NMI line so that NMIs can still be counted. This service ensures that the counter in the semi-custom chip is reset properly so that on switching NMIs back to the processor the time can be updated properly. In order to do this it is imperative that the BT$NON service is used to switch on NMIs. The maximum time that can be stored in the counter is 2048 seconds, so BT$NON must be called before this time has elapsed.
There is a disadvantage to this pair of services, in that on restoring NMIs to the processor the BT$NON service must wait for the first NMI before counting the number of NMIs that have occurred while NMIs were switched off. This means that depending on when in the cycle the BT$NON service is called a delay of between 0 and 1 second can occur. See chapter 10 for more information on the timing services.
Finally note that the counter used to count NMIs when they are disabled from the processor is also used to scan the keyboard and as such any keyboard interrupt occurring after BT$NOF has been called will destroy the NMI counter. Thus to disable NMIs and preserve the system time, interrupts should also be disabled before calling BT$NOF. Keyboard services must not be called, as they will poll the keyboard directly when interrupts are disabled.
TPA ; GET CURRENT STATUS PSH A ; SAVE IT SEI ; DISABLE INTERRUPTS OS BT$NOF ; SWITCH NMIS OFF. ; CODE PERFORMED WITH NO INTERRUPTS OCCURRING. OS BT$NON ; SWITCH NMIS BACK ON AND UPDATE TIME. PUL A ; RESTORE PREVIOUS STATUS TAP ; SET STATUS REGISTER
VECTOR NUMBER: 010
INPUT PARAMETERS: None
OUTPUT VALUES: None
This system service routine switches on NMIs to the processor.
BT$NON should only be used to re-establish NMIs if they have been disabled with the BT$NOF service.
VECTOR NUMBER: 011 INPUT PARAMETERS: None OUTPUT VALUES: None
This system service routine will push or pop the seven variables UTW_R0 to UTW_R6 on the machine stack.
This system service must be followed by a control byte which contains the instructions for the service. Execution of code continues after the control byte.
The format of the control byte is as follows
BIT 7 - If set then pop the variables else push the variables. BIT 6 - If set then push or pop UTW_R6 BIT 5 - If set then push or pop UTW_R5 BIT 4 - If set then push or pop UTW_R4 BIT 3 - If set then push or pop UTW_R3 BIT 2 - If set then push or pop UTW_R2 BIT 1 - If set then push or pop UTW_R1 BIT 0 - If set then push or pop UTW_R0
Thus if the byte value is $5 then UTW_R2 and UTW_R0 will be pushed.
When pushing, the higher addressed variables are pushed first and when popping, the lower address variables are popped first. Thus if UTW_R5 and UTW_R2 are pushed and UTW_R2 and UTW_R1 are popped then UTW_R1 will get the old value of UTW_R2 and UTW_R2 will get the old value of UTW_R5.
NOTE: no check is made to ensure that there is room on the machine stack to take all the variables pushed.
OS BT$PPRG ; PUSH UTW_R0 .BYTE 1 ; INSTRUCTION BYTE TO BT$PPRG ; CAN NOW USE UTW_R0 OS BT$PPRG ; POP UTW_R0 .BYTE $81 ; INSTRUCTION BYTE TO BT$PPRG
VECTOR NUMBER: 012
INPUT PARAMETERS: None
OUTPUT VALUES: None
This system service may be called to switch off the Organiser II.
When switching off, the service saves the entire state of the machine so that on power up everything is restored to exactly the same state as when the service was called. See the section 5.4 for an exact description of the power down procedure.
NOTE that on power up the top 8 bytes of zero page ram (i.e. $F9-$FF) are always trashed by the operating system.
It is easier to intercept the warm startup routine via the BTA_WRM vector to determine if the machine has been switched off than to try and intercept the switch off service via the SWI vector.
OS BT$SWOF ; SWITCH OFF THE MACHINE HERE ; RESTARTS HERE ON POWER UP