Difference between revisions of "83Plus:Ports:03"

From WikiTI
Jump to: navigation, search
(Added categories)
 
(12 intermediate revisions by 6 users not shown)
Line 1: Line 1:
[[Category:83Plus:Ports:By_Address|03 - Interrupt Mask]]
+
[[Category:83Plus:Ports:By_Address|03 - Interrupt Mask]] [[Category:83Plus:Ports:By_Name|Interrupt Mask]]
[[Category:83Plus:Ports:By_Name|Interrupt Mask]]
+
 
== Synopsis ==
 
== Synopsis ==
 
'''Port Number:''' 03h
 
'''Port Number:''' 03h
Line 6: Line 5:
 
'''Function:''' Interrupt Masking Port
 
'''Function:''' Interrupt Masking Port
  
This port controls what devices will be allowed to trigger interrupts.
+
''See also: [[83Plus:Interrupts]]''
 +
 
 +
This port controls what devices will be allowed to trigger interrupts. When an interrupt is triggered, it should be cleared by reseting the corresponding bit.  Otherwise, it will continuously call the interrupt code once interrupts are reenabled with ei.
  
 
=== Read Values ===
 
=== Read Values ===
 
* Bit 0: Set if pressing the ON key will generate an interrupt.
 
* Bit 0: Set if pressing the ON key will generate an interrupt.
* Bit 1: Set if the hardware timer will generate an interrupt (~150 times per second).
+
* Bit 1: Set if the first hardware timer will generate an interrupt (range: 108Hz-512Hz).
 +
* Bit 2: Set if the second hardware timer will generate an interrupt (range: 216Hz-1024Hz).
 
* Bit 4: Set if the linkport will generate an interrupt.
 
* Bit 4: Set if the linkport will generate an interrupt.
  
 
=== Write Values ===
 
=== Write Values ===
* Bit 0: Set 1 to enable the ON key. Set 0 to disable it.
+
* Bit 0: Set 1 to enable the ON key. Set 0 acknowledge the interrupt request and/or to disable it.
* Bit 1: Set 1 to enable the hardware timer. Set 0 to disable it.
+
* Bit 1: Set 1 to enable the first hardware timer. Set 0 acknowledge the interrupt request and/or to disable it.
* Bit 3: Set 1 to enable the LCD. Set 0 to turn off the LCD.
+
* Bit 2: Set 1 to enable the second hardware timer. Set 0 acknowledge the interrupt request and/or to disable it.
* Bit 4: Set 1 to enable the linkport interrupt. Set 0 to disable it. (Does not completely disable the linkport.)
+
* Bit 3: Set 0 to put the calculator in low power mode if and only if the Z80 cpu enters the halt state (during the executing of a halt instruction). Set 1 to keep the calculator powered.
 +
* Bit 4: Set 1 to enable the linkport interrupt. Set 0 acknowledge the interrupt request and/or to disable it. (Does not completely disable the linkport.)
  
 
== Comments ==
 
== Comments ==
For normal operation, write 0B (00001011) to this port.
+
* For normal operation, write 0B (00001011) to this port. This will allow the first timer to generate interrupts, and the on key.
 +
* In low power mode it is known that at least the lcd driver enters standby mode and that the timer hardware has been disabled.
  
 
== Example ==
 
== Example ==
 +
===Soft Powerdown===
 
This example shows how to do a soft powerdown (similar to the auto powerdown) on the calculator.
 
This example shows how to do a soft powerdown (similar to the auto powerdown) on the calculator.
This may or may not wipe the LCD screen, so you should first copy it's contents to a buffer like saveSScreen and then copy it back afterwards.
+
This may or may not wipe the LCD screen, so you should first copy its contents to a buffer like saveSScreen and then copy it back afterwards.
 
  <nowiki> push af
 
  <nowiki> push af
  ld a, 11h ;Enable linkport, ON key. Disable timer. Turn off LCD.
+
  ld a, 11h ;Enable linkport, ON key. Disable timer.
 +
          ;Set low power mode.
 
  out (3), a
 
  out (3), a
  halt ;Wait for an interrupt (either ON key or insert link cable).
+
  halt     ;Enter low power mode (disabling various devices)
  ld a, 0Bh ;Enable ON key, tiemr. Disable linkport. Turn on LCD.
+
          ;and wait for an interrupt (either ON key or
 +
          ;link activity) which will enable all hardware
 +
          ;devices again.
 +
  ld a, 0Bh ;Enable ON key, timer. Disable linkport.
 +
          ;Keep calculator powered.
 
  out (3), a
 
  out (3), a
 
  pop af</nowiki>
 
  pop af</nowiki>
 +
 +
===Simple Interrupt===
 +
This example will show how to set up the first timer for an interrupt and its use in the [[wikipedia:Interrupt_handler|ISR]].  It will also show beyond just port 3 usage since this port requires more complex interaction for its typical use.
 +
<nowiki>Install_ISR:
 +
 +
;Disabling interrupts prior to installation.
 +
;This is in case an im 2 interrupt is already running.
 +
;(MirageOS would present such a case.)
 +
;
 +
di
 +
 +
;A 257 byte vector table(located in StatVars) is
 +
;filled with the same byte.  This byte will determine
 +
;the location of the interrupt code's start.
 +
;If the table is filled with $XY then the code must be
 +
;located at $XYXY.
 +
;
 +
ld hl,$8B00
 +
ld (hl),$8A
 +
ld de,$8B01
 +
ld bc,256
 +
ldir
 +
 +
;The interrupt code is copied to a safe code buffer(StatVars).
 +
;If the interrupt code is to large, you may alternatively
 +
;place jp instruction in this code buffer that jumps to your
 +
;interrupt code. Interrupt code should be located in ram. While
 +
;nothing physically prevents use of bank4000 area, it is
 +
;commonly swapped out and so at the very least precautions
 +
;would be required to use that area.
 +
;
 +
ld hl,Interrupt_Start
 +
ld de,$8A8A
 +
ld bc,Interrupt_End-Interrupt_Start
 +
ldir
 +
 +
;You must designate what hardware will generate an interrupt.
 +
;For safety, acknowledging any waiting requests may
 +
;also be done.
 +
;
 +
ld a,%00001000 ;Acknowledge and disable
 +
out (3),a
 +
ld a,%00001010 ;Set 1st timer active
 +
out (3),a
 +
ld a,%00000110 ;Slowest frequency, ~110hz
 +
out (4),a
 +
 +
;i is the higher byte of the address that points to the
 +
;vector table.  The lower byte, for all practicality,
 +
;should be considered random.
 +
;
 +
ld a,$8B
 +
ld i,a
 +
im 2
 +
ei
 +
ret
 +
 +
 +
;This small function simply ends the installed interrupt.
 +
;This should be done prior to exit, or when it is not safe
 +
;to have a custom interrupt running.
 +
;
 +
Kill_ISR:
 +
di
 +
im 1
 +
ret
 +
 +
 +
Interrupt_Start:
 +
exx
 +
ex af,af'
 +
 +
;<- Interrupt Code Here
 +
;This code should be small and brief.
 +
;Assuming, that the interrupt is occurring 110 times a second, this
 +
;code would have to execute in (CPU_Speed / Frequency) tstates
 +
;ex: 6000000hz / 110hz = ~54545 tstates
 +
;
 +
;Failure to execute in that time would result in missing an
 +
;interrupt request, in other words you would skip interrupts.
 +
;
 +
;However using less than that amount of time, but near to it
 +
;would result in leaving little time for the main code's execution.
 +
;For example, if the timer generates interrupts every 54545 tstates,
 +
;and your interrupt code executes in 54000 tstates, you would leave
 +
;only 545 tstates for your main programs execution in that time slice.
 +
;The interrupt would take up 99% of the cpu time.
 +
;(This would be a likely issue in gray scale applications.)
 +
;
 +
 +
ld a,%00001000 ;Acknowledge and disable
 +
out (3),a
 +
ld a,%00001010 ;Set 1st timer active
 +
out (3),a
 +
ld a,%00000110 ;Slowest frequency, ~110hz
 +
out (4),a
 +
ex af,af'
 +
exx
 +
ei
 +
ret
 +
Interrupt_End:</nowiki>
 +
 +
  
 
== Credits and Contributions ==
 
== Credits and Contributions ==
'''Michael Vincent''': For documenting [http://www.michaelv.org/programs/calcs/ports/port3.html here] on the interrupt bits.
+
*'''Michael Vincent''': For documenting [http://www.michaelv.org/programs/calcs/ports/port3.html here] on the interrupt bits.
 +
*'''James Montelongo''': For documenting the interrupt bits.

Latest revision as of 22:26, 10 September 2013

Synopsis

Port Number: 03h

Function: Interrupt Masking Port

See also: 83Plus:Interrupts

This port controls what devices will be allowed to trigger interrupts. When an interrupt is triggered, it should be cleared by reseting the corresponding bit. Otherwise, it will continuously call the interrupt code once interrupts are reenabled with ei.

Read Values

  • Bit 0: Set if pressing the ON key will generate an interrupt.
  • Bit 1: Set if the first hardware timer will generate an interrupt (range: 108Hz-512Hz).
  • Bit 2: Set if the second hardware timer will generate an interrupt (range: 216Hz-1024Hz).
  • Bit 4: Set if the linkport will generate an interrupt.

Write Values

  • Bit 0: Set 1 to enable the ON key. Set 0 acknowledge the interrupt request and/or to disable it.
  • Bit 1: Set 1 to enable the first hardware timer. Set 0 acknowledge the interrupt request and/or to disable it.
  • Bit 2: Set 1 to enable the second hardware timer. Set 0 acknowledge the interrupt request and/or to disable it.
  • Bit 3: Set 0 to put the calculator in low power mode if and only if the Z80 cpu enters the halt state (during the executing of a halt instruction). Set 1 to keep the calculator powered.
  • Bit 4: Set 1 to enable the linkport interrupt. Set 0 acknowledge the interrupt request and/or to disable it. (Does not completely disable the linkport.)

Comments

  • For normal operation, write 0B (00001011) to this port. This will allow the first timer to generate interrupts, and the on key.
  • In low power mode it is known that at least the lcd driver enters standby mode and that the timer hardware has been disabled.

Example

Soft Powerdown

This example shows how to do a soft powerdown (similar to the auto powerdown) on the calculator. This may or may not wipe the LCD screen, so you should first copy its contents to a buffer like saveSScreen and then copy it back afterwards.

 push af
 ld a, 11h ;Enable linkport, ON key. Disable timer.
           ;Set low power mode.
 out (3), a
 halt      ;Enter low power mode (disabling various devices)
           ;and wait for an interrupt (either ON key or
           ;link activity) which will enable all hardware
           ;devices again.
 ld a, 0Bh ;Enable ON key, timer. Disable linkport.
           ;Keep calculator powered.
 out (3), a
 pop af

Simple Interrupt

This example will show how to set up the first timer for an interrupt and its use in the ISR. It will also show beyond just port 3 usage since this port requires more complex interaction for its typical use.

Install_ISR:

;Disabling interrupts prior to installation.
;This is in case an im 2 interrupt is already running.
;(MirageOS would present such a case.)
;
	di

;A 257 byte vector table(located in StatVars) is 
;filled with the same byte.  This byte will determine 
;the location of the interrupt code's start.
;If the table is filled with $XY then the code must be
;located at $XYXY.
;
	ld hl,$8B00
	ld (hl),$8A
	ld de,$8B01
	ld bc,256
	ldir

;The interrupt code is copied to a safe code buffer(StatVars).
;If the interrupt code is to large, you may alternatively
;place jp instruction in this code buffer that jumps to your
;interrupt code. Interrupt code should be located in ram. While
;nothing physically prevents use of bank4000 area, it is 
;commonly swapped out and so at the very least precautions
;would be required to use that area.
;
	ld hl,Interrupt_Start
	ld de,$8A8A
	ld bc,Interrupt_End-Interrupt_Start
	ldir

;You must designate what hardware will generate an interrupt.
;For safety, acknowledging any waiting requests may
;also be done.
;
	ld a,%00001000		;Acknowledge and disable
	out (3),a
	ld a,%00001010		;Set 1st timer active
	out (3),a
	ld a,%00000110		;Slowest frequency, ~110hz
	out (4),a

;i is the higher byte of the address that points to the
;vector table.  The lower byte, for all practicality,
;should be considered random.
;
	ld a,$8B
	ld i,a
	im 2
	ei
	ret


;This small function simply ends the installed interrupt.
;This should be done prior to exit, or when it is not safe
;to have a custom interrupt running.
;
Kill_ISR:
	di
	im 1
	ret


Interrupt_Start:
	exx
	ex af,af'

;<- Interrupt Code Here
;This code should be small and brief.
;Assuming, that the interrupt is occurring 110 times a second, this 
;code would have to execute in (CPU_Speed / Frequency) tstates
;ex: 6000000hz / 110hz = ~54545 tstates
;
;Failure to execute in that time would result in missing an 
;interrupt request, in other words you would skip interrupts.
;
;However using less than that amount of time, but near to it
;would result in leaving little time for the main code's execution.
;For example, if the timer generates interrupts every 54545 tstates,
;and your interrupt code executes in 54000 tstates, you would leave
;only 545 tstates for your main programs execution in that time slice.
;The interrupt would take up 99% of the cpu time.
;(This would be a likely issue in gray scale applications.)
;

	ld a,%00001000		;Acknowledge and disable
	out (3),a
	ld a,%00001010		;Set 1st timer active
	out (3),a
	ld a,%00000110		;Slowest frequency, ~110hz
	out (4),a
	ex af,af'
	exx
	ei
	ret
Interrupt_End:


Credits and Contributions

  • Michael Vincent: For documenting here on the interrupt bits.
  • James Montelongo: For documenting the interrupt bits.