Author Topic: Interrupt routine not executing  (Read 5035 times)

0 Members and 1 Guest are viewing this topic.

Offline Hot_Dog

  • CoT Emeritus
  • LV12 Extreme Poster (Next: 5000)
  • *
  • Posts: 3006
  • Rating: +445/-10
    • View Profile
Interrupt routine not executing
« on: July 02, 2010, 07:34:35 am »
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.  

Code: [Select]

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.
« Last Edit: July 02, 2010, 11:33:54 am by Hot_Dog »

Offline Quigibo

  • The Executioner
  • CoT Emeritus
  • LV11 Super Veteran (Next: 3000)
  • *
  • Posts: 2031
  • Rating: +1075/-24
  • I wish real life had a "Save" and "Load" button...
    • View Profile
Re: Interrupt routine not executing
« Reply #1 on: July 02, 2010, 12:21:34 pm »
You have to reset the interrupt timer at the end of your interrupt routine so it can start triggering again.

Right where your "Exit_Interrupt_Routine:" is you should insert the following code:
Code: [Select]
ld a,%00001000
out (3),a
ld a,%00001010
out (3),a

Also, if your interrupt code is longer or close to the frequency of an interrupt, you'll want to disable interrupts for the routine and then re-enable them on exit.
___Axe_Parser___
Today the calculator, tomorrow the world!

Offline Hot_Dog

  • CoT Emeritus
  • LV12 Extreme Poster (Next: 5000)
  • *
  • Posts: 3006
  • Rating: +445/-10
    • View Profile
Re: Interrupt routine not executing
« Reply #2 on: July 02, 2010, 02:39:29 pm »
Thanks Quigibo and Iambian, I now have everything working.  I also shortened my routine so that it wouldn't be longer than the frequency.