6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Jul 05, 2024 4:48 pm

All times are UTC




Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: bugged 6502 emu in BASIC
PostPosted: Sun Jun 05, 2011 5:03 am 
Offline

Joined: Sun Jun 05, 2011 4:51 am
Posts: 8
Howdy :)

Trying to getting an 6502 emulator working using a basic that has no bytes/words/dwords, only signed integers of 32bit size, nothing else.

I think this is a convert from Pascal to start with, and so I tried found that and compare the sources but no luck yet.

ADC and SBC being a bit complex , does anyone know if C64 KERNAL uses decimal mode? the pascal original source does not use decimal mode and are supposed to be able to run c64 kernal nonetheless, nonetheless it would be nice to have it confirmed.

Tried finding the bug for sometime now without luck, It does run C64 kernel but shows weird characters and actually its an basic error message. You get the blinking cursor and this, not the introduction text C64 BASIC FREE etc.. as you are supposed to.


Any luck any of you spot the bug?

This is how it looks like this, cursor is alive blinking as should and as routine feeds keyboard to kernal buffer, you may type and it respond just with wierd characters/graphics and error messages.

This is how it looks like: (it says OUT OF MEMORY ERROR IN READY if you subtract value of 64 from the ascii this is should not be needed and are probably part of the bug in some instruction logic)
Image

UPDATED CREDITS GOES TO
- Marc Dendooven made tutorials and Pascal version
- Blitz conversion and optimizations by Jimmy
- Debugged by Lee Davison and Danny Olsson.

Here included is the fixed full source BASIC sourcecode, enjoy!

UPDATE
Last years hard work on CartAdore showed fruitful finally. It begins coming close to be what it is supposed to be;
The goal is to be an open source emulator covering only a few sheets of paper, for an easy overview learning about emulators.
Special thanks goes to Lee and Danny for doing emense work on this the last few days.

Code:
;************************************************************************************
; Commodore 64 emulator
;
; Translated and corrected sourcecodes
; originally  Pascal source by Ed64 ( Marc Dendooven )
;
; Blitz3D Conversion by Jimmy
; 2007 - 2011
; 6502 emulator "CartAdore"
; Official webpage but soon to come
;
; Debugged by Lee Davison and Danny Olsson
; bugfixed to a running state and commented by Lee Davison 2011/06/05
;
; visit:  <a href="http://www.themotionstore.com/leeedavison/" target="_blank">http://www.themotionstore.com/leeedavison/</a>
;
; Sorry, the text is formatted for TAB stops at six characters not four characters
; as used by the Blitz IDE but the Blitz syntax highlighting colours make me want to
; stab my eyes out. So I used another, monochrome, text editor.
;
; Version 0.53
;
;************************************************************************************
;
; Emulates a 6502 (without secret opcodes and extra 6510 opcodes, just standard C64
; opcodes)
; Does not emulate SID or CIA(input/output 2 6526 adapters w16bit parallel IO 8bit
; seraial IO, TOD clock with alarm)
; Does an crudly simple VIC II emulation (40x25 textmode 1024 area without colourmap,
; and vbl interrupt) nothing else
; 2Joystickports, userport, cartridge, disk, datasette

; Improved but as of yet unused C64 colour palette:
;
; $000000   black
; $FFFFFF   white
; $68372B   red
; $70A4B2   cyan
; $6F3D86   purple
; $588D43   green
; $352879   blue
; $B8C76F   yellow
; $6F4F25   lt brown
; $433900   brown
; $9A6759   pink
; $444444   dark grey
; $6C6C6C   grey
; $9AD284   lt green
; $6C5EB5   lt blue
; $959595   lt grey

;************************************************************************************
;
; Constants

Const n = $80               ; status bits in p: NV..DIZC
Const v = $40
Const b = $10               ; b isn't a real bit, don't set it
Const d = $08
Const i = $04
Const z = $02
Const c = $01

;************************************************************************************
;
; Global variables

                     ; 8 bit registers
Global a                  ; Accumulator
Global x                  ; X register
Global y                  ; Y register
Global s                  ; the low 8 bits of the stack pointer
Global p                  ; processor status register
Global op                  ; the current opcode

                     ; 16 bit register
Global pc                  ; program counter

Dim ram(65536)               ; Arrays are global
Dim basic_rom(65536)            ; $A000-$BFFF
Dim char_rom(65536)            ; $D000-$DFFF
Dim kernal_rom(65536)            ; $E000-$FFFF


;************************************************************************************
;
; start of code

Graphics 640,400               ; a big enough window for no borders

; Load the roms

f = ReadFile("BASIC.ROM")
For index = $A000 To $A000 + $1FFF
  basic_rom(index) = ReadByte(f)
Next
CloseFile f


f = ReadFile("CHAR.ROM")
For index = $D000 To $D000 + $0FFF
  char_rom(index) = ReadByte(f)
Next
CloseFile f


f = ReadFile("KERNAL.ROM")
For index = $E000 To $E000 + $1FFF
  kernal_rom(index) = ReadByte(f)
Next
CloseFile f


; start up the processor

reset()                  ; set the initial pc and disable interrupts

; Main loop

Repeat
  cycle = cycle + 2            ; all instructions are a minimum of two cycles
  op = peek(pc)               ; get the next opcode
  pc = (pc + 1) And $FFFF         ; increment the program counter

  Select op
   Case $69 : adc(imm())         ; was broken, now ok
   Case $65 : adc(zp())         ; was broken, now ok
   Case $75 : adc(zpx())         ; was broken, now ok
   Case $6D : adc(abs_())         ; was broken, now ok
   Case $7D : adc(abs_x())         ; was broken, now ok
   Case $79 : adc(abs_y())         ; was broken, now ok
   Case $61 : adc(indx())         ; was broken, now ok
   Case $71 : adc(indy())         ; was broken, now ok
   Case $29 : and_(imm())         ; ok
   Case $25 : and_(zp())         ; ok
   Case $35 : and_(zpx())         ; ok
   Case $2D : and_(abs_())         ; ok
   Case $3D : and_(abs_x())      ; ok
   Case $39 : and_(abs_y())      ; ok
   Case $21 : and_(indx())         ; ok
   Case $31 : and_(indy())         ; ok
   Case $0A : asl_A()         ; ok
   Case $06 : asl(zp())         ; ok
   Case $16 : asl(zpx())         ; ok
   Case $0E : asl(abs_())         ; ok
   Case $1E : asl(abs_x())         ; ok
   Case $90 : bfc(c)            ; ok ; bcc
   Case $B0 : bfs(c)            ; ok ; bcs
   Case $F0 : bfs(z)            ; ok ; beq
   Case $24 : bit(zp())         ; was broken, now ok
   Case $2C : bit(abs_())         ; was broken, now ok
   Case $30 : bfs(n)            ; ok ; bmi
   Case $D0 : bfc(z)            ; ok ; bne
   Case $10 : bfc(n)            ; ok ; bpl
   Case $00 : brk()            ; ok
   Case $50 : bfc(v)            ; ok ; bvc
   Case $70 : bfs(v)            ; ok ; bvs
   Case $18 : setflag(c,False)      ; ok ; clc
   Case $D8 : setflag(d,False)      ; ok ; cld
   Case $58 : setflag(i,False)      ; ok ; cli
   Case $B8 : setflag(v,False)      ; ok ; clv
   Case $C9 : cmp(imm())         ; ok
   Case $C5 : cmp(zp())         ; ok
   Case $D5 : cmp(zpx())         ; ok
   Case $CD : cmp(abs_())         ; ok
   Case $DD : cmp(abs_x())         ; ok
   Case $D9 : cmp(abs_y())         ; ok
   Case $C1 : cmp(indx())         ; ok
   Case $D1 : cmp(indy())         ; ok
   Case $E0 : cpx(imm())         ; ok
   Case $E4 : cpx(zp())         ; ok
   Case $EC : cpx(abs_())         ; ok
   Case $C0 : cpy(imm())         ; ok
   Case $C4 : cpy(zp())         ; ok
   Case $CC : cpy(abs_())         ; ok
   Case $C6 : dec_(zp())         ; ok
   Case $D6 : dec_(zpx())         ; ok
   Case $CE : dec_(abs_())         ; ok
   Case $DE : dec_(abs_x())      ; ok
   Case $CA : dex()            ; ok
   Case $88 : dey()            ; ok
   Case $49 : eor(imm())         ; ok
   Case $45 : eor(zp())         ; ok
   Case $55 : eor(zpx())         ; ok
   Case $4D : eor(abs_())         ; ok
   Case $5D : eor(abs_x())         ; ok
   Case $59 : eor(abs_y())         ; ok
   Case $41 : eor(indx())         ; ok
   Case $51 : eor(indy())         ; ok
   Case $E6 : inc_(zp())         ; ok
   Case $F6 : inc_(zpx())         ; ok
   Case $EE : inc_(abs_())         ; ok
   Case $FE : inc_(abs_x())      ; ok
   Case $E8 : inx()            ; ok
   Case $C8 : iny()            ; ok
   Case $4C : jmp(abs_())         ; ok
   Case $6C : jmp(ind())         ; ok
   Case $20 : jsr(abs_())         ; ok
   Case $A9 : lda(imm())         ; ok
   Case $A5 : lda(zp())         ; ok
   Case $B5 : lda(zpx())         ; ok
   Case $AD : lda(abs_())         ; ok
   Case $BD : lda(abs_x())         ; ok
   Case $B9 : lda(abs_y())         ; ok
   Case $A1 : lda(indx())         ; ok
   Case $B1 : lda(indy())         ; ok
   Case $A2 : ldx(imm())         ; ok
   Case $A6 : ldx(zp())         ; ok
   Case $B6 : ldx(zpy())         ; ok
   Case $AE : ldx(abs_())         ; ok
   Case $BE : ldx(abs_y())         ; ok
   Case $A0 : ldy(imm())         ; ok
   Case $A4 : ldy(zp())         ; ok
   Case $B4 : ldy(zpx())         ; ok
   Case $AC : ldy(abs_())         ; ok
   Case $BC : ldy(abs_x())         ; ok
   Case $4A : lsr_A()         ; ok
   Case $46 : lsr(zp())         ; ok
   Case $56 : lsr(zpx())         ; ok
   Case $4E : lsr(abs_())         ; ok
   Case $5E : lsr(abs_x())         ; ok
   Case $EA : ; nop            ; ok
   Case $09 : ora(imm())         ; ok
   Case $05 : ora(zp())         ; ok
   Case $15 : ora(zpx())         ; ok
   Case $0D : ora(abs_())         ; ok
   Case $1D : ora(abs_x())         ; ok
   Case $19 : ora(abs_y())         ; ok
   Case $01 : ora(indx())         ; ok
   Case $11 : ora(indy())         ; ok
   Case $48 : push(a)         ; ok ; pha
   Case $08 : php()            ; was broken, now ok
   Case $68 : pla()            ; ok
   Case $28 : plp()            ; was broken, now ok
   Case $2A : rol_A()         ; ok
   Case $26 : rol(zp())         ; ok
   Case $36 : rol(zpx())         ; ok
   Case $2E : rol(abs_())         ; ok
   Case $3E : rol(abs_x())         ; ok
   Case $6A : ror_A()         ; ok
   Case $66 : ror(zp())         ; ok
   Case $76 : ror(zpx())         ; ok
   Case $6E : ror(abs_())         ; ok
   Case $7E : ror(abs_x())         ; ok
   Case $40 : rti()            ; ok
   Case $60 : rts()            ; ok
   Case $E9 : sbc(imm())         ; was broken, now ok
   Case $E5 : sbc(zp())         ; was broken, now ok
   Case $F5 : sbc(zpx())         ; was broken, now ok
   Case $ED : sbc(abs_())         ; was broken, now ok
   Case $FD : sbc(abs_x())         ; was broken, now ok
   Case $F9 : sbc(abs_y())         ; was broken, now ok
   Case $E1 : sbc(indx())         ; was broken, now ok
   Case $F1 : sbc(indy())         ; was broken, now ok
   Case $38 : setflag(c,True)      ; ok ; sec
   Case $F8 : setflag(d,True)      ; ok ; sed
   Case $78 : setflag(i,True)      ; ok ; sei
   Case $85 : sta(zp())         ; ok
   Case $95 : sta(zpx())         ; ok
   Case $8D : sta(abs_())         ; ok
   Case $9D : sta(abs_x())         ; ok
   Case $99 : sta(abs_y())         ; ok
   Case $81 : sta(indx())         ; ok
   Case $91 : sta(indy())         ; ok
   Case $86 : stx(zp())         ; ok
   Case $96 : stx(zpy())         ; ok
   Case $8E : stx(abs_())         ; ok
   Case $84 : sty(zp())         ; ok
   Case $94 : sty(zpx())         ; ok
   Case $8C : sty(abs_())         ; ok
   Case $AA : tax()            ; ok
   Case $A8 : tay()            ; ok
   Case $BA : tsx()            ; ok
   Case $8A : txa()            ; ok
   Case $9A : txs()            ; ok
   Case $98 : tya()            ; ok
   Case $3F               ; use opcode $3F to drop into the debugger
     Stop
   Case $7F               ; use opcode $7F to output a value
     Print peek(pc)
     pc = (pc + 1) And $FFFF
   Default               ; an invalid opcode tells you where it is
     Write pc - 1
     Write " "
     Write op
     Print " unknown instruction"
     WaitKey
   End
  End Select

; 1000000 cycles / vertical blanking

  If cycle > 1000000/50 Then cycle = cycle - 1000000/50 : VWait : irq()

Until MouseDown(2)
End

;************************************************************************************
;
; functions that read/write memory

; return a word from (address)

Function peek2(address)
  peek2 = peek(address) + peek(address + 1) Shl 8
  Return peek2
End Function


; pokes a byte into memory

Function poke(address,value)
  ram(address) = value And $FF
  If (address=>$0400) And (address=<$07E7) Then VicText(address-$0400,value)
End Function


; get a byte from memory

Function peek(address)
  If address=>$A000 And address=<$BFFF Then
    peek = basic_rom(address)
  Else If address=>$D000 And address=<$DFFF Then
    peek = io(address)
  Else If address=>$E000 And address=<$FFFF Then
    peek = kernal_rom(address)
  Else
    peek = ram(address)
  End If
  Return peek
End Function


; read a byte from an i/o device

Function io(address)
  If address = $D012 Then io=$00 Else io=$FF ; fake rasterinterrupt (rasterline 0 or 255)
  Return io
End Function


;************************************************************************************
;
; functions which return address for the instructions to work with

; return the address of the immediate byte

Function imm()   
  imm = pc
  pc = (pc + 1) And $FFFF
  Return imm
End Function


; return the address of the zero page byte

Function zp()
  zp = peek(pc)
  pc = (pc + 1) And $FFFF
  Return zp
End Function


; return the address of the zero page byte indexed by X

Function zpx()
  zpx = (peek(pc) + x) And $FF
  pc = (pc + 1) And $FFFF
  Return zpx
End Function


; return the address of the zero page byte indexed by Y

Function zpy()
  zpy = (peek(pc) + y) And $FF
  pc = (pc + 1) And $FFFF
  Return zpy
End Function


; return the absolute address

Function abs_()
  abs_ = peek2(pc) And $FFFF
  pc = (pc + 2) And $FFFF
  Return abs_
End Function


; return the absolute address indexed by X

Function abs_x()
  absx = (peek2(pc) + x) And $FFFF
  pc = (pc + 2) And $FFFF
  Return absx
End Function


; return the absolute address indexed by Y

Function abs_y()
  absy = (peek2(pc) + y) And $FFFF
  pc = (pc + 2) And $FFFF
  Return absy
End Function


; return the indirect address, this is broken on the NMOS 6502 if it crosses a page
; boundary

Function ind()
  ind = peek2(peek2(pc))
  pc = (pc + 2) And $FFFF
  Return ind
End Function


; return the (indirect,X) address

Function indx()
  indx = peek2(lo(peek(pc) + x)) And $FFFF
  pc = (pc + 1) And $FFFF
  Return indx
End Function


; return the (indirect),Y address

Function indy()
  indy = (peek2(peek(pc)) + y) And $FFFF
  pc = (pc + 1) And $FFFF
  Return indy
End Function


;************************************************************************************
;
; flags, bits, words and bytes

; set the flag bit in the status byte
;
; never use this routine to set the b flag as it won't get cleared and everything will
; then go pear shaped

Function setflag(flag,status)
  If status Then p = (p Or flag) Else p = (p And (flag Xor $FF))
End Function


; return the 0 or 1 state of a flag bit

Function flagset(flag)
  flagset = (p And flag) <> 0         ; the <> 0 ensures only 0 or 1 is returned
  Return flagset
End Function


; return the low byte of a word

Function lo(value)
  Return value And $FF
End Function


; return the high byte of a word

Function hi(value)
  value = (value Shr 8) And $FF
  Return value
End Function


; push a byte onto the stack and decrement the stack pointer

Function push(byte)
  poke($100 + s,byte)
  s = (s - 1) And $FF
End Function


; increment the stack pointer and pull a byte from the stack

Function pull()
  s = (s + 1) And $FF
  pull = peek($100 + s)
  Return pull
End Function


; sign extend a byte to 32 bits

Function signedbyte(byte)
  h = byte
  If h => 128 Then h = h - $100
  Return h
End Function


;************************************************************************************
;
; the opcodes

; branch if the flag bit is set

Function bfs(flag)
  If flagset(flag) Then pc = pc + signedbyte(peek(pc))
  pc = (pc + 1) And $FFFF
End Function


; branch if the flag bit is clear

Function bfc(flag)
  If Not flagset(flag) Then pc = pc + signedbyte(peek(pc))
  pc = (pc + 1) And $FFFF
End Function


; decimal mode is not needed to run the C64 firmware

Function adc(address)
  val = peek(address)            ; get the value from memory
  bit = flagset(c)            ; get the carry value in bit
  hc = (((a And $7F) + (val And $7F) + bit) And $80) = $80
                     ; calculate the carry from b6 to b7
  h = a + val + bit            ; calculate the new value and new carry
  a = h And $FF               ; and copy the value part to A
  h = (h And $100) = $100         ; calculate the carry from b7
  setflag(c,h)               ; set the carry bit in the status
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
  setflag(v,h Xor hc)            ; set the overflow bit in the status
                     ; overflow is true when hc and h differ
End Function


; decimal mode is not needed to run the C64 firmware

Function sbc(address)
  val = peek(address)            ; get the value from memory
  bit = Not flagset(c)            ; get the inverted carry value in bit
  hc = Not (((a And $7F) - (val And $7F) - bit) And $80)
                     ; calculate the inverted carry from b6 to b7
  h = a - val - bit            ; calculate the new value and new carry
  a = h And $FF               ; and copy the value part to A
  h = Not (h And $100)            ; calculate the inverted carry from b7
  setflag(c,h)               ; set the carry bit in the status
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
  setflag(v,h Xor hc)            ; set the overflow bit in the status
                     ; overflow is true when hc and h differ
End Function


Function asl(address)
  byte = peek(address) Shl 1         ; get and shift the value
  setflag(c,byte And $100)         ; set the carry bit in the status
  byte = byte And $FF            ; mask the result to byte size
  poke(address,byte)            ; save the result back to memory
  setflag(z,Not byte)            ; set the zero bit in the status
  setflag(n,byte And n)            ; set the negative bit in the status
End Function


Function asl_A()
  a = a Shl 1               ; shift the value
  setflag(c,a And $100)            ; set the carry bit in the status
  a = a And $FF               ; mask the result to byte size
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function rol(address)
  byte = (peek(address) Shl 1) + flagset(c)
                     ; get shift and add the carry to the value
  setflag(c,byte And $100)         ; set the carry bit in the status
  byte = byte And $FF            ; mask the result to byte size
  poke(address,byte)            ; save the result back to memory
  setflag(z,Not byte)            ; set the zero bit in the status
  setflag(n,byte And n)            ; set the negative bit in the status
End Function


Function rol_A()
  a = (a Shl 1) +  flagset(c)         ; shift and add the carry to the value
  setflag(c,a And $100)            ; set the carry bit in the status
  a = a And $FF               ; mask the result to byte size
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function ror(address)
  byte = peek(address)            ; get the value from memory
  bit = flagset(c) Shl 7         ; get the carry value in b7
  setflag(c,byte And 1)            ; set the carry bit in the status
  byte = (byte Shr 1) Or bit         ; shift and add the carry to the value
  poke(address,byte)            ; save the result back to memory
  setflag(z,Not byte)            ; set the zero bit in the status
  setflag(n,byte And n)            ; set the negative bit in the status
End Function


Function ror_A()
  bit = flagset(c) Shl 7         ; get the carry value in b7
  setflag(c,a And 1)            ; set the carry bit in the status
  a = (a Shr 1) Or bit            ; shift and add the carry to the value
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function lsr(address)
  byte = peek(address)            ; get the value from memory
  setflag(c,byte And 1)            ; set the carry bit in the status
  byte = byte Shr 1            ; shift the value
  poke(address,byte)            ; save the result back to memory
  setflag(z,Not byte)            ; set the zero bit in the status
  setflag(n,False)            ; clear the negative bit in the status
End Function


Function lsr_A()
  setflag(c,a And 1)            ; set the carry bit in the status
  a = a Shr 1               ; shift the value
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,False)            ; clear the negative bit in the status
End Function


Function bit(address)
  h = peek(address)            ; get the value from memory
  setflag(n,h And n)            ; set the negative bit in the status
  setflag(v,h And v)            ; set the overflow bit in the status
  setflag(z,Not(h And a))         ; set the zero bit in the status
End Function


Function brk()
  pc = (pc + 1) And $FFFF         ; increment the pc
  push(hi(pc))               ; push the pc high byte
  push(lo(pc))               ; push the pc low byte
  push(p Or b)               ; push the status byte with the break bit set
  setflag(i,True)               ; set the interrupt disable bit
  pc = peek2($FFFE)            ; get the IRQ vector
End Function


Function and_(address)
  a = a And peek(address)         ; AND the address contents with A
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function ora(address)
  a=a Or peek(address)            ; OR the address contents with A
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function eor(address)
  a = a Xor peek(address)         ; EOR the address contents with A
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function cmp(address)
  h = a - peek(address)            ; calculate A = the address contents
  setflag(c,Not (h And $100))         ; set the carry bit in the status
  setflag(z,Not (h And $FF))         ; set the zero bit in the status
  setflag(n,h And n)            ; set the negative bit in the status
End Function


Function cpx(address)
  h = x - peek(address)            ; calculate X = the address contents
  setflag(c,Not (h And $100))         ; set the carry bit in the status
  setflag(z,Not (h And $FF))         ; set the zero bit in the status
  setflag(n,h And n)            ; set the negative bit in the status
End Function


Function cpy(address)
  h = y - peek(address)            ; calculate Y = the address contents
  setflag(c,Not (h And $100))         ; set the carry bit in the status
  setflag(z,Not (h And $FF))         ; set the zero bit in the status
  setflag(n,h And n)            ; set the negative bit in the status
End Function


Function dec_(address)
  h = (peek(address) - 1) And $FF      ; calculate the address contents - 1
  poke(address,h)               ; save the result back to memory
  setflag(z,Not h)            ; set the zero bit in the status
  setflag(n,h And n)            ; set the negative bit in the status
End Function


Function inc_(address)
  h = (peek(address) + 1) And $FF      ; calculate the address contents + 1
  poke(address,h)               ; save the result back to memory
  setflag(z,Not h)            ; set the zero bit in the status
  setflag(n,h And n)            ; set the negative bit in the status
End Function


Function dex()
  x = (x - 1) And $FF            ; calculate X - 1
  setflag(z,Not x)            ; set the zero bit in the status
  setflag(n,x And n)            ; set the negative bit in the status
End Function


Function inx()
  x = (x + 1) And $FF            ; calculate X + 1
  setflag(z,Not x)            ; set the zero bit in the status
  setflag(n,x And n)            ; set the negative bit in the status
End Function


Function dey()
  y = (y - 1) And $FF            ; calculate Y - 1
  setflag(z,Not y)            ; set the zero bit in the status
  setflag(n,y And n)            ; set the negative bit in the status
End Function


Function iny()
  y = (y + 1) And $FF            ; calculate Y + 1
  setflag(z,Not y)            ; set the zero bit in the status
  setflag(n,y And n)            ; set the negative bit in the status
End Function


Function jmp(address)
  pc = address               ; copy the address to the pc
End Function


Function jsr(address)
  pc = (pc - 1) And $FFFF         ; decrement the address
  push(hi(pc))               ; push the pc high byte
  push(lo(pc))               ; push the pc low byte
  pc = address               ; copy the address to the pc
End Function


Function rts()
  pc = 1 + pull()               ; pull the pc low byte
  pc = pc + pull() Shl 8         ; pull the pc high byte
End Function


Function rti()
  p = pull()               ; pull the status byte
  pc = pull()               ; pull the pc low byte
  pc = pc + pull() Shl 8         ; pull the pc high byte
End Function


Function lda(address)
  a = peek(address)            ; get the value from memory
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function ldx(address)
  x = peek(address)            ; get the value from memory
  setflag(z,Not x)            ; set the zero bit in the status
  setflag(n,x And n)            ; set the negative bit in the status
End Function


Function ldy(address)
  y = peek(address)            ; get the value from memory
  setflag(z,Not y)            ; set the zero bit in the status
  setflag(n,y And n)            ; set the negative bit in the status
End Function


Function pla()
  a = pull()               ; pull a byte from the stack
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function php()
  push(p Or b)               ; push the status byte with the break bit set
End Function


Function plp()
  p = pull() AND (b Xor $FF)         ; pull the status byte and clear the break bit
End Function


Function sta(address)
  poke(address,a)               ; save A to the memory
End Function


Function stx(address)
  poke(address,x)               ; save X to the memory
End Function


Function sty(address)
  poke(address,y)               ; save Y to the memory
End Function


Function tax()
  x = a                  ; copy X to A
  setflag(z,Not x)            ; set the zero bit in the status
  setflag(n,x And n)            ; set the negative bit in the status
End Function


Function tay()
  y = a                  ; copy Y to A
  setflag(z,Not y)            ; set the zero bit in the status
  setflag(n,y And n)            ; set the negative bit in the status
End Function


Function tsx()
  x = s                  ; copy X to the stack pointer
  setflag(z,Not x)            ; set the zero bit in the status
  setflag(n,x And n)            ; set the negative bit in the status
End Function


Function txa()
  a = x                  ; copy A to X
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


Function txs()
  s = x                  ; copy the stack pointer to X
End Function


Function tya()
  a = y                  ; copy A to Y
  setflag(z,Not a)            ; set the zero bit in the status
  setflag(n,a And n)            ; set the negative bit in the status
End Function


;************************************************************************************
;
; the minimal hardware emulation

; interrupts

Function nmi()
  push(hi(pc))               ; push the pc high byte
  push(lo(pc))               ; push the pc low byte
  push(p)                  ; push the status byte with the break bit clear
  setflag(i,True)               ; set the interrupt disable bit
  pc = peek2($FFFA)            ; get the NMI vector
End Function


Function reset()
  setflag(i,True)               ; set the interrupt disable bit
  pc = peek2($FFFC)            ; get the RESET vector
End Function


; vertical blanking interrupt

Function irq()
  If flagset(i) Goto noint         ; if the disable bit is set just exit

    push(hi(pc))               ; push the pc high byte
    push(lo(pc))               ; push the pc low byte
    push(p)                  ; push the status byte with the break bit clear
    setflag(i,True)            ; set the interrupt disable bit
    pc = peek2($FFFE)            ; get the IRQ vector

    addkey()               ; pretend to scan the keyboard
.noint
End Function


; VIC chip peek

Function vicPeek(address)
  If address=>$1000 And address=<$1FFF Then
    peek = char_rom(address + $C000)
  Else If address=>$9000 And address=<$9FFF Then
    peek = char_rom(address + $4000)
  Else
    peek = ram(address)
  End If
  Return peek
End Function


; output a text byte to the screen

Function vicText(pos,val)
  LockBuffer()
  val = $1000 + val * 8            ; this will change if banks are implemented
  x0 = (pos Mod 40) * 8            ; left edge x co-ordinate from pos
  y0 = Int((pos / 40)) * 8         ; top edge y co-ordinate from pos

  For yyy = 0 To 7            ; for each character row
    byte = vicPeek(val + yyy)         ; get the row byte from the character ROM
    y1 = (y0 + yyy) Shl 1         ; calculate the screen y co-ordinate
    For xxx = 0 To 7            ; for each pixel in the row
   x1 = (x0 + xxx) Shl 1         ; calculate the screen x co-ordinate
   If (byte And ($80 Shr xxx)) Then   ; if the bit is set
        colour = $6C5EB5         ;   set the foreground colour
   Else                  ; else if the bit is clear
     colour = $352879         ;   set the background colour
   End If
   WritePixelFast x1    , y1, colour   ; write one pixel
   WritePixelFast x1 + 1, y1, colour   ; and the one next to it on the same row
                     ; it makes for a stripey screen
    Next
  Next
  UnlockBuffer()
End Function


; keyboard routine. shift lock doesn't seem to work and shift is the wrong sense

Function addkey()
  kb = GetKey() And $FF            ; get a key
  If kb Then               ; if there is a key
    buff = peek($C6)            ;   get the keyboard buffer index
    If buff < peek($0289) Then      ;   if there's room in the buffer
      poke($0277 + buff,kb)         ;     save the key
      poke($C6,buff + 1)         ;     save the updated buffer index
    End If
  End If
End Function

;************************************************************************************



I include the original full source BASIC sourcecode here

Code:
;---------------------------------------
; Commodore 64 emulator
;
; Translated and corrected sourcecodes
; originally by unknown author
;
; Version 0.2
;---------------------------------------
; Emulates a 6502 (without secret opcodes and extra 6510 opcodes, just standard C64 opcodes)
; Does not emulate SID or Joystickports, userport, cartridge, disk, datasette, CIA(input/output 2 6526 adapters w16bit parallel IO 8bit serial IO, clock with alarm)
; Does an simple VIC II emulation (40x25 textmode 1024 area without colourmap, and vbl interrupt) nothing else
; Notes: 100 - 1FF is stack page
; Improved C64 palette: black, white, red, cyan, purple, green, blue, yellow, lt brown, brown, pink, dark gray, gray, lt green, lt blue, lt gray
; $000000, $FFFFFF, $68372B, $70A4B2, $6F3D86, $588D43, $352879, $B8C76F, $6F4F25, $433900, $9A6759, $444444, $6C6C6C, $9AD284, $6C5EB5, $959595

Graphics 1024,600

; Global variables
Global a,x,y,s,p,op   ; Bytes
Global pc         ; Words
Dim ram(65536)      ; Arrays are global
Dim basic_rom(65536); $A000-$BFFF
Dim char_rom(65536) ; $D000-$DFFF
Dim kernal_rom(65536);$E000-$FFFF

; Load roms
f=ReadFile("BASIC.ROM") : For temp=0 To 8191 : byte=ReadByte(f) : basic_rom($A000+temp)=byte : Next : CloseFile f
f=ReadFile("CHAR.ROM") : For temp=0 To 4095 : byte=ReadByte(f) : char_rom($D000+temp)=byte : Next : CloseFile f
f=ReadFile("KERNAL.ROM") : For temp=0 To 8191 : byte=ReadByte(f) : kernal_rom($E000+temp)=byte : Next : CloseFile f

; Constants
Const c=1, z=2, i=4, d=8, b=16, v=64, n=128 ; statusreg p: NV.BDIZC

; Processor

reset()

; Main loop  OKAY
Repeat
cycle=cycle+1 : op=peek(pc) : pc=pc+1

Select op
           Case $69 : adc(imm()) ; OKAY
           Case $65 : adc(zp()) ; OKAY
           Case $75 : adc(zpx()) ; OKAY
           Case $6D : adc(abs_()) ; OKAY
           Case $7D : adc(abs_x()) ; OKAY
           Case $79 : adc(abs_y()) ; OKAY
           Case $61 : adc(indx()) ; OKAY
           Case $71 : adc(indy()) ; OKAY
           Case $29 : and_(imm()) ; OKAY
           Case $25 : and_(zp()) ; OKAY
           Case $35 : and_(zpx()) ; OKAY
           Case $2D : and_(abs_()) ; OKAY
           Case $3D : and_(abs_x()) ; OKAY
           Case $39 : and_(abs_y()) ; OKAY
           Case $21 : and_(indx()) ; OKAY
           Case $31 : and_(indy()) ; OKAY
           Case $0A : asl_A() ; OKAY
           Case $06 : asl(zp()) ; OKAY
           Case $16 : asl(zpx()) ; OKAY
           Case $0E : asl(abs_()) ; OKAY
           Case $1E : asl(abs_x()) ; OKAY
           Case $90 : bfc(c) ; bcc ; OKAY
           Case $B0 : bfs(c) ; bcs ; OKAY
           Case $F0 : bfs(z) ; beq ; OKAY
           Case $24 : bit(zp()) ; OKAY
           Case $2C : bit(abs_()) ; OKAY
           Case $30 : bfs(n) ; bmi ; OKAY
           Case $D0 : bfc(z) ; bne ; OKAY
           Case $10 : bfc(n) ; bpl ; OKAY
           Case $00 : brk() ; OKAY
           Case $50 : bfc(v) ; bvc ; OKAY
           Case $70 : bfs(v) ; bvs ; OKAY
           Case $18 : setflag(c,False) ; clc ; OKAY
           Case $D8 : setflag(d,False) ; cld ; OKAY
           Case $58 : setflag(i,False) ; cli ; OKAY
           Case $B8 : setflag(v,False) ; clv ; OKAY
           Case $C9 : cmp(imm()) ; OKAY
           Case $C5 : cmp(zp()) ; OKAY
           Case $D5 : cmp(zpx()) ; OKAY
           Case $CD : cmp(abs_()) ; OKAY
           Case $DD : cmp(abs_x()) ; OKAY
           Case $D9 : cmp(abs_y()) ; OKAY
           Case $C1 : cmp(indx()) ; OKAY
           Case $D1 : cmp(indy()) ; OKAY
           Case $E0 : cpx(imm()) ; OKAY
           Case $E4 : cpx(zp()) ; OKAY
           Case $EC : cpx(abs_()) ; OKAY
           Case $C0 : cpy(imm()) ; OKAY
           Case $C4 : cpy(zp()) ; OKAY
           Case $CC : cpy(abs_()) ; OKAY
           Case $C6 : dec_(zp()) ; OKAY
           Case $D6 : dec_(zpx()) ; OKAY
           Case $CE : dec_(abs_()) ; OKAY
           Case $DE : dec_(abs_x()) ; OKAY
           Case $CA : dex() ; OKAY
           Case $88 : dey() ; OKAY
           Case $49 : eor(imm()) ; OKAY
           Case $45 : eor(zp()) ; OKAY
           Case $55 : eor(zpx()) ; OKAY
           Case $4D : eor(abs_()) ; OKAY
           Case $5D : eor(abs_x()) ; OKAY
           Case $59 : eor(abs_y()) ; OKAY
           Case $41 : eor(indx()) ; OKAY
           Case $51 : eor(indy()) ; OKAY
           Case $E6 : inc_(zp()) ; OKAY
           Case $F6 : inc_(zpx()) ; OKAY
           Case $EE : inc_(abs_()) ; OKAY
           Case $FE : inc_(abs_x()) ; OKAY
           Case $E8 : inx() ; OKAY
           Case $C8 : iny() ; OKAY
           Case $4C : jmp(abs_()) ; OKAY
           Case $6C : jmp(ind()) ; OKAY
           Case $20 : jsr(abs_()) ; OKAY
           Case $A9 : lda(imm()) ; OKAY
           Case $A5 : lda(zp()) ; OKAY
           Case $B5 : lda(zpx()) ; OKAY
           Case $AD : lda(abs_()) ; OKAY
           Case $BD : lda(abs_x()) ; OKAY
           Case $B9 : lda(abs_y()) ; OKAY
           Case $A1 : lda(indx()) ; OKAY
           Case $B1 : lda(indy()) ; OKAY
           Case $A2 : ldx(imm()) ; OKAY
           Case $A6 : ldx(zp()) ; OKAY
           Case $B6 : ldx(zpy()) ; OKAY
           Case $AE : ldx(abs_()) ; OKAY
           Case $BE : ldx(abs_y()) ; OKAY
           Case $A0 : ldy(imm()) ; OKAY
           Case $A4 : ldy(zp()) ; OKAY
           Case $B4 : ldy(zpx()) ; OKAY
           Case $AC : ldy(abs_()) ; OKAY
           Case $BC : ldy(abs_x()) ; OKAY
           Case $4A : lsr_A() ; OKAY
           Case $46 : lsr(zp()) ; OKAY
           Case $56 : lsr(zpx()) ; OKAY
           Case $4E : lsr(abs_()) ; OKAY
           Case $5E : lsr(abs_x()) ; OKAY
           Case $EA : ; nop ; OKAY
           Case $09 : ora(imm()) ; OKAY
           Case $05 : ora(zp()) ; OKAY
           Case $15 : ora(zpx()) ; OKAY
           Case $0D : ora(abs_()) ; OKAY
           Case $1D : ora(abs_x()) ; OKAY
           Case $19 : ora(abs_y()) ; OKAY
           Case $01 : ora(indx()) ; OKAY
           Case $11 : ora(indy()) ; OKAY
           Case $48 : push(a)  ; pha ; OKAY
           Case $08 : push(p)  ; php ; OKAY
           Case $68 : pla() ; OKAY
           Case $28 : p=pull() ; plp ; OKAY
           Case $2A : rol_A() ; OKAY
           Case $26 : rol(zp()) ; OKAY
           Case $36 : rol(zpx()) ; OKAY
           Case $2E : rol(abs_()) ; OKAY
           Case $3E : rol(abs_x()) ; OKAY
           Case $6A : ror_A() ; OKAY
           Case $66 : ror(zp()) ; OKAY
           Case $76 : ror(zpx()) ; OKAY
           Case $6E : ror(abs_()) ; OKAY
           Case $7E : ror(abs_x()) ; OKAY
           Case $40 : rti() ; OKAY
           Case $60 : rts() ; OKAY
           Case $E9 : sbc(imm()) ; OKAY
           Case $E5 : sbc(zp()) ; OKAY
           Case $F5 : sbc(zpx()) ; OKAY
           Case $ED : sbc(abs_()) ; OKAY
           Case $FD : sbc(abs_x()) ; OKAY
           Case $F9 : sbc(abs_y()) ; OKAY
           Case $E1 : sbc(indx()) ; OKAY ; OKAY
           Case $F1 : sbc(indy()) ; OKAY
           Case $38 : setflag(c,True)     ; sec ; OKAY
           Case $F8 : setflag(d,True)     ; sed ; OKAY
           Case $78 : setflag(i,True)     ; sei ; OKAY
           Case $85 : sta(zp()) ; OKAY
           Case $95 : sta(zpx()) ; OKAY
           Case $8D : sta(abs_()) ; OKAY
           Case $9D : sta(abs_x()) ; OKAY
           Case $99 : sta(abs_y()) ; OKAY
           Case $81 : sta(indx()) ; OKAY
           Case $91 : sta(indy()) ; OKAY
           Case $86 : stx(zp()) ; OKAY
           Case $96 : stx(zpy()) ; OKAY
           Case $8E : stx(abs_()) ; OKAY
           Case $84 : sty(zp()) ; OKAY
           Case $94 : sty(zpx()) ; OKAY
           Case $8C : sty(abs_()) ; OKAY
           Case $AA : tax() ; OKAY
           Case $A8 : tay() ; OKAY
           Case $BA : tsx() ; OKAY
           Case $8A : txa() ; OKAY
           Case $9A : txs() ; OKAY
           Case $98 : tya() ; OKAY
           Default Print "unknown instruction":WaitKey:End
End Select

If cycle>1000000/50 Then cycle=cycle-1000000/50:VWait:irq() ; 1000000 instructions / vertical blanking
Until MouseDown(2) ; quit when pressing right mousebutton

Function peek2(address) : peek2 = peek(address) + peek(address+1)*256 : Return peek2 : End Function ; OKAY

Function poke(address,value) ; pokes a byte
ram(address)=value : If address=>$400 And address=<$7E7 Then VicText(address-$400,value)
End Function

Function peek(address) ; returns a byte ; OKAY
peek=ram(address)
If address=>$A000 And address=<$BFFF Then peek=basic_rom(address)
If address=>$D000 And address=<$DFFF Then peek=io(address)
If address=>$E000 And address=<$FFFF Then peek=kernal_rom(address)
Return peek
End Function

Function io(address) ; OKAY
If address = $D012 Then io=$00 Else io=$FF ; fake rasterinterrupt (rasterline 0 or 256)
Return io
End Function

Function signedbyte(byte) ; Checked, reads byte as 2nd complement byte, outputs -128 to 127
temp=byte:If temp=>128 Then temp=temp-256
Return temp
End Function

; Addressing modes: functions which return address for instructions to work upon ; 99%
Function imm() : imm=pc : pc=pc+1 : pc=pc And 65535 : Return imm : End Function ; returns normal word
Function zp() : zp=peek(pc) : pc=pc+1 : pc = pc And 65535 : Return zp : End Function ; returns normal byte
Function zpx() : zpx=peek(pc)+x : zpx = zpx and 255 : pc=pc+1 : pc=pc And 65535 : Return zpx : End Function
Function zpy() : zpy=peek(pc)+y : zpy = zpy and 255 : pc=pc+1 : pc=pc And 65535 : Return zpy : End Function
Function abs_() : abs_=peek2(pc) : pc=pc+2 : abs_=Abs_ And 65535 : pc = pc And 65535 : Return abs_ : End Function
Function abs_x() : absx=peek2(pc)+x : absx = absx and 65535 : pc=pc+2 : pc = pc and 65535 : Return absx : End Function
Function abs_y() : absy=peek2(pc)+y : absy = absy and 65535 : pc=pc+2 : pc = pc and 65535 : Return absy : End Function
Function ind() : ind=peek2(peek2(pc)) : pc=pc+2 : pc = pc and 65535 : Return ind : End Function
Function indx() : indx=peek2(lo(peek(pc)+x)) : indx = indx And 65535 : pc=pc+1 : pc = pc And 65535 : Return indx : End Function
Function indy() : indy=peek2(peek(pc))+y : indy = indy and 65535 : pc=pc+1 : pc = pc and 65535 : Return indy : End Function

Function setflag(flag,status) ; OKAY
If status Then p=(p Or flag) Else p=(p And (flag Xor 255))
End Function

Function flagset(flag) : flagset=(p And flag) : Return flagset : End Function ; OKAY
Function lo(value) : Return value And 255 : End Function ; OKAY
Function hi(value) : value=value Shr 8 : Return value And 255 : End Function
Function push(byte) : poke (256+s,byte) : s=s-1 : s=Abs(s+256) And 255 : End Function ; OKAY
Function pull() : s=s+1 : s=Abs(s+256) And 255 : pull=peek(256+s) : Return pull : End Function ; OKAY

Function bfs(flag) ; 99%
If flagset(flag) Then pc=pc+signedbyte(peek(pc))+1 Else pc=pc+1
pc=Abs (pc+65536) And 65535
End Function

Function bfc(flag) ; 99%
If flagset(flag) Then pc=pc+1 Else pc=pc+signedbyte(peek(pc))+1
pc=Abs (pc+65536) And 65535
End Function

Function adc(address) ; 99% ; DECIMAL MODE NOT NEEDED?
val=peek(address) : h=a+val : If flagset(c) Then h=h+1
a=h : setflag(c,h>$FF) : a=Abs(a+256) And 255 : setflag(z,a=0) : setflag(n,a And n)
h=h+$80
setflag(v, ( (h>$FF) Or (h<0)) ) ; SetFlag(v,( (((a Xor val) And $80) And ((a Xor h) And  $80)) Xor 65535) And 65536 )
End Function

Function sbc (address) ; 99% ; DECIMAL MODE NOT NEEDED?
val=peek(address) : h=a-val : If Not flagset(c) Then h=h-1
a=h :setflag(c,h<=$FF) : a=Abs(a+256) And 255 : setflag(z,a=0) : setflag(n,a And n)
h=h+$80
setflag(v, ((h>$FF) Or (h<0)) ) ; SetFlag(v,(((a Xor val) And $80) And ((a Xor h) And $80)) And 65536)
End Function

Function asl(address) ; 99%
byte=peek(address) : setflag(c,(byte And $80)) : byte=byte Shl 1 : byte=byte And 255 : poke(address,byte) : setflag(z,byte=0) : setflag(n,byte And n)
End Function

Function rol_A() ; 99%
bit=flagset(c) : setflag(c,(a And $80)) : a=a Shl 1 : a=a And 255
If bit Then a=a Or $01
setflag(z,a=0) : setflag(n,a And n)
End Function

Function rol(address) ; 99%
byte=peek(address) : bit=flagset(c) : setflag(c,(byte And $80)) : byte=byte Shl 1 : byte=byte And 255
If bit Then byte=byte Or $01
poke(address,byte) : setflag(z,byte=0) : setflag(n,byte And n)
End Function

Function ror_A() ; 99%
bit=flagset(c) : setflag(c,(a And $01)) : a=a Shr 1 : a=a And 255
If bit Then a=a Or $80
setflag(z,a=0) : setflag(n,a And n)
End Function

Function ror(address) ; 99%
byte=peek(address) : bit=flagset(c) : setflag(c,(byte And $01)) : byte=byte Shr 1 : byte=byte And 255
If bit Then byte=byte Or $80
poke(address,byte) : setflag(z,byte=0) : setflag(n,byte And n)
End Function

Function lsr_A() : setflag(c,(a And $01)) : a=a Shr 1 : a=a And 255 : setflag(z,a=0) : setflag(n,False) : End Function ; OKAY
Function lsr(address) : byte=peek(address) : setflag(C,(byte And $01)) : byte=byte Shr 1 : byte=byte And 255 : poke(address,byte) : setflag(z,byte=0) : setflag(n,False) : End Function ; 99%
Function bit(address) : h=peek(address) : setflag(n,(h And $80)) : setflag(v,(h And $40)) : setflag(z,((h And a)=0) ) : End Function ; 99%
Function brk() : setflag(b,True) : pc=pc+1 : pc=pc And 65535 : push(hi(pc)) : push(lo(pc)) : push(p) : setflag(i,True) : pc=peek2($FFFE) : End Function ; 99%
Function and_(address) : a=a And peek(address) : setflag(z,a=0) : setflag(n,a And n) : End Function ; OKAY!
Function ora(address) : a=a Or peek(address) : setflag(z,a=0) : setflag(n,a And n) : End Function ; OKAY!
Function asl_A() : setflag(c,(a And $80)) : a=a Shl 1 : a=a And 255 : setflag(z,a=0) : setflag(n,a And n) : End Function ; 99%
Function cmp(address) : h=a-peek(address) : setflag(c,h<=$FF) : h=Abs(h+256) And 255 : setflag(z,h=0) : setflag(n,h And n) : End Function ; 99% + 256 as could be negative? carry measuring correct?
Function cpx(address) : h=x-peek(address) : setflag(c,h<=$FF) : h=Abs(h+256) And 255 : setflag(z,h=0) : setflag(n,h And n) : End Function ; 99% + 256 as could be negative? carry measuring correct?
Function cpy(address) : h=y-peek(address) : setflag(c,h<=$FF) : h=Abs(h+256) And 255 : setflag(z,h=0) : setflag(n,h And n) : End Function ; 99% + 256 as could be negative? carry measuring correct?
Function dec_(address) :h=peek(address)-1 : h=Abs(h+256) And 255 : poke (address,h) : setflag(z,h=0) : setflag(n,h And n) : End Function ; 99%
Function dex() : x=x-1 : x=Abs(x+256) And 255 : setflag(z,x=0) : setflag(n,x And n) : End Function ; 99%
Function dey() : y=y-1 : y=Abs(y+256) And 255 : setflag(z,y=0) : setflag(n,y And n) : End Function ; 99%
Function eor(address) : a=a Xor peek(address) : setflag(z,a=0) : setflag(n,a And n) : End Function ; OKAY!
Function inc_(address) : h=peek(address)+1 : h=h And 255 : poke (address,h) : setflag(z,h=0) : setflag(n,h And n) : End Function ; 99%
Function inx() : x=(x+1) And 255 : setflag(z,x=0) : setflag(n,x And n) : End Function ; OKAY
Function iny() : y=(y+1) And 255 : setflag(z,y=0) : setflag(n,y And n) : End Function ; OKAY
Function jmp(address) : pc=address : End Function ; OKAY
Function jsr(address) : pc=pc-1 : pc=Abs(pc+65536) And 65535 : push(hi(pc)) : push(lo(pc)) : pc=address : End Function ; OKAY
Function rts() : pc=pull() : pc=pc+pull()*256+1 : End Function ; OKAY!
Function rti() : p=pull() : pc=pull() : pc=pc+pull()*256 : End Function ; OKAY!
Function lda(address) : a=peek(address) : setflag(z,a=0) : setflag(n,a And n) : End Function ; OKAY!
Function ldx(address) : x=peek(address) : setflag(z,x=0) : setflag(n,x And n) : End Function ; OKAY!
Function ldy(address) : y=peek(address) : setflag(z,y=0) : setflag(n,y And n) : End Function ; OKAY!
Function pla() : a=pull() : setflag(z,a=0) : setflag(n,a And n) : End Function ; OKAY
Function sta(address) : poke (address,a) : End Function ; OKAY!
Function stx(address) : poke (address,x) : End Function ; OKAY!
Function sty(address) : poke (address,y) : End Function ; OKAY!
Function tax() : x=a : setflag(z,x=0) : setflag(n,x And n) : End Function ; OKAY!
Function tay() : y=a : setflag(z,y=0) : setflag(n,y And n) : End Function ; OKAY!
Function tsx() : x=s : setflag(z,x=0) : setflag(n,x And n) : End Function ; OKAY!
Function txa() : a=x : setflag(z,a=0) : setflag(n,a And n) : End Function ; OKAY!
Function txs() : s=x : End Function ; OKAY!
Function tya() : a=y : setflag(z,a=0) : setflag(n,a And n) : End Function ; OKAY!

Function vicPeek(address) ; returns byte OKAY
peek=ram(address)
If address=>$1000 And address=<$1FFF Then peek=char_rom(address+$C000)
If address=>$9000 And address=<$9FFF Then peek=char_rom(address+$4000)
Return peek
End Function

Function vicText(pos,val) ; OKAY
LockBuffer() : x0=(pos Mod 40)*8 : y0=Int((pos / 40))*8
For xxx=0 To 7 : For yyy=0 To 7
colour=$352879 : If (vicPeek($1000+val*8+yyy) And ($80 Shr xxx)) Then colour = $6C5EB5
WritePixelFast (x0+xxx) Shl 1,(y0+yyy) Shl 1,colour : WritePixelFast 1+(x0+xxx) Shl 1,(y0+yyy) Shl 1,colour ; with abit retro feeling
Next : Next : UnlockBuffer()
End Function

Function reset() : pc=peek2($FFFC) : setflag(i,True) : End Function ; OKAY

Function irq() ; VERTCIAL BLANKING INTERUPT ; OKAY
If Not flagset(i) Then setflag(B,False) : push(hi(pc)) : push(lo(pc)) : push(p) : setflag(i,True) : pc=peek2($FFFE) : addkey()
End Function

Function nmi() : setflag(b,False) : push(hi(pc)) : push(lo(pc)) : push(p) : setflag(i,True) : pc=peek2($FFFA) : End Function ; OKAY

Function addkey() ; Keyboard routine ; OKAY (SCANCODE might need uppercase or other conversion or not)
buff = peek($C6) ; If ch = 0 Then ch=ord(readkey), ch = 145 ; up, ch = 157 ; left, ch =  17 ; down, ch =  29 ; right, ch = 148 ; inst-del
If buff < 10 Then kb=GetKey() : If kb Then poke($0277+buff,kb) : poke ($c6,buff+1)
End Function
:) :) :) :)

UPDATED code to reflect proposed changes


Last edited by JayPanda on Mon Jun 06, 2011 9:36 am, edited 4 times in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jun 05, 2011 6:42 am 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
In ADC and SBC I think you need to do the ..

Code:
a=Abs(a+256) And 255

.. before you do the ..

Code:
setflag(z,a=0)


I'm not sure though why you do the Abs() as just doing ..

Code:
a=a And 255

.. should do the same thing.

What BASIC is that?

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jun 05, 2011 7:15 am 
Offline

Joined: Sun Jun 05, 2011 4:51 am
Posts: 8
leeeeee wrote:
In ADC and SBC I think you need to do the ..

Code:
a=Abs(a+256) And 255

.. before you do the ..

Code:
setflag(z,a=0)


I'm not sure though why you do the Abs() as just doing ..

Code:
a=a And 255

.. should do the same thing.

What BASIC is that?

Lee.


I tried that modification , still same though. Any other ideas?

You are very right about the abs() , its just slipped in there. I use that when counting goes negative, and as im not optimizing as its now even working, I have not
bothered much differ between ABS(X+256) AND 255 (needed for subtracted x getting byte wrapped) and just X AND 255 (for positive x getting byte wrapped).

It is Blitz BASIC

EDIT I meant to say Blitz3D
http://www.blitzbasic.com/Products/_index_.php


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jun 05, 2011 7:43 am 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
That's an out of memory error and the wrong character set by the look of it.

I've never used Blitz so I'll see what I can do.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jun 05, 2011 8:00 am 
Offline

Joined: Sun Jun 05, 2011 4:51 am
Posts: 8
leeeeee wrote:
That's an out of memory error and the wrong character set by the look of it.

I've never used Blitz so I'll see what I can do.

Lee.


If I am not misstaken The Blitz3D demo is free and not limited in any way what I know. Saving this 6502 emu clip on your desktop as emu.bb or something like that and put the 3 C64 ROMs files beside it same folder. (20KB total) Just load and click compile and it should run fine :) With bugs and everything!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jun 05, 2011 9:18 pm 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
Well I got the Blitz3D <cough>demo</cough> and yay! Go me.

Image

Now I just need to work out what I did to fix it apart from fixing the kernal image from my C64 which doesn't work in a standard C64.

More later.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 3:52 am 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
I made a page about it here.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 4:16 am 
Offline

Joined: Sun Jun 05, 2011 4:51 am
Posts: 8
leeeeee wrote:
I made a page about it here.

Lee.


Will check it out.

Actually all bits and comments are made by me haha, I've been doing this thing for over a year now, sorry about the style, originally from some very nice Pascal source by someone.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 4:19 am 
Offline

Joined: Sun Jun 05, 2011 4:51 am
Posts: 8
JayPanda wrote:
leeeeee wrote:
I made a page about it here.

Lee.


Will check it out.

Actually all bits and comments are made by me haha, I've been doing this thing for over a year now, sorry about the style, originally from some very nice Pascal source by someone.


EDITED: so very nice to see it fully alive, you would not believe :) Great job finding the bugs

I put up the newest offical copy here
http://www.blitzbasic.com/Community/pos ... 25#1091067

It also includes the full rom in BASIC source. (mostly for curiosuity)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 5:04 am 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
The original was ED64 by Marc Dendooven. You can download the first six of nine chapters of the series from the Wayback Machine.

Unfortunately the version with the hires mode doesn't seem to be available.

We've even mentioned it before on this forum.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 5:08 am 
Offline

Joined: Sun Jun 05, 2011 4:51 am
Posts: 8
leeeeee wrote:
The original was ED64 by Marc Dendooven. You can download the first six of nine chapters of the series from the Wayback Machine.

Unfortunately the version with the hires mode doesn't seem to be available.

We've even mentioned it before on this forum.

Lee.


Yes I put him in the Sourcecode just the other minute. And I think I could get the hires version If someone wants it. I will have to check that later on. I know for sure he made 10 chapters on the matter few years ago.

EDIT Cleaning the attic really makes a difference, I for sure have that 10th chapter. If it is okay with Marc and everyone I may upload this later as soon as possible.

take care!
/Jay


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 6:03 am 
Offline

Joined: Sun Jun 05, 2011 4:51 am
Posts: 8
leeeeee wrote:
I made a page about it here.

Lee.


I sortof missed It was not me glancing at a sudden working ROM, must have been great AHA feeling!

But I salute you, great job!

EDITED 4 years work sweat finally got to an end, Marc was such inspiration source, and last night I was up all night finding the bug and that and found and brought few opcodes to focus CMP, ADC, SBC etc in my comments, SBC seem to be the most missunderstood instruction of them all. But one things is I was surprised C64 does not used decimal mode. I always beilieved it did somewhere in its rosty innerds.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 10:07 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
JayPanda wrote:
... But one things is I was surprised C64 does not used decimal mode. I always beilieved it did somewhere in its rosty innerds.


Very interesting, I thought so too!

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 1:34 pm 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
To make sure decimal mode isn't used I searched the C64 sources for SED and CLD.

No SED at all and only one CLD which is in the reset code.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jun 06, 2011 2:44 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8246
Location: Midwestern USA
leeeeee wrote:
To make sure decimal mode isn't used I searched the C64 sources for SED and CLD.

No SED at all and only one CLD which is in the reset code.

Lee.

All floating point math in all eight bit Commodore machines was done in excess-128 notation. The M/L monitor in the C-128 used BCD for number conversion when a decimal integer was displayed. As far as I can recall, only Atari eight bit machines used BCD for floating point work.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: