OPTROM Switching: Difference between revisions

From Bitchin100 DocGarden
Jump to navigationJump to search
No edit summary
Line 11: Line 11:
Some time was spent in developing an improved method to call main ROM from option ROM, and to handle interrupts from within the optrom.  This code was developed by John Hogerhius and Steve Adolph, inspired by work done by Mo Budlong.
Some time was spent in developing an improved method to call main ROM from option ROM, and to handle interrupts from within the optrom.  This code was developed by John Hogerhius and Steve Adolph, inspired by work done by Mo Budlong.


The goal was to  
The goal was to
* use only the stack
 
* minimize code size
* Use only the stack - no unsafe use of RAM variables
* reduce execution time
* Minimize code size
* Minimize execution time overhead
 
To these ends, the code is heavily optimized, making good use of the undocumented 8085 instructions.


<code><pre>
<code><pre>

Revision as of 20:17, 27 May 2010

Overview

On the Model 100 (unmodified), the lower 32K is always occupied by a ROM (Read-Only Memory). This is either the stock "BASIC ROM" or an Option ROM (OptROM).

If you are interested in creating your own OptROM, this article presents template assembly code to provide the fundamental facilities you need to put in place to implement a new OptROM.

Option ROM Code Template

Some time was spent in developing an improved method to call main ROM from option ROM, and to handle interrupts from within the optrom. This code was developed by John Hogerhius and Steve Adolph, inspired by work done by Mo Budlong.

The goal was to

  • Use only the stack - no unsafe use of RAM variables
  • Minimize code size
  • Minimize execution time overhead

To these ends, the code is heavily optimized, making good use of the undocumented 8085 instructions.


OPON:			.EQU	0FAA4H


;-----------------------------------------------------------------------
; ROM start
;-----------------------------------------------------------------------
	.org	0000h

RST0:	di
	JMP	program		; standard entry
	.DB	0,0,0,0
RST1:	RET
	.DB	0,0,0,0,0,0,0
RST2:	RET			;Not used
	.DB	0,0,0,0,0,0,0
RST3:	RET			;Not Used
	.DB	0,0,0,0,0,0,0
RST4:	RET			;Not Used
	.DB	0,0,0
TRAP:	DI
	CALL	INTCALL
RST5:	RET			;Not Used
	.DB	0,0,0
RST55:	DI
	CALL	INTCALL
RST6:	JMP	STDCALL		;RST 6 used as short call to a Standard ROM routine.
	.DB	0
RST65:	DI			;Replaces the 6.5 interrupt and sets up a call to 6.5 in Standard ROM
	CALL	INTCALL
RST7:	RET			;Not Used
	.DB	0,0,0
RST75: 	DI			;Replaces the 7.5 interrupt and sets up a call to 7.5 in Standard ROM
	CALL	INTCALL

	.org	0040h

OPON_img:			; auto copied on power up
				; 8 bytes
	PUSH	PSW		; temp store psw
	mvi	a,01h
	OUT	0E8H
	pop	psw	
	ret

	.db	00h




	.org	0048h

;---------------------------------------------------------
;The STDCALL routine allows a program running in the
;the Option ROM to call and return to an address in the
;Option ROM.
;Syntax is to use a RST 6 plus the address to be called.
;
; 		RST	6
; rvect-->	DW	04B44H  (cvect)
; pvect-->
;
;---------------------------------------------------------

STDCALL:			; 23 bytes
				; stack = rvect
	xthl
	inx 	h
	inx 	h
	xthl			; fix up first stack entry
				; stack = pvect
				; hl=hl'

	push	h			
	lxi 	h, OPON
	xthl			; stack = pvect, OPON
				; hl=hl'

	push 	h
	push 	d		; stack = pvect, OPON, hl', de'

	ldsi 	06h		; point de to stack location of return vector


	lhlx			; hl=pvect
	dcx 	h
	dcx 	h		; point hl=pvect-2
	xchg			; de=pvect-2
	lhlx			; hl=cvect

	pop 	d		; de=de'
	xthl			; hl=hl', stack= pvect, OPON, cvect

	jmp 	STDON


;---------------------------------------------------------
;Routine for the hardware traps.
;return address on entry is related to which interrupt occured.
; 
;		after interrupt occurs
; ivect		DI
;		call	INTCALL
; rvect -->
; so stack = pvect, rvect
;---------------------------------------------------------

INTCALL:			; final stack must be opon, introutine
				; interrupts are off
				; enter with return location on stack, indicating int routine
				; stack = pvect, rvect
				; 20 bytes
	push	h	
	push	d		; stack = pvect, rvect, hl', de'

	ldsi	04h

	lhlx			; hl= rvect

	dcx	h
	dcx	h
	dcx	h
	dcx	h		; hl = ivect

	push	h		; stack = pvect, rvect, hl', de', ivect

	lxi	h,OPON
	shlx			; stack = pvect, OPON, hl', de', ivect

	pop	h		; hl=ivect
	pop	d		; de=de'

	xthl			; stack = pvect, OPON, ivect
				; hl=hl', de=de'

	jmp	STDON

;---------------------------------------------------------
;OPEXIT/STDON: Turns off the Option ROM (or turns on Standard ROM)
;---------------------------------------------------------
	.org	0085h

STDON:
	PUSH	PSW
	PUSH	H		; 26C8, F1 C9  POP PSW, RET
	LXI	H,26C8H		; it returns to this location --> pop psw; ret
	XTHL

OPEXIT:				; return to location pushed on stack
	xra	a
	OUT	0E8H
	RET			; RET can be found at 008EH in stdrom
				; in both M100 and T200


EXIT:
	.org	00094H
	pop	h
	lxi	h,0000h
	xthl			; restart

	jmp	OPEXIT



Demo program for an option rom


Note that in some instances one might need to use the data stored in FF45 to preseve the state of thinks like the cassette relay. In that case, it is relatively simple to extend this to cover FF45 support properly.