Page 58,132 Title ANTIC.ASM ANTIC emulator ;****************************************************************************** ; ; Name: ANTIC ; ; Group: Emulator ; ; Revision: 0.00 ; ; Date: 07-13-94 ; ; Author: Michael Munoz ; ;****************************************************************************** ; ; Module Functional Description: ; ; These routines simulate all of the atari playfield graphics. ; All of the CITA graphics modes have been implemented. I do ; no know how to implement the GITA grpahics modes. ; Each routine is listed by its OS graphics mode number, ; i.e. Antic_mode2 is the OS graphics mode 2 (Basic mode 0). ; ;****************************************************************************** ; ; Changes: ; ; DATE REVISION DESCRIPTION ; -------- -------- ------------------------------------------------------- ; ;****************************************************************************** Page ; ; Public Declarations ; Public Antic_Update Public Antic_Blank Public Antic_Jmp Public Antic_mode2 Public Antic_mode3 Public Antic_mode4 Public Antic_mode5 Public Antic_mode6 Public Antic_mode7 Public Antic_mode8 Public Antic_mode9 Public Antic_modeA Public Antic_modeB Public Antic_modeC Public Antic_modeD Public Antic_modeE Public Antic_modeF Public Antic_dlist Public Antic_dinstr Public Antic_pc Public Antic_evcount Public Antic_memscan Public Antic_wait Public Antic_sc Public Antic_dliflag Public Video_Pntr_Cur Public Video_Pntr_Old Public sTOP Public sBOT Public instr_count Public Hsync ; External Declarations ; Extrn nmi_flag:Byte Extrn COUNT_Table:Byte Extrn Flag_Encode:Byte Extrn Exit:Near ; ; Define any include files needed ; Include Macros.inc ; Include the macro definitions Include Equates.inc ; Include the equate definitions Include Atari.inc ; Atari equates ; Local MACROS ; ; The DLITEST macro is used to determine whether we need call ; the display list interrupt routine. If a DLI is required ; a flag is set and tested in Hardware_Update() in Hardware.asm ; DLITEST macro local No_DLI mov bl,cs:Antic_dinstr ; ***bl is dinstr*** test bl,B7 ; DLI enabled? je No_DLI mov di,LB_NMIEN ; nmi enabled? mov al,Antic_ram[di] test al,80h je No_DLI mov di,NMIST ; update NMI status mov Byte Ptr [di],80h ; set msb mov cs:[nmi_flag],1 ; set dli flag No_DLI: endm ; ; Determines the width of the screen, and saves any overscan in ; Antic_Overscan. ; GET_OVERSCAN macro SHIFT mov di,LB_DMACTL ; short address for dmactl register mov al,Antic_ram[di] ; get dmactl from antic ram ; Get the size of the screen > 320 (ignore narrow playfield) and al,B0 ; get wide playfield bit shl al,SHIFT+1 ; get size of block for the mode shr al,1 xor ah,ah mov cs:Antic_Overscan,ax ; save overscan endm ; ; Tests to see if memory scan counter needs to be reloaded ; and reloads if required. ; RELOAD macro local _No_Reload ; get the address of the Atari display data mov si,cs:Antic_memscan ; get display memory address ; Assume dinstr is in bl test bl,B6 ; do we need to reload memscan? je _No_Reload ; no, take jmp mov di,cs:Antic_pc ; get current dlist counter inc di ; get next byte mov si,[di] ; get memory pointer in si inc di ; point to current dlist byte mov cs:Antic_pc,di ; save current instruction count _No_Reload: mov cs:Antic_Old_memscan,si endm ; ; This macro updates the extended vertical scan counter ; and performs a test for display list interrupt ; EVC_UPDATE macro SC local On_Screen local Off_Display local _No_Reload DLITEST ; update scan count here so that we know that current scan line ; for PM graphics which are done after playfield graphics. mov ax,cs:Antic_evcount ; Update antic vertical line counter add ax,cs:Antic_sc ; add previous scan line count mov cs:Antic_evcount,ax ; save back in cs:Antic_evcount cmp ax,cs:sTOP ; past top of display? jl Off_Display cmp ax,sBOT ; last displayed horizontal line jbe On_Screen ; current scan line within display Off_Display: test bl,B6 ; do we need to reload memscan? je _No_Reload ; no, take jmp mov di,cs:Antic_pc ; get current dlist counter mov si,[di+1] ; get memory pointer in si mov cs:Antic_memscan,si add cs:Antic_pc,2 _No_Reload: mov cs:Antic_sc,SC inc cs:Antic_pc ; point to next instruction popa ret On_Screen: endm ; ; The Get_Colors macro reads the colors from the atari ram and ; orders the colors in a more useable fashion in COLOR_TABLE ; ; uses bp, al and di Get_Colors macro mov di,LB_COLBK mov al,Gita_ram[di] mov bx,0 mov cs:COLOR_TABLE[bx],al mov di,LB_COLPF0 mov al,Gita_ram[di] inc bx mov cs:COLOR_TABLE[bx],al inc di mov al,Gita_ram[di] inc bx mov cs:COLOR_TABLE[bx],al inc di mov al,Gita_ram[di] inc bx mov cs:COLOR_TABLE[bx],al inc di mov al,Gita_ram[di] inc bx mov cs:COLOR_TABLE[bx],al endm ; ; The Write_Color macro is used in graphics mode d ; Write color uses al, di and dx Write_Color_2 macro mov bh,cs:COLOR_TABLE[bp] ; convert to a color mov es:[di],bh ; write color to screen inc di mov es:[di],bh ; write color to screen again inc di endm ; ; The Write_Color_4 macro is used in graphics mode A ; Write color uses al, di and dx Write_Color_4 macro mov bh,cs:COLOR_TABLE[bp] ; convert to a color mov es:[di],bh ; write color to screen inc di mov es:[di],bh ; write color to screen again inc di mov es:[di],bh ; write color to screen inc di mov es:[di],bh ; write color to screen again inc di endm ; ; The Write_Color_8 macro is used in graphics mode 8 ; Write color uses al, di and dx Write_Color_8 macro mov bh,cs:COLOR_TABLE[bp] ; convert to a color mov es:[di],bh ; write color to screen inc di mov es:[di],bh ; write color to screen again inc di mov es:[di],bh ; write color to screen inc di mov es:[di],bh ; write color to screen again inc di mov es:[di],bh ; write color to screen inc di mov es:[di],bh ; write color to screen again inc di mov es:[di],bh ; write color to screen inc di mov es:[di],bh ; write color to screen again inc di endm .286c ; Include 80286 instructions Page ; ; Define the emulator code segment ; Emulate Segment Word Public 'EMULATE' ; Emulator code segment Assume cs:Emulate, ds:Nothing, es:Nothing even ;Memory for ANTIC instr_count DW 128d ; Number of 6502 clocks before the ; next Hardware update Hsync DW 128d sTOP DW 32d ; top of screen sBOT DW 224d ; bottom of screen Video_Pntr_Cur DW 0 ; points to next screen location Video_Pntr_Old DW 0 ; Old screen position Antic_dlist DW 0 ; display list address Antic_dinstr DB 0 ; current DL instruction Antic_pc DW 0 ; current DL program counter Antic_evcount DW 0 ; current vertical count Antic_memscan DW 0 ; memory location of display Antic_Old_memscan DW 0 Antic_Overscan DW 0 Antic_wait DB 0 ; wait for vsync flag Antic_sc DW 0 ; Antic_dliflag DB 0 ; dli interrupt requested? ch1 DB 0 ; holds Antic_shift DW ? index_k DW ? ; used for looping index_i DW ? index_j DW ? temp DW ? ; Table of current colors COLOR_TABLE EQU This Byte DB 0 DB 0 DB 0 DB 0 DB 0 Subttl ANTIC_blank Page + ;****************************************************************************** ; ; ANTIC_blank ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax,cx - restored ; ; Function: ; ; Increments the vertical counter to simulate adding blank lines ; on the screen. ; ;****************************************************************************** Even ; Force procedure to even address Antic_Blank Proc Near push cx ; checks for a display list instruction request ; and get the current display instruction in bl. DLITEST ; get background color mov di,LB_COLBK mov cl,Gita_ram[di] mov ch,cl ; Update scan line mov ax,cs:Antic_evcount ; get current scan line add ax,cs:Antic_sc mov cs:Antic_evcount,ax ; updata evcount ; determine number of blank lines shr bl,4 ; move upper fours bits and bl,07h ;get lower three bits inc bl ;add one ; save number of blank lines in Antic_sc for Player_Missle() xor bh,bh ; make a word mov cs:Antic_sc,bx ; save the number of blank lines ; See if blank lines cross the top of the IBM display add ax,bx ; add number of blank lines sub ax,cs:sTOP ; less top of screen ; if ax = Antic_evcount + Antic_sc - sTOP is negative or zero jle Not_On_Screen cmp bx,ax ; get smaller of two in bx jge Smaller_ax mov ax,bx Smaller_ax: ; get current video pointer mov di,cs:Video_Pntr_Cur ; save as old pointer for Player_Missle() in Gita.asm mov cs:Video_Pntr_Old,di Blank_Loop: mov bx,160d Blank_Pixel_Loop: mov Word Ptr es:[di],cx ; write blank add di,2 dec bx jne Blank_Pixel_Loop dec ax jne Blank_Loop mov cs:Video_Pntr_Cur,di ;update video pointer Not_On_Screen: mov ax,cs:Hsync shl ax,3 ; assume 8 scan lines mov cs:instr_count,ax ; cs:Hsync*number of blank lines inc cs:Antic_pc ; get next disp. intsruction pop cx ret Antic_Blank ENDP Subttl ANTIC_JMP Page + ;****************************************************************************** ; ; ANTIC_JMP ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax,di - restored ; ; Function: ; ; Reloads the the display list address and sets the ; Antic_wait (wait for vertical blank) flag if ; required. ; ;****************************************************************************** Even ; Force procedure to even address Antic_Jmp Proc Near ; checks for a display list instruction request ; and get the current display instruction in bl. DLITEST ; this mode reloads the display list address mov di,cs:Antic_pc ; get Antic program counter inc di ; point to next byte mov al,[di] ; get lo byte of display list addr inc di ; point to next byte mov ah,[di] ; get hi byte of display list addr mov cs:Antic_dlist,ax ; update display list ; update scan count mov cs:Antic_sc,0 ; Player_Missle() will not display ; anything this time. mov ax,cs:Hsync ; Run Hardware_update after mov cs:instr_count,ax ; next scan line. ; see if wait for vertical blank test bl,B6 je No_JVB mov cs:Antic_wait,1 ; set wait for vert. blank flag ; clear to end of IBM display mov di,Video_Pntr_Cur Clear_Loop: cmp di,0fa00h ; max display jae Clear_Loop_Done mov Word Ptr es:[di],0 add di,2 jmp Clear_Loop Clear_Loop_Done: mov Video_Pntr_Cur,0 mov Video_Pntr_Old,0 No_JVB: ret Antic_Jmp ENDP Subttl ANTIC_mode2 Page + ;****************************************************************************** ; ; ANTIC_mode2 ; 40 text characters each 8x8 pixels ; 2 colors ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; none. ; ; Register Usage: ; bl - display list instruction ; bh - character control ; si - memory scan address (atari display data) ; dl - pfcol1 (foreground color) ; dh - pfcol2 (background color) ; bp - character table base address ; ; Comments: ; ; Vertical and horizontal scrolling is not implemented ; ;****************************************************************************** Even ; Force procedure to even address Antic_mode2 Proc Near pusha ; save all registers EVC_UPDATE 8 ; update vert. scan counter RELOAD ; see if we need to update memscan GET_OVERSCAN 2 ; determine value of horizontal overscan ; either 0 or 4 ; get the color values mov di,LB_COLPF1 ; read value for color pf1 mov dl,Gita_ram[di] ; dl = colpf1 inc di ; address of COLPF2 mov dh,Gita_ram[di] ; dh = colpf2 ; Get the character table address mov di,LB_CHBASE ; get chbase address mov ah,Antic_ram[di] ; get character base xor al,al ; starts on 256 boundry mov bp,ax ; save base in bp ; Save current IBM screen location for Player_Missle in Gita.asm mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; Get the character control value mov di,LB_CHACTL ; get chactl address mov bh,Antic_ram[di] ; keep in value bh ; start 8 vertical scan line loop mov index_k,0 ; initialize to zero Start_K_Loop: mov si,cs:Antic_Old_memscan ; get start of char. memory add si,cs:Antic_Overscan ; add overscan value ; Read in 40 characters mov index_i,40d ; 8 bytes per character Build_Character: mov bl,[si] ; save character name in bl inc si ; inc memscan to point to next character mov al,bl ; copy character name to al and ax,07fh ; strip of special display bit shl ax,3 ; 8 bytes per char. so mult. char. name by 8 add ax,index_k ; point to current row in char. table mov di,ax ; copy character table offset to di mov ah,ds:[bp][di] ; get char. display data from table ; point to by bp test bl,B7 ; test char. name, special bit set? je Not_Special ; no, take jmp test bh,B0 ; do we want to blank the char.? je No_Blank ; no, try inverse mov ah,0 ; blank character No_Blank: test bh,B1 ; inverse video? je No_Inverse ; no, display character not ah ; do inverse video No_Inverse: Not_Special: mov ch1,ah ; save display byte in ch1 mov di,Video_Pntr_Cur ; get the current IBM screen location mov cx,8h ; use cx as a pixel loop counter Pixel_Loop: mov es:[di],dh ; es points to IBM display ; write the background color rol ch1,1 ; get display bit into carry jnc Disp_Color2 ; if zero do nothing since we have already ; displayed the background color mov es:[di],dl ; otherwise display foreground color Disp_Color2: inc di ; point to next IBM screen location loopne Pixel_Loop ; dec cx and jmp if cx not equal to zero mov Video_Pntr_Cur,di ; update the video pointer dec index_i ; increment loop counter je Next_Char_Disp ; no, get next scan line jmp Build_Character ; no, continue Next_Char_Disp: inc index_k ; increment the char. counter cmp index_k,8d ; see if we have display all 8 scan lines je Loop_K_End ; see if we are finished jmp Start_K_Loop ; display the next scan line Loop_K_End: ; Account for wide playfield in display data memory add si,cs:Antic_Overscan ; For wide screens adjust for overscan mov cs:Antic_memscan,si ; save data pointer for next time inc cs:Antic_pc ;point to next display list instruction Antic_Mode2_Done: mov Antic_sc,8 ; Tell GITA how many scan lines were painted ; compute number of 6502 clock cycle until next hardware update mov ax,cs:Hsync shl ax,3 mov cs:instr_count,ax popa ; restore all registers ret Antic_mode2 ENDP Subttl ANTIC_mode3 Page + ;****************************************************************************** ; ; ANTIC_mode3 ; 40 text characters each 10x8 pixels ; 2 colors ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; none ; ; Register Usage: ; bl - display list instruction ; bh - character control ; si - memory scan address (atari display data) ; dl - pfcol1 (foreground color) ; dh - pfcol2 (background color) ; bp - character table base address ; ;****************************************************************************** Even ; Force procedure to even address Antic_mode3 Proc Near pusha ; save all registers EVC_UPDATE 10 ; update extended vert. counter RELOAD ; see if we need to reload memscan GET_OVERSCAN 2 ; see if we are using the wide screen mode mov di,LB_CHACTL ; get chactl address mov bh,Antic_ram[di] ; keep in value bh ; Get color values mov di,LB_COLPF1 ; get pointer to color PF1 mov dl,Gita_ram[di] ; dl = colpf1 inc di ; get pointer to color PF2 mov dh,Gita_ram[di] ; dh = colpf2 ; Get character base mov di,LB_CHBASE ; get chbase address mov ah,Antic_ram[di] ; get character base xor al,al ; starts on 256 boundry mov bp,ax ; save base in bp ; precompute partial display address mov ax,Video_Pntr_Cur ; get a pointer to the IBM display mov Video_Pntr_Old,ax ; save for use by GITA mov di,ax ; get a copy of the pointer in di mov cx,640d ; write two blank lines each 320 pixels Blank_2: mov es:[di],dh ; es: accesses the Video ram inc di ; point to next display location loopne Blank_2 ;loop until all 320 blank pixels are displayed mov Video_Pntr_Cur,di ; save new IBM screen position ; start 10 vertical scan line loop ; the character is 10 scan lines high mov index_k,1 ; skip first two lines Start_K_Loop_3: ; reload memscan at start of each display row mov si,Antic_Old_memscan ; get start of char. memory ; Critical timing loop. Read in 40 characters mov index_i,0h ; 8 bytes per character (4) Build_Character_3: ; cs:Antic_dinstr is no longer needed so we can use the bl register mov bl,[si] ; save atascii in bl inc si ; inc memscan mov ax,index_k ; get current index and ax,7 ; modulo 8 mov cs:temp,ax ; save in temp mov al,bl ; get atascii (2) and ax,07fh ; strip of special bit (4) shl ax,3 ; 8 bytes per character (*8) (8) add ax,cs:temp ; point to current row (3) mov di,ax ; use index register (2) mov ah,ds:[bp][di] ; character at [CHBASE+ch*8+cx] (21) test bl,B7 ; special bit set? (4) je Not_Special_3 ; no, take jmp (4,16) test bh,B0 ; blank ? (4) je No_Blank_3 ; no, try inverse (4,16) mov ah,0 ; blank character (4) No_Blank_3: test bh,B1 ; inverse video? (4) je No_Inverse_3 ; no, display character (4,16) not ah ; do inverse video (2) No_Inverse_3: Not_Special_3: mov ch1,ah ; save display byte mov di,Video_Pntr_Cur mov cx,8h Pixel_Loop_3: mov es:[di],dh rol ch1,1 ; get pixel value jnc Disp_Color3 ; diplay background color mov es:[di],dl ; use color2 Disp_Color3: inc di ; loopne Pixel_Loop_3 mov Video_Pntr_Cur,di inc index_i ; increment loop counter cmp index_i,40d ; displayed all 40 bytes? je Next_Char_Disp_3 ; yes, get next scan line jmp Build_Character_3 ; no, continue Next_Char_Disp_3: inc index_k ; increment the char. counter cmp index_k,9d ; 8 scan lines are done here je Loop_K_End_3 jmp Start_K_Loop_3 Loop_K_End_3: add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_Mode3_Done: mov Antic_sc,10d ; compute number of 6502 clock cycle until next hardware update mov ax,cs:Hsync mov cx,ax shl ax,3 shl cx,1 add ax,cx mov cs:instr_count,ax popa ; restore all registers ret Antic_mode3 ENDP Subttl ANTIC_mode4 Page + ;****************************************************************************** ; ; ANTIC_mode4 ; 40 characters each 8x8 pixels ; 5 colors ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; none ; ; Register Usage: ; bl - display list instruction ; si - memory scan address (atari display data) ; dx - character table base address ; ;****************************************************************************** Even ; Force procedure to even address Antic_mode4 Proc Near pusha EVC_UPDATE 8 ; update event counter RELOAD GET_OVERSCAN 2 ; character map address mov di,LB_CHBASE ; get chbase address mov ah,Antic_ram[di] ; get character base xor al,al ; starts on 256 boundry mov dx,ax ; save base in dx ; get current IBM screen location mov ax,Video_Pntr_Cur ; Video_pntr_Old is used in PM graphics mov Video_Pntr_Old,ax ; start 8 vertical scan line loop mov index_k,0 ; initialize to zero Start_K_Loop_4: mov si,Antic_Old_memscan ; get start of char. memory ; Critical timing loop. Read in 40 characters mov cx,40d ; 8 bytes per character (4) Build_Character_4: ; cs:Antic_dinstr is no longer needed so we can use the bl register Get_Colors ; macro to load color table mov bl,[si] ; save atascii in bl inc si ; inc memscan mov al,bl ; get atascii (2) and ax,07fh ; strip of special bit (4) shl ax,3 ; 8 bytes per cahracter (*8) (8) add ax,index_k ; point to current row (3) mov di,ax ; use index register (2) mov bp,dx mov ah,ds:[bp][di] ; character at [CHBASE+ch*8+cx] (21) mov ch1,ah ; save display byte test bl,B7 ; special bit set? (4) je Not_Special_4 ; no, take jmp (4,16) mov di,4 mov al,cs:COLOR_TABLE[di] mov cs:COLOR_TABLE[di-1],al ; use colorpf3 insread of colorpf2 Not_Special_4: ;get current location of the IBM screen into di mov di,Video_Pntr_Cur ; Write one bytes worth of graphics data to the IBM screen mov al,ch1 ; get the graphics data byte in ax xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits Write_Color_2 ; macro to write the data to display mov bp,ax ; uses bh, dx, di shr bp,4 and bp,03h Write_Color_2 mov bp,ax shr bp,2 and bp,03h Write_Color_2 mov bp,ax and bp,03h Write_Color_2 mov Video_Pntr_Cur,di dec cx ; increment loop counter je Next_Char_Disp_4 ; yes, get next scan line jmp Build_Character_4 ; no, continue Next_Char_Disp_4: ; add si,overscan ; add and overscan bytes inc index_k ; increment the char. counter cmp index_k,8d ; 8 scan lines are done here je Loop_K_End_4 jmp Start_K_Loop_4 Loop_K_End_4: add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_Mode4_Done: mov Antic_sc,8 mov ax,cs:Hsync shl ax,3 ; cs:Hsync*16*8 mov cs:instr_count,ax popa ; restore all registers ret Antic_mode4 ENDP Subttl ANTIC_mode5 Page + ;****************************************************************************** ; ; ANTIC_mode5 ; 40 characters each 16x8 pixels ; 5 colors ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; none ; ; Register Usage: ; bl - display list instruction ; si - memory scan address (atari display data) ; dx - character table base address ; ;****************************************************************************** Even ; Force procedure to even address Antic_mode5 Proc Near pusha EVC_UPDATE 16 ; update event counter RELOAD GET_OVERSCAN 2 ; character map address mov di,LB_CHBASE ; get chbase address mov dh,Antic_ram[di] ; get character base xor dl,dl ; starts on 256 boundry ; get current IBM screen location mov ax,Video_Pntr_Cur ; Video_pntr_Old is used in PM graphics mov Video_Pntr_Old,ax ; start 8 vertical scan line loop mov index_k,0 ; initialize to zero mov index_i,2 ; double scan Start_K_Loop_5: mov si,Antic_Old_memscan ; get start of char. memory ; Critical timing loop. Read in 40 characters mov cx,40d ; 8 bytes per character (4) Build_Character_5: ; cs:Antic_dinstr is no longer needed so we can use the bl register Get_Colors ; macro to load color table mov bl,[si] ; save atascii in bl inc si ; inc memscan mov al,bl ; get atascii (2) and ax,07fh ; strip of special bit (4) shl ax,3 ; 8 bytes per cahracter (*8) (8) add ax,index_k ; point to current row (3) mov di,ax ; use index register (2) mov bp,dx mov ah,ds:[bp][di] ; character at [CHBASE+ch*8+cx] (21) mov ch1,ah ; save display byte test bl,B7 ; special bit set? (4) je Not_Special_5 ; no, take jmp (4,16) mov di,4 mov al,cs:COLOR_TABLE[di] mov cs:COLOR_TABLE[di-1],al ; use colorpf3 insread of colorpf2 Not_Special_5: ;get current location of the IBM screen into di mov di,Video_Pntr_Cur ; Write one bytes worth of graphics data to the IBM screen mov al,ch1 ; get the graphics data byte in ax xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits Write_Color_2 ; macro to write the data to display mov bp,ax ; uses bh, dx, di shr bp,4 and bp,03h Write_Color_2 mov bp,ax shr bp,2 and bp,03h Write_Color_2 mov bp,ax and bp,03h Write_Color_2 mov Video_Pntr_Cur,di dec cx ; increment loop counter je Next_Char_Disp_5 ; yes, get next scan line jmp Build_Character_5 ; no, continue Next_Char_Disp_5: ; add si,overscan ; add and overscan bytes dec index_i je Displayed_two ; display two scan lines the same jmp Start_K_Loop_5 Displayed_two: mov index_i,2 ; double scan inc index_k ; increment the char. counter cmp index_k,8d ; 8 scan lines are done here je Loop_K_End_5 jmp Start_K_Loop_5 Loop_K_End_5: add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_Mode5_Done: mov Antic_sc,16d mov ax,cs:Hsync shl ax,4 ; cs:Hsync*16*16 mov cs:instr_count,ax popa ; restore all registers ret Antic_mode5 ENDP Subttl ANTIC_mode6 Page + ;****************************************************************************** ; ; ANTIC_mode6 ; 20 characters each 8x16 pixels ; 5 colors ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ; Register Usage: ; bl - display list instruction ; si - memory scan address (atari display data) ; dx - character table base address ; ;****************************************************************************** Even ; Force procedure to even address Antic_mode6 Proc Near pusha EVC_UPDATE 8 ; update event counter RELOAD GET_OVERSCAN 1 ; character map address mov di,LB_CHBASE ; get chbase address mov ah,Antic_ram[di] ; get character base xor al,al ; starts on 256 boundry mov dx,ax ; save base in dx ; get current IBM screen location mov ax,Video_Pntr_Cur ; Video_pntr_Old is used in PM graphics mov Video_Pntr_Old,ax ; start 8 vertical scan line loop mov index_k,0 ; initialize to zero Start_K_Loop_6: mov si,Antic_Old_memscan ; get start of char. memory ; Critical timing loop. Read in 40 characters mov cx,20d ; 8 bytes per character (4) Build_Character_6: ; cs:Antic_dinstr is no longer needed so we can use the bl register Get_Colors ; macro to load color table mov bl,[si] ; save atascii in bl inc si ; inc memscan mov al,bl ; get atascii (2) and ax,03fh ; strip of special bit (4) shl ax,3 ; 8 bytes per character (*8) (8) add ax,index_k ; point to current row (3) mov di,ax ; use index register (2) mov bp,dx mov ah,ds:[bp][di] ; character at [CHBASE+ch*8+cx] (21) mov ch1,ah ; save display byte Not_Special_6: ;get current location of the IBM screen into di mov di,Video_Pntr_Cur mov index_i,8 Pixel_Loop_6: ; Write one bytes worth of graphics data to the IBM screen mov al,bl ; get the color data xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits inc bp ; get higher set of colors rol ch1,1 ; get data bit jc Use_Colors_6 mov bp,0 ; use background color Use_Colors_6: Write_Color_2 dec index_i jne Pixel_Loop_6 mov Video_Pntr_Cur,di dec cx ; increment loop counter je Next_Char_Disp_6 ; yes, get next scan line jmp Build_Character_6 ; no, continue Next_Char_Disp_6: ; add si,overscan ; add and overscan bytes inc index_k ; increment the char. counter cmp index_k,8d ; 8 scan lines are done here je Loop_K_End_6 jmp Start_K_Loop_6 Loop_K_End_6: add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_Mode6_Done: mov Antic_sc,8 mov ax,cs:Hsync shl ax,3 ; cs:Hsync*16*8 mov cs:instr_count,ax popa ; restore all registers ret Antic_mode6 ENDP Subttl ANTIC_mode7 Page + ;****************************************************************************** ; ; ANTIC_mode7 ; 20 characters each 16x16 pixels ; 5 colors ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ; Register Usage: ; bl - display list instruction ; si - memory scan address (atari display data) ; dx - character table base address ; ;****************************************************************************** Even ; Force procedure to even address Antic_mode7 Proc Near pusha EVC_UPDATE 16 ; update event counter RELOAD GET_OVERSCAN 1 ; character map address mov di,LB_CHBASE ; get chbase address mov ah,Antic_ram[di] ; get character base xor al,al ; starts on 256 boundry mov dx,ax ; save base in dx ; get current IBM screen location mov ax,Video_Pntr_Cur ; Video_pntr_Old is used in PM graphics mov Video_Pntr_Old,ax ; start 8 vertical scan line loop mov index_k,0 ; initialize to zero mov index_j,2 Start_K_Loop_7: mov si,Antic_Old_memscan ; get start of char. memory ; Critical timing loop. Read in 40 characters mov cx,20d ; 8 bytes per character (4) Build_Character_7: ; cs:Antic_dinstr is no longer needed so we can use the bl register Get_Colors ; macro to load color table mov bl,[si] ; save atascii in bl inc si ; inc memscan mov al,bl ; get atascii (2) and ax,03fh ; strip of special bit (4) shl ax,3 ; 8 bytes per character (*8) (8) add ax,index_k ; point to current row (3) mov di,ax ; use index register (2) mov bp,dx mov ah,ds:[bp][di] ; character at [CHBASE+ch*8+cx] (21) mov ch1,ah ; save display byte Not_Special_7: ;get current location of the IBM screen into di mov di,Video_Pntr_Cur mov index_i,8 Pixel_Loop_7: ; Write one bytes worth of graphics data to the IBM screen mov al,bl ; get the color data xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits inc bp ; get higher set of colors rol ch1,1 ; get data bit jc Use_Colors_7 mov bp,0 ; use background color Use_Colors_7: Write_Color_2 dec index_i jne Pixel_Loop_7 mov Video_Pntr_Cur,di dec cx ; increment loop counter je Next_Char_Disp_7 ; yes, get next scan line jmp Build_Character_7 ; no, continue Next_Char_Disp_7: ; add si,overscan ; add and overscan bytes dec index_j je Double_Scan_Done_7 jmp Start_K_Loop_7 Double_Scan_Done_7: mov index_j,2 inc index_k ; increment the char. counter cmp index_k,8d ; 8 scan lines are done here je Loop_K_End_7 jmp Start_K_Loop_7 Loop_K_End_7: add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_Mode7_Done: mov Antic_sc,16 mov ax,cs:Hsync shl ax,4 ; cs:Hsync*16*16 mov cs:instr_count,ax popa ; restore all registers ret Antic_mode7 ENDP ;****************************************************************************** ; ; ANTIC_mode8 ; Graphics mode block size 8x8 ; 4 colors ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ;****************************************************************************** Antic_mode8 Proc Near pusha EVC_UPDATE 8 ; update event counter RELOAD GET_OVERSCAN 0 ; get colors and store in COLOR_TABLE Get_Colors ; CX, AL, DI ARE USED ; There are 320 pixels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do eight scan lines in this loop mov cx,10d ; initialize to zero mov index_k,8 ; do this loop 8 times mov di,Video_Pntr_Cur ; get IBM screen location Start_K_Loop_8: ; get current atari screen memory byte mov bl,[si] ; save graphics data in bl inc si ; point to graphics next byte ; Write one bytes worth of graphics data to the IBM screen mov al,bl ; get the graphics data byte in ax xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits Write_Color_8 ; macro to write the data to display mov bp,ax ; uses bh, dx, di shr bp,4 and bp,03h Write_Color_8 mov bp,ax shr bp,2 and bp,03h Write_Color_8 mov bp,ax and bp,03h Write_Color_8 dec cx ; decrement the char. counter jne Continue_Loop_8 ; mov cx,10d ; reset bytes/per scan line counter dec index_k je Loop_K_End_8 mov si,cs:Antic_Old_memscan ; reload memory scan counter Continue_Loop_8: jmp Start_K_Loop_8 Loop_K_End_8: mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_Mode8_Done: mov Antic_sc,8 mov ax,cs:Hsync shl ax,3 ; cs:Hsync*16*8 mov cs:instr_count,ax popa ; restore all registers ret Antic_mode8 ENDP ;****************************************************************************** ; ; ANTIC_mode9 ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ;****************************************************************************** Antic_mode9 Proc Near pusha EVC_UPDATE 4 ; update event counter RELOAD GET_OVERSCAN 0 ; get colors and store in COLOR_TABLE mov di,LB_COLPF0 mov dl,Gita_ram[di] ; dl = colpf0 mov di,LB_COLBK mov dh,Gita_ram[di] ; dh = colbk mov cs:Antic_memscan,si ; There are 320 pixels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do eight scan lines in this loop mov cx,10d ; initialize to zero mov index_k,4 ; do this loop 8 times mov di,Video_Pntr_Cur ; get IBM screen location Start_K_Loop_9: ; get current atari screen memory byte mov bl,[si] ; save graphics data in bl inc si ; point to graphics next byte ; Write one bytes worth of graphics data to the IBM screen mov ah,bl ; get the graphics data byte in ax mov index_i,8 Loop_i_9: mov es:[di],dh mov es:[di+1],dh mov es:[di+2],dh mov es:[di+3],dh rol ax,1 ; get pixel value jnc Disp_Color9 ; diplay background color mov es:[di],dl ; use color2 mov es:[di+1],dl mov es:[di+2],dl mov es:[di+3],dl Disp_Color9: add di,4 dec index_i jne Loop_i_9 dec cx ; decrement the b/s counter jne Continue_Loop_9 ; mov cx,10d ; reset bytes/per scan line counter dec index_k ; dec display scan line count je Loop_K_End_9 mov si,cs:Antic_memscan ; reload memory scan counter Continue_Loop_9: jmp Start_K_Loop_9 Loop_K_End_9: mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_Mode9_Done: mov Antic_sc,4 mov ax,cs:Hsync shl ax,2 ; cs:Hsync*16*4 mov cs:instr_count,ax popa ; restore all registers ret Antic_mode9 ENDP ;****************************************************************************** ; ; ANTIC_modeA ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ;****************************************************************************** Antic_modeA Proc Near pusha EVC_UPDATE 4 ; update event counter RELOAD GET_OVERSCAN 1 ; get colors and store in COLOR_TABLE Get_Colors ; CX, AL, DI ARE USED mov cs:Antic_memscan,si ; There are 320 pixels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do eight scan lines in this loop mov cx,20d ; initialize to zero mov index_k,4 ; do this loop 8 times mov di,Video_Pntr_Cur ; get IBM screen location Start_K_Loop_A: ; get current atari screen memory byte mov bl,[si] ; save graphics data in bl inc si ; point to graphics next byte ; Write one bytes worth of graphics data to the IBM screen mov al,bl ; get the graphics data byte in ax xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits Write_Color_4 ; macro to write the data to display mov bp,ax ; uses bh, dx, di shr bp,4 and bp,03h Write_Color_4 mov bp,ax shr bp,2 and bp,03h Write_Color_4 mov bp,ax and bp,03h Write_Color_4 dec cx ; decrement the char. counter jne Continue_Loop_A ; mov cx,20d ; reset bytes/per scan line counter dec index_k je Loop_K_End_A mov si,cs:Antic_memscan ; reload memory scan counter Continue_Loop_A: jmp Start_K_Loop_A Loop_K_End_A: mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_ModeA_Done: mov Antic_sc,4 mov ax,cs:Hsync shl ax,2 ; cs:Hsync*16*4 mov cs:instr_count,ax popa ; restore all registers ret Antic_modeA ENDP ;****************************************************************************** ; ; ANTIC_modeB ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ;****************************************************************************** Antic_modeB Proc Near pusha EVC_UPDATE 2 ; update event counter RELOAD GET_OVERSCAN 1 ; get colors and store in COLOR_TABLE mov di,LB_COLPF0 mov dl,Gita_ram[di] ; dl = colpf0 mov di,LB_COLBK mov dh,Gita_ram[di] ; dh = colbk mov cs:Antic_memscan,si ; There are 320 pixels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do eight scan lines in this loop mov cx,20d ; initialize to zero mov index_k,2 ; do this loop 2 times mov di,Video_Pntr_Cur ; get IBM screen location Start_K_Loop_B: ; get current atari screen memory byte mov bl,[si] ; save graphics data in bl inc si ; point to graphics next byte ; Write one bytes worth of graphics data to the IBM screen mov ah,bl ; get the graphics data byte in ax mov index_i,8 Loop_i_B: mov es:[di],dh mov es:[di+1],dh rol ax,1 ; get pixel value jnc Disp_ColorB ; diplay background color mov es:[di],dl ; use color2 mov es:[di+1],dl Disp_ColorB: add di,2 dec index_i jne Loop_i_B dec cx ; decrement the b/s counter jne Continue_Loop_B ; mov cx,20d ; reset bytes/per scan line counter dec index_k ; dec display scan line count je Loop_K_End_B mov si,cs:Antic_memscan ; reload memory scan counter Continue_Loop_B: jmp Start_K_Loop_B Loop_K_End_B: mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_ModeB_Done: mov Antic_sc,2 mov ax,cs:Hsync shl ax,1 ; cs:Hsync*16*2 mov cs:instr_count,ax popa ; restore all registers ret Antic_modeB ENDP ;****************************************************************************** ; ; ANTIC_modeC ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ;****************************************************************************** Antic_modeC Proc Near pusha EVC_UPDATE 1 ; update event counter RELOAD GET_OVERSCAN 2 ; get colors and store in COLOR_TABLE mov di,LB_COLPF0 mov dl,Gita_ram[di] ; dl = colpf0 mov di,LB_COLBK mov dh,Gita_ram[di] ; dh = colbk mov cs:Antic_memscan,si ; precompute partial display address ; There are 320 pixels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do eight scan lines in this loop mov cx,20d ; initialize to zero mov di,Video_Pntr_Cur ; get IBM screen location Start_K_Loop_C: ; get current atari screen memory byte mov bl,[si] ; save graphics data in bl inc si ; point to graphics next byte ; Write one bytes worth of graphics data to the IBM screen mov ah,bl ; get the graphics data byte in ax mov index_i,8 Loop_i_C: mov es:[di],dh mov es:[di+1],dh rol ax,1 ; get pixel value jnc Disp_ColorC ; diplay background color mov es:[di],dl ; use color2 mov es:[di+1],dl Disp_ColorC: add di,2 dec index_i jne Loop_i_C dec cx ; decrement the b/s counter jne Start_K_Loop_C ; Loop_K_End_C: mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_ModeC_Done: mov Antic_sc,1 mov ax,cs:Hsync mov cs:instr_count,ax popa ; restore all registers ret Antic_modeC ENDP Subttl ANTIC_modeD Page + ;****************************************************************************** ; ; ANTIC_modeD 160x96x4 ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; none ; ;****************************************************************************** Even ; Force procedure to even address Antic_modeD Proc Near pusha EVC_UPDATE 2 ; update event counter RELOAD GET_OVERSCAN 2 ; get colors and store in COLOR_TABLE Get_Colors ; CX, AL, DI ARE USED mov cs:Antic_memscan,si ; There are 320 poxels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do two scan lines in this loop mov cx,0 ; initialize to zero mov di,Video_Pntr_Cur Start_K_Loop_D: ; get current atari screen memory byte mov bl,[si] ; save graphics in bl inc si ; point to next byte ; Write one bytes worth of graphics data to the IBM screen mov al,bl ; get the graphics data byte in ax xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits Write_Color_2 ; macro to write the data to display mov bp,ax ; uses bh, dx, di shr bp,4 and bp,03h Write_Color_2 mov bp,ax shr bp,2 and bp,03h Write_Color_2 mov bp,ax and bp,03h Write_Color_2 inc cx ; increment the char. counter cmp cx,40d ; two scan lines jne Continue_Loop_D ; mov si,cs:Antic_memscan Continue_Loop_D: cmp cx,80d je Loop_K_End_D jmp Start_K_Loop_D Loop_K_End_D: mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_ModeD_Done: mov Antic_sc,2 mov ax,cs:Hsync shl ax,1 ; cs:Hsync*16*2 mov cs:instr_count,ax popa ; restore all registers ret Antic_modeD ENDP ;****************************************************************************** ; ; ANTIC_modeE 160x191x4 ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; none ; ;****************************************************************************** Even ; Force procedure to even address Antic_modeE Proc Near pusha EVC_UPDATE 1 ; update event counter RELOAD GET_OVERSCAN 2 ; get colors and store in COLOR_TABLE Get_Colors ; CX, AL, DI ARE USED mov cs:Antic_memscan,si ; There are 320 poxels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do two scan lines in this loop mov cx,0 ; initialize to zero mov di,Video_Pntr_Cur Start_K_Loop_E: ; get current atari screen memory byte mov bl,[si] ; save graphics in bl inc si ; point to next byte ; Write one bytes worth of graphics data to the IBM screen mov al,bl ; get the graphics data byte in ax xor ah,ah ; make a word mov bp,ax ; copy ax shr bp,6 ; get lefmost two bits Write_Color_2 ; macro to write the data to display mov bp,ax ; uses bh, dx, di shr bp,4 and bp,03h Write_Color_2 mov bp,ax shr bp,2 and bp,03h Write_Color_2 mov bp,ax and bp,03h Write_Color_2 inc cx ; increment the char. counter cmp cx,40d ; two scan lines jne Start_K_Loop_E ; mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_ModeE_Done: mov Antic_sc,1 mov ax,cs:Hsync mov cs:instr_count,ax popa ; restore all registers ret Antic_modeE ENDP ;****************************************************************************** ; ; ANTIC_modeF ; ; Registers on Entry: ; ; none ; ; Registers on Exit: ; ; ax - destroyed ; di - destroyed ; ;****************************************************************************** Antic_modeF Proc Near pusha EVC_UPDATE 1 ; update event counter mov bl,cs:Antic_dinstr ; bl is dinstr (display list instruc.) ; All of these tests take time, for speed these may be deleted ; at the cost of ocasionally running into a error in the display. mov di,LB_DMACTL ; short address for dmactl register mov al,Antic_ram[di] ; get dmactl from antic ram test al,B1 ; playfield enabled? jne Get_Overscan_F ; yes, continue jmp Antic_ModeF_Done ; no, exit Get_Overscan_F: mov si,cs:Antic_memscan ; get display memory address test bl,B6 ; do we need to reload memscan? je No_Reload_F ; no, take jmp mov di,cs:Antic_pc ; get current dlist counter inc di ; get next byte mov si,[di] ; get memory pointer in si inc di ; point to current dlist byte mov cs:Antic_pc,di ; save current instruction count No_Reload_F: ; get colors and store in COLOR_TABLE mov di,LB_COLPF1 mov dl,Gita_ram[di] ; dl = colpf0 mov di,LB_COLPF2 mov dh,Gita_ram[di] ; dh = colpf1 mov cs:Antic_memscan,si ; There are 320 pixels per vertical IBM display line ; so 320 bytes x current vertical scan line gives the ; IBM video memory offset for the current display line ; precompute partial display address mov ax,Video_Pntr_Cur mov Video_Pntr_Old,ax ; do eight scan lines in this loop mov cx,40d ; initialize to zero mov di,Video_Pntr_Cur ; get IBM screen location Start_K_Loop_F: ; get current atari screen memory byte mov bl,[si] ; save graphics data in bl inc si ; point to graphics next byte ; Write one bytes worth of graphics data to the IBM screen mov ah,bl ; get the graphics data byte in ax mov index_i,8 Loop_i_F: mov es:[di],dh rol ax,1 ; get pixel value jnc Disp_ColorF ; diplay background color mov es:[di],dl ; use color2 Disp_ColorF: inc di dec index_i jne Loop_i_F dec cx ; decrement the b/s counter jne Start_K_Loop_F ; Loop_K_Fnd_F: mov Video_Pntr_Cur,di add si,cs:Antic_Overscan mov cs:Antic_memscan,si ; save for next time inc cs:Antic_pc ; point to next instruction Antic_ModeF_Done: mov Antic_sc,1 mov ax,cs:Hsync mov cs:instr_count,ax popa ; restore all registers ret Antic_modeF ENDP ;****************************************************************************** ; ; Update Antic pseudo registers ; ; Entry: ; al: data ; di: EA ; ; uses: di,ax ;****************************************************************************** Antic_Update Proc Near cmp di,NMIRES ;reset nmi status? jne Not_nmireset ;no mov Word Ptr [di], 0 ;reset status ret Not_nmireset: cmp di,WSYNC ;wait for cs:Hsync? jne Not_wsync ;no mov bp,30 ; mov bp,cs:Hsync ; force harware update ; shl bp,5 ret Not_wsync: cmp di,DLISTH ;are we updating dlist je Is_dlist ;yes cmp di,DLISTL ;check both high and low addresses je Is_dlist ;yes jmp Antic_update_exit ;no dlist update Is_dlist: mov [di],al ;save to atari ram push ax mov di,DLISTH ; mov ah,ds:[di] ;get dlist high value in ah mov di,DLISTL ; mov al,ds:[di] ;get dlist low value in al mov cs:Antic_dlist,ax ;save in cs:Antic_dlist pop ax Antic_update_exit: and di,01fh ;update antic ram space... mov Antic_ram[di],al ;just in case ret Antic_Update Endp ;***************************************************************************** ; ; Define the end of the Emulator Code Segment ; ;****************************************************************************** Emulate Ends End ; End of the Hardware module