Mercurial > hg > Members > kono > nitros9-code
view level1/modules/ccio.asm @ 1583:2d73cd04596b
More comments
author | boisy |
---|---|
date | Fri, 21 May 2004 15:14:45 +0000 |
parents | e19a38f50c3a |
children | 0e3a28789196 |
line wrap: on
line source
******************************************************************** * CCIO - OS-9 Level One V2 CoCo I/O driver * * $Id$ * * Edt/Rev YYYY/MM/DD Modified by * Comment * ------------------------------------------------------------------ * 12 ????/??/?? ??? * From Tandy OS-9 Level One VR 02.00.00. * * 12r1 2003/09/11 Rodney V. Hamilton * Modified key table to include $7F, $1D, $1E and $1F codes. nam CCIO ttl OS-9 Level One V2 CoCo I/O driver ifp1 use defsfile use scfdefs use cciodefs endc tylg set Drivr+Objct atrv set ReEnt+rev rev set $01 edition set 12 mod eom,name,tylg,atrv,start,size rmb V.SCF u001D rmb 7 u0024 rmb 1 u0025 rmb 1 u0026 rmb 2 u0028 rmb 1 u0029 rmb 4 ScreenX rmb 1 ScreenY rmb 1 u002F rmb 1 u0030 rmb 1 u0031 rmb 1 u0032 rmb 1 u0033 rmb 2 u0035 rmb 2 u0037 rmb 9 u0040 rmb 2 u0042 rmb 2 u0044 rmb 1 u0045 rmb 2 u0047 rmb 1 u0048 rmb 1 u0049 rmb 2 u004B rmb 5 u0050 rmb 1 u0051 rmb 1 WrChar rmb 1 CoInUse rmb 2 u0055 rmb 6 u005B rmb 2 u005D rmb 2 u005F rmb 1 u0060 rmb 1 u0061 rmb 2 u0063 rmb 2 u0065 rmb 1 u0066 rmb 1 u0067 rmb 1 u0068 rmb 1 u0069 rmb 1 u006A rmb 1 u006B rmb 1 u006C rmb 1 u006D rmb 1 u006E rmb 1 u006F rmb 1 u0070 rmb 1 trulocas rmb 1 CoEnt equ . GRFOEnt rmb 6 IBufHead rmb 1 IBufTail rmb 1 u007A rmb 128 size equ . fcb UPDAT.+EXEC. name fcs /CCIO/ fcb edition start lbra Init lbra Read lbra Write lbra GetStat lbra SetStat lbra Term * Init * * Entry: * Y = address of device descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Init stu >D.KbdSta store devmem ptr clra clear A leax <V.SCF,u point to memory after V.SCF ldb #$5D get counter L002E sta ,x+ clear mem decb decrement counter bne L002E continue if more coma A = $FF comb B = $FF stb <VD.Caps,u std <u005F,u std <u0061,u lda #60 sta <u0051,u leax >AltIRQ,pcr get IRQ routine ptr stx >D.AltIRQ store in AltIRQ leax >L03CC,pcr stx <u005B,u leax >L050F,pcr stx <u005D,u ldd <IT.PAR,y get parity and baud lbra L05CE process them * Term * * Entry: * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Term pshs cc orcc #IRQMask mask interrupts ldx >D.Clock get clock vector stx >D.AltIRQ and put back in AltIRQ puls pc,cc * Read * * Entry: * Y = address of path descriptor * U = address of device memory area * * Exit: * A = character read * CC = carry set on error * B = error code * Read leax <VD.InBuf,u point X to input buffer ldb <VD.IBufT,u get tail pointer orcc #IRQMask mask IRQ cmpb <VD.IBufH,u same as head pointer beq Put2Bed if so, buffer is empty, branch to sleep abx X now points to curr char lda ,x get char bsr L009D check for tail wrap stb <VD.IBufT,u store updated tail andcc #^(IRQMask+Carry) unmask IRQ rts Put2Bed lda V.BUSY,u get calling process ID sta V.WAKE,u store in V.WAKE andcc #^IRQMask clear interrupts ldx #$0000 os9 F$Sleep sleep forever clr V.WAKE,u clear wake ldx <D.Proc get pointer to current proc desc ldb <P$Signal,x get signal recvd beq Read branch if no signal cmpb #S$Window window signal? bcc Read branch if so coma rts * Check if we need to wrap around tail pointer to zero L009D incb cmpb #$7F bls L00A3 clrb L00A3 rts * * IRQ routine for keyboard * AltIRQ ldu >D.KbdSta get keyboard static ldb <u0032,u beq L00B7 ldb <u002F,u beq L00B7 lda <u0030,u lbsr L03CC L00B7 ldx #PIA0Base clra clrb std <u006A,u clear bsr L00E8 bne L00CC clr $02,x lda ,x get byte from PIA coma complement anda #$7F strip off hi bit bne L00F1 branch if any bit set L00CC clra clrb std <u006E,u clear coma A = $FF tst <u006D,u bne L00DA sta <u005F,u L00DA stb <u006D,u comb sta <u0060,u std <u0061,u L00E4 jmp [>D.Clock] jump into clock module L00E8 comb stb $02,x ldb ,x comb andb #$03 rts L00F1 bsr L015C bmi L00CC clrb bsr L00E8 bne L00CC cmpa <u006F,u bne L010E ldb <u0051,u beq L010A decb L0105 stb <u0051,u bra L00E4 L010A ldb #$05 bra L011A L010E sta <u006F,u ldb #$05 tst <u006B,u bne L0105 ldb #60 L011A stb <u0051,u ldb <VD.IBufH,u leax <VD.InBuf,u abx lbsr L009D check for tail wrap cmpb <VD.IBufT,u beq L012F stb <VD.IBufH,u L012F sta ,x beq L014F cmpa V.PCHR,u bne L013F ldx V.DEV2,u beq L014F sta $08,x bra L014F L013F ldb #S$Intrpt cmpa V.INTR,u beq L014B ldb #S$Abort cmpa V.QUIT,u bne L014F L014B lda V.LPRC,u bra L0153 L014F ldb #S$Wake lda V.WAKE,u L0153 beq L0158 os9 F$Send L0158 clr V.WAKE,u bra L00E4 L015C clra clrb std <u0066,u std <u0068,u coma comb std <u0063,u sta <u0065,u deca sta $02,x L016F lda ,x coma anda #$7F beq L0183 ldb #$FF L0178 incb lsra bcc L017F lbsr L0221 L017F cmpb #$06 bcs L0178 L0183 inc <u0068,u orcc #Carry rol $02,x bcs L016F lbsr L0289 bmi L020A cmpa <u005F,u bne L0199 inc <u006B,u L0199 sta <u005F,u beq L01B9 suba #$1A bhi L01B9 adda #$1A ldb <u0067,u bne L01E9 adda #$40 ldb <u0066,u eorb <VD.Caps,u andb #$01 bne L01E9 adda #$20 bra L01E9 L01B9 ldb #$03 mul lda <u0066,u beq L01C4 incb bra L01CB L01C4 lda <u0067,u beq L01CB addb #$02 L01CB lda <u006C,u beq L01D4 cmpb #$11 ble L0208 L01D4 cmpb #$4C blt L01DD inc <u0069,u subb #$06 L01DD pshs x leax >L0321,pcr lda b,x puls x bmi L01FD L01E9 ldb <u0069,u beq L01FA cmpa #$3F bls L01F8 cmpa #$5B bcc L01F8 ora #$20 L01F8 ora #$80 L01FA andcc #^Negative rts L01FD inc <u006D,u ldb <u006B,u bne L0208 com <VD.Caps,u L0208 orcc #Negative L020A rts L020B pshs b,a clrb orcc #Carry inca L0211 rolb deca bne L0211 bra L0219 L0217 pshs b,a L0219 orb <u006A,u stb <u006A,u puls pc,b,a L0221 pshs b,a cmpb #$03 bne L0230 lda <u0068,u cmpa #$03 blt L0230 bsr L020B L0230 lslb lslb lslb addb <u0068,u beq L025D cmpb #$33 bne L0243 inc <u0069,u ldb #$04 bra L0219 L0243 cmpb #$31 beq L024B cmpb #$34 bne L0252 L024B inc <u0067,u ldb #$02 bra L0219 L0252 cmpb #$37 bne L0262 com <u0066,u ldb #$01 bra L0219 L025D ldb #$04 bsr L0217 clrb L0262 pshs x leax <u0063,u bsr L026D puls x puls pc,b,a L026D pshs a lda ,x bpl L0279 stb ,x ldb #$01 puls pc,a L0279 lda $01,x bpl L0283 stb $01,x ldb #$02 puls pc,a L0283 stb $02,x ldb #$03 puls pc,a L0289 pshs y,x,b bsr L02EE ldb <u006E,u beq L02C5 leax <u0060,u pshs b L0297 leay <u0063,u ldb #$03 lda ,x bmi L02B6 L02A0 cmpa ,y bne L02AA clr ,y com ,y bra L02B6 L02AA leay $01,y decb bne L02A0 lda #$FF sta ,x dec <u006E,u L02B6 leax $01,x dec ,s bne L0297 leas $01,s ldb <u006E,u beq L02C5 bsr L0309 L02C5 leax <u0063,u lda #$03 L02CA ldb ,x+ bpl L02DE deca bne L02CA ldb <u006E,u beq L02EA decb leax <u0060,u lda b,x bra L02E8 L02DE tfr b,a leax <u0060,u bsr L026D stb <u006E,u L02E8 puls pc,y,x,b L02EA orcc #Negative puls pc,y,x,b L02EE ldd <u0066,u bne L0301 lda #$03 leax <u0063,u L02F8 ldb ,x beq L0302 leax $01,x deca bne L02F8 L0301 rts L0302 comb stb ,x inc <u0069,u rts L0309 leax <u0060,u bsr L0314 leax $01,x bsr L0314 leax -$01,x L0314 lda ,x bpl L0320 ldb $01,x bmi L0320 sta $01,x stb ,x L0320 rts L0321 fcb $00,$40,$60 ALT @ ` fcb $0c,$1c,$13 UP fcb $0a,$1a,$12 DOWN fcb $08,$18,$10 LEFT fcb $09,$19,$11 RIGHT fcb $20,$20,$20 SPACEBAR fcb $30,$30,$81 0 0 capslock fcb $31,$21,$7c 1 ! | fcb $32,$22,$00 2 " null fcb $33,$23,$7e 3 # ~ fcb $34,$24,$1d 4 $ RS (was null) fcb $35,$25,$1e 5 % GS (was null) fcb $36,$26,$1f 6 & US (was null) fcb $37,$27,$5e 7 ' ^ fcb $38,$28,$5b 8 ( [ fcb $39,$29,$5d 9 ) ] fcb $3a,$2a,$00 : * null fcb $3b,$2b,$7f ; + del (was null) fcb $2c,$3c,$7b , < { fcb $2d,$3d,$5f - = _ fcb $2e,$3e,$7d . > } fcb $2f,$3f,$5c / ? \ fcb $0d,$0d,$0d ENTER key fcb $00,$00,$00 CLEAR key fcb $05,$03,$1b BREAK key fcb $31,$33,$35 F1 key fcb $32,$34,$36 F2 key * Write * * Entry: * A = character to write * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Write ldb <VD.NGChr,u are we in the process of getting parameters? bne PrmHandl yes, go process sta <VD.WrChr,u save character to write cmpa #C$SPAC space or higher? bcc GoCo yes, normal write cmpa #$1E escape sequence $1E or $1F? bcc Escape yes, go process cmpa #$0F GFX codes? lbcc GfxDispatch branch if so cmpa #C$BELL bell? lbeq Ding if so, ring bell * Here we call the CO-module to write the character GoCo lda <VD.CurCo,u get CO32/CO80 flag CoWrite ldb #$03 we want to write CallCO leax <CoEnt,u get base pointer to CO-entries ldx a,x get pointer to CO32/CO80 beq NoIOMod branch if no module lda <VD.WrChr,u get character to write L039D jmp b,x call i/o subroutine NoIOMod comb ldb #E$MNF rts * Parameter handler PrmHandl cmpb #$02 two parameters left? beq L03B0 branch if so sta <VD.NChar,u else store in VD.NChar clr <VD.NGChr,u clear parameter counter jmp [<VD.RTAdd,u] jump to return address L03B0 sta <VD.NChr2,u store in VD.NChr2 dec <VD.NGChr,u decrement parameter counter clrb rts Escape beq L03C5 if $1E, we conveniently ignore it leax <COEscape,pcr else it's $1F... set up to get next char L03BD ldb #$01 L03BF stx <VD.RTAdd,u stb <VD.NGChr,u L03C5 clrb rts COEscape ldb #$03 write offset into CO-module lbra JmpCO L03CC pshs x,a stb <u002F,u lda >PIA1Base+2 anda #$07 ora ,s+ tstb bne L03DE ora <VD.CFlag,u L03DE sta >PIA1Base+2 sta <u0030,u tstb bne L03F5 * Bang %00010101 to VDG stb >$FFC0 stb >$FFC2 stb >$FFC4 lda <u001D,u bra L0401 * Bang %00101001 to VDG L03F5 stb >$FFC0 stb >$FFC3 stb >$FFC5 lda <VD.CurBf,u L0401 ldb #$07 ldx #$FFC6 lsra L0407 lsra bcs L0410 sta ,x+ leax $01,x bra L0414 L0410 leax $01,x sta ,x+ L0414 decb bne L0407 clrb puls pc,x GRFO fcs /GRFO/ CO32 fcs /CO32/ CO80 fcs /CO80/ * GetStat * * Entry: * A = function code * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * GetStat sta <VD.WrChr,u cmpa #SS.Ready bne L0439 lda <VD.IBufT,u get buff tail ptr suba <VD.IBufH,u Num of chars ready in A lbeq NotReady branch if empty SSEOF clrb rts L0439 cmpa #SS.EOF beq SSEOF ldx PD.RGS,y cmpa #SS.Joy beq SSJOY cmpa #SS.ScSiz beq SSSCSIZ cmpa #SS.KySns beq SSKYSNS cmpa #SS.DStat lbeq SSDSTAT ldb #$06 getstat entry into CO-module lbra JmpCO SSKYSNS ldb <u006A,u get key sense info stb R$A,x put in caller's A clrb rts SSSCSIZ clra ldb <VD.Col,u std R$X,x ldb <VD.Row,u std R$Y,x clrb rts * Get joytsick values SSJOY pshs y,cc orcc #IRQMask mask interrupts lda #$FF sta >PIA0Base+2 ldb >PIA0Base ldy R$X,x get joystick number to poll bne L0481 andb #$01 bne L0485 bra L0486 L0481 andb #$02 beq L0486 L0485 clra L0486 sta R$A,x lda >PIA0Base+3 ora #$08 ldy R$X,x bne L0494 anda #$F7 L0494 sta >PIA0Base+3 lda >PIA0Base+1 anda #$F7 bsr L04B3 std R$X,x lda >PIA0Base+1 ora #$08 bsr L04B3 pshs b,a ldd #$003F subd ,s++ std R$Y,x clrb puls pc,y,cc L04B3 sta >PIA0Base+1 lda #$7F ldb #$40 bra L04C7 L04BC lsrb cmpb #$01 bhi L04C7 lsra lsra tfr a,b clra rts L04C7 pshs b sta >PIA1Base tst >PIA0Base bpl L04D5 adda ,s+ bra L04BC L04D5 suba ,s+ bra L04BC SSDSTAT lbsr L065B bcs L050E ldd <u0045,u bsr L050F tfr a,b andb ,x L04E7 bita #$01 bne L04F6 lsra lsrb tst <u0024,u bmi L04E7 lsra lsrb bra L04E7 L04F6 pshs b ldb <u004B,u andb #$FC orb ,s+ ldx $06,y stb $01,x ldd <u0045,u std $06,x ldd <VD.CurBf,u std $04,x clrb L050E rts L050F pshs y,b,a ldb <u0024,u bpl L0517 lsra L0517 lsra lsra pshs a ldb #$BF subb $02,s lda #$20 mul addb ,s+ adca #$00 ldy <VD.CurBf,u leay d,y lda ,s sty ,s anda <u0044,u ldx <u0042,u lda a,x puls pc,y,x * SetStat * * Entry: * A = function code * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * SetStat sta <VD.WrChr,u save function code ldx PD.RGS,y get caller's regs cmpa #SS.ComSt lbeq SSCOMST cmpa #SS.AAGBf beq SSAAGBF cmpa #SS.SLGBf beq SSSLGBF cmpa #SS.KySns bne CoGetStt ldd R$X,x beq L0558 ldb #$FF L0558 stb <u006C,u L055B clrb L055C rts CoGetStt ldb #$09 CO-module setstat JmpCO pshs b lda <VD.CurCo,u get CO-module in use lbsr CallCO puls a bcc L055B tst <VD.GRFOE,u GRFO linked? beq L055C tfr a,b clra GRFO address offset in statics lbra CallCO call it * Reserve an additional graphics buffer (up to 2) SSAAGBF ldb <VD.Rdy,u was initial buffer allocated with $0F? lbeq NotReady branch if not pshs b save buffer number leay <VD.AGBuf,u point to additional graphics buffers ldd ,y first entry empty? beq L058E branch if so leay $02,y else move to next entry inc ,s increment B on stack ldd ,y second entry empty? bne L059E if not, no room for more... error out L058E lbsr GetMem allocate graphics buffer memory bcs L05A1 branch if error std ,y save new buffer pointer at ,Y std R$X,x and in caller's X puls b get buffer number off stack clra clear hi byte of D std R$Y,x and put in caller's Y (buffer number) clrb call is ok rts and return L059E ldb #E$BMode coma L05A1 puls pc,a * Select a graphics buffer SSSLGBF ldb <VD.Rdy,u was initial buffer allocated with $0F? lbeq NotReady branch if not ldd R$Y,x else get buffer number from caller cmpd #$0002 compare against high bhi BadMode branch if error leay <VD.GBuff,u point to base graphics buffer address lslb multiply by 2 ldd b,y get pointer beq BadMode branch if error std <VD.CurBf,u else save in current ldd R$X,x get select flag beq L05C3 if zero, do nothing ldb #$01 else set display flag L05C3 stb <u0032,u save display flag clrb rts BadMode comb ldb #E$BMode rts SSCOMST ldd R$Y,x Get caller's Y L05CE bita #$02 CO80? bne GoCO80 branch if so ldb #$10 assume true lower case TRUE bita #$01 true lowercase bit set? bne GoCO32 branch if so clrb true lower case FALSE GoCO32 stb <VD.CFlag,u save flag for later lda #$02 CO32 is loaded bit ldx #$2010 32x16 pshs u,y,x,a leax >CO32,pcr bra L05F4 GoCO80 lda #$04 'CO80 is loaded' bit ldx #$5018 80x24 pshs u,y,x,a leax >CO80,pcr L05F4 bsr L0601 load CO-module if not already loaded puls u,y,x,a bcs L0600 stx <VD.Col,u save screen size sta <VD.CurCo,u current module in use? ($02=CO32, $04=C080) L0600 rts L0601 bita <u0070,u module loaded? beq L0608 branch if not L0606 clrb else clear carry rts and return L0608 pshs y,x,a lbsr LinkSub bcc L061F branch if link was successful ldx $01,s get pointer to name on stack pshs u os9 F$Load try to load subroutine I/O module puls u bcc L061F puls y,x,a lbra NoIOMod L061F leax <CoEnt,u get base pointer to CO-entries lda ,s get A off stack sty a,x save off CO32/CO80 entry point puls y,x,a ldb #$00 CO-module init offset lbra CallCO call it * Link to subroutine LinkSub pshs u lda #Systm+Objct os9 F$Link puls pc,u L0637 fdb $0055,$aaff GfxDispatch cmpa #$15 GRFO-handled code? bcc GoGrfo branch if so cmpa #$0F display graphics code? beq Do0F branch if so suba #$10 bsr L065B check if first gfx screen was alloc'ed bcs L0663 if not, return with error leax <gfxtbl,pcr else point to jump table lsla multiply by two ldd a,x get address of routine jmp d,x jump to it * Jump table for graphics codes $10-$14 gfxtbl fdb Do10-gfxtbl $10 - Preset Screen fdb Do11-gfxtbl $11 - Set Color fdb Do12-gfxtbl $12 - End Graphics fdb Do13-gfxtbl $13 - Erase Graphics fdb Do14-gfxtbl $14 - Home Graphics Cursor L065B ldb <VD.Rdy,u ready? bne L0606 NotReady comb ldb #E$NotRdy L0663 rts GoGrfo bsr L065B bcs L0663 ldx <VD.GRFOE,u get GRFO entry point bne L0681 branch if not zero pshs y,a else preserve regs bne L067F leax >GRFO,pcr get pointer to name string bsr LinkSub link to GRFO bcc L067B branch if ok puls pc,y,a else exit with error L067B sty <VD.GRFOE,u save module entry pointer L067F puls y,a restore regs L0681 clra A = GRFO address offset in statics lbra CoWrite * Allocate GFX mem -- we must allocate on a 512 byte page boundary GetMem pshs u save static pointer ldd #6144+256 allocate graphics memory + 1 page os9 F$SRqMem do it bcc L0691 branch if ok puls pc,u else return with error L0691 tfr u,d move mem ptr to D puls u restore statics tfr a,b move high 8 bits to lower bita #$01 odd page? beq L069F branch if not adda #$01 bra L06A1 L069F addb #$18 L06A1 pshs u,a tfr b,a clrb tfr d,u ldd #256 os9 F$SRtMem return page puls u,a bcs L06B3 branch if error clrb L06B3 rts * $0F - display graphics Do0F leax <DispGfx,pcr ldb #$02 lbra L03BF DispGfx ldb <VD.Rdy,u already allocated initial buffer? bne L06D1 branch if so bsr GetMem else get graphics memory bcs L06EF branch if error std <VD.CurBf,u save memory std <VD.GBuff,u and GBuff inc <VD.Rdy,u ok, we're ready lbsr EraseGfx clear gfx mem L06D1 lda <VD.NChar,u sta <u004B,u anda #$03 leax >L0637,pcr lda a,x sta <u0047,u sta <u0048,u lda <VD.NChr2,u cmpa #$01 bls L06F0 comb ldb #E$BMode L06EF rts L06F0 tsta beq L0710 ldd #$C003 std <u0049,u lda #$01 sta <u0024,u lda #$E0 ldb <VD.NChar,u andb #$08 beq L0709 lda #$F0 L0709 ldb #$03 leax <L0742,pcr bra L072D L0710 ldd #$8001 std <u0049,u lda #$FF tst <u0047,u beq L0723 sta <u0047,u sta <u0048,u L0723 sta <u0024,u lda #$F0 ldb #$07 leax <L0746,pcr L072D stb <u0044,u stx <u0042,u ldb <VD.NChar,u andb #$04 lslb pshs b ora ,s+ ldb #$01 lbra L03CC L0742 fcb $c0,$30,$0c,$03 L0746 fcb $80,$40,$20,$10,$08,$04,$02,$01 * $11 - Set Color Do11 leax <SetColor,pcr set up return address lbra L03BD SetColor clr <VD.NChr2,u lda <u0024,u bmi L075F inc <VD.NChr2,u L075F lbra L06D1 * End graphics Do12 leax <VD.GBuff,u point to first buffer ldy #$0000 Y = 0 ldb #$03 free 3 gfx screens max pshs u,b L076D ldd #6144 size of graphics screen ldu ,x++ get address of graphics screen beq L077A branch if zero sty -$02,x else clear entry os9 F$SRtMem and return memory L077A dec ,s decrement counter bgt L076D keep going if not end ldu ,x flood fill buffer? beq L0788 branch if not allocated ldd #512 else get size os9 F$SRtMem and free memory L0788 puls u,b restore regs clra sta <VD.Rdy,u gfx mem no longer alloced lbra L03CC Do10 leax <Preset,pcr set up return address lbra L03BD Preset lda <VD.NChar,u tst <u0024,u bpl L07A7 ldb #$FF anda #$01 beq EraseGfx bra L07B2 L07A7 anda #$03 leax >L0637,pcr ldb a,x bra L07B2 * Erase graphics screen Do13 EraseGfx clrb value to clear screen with L07B2 ldx <VD.CurBf,u leax >6144+1,x point to end of gfx mem + 1 L07B9 stb ,-x clear cmpx <VD.CurBf,u X = to start? bhi L07B9 if not, continue * Home Graphics cursor Do14 clra clrb std <u0045,u rts * * Ding - tickle CoCo's PIA to emit a sound * Ding pshs b,a lda >PIA0Base+1 ldb >PIA0Base+3 pshs b,a anda #$F7 andb #$F7 sta >PIA0Base+1 stb >PIA0Base+3 lda >PIA1Base+3 pshs a ora #$08 sta >PIA1Base+3 ldb #$0A L07E6 lda #$FE bsr DingDuration lda #$02 bsr DingDuration decb bne L07E6 puls a sta >PIA1Base+3 puls b,a sta >PIA0Base+1 stb >PIA0Base+3 puls pc,b,a DingDuration sta >PIA1Base lda #128 L0805 inca bne L0805 rts emod eom equ * end