Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix interrupt handling in DOS 1 mode #107

Merged
merged 1 commit into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 68 additions & 111 deletions source/kernel/bank0/init.mac
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,7 @@ OVERRIDE:
SLAVE:
ld a,(KER250##+3)
or a
ret nz ;Return if four 2.50 kernels initialized already
ret nz ;Return if four Nextor kernels initialized already

call VALTBL ;get number of drives declared so far
ret z ;no room is left
Expand Down Expand Up @@ -1480,42 +1480,10 @@ endif
ld hl,(HIMEM##) ;save HIMEM
ld (HIMSAV##),hl ;
;
ld hl,H.TIMI ;Save the current setting of
push hl ; the timer interrupt hook
ld de,TIMI_SAVE## ; in our data area.
ld bc,5
ldir
;===== start add DOS2.50 (support MegaSCSI)
ld hl,_TIME_IRQ##
ld de,@TIME_IRQ##
call MYHOOK
;===== end add DOS2.50
pop hl ;Now set up an inter-slot call

;This "patch for MegaSCSI" was causing the kanji mode to not work
;(CALL KANJI hanging the computer)
;since the Kanji ROM timer interrupt routine assumes that the
;previous hook is either a RET or a RST 30h (not a CALL!)
if 0
;===== start mod DOS2.50 (support MegaSCSI)
ld de,_TIME_IRQ## ; to our timer interrupt
ld (hl),0;NOP ; routine in this ROM page.
inc hl
ld (hl),0CDh;CALL
inc hl
ld (hl),e
inc hl
ld (hl),d
inc hl
ld (hl),0C9h;RET
else
ld hl,TIMI_SAVE##
ld de,@TIME_IRQ##
call MYHOOK
endif
call SAVE_AND_PATCH_HTIMI

;; ld de,@TIME_IRQ##
;; call MYHOOK
;===== end mod DOS2.50
;
; Establish extended BIOS hook
;
Expand Down Expand Up @@ -2111,36 +2079,46 @@ endif
;
;------------------------------------------------------------------------------
;
; Timer interrupt handler.
;
; Note that both in normal mode and in DOS 1 mode jumping to the previous
; hook will trigger the chain of interrupt routines for the drivers
; attached to MSX-DOS 1 kernels (each will call its "previous hook"
; as configured in HOOKSAV).

TIMINT::
push af ;Save VDP status
ld a,(DOS_VER##)
or a
jr nz,DOS2INT

;Interrupt handler, DOS 1 version

call TIMI_250 ;Call 2.50 kernels driver interrupt routine.
ex af,af'
pop af ;Restore VDP status
ex af,af'
ld a,3
ld ix,PRV1INT##
jp CALBNK##
;Interrupt handler, DOS 1 mode version

call TIMI_NEXTOR_DRV ;Call interrupt routine for Nextor drivers.
pop af ;Restore VDP status.
jp TM1_SAVE## ;Jump to the previous interrupt routine.


;Interrupt handler, DOS 2 version
;Interrupt handler, normal ("DOS 2 mode") version

DOS2INT:
call TIME_IRQ## ;Call the master interrupt routine.
call TIMI_DRV ;Call driver interrupt routine in turn.
call TIMI_250 ;Call 2.50 kernels driver interrupt routine.
pop af ;Restore VDP status
jp TIMI_SAVE##
call TIMI_DOS2_DRV ;Call interrupt routines of drivers attached to DOS 2 kernels.
call TIMI_NEXTOR_DRV ;Call interrupt routine for Nextor drivers.
pop af ;Restore VDP status.
jp TIMI_SAVE## ;Jump to the previous interrupt routine.

TIMI_DRV:

TIMI_DOS2_DRV:
;
; Call all possible disk drivers interrupt which is combined with
; new DOS2 code. This is because the disk drivers entry may not
; be revealed at this point (because of local banking)
; Call the interrupt routines of drivers attached to MSX-DOS 2 kernels.
; These are the ones that have an entry in HOOKSAV whose slot number matches
; the entry with the same index in DRVTBL, thus representing a "my hook" entry
; (if the slot number is different then the HOOKSAV entry has been
; set by a driver attached to a MSX-DOS 1 kernel, and in this case
; it represents a "previous hook" entry and the driver itself will call it
; at the end of its own interrupt routine).
;
ld de,DRVTBL
ld hl,HOOKSAV
Expand All @@ -2151,26 +2129,22 @@ scan_loop:
ret z ; yes, done

inc de
ld a,(de) ;Get slot address
ld a,(de) ;Get slot address from DRVTBL
inc de
cp (hl) ; same?
jr nz,next_cart ; no, this has been set by
; old SETINT
ld a,(MASTER_SLOT##)
cp (hl) ;Is it me?
ld a,(hl) ; assume not
cp (hl) ; same slot number in equivalent HOOKSAV entry?
jr nz,next_cart ; no, HOOKSAV entry has been set by DOS 1 SETINT
ld a,(hl) ; slot number
push bc ; save count
push de ; DRVTBL pointer
push hl ; HOOKSAV pointer
inc hl
ld e,(hl)
inc hl
ld d,(hl)
push af
pop iy
db 0FDh,67h ;LD IYh,A
push de
pop ix
call call_drv
call CALSLT
pop hl
pop de
pop bc
Expand All @@ -2181,21 +2155,18 @@ next_cart:
djnz scan_loop
ret
;
call_drv:
jp nz,CALSLT ;Was slave, call thru inter-slot call
jp (ix) ;Was me, just call my slot.
;
;
TIMI_250:
TIMI_NEXTOR_DRV:
;
; Call the interrupt routine of DOS 2.50 kernels
; Call the interrupt routine of all drivers attached to Nextor kernels.
;
ld hl,KER250
ld b,4
T250_LOOP:
TNEX_LOOP:
ld a,(hl)
bit 6,a ;Zero if empty entry or if no interrupt declared
jr z,T250_DJNZ
jr z,TNEX_DJNZ

push hl
push bc
Expand All @@ -2210,11 +2181,15 @@ T250_LOOP:
pop bc
pop hl

T250_DJNZ:
TNEX_DJNZ:
inc hl
djnz T250_LOOP
djnz TNEX_LOOP
ret

call_drv:
jp nz,CALSLT ;Was slave, call thru inter-slot call
jp (ix) ;Was me, just call my slot.

;
;public PROMPT
PROMPT:
Expand Down Expand Up @@ -2346,35 +2321,6 @@ ADDHLBC:
add hl,bc
ret

;
; Define disk driver's timer interrupt entry
;
; HL = timer interrupt entry address
;
public SETINT
SETINT:
ex de,hl ; de = interrupt entry
call GSLOT1##
push af ; save slot number
call GET_DISKID_HL
ld a,(hl) ;(DISKID) ; make a pointer to HOOKSAV
ld hl,HOOKSAV
call ADDHLBC
add hl,bc
add hl,bc
pop af
ld (hl),a
inc hl
ld (hl),e
inc hl
ld (hl),d
;
; Return from disk driver interrupt (was jump to previous hook in DOS1)
;
public PRVINT
PRVINT:
ret

;
;-----------------------------------------------------------------------
;
Expand Down Expand Up @@ -2943,17 +2889,9 @@ olddos_9:
ld de,@EXTBIO##
call MYHOOK

ld a,3 ;Do a DOS1 style SETINT
ld ix,SET1INT##
ld hl,@TIME_IRQ##
call CALBNK##

;ld a,(FCALSAV##) ;TODO: Investigate why FCALSAV is all zeros
;or a ;at this point (should be all RETs)
;jr nz,FCALSAV_OK
;ld a,0C9h ;Code for RET
;ld (FCALSAV##),a
;FCALSAV_OK:
ld hl,TM1_SAVE##
ld de,@TIME_IRQ##
call SAVE_AND_PATCH_HTIMI

ld a,3
ld (MAIN_BANK##),a
Expand All @@ -2962,6 +2900,25 @@ olddos_9:
push hl ; CLEAN+11h (just after RET P) of
ld a,3 ; INIT.Z80, not INIT.MAC (this code).
jp CHGBNK


; Make a copy of H.TIMI hook and then patch it to point to another address
; of our slot via interslot call.
;
; In: HL = Address for the copy
; DE = New destination address (in main Nextor kernel) for the hook

SAVE_AND_PATCH_HTIMI:
push de
ex de,hl
ld hl,H.TIMI
push hl
ld bc,5
ldir
pop hl
pop de
jp MYHOOK

;
;
;===== start add DOS2.50 (build type)
Expand Down
53 changes: 2 additions & 51 deletions source/kernel/bank3/dos1ker.mac
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,7 @@ SET_SLOT:
pop iy
ret

ALIGN 04115h-6
jp SETINT
jp PRVINT
ALIGN 04115h

; Subroutine store date
; Inputs
Expand Down Expand Up @@ -5662,55 +5660,8 @@ A5FF3: ld c,a
add hl,bc
ret

; Subroutine install my diskdriver interrupt handler
; Inputs HL = pointer to interrupt handler
; Outputs -
; Remark used by the diskdriver

SETINT:
A5FF6: ld a,(H.TIMI+0)
cp 0C9H
jr z,A6012 ; H.TIMI not hooked, skip saving H.TIMI
push hl
ld a,(DEVICE) ; this diskdriver number
ld hl,YFB29
call A5FF1
add hl,bc
add hl,bc ; get DRVINT pointer
ex de,hl
ld hl,H.TIMI+1
ld c,003H
ldir ; save slotid and address (assumes that is hooked by a CALLF!)
pop hl
A6012: di
ld a,0F7H
ld (H.TIMI+0),a
ld (H.TIMI+2),hl ; diskdriver interrupt handler
ld a,0C9H
ld (H.TIMI+4),a
call A402D
ld (H.TIMI+1),a ; slotid of this diskdriver
ret
ALIGN 603Dh

; Subroutine call orginal interrupt handler
; Inputs -
; Outputs -
; Remark used by the diskdriver

PRVINT:
A6027: push af
call A402D ; slotid of this diskdriver
ld b,4
ld de,YFB29
ld hl,YFB21+1
A6033: cp (hl) ; is this my DRVTBL entry ?
jr z,A603F ; yep, get the saved interrupt handler and jump to it
inc de
inc de
inc de
inc hl
inc hl
djnz A6033 ; next DRVTBL and DRVINT entry
A603D: pop af
ret ; quit

Expand Down
24 changes: 4 additions & 20 deletions source/kernel/data.mac
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ ram_ad defl DATABASE
var1 TIM_TICK ;Deferred timeout counter for unit descriptor
; timeouts.
;
var TIMI_SAVE,5 ;Save address for old interrupt hook.
var TIMI_SAVE,5 ;Save address for old interrupt hook
;(in DOS 1 mode TM1_SAVE is used instead)
;
var2 MAP_TAB ;Pointer to mapper records.
;
Expand Down Expand Up @@ -270,15 +271,12 @@ ram_ad defl DATABASE
const DVB_TABLE,P0_64K ;Pointer to table of device-based drives for DOS1
const KSLOT,P2_64K ;Slot of disk controller being called (used in DOS 1 mode)
;
;===== start mod DOS2.50 (support MegaSCSI)
var1 NXT_VER ;Nextor version numbr
var1 MAIN_BANK
var1 MAIN_BANK ;Will be 0 in normal mode or 3 in DOS 1 mode
var KER250,4 ;Nextor kernel slots,
;bit 6 is set if timer interrupt routine is to be called
;bit 5 is set if the driver provides configuration
var _TIME_IRQ,5,F31E
;; spare 11
;===== end mod DOS2.50
var TM1_SAVE,5,F31E ;Save address for old interrupt hook (used in DOS 1 mode)
;
; ------------------------
;
Expand Down Expand Up @@ -584,20 +582,6 @@ ram_ad defl 4100h
var0 DV_MTOFF
var3 DEV_CMD

;-----------------------------------------------------------------------------
;
; DOS 1 bank routines for interrupt management

ram_ad defl 04115h-6

var3 SET1INT
var3 PRV1INT

;-----------------------------------------------------------------------------
;
; Fields in the disk amulation mode table


;-----------------------------------------------------------------------------
;

Expand Down