; DEC 99999 AAAAAAAAAAAAAAAAAAA ;? vsynch * &13 ; poke ; *** Tim *** Routine to poke/peek a byte into/form either ; | the io processor or the language processor. ; | If the byte is destined specifically for the io ; | processor, it is poked there straight away. ; | Otherwise, if a second processor is detected, the ; | tube is claimed, the byte poked and then released. ; | ; | Routine entered with X,Y pointing to 4 byte address ; | A = 0 - byte peeked, A = 1 - TTEMP2 poked ; | PHA ; | STX TTEMP ; | TTEMP is zero-page STY TTEMP+1 ; | LDYIM 3 ; | LDAIY TTEMP ; | Read byte 4 of address CMPIM &FF ; | If equal to &FF then it could be for io proc. BNE poke2 ; | DEY ; | LDAIY TTEMP ; | Read byte 3 of address CMPIM &FF ; | BNE poke2 ; | Branch if not for io proc. poke3 ; | DEY ; | LDAIY TTEMP ; | Read MSB PHA ; | DEY ; | LDAIY TTEMP ; | Read LSB STA TTEMP ; | PLA ; | STA TTEMP+1 ; | PLA ; | Restore poke/peek flag BEQ pokepe ; | Branch if peek LDA TTEMP2 ; | Read byte to be poked STAIY TTEMP ; | Poke byte RTS ; | pokepe ; | LDAIY TTEMP ; | Read byte RTS ; | ; | poke2 ; | JSR istube ; | Check for tube presence PHP ; | LDYIM 2 ; | PLP ; | BEQ poke3 ; | Branch if no tube JSR claim ; | Claim tube PLA ; | Pull poke/peek flag PHP ; | Save interrupt status PHA ; | Restore direction byte SEI ; | Interrupts off LDX TTEMP ; | Point X and Y to address address (!) LDY TTEMP+1 ; | JSR tube ; | Set up transfer PLA ; | Read poke/peek byte BEQ loopqq ; | Branch if peek loop ; | BIT TR3STA ; | BVC loop ; | Branch if tube full LDA TTEMP2 ; | Read back byte to poke STA TR3DAT ; | Poke byte (At last !!) plplpl ; | JSR letgo ; | Release tube PLP ; | Restore interrupt status RTS ; | loopqq ; | BIT TR3STA ; | BPL loopqq ; | Branch if tube empty LDA TR3DAT ; | Peek byte PHA ; | JSR letgo ; | PLA ; | PLP ; | Restore interrupt status RTS ; | ; claim ; *** Tim *** Routine to claim tube LDAIM identi :OR: &C0 ; | Load in tube id JSR tube ; | Attempt to claim tube BCC claim ; | Branch if not successful RTS ; *** Tim *** ; letgo ; *** Tim *** Routine to release tube LDAIM identi :OR: &80 ; | Release tube id JSR tube ; | RTS ; *** Tim *** ; istube ; *** Tim *** Routine to check for tube presence LDAIM &EA ; | OSBYTE code for tube presence LDXIM 0 ; | LDYIM 255 ; | JSR osbyte ; | Read tube presence CPXIM 0 ; | Returns Z=0 => tube present RTS ; | Z=1 => no tube ; ; MOS-supplied pointer to control block on entry to OSWORD ;****** WORKING STORAGE OUTSIDE ZERO PAGE ***** ; ; ;*************************************************************** ;* ;* starti ;* ;* *TIME command ;* ;* calls osword &7A (&98) to get local time in ascii ;* validates it and prints it with editing if OK ;* ;*************************************************************** ; starti LdaIM &98 ; osword call sub-number Sta timebl Jsr time00 ; osword ; call time00 ; ; check error return ; LdyIM 11 ; offset to error indicator LdaAY timebl CmpIM &F0 Bne star00 Jsr stri02 = "Time not available" = 0 Jmp starex ; star00 CmpIM &FF Bne starok Jsr stri02 = "Time reception error" = 0 Jmp starex ; starok LdyIM 5 ; offset to ascii result starpr LdaAY timebl Jsr oswrch Iny LdaAY timebl Jsr oswrch Iny CpyIM 11 ; finished? Beq starex LdaIM ":" Jsr oswrch Jmp starpr ; starex Jsr osnewl ; Sec ; Tell MOS command has been recognised Rts ; ; ; ;*************************************************************** ;* ;* osword call &7A (&98) ;* ;* time00 ;* ;* grabs Co-ordinated Universal Time (UTC) group and time ;* offset byte from the Television Service Data Packet (TSDP) ;* (TSbuff) and decodes them into ascii HHMMSS ;* ;* OnAY entry X point to parameter block; ;* 1 byte osword call sub-number ;* 3 bytes packed decimal HHMMSS (output) ;* 1 byte packed decimal offset (output) ;* 6 bytes ascii time HHMMSS (output) ;* 1 byte error/date change indicator (output) ;* 00 no date change needed ;* 01 add 1 day to date ;* 09 subtract 1 day from date ;* F0 no TSDP ;* FF bad TSDP data ;* ;* OnAX exit, A,Y are preserved ;* ;* NB routine uses decimal mode arithmetic. Therefore, ;* interrs are disabled for most of this routine ;* ;************************************************************** ; time00 Php ; save processor status ; ; get UTC group and offset byte ; LdxIM 9 ; offset within TSDP LdaIM 0 ; set location in TSDP area to illega value StaAX TSbuff ; to make sure TSDP is being transmitted LdaIM 60 ; loop count Sta timewo timech LdaIM vsynch ; wait for vsynch to get 1/50th sec delay Jsr osbyte LdxIM 9 LdaAX TSbuff ; new data? Bne timege ; yes. grab it! Dec timewo Bne timech ; no. look a while longer ; ; TSDP is not being transmitted ; LdyIM 11 ; offset to error indicator LdaIM &F0 ; indicate no TSDP StaAY timebl Jmp timeex ; ; TSDP has been received ; timege Sei LdyIM 4 ; offset within param. block StaAY timebl LdxIM 15 LdyIM 3 time01 LdaAX TSbuff ; get UTC bytes StaAY timebl Dex Dey Bne time01 ; ; check TSDP data for validity ; CmpIM &11 ; HH between 0-23 after decrementing? Bcc timeba CmpIM &35 Bcc timecl ; data is good ; timeba ; ; data is invali ; LdyIM 11 ; offset to error indicator LdaIM &FF ; indicate bad data StaAY timebl Jmp timeex ; timecl ; ; data is good ; LdaIM 0 LdyIM 11 ; offset to date byte in param. block StaAY timebl ; initialise date change indicator ; ; process UTC and offset ; Sed ; set packed decimal arithmetic mode ; ; subtract 1 from each decimal digit ; LdyIM 1 timede LdaAY timebl ; getAM pair of digits HHM or SS Sec SbcIM &11 ; decrement each packed decimal digit by 1 StaAY timebl ; put them back Iny CpyIM 4 ; more? Bne timede ; ; decode offset byte ; LdxIM 0 ; initialise sign flag (zero = + , nonzero = -) LdaAY timebl ; get offset byte AslA ; lose msb AslA ; sign bit ---> carry Bcc timeha LdxIM &FF ; complement sign flag ; ; get half-hour bit ; timeha LsrA ; lose lower 3 bits LsrA LsrA LsrA Bcc timebc ; zero halfhours Pha ; save shifted offset LdaIM &30 ; add/subtract 30 mins. Jsr calcmi Pla ; ; convert binary whole number offset into two packed decimal ; digits for addition/subtraction with UTC ; timebc Beq timeco ; zero offset CmpIM 10 Bcc timeof ; upper half of byte is already zero Sec SbcIM 10 ; correct units digit OraIM &10 ; set tens digit ; ; now add/subtract packed decimal offset to UTC ; timeof Jsr calcho ; timeco Cld ; restore processor status to integer mode ; Jsr btoa ; convert result to ascii bytes ; timeex ; Plp ; Restore status as on entry Rts ; ; ;***************************************************************** ;* ;* calcmi ;* ;* adds/subtracts A from MM modulo 60 with adjustment to HH if ;* necessary ;* ;***************************************************************** ; calcmi LdyIM 2 ; point to MM Jsr swit00 ; add/subtract A to/from MM modulo 60 Bcs calcad ; carry/borrow to/from 100's digit CmpIM &60 ; hour changed? Bcc calcex ; no. HH,MM are correct calcad Txa ; yes. get sign flag Pha ; save proper status EorIM &FF ; complement for modulo adjustment Tax LdaIM &60 ; modulo adjustment factor Jsr swit00 ; adjust MM Pla ; restore sign flag Tax LdaIM 1 ; add/subtract 1 to/from HH Jsr calcho ; calcex Rts ; ; ;***************************************************************** ;* ;* calcho ;* ;* adds/subtracts A from HH modulo 24 ;* indicates if date needs adjustment ;* ;***************************************************************** ; calcho LdyIM 1 ; point to HH Jsr swit00 ; add/subtract A to/from HH modulo 24 CmpIM &24 ; day changed? Bcc hourse ; no. HH,date are correct Txa ; yes. get sign flag Pha ; save proper status EorIM &FF ; complement sign for modulo adjustment Tax LdaIM &24 ; modulo adjustment factor Jsr swit00 ; adjust HH Pla ; restore sign flag Tax AndIM 8 ; bit 3 will indicate sign of date mod. OraIM 1 ; bit 0 will indicate mod. required LdyIM 11 ; offset to date change indicator in param. block StaAY timebl ; hourse Rts ; ; ;**************************************************************** ;* ;* .swit00 switchable adder/subtracter ;* ;* adds/subtracts AAY to/from (tbloc) ;* ;* switches on sign flag (X) ;* X=0 adder , X=1 subtracter ;* ;* on exit, Carry is set if there was either a carry :OR: A BORROW ;* ;**************************************************************** ; swit00 Sta timewo ; save second operan to get order right LdaAY timebl ; get first operan CpxIM 0 ; add or subtract? Bne swit03 switch Clc Adc timewo Jmp swit02 ; swit03 Sec Sbc timewo Bcc swit01 Clc ; no borrow Bcc swit02 swit01 Sec ; borrow ; swit02 StaAY timebl Rts ; ; ;**************************************************************** ;* ;* bcdtoascii ;* ;* converts adjusted UTC (3 bytes packed decimal) into ;* 6 byte asacii string ;* ;**************************************************************** ; btoa LdyIM 5 ; offset to leftmost ascii byte Sty timewo ; save it for switch later LdyIM 1 ; offset to leftmost UTC byte ; bcdloo LdaAY timebl ; get UTC decimal pair Pha LSRA ; convert lefthand digit to binary LSRA LSRA LSRA OraIM &30 ; convert binary to ascii character Sty timewo+1 ; switch offsets Ldy timewo StaAY timebl ; put ascii byte Pla ; restore UTC pair AndIM &0F ; convert righthand digit to binary OraIM &30 ; convert binary to ascii character Iny StaAY timebl ; put ascii byte Iny ; offset to next ascii byte Sty timewo ; switch offsets again Ldy timewo+1 Iny ; point to next UTC pair CpyIM 4 Bne bcdloo ; Rts ; ; LNK DEC9B