mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 22:13:13 -06:00
Preliminary Support for Interrupt Management API
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
HBIOS Management Functions
|
||||
==========================
|
||||
|
||||
RESET: ($F0):
|
||||
RESET ($F0):
|
||||
B=Function A=Result
|
||||
|
||||
VER ($F1):
|
||||
@@ -52,7 +52,7 @@ GET ($F8):
|
||||
VDACNT ($40):
|
||||
BC=Function/Subfunction A=Result
|
||||
E=Video Unit Count
|
||||
|
||||
|
||||
TIMER ($D0):
|
||||
BC=Function/Subfunction A=Result
|
||||
DE:HL=Timer Value (32 bit)
|
||||
@@ -90,17 +90,101 @@ SET ($F9):
|
||||
DE=Boot Volume (Disk Unit/Slice)
|
||||
L=Boot Bank Id
|
||||
|
||||
PEEK: ($FA):
|
||||
PEEK ($FA):
|
||||
B=Function A=Result
|
||||
D=Bank E=Byte Value
|
||||
HL=Address
|
||||
|
||||
POKE: ($FB):
|
||||
POKE ($FB):
|
||||
B=Function A=Result
|
||||
D=Bank
|
||||
E=Byte Value
|
||||
HL=Address
|
||||
|
||||
INT ($FC): Interrupt vector management functions
|
||||
BC=Function/Subfunction A=Result
|
||||
|
||||
Subfunctions:
|
||||
|
||||
INTINF ($00): Query interrupt system information
|
||||
BC=Function/Subfunction A=Result
|
||||
D=Interrupt Mode
|
||||
E=Interrupt Vector Table Size
|
||||
|
||||
Report interrupt interrupt management system information.
|
||||
|
||||
Interrupt Mode:
|
||||
0: Interrupts disabled
|
||||
1: Z80 Interrupt Mode 1 active
|
||||
2: Z80 Interrupt Mode 2 active
|
||||
|
||||
Interrupt Vector Table Size:
|
||||
If interrupts are disabled, this will be zero. if interrupt mode 1, this
|
||||
will be the number of entries in the interrupt call list. if interrupt mode
|
||||
2, this will be the number of slots in the interrupt vector table.
|
||||
|
||||
INTGET ($10): Get interrupt vector
|
||||
BC=Function/Subfunction A=Result
|
||||
E=Interrupt Vector Table Position HL=Interrupt Vector
|
||||
|
||||
Return the Interrupt Vector for the specified Interrupt Vector Table Position.
|
||||
|
||||
INTSET ($20): Set interrupt vector
|
||||
BC=Function/Subfunction A=Result
|
||||
HL=Interrupt Vector HL=Previous Vector
|
||||
E=Interrupt Vector Table Position DE=Interrupt Routing Engine Address
|
||||
|
||||
Set the Interrupt Vector for the specified Interrupt Vector Table Position to the
|
||||
specified Interrupt Vector. The previous value at the specified table position
|
||||
will be returned. The Vector Table Position is a zero-based index into the
|
||||
interrupt vector table and must specify a position less than or equal to the
|
||||
size of the table.
|
||||
|
||||
The new interrupt vector must point to a proper interrupt handler located in the
|
||||
top 32K of CPU address space. Note that during interrupt processing, the lower
|
||||
32K of CPU address space will contain the RomWBW HBIOS code bank, not the lower
|
||||
32K of application TPA. As such, a dynamically installed interrupt handler does
|
||||
not have access to the lower 32K of TPA and must be careful to avoid modifying
|
||||
the contents of the lower 32K of memory. Invoking RomWBW HBIOS functions within
|
||||
an interrupt handler is not supported. The interrupt management framework takes
|
||||
care of saving and restoring AF, BC, DE, HL, and IY. Any other registers modified
|
||||
must be saved and restored by the interrupt handler.
|
||||
|
||||
Interrupt handlers are different for IM1 or IM2.
|
||||
|
||||
For IM1:
|
||||
|
||||
The new interrupt handler is responsible for chaining (JP) to the previous vector
|
||||
if the interrupt is not handled. The interrupt handler must return with ZF set
|
||||
if interrupt is handled and ZF cleared if not handled.
|
||||
|
||||
For IM2:
|
||||
|
||||
The interrupt handler requires an invocation stub separate from the actual interrupt
|
||||
handling code. The stub must be:
|
||||
|
||||
PUSH HL
|
||||
LD HL,<adr of actual interrupt handler>
|
||||
JP <adr of int routing engine>
|
||||
|
||||
When calling Set Interrupt Vector, the address of the stub must be provided for the
|
||||
Interrupt Vector parameter. The address of the Interrupt Routing Engine will be
|
||||
returned in DE and must be inserted into the stub code as indicated above. In the
|
||||
case of IM2 mode interrutps, the actual interrupt handler should not chain to the
|
||||
previous entry. The new interrupt handler must assume all responsibilities for
|
||||
the specific interrupt slot being occupied.
|
||||
|
||||
If the caller is transient, then the caller must remove the new interrupt handler and
|
||||
restore the original one prior to termination. This is accomplished by calling this
|
||||
function with the Interrupt Vector set to the Previous Vector returned in the original
|
||||
call.
|
||||
|
||||
The caller is responsible for disabling interrupts prior to making an INTSET call and
|
||||
enabling them afterwards. The caller is responsible for ensuring that a valid interrupt
|
||||
handler is installed prior to enabling any hardware interrupts associated with the handler.
|
||||
Also, if the handler is transient, the caller must disable the hardware interrupt(s)
|
||||
associated with the handler prior to uninstalling it.
|
||||
|
||||
================
|
||||
Serial Functions
|
||||
================
|
||||
@@ -167,7 +251,7 @@ DEVICE ($06):
|
||||
|
||||
Serial Device Attributes Byte:
|
||||
7: 0=RS-232, 1=Terminal
|
||||
|
||||
|
||||
If Terminal, 3-0 is attached Video Unit #
|
||||
|
||||
==============
|
||||
@@ -234,18 +318,18 @@ DEVICE ($17)
|
||||
|
||||
Disk Device Attributes Byte:
|
||||
7: 1=Floppy, 0=Hard Disk (or similar, e.g. CF, SD, RAM)
|
||||
|
||||
|
||||
If Floppy:
|
||||
6-5: Form Factor (0=8", 1=5.25", 2=3.5", 3=Other)
|
||||
4: Sides (0=SS, 1=DS)
|
||||
3-2: Density (0=SD, 1=DD, 2=HD, 3=ED)
|
||||
1-0: Reserved
|
||||
|
||||
|
||||
If Hard Disk:
|
||||
6: Removable
|
||||
5-3: Type (0=Hard, 1=CF, 2=SD, 3=USB, 4=ROM, 5=RAM, 6=RAMF, 7=?)
|
||||
2-0: Reserved
|
||||
|
||||
|
||||
Note: IDE value 848Ah in IDENTIFY DEVICE data word 0 indicates CF Card
|
||||
|
||||
MEDIA ($18):
|
||||
@@ -277,7 +361,7 @@ GEOMETRY ($1B):
|
||||
D:7=LBA Capable
|
||||
E=Sectors
|
||||
BC=Block Size
|
||||
|
||||
|
||||
Report current media geometry information.
|
||||
If media is unknown, return error (no media)
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ $ImgFile = "${OutDir}/${RomName}.img" # Final name of IMG image (memory loadable
|
||||
if ($Platform -eq "UNA") {$CBiosFile = '../CBIOS/cbios_una.bin'} else {$CBiosFile = '../CBIOS/cbios_wbw.bin'}
|
||||
|
||||
# List of RomWBW proprietary apps to imbed in ROM disk.
|
||||
$RomApps = "assign","fdu","format","mode","osldr","rtc","survey","syscopy","sysgen","talk","timer","xm"
|
||||
$RomApps = "assign","fdu","format","mode","osldr","rtc","survey","syscopy","sysgen","talk","timer","xm","inttest"
|
||||
|
||||
""
|
||||
"Building ${RomName}: ${ROMSize}KB ROM configuration ${Config} for Z${CPUType}..."
|
||||
|
||||
@@ -491,6 +491,25 @@ HBX_IVT:
|
||||
.DW INT_BAD ;
|
||||
.DW INT_BAD ;
|
||||
;
|
||||
HBX_IVTCNT .EQU ($ - HBX_IVT) / 2
|
||||
;
|
||||
HBX_ITBL:
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
.DW HB_BADINT
|
||||
#ENDIF
|
||||
;
|
||||
; INTERRUPT HANDLER STUBS
|
||||
@@ -1465,6 +1484,8 @@ SYS_DISPATCH:
|
||||
JP Z,SYS_PEEK ; $FA
|
||||
DEC A
|
||||
JP Z,SYS_POKE ; $FB
|
||||
DEC A
|
||||
JP Z,SYS_INT ; $FC
|
||||
CALL PANIC ; INVALID
|
||||
;
|
||||
; SOFT RESET HBIOS, RELEASE HEAP MEMORY NOT USED BY HBIOS
|
||||
@@ -1740,6 +1761,123 @@ SYS_POKE:
|
||||
XOR A
|
||||
RET
|
||||
;
|
||||
; INTERRUPT MANAGEMENT FUNCTIONS
|
||||
; SUBFUNCTION IN C
|
||||
;
|
||||
SYS_INT:
|
||||
LD A,C ; GET REQUESTED SUB-FUNCTION
|
||||
CP BF_SYSINT_INFO
|
||||
JR Z,SYS_INTINFO
|
||||
CP BF_SYSINT_GET
|
||||
JR Z,SYS_INTGET
|
||||
CP BF_SYSINT_SET
|
||||
JR Z,SYS_INTSET
|
||||
OR $FF ; SIGNAL ERROR
|
||||
RET
|
||||
;
|
||||
; GET INTERRUPT SYSTEM INFORMATION
|
||||
; RETURN D:=INTERRUPT MODE, E:=INT VEC TABLE SIZE
|
||||
;
|
||||
SYS_INTINFO:
|
||||
LD D,INTMODE ; D := ACTIVE INTERRUPT MODE
|
||||
#IF (INTMODE == 0)
|
||||
LD E,0 ; 0 ENTRIES IF INTERRUPTS DISABLED
|
||||
#ENDIF
|
||||
#IF (INTMODE == 1)
|
||||
LD A,(HB_IM1CNT) ; RETURN IM1 CALL LIST SIZE
|
||||
LD E,A
|
||||
#ENDIF
|
||||
#IF (INTMODE == 2)
|
||||
LD E,HBX_IVTCNT ; RETURN INT VEC TABLE SIZE
|
||||
#ENDIF
|
||||
XOR A ; INDICATE SUCCESS
|
||||
RET ; AND DONE
|
||||
;
|
||||
; ROUTINE SHARED BY INT GET/SET. RETURNS ADDRESS OF VECTOR FOR SPECIFIED LIST / TABLE
|
||||
; POSITION. ZF SET ON RETURN FOR SUCCESS, ELSE ERROR.
|
||||
;
|
||||
SYS_INTVECADR:
|
||||
#IF (INTMODE == 0)
|
||||
CALL PANIC ; INVALID FOR INT MODE 0
|
||||
OR $FF
|
||||
RET
|
||||
#ENDIF
|
||||
#IF (INTMODE == 1)
|
||||
LD A,(HB_IM1CNT) ; GET CURRENT ENTRY COUNT
|
||||
INC A ; ALLOW FOR EXTRA ENTRY TO APPEND AT END
|
||||
LD C,A ; SAVE IN C FOR COMPARE
|
||||
#ENDIF
|
||||
#IF (INTMODE == 2)
|
||||
LD C,HBX_IVTCNT ; GET CURRENT ENTRY COUNT
|
||||
#ENDIF
|
||||
LD A,E ; INCOMING INDEX POSITION TO A
|
||||
CP C ; COMPARE TO VECTOR COUNT
|
||||
JR C,SYS_INTGET1 ; CONTINUE IF POSITION IN RANGE
|
||||
CALL PANIC ; ELSE ERROR
|
||||
OR $FF
|
||||
RET
|
||||
SYS_INTGET1:
|
||||
OR A
|
||||
RLA ; HL := (A * 2) FOR IM2
|
||||
#IF (INTMODE == 1)
|
||||
RLA ; ... HL := (A * 4) + 1 FOR IM1
|
||||
INC A
|
||||
#ENDIF
|
||||
LD H,0
|
||||
LD L,A
|
||||
#IF (INTMODE == 1)
|
||||
LD DE,HB_IM1INT ; DE := START OF CALL LIST
|
||||
#ENDIF
|
||||
#IF (INTMODE == 2)
|
||||
LD DE,HBX_IVT ; DE := START OF VECTOR TABLE
|
||||
#ENDIF
|
||||
ADD HL,DE ; HL := ADR OF VECTOR
|
||||
XOR A ; INDICATE SUCCESS
|
||||
RET
|
||||
;
|
||||
; RETURN THE INTERRUPT VECTOR FOR A SPECIFIED POSITION IN THE INT VECTOR LIST / TABLE
|
||||
; ENTRY: E=LIST/TABLE POSITION
|
||||
; RETURN: HL=INTERRUPT VECTOR
|
||||
;
|
||||
SYS_INTGET:
|
||||
CALL SYS_INTVECADR ; GET VECTOR ADDRESS
|
||||
RET NZ ; BAIL OUT ON ERROR
|
||||
LD A,(HL) ; DEREF HL TO GET VECTOR
|
||||
INC HL
|
||||
LD H,(HL)
|
||||
LD L,A
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; DONE
|
||||
;
|
||||
; SET AN INTERRUPT VECTOR FOR A SPECIFIED POSITION IN THE INT VECTOR LIST / TABLE
|
||||
; ENTRY: E=LIST/TABLE POSITION, HL=NEW INTERRUPT VECTOR
|
||||
; RETURN: HL=PREVIOUS INTERRUPT VECTOR, DE=ADR OF INT ROUTING ENGINE FOR IM2
|
||||
;
|
||||
SYS_INTSET:
|
||||
PUSH HL ; SAVE NEW VECTOR
|
||||
CALL SYS_INTVECADR ; GET VECTOR ADDRESS
|
||||
JR Z,SYS_INTSET1 ; CONTINUE IF OK
|
||||
POP HL ; FIX STACK
|
||||
RET NZ ; BAIL OUT ON ERROR
|
||||
SYS_INTSET1:
|
||||
PUSH HL ; SAVE VECTOR ADDRESS
|
||||
LD A,(HL) ; DEREF HL TO GET PREV VECTOR
|
||||
INC HL
|
||||
LD H,(HL)
|
||||
LD L,A
|
||||
EX (SP),HL ; (SP) := PREV VEC, HL := VEC ADR
|
||||
POP DE ; DE := PREV VEC
|
||||
POP BC ; BC := NEW VEC
|
||||
LD (HL),C ; SAVE LSB
|
||||
INC HL
|
||||
LD (HL),B ; SAVE MSB
|
||||
EX DE,HL ; HL := PREV VEC
|
||||
#IF (INTMODE == 2)
|
||||
LD DE,HBX_INT ; DE := IM2 INT ROUTING ENGINE
|
||||
#ENDIF
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; DONE
|
||||
;
|
||||
;==================================================================================================
|
||||
; GLOBAL HBIOS FUNCTIONS
|
||||
;==================================================================================================
|
||||
@@ -1765,30 +1903,43 @@ CIO_IDLE:
|
||||
; CALL XXXX ; CALL INT HANDLER
|
||||
; RET NZ ; RETURN IF HANDLED
|
||||
;
|
||||
HB_IM1INT: ; IM1 DEVICE INTERRUPT HANDLER
|
||||
JP HB_BADINT
|
||||
RET ; START WITH NO ENTRIES
|
||||
.FILL 4 * 8,$C9 ; ROOM FOR 8 ENTRIES
|
||||
; NOTE THAT THE LIST IS INITIALLY FILLED WITH CALLS TO HB_BADINT.
|
||||
; AS THE TABLE IS POPULATED, THE ADDRESS OF HB_BADINT IS OVERLAID
|
||||
; WITH THE ADDRESS OF A REAL INTERRUPT HANDLER.
|
||||
;
|
||||
; THERE IS ROOM FOR 8 ENTRIES PLUS A FINAL CALL TO HB_BADINT.
|
||||
;
|
||||
HB_IM1INT: ; IM1 DEVICE INTERRUPT HANDLER CALL LIST
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
CALL HB_BADINT \ RET NZ
|
||||
;
|
||||
; ROUTINE BELOW IS USED TO ADD A NEW VECTOR TO THE IM1
|
||||
; CALL LIST ABOVE. ENTER WITH HL=VECTOR ADDRESS IN HBIOS
|
||||
;
|
||||
HB_ADDIM1:
|
||||
EX DE,HL ; VECTOR ADDRESS TO DE
|
||||
LD HL,(HB_IM1P) ; GET PTR FOR NEXT ENTRY
|
||||
LD (HL),$CD ; "CALL" OPCODE
|
||||
INC HL ; BUMP PTR
|
||||
LD HL,(HB_IM1PTR) ; GET PTR FOR NEXT ENTRY
|
||||
INC HL ; BUMP PTR TO ADDRESS FIELD OF CALL OPCODE
|
||||
LD (HL),E ; ADD VECTOR ADDRESS
|
||||
INC HL ; ...
|
||||
LD (HL),D ; ...
|
||||
INC HL ; BUMP PTR
|
||||
LD (HL),$C0 ; "RET NZ" OPCODE
|
||||
INC HL ; BUMP PTR
|
||||
LD (HL),$C9 ; FINAL "RET" OPCODE
|
||||
LD (HB_IM1P),HL ; SAVE POINTER
|
||||
LD (HB_IM1PTR),HL ; SAVE UPDATED POINTER
|
||||
LD HL,HB_IM1CNT ; POINT TO ENTRY COUNT
|
||||
INC (HL) ; INCREMENT
|
||||
RET ; DONE
|
||||
;
|
||||
HB_IM1P .DW HB_IM1INT ; POINTER FOR NEXT IM1 ENTRY
|
||||
HB_IM1CNT .DB 0 ; NUMBER OF ENTRIES IN CALL LIST
|
||||
HB_IM1MAX .DB 8 ; MAX ENTRIES IN CALL LIST
|
||||
HB_IM1PTR .DW HB_IM1INT ; POINTER FOR NEXT IM1 ENTRY
|
||||
;
|
||||
#ENDIF
|
||||
;
|
||||
@@ -1843,6 +1994,7 @@ HB_BADINT:
|
||||
PRTS("+++ BAD INT: $")
|
||||
CALL _REGDMP
|
||||
CALL CONTINUE
|
||||
OR $FF ; SIGNAL INTERRUPT HANDLED
|
||||
RET
|
||||
;
|
||||
; COMMON API FUNCTION DISPATCH CODE
|
||||
|
||||
@@ -65,6 +65,7 @@ BF_SYSGET .EQU BF_SYS + 8 ; GET HBIOS INFO
|
||||
BF_SYSSET .EQU BF_SYS + 9 ; SET HBIOS PARAMETERS
|
||||
BF_SYSPEEK .EQU BF_SYS + 10 ; GET A BYTE VALUE FROM ALT BANK
|
||||
BF_SYSPOKE .EQU BF_SYS + 11 ; SET A BYTE VALUE IN ALT BANK
|
||||
BF_SYSINT .EQU BF_SYS + 12 ; MANAGE INTERRUPT VECTORS
|
||||
;
|
||||
BF_SYSGET_CIOCNT .EQU $00 ; GET CHAR UNIT COUNT
|
||||
BF_SYSGET_DIOCNT .EQU $10 ; GET DISK UNIT COUNT
|
||||
@@ -78,6 +79,10 @@ BF_SYSGET_BNKINFO .EQU $F2 ; GET BANK ASSIGNMENT INFO
|
||||
BF_SYSSET_TIMER .EQU $D0 ; SET TIMER VALUE
|
||||
BF_SYSSET_BOOTINFO .EQU $E0 ; SET BOOT INFORMATION
|
||||
;
|
||||
BF_SYSINT_INFO .EQU $00 ; GET INTERRUPT SYSTEM INFO
|
||||
BF_SYSINT_GET .EQU $10 ; GET INT VECTOR ADDRESS
|
||||
BF_SYSINT_SET .EQU $20 ; SET INT VECTOR ADDRESS
|
||||
;
|
||||
; SERIAL DEVICE IDS
|
||||
;
|
||||
CIODEV_UART .EQU $00
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
#DEFINE RMN 9
|
||||
#DEFINE RUP 1
|
||||
#DEFINE RTP 0
|
||||
#DEFINE BIOSVER "2.9.1-pre.6"
|
||||
#DEFINE BIOSVER "2.9.1-pre.7"
|
||||
|
||||
Reference in New Issue
Block a user