OPTROM Switching: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
== Overview == | == 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. | 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. | ||
Line 7: | Line 15: | ||
* minimize code size | * minimize code size | ||
* reduce execution time | * reduce execution time | ||
<code><pre> | <code><pre> |
Revision as of 20:15, 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
- minimize code size
- reduce execution time
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.