The PSION Organiser II Homepage
 
Home
Technical Reference
Introduction
System
Versions
Operating
System
Memory Usage
Filing System
System Timing
System Board
Power Supply Board
Display
Keyboard
Interface Slots
Packs
General
Flashpacks
Low Level
Access
External
Interfacing
Comms Link
Psion Link
Protocol
Utility System
Services
Built-in
Applications
LZ Passwords
Programming
Language
General
Q-Code
Table
Interpreter
System Services
 

Technical Reference Manual

OPERATING SYSTEM

SYSTEM INTERFACE

POWER UP

POWER DOWN

INTERRUPTS

VECTORS

SYSTEM SERVICES

SYSTEM INTERFACE

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.

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.

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.

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:

                OS KB$GETK

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.

MEMORY STORAGE

In the following description refer to chapter Memory Usage for the addresses of the variables described.

The six words of memory storage labeled 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 labeled 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:

  • 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 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.

SYSTEM CONSTANTS AND MACROS

The files system.inc (CM/XP) and syslz.inc (LZ) contain a set of useful constants and macros used in the examples.

ERROR NUMBERS

Included in the file errors.inc 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 signaled an error by returning with the carry flag set.

VECTOR NUMBERS

Included in the file swi.inc are all the operating system service names and numbers. The system services are briefly explained in this manual. Please refer to the System Services page for an in depth discussion.

Note that vectors 0 to 125 are available on all machines, 126 is available from OS version 2.5 on and 127 from OS version 2.7 on. Vector 128 is available on multi-lingual machines only.

Vectors 129 to 179 are only available on LZ machines.

A call to an unavailable vector may cause a system crash, therefor it is advisable to check the system version before calling one of these services.

POWER UP

The machine can be switched on in 3 different ways.

  1. By pressing the ON/CLEAR key.
  2. By the clock counter expiring in the semi-custom chip.
  3. By asserting the ON line from the top slot.

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.

  1. Zero page RAM is enabled by setting the RAME bit in PORT 5 of the processor.
  2. The machine stack is initialized temporarily to the top of zero page RAM, i.e. at address $FF.
  3. The LCD display is cleared.
  4. The control lines to the datapack bus are initialized to a known state.

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.

COLD START

On executing a cold start the machine performs the following procedures:

  1. Perform a simple RAM test on the external RAM.
  2. Determine the last address in the external RAM.
  3. Check that this address is valid for the three memory models available, i.e. $3FFF, $5FFF or $7FFF.
  4. If the value does not correspond to one of the valid values then the RAM must be faulty, so the buzzer is sounded and the machine powered down.
  5. Use the last address of valid RAM plus 1 to initialize BTA_RTOP.
  6. Set the machine stack address to BTA_RTOP.
  7. Subtract 256 from BTA_RTOP and use the value to initialize RTA_SP and BTA_SBAS. This leaves 256 bytes for the machine stack.
  8. Initialize all soft vectors and all operating system variables.
  9. Enable NMI interrupts to the processor.
  10. Start the timer to provide keyboard scan interrupts.
  11. Test that the battery voltage is over 5 volts. If it is not then display low battery message for 4 seconds and then switch off the machine.
  12. Boot any devices.
  13. Show copyright message.
  14. Start at the top level menu.

Multi-lingual 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 rebooted whenever a language is selected.

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 Vectors on replacing vectored routines.

The system warm start routine performs the following actions:

  1. Switch non-maskable interrupts (NMI) on to the processor.
    This is done by testing the ADDRESS SCA_NMIMPU
  2. Wait for the first NMI to occur.
    This is necessary as on each switch-on the clock counter in the semi custom chip gains a second and so the first NMI must be ignored.
  3. Test the hardware flag ACOUT in POB_PORT5.
    If the flag is true then the counter has expired and the time needs updating as follows:
    1. Update the system clock by the length of time the machine has been switched off for.
    2. Determine whether an alarm is due currently and if so carry on with the power-on sequence, if not then just switch off the machine again.
    Otherwise the machine was switched on with the ON/CLEAR key or by an external interface and the system clock is updated by the time the machine has been switched off for.
  4. Restore the display to its state before power down.
  5. Set the ALARM_TO_DO flag so that any alarms will be serviced.
  6. Reset the AUTO_SWITCH_OFF countdown and check that it's greater than 15 seconds. If it is not then make it 15 seconds.
  7. Check for low battery as in cold starting.
  8. Restore the interrupt status and the value in TIMER 1 STATUS CONTROL REGISTER (TSCR1) which were saved by the BT$SWOF service.
  9. Wait for the ON/CLEAR key to be released.
  10. Restore the USER-DEFINED GRAPHICS as saved by the BT$SWOF service.
  11. Flush the keyboard buffer and restart keyboard scan interrupts.
  12. Execute a return instruction which resumes execution after the call to the BT$SWOF service.

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 Vectors on replacing vectored routines.

The system power down service performs the following steps:

  1. Save the current value of the status flag, to preserve the interrupt status.
  2. Save the value in the TIMER 1 STATUS CONTROL REGISTER (TSCR1).
  3. Disable interrupts.
  4. Clear the LCD display.
  5. Save the current values of the USER DEFINED GRAPHICS in the LCD.
  6. Switch off the interface slots.
  7. Reset the COUNTER to 0.
  8. Check whether any alarms are due to run in the next 34 minutes and 8 seconds. If so, adjust the counter so that the machine is woken up in time to service the alarm. See section Keeping Time for more information.
  9. Switch non-maskable interrupts to the COUNTER.
  10. Disable the internal RAM by clearing the RAME bit in POB_RCR.
  11. Test the address SCA_SWITCHOFF to put the processor in standby mode.

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.

INTERRUPTS

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.

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)If it is zero then set the flag and return from the interrupt.
  3. Update the system time by one second.
  4. Check whether the seconds count is exactly zero, i.e. a whole minute.
    If it is then check the alarms enabled flag AMB_EI. If it is set then set AMB_DOIT which will trigger a scan of the alarms pending lists at the next TIMER 1 interrupt. Thus alarms are scanned only every minute and are under control of the processor interrupt flag.
  5. Check the auto switch off flag TMB_SWOF.
    If it's set then decrement the time out count in TMW_TOUT if it is not already zero.
  6. Return from the interrupt.

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:

  1. Reset the free running counter to zero.
  2. Set the timer 1 output compare register to the value in KBW_TDEL.
  3. Check the alarm service required flag AMB_DOIT. If it is set then run the alarm service and clear the flag AMB_DOIT.
  4. Increment the frame counter TMW_FRAM.
  5. Decrement the word DPW_REDY if it's not already zero.
    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 Keyboard Polling for more information.

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

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 and as such should not be used.

VECTORS

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

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.

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


SOFTWARE VECTORS

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

SYSTEM SERVICES

BT$NMDN

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.

BT$NMEN

This system service routine switches on NMIs to the processor. BT$NMEN should only be used to reestablish NMIs if they have been disabled with the BT$NMDN service.

BT$NOF

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 System Timing 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.

EXAMPLE

        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

BT$NON

This system service routine switches on NMIs to the processor. BT$NON should only be used to reestablish NMIs if they have been disabled with the BT$NOF service.

BT$PPRG

This system service routine will push or pop the seven variables UTW_R0 to UTW_R6 on the machine stack.

BT$SWOF

This system service may be called to switch off the Organiser II.

BT$TOFF (LZ only)

A new facility on the LZ is the ability to switch off for a specified time before switching back on automatically. This can be done from OPL with the "OFF x%" command and from machine code using BT$TOFF. The maximum time to be off is 1800 seconds (30 minutes) since the system clock must be updated. The routine can, of course, be called repeatedly to 'apparently' switch off for longer times.

EXAMPLE: Switch the machine off for 12 hours.

   LDA A,#24     ;24 1/2 hours needed
   PSH A
   LDD #1800     ;to switch off for 30 minutes
   OS BT$TOFF
   PUL A
   DEC A
   BNE 1$        ;repeat 24 times
   RTS

Note: If an ALARM is due before the time to switch back on, the machine will switch on early to service the alarm.

 
first previous   next top