I have included the code below for an interrupt routine I wrote, as well as the code for setting it up. The interrupt routine executes only once, and then Context_Sensitive_Get_Key, which uses ports, occurs indefinitely without a single timer interrupt. I would appreciate help on how to get this to work. However, I'm currently experimenting, so please do not offer suggestions about my code below besides getting the interrupt routine working--I'm afraid I will be annoyed at any suggestions that do not involve getting the interrupts working.
Oh, and DrawMapFull has nothing to do with it.
Start:
di
;Timing in the game, including "forcing" FPS depending
;on what speed we want, is done via interrupts.
;This is to achieve a consistant speed.
;So we need to load interrupt information.
ld hl, Play_One_SAD_Frame
ld de, $9A9A
ld bc, End_SAD_Frame - Play_One_SAD_Frame
ldir
ld a, $99
ld i, a
LD HL, $9900
LD DE, $9901
LD BC, 256
ld A, $9a
LD ($9900), A
LDIR
;This is where the game is loaded. Thus this code is run only once.
xor a ;Start with 0 buildings.
ld (BuildingCount), a
;The game requires user RAM.
ld hl,21000
ld de,$9d95
bcall(_InsertMem)
;Savescreen is used for saving data involving maps. Thus, we need to disable
;the APD so that the data will not be corrupted.
RES apdAble,(IY+apdFlags)
;Structure_Locations holds the locations of all buildings that could possibly exit,
;up to 200. Four bytes for each building: TileX, TileY, 6 bits for the building's
;ID, and 10 bits for the buildings HP.
Structure_Locations .equ $9D95 + 17500
;The Map Data, containing the tiles in tilemap form. Maps can be no bigger than
;3600 bytes, but a 3600 byte map requires 900 bytes for fog-of-war and collision
;information. Therefore, 4500 bytes is needed in this area.
MapData .equ $9D95 + 5000
;Tile Data. Requires 8000 bytes.
TileData .equ $9D95 + 9500
;To optimize the drawing of structures
Store_Structure_Sprite_Addresses:
; B_CALL _Load_Sprite_Data
B_CALL _Load_Map_Data
B_CALL _Load_Tile_Data
ld hl,2
ld (delta),hl
ld (DeltaPreserve), hl
ld a,1
ld (Num_Layers),a
xor a
ld h,a
ld a,(mapdata)
ld l,a
ld (mapheight),hl
ld a,(mapdata+1)
ld l,a
ld (Mapwidth),hl
ld hl,0
ld (MapY),hl
ld (MapX),hl
ld hl,TileData
ld (Tileptr),hl
ld hl,MapData+2
ld (MAPptr),hl
ld hl,Mapbuf1
ld (MapbufPtr),hl
ld hl,premap
ld (PreMapPTR),hl
IM 2
ei
call DrawMapFull
Loop:
call Context_Sensitive_Get_Key
jr Loop
Play_One_SAD_Frame:
;For those ASM experts out there, it sure looks like I'm making this
;interrupt routine too long with all the subroutines that are running.
;However, by including an interrupt counter and running certain subs only
;when it reaches a maximum, I can achieve a consistent frame rate and
;ensure that the interrupt routine doesn't call itself in the middle of itself.
EX AF, AF'
EXX
ld a, (Interrupt_Counter)
;cp Twenty_Frames_Per_Second
;jr z, SAD_Frame
inc a
ld (Interrupt_Counter), a
ld h, 0
ld l, a
B_CALL _DispHL
Exit_Interrupt_Routine:
EX AF, AF'
EXX
RET
SAD_Frame:
EX AF, AF'
EXX
xor a
ld (Interrupt_Counter), a
call DrawMapFull ;Only if the map doesn't need to be fully drawn.
ld a,(MapY)
and tile_width*8-1
ld h,a
ld e,PMAPWIDTH*Tile_width
call HxE
ld de,mapbuf1
add hl,de
ld de, plotsscreen
ld bc, 768
ldir
BIT MenuMode, (IY + flag)
call nz, Draw_Menu
BIT Cursor_Mode, (IY + flag)
call nz, Draw_Select_Cursor
call Continue_Building_Construction
ld hl, plotsscreen
call safecopy
RET
End_SAD_Frame:
EDIT: It just seems that the interrupt only runs once, even before Context_Sensitive_Get_Key starts. I tried placing a whole bunch of "HALT" routines immediately following the "ei", and the debugger says the calculator just stays there, as if interrupts have been disabled.