;******************************************************** ; ; ATALAN Atari standard library ; ; Parts of code have been taken from Effectus library. ; ;******************************************************** ;Noname ;651-655 028B-028F ; ;More spare bytes that you shouldn't use because future versions of the OS might use them. ;Locations 651 and 652 are already used by version "B" as part of the interrupt handler routines. ;OS registers we use as temporary: ; ;BUFRLO,BUFRHI 50,51 $32,$33 ;BFENLO,BFENHI 52,53 $34,$35 ;ADRESS 100,101 $64,$65 A temporary storage location used by the display handler for so many things that it made my mind spin and I forgot what they were. ;MLTTMP 102,103 $66,$67 More temporary storage, with aliases OPNTMP and TOADR. ;SAVADR 104,105 $68,$69 Also know as FRMADR. Also used for temporary storage. ; Also not significant enough to explain (look at the OS listing if, for some reason, you really care). ;Registers used when drawing line ;ROWAC 112,113 $70,$71 ;COLAC 114,115 $72,$73 ;ENDPT 116,117 $74,$75 ;COUNTR 126,127 $7E,$7F COUNTR tells how many points have to be plotted before the line is finished. _putchr_proc_adr = $653 ;+$654 ?argptr = $32 ;$33 ?varptr = $34 ?size = $15 ;15 //$16 BUFADR ?aux2 = $38 ?aux = $39 ;Following assigns are defined by mc6502.atl _TW1 = $32 ;$33 mc6502.atl defines these labels as _TEMPW1, _TEMPW2. _TW2 = $34 ;$35 _TW3 = $15 ;$16 _TL1 = $70 ;four byte register ($70-$73) defined under name _TEMPL1 in mc6502.atl _stdbuf = $600 ;TODO: use LINBUF ($247-$26E) (100,101 can point to it) ;Argument list: ; 0 end of list ; 1..127 Constant string ; 128 EOL ; 129 one byte integer reference ; 130 two byte integer reference ; 131 three byte integer eference ; 132 four byte integer reference _std_print_adr .proc lda #<_adr_putchr sta _putchr_proc_adr lda #>_adr_putchr sta _putchr_proc_adr+1 ;Get address of argument from stack pla sta ?argptr pla sta ?argptr+1 jsr _read_byte ;just skip next byte (that is part of return address) ;Read command from input command jsr _read_byte sta ?size tay ; to set the flags beq done ;command 0 means end of sequence bpl str ;1..127 constant string ;Write n-byte integer variable and #$7f ; sec ; sbc #128 sta ?size beq eol jsr _read_byte sta ?varptr jsr _read_byte sta ?varptr+1 jsr _std_bin_to_bcd jsr _std_print_hex clc bcc command ;jmp command eol lda #155 jsr _std_putchr clc bcc command ;jmp command ;Write constant string (size is 1..127, already stored) str jsr _read_byte jsr _std_putchr dec ?size bne str beq command done jmp (?argptr) rts _read_byte ldy #0 lda (?argptr),y inc ?argptr bne skip inc ?argptr+1 skip rts .endp _std_putchr .proc jmp (_putchr_proc_adr) rts .endp _adr_putchr .proc ;Write byte to address specified by _arr and increment the address by 1. ;Convert ASCII to ATARI character screen code ; ;The rules are following: ;0..31 +64 ;32..95 -32 ;96..127 0 (codes are same) tax rol rol rol rol and #3 tay txa eor tbl,y ;write the char to specified address ldy #0 sta (_arr),y inc _arr bne skip1 inc _arr+1 skip1 rts tbl dta b(%01000000) ;%0 00 00000 00..31 +64 dta b(%00100000) ;%0 01 00000 32..63 -32 dta b(%01100000) ;%0 10 00000 64..95 -32 dta b(%00000000) ;%0 11 00000 96..127 0 .endp .proc _std_print_hex ;Print hexadecimal number of arbitrary length (?size). ;Leading zeroes are not printed. ;In: ; ?varptr Pointer to memory containing the number ; ?size Number of bytes to print ;Uses: ; ?aux ; ?aux2 lda ?size sta ?aux lda #0 sta ?aux2 ; number of non-zero digits on output beq _loop _outbyte ldy ?aux lda (?varptr),y pha lsr lsr lsr lsr jsr _write_digit pla and #$0f jsr _write_digit _loop dec ?aux bpl _outbyte ;If no character has been written, write at least one 0 lda ?aux2 bne _no_empty lda #48 jsr _std_putchr _no_empty rts _write_digit ;In: a 4 bit digit tax bne _non_zero lda ?aux2 beq _done ;this is zero and there has been no char before - no output _non_zero lda hex,x jsr _std_putchr inc ?aux2 _done rts hex dta c"0123456789ABCDEF" .endp .proc _std_bin_to_bcd ;Convert binary number to BCD. ;Arbitrary size (up to 127 bytes) are supported. ;In: ; ?varptr pointer to binary number ; ?size number of bytes ;Out: ; ?size on output, returns size of resulting bcd number ; ?varptr on output, containg pointer to converted BCD ;Uses: ; _stdbuf ; ?aux ; ?aux2 ;Compute size of resulting number ldy ?size sty ?aux ; used to count later iny ;add space to result sty ?size ;Zero the destination buffer lda #0 zero sta _stdbuf-1,y dey bne zero ;**** We convert the number byte a time sed ;?aux = varptr(?aux) bytes dec ?aux ldy ?aux lda (?varptr),y sta ?aux2 sec ;set top bit to 1 bcs loop shift_byte ldx #0 ldy ?size bcd_mul2 lda _stdbuf,x adc _stdbuf,x ;buf2(x) = buf2(x) * 2 + carry sta _stdbuf,x inx dey bne bcd_mul2 clc loop rol ?aux2 ;divide by two, if result is 0, end bne shift_byte lda ?aux bne bytes cld lda #<_stdbuf sta ?varptr lda #>_stdbuf sta ?varptr+1 rts .endp /* Mul8 - 8-bit multiplication routine Original source: Book Atari Roots (Chapter Ten - Assembly Language Math) Hyperlink: http://www.atariarchives.org/roots/chapter_10.php Parameters: a First multiplicant x Second multiplicant Result: TEMPW2,TEMPW2+1 high byte of the result */ _sys_mul8 .proc MUL1 = _TW1 MUL2 = _TW1+1 RES = _TW2 ;_TW2+1 sta MUL1 ;input comes in A and X stx MUL2 lda #0 ;RES = 0 sta RES ldx #8 loop lsr MUL1 ;MUL1 = MUL1 / 2 bcc noadd clc ;RES = RES + (MUL2 * $ff) adc MUL2 noadd ror @ ;RES = RES / 2 (Carry is 0, when there was no add) ror RES dex bne loop sta RES+1 rts .endp